add isl_basic_map_get_tuple_name
[platform/upstream/isl.git] / isl_map.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2010      INRIA Saclay
4  *
5  * Use of this software is governed by the GNU LGPLv2.1 license
6  *
7  * Written by Sven Verdoolaege, K.U.Leuven, Departement
8  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France 
11  */
12
13 #include <string.h>
14 #include <strings.h>
15 #include "isl_ctx.h"
16 #include "isl_blk.h"
17 #include "isl_dim_private.h"
18 #include "isl_equalities.h"
19 #include "isl_list.h"
20 #include "isl_lp.h"
21 #include "isl_seq.h"
22 #include "isl_set.h"
23 #include "isl_map.h"
24 #include "isl_map_private.h"
25 #include "isl_map_piplib.h"
26 #include <isl_reordering.h>
27 #include "isl_sample.h"
28 #include "isl_tab.h"
29 #include "isl_vec.h"
30 #include <isl_mat_private.h>
31
32 /* Maps dst positions to src positions */
33 struct isl_dim_map {
34         unsigned len;
35         int pos[1];
36 };
37
38 static struct isl_dim_map *isl_dim_map_alloc(struct isl_ctx *ctx, unsigned len)
39 {
40         int i;
41         struct isl_dim_map *dim_map;
42         dim_map = isl_alloc(ctx, struct isl_dim_map,
43                                 sizeof(struct isl_dim_map) + len * sizeof(int));
44         if (!dim_map)
45                 return NULL;
46         dim_map->len = 1 + len;
47         dim_map->pos[0] = 0;
48         for (i = 0; i < len; ++i)
49                 dim_map->pos[1 + i] = -1;
50         return dim_map;
51 }
52
53 static unsigned n(struct isl_dim *dim, enum isl_dim_type type)
54 {
55         switch (type) {
56         case isl_dim_param:     return dim->nparam;
57         case isl_dim_in:        return dim->n_in;
58         case isl_dim_out:       return dim->n_out;
59         case isl_dim_all:       return dim->nparam + dim->n_in + dim->n_out;
60         default:                return 0;
61         }
62 }
63
64 static unsigned pos(struct isl_dim *dim, enum isl_dim_type type)
65 {
66         switch (type) {
67         case isl_dim_param:     return 1;
68         case isl_dim_in:        return 1 + dim->nparam;
69         case isl_dim_out:       return 1 + dim->nparam + dim->n_in;
70         default:                return 0;
71         }
72 }
73
74 static void isl_dim_map_dim_range(struct isl_dim_map *dim_map,
75         struct isl_dim *dim, enum isl_dim_type type,
76         unsigned first, unsigned n, unsigned dst_pos)
77 {
78         int i;
79         unsigned src_pos;
80
81         if (!dim_map || !dim)
82                 return;
83         
84         src_pos = pos(dim, type);
85         for (i = 0; i < n; ++i)
86                 dim_map->pos[1 + dst_pos + i] = src_pos + first + i;
87 }
88
89 static void isl_dim_map_dim(struct isl_dim_map *dim_map, struct isl_dim *dim,
90                 enum isl_dim_type type, unsigned dst_pos)
91 {
92         isl_dim_map_dim_range(dim_map, dim, type, 0, n(dim, type), dst_pos);
93 }
94
95 static void isl_dim_map_div(struct isl_dim_map *dim_map,
96                 struct isl_basic_map *bmap, unsigned dst_pos)
97 {
98         int i;
99         unsigned src_pos;
100
101         if (!dim_map || !bmap)
102                 return;
103         
104         src_pos = 1 + isl_dim_total(bmap->dim);
105         for (i = 0; i < bmap->n_div; ++i)
106                 dim_map->pos[1 + dst_pos + i] = src_pos + i;
107 }
108
109 static void isl_dim_map_dump(struct isl_dim_map *dim_map)
110 {
111         int i;
112
113         for (i = 0; i < dim_map->len; ++i)
114                 fprintf(stderr, "%d -> %d; ", i, dim_map->pos[i]);
115         fprintf(stderr, "\n");
116 }
117
118 unsigned isl_basic_map_dim(const struct isl_basic_map *bmap,
119                                 enum isl_dim_type type)
120 {
121         if (!bmap)
122                 return 0;
123         switch (type) {
124         case isl_dim_cst:       return 1;
125         case isl_dim_param:
126         case isl_dim_in:
127         case isl_dim_out:       return isl_dim_size(bmap->dim, type);
128         case isl_dim_div:       return bmap->n_div;
129         case isl_dim_all:       return isl_basic_map_total_dim(bmap);
130         default:                return 0;
131         }
132 }
133
134 unsigned isl_map_dim(const struct isl_map *map, enum isl_dim_type type)
135 {
136         return map ? n(map->dim, type) : 0;
137 }
138
139 unsigned isl_set_dim(const struct isl_set *set, enum isl_dim_type type)
140 {
141         return set ? n(set->dim, type) : 0;
142 }
143
144 unsigned isl_basic_map_offset(struct isl_basic_map *bmap,
145                                         enum isl_dim_type type)
146 {
147         struct isl_dim *dim = bmap->dim;
148         switch (type) {
149         case isl_dim_cst:       return 0;
150         case isl_dim_param:     return 1;
151         case isl_dim_in:        return 1 + dim->nparam;
152         case isl_dim_out:       return 1 + dim->nparam + dim->n_in;
153         case isl_dim_div:       return 1 + dim->nparam + dim->n_in + dim->n_out;
154         default:                return 0;
155         }
156 }
157
158 static unsigned map_offset(struct isl_map *map, enum isl_dim_type type)
159 {
160         return pos(map->dim, type);
161 }
162
163 unsigned isl_basic_set_dim(const struct isl_basic_set *bset,
164                                 enum isl_dim_type type)
165 {
166         return isl_basic_map_dim((const struct isl_basic_map*)bset, type);
167 }
168
169 unsigned isl_basic_set_n_dim(const struct isl_basic_set *bset)
170 {
171         return isl_basic_set_dim(bset, isl_dim_set);
172 }
173
174 unsigned isl_basic_set_n_param(const struct isl_basic_set *bset)
175 {
176         return isl_basic_set_dim(bset, isl_dim_param);
177 }
178
179 unsigned isl_basic_set_total_dim(const struct isl_basic_set *bset)
180 {
181         return isl_dim_total(bset->dim) + bset->n_div;
182 }
183
184 unsigned isl_set_n_dim(const struct isl_set *set)
185 {
186         return isl_set_dim(set, isl_dim_set);
187 }
188
189 unsigned isl_set_n_param(const struct isl_set *set)
190 {
191         return isl_set_dim(set, isl_dim_param);
192 }
193
194 unsigned isl_basic_map_n_in(const struct isl_basic_map *bmap)
195 {
196         return bmap ? bmap->dim->n_in : 0;
197 }
198
199 unsigned isl_basic_map_n_out(const struct isl_basic_map *bmap)
200 {
201         return bmap ? bmap->dim->n_out : 0;
202 }
203
204 unsigned isl_basic_map_n_param(const struct isl_basic_map *bmap)
205 {
206         return bmap ? bmap->dim->nparam : 0;
207 }
208
209 unsigned isl_basic_map_n_div(const struct isl_basic_map *bmap)
210 {
211         return bmap ? bmap->n_div : 0;
212 }
213
214 unsigned isl_basic_map_total_dim(const struct isl_basic_map *bmap)
215 {
216         return bmap ? isl_dim_total(bmap->dim) + bmap->n_div : 0;
217 }
218
219 unsigned isl_map_n_in(const struct isl_map *map)
220 {
221         return map->dim->n_in;
222 }
223
224 unsigned isl_map_n_out(const struct isl_map *map)
225 {
226         return map->dim->n_out;
227 }
228
229 unsigned isl_map_n_param(const struct isl_map *map)
230 {
231         return map->dim->nparam;
232 }
233
234 int isl_map_compatible_domain(struct isl_map *map, struct isl_set *set)
235 {
236         int m;
237         if (!map || !set)
238                 return -1;
239         m = isl_dim_match(map->dim, isl_dim_param, set->dim, isl_dim_param);
240         if (m < 0 || !m)
241                 return m;
242         return isl_dim_tuple_match(map->dim, isl_dim_in, set->dim, isl_dim_set);
243 }
244
245 int isl_basic_map_compatible_domain(struct isl_basic_map *bmap,
246                 struct isl_basic_set *bset)
247 {
248         int m;
249         if (!bmap || !bset)
250                 return -1;
251         m = isl_dim_match(bmap->dim, isl_dim_param, bset->dim, isl_dim_param);
252         if (m < 0 || !m)
253                 return m;
254         return isl_dim_tuple_match(bmap->dim, isl_dim_in, bset->dim, isl_dim_set);
255 }
256
257 int isl_basic_map_compatible_range(struct isl_basic_map *bmap,
258                 struct isl_basic_set *bset)
259 {
260         int m;
261         if (!bmap || !bset)
262                 return -1;
263         m = isl_dim_match(bmap->dim, isl_dim_param, bset->dim, isl_dim_param);
264         if (m < 0 || !m)
265                 return m;
266         return isl_dim_tuple_match(bmap->dim, isl_dim_out, bset->dim, isl_dim_set);
267 }
268
269 isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap)
270 {
271         return bmap ? bmap->ctx : NULL;
272 }
273
274 isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_set *bset)
275 {
276         return bset ? bset->ctx : NULL;
277 }
278
279 isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map)
280 {
281         return map ? map->ctx : NULL;
282 }
283
284 isl_ctx *isl_set_get_ctx(__isl_keep isl_set *set)
285 {
286         return set ? set->ctx : NULL;
287 }
288
289 struct isl_dim *isl_basic_map_get_dim(struct isl_basic_map *bmap)
290 {
291         if (!bmap)
292                 return NULL;
293         return isl_dim_copy(bmap->dim);
294 }
295
296 struct isl_dim *isl_basic_set_get_dim(struct isl_basic_set *bset)
297 {
298         if (!bset)
299                 return NULL;
300         return isl_dim_copy(bset->dim);
301 }
302
303 struct isl_dim *isl_map_get_dim(struct isl_map *map)
304 {
305         if (!map)
306                 return NULL;
307         return isl_dim_copy(map->dim);
308 }
309
310 struct isl_dim *isl_set_get_dim(struct isl_set *set)
311 {
312         if (!set)
313                 return NULL;
314         return isl_dim_copy(set->dim);
315 }
316
317 __isl_give isl_basic_map *isl_basic_map_set_tuple_name(
318         __isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s)
319 {
320         bmap = isl_basic_map_cow(bmap);
321         if (!bmap)
322                 return NULL;
323         bmap->dim = isl_dim_set_tuple_name(bmap->dim, type, s);
324         if (!bmap->dim)
325                 goto error;
326         return bmap;
327 error:
328         isl_basic_map_free(bmap);
329         return NULL;
330 }
331
332 const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap,
333         enum isl_dim_type type)
334 {
335         return bmap ? isl_dim_get_tuple_name(bmap->dim, type) : NULL;
336 }
337
338 __isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map,
339         enum isl_dim_type type, const char *s)
340 {
341         int i;
342
343         map = isl_map_cow(map);
344         if (!map)
345                 return NULL;
346
347         map->dim = isl_dim_set_tuple_name(map->dim, type, s);
348         if (!map->dim)
349                 goto error;
350
351         for (i = 0; i < map->n; ++i) {
352                 map->p[i] = isl_basic_map_set_tuple_name(map->p[i], type, s);
353                 if (!map->p[i])
354                         goto error;
355         }
356
357         return map;
358 error:
359         isl_map_free(map);
360         return NULL;
361 }
362
363 __isl_give isl_set *isl_set_set_tuple_name(__isl_take isl_set *set,
364         const char *s)
365 {
366         return (isl_set *)isl_map_set_tuple_name((isl_map *)set, isl_dim_set, s);
367 }
368
369 __isl_give isl_basic_map *isl_basic_map_set_dim_name(
370         __isl_take isl_basic_map *bmap,
371         enum isl_dim_type type, unsigned pos, const char *s)
372 {
373         if (!bmap)
374                 return NULL;
375         bmap->dim = isl_dim_set_name(bmap->dim, type, pos, s);
376         if (!bmap->dim)
377                 goto error;
378         return bmap;
379 error:
380         isl_basic_map_free(bmap);
381         return NULL;
382 }
383
384 __isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map,
385         enum isl_dim_type type, unsigned pos, const char *s)
386 {
387         int i;
388
389         if (!map)
390                 return NULL;
391
392         map->dim = isl_dim_set_name(map->dim, type, pos, s);
393         if (!map->dim)
394                 goto error;
395
396         for (i = 0; i < map->n; ++i) {
397                 map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s);
398                 if (!map->p[i])
399                         goto error;
400         }
401
402         return map;
403 error:
404         isl_map_free(map);
405         return NULL;
406 }
407
408 __isl_give isl_basic_set *isl_basic_set_set_dim_name(
409         __isl_take isl_basic_set *bset,
410         enum isl_dim_type type, unsigned pos, const char *s)
411 {
412         return (isl_basic_set *)isl_basic_map_set_dim_name(
413                 (isl_basic_map *)bset, type, pos, s);
414 }
415
416 __isl_give isl_set *isl_set_set_dim_name(__isl_take isl_set *set,
417         enum isl_dim_type type, unsigned pos, const char *s)
418 {
419         return (isl_set *)isl_map_set_dim_name((isl_map *)set, type, pos, s);
420 }
421
422 int isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap)
423 {
424         if (!bmap)
425                 return -1;
426         return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
427 }
428
429 static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx,
430                 struct isl_basic_map *bmap, unsigned extra,
431                 unsigned n_eq, unsigned n_ineq)
432 {
433         int i;
434         size_t row_size = 1 + isl_dim_total(bmap->dim) + extra;
435
436         bmap->ctx = ctx;
437         isl_ctx_ref(ctx);
438
439         bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size);
440         if (isl_blk_is_error(bmap->block))
441                 goto error;
442
443         bmap->ineq = isl_alloc_array(ctx, isl_int *, n_ineq + n_eq);
444         if (!bmap->ineq)
445                 goto error;
446
447         if (extra == 0) {
448                 bmap->block2 = isl_blk_empty();
449                 bmap->div = NULL;
450         } else {
451                 bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
452                 if (isl_blk_is_error(bmap->block2))
453                         goto error;
454
455                 bmap->div = isl_alloc_array(ctx, isl_int *, extra);
456                 if (!bmap->div)
457                         goto error;
458         }
459
460         for (i = 0; i < n_ineq + n_eq; ++i)
461                 bmap->ineq[i] = bmap->block.data + i * row_size;
462
463         for (i = 0; i < extra; ++i)
464                 bmap->div[i] = bmap->block2.data + i * (1 + row_size);
465
466         bmap->ref = 1;
467         bmap->flags = 0;
468         bmap->c_size = n_eq + n_ineq;
469         bmap->eq = bmap->ineq + n_ineq;
470         bmap->extra = extra;
471         bmap->n_eq = 0;
472         bmap->n_ineq = 0;
473         bmap->n_div = 0;
474         bmap->sample = NULL;
475
476         return bmap;
477 error:
478         isl_basic_map_free(bmap);
479         return NULL;
480 }
481
482 struct isl_basic_set *isl_basic_set_alloc(struct isl_ctx *ctx,
483                 unsigned nparam, unsigned dim, unsigned extra,
484                 unsigned n_eq, unsigned n_ineq)
485 {
486         struct isl_basic_map *bmap;
487         bmap = isl_basic_map_alloc(ctx, nparam, 0, dim, extra, n_eq, n_ineq);
488         return (struct isl_basic_set *)bmap;
489 }
490
491 struct isl_basic_set *isl_basic_set_alloc_dim(struct isl_dim *dim,
492                 unsigned extra, unsigned n_eq, unsigned n_ineq)
493 {
494         struct isl_basic_map *bmap;
495         if (!dim)
496                 return NULL;
497         isl_assert(dim->ctx, dim->n_in == 0, return NULL);
498         bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
499         return (struct isl_basic_set *)bmap;
500 }
501
502 struct isl_basic_map *isl_basic_map_alloc_dim(struct isl_dim *dim,
503                 unsigned extra, unsigned n_eq, unsigned n_ineq)
504 {
505         struct isl_basic_map *bmap;
506
507         if (!dim)
508                 return NULL;
509         bmap = isl_calloc_type(dim->ctx, struct isl_basic_map);
510         if (!bmap)
511                 goto error;
512         bmap->dim = dim;
513
514         return basic_map_init(dim->ctx, bmap, extra, n_eq, n_ineq);
515 error:
516         isl_dim_free(dim);
517         return NULL;
518 }
519
520 struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx,
521                 unsigned nparam, unsigned in, unsigned out, unsigned extra,
522                 unsigned n_eq, unsigned n_ineq)
523 {
524         struct isl_basic_map *bmap;
525         struct isl_dim *dim;
526
527         dim = isl_dim_alloc(ctx, nparam, in, out);
528         if (!dim)
529                 return NULL;
530
531         bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
532         return bmap;
533 }
534
535 static void dup_constraints(
536                 struct isl_basic_map *dst, struct isl_basic_map *src)
537 {
538         int i;
539         unsigned total = isl_basic_map_total_dim(src);
540
541         for (i = 0; i < src->n_eq; ++i) {
542                 int j = isl_basic_map_alloc_equality(dst);
543                 isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
544         }
545
546         for (i = 0; i < src->n_ineq; ++i) {
547                 int j = isl_basic_map_alloc_inequality(dst);
548                 isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
549         }
550
551         for (i = 0; i < src->n_div; ++i) {
552                 int j = isl_basic_map_alloc_div(dst);
553                 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
554         }
555         ISL_F_SET(dst, ISL_BASIC_SET_FINAL);
556 }
557
558 struct isl_basic_map *isl_basic_map_dup(struct isl_basic_map *bmap)
559 {
560         struct isl_basic_map *dup;
561
562         if (!bmap)
563                 return NULL;
564         dup = isl_basic_map_alloc_dim(isl_dim_copy(bmap->dim),
565                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
566         if (!dup)
567                 return NULL;
568         dup_constraints(dup, bmap);
569         dup->flags = bmap->flags;
570         dup->sample = isl_vec_copy(bmap->sample);
571         return dup;
572 }
573
574 struct isl_basic_set *isl_basic_set_dup(struct isl_basic_set *bset)
575 {
576         struct isl_basic_map *dup;
577
578         dup = isl_basic_map_dup((struct isl_basic_map *)bset);
579         return (struct isl_basic_set *)dup;
580 }
581
582 struct isl_basic_set *isl_basic_set_copy(struct isl_basic_set *bset)
583 {
584         if (!bset)
585                 return NULL;
586
587         if (ISL_F_ISSET(bset, ISL_BASIC_SET_FINAL)) {
588                 bset->ref++;
589                 return bset;
590         }
591         return isl_basic_set_dup(bset);
592 }
593
594 struct isl_set *isl_set_copy(struct isl_set *set)
595 {
596         if (!set)
597                 return NULL;
598
599         set->ref++;
600         return set;
601 }
602
603 struct isl_basic_map *isl_basic_map_copy(struct isl_basic_map *bmap)
604 {
605         if (!bmap)
606                 return NULL;
607
608         if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)) {
609                 bmap->ref++;
610                 return bmap;
611         }
612         bmap = isl_basic_map_dup(bmap);
613         if (bmap)
614                 ISL_F_SET(bmap, ISL_BASIC_SET_FINAL);
615         return bmap;
616 }
617
618 struct isl_map *isl_map_copy(struct isl_map *map)
619 {
620         if (!map)
621                 return NULL;
622
623         map->ref++;
624         return map;
625 }
626
627 void isl_basic_map_free(struct isl_basic_map *bmap)
628 {
629         if (!bmap)
630                 return;
631
632         if (--bmap->ref > 0)
633                 return;
634
635         isl_ctx_deref(bmap->ctx);
636         free(bmap->div);
637         isl_blk_free(bmap->ctx, bmap->block2);
638         free(bmap->ineq);
639         isl_blk_free(bmap->ctx, bmap->block);
640         isl_vec_free(bmap->sample);
641         isl_dim_free(bmap->dim);
642         free(bmap);
643 }
644
645 void isl_basic_set_free(struct isl_basic_set *bset)
646 {
647         isl_basic_map_free((struct isl_basic_map *)bset);
648 }
649
650 static int room_for_con(struct isl_basic_map *bmap, unsigned n)
651 {
652         return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size;
653 }
654
655 int isl_basic_map_alloc_equality(struct isl_basic_map *bmap)
656 {
657         struct isl_ctx *ctx;
658         if (!bmap)
659                 return -1;
660         ctx = bmap->ctx;
661         isl_assert(ctx, room_for_con(bmap, 1), return -1);
662         isl_assert(ctx, (bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size,
663                         return -1);
664         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
665         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
666         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
667         ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
668         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
669         if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
670                 isl_int *t;
671                 int j = isl_basic_map_alloc_inequality(bmap);
672                 if (j < 0)
673                         return -1;
674                 t = bmap->ineq[j];
675                 bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
676                 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
677                 bmap->eq[-1] = t;
678                 bmap->n_eq++;
679                 bmap->n_ineq--;
680                 bmap->eq--;
681                 return 0;
682         }
683         isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + isl_basic_map_total_dim(bmap),
684                       bmap->extra - bmap->n_div);
685         return bmap->n_eq++;
686 }
687
688 int isl_basic_set_alloc_equality(struct isl_basic_set *bset)
689 {
690         return isl_basic_map_alloc_equality((struct isl_basic_map *)bset);
691 }
692
693 int isl_basic_map_free_equality(struct isl_basic_map *bmap, unsigned n)
694 {
695         if (!bmap)
696                 return -1;
697         isl_assert(bmap->ctx, n <= bmap->n_eq, return -1);
698         bmap->n_eq -= n;
699         return 0;
700 }
701
702 int isl_basic_set_free_equality(struct isl_basic_set *bset, unsigned n)
703 {
704         return isl_basic_map_free_equality((struct isl_basic_map *)bset, n);
705 }
706
707 int isl_basic_map_drop_equality(struct isl_basic_map *bmap, unsigned pos)
708 {
709         isl_int *t;
710         if (!bmap)
711                 return -1;
712         isl_assert(bmap->ctx, pos < bmap->n_eq, return -1);
713
714         if (pos != bmap->n_eq - 1) {
715                 t = bmap->eq[pos];
716                 bmap->eq[pos] = bmap->eq[bmap->n_eq - 1];
717                 bmap->eq[bmap->n_eq - 1] = t;
718         }
719         bmap->n_eq--;
720         return 0;
721 }
722
723 int isl_basic_set_drop_equality(struct isl_basic_set *bset, unsigned pos)
724 {
725         return isl_basic_map_drop_equality((struct isl_basic_map *)bset, pos);
726 }
727
728 void isl_basic_map_inequality_to_equality(
729                 struct isl_basic_map *bmap, unsigned pos)
730 {
731         isl_int *t;
732
733         t = bmap->ineq[pos];
734         bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
735         bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
736         bmap->eq[-1] = t;
737         bmap->n_eq++;
738         bmap->n_ineq--;
739         bmap->eq--;
740         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
741         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
742         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
743         ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
744 }
745
746 static int room_for_ineq(struct isl_basic_map *bmap, unsigned n)
747 {
748         return bmap->n_ineq + n <= bmap->eq - bmap->ineq;
749 }
750
751 int isl_basic_map_alloc_inequality(struct isl_basic_map *bmap)
752 {
753         struct isl_ctx *ctx;
754         if (!bmap)
755                 return -1;
756         ctx = bmap->ctx;
757         isl_assert(ctx, room_for_ineq(bmap, 1), return -1);
758         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
759         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
760         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
761         ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
762         isl_seq_clr(bmap->ineq[bmap->n_ineq] +
763                       1 + isl_basic_map_total_dim(bmap),
764                       bmap->extra - bmap->n_div);
765         return bmap->n_ineq++;
766 }
767
768 int isl_basic_set_alloc_inequality(struct isl_basic_set *bset)
769 {
770         return isl_basic_map_alloc_inequality((struct isl_basic_map *)bset);
771 }
772
773 int isl_basic_map_free_inequality(struct isl_basic_map *bmap, unsigned n)
774 {
775         if (!bmap)
776                 return -1;
777         isl_assert(bmap->ctx, n <= bmap->n_ineq, return -1);
778         bmap->n_ineq -= n;
779         return 0;
780 }
781
782 int isl_basic_set_free_inequality(struct isl_basic_set *bset, unsigned n)
783 {
784         return isl_basic_map_free_inequality((struct isl_basic_map *)bset, n);
785 }
786
787 int isl_basic_map_drop_inequality(struct isl_basic_map *bmap, unsigned pos)
788 {
789         isl_int *t;
790         if (!bmap)
791                 return -1;
792         isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
793
794         if (pos != bmap->n_ineq - 1) {
795                 t = bmap->ineq[pos];
796                 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
797                 bmap->ineq[bmap->n_ineq - 1] = t;
798                 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
799         }
800         bmap->n_ineq--;
801         return 0;
802 }
803
804 int isl_basic_set_drop_inequality(struct isl_basic_set *bset, unsigned pos)
805 {
806         return isl_basic_map_drop_inequality((struct isl_basic_map *)bset, pos);
807 }
808
809 __isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap,
810         isl_int *eq)
811 {
812         int k;
813
814         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
815         if (!bmap)
816                 return NULL;
817         k = isl_basic_map_alloc_equality(bmap);
818         if (k < 0)
819                 goto error;
820         isl_seq_cpy(bmap->eq[k], eq, 1 + isl_basic_map_total_dim(bmap));
821         return bmap;
822 error:
823         isl_basic_map_free(bmap);
824         return NULL;
825 }
826
827 __isl_give isl_basic_set *isl_basic_set_add_eq(__isl_take isl_basic_set *bset,
828         isl_int *eq)
829 {
830         return (isl_basic_set *)
831                 isl_basic_map_add_eq((isl_basic_map *)bset, eq);
832 }
833
834 __isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap,
835         isl_int *ineq)
836 {
837         int k;
838
839         bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
840         if (!bmap)
841                 return NULL;
842         k = isl_basic_map_alloc_inequality(bmap);
843         if (k < 0)
844                 goto error;
845         isl_seq_cpy(bmap->ineq[k], ineq, 1 + isl_basic_map_total_dim(bmap));
846         return bmap;
847 error:
848         isl_basic_map_free(bmap);
849         return NULL;
850 }
851
852 __isl_give isl_basic_set *isl_basic_set_add_ineq(__isl_take isl_basic_set *bset,
853         isl_int *ineq)
854 {
855         return (isl_basic_set *)
856                 isl_basic_map_add_ineq((isl_basic_map *)bset, ineq);
857 }
858
859 int isl_basic_map_alloc_div(struct isl_basic_map *bmap)
860 {
861         if (!bmap)
862                 return -1;
863         isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1);
864         isl_seq_clr(bmap->div[bmap->n_div] +
865                       1 + 1 + isl_basic_map_total_dim(bmap),
866                       bmap->extra - bmap->n_div);
867         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
868         return bmap->n_div++;
869 }
870
871 int isl_basic_set_alloc_div(struct isl_basic_set *bset)
872 {
873         return isl_basic_map_alloc_div((struct isl_basic_map *)bset);
874 }
875
876 int isl_basic_map_free_div(struct isl_basic_map *bmap, unsigned n)
877 {
878         if (!bmap)
879                 return -1;
880         isl_assert(bmap->ctx, n <= bmap->n_div, return -1);
881         bmap->n_div -= n;
882         return 0;
883 }
884
885 int isl_basic_set_free_div(struct isl_basic_set *bset, unsigned n)
886 {
887         return isl_basic_map_free_div((struct isl_basic_map *)bset, n);
888 }
889
890 /* Copy constraint from src to dst, putting the vars of src at offset
891  * dim_off in dst and the divs of src at offset div_off in dst.
892  * If both sets are actually map, then dim_off applies to the input
893  * variables.
894  */
895 static void copy_constraint(struct isl_basic_map *dst_map, isl_int *dst,
896                             struct isl_basic_map *src_map, isl_int *src,
897                             unsigned in_off, unsigned out_off, unsigned div_off)
898 {
899         unsigned src_nparam = isl_basic_map_n_param(src_map);
900         unsigned dst_nparam = isl_basic_map_n_param(dst_map);
901         unsigned src_in = isl_basic_map_n_in(src_map);
902         unsigned dst_in = isl_basic_map_n_in(dst_map);
903         unsigned src_out = isl_basic_map_n_out(src_map);
904         unsigned dst_out = isl_basic_map_n_out(dst_map);
905         isl_int_set(dst[0], src[0]);
906         isl_seq_cpy(dst+1, src+1, isl_min(dst_nparam, src_nparam));
907         if (dst_nparam > src_nparam)
908                 isl_seq_clr(dst+1+src_nparam,
909                                 dst_nparam - src_nparam);
910         isl_seq_clr(dst+1+dst_nparam, in_off);
911         isl_seq_cpy(dst+1+dst_nparam+in_off,
912                     src+1+src_nparam,
913                     isl_min(dst_in-in_off, src_in));
914         if (dst_in-in_off > src_in)
915                 isl_seq_clr(dst+1+dst_nparam+in_off+src_in,
916                                 dst_in - in_off - src_in);
917         isl_seq_clr(dst+1+dst_nparam+dst_in, out_off);
918         isl_seq_cpy(dst+1+dst_nparam+dst_in+out_off,
919                     src+1+src_nparam+src_in,
920                     isl_min(dst_out-out_off, src_out));
921         if (dst_out-out_off > src_out)
922                 isl_seq_clr(dst+1+dst_nparam+dst_in+out_off+src_out,
923                                 dst_out - out_off - src_out);
924         isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out, div_off);
925         isl_seq_cpy(dst+1+dst_nparam+dst_in+dst_out+div_off,
926                     src+1+src_nparam+src_in+src_out,
927                     isl_min(dst_map->extra-div_off, src_map->n_div));
928         if (dst_map->n_div-div_off > src_map->n_div)
929                 isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out+
930                                 div_off+src_map->n_div,
931                                 dst_map->n_div - div_off - src_map->n_div);
932 }
933
934 static void copy_div(struct isl_basic_map *dst_map, isl_int *dst,
935                      struct isl_basic_map *src_map, isl_int *src,
936                      unsigned in_off, unsigned out_off, unsigned div_off)
937 {
938         isl_int_set(dst[0], src[0]);
939         copy_constraint(dst_map, dst+1, src_map, src+1, in_off, out_off, div_off);
940 }
941
942 static struct isl_basic_map *add_constraints(struct isl_basic_map *bmap1,
943                 struct isl_basic_map *bmap2, unsigned i_pos, unsigned o_pos)
944 {
945         int i;
946         unsigned div_off;
947
948         if (!bmap1 || !bmap2)
949                 goto error;
950
951         div_off = bmap1->n_div;
952
953         for (i = 0; i < bmap2->n_eq; ++i) {
954                 int i1 = isl_basic_map_alloc_equality(bmap1);
955                 if (i1 < 0)
956                         goto error;
957                 copy_constraint(bmap1, bmap1->eq[i1], bmap2, bmap2->eq[i],
958                                 i_pos, o_pos, div_off);
959         }
960
961         for (i = 0; i < bmap2->n_ineq; ++i) {
962                 int i1 = isl_basic_map_alloc_inequality(bmap1);
963                 if (i1 < 0)
964                         goto error;
965                 copy_constraint(bmap1, bmap1->ineq[i1], bmap2, bmap2->ineq[i],
966                                 i_pos, o_pos, div_off);
967         }
968
969         for (i = 0; i < bmap2->n_div; ++i) {
970                 int i1 = isl_basic_map_alloc_div(bmap1);
971                 if (i1 < 0)
972                         goto error;
973                 copy_div(bmap1, bmap1->div[i1], bmap2, bmap2->div[i],
974                          i_pos, o_pos, div_off);
975         }
976
977         isl_basic_map_free(bmap2);
978
979         return bmap1;
980
981 error:
982         isl_basic_map_free(bmap1);
983         isl_basic_map_free(bmap2);
984         return NULL;
985 }
986
987 static void copy_constraint_dim_map(isl_int *dst, isl_int *src,
988                                         struct isl_dim_map *dim_map)
989 {
990         int i;
991
992         for (i = 0; i < dim_map->len; ++i) {
993                 if (dim_map->pos[i] < 0)
994                         isl_int_set_si(dst[i], 0);
995                 else
996                         isl_int_set(dst[i], src[dim_map->pos[i]]);
997         }
998 }
999
1000 static void copy_div_dim_map(isl_int *dst, isl_int *src,
1001                                         struct isl_dim_map *dim_map)
1002 {
1003         isl_int_set(dst[0], src[0]);
1004         copy_constraint_dim_map(dst+1, src+1, dim_map);
1005 }
1006
1007 static struct isl_basic_map *add_constraints_dim_map(struct isl_basic_map *dst,
1008                 struct isl_basic_map *src, struct isl_dim_map *dim_map)
1009 {
1010         int i;
1011
1012         if (!src || !dst || !dim_map)
1013                 goto error;
1014
1015         for (i = 0; i < src->n_eq; ++i) {
1016                 int i1 = isl_basic_map_alloc_equality(dst);
1017                 if (i1 < 0)
1018                         goto error;
1019                 copy_constraint_dim_map(dst->eq[i1], src->eq[i], dim_map);
1020         }
1021
1022         for (i = 0; i < src->n_ineq; ++i) {
1023                 int i1 = isl_basic_map_alloc_inequality(dst);
1024                 if (i1 < 0)
1025                         goto error;
1026                 copy_constraint_dim_map(dst->ineq[i1], src->ineq[i], dim_map);
1027         }
1028
1029         for (i = 0; i < src->n_div; ++i) {
1030                 int i1 = isl_basic_map_alloc_div(dst);
1031                 if (i1 < 0)
1032                         goto error;
1033                 copy_div_dim_map(dst->div[i1], src->div[i], dim_map);
1034         }
1035
1036         free(dim_map);
1037         isl_basic_map_free(src);
1038
1039         return dst;
1040 error:
1041         free(dim_map);
1042         isl_basic_map_free(src);
1043         isl_basic_map_free(dst);
1044         return NULL;
1045 }
1046
1047 struct isl_basic_set *isl_basic_set_add_constraints(struct isl_basic_set *bset1,
1048                 struct isl_basic_set *bset2, unsigned pos)
1049 {
1050         return (struct isl_basic_set *)
1051                 add_constraints((struct isl_basic_map *)bset1,
1052                                 (struct isl_basic_map *)bset2, 0, pos);
1053 }
1054
1055 struct isl_basic_map *isl_basic_map_extend_dim(struct isl_basic_map *base,
1056                 struct isl_dim *dim, unsigned extra,
1057                 unsigned n_eq, unsigned n_ineq)
1058 {
1059         struct isl_basic_map *ext;
1060         unsigned flags;
1061         int dims_ok;
1062
1063         if (!dim)
1064                 goto error;
1065
1066         if (!base)
1067                 goto error;
1068
1069         dims_ok = isl_dim_equal(base->dim, dim) &&
1070                   base->extra >= base->n_div + extra;
1071
1072         if (dims_ok && room_for_con(base, n_eq + n_ineq) &&
1073                        room_for_ineq(base, n_ineq)) {
1074                 isl_dim_free(dim);
1075                 return base;
1076         }
1077
1078         isl_assert(base->ctx, base->dim->nparam <= dim->nparam, goto error);
1079         isl_assert(base->ctx, base->dim->n_in <= dim->n_in, goto error);
1080         isl_assert(base->ctx, base->dim->n_out <= dim->n_out, goto error);
1081         extra += base->extra;
1082         n_eq += base->n_eq;
1083         n_ineq += base->n_ineq;
1084
1085         ext = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
1086         dim = NULL;
1087         if (!ext)
1088                 goto error;
1089
1090         if (dims_ok)
1091                 ext->sample = isl_vec_copy(base->sample);
1092         flags = base->flags;
1093         ext = add_constraints(ext, base, 0, 0);
1094         if (ext) {
1095                 ext->flags = flags;
1096                 ISL_F_CLR(ext, ISL_BASIC_SET_FINAL);
1097         }
1098
1099         return ext;
1100
1101 error:
1102         isl_dim_free(dim);
1103         isl_basic_map_free(base);
1104         return NULL;
1105 }
1106
1107 struct isl_basic_set *isl_basic_set_extend_dim(struct isl_basic_set *base,
1108                 struct isl_dim *dim, unsigned extra,
1109                 unsigned n_eq, unsigned n_ineq)
1110 {
1111         return (struct isl_basic_set *)
1112                 isl_basic_map_extend_dim((struct isl_basic_map *)base, dim,
1113                                                         extra, n_eq, n_ineq);
1114 }
1115
1116 struct isl_basic_map *isl_basic_map_extend_constraints(
1117                 struct isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
1118 {
1119         if (!base)
1120                 return NULL;
1121         return isl_basic_map_extend_dim(base, isl_dim_copy(base->dim),
1122                                         0, n_eq, n_ineq);
1123 }
1124
1125 struct isl_basic_map *isl_basic_map_extend(struct isl_basic_map *base,
1126                 unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra,
1127                 unsigned n_eq, unsigned n_ineq)
1128 {
1129         struct isl_basic_map *bmap;
1130         struct isl_dim *dim;
1131
1132         if (!base)
1133                 return NULL;
1134         dim = isl_dim_alloc(base->ctx, nparam, n_in, n_out);
1135         if (!dim)
1136                 goto error;
1137
1138         bmap = isl_basic_map_extend_dim(base, dim, extra, n_eq, n_ineq);
1139         return bmap;
1140 error:
1141         isl_basic_map_free(base);
1142         return NULL;
1143 }
1144
1145 struct isl_basic_set *isl_basic_set_extend(struct isl_basic_set *base,
1146                 unsigned nparam, unsigned dim, unsigned extra,
1147                 unsigned n_eq, unsigned n_ineq)
1148 {
1149         return (struct isl_basic_set *)
1150                 isl_basic_map_extend((struct isl_basic_map *)base,
1151                                         nparam, 0, dim, extra, n_eq, n_ineq);
1152 }
1153
1154 struct isl_basic_set *isl_basic_set_extend_constraints(
1155                 struct isl_basic_set *base, unsigned n_eq, unsigned n_ineq)
1156 {
1157         return (struct isl_basic_set *)
1158                 isl_basic_map_extend_constraints((struct isl_basic_map *)base,
1159                                                     n_eq, n_ineq);
1160 }
1161
1162 struct isl_basic_set *isl_basic_set_cow(struct isl_basic_set *bset)
1163 {
1164         return (struct isl_basic_set *)
1165                 isl_basic_map_cow((struct isl_basic_map *)bset);
1166 }
1167
1168 struct isl_basic_map *isl_basic_map_cow(struct isl_basic_map *bmap)
1169 {
1170         if (!bmap)
1171                 return NULL;
1172
1173         if (bmap->ref > 1) {
1174                 bmap->ref--;
1175                 bmap = isl_basic_map_dup(bmap);
1176         }
1177         if (bmap)
1178                 ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL);
1179         return bmap;
1180 }
1181
1182 struct isl_set *isl_set_cow(struct isl_set *set)
1183 {
1184         if (!set)
1185                 return NULL;
1186
1187         if (set->ref == 1)
1188                 return set;
1189         set->ref--;
1190         return isl_set_dup(set);
1191 }
1192
1193 struct isl_map *isl_map_cow(struct isl_map *map)
1194 {
1195         if (!map)
1196                 return NULL;
1197
1198         if (map->ref == 1)
1199                 return map;
1200         map->ref--;
1201         return isl_map_dup(map);
1202 }
1203
1204 static void swap_vars(struct isl_blk blk, isl_int *a,
1205                         unsigned a_len, unsigned b_len)
1206 {
1207         isl_seq_cpy(blk.data, a+a_len, b_len);
1208         isl_seq_cpy(blk.data+b_len, a, a_len);
1209         isl_seq_cpy(a, blk.data, b_len+a_len);
1210 }
1211
1212 struct isl_basic_set *isl_basic_set_swap_vars(
1213                 struct isl_basic_set *bset, unsigned n)
1214 {
1215         int i;
1216         struct isl_blk blk;
1217         unsigned dim;
1218         unsigned nparam;
1219
1220         if (!bset)
1221                 goto error;
1222
1223         nparam = isl_basic_set_n_param(bset);
1224         dim = isl_basic_set_n_dim(bset);
1225         isl_assert(bset->ctx, n <= dim, goto error);
1226
1227         if (n == dim)
1228                 return bset;
1229
1230         bset = isl_basic_set_cow(bset);
1231         if (!bset)
1232                 return NULL;
1233
1234         blk = isl_blk_alloc(bset->ctx, dim);
1235         if (isl_blk_is_error(blk))
1236                 goto error;
1237
1238         for (i = 0; i < bset->n_eq; ++i)
1239                 swap_vars(blk,
1240                           bset->eq[i]+1+nparam, n, dim - n);
1241
1242         for (i = 0; i < bset->n_ineq; ++i)
1243                 swap_vars(blk,
1244                           bset->ineq[i]+1+nparam, n, dim - n);
1245
1246         for (i = 0; i < bset->n_div; ++i)
1247                 swap_vars(blk,
1248                           bset->div[i]+1+1+nparam, n, dim - n);
1249
1250         isl_blk_free(bset->ctx, blk);
1251
1252         ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED);
1253         bset = isl_basic_set_gauss(bset, NULL);
1254         return isl_basic_set_finalize(bset);
1255 error:
1256         isl_basic_set_free(bset);
1257         return NULL;
1258 }
1259
1260 struct isl_set *isl_set_swap_vars(struct isl_set *set, unsigned n)
1261 {
1262         int i;
1263         set = isl_set_cow(set);
1264         if (!set)
1265                 return NULL;
1266
1267         for (i = 0; i < set->n; ++i) {
1268                 set->p[i] = isl_basic_set_swap_vars(set->p[i], n);
1269                 if (!set->p[i]) {
1270                         isl_set_free(set);
1271                         return NULL;
1272                 }
1273         }
1274         ISL_F_CLR(set, ISL_SET_NORMALIZED);
1275         return set;
1276 }
1277
1278 struct isl_basic_map *isl_basic_map_set_to_empty(struct isl_basic_map *bmap)
1279 {
1280         int i = 0;
1281         unsigned total;
1282         if (!bmap)
1283                 goto error;
1284         total = isl_basic_map_total_dim(bmap);
1285         isl_basic_map_free_div(bmap, bmap->n_div);
1286         isl_basic_map_free_inequality(bmap, bmap->n_ineq);
1287         if (bmap->n_eq > 0)
1288                 isl_basic_map_free_equality(bmap, bmap->n_eq-1);
1289         else {
1290                 i = isl_basic_map_alloc_equality(bmap);
1291                 if (i < 0)
1292                         goto error;
1293         }
1294         isl_int_set_si(bmap->eq[i][0], 1);
1295         isl_seq_clr(bmap->eq[i]+1, total);
1296         ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
1297         isl_vec_free(bmap->sample);
1298         bmap->sample = NULL;
1299         return isl_basic_map_finalize(bmap);
1300 error:
1301         isl_basic_map_free(bmap);
1302         return NULL;
1303 }
1304
1305 struct isl_basic_set *isl_basic_set_set_to_empty(struct isl_basic_set *bset)
1306 {
1307         return (struct isl_basic_set *)
1308                 isl_basic_map_set_to_empty((struct isl_basic_map *)bset);
1309 }
1310
1311 void isl_basic_map_swap_div(struct isl_basic_map *bmap, int a, int b)
1312 {
1313         int i;
1314         unsigned off = isl_dim_total(bmap->dim);
1315         isl_int *t = bmap->div[a];
1316         bmap->div[a] = bmap->div[b];
1317         bmap->div[b] = t;
1318
1319         for (i = 0; i < bmap->n_eq; ++i)
1320                 isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]);
1321
1322         for (i = 0; i < bmap->n_ineq; ++i)
1323                 isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]);
1324
1325         for (i = 0; i < bmap->n_div; ++i)
1326                 isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]);
1327         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1328 }
1329
1330 /* Eliminate the specified n dimensions starting at first from the
1331  * constraints using Fourier-Motzkin.  The dimensions themselves
1332  * are not removed.
1333  */
1334 __isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
1335         enum isl_dim_type type, unsigned first, unsigned n)
1336 {
1337         int i;
1338
1339         if (!map)
1340                 return NULL;
1341         if (n == 0)
1342                 return map;
1343
1344         map = isl_map_cow(map);
1345         if (!map)
1346                 return NULL;
1347         isl_assert(map->ctx, first + n <= isl_map_dim(map, type), goto error);
1348         first += pos(map->dim, type) - 1;
1349         
1350         for (i = 0; i < map->n; ++i) {
1351                 map->p[i] = isl_basic_map_eliminate_vars(map->p[i], first, n);
1352                 if (!map->p[i])
1353                         goto error;
1354         }
1355         return map;
1356 error:
1357         isl_map_free(map);
1358         return NULL;
1359 }
1360
1361 /* Eliminate the specified n dimensions starting at first from the
1362  * constraints using Fourier-Motzkin.  The dimensions themselves
1363  * are not removed.
1364  */
1365 __isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set,
1366         enum isl_dim_type type, unsigned first, unsigned n)
1367 {
1368         return (isl_set *)isl_map_eliminate((isl_map *)set, type, first, n);
1369 }
1370
1371 /* Eliminate the specified n dimensions starting at first from the
1372  * constraints using Fourier-Motzkin.  The dimensions themselves
1373  * are not removed.
1374  */
1375 __isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set,
1376         unsigned first, unsigned n)
1377 {
1378         return isl_set_eliminate(set, isl_dim_set, first, n);
1379 }
1380
1381 /* Project out n dimensions starting at first using Fourier-Motzkin */
1382 struct isl_set *isl_set_remove_dims(struct isl_set *set,
1383         unsigned first, unsigned n)
1384 {
1385         set = isl_set_eliminate_dims(set, first, n);
1386         set = isl_set_drop_dims(set, first, n);
1387         return set;
1388 }
1389
1390 __isl_give isl_basic_map *isl_basic_map_remove_divs(
1391         __isl_take isl_basic_map *bmap)
1392 {
1393         bmap = isl_basic_map_eliminate_vars(bmap, isl_dim_total(bmap->dim),
1394                                                 bmap->n_div);
1395         if (!bmap)
1396                 return NULL;
1397         bmap->n_div = 0;
1398         return bmap;
1399 }
1400
1401 __isl_give isl_basic_set *isl_basic_set_remove_divs(
1402         __isl_take isl_basic_set *bset)
1403 {
1404         return (struct isl_basic_set *)isl_basic_map_remove_divs(
1405                         (struct isl_basic_map *)bset);
1406 }
1407
1408 struct isl_set *isl_set_remove_divs(struct isl_set *set)
1409 {
1410         int i;
1411
1412         if (!set)
1413                 return NULL;
1414         if (set->n == 0)
1415                 return set;
1416
1417         set = isl_set_cow(set);
1418         if (!set)
1419                 return NULL;
1420         
1421         for (i = 0; i < set->n; ++i) {
1422                 set->p[i] = isl_basic_set_remove_divs(set->p[i]);
1423                 if (!set->p[i])
1424                         goto error;
1425         }
1426         return set;
1427 error:
1428         isl_set_free(set);
1429         return NULL;
1430 }
1431
1432 struct isl_basic_map *isl_basic_map_remove(struct isl_basic_map *bmap,
1433         enum isl_dim_type type, unsigned first, unsigned n)
1434 {
1435         if (!bmap)
1436                 return NULL;
1437         isl_assert(bmap->ctx, first + n <= isl_basic_map_dim(bmap, type),
1438                         goto error);
1439         if (n == 0)
1440                 return bmap;
1441         bmap = isl_basic_map_eliminate_vars(bmap,
1442                         isl_basic_map_offset(bmap, type) - 1 + first, n);
1443         if (!bmap)
1444                 return bmap;
1445         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY) && type == isl_dim_div)
1446                 return bmap;
1447         bmap = isl_basic_map_drop(bmap, type, first, n);
1448         return bmap;
1449 error:
1450         isl_basic_map_free(bmap);
1451         return NULL;
1452 }
1453
1454 __isl_give isl_basic_set *isl_basic_set_remove(__isl_take isl_basic_set *bset,
1455         enum isl_dim_type type, unsigned first, unsigned n)
1456 {
1457         return (isl_basic_set *)
1458                 isl_basic_map_remove((isl_basic_map *)bset, type, first, n);
1459 }
1460
1461 struct isl_map *isl_map_remove(struct isl_map *map,
1462         enum isl_dim_type type, unsigned first, unsigned n)
1463 {
1464         int i;
1465
1466         if (n == 0)
1467                 return map;
1468
1469         map = isl_map_cow(map);
1470         if (!map)
1471                 return NULL;
1472         isl_assert(map->ctx, first + n <= isl_map_dim(map, type), goto error);
1473         
1474         for (i = 0; i < map->n; ++i) {
1475                 map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
1476                         isl_basic_map_offset(map->p[i], type) - 1 + first, n);
1477                 if (!map->p[i])
1478                         goto error;
1479         }
1480         map = isl_map_drop(map, type, first, n);
1481         return map;
1482 error:
1483         isl_map_free(map);
1484         return NULL;
1485 }
1486
1487 __isl_give isl_set *isl_set_remove(__isl_take isl_set *bset,
1488         enum isl_dim_type type, unsigned first, unsigned n)
1489 {
1490         return (isl_set *)isl_map_remove((isl_map *)bset, type, first, n);
1491 }
1492
1493 /* Project out n inputs starting at first using Fourier-Motzkin */
1494 struct isl_map *isl_map_remove_inputs(struct isl_map *map,
1495         unsigned first, unsigned n)
1496 {
1497         return isl_map_remove(map, isl_dim_in, first, n);
1498 }
1499
1500 /* Project out n dimensions starting at first using Fourier-Motzkin */
1501 struct isl_basic_set *isl_basic_set_remove_dims(struct isl_basic_set *bset,
1502         unsigned first, unsigned n)
1503 {
1504         unsigned nparam = isl_basic_set_n_param(bset);
1505         bset = isl_basic_set_eliminate_vars(bset, nparam + first, n);
1506         bset = isl_basic_set_drop_dims(bset, first, n);
1507         return bset;
1508 }
1509
1510 static void dump_term(struct isl_basic_map *bmap,
1511                         isl_int c, int pos, FILE *out)
1512 {
1513         const char *name;
1514         unsigned in = isl_basic_map_n_in(bmap);
1515         unsigned dim = in + isl_basic_map_n_out(bmap);
1516         unsigned nparam = isl_basic_map_n_param(bmap);
1517         if (!pos)
1518                 isl_int_print(out, c, 0);
1519         else {
1520                 if (!isl_int_is_one(c))
1521                         isl_int_print(out, c, 0);
1522                 if (pos < 1 + nparam) {
1523                         name = isl_dim_get_name(bmap->dim,
1524                                                 isl_dim_param, pos - 1);
1525                         if (name)
1526                                 fprintf(out, "%s", name);
1527                         else
1528                                 fprintf(out, "p%d", pos - 1);
1529                 } else if (pos < 1 + nparam + in)
1530                         fprintf(out, "i%d", pos - 1 - nparam);
1531                 else if (pos < 1 + nparam + dim)
1532                         fprintf(out, "o%d", pos - 1 - nparam - in);
1533                 else
1534                         fprintf(out, "e%d", pos - 1 - nparam - dim);
1535         }
1536 }
1537
1538 static void dump_constraint_sign(struct isl_basic_map *bmap, isl_int *c,
1539                                 int sign, FILE *out)
1540 {
1541         int i;
1542         int first;
1543         unsigned len = 1 + isl_basic_map_total_dim(bmap);
1544         isl_int v;
1545
1546         isl_int_init(v);
1547         for (i = 0, first = 1; i < len; ++i) {
1548                 if (isl_int_sgn(c[i]) * sign <= 0)
1549                         continue;
1550                 if (!first)
1551                         fprintf(out, " + ");
1552                 first = 0;
1553                 isl_int_abs(v, c[i]);
1554                 dump_term(bmap, v, i, out);
1555         }
1556         isl_int_clear(v);
1557         if (first)
1558                 fprintf(out, "0");
1559 }
1560
1561 static void dump_constraint(struct isl_basic_map *bmap, isl_int *c,
1562                                 const char *op, FILE *out, int indent)
1563 {
1564         int i;
1565
1566         fprintf(out, "%*s", indent, "");
1567
1568         dump_constraint_sign(bmap, c, 1, out);
1569         fprintf(out, " %s ", op);
1570         dump_constraint_sign(bmap, c, -1, out);
1571
1572         fprintf(out, "\n");
1573
1574         for (i = bmap->n_div; i < bmap->extra; ++i) {
1575                 if (isl_int_is_zero(c[1+isl_dim_total(bmap->dim)+i]))
1576                         continue;
1577                 fprintf(out, "%*s", indent, "");
1578                 fprintf(out, "ERROR: unused div coefficient not zero\n");
1579                 abort();
1580         }
1581 }
1582
1583 static void dump_constraints(struct isl_basic_map *bmap,
1584                                 isl_int **c, unsigned n,
1585                                 const char *op, FILE *out, int indent)
1586 {
1587         int i;
1588
1589         for (i = 0; i < n; ++i)
1590                 dump_constraint(bmap, c[i], op, out, indent);
1591 }
1592
1593 static void dump_affine(struct isl_basic_map *bmap, isl_int *exp, FILE *out)
1594 {
1595         int j;
1596         int first = 1;
1597         unsigned total = isl_basic_map_total_dim(bmap);
1598
1599         for (j = 0; j < 1 + total; ++j) {
1600                 if (isl_int_is_zero(exp[j]))
1601                         continue;
1602                 if (!first && isl_int_is_pos(exp[j]))
1603                         fprintf(out, "+");
1604                 dump_term(bmap, exp[j], j, out);
1605                 first = 0;
1606         }
1607 }
1608
1609 static void dump(struct isl_basic_map *bmap, FILE *out, int indent)
1610 {
1611         int i;
1612
1613         dump_constraints(bmap, bmap->eq, bmap->n_eq, "=", out, indent);
1614         dump_constraints(bmap, bmap->ineq, bmap->n_ineq, ">=", out, indent);
1615
1616         for (i = 0; i < bmap->n_div; ++i) {
1617                 fprintf(out, "%*s", indent, "");
1618                 fprintf(out, "e%d = [(", i);
1619                 dump_affine(bmap, bmap->div[i]+1, out);
1620                 fprintf(out, ")/");
1621                 isl_int_print(out, bmap->div[i][0], 0);
1622                 fprintf(out, "]\n");
1623         }
1624 }
1625
1626 void isl_basic_set_dump(struct isl_basic_set *bset, FILE *out, int indent)
1627 {
1628         if (!bset) {
1629                 fprintf(out, "null basic set\n");
1630                 return;
1631         }
1632
1633         fprintf(out, "%*s", indent, "");
1634         fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
1635                         bset->ref, bset->dim->nparam, bset->dim->n_out,
1636                         bset->extra, bset->flags);
1637         dump((struct isl_basic_map *)bset, out, indent);
1638 }
1639
1640 void isl_basic_map_dump(struct isl_basic_map *bmap, FILE *out, int indent)
1641 {
1642         if (!bmap) {
1643                 fprintf(out, "null basic map\n");
1644                 return;
1645         }
1646
1647         fprintf(out, "%*s", indent, "");
1648         fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
1649                         "flags: %x, n_name: %d\n",
1650                 bmap->ref,
1651                 bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
1652                 bmap->extra, bmap->flags, bmap->dim->n_name);
1653         dump(bmap, out, indent);
1654 }
1655
1656 int isl_inequality_negate(struct isl_basic_map *bmap, unsigned pos)
1657 {
1658         unsigned total;
1659         if (!bmap)
1660                 return -1;
1661         total = isl_basic_map_total_dim(bmap);
1662         isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
1663         isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
1664         isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1);
1665         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1666         return 0;
1667 }
1668
1669 struct isl_set *isl_set_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
1670 {
1671         struct isl_set *set;
1672
1673         if (!dim)
1674                 return NULL;
1675         isl_assert(dim->ctx, dim->n_in == 0, return NULL);
1676         isl_assert(dim->ctx, n >= 0, return NULL);
1677         set = isl_alloc(dim->ctx, struct isl_set,
1678                         sizeof(struct isl_set) +
1679                         (n - 1) * sizeof(struct isl_basic_set *));
1680         if (!set)
1681                 goto error;
1682
1683         set->ctx = dim->ctx;
1684         isl_ctx_ref(set->ctx);
1685         set->ref = 1;
1686         set->size = n;
1687         set->n = 0;
1688         set->dim = dim;
1689         set->flags = flags;
1690         return set;
1691 error:
1692         isl_dim_free(dim);
1693         return NULL;
1694 }
1695
1696 struct isl_set *isl_set_alloc(struct isl_ctx *ctx,
1697                 unsigned nparam, unsigned dim, int n, unsigned flags)
1698 {
1699         struct isl_set *set;
1700         struct isl_dim *dims;
1701
1702         dims = isl_dim_alloc(ctx, nparam, 0, dim);
1703         if (!dims)
1704                 return NULL;
1705
1706         set = isl_set_alloc_dim(dims, n, flags);
1707         return set;
1708 }
1709
1710 /* Make sure "map" has room for at least "n" more basic maps.
1711  */
1712 struct isl_map *isl_map_grow(struct isl_map *map, int n)
1713 {
1714         int i;
1715         struct isl_map *grown = NULL;
1716
1717         if (!map)
1718                 return NULL;
1719         isl_assert(map->ctx, n >= 0, goto error);
1720         if (map->n + n <= map->size)
1721                 return map;
1722         grown = isl_map_alloc_dim(isl_map_get_dim(map), map->n + n, map->flags);
1723         if (!grown)
1724                 goto error;
1725         for (i = 0; i < map->n; ++i) {
1726                 grown->p[i] = isl_basic_map_copy(map->p[i]);
1727                 if (!grown->p[i])
1728                         goto error;
1729                 grown->n++;
1730         }
1731         isl_map_free(map);
1732         return grown;
1733 error:
1734         isl_map_free(grown);
1735         isl_map_free(map);
1736         return NULL;
1737 }
1738
1739 /* Make sure "set" has room for at least "n" more basic sets.
1740  */
1741 struct isl_set *isl_set_grow(struct isl_set *set, int n)
1742 {
1743         return (struct isl_set *)isl_map_grow((struct isl_map *)set, n);
1744 }
1745
1746 struct isl_set *isl_set_dup(struct isl_set *set)
1747 {
1748         int i;
1749         struct isl_set *dup;
1750
1751         if (!set)
1752                 return NULL;
1753
1754         dup = isl_set_alloc_dim(isl_dim_copy(set->dim), set->n, set->flags);
1755         if (!dup)
1756                 return NULL;
1757         for (i = 0; i < set->n; ++i)
1758                 dup = isl_set_add_basic_set(dup, isl_basic_set_copy(set->p[i]));
1759         return dup;
1760 }
1761
1762 struct isl_set *isl_set_from_basic_set(struct isl_basic_set *bset)
1763 {
1764         struct isl_set *set;
1765
1766         if (!bset)
1767                 return NULL;
1768
1769         set = isl_set_alloc_dim(isl_dim_copy(bset->dim), 1, ISL_MAP_DISJOINT);
1770         if (!set) {
1771                 isl_basic_set_free(bset);
1772                 return NULL;
1773         }
1774         return isl_set_add_basic_set(set, bset);
1775 }
1776
1777 struct isl_map *isl_map_from_basic_map(struct isl_basic_map *bmap)
1778 {
1779         struct isl_map *map;
1780
1781         if (!bmap)
1782                 return NULL;
1783
1784         map = isl_map_alloc_dim(isl_dim_copy(bmap->dim), 1, ISL_MAP_DISJOINT);
1785         if (!map) {
1786                 isl_basic_map_free(bmap);
1787                 return NULL;
1788         }
1789         return isl_map_add_basic_map(map, bmap);
1790 }
1791
1792 __isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set,
1793                                                 __isl_take isl_basic_set *bset)
1794 {
1795         return (struct isl_set *)isl_map_add_basic_map((struct isl_map *)set,
1796                                                 (struct isl_basic_map *)bset);
1797 }
1798
1799 void isl_set_free(struct isl_set *set)
1800 {
1801         int i;
1802
1803         if (!set)
1804                 return;
1805
1806         if (--set->ref > 0)
1807                 return;
1808
1809         isl_ctx_deref(set->ctx);
1810         for (i = 0; i < set->n; ++i)
1811                 isl_basic_set_free(set->p[i]);
1812         isl_dim_free(set->dim);
1813         free(set);
1814 }
1815
1816 void isl_set_dump(struct isl_set *set, FILE *out, int indent)
1817 {
1818         int i;
1819
1820         if (!set) {
1821                 fprintf(out, "null set\n");
1822                 return;
1823         }
1824
1825         fprintf(out, "%*s", indent, "");
1826         fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
1827                         set->ref, set->n, set->dim->nparam, set->dim->n_out,
1828                         set->flags);
1829         for (i = 0; i < set->n; ++i) {
1830                 fprintf(out, "%*s", indent, "");
1831                 fprintf(out, "basic set %d:\n", i);
1832                 isl_basic_set_dump(set->p[i], out, indent+4);
1833         }
1834 }
1835
1836 void isl_map_dump(struct isl_map *map, FILE *out, int indent)
1837 {
1838         int i;
1839
1840         if (!map) {
1841                 fprintf(out, "null map\n");
1842                 return;
1843         }
1844
1845         fprintf(out, "%*s", indent, "");
1846         fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
1847                      "flags: %x, n_name: %d\n",
1848                         map->ref, map->n, map->dim->nparam, map->dim->n_in,
1849                         map->dim->n_out, map->flags, map->dim->n_name);
1850         for (i = 0; i < map->n; ++i) {
1851                 fprintf(out, "%*s", indent, "");
1852                 fprintf(out, "basic map %d:\n", i);
1853                 isl_basic_map_dump(map->p[i], out, indent+4);
1854         }
1855 }
1856
1857 struct isl_basic_map *isl_basic_map_intersect_domain(
1858                 struct isl_basic_map *bmap, struct isl_basic_set *bset)
1859 {
1860         struct isl_basic_map *bmap_domain;
1861         struct isl_dim *dim;
1862
1863         if (!bmap || !bset)
1864                 goto error;
1865
1866         isl_assert(bset->ctx, isl_dim_match(bmap->dim, isl_dim_param,
1867                                         bset->dim, isl_dim_param), goto error);
1868
1869         if (isl_dim_size(bset->dim, isl_dim_set) != 0)
1870                 isl_assert(bset->ctx,
1871                     isl_basic_map_compatible_domain(bmap, bset), goto error);
1872
1873         bmap = isl_basic_map_cow(bmap);
1874         if (!bmap)
1875                 goto error;
1876         bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
1877                         bset->n_div, bset->n_eq, bset->n_ineq);
1878         dim = isl_dim_reverse(isl_dim_copy(bset->dim));
1879         bmap_domain = isl_basic_map_from_basic_set(bset, dim);
1880         bmap = add_constraints(bmap, bmap_domain, 0, 0);
1881
1882         bmap = isl_basic_map_simplify(bmap);
1883         return isl_basic_map_finalize(bmap);
1884 error:
1885         isl_basic_map_free(bmap);
1886         isl_basic_set_free(bset);
1887         return NULL;
1888 }
1889
1890 struct isl_basic_map *isl_basic_map_intersect_range(
1891                 struct isl_basic_map *bmap, struct isl_basic_set *bset)
1892 {
1893         struct isl_basic_map *bmap_range;
1894
1895         if (!bmap || !bset)
1896                 goto error;
1897
1898         isl_assert(bset->ctx, isl_dim_match(bmap->dim, isl_dim_param,
1899                                         bset->dim, isl_dim_param), goto error);
1900
1901         if (isl_dim_size(bset->dim, isl_dim_set) != 0)
1902                 isl_assert(bset->ctx,
1903                     isl_basic_map_compatible_range(bmap, bset), goto error);
1904
1905         bmap = isl_basic_map_cow(bmap);
1906         if (!bmap)
1907                 goto error;
1908         bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
1909                         bset->n_div, bset->n_eq, bset->n_ineq);
1910         bmap_range = isl_basic_map_from_basic_set(bset, isl_dim_copy(bset->dim));
1911         bmap = add_constraints(bmap, bmap_range, 0, 0);
1912
1913         bmap = isl_basic_map_simplify(bmap);
1914         return isl_basic_map_finalize(bmap);
1915 error:
1916         isl_basic_map_free(bmap);
1917         isl_basic_set_free(bset);
1918         return NULL;
1919 }
1920
1921 int isl_basic_map_contains(struct isl_basic_map *bmap, struct isl_vec *vec)
1922 {
1923         int i;
1924         unsigned total;
1925         isl_int s;
1926
1927         total = 1 + isl_basic_map_total_dim(bmap);
1928         if (total != vec->size)
1929                 return -1;
1930
1931         isl_int_init(s);
1932
1933         for (i = 0; i < bmap->n_eq; ++i) {
1934                 isl_seq_inner_product(vec->el, bmap->eq[i], total, &s);
1935                 if (!isl_int_is_zero(s)) {
1936                         isl_int_clear(s);
1937                         return 0;
1938                 }
1939         }
1940
1941         for (i = 0; i < bmap->n_ineq; ++i) {
1942                 isl_seq_inner_product(vec->el, bmap->ineq[i], total, &s);
1943                 if (isl_int_is_neg(s)) {
1944                         isl_int_clear(s);
1945                         return 0;
1946                 }
1947         }
1948
1949         isl_int_clear(s);
1950
1951         return 1;
1952 }
1953
1954 int isl_basic_set_contains(struct isl_basic_set *bset, struct isl_vec *vec)
1955 {
1956         return isl_basic_map_contains((struct isl_basic_map *)bset, vec);
1957 }
1958
1959 struct isl_basic_map *isl_basic_map_intersect(
1960                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
1961 {
1962         struct isl_vec *sample = NULL;
1963
1964         if (!bmap1 || !bmap2)
1965                 goto error;
1966
1967         isl_assert(bmap1->ctx, isl_dim_match(bmap1->dim, isl_dim_param,
1968                                      bmap2->dim, isl_dim_param), goto error);
1969         if (isl_dim_total(bmap1->dim) ==
1970                                 isl_dim_size(bmap1->dim, isl_dim_param) &&
1971             isl_dim_total(bmap2->dim) !=
1972                                 isl_dim_size(bmap2->dim, isl_dim_param))
1973                 return isl_basic_map_intersect(bmap2, bmap1);
1974
1975         if (isl_dim_total(bmap2->dim) !=
1976                                         isl_dim_size(bmap2->dim, isl_dim_param))
1977                 isl_assert(bmap1->ctx,
1978                             isl_dim_equal(bmap1->dim, bmap2->dim), goto error);
1979
1980         if (bmap1->sample &&
1981             isl_basic_map_contains(bmap1, bmap1->sample) > 0 &&
1982             isl_basic_map_contains(bmap2, bmap1->sample) > 0)
1983                 sample = isl_vec_copy(bmap1->sample);
1984         else if (bmap2->sample &&
1985             isl_basic_map_contains(bmap1, bmap2->sample) > 0 &&
1986             isl_basic_map_contains(bmap2, bmap2->sample) > 0)
1987                 sample = isl_vec_copy(bmap2->sample);
1988
1989         bmap1 = isl_basic_map_cow(bmap1);
1990         if (!bmap1)
1991                 goto error;
1992         bmap1 = isl_basic_map_extend_dim(bmap1, isl_dim_copy(bmap1->dim),
1993                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
1994         bmap1 = add_constraints(bmap1, bmap2, 0, 0);
1995
1996         if (!bmap1)
1997                 isl_vec_free(sample);
1998         else if (sample) {
1999                 isl_vec_free(bmap1->sample);
2000                 bmap1->sample = sample;
2001         }
2002
2003         bmap1 = isl_basic_map_simplify(bmap1);
2004         return isl_basic_map_finalize(bmap1);
2005 error:
2006         if (sample)
2007                 isl_vec_free(sample);
2008         isl_basic_map_free(bmap1);
2009         isl_basic_map_free(bmap2);
2010         return NULL;
2011 }
2012
2013 struct isl_basic_set *isl_basic_set_intersect(
2014                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
2015 {
2016         return (struct isl_basic_set *)
2017                 isl_basic_map_intersect(
2018                         (struct isl_basic_map *)bset1,
2019                         (struct isl_basic_map *)bset2);
2020 }
2021
2022 /* Special case of isl_map_intersect, where both map1 and map2
2023  * are convex, without any divs and such that either map1 or map2
2024  * contains a single constraint.  This constraint is then simply
2025  * added to the other map.
2026  */
2027 static __isl_give isl_map *map_intersect_add_constraint(
2028         __isl_take isl_map *map1, __isl_take isl_map *map2)
2029 {
2030         struct isl_basic_map *bmap1;
2031         struct isl_basic_map *bmap2;
2032
2033         isl_assert(map1->ctx, map1->n == 1, goto error);
2034         isl_assert(map2->ctx, map1->n == 1, goto error);
2035         isl_assert(map1->ctx, map1->p[0]->n_div == 0, goto error);
2036         isl_assert(map2->ctx, map1->p[0]->n_div == 0, goto error);
2037
2038         if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
2039                 return isl_map_intersect(map2, map1);
2040
2041         isl_assert(map2->ctx,
2042                     map2->p[0]->n_eq + map2->p[0]->n_ineq == 1, goto error);
2043
2044         map1 = isl_map_cow(map1);
2045         if (!map1)
2046                 goto error;
2047         if (isl_map_fast_is_empty(map1)) {
2048                 isl_map_free(map2);
2049                 return map1;
2050         }
2051         map1->p[0] = isl_basic_map_cow(map1->p[0]);
2052         if (map2->p[0]->n_eq == 1)
2053                 map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]);
2054         else
2055                 map1->p[0] = isl_basic_map_add_ineq(map1->p[0],
2056                                                         map2->p[0]->ineq[0]);
2057
2058         map1->p[0] = isl_basic_map_simplify(map1->p[0]);
2059         map1->p[0] = isl_basic_map_finalize(map1->p[0]);
2060         if (!map1->p[0])
2061                 goto error;
2062
2063         if (isl_basic_map_fast_is_empty(map1->p[0])) {
2064                 isl_basic_map_free(map1->p[0]);
2065                 map1->n = 0;
2066         }
2067
2068         isl_map_free(map2);
2069
2070         return map1;
2071 error:
2072         isl_map_free(map1);
2073         isl_map_free(map2);
2074         return NULL;
2075 }
2076
2077 struct isl_map *isl_map_intersect(struct isl_map *map1, struct isl_map *map2)
2078 {
2079         unsigned flags = 0;
2080         struct isl_map *result;
2081         int i, j;
2082
2083         if (!map1 || !map2)
2084                 goto error;
2085
2086         if (isl_map_fast_is_empty(map1)) {
2087                 isl_map_free(map2);
2088                 return map1;
2089         }
2090         if (isl_map_fast_is_empty(map2)) {
2091                 isl_map_free(map1);
2092                 return map2;
2093         }
2094
2095         if (map1->n == 1 && map2->n == 1 &&
2096             map1->p[0]->n_div == 0 && map2->p[0]->n_div == 0 &&
2097             isl_dim_equal(map1->dim, map2->dim) &&
2098             (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
2099              map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
2100                 return map_intersect_add_constraint(map1, map2);
2101         isl_assert(map1->ctx, isl_dim_match(map1->dim, isl_dim_param,
2102                                          map2->dim, isl_dim_param), goto error);
2103         if (isl_dim_total(map1->dim) ==
2104                                 isl_dim_size(map1->dim, isl_dim_param) &&
2105             isl_dim_total(map2->dim) != isl_dim_size(map2->dim, isl_dim_param))
2106                 return isl_map_intersect(map2, map1);
2107
2108         if (isl_dim_total(map2->dim) != isl_dim_size(map2->dim, isl_dim_param))
2109                 isl_assert(map1->ctx,
2110                             isl_dim_equal(map1->dim, map2->dim), goto error);
2111
2112         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
2113             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
2114                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
2115
2116         result = isl_map_alloc_dim(isl_dim_copy(map1->dim),
2117                                 map1->n * map2->n, flags);
2118         if (!result)
2119                 goto error;
2120         for (i = 0; i < map1->n; ++i)
2121                 for (j = 0; j < map2->n; ++j) {
2122                         struct isl_basic_map *part;
2123                         part = isl_basic_map_intersect(
2124                                     isl_basic_map_copy(map1->p[i]),
2125                                     isl_basic_map_copy(map2->p[j]));
2126                         if (isl_basic_map_is_empty(part))
2127                                 isl_basic_map_free(part);
2128                         else
2129                                 result = isl_map_add_basic_map(result, part);
2130                         if (!result)
2131                                 goto error;
2132                 }
2133         isl_map_free(map1);
2134         isl_map_free(map2);
2135         return result;
2136 error:
2137         isl_map_free(map1);
2138         isl_map_free(map2);
2139         return NULL;
2140 }
2141
2142 struct isl_set *isl_set_intersect(struct isl_set *set1, struct isl_set *set2)
2143 {
2144         return (struct isl_set *)
2145                 isl_map_intersect((struct isl_map *)set1,
2146                                   (struct isl_map *)set2);
2147 }
2148
2149 struct isl_basic_map *isl_basic_map_reverse(struct isl_basic_map *bmap)
2150 {
2151         struct isl_dim *dim;
2152         struct isl_basic_set *bset;
2153         unsigned in;
2154
2155         if (!bmap)
2156                 return NULL;
2157         bmap = isl_basic_map_cow(bmap);
2158         if (!bmap)
2159                 return NULL;
2160         dim = isl_dim_reverse(isl_dim_copy(bmap->dim));
2161         in = isl_basic_map_n_in(bmap);
2162         bset = isl_basic_set_from_basic_map(bmap);
2163         bset = isl_basic_set_swap_vars(bset, in);
2164         return isl_basic_map_from_basic_set(bset, dim);
2165 }
2166
2167 __isl_give isl_basic_map *isl_basic_map_insert(__isl_take isl_basic_map *bmap,
2168                 enum isl_dim_type type, unsigned pos, unsigned n)
2169 {
2170         struct isl_dim *res_dim;
2171         struct isl_basic_map *res;
2172         struct isl_dim_map *dim_map;
2173         unsigned total, off;
2174         enum isl_dim_type t;
2175
2176         if (n == 0)
2177                 return bmap;
2178
2179         if (!bmap)
2180                 return NULL;
2181
2182         res_dim = isl_dim_insert(isl_basic_map_get_dim(bmap), type, pos, n);
2183
2184         total = isl_basic_map_total_dim(bmap) + n;
2185         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2186         off = 0;
2187         for (t = isl_dim_param; t <= isl_dim_out; ++t) {
2188                 if (t != type) {
2189                         isl_dim_map_dim(dim_map, bmap->dim, t, off);
2190                 } else {
2191                         unsigned size = isl_basic_map_dim(bmap, t);
2192                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2193                                                 0, pos, off);
2194                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2195                                                 pos, size - pos, off + pos + n);
2196                 }
2197                 off += isl_dim_size(res_dim, t);
2198         }
2199         isl_dim_map_div(dim_map, bmap, off);
2200
2201         res = isl_basic_map_alloc_dim(res_dim,
2202                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
2203         res = add_constraints_dim_map(res, bmap, dim_map);
2204         res = isl_basic_map_simplify(res);
2205         return isl_basic_map_finalize(res);
2206 }
2207
2208 __isl_give isl_basic_map *isl_basic_map_add(__isl_take isl_basic_map *bmap,
2209                 enum isl_dim_type type, unsigned n)
2210 {
2211         if (!bmap)
2212                 return NULL;
2213         return isl_basic_map_insert(bmap, type,
2214                                         isl_basic_map_dim(bmap, type), n);
2215 }
2216
2217 __isl_give isl_basic_set *isl_basic_set_add(__isl_take isl_basic_set *bset,
2218                 enum isl_dim_type type, unsigned n)
2219 {
2220         if (!bset)
2221                 return NULL;
2222         isl_assert(bset->ctx, type != isl_dim_in, goto error);
2223         return (isl_basic_set *)isl_basic_map_add((isl_basic_map *)bset, type, n);
2224 error:
2225         isl_basic_set_free(bset);
2226         return NULL;
2227 }
2228
2229 __isl_give isl_map *isl_map_insert(__isl_take isl_map *map,
2230                 enum isl_dim_type type, unsigned pos, unsigned n)
2231 {
2232         int i;
2233
2234         if (n == 0)
2235                 return map;
2236
2237         map = isl_map_cow(map);
2238         if (!map)
2239                 return NULL;
2240
2241         map->dim = isl_dim_insert(map->dim, type, pos, n);
2242         if (!map->dim)
2243                 goto error;
2244
2245         for (i = 0; i < map->n; ++i) {
2246                 map->p[i] = isl_basic_map_insert(map->p[i], type, pos, n);
2247                 if (!map->p[i])
2248                         goto error;
2249         }
2250
2251         return map;
2252 error:
2253         isl_map_free(map);
2254         return NULL;
2255 }
2256
2257 __isl_give isl_set *isl_set_insert(__isl_take isl_set *set,
2258                 enum isl_dim_type type, unsigned pos, unsigned n)
2259 {
2260         return (isl_set *)isl_map_insert((isl_map *)set, type, pos, n);
2261 }
2262
2263 __isl_give isl_map *isl_map_add(__isl_take isl_map *map,
2264                 enum isl_dim_type type, unsigned n)
2265 {
2266         if (!map)
2267                 return NULL;
2268         return isl_map_insert(map, type, isl_map_dim(map, type), n);
2269 }
2270
2271 __isl_give isl_set *isl_set_add(__isl_take isl_set *set,
2272                 enum isl_dim_type type, unsigned n)
2273 {
2274         if (!set)
2275                 return NULL;
2276         isl_assert(set->ctx, type != isl_dim_in, goto error);
2277         return (isl_set *)isl_map_add((isl_map *)set, type, n);
2278 error:
2279         isl_set_free(set);
2280         return NULL;
2281 }
2282
2283 __isl_give isl_basic_map *isl_basic_map_move_dims(
2284         __isl_take isl_basic_map *bmap,
2285         enum isl_dim_type dst_type, unsigned dst_pos,
2286         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2287 {
2288         int i;
2289         struct isl_dim_map *dim_map;
2290         struct isl_basic_map *res;
2291         enum isl_dim_type t;
2292         unsigned total, off;
2293
2294         if (!bmap)
2295                 return NULL;
2296         if (n == 0)
2297                 return bmap;
2298
2299         isl_assert(bmap->ctx, src_pos + n <= isl_basic_map_dim(bmap, src_type),
2300                 goto error);
2301
2302         if (dst_type == src_type && dst_pos == src_pos)
2303                 return bmap;
2304
2305         isl_assert(bmap->ctx, dst_type != src_type, goto error);
2306
2307         if (pos(bmap->dim, dst_type) + dst_pos ==
2308             pos(bmap->dim, src_type) + src_pos +
2309                                             ((src_type < dst_type) ? n : 0)) {
2310                 bmap = isl_basic_map_cow(bmap);
2311                 if (!bmap)
2312                         return NULL;
2313
2314                 bmap->dim = isl_dim_move(bmap->dim, dst_type, dst_pos,
2315                                                 src_type, src_pos, n);
2316                 if (!bmap->dim)
2317                         goto error;
2318
2319                 bmap = isl_basic_map_finalize(bmap);
2320
2321                 return bmap;
2322         }
2323
2324         total = isl_basic_map_total_dim(bmap);
2325         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2326
2327         off = 0;
2328         for (t = isl_dim_param; t <= isl_dim_out; ++t) {
2329                 unsigned size = isl_dim_size(bmap->dim, t);
2330                 if (t == dst_type) {
2331                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2332                                             0, dst_pos, off);
2333                         off += dst_pos;
2334                         isl_dim_map_dim_range(dim_map, bmap->dim, src_type,
2335                                             src_pos, n, off);
2336                         off += n;
2337                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2338                                             dst_pos, size - dst_pos, off);
2339                         off += size - dst_pos;
2340                 } else if (t == src_type) {
2341                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2342                                             0, src_pos, off);
2343                         off += src_pos;
2344                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2345                                         src_pos + n, size - src_pos - n, off);
2346                         off += size - src_pos - n;
2347                 } else {
2348                         isl_dim_map_dim(dim_map, bmap->dim, t, off);
2349                         off += size;
2350                 }
2351         }
2352         isl_dim_map_div(dim_map, bmap, off);
2353
2354         res = isl_basic_map_alloc_dim(isl_basic_map_get_dim(bmap),
2355                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
2356         bmap = add_constraints_dim_map(res, bmap, dim_map);
2357
2358         bmap->dim = isl_dim_move(bmap->dim, dst_type, dst_pos,
2359                                         src_type, src_pos, n);
2360         if (!bmap->dim)
2361                 goto error;
2362
2363         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
2364         bmap = isl_basic_map_gauss(bmap, NULL);
2365         bmap = isl_basic_map_finalize(bmap);
2366
2367         return bmap;
2368 error:
2369         isl_basic_map_free(bmap);
2370         return NULL;
2371 }
2372
2373 __isl_give isl_basic_set *isl_basic_set_move_dims(__isl_take isl_basic_set *bset,
2374         enum isl_dim_type dst_type, unsigned dst_pos,
2375         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2376 {
2377         return (isl_basic_set *)isl_basic_map_move_dims(
2378                 (isl_basic_map *)bset, dst_type, dst_pos, src_type, src_pos, n);
2379 }
2380
2381 __isl_give isl_set *isl_set_move_dims(__isl_take isl_set *set,
2382         enum isl_dim_type dst_type, unsigned dst_pos,
2383         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2384 {
2385         if (!set)
2386                 return NULL;
2387         isl_assert(set->ctx, dst_type != isl_dim_in, goto error);
2388         return (isl_set *)isl_map_move_dims((isl_map *)set, dst_type, dst_pos,
2389                                         src_type, src_pos, n);
2390 error:
2391         isl_set_free(set);
2392         return NULL;
2393 }
2394
2395 __isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
2396         enum isl_dim_type dst_type, unsigned dst_pos,
2397         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2398 {
2399         int i;
2400
2401         if (!map)
2402                 return NULL;
2403         if (n == 0)
2404                 return map;
2405
2406         isl_assert(map->ctx, src_pos + n <= isl_map_dim(map, src_type),
2407                 goto error);
2408
2409         if (dst_type == src_type && dst_pos == src_pos)
2410                 return map;
2411
2412         isl_assert(map->ctx, dst_type != src_type, goto error);
2413
2414         map = isl_map_cow(map);
2415         if (!map)
2416                 return NULL;
2417
2418         map->dim = isl_dim_move(map->dim, dst_type, dst_pos, src_type, src_pos, n);
2419         if (!map->dim)
2420                 goto error;
2421
2422         for (i = 0; i < map->n; ++i) {
2423                 map->p[i] = isl_basic_map_move_dims(map->p[i],
2424                                                 dst_type, dst_pos,
2425                                                 src_type, src_pos, n);
2426                 if (!map->p[i])
2427                         goto error;
2428         }
2429
2430         return map;
2431 error:
2432         isl_map_free(map);
2433         return NULL;
2434 }
2435
2436 /* Move the specified dimensions to the last columns right before
2437  * the divs.  Don't change the dimension specification of bmap.
2438  * That's the responsibility of the caller.
2439  */
2440 static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
2441         enum isl_dim_type type, unsigned first, unsigned n)
2442 {
2443         struct isl_dim_map *dim_map;
2444         struct isl_basic_map *res;
2445         enum isl_dim_type t;
2446         unsigned total, off;
2447
2448         if (!bmap)
2449                 return NULL;
2450         if (pos(bmap->dim, type) + first + n == 1 + isl_dim_total(bmap->dim))
2451                 return bmap;
2452
2453         total = isl_basic_map_total_dim(bmap);
2454         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2455
2456         off = 0;
2457         for (t = isl_dim_param; t <= isl_dim_out; ++t) {
2458                 unsigned size = isl_dim_size(bmap->dim, t);
2459                 if (t == type) {
2460                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2461                                             0, first, off);
2462                         off += first;
2463                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2464                                             first, n, total - bmap->n_div - n);
2465                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2466                                             first + n, size - (first + n), off);
2467                         off += size - (first + n);
2468                 } else {
2469                         isl_dim_map_dim(dim_map, bmap->dim, t, off);
2470                         off += size;
2471                 }
2472         }
2473         isl_dim_map_div(dim_map, bmap, off + n);
2474
2475         res = isl_basic_map_alloc_dim(isl_basic_map_get_dim(bmap),
2476                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
2477         res = add_constraints_dim_map(res, bmap, dim_map);
2478         return res;
2479 }
2480
2481 /* Turn the n dimensions of type type, starting at first
2482  * into existentially quantified variables.
2483  */
2484 __isl_give isl_basic_map *isl_basic_map_project_out(
2485                 __isl_take isl_basic_map *bmap,
2486                 enum isl_dim_type type, unsigned first, unsigned n)
2487 {
2488         int i;
2489         size_t row_size;
2490         isl_int **new_div;
2491         isl_int *old;
2492
2493         if (n == 0)
2494                 return bmap;
2495
2496         if (!bmap)
2497                 return NULL;
2498
2499         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
2500                 return isl_basic_map_remove(bmap, type, first, n);
2501
2502         isl_assert(bmap->ctx, first + n <= isl_basic_map_dim(bmap, type),
2503                         goto error);
2504
2505         bmap = move_last(bmap, type, first, n);
2506         bmap = isl_basic_map_cow(bmap);
2507         if (!bmap)
2508                 return NULL;
2509
2510         row_size = 1 + isl_dim_total(bmap->dim) + bmap->extra;
2511         old = bmap->block2.data;
2512         bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
2513                                         (bmap->extra + n) * (1 + row_size));
2514         if (!bmap->block2.data)
2515                 goto error;
2516         new_div = isl_alloc_array(bmap->ctx, isl_int *, bmap->extra + n);
2517         if (!new_div)
2518                 goto error;
2519         for (i = 0; i < n; ++i) {
2520                 new_div[i] = bmap->block2.data +
2521                                 (bmap->extra + i) * (1 + row_size);
2522                 isl_seq_clr(new_div[i], 1 + row_size);
2523         }
2524         for (i = 0; i < bmap->extra; ++i)
2525                 new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
2526         free(bmap->div);
2527         bmap->div = new_div;
2528         bmap->n_div += n;
2529         bmap->extra += n;
2530
2531         bmap->dim = isl_dim_drop(bmap->dim, type, first, n);
2532         if (!bmap->dim)
2533                 goto error;
2534         bmap = isl_basic_map_simplify(bmap);
2535         bmap = isl_basic_map_drop_redundant_divs(bmap);
2536         return isl_basic_map_finalize(bmap);
2537 error:
2538         isl_basic_map_free(bmap);
2539         return NULL;
2540 }
2541
2542 /* Turn the n dimensions of type type, starting at first
2543  * into existentially quantified variables.
2544  */
2545 struct isl_basic_set *isl_basic_set_project_out(struct isl_basic_set *bset,
2546                 enum isl_dim_type type, unsigned first, unsigned n)
2547 {
2548         return (isl_basic_set *)isl_basic_map_project_out(
2549                         (isl_basic_map *)bset, type, first, n);
2550 }
2551
2552 /* Turn the n dimensions of type type, starting at first
2553  * into existentially quantified variables.
2554  */
2555 __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
2556                 enum isl_dim_type type, unsigned first, unsigned n)
2557 {
2558         int i;
2559
2560         if (!map)
2561                 return NULL;
2562
2563         if (n == 0)
2564                 return map;
2565
2566         isl_assert(map->ctx, first + n <= isl_map_dim(map, type), goto error);
2567
2568         map = isl_map_cow(map);
2569         if (!map)
2570                 return NULL;
2571
2572         map->dim = isl_dim_drop(map->dim, type, first, n);
2573         if (!map->dim)
2574                 goto error;
2575
2576         for (i = 0; i < map->n; ++i) {
2577                 map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
2578                 if (!map->p[i])
2579                         goto error;
2580         }
2581
2582         return map;
2583 error:
2584         isl_map_free(map);
2585         return NULL;
2586 }
2587
2588 /* Turn the n dimensions of type type, starting at first
2589  * into existentially quantified variables.
2590  */
2591 __isl_give isl_set *isl_set_project_out(__isl_take isl_set *set,
2592                 enum isl_dim_type type, unsigned first, unsigned n)
2593 {
2594         return (isl_set *)isl_map_project_out((isl_map *)set, type, first, n);
2595 }
2596
2597 static struct isl_basic_map *add_divs(struct isl_basic_map *bmap, unsigned n)
2598 {
2599         int i, j;
2600
2601         for (i = 0; i < n; ++i) {
2602                 j = isl_basic_map_alloc_div(bmap);
2603                 if (j < 0)
2604                         goto error;
2605                 isl_seq_clr(bmap->div[j], 1+1+isl_basic_map_total_dim(bmap));
2606         }
2607         return bmap;
2608 error:
2609         isl_basic_map_free(bmap);
2610         return NULL;
2611 }
2612
2613 struct isl_basic_map *isl_basic_map_apply_range(
2614                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
2615 {
2616         struct isl_dim *dim_result = NULL;
2617         struct isl_basic_map *bmap;
2618         unsigned n_in, n_out, n, nparam, total, pos;
2619         struct isl_dim_map *dim_map1, *dim_map2;
2620
2621         if (!bmap1 || !bmap2)
2622                 goto error;
2623
2624         dim_result = isl_dim_join(isl_dim_copy(bmap1->dim),
2625                                   isl_dim_copy(bmap2->dim));
2626
2627         n_in = isl_basic_map_n_in(bmap1);
2628         n_out = isl_basic_map_n_out(bmap2);
2629         n = isl_basic_map_n_out(bmap1);
2630         nparam = isl_basic_map_n_param(bmap1);
2631
2632         total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
2633         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
2634         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
2635         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
2636         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
2637         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
2638         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
2639         isl_dim_map_div(dim_map1, bmap1, pos += n_out);
2640         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
2641         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
2642         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
2643
2644         bmap = isl_basic_map_alloc_dim(dim_result,
2645                         bmap1->n_div + bmap2->n_div + n,
2646                         bmap1->n_eq + bmap2->n_eq,
2647                         bmap1->n_ineq + bmap2->n_ineq);
2648         bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
2649         bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
2650         bmap = add_divs(bmap, n);
2651         bmap = isl_basic_map_simplify(bmap);
2652         bmap = isl_basic_map_drop_redundant_divs(bmap);
2653         return isl_basic_map_finalize(bmap);
2654 error:
2655         isl_basic_map_free(bmap1);
2656         isl_basic_map_free(bmap2);
2657         return NULL;
2658 }
2659
2660 struct isl_basic_set *isl_basic_set_apply(
2661                 struct isl_basic_set *bset, struct isl_basic_map *bmap)
2662 {
2663         if (!bset || !bmap)
2664                 goto error;
2665
2666         isl_assert(bset->ctx, isl_basic_map_compatible_domain(bmap, bset),
2667                     goto error);
2668
2669         return (struct isl_basic_set *)
2670                 isl_basic_map_apply_range((struct isl_basic_map *)bset, bmap);
2671 error:
2672         isl_basic_set_free(bset);
2673         isl_basic_map_free(bmap);
2674         return NULL;
2675 }
2676
2677 struct isl_basic_map *isl_basic_map_apply_domain(
2678                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
2679 {
2680         if (!bmap1 || !bmap2)
2681                 goto error;
2682
2683         isl_assert(bmap1->ctx,
2684             isl_basic_map_n_in(bmap1) == isl_basic_map_n_in(bmap2), goto error);
2685         isl_assert(bmap1->ctx,
2686             isl_basic_map_n_param(bmap1) == isl_basic_map_n_param(bmap2),
2687             goto error);
2688
2689         bmap1 = isl_basic_map_reverse(bmap1);
2690         bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
2691         return isl_basic_map_reverse(bmap1);
2692 error:
2693         isl_basic_map_free(bmap1);
2694         isl_basic_map_free(bmap2);
2695         return NULL;
2696 }
2697
2698 /* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
2699  * A \cap B -> f(A) + f(B)
2700  */
2701 struct isl_basic_map *isl_basic_map_sum(
2702                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
2703 {
2704         unsigned n_in, n_out, nparam, total, pos;
2705         struct isl_basic_map *bmap = NULL;
2706         struct isl_dim_map *dim_map1, *dim_map2;
2707         int i;
2708
2709         if (!bmap1 || !bmap2)
2710                 goto error;
2711
2712         isl_assert(bmap1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim),
2713                 goto error);
2714
2715         nparam = isl_basic_map_n_param(bmap1);
2716         n_in = isl_basic_map_n_in(bmap1);
2717         n_out = isl_basic_map_n_out(bmap1);
2718
2719         total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
2720         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
2721         dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
2722         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
2723         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
2724         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
2725         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
2726         isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
2727         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
2728         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
2729         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
2730
2731         bmap = isl_basic_map_alloc_dim(isl_dim_copy(bmap1->dim),
2732                         bmap1->n_div + bmap2->n_div + 2 * n_out,
2733                         bmap1->n_eq + bmap2->n_eq + n_out,
2734                         bmap1->n_ineq + bmap2->n_ineq);
2735         for (i = 0; i < n_out; ++i) {
2736                 int j = isl_basic_map_alloc_equality(bmap);
2737                 if (j < 0)
2738                         goto error;
2739                 isl_seq_clr(bmap->eq[j], 1+total);
2740                 isl_int_set_si(bmap->eq[j][1+nparam+n_in+i], -1);
2741                 isl_int_set_si(bmap->eq[j][1+pos+i], 1);
2742                 isl_int_set_si(bmap->eq[j][1+pos-n_out+i], 1);
2743         }
2744         bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
2745         bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
2746         bmap = add_divs(bmap, 2 * n_out);
2747
2748         bmap = isl_basic_map_simplify(bmap);
2749         return isl_basic_map_finalize(bmap);
2750 error:
2751         isl_basic_map_free(bmap);
2752         isl_basic_map_free(bmap1);
2753         isl_basic_map_free(bmap2);
2754         return NULL;
2755 }
2756
2757 /* Given two maps A -> f(A) and B -> g(B), construct a map
2758  * A \cap B -> f(A) + f(B)
2759  */
2760 struct isl_map *isl_map_sum(struct isl_map *map1, struct isl_map *map2)
2761 {
2762         struct isl_map *result;
2763         int i, j;
2764
2765         if (!map1 || !map2)
2766                 goto error;
2767
2768         isl_assert(map1->ctx, isl_dim_equal(map1->dim, map2->dim), goto error);
2769
2770         result = isl_map_alloc_dim(isl_dim_copy(map1->dim),
2771                                 map1->n * map2->n, 0);
2772         if (!result)
2773                 goto error;
2774         for (i = 0; i < map1->n; ++i)
2775                 for (j = 0; j < map2->n; ++j) {
2776                         struct isl_basic_map *part;
2777                         part = isl_basic_map_sum(
2778                                     isl_basic_map_copy(map1->p[i]),
2779                                     isl_basic_map_copy(map2->p[j]));
2780                         if (isl_basic_map_is_empty(part))
2781                                 isl_basic_map_free(part);
2782                         else
2783                                 result = isl_map_add_basic_map(result, part);
2784                         if (!result)
2785                                 goto error;
2786                 }
2787         isl_map_free(map1);
2788         isl_map_free(map2);
2789         return result;
2790 error:
2791         isl_map_free(map1);
2792         isl_map_free(map2);
2793         return NULL;
2794 }
2795
2796 __isl_give isl_set *isl_set_sum(__isl_take isl_set *set1,
2797         __isl_take isl_set *set2)
2798 {
2799         return (isl_set *)isl_map_sum((isl_map *)set1, (isl_map *)set2);
2800 }
2801
2802 /* Given a basic map A -> f(A), construct A -> -f(A).
2803  */
2804 struct isl_basic_map *isl_basic_map_neg(struct isl_basic_map *bmap)
2805 {
2806         int i, j;
2807         unsigned off, n;
2808
2809         bmap = isl_basic_map_cow(bmap);
2810         if (!bmap)
2811                 return NULL;
2812
2813         n = isl_basic_map_dim(bmap, isl_dim_out);
2814         off = isl_basic_map_offset(bmap, isl_dim_out);
2815         for (i = 0; i < bmap->n_eq; ++i)
2816                 for (j = 0; j < n; ++j)
2817                         isl_int_neg(bmap->eq[i][off+j], bmap->eq[i][off+j]);
2818         for (i = 0; i < bmap->n_ineq; ++i)
2819                 for (j = 0; j < n; ++j)
2820                         isl_int_neg(bmap->ineq[i][off+j], bmap->ineq[i][off+j]);
2821         for (i = 0; i < bmap->n_div; ++i)
2822                 for (j = 0; j < n; ++j)
2823                         isl_int_neg(bmap->div[i][1+off+j], bmap->div[i][1+off+j]);
2824         return isl_basic_map_finalize(bmap);
2825 }
2826
2827 /* Given a map A -> f(A), construct A -> -f(A).
2828  */
2829 struct isl_map *isl_map_neg(struct isl_map *map)
2830 {
2831         int i;
2832
2833         map = isl_map_cow(map);
2834         if (!map)
2835                 return NULL;
2836
2837         for (i = 0; i < map->n; ++i) {
2838                 map->p[i] = isl_basic_map_neg(map->p[i]);
2839                 if (!map->p[i])
2840                         goto error;
2841         }
2842
2843         return map;
2844 error:
2845         isl_map_free(map);
2846         return NULL;
2847 }
2848
2849 __isl_give isl_set *isl_set_neg(__isl_take isl_set *set)
2850 {
2851         return (isl_set *)isl_map_neg((isl_map *)set);
2852 }
2853
2854 /* Given a basic map A -> f(A) and an integer d, construct a basic map
2855  * A -> floor(f(A)/d).
2856  */
2857 struct isl_basic_map *isl_basic_map_floordiv(struct isl_basic_map *bmap,
2858                 isl_int d)
2859 {
2860         unsigned n_in, n_out, nparam, total, pos;
2861         struct isl_basic_map *result = NULL;
2862         struct isl_dim_map *dim_map;
2863         int i;
2864
2865         if (!bmap)
2866                 return NULL;
2867
2868         nparam = isl_basic_map_n_param(bmap);
2869         n_in = isl_basic_map_n_in(bmap);
2870         n_out = isl_basic_map_n_out(bmap);
2871
2872         total = nparam + n_in + n_out + bmap->n_div + n_out;
2873         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2874         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
2875         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
2876         isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
2877         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
2878
2879         result = isl_basic_map_alloc_dim(isl_dim_copy(bmap->dim),
2880                         bmap->n_div + n_out,
2881                         bmap->n_eq, bmap->n_ineq + 2 * n_out);
2882         result = add_constraints_dim_map(result, bmap, dim_map);
2883         result = add_divs(result, n_out);
2884         for (i = 0; i < n_out; ++i) {
2885                 int j;
2886                 j = isl_basic_map_alloc_inequality(result);
2887                 if (j < 0)
2888                         goto error;
2889                 isl_seq_clr(result->ineq[j], 1+total);
2890                 isl_int_neg(result->ineq[j][1+nparam+n_in+i], d);
2891                 isl_int_set_si(result->ineq[j][1+pos+i], 1);
2892                 j = isl_basic_map_alloc_inequality(result);
2893                 if (j < 0)
2894                         goto error;
2895                 isl_seq_clr(result->ineq[j], 1+total);
2896                 isl_int_set(result->ineq[j][1+nparam+n_in+i], d);
2897                 isl_int_set_si(result->ineq[j][1+pos+i], -1);
2898                 isl_int_sub_ui(result->ineq[j][0], d, 1);
2899         }
2900
2901         result = isl_basic_map_simplify(result);
2902         return isl_basic_map_finalize(result);
2903 error:
2904         isl_basic_map_free(result);
2905         return NULL;
2906 }
2907
2908 /* Given a map A -> f(A) and an integer d, construct a map
2909  * A -> floor(f(A)/d).
2910  */
2911 struct isl_map *isl_map_floordiv(struct isl_map *map, isl_int d)
2912 {
2913         int i;
2914
2915         map = isl_map_cow(map);
2916         if (!map)
2917                 return NULL;
2918
2919         ISL_F_CLR(map, ISL_MAP_DISJOINT);
2920         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
2921         for (i = 0; i < map->n; ++i) {
2922                 map->p[i] = isl_basic_map_floordiv(map->p[i], d);
2923                 if (!map->p[i])
2924                         goto error;
2925         }
2926
2927         return map;
2928 error:
2929         isl_map_free(map);
2930         return NULL;
2931 }
2932
2933 static struct isl_basic_map *var_equal(struct isl_basic_map *bmap, unsigned pos)
2934 {
2935         int i;
2936         unsigned nparam;
2937         unsigned n_in;
2938
2939         i = isl_basic_map_alloc_equality(bmap);
2940         if (i < 0)
2941                 goto error;
2942         nparam = isl_basic_map_n_param(bmap);
2943         n_in = isl_basic_map_n_in(bmap);
2944         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
2945         isl_int_set_si(bmap->eq[i][1+nparam+pos], -1);
2946         isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1);
2947         return isl_basic_map_finalize(bmap);
2948 error:
2949         isl_basic_map_free(bmap);
2950         return NULL;
2951 }
2952
2953 /* Add a constraints to "bmap" expressing i_pos < o_pos
2954  */
2955 static struct isl_basic_map *var_less(struct isl_basic_map *bmap, unsigned pos)
2956 {
2957         int i;
2958         unsigned nparam;
2959         unsigned n_in;
2960
2961         i = isl_basic_map_alloc_inequality(bmap);
2962         if (i < 0)
2963                 goto error;
2964         nparam = isl_basic_map_n_param(bmap);
2965         n_in = isl_basic_map_n_in(bmap);
2966         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
2967         isl_int_set_si(bmap->ineq[i][0], -1);
2968         isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
2969         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
2970         return isl_basic_map_finalize(bmap);
2971 error:
2972         isl_basic_map_free(bmap);
2973         return NULL;
2974 }
2975
2976 /* Add a constraint to "bmap" expressing i_pos <= o_pos
2977  */
2978 static __isl_give isl_basic_map *var_less_or_equal(
2979         __isl_take isl_basic_map *bmap, unsigned pos)
2980 {
2981         int i;
2982         unsigned nparam;
2983         unsigned n_in;
2984
2985         i = isl_basic_map_alloc_inequality(bmap);
2986         if (i < 0)
2987                 goto error;
2988         nparam = isl_basic_map_n_param(bmap);
2989         n_in = isl_basic_map_n_in(bmap);
2990         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
2991         isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
2992         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
2993         return isl_basic_map_finalize(bmap);
2994 error:
2995         isl_basic_map_free(bmap);
2996         return NULL;
2997 }
2998
2999 /* Add a constraints to "bmap" expressing i_pos > o_pos
3000  */
3001 static struct isl_basic_map *var_more(struct isl_basic_map *bmap, unsigned pos)
3002 {
3003         int i;
3004         unsigned nparam;
3005         unsigned n_in;
3006
3007         i = isl_basic_map_alloc_inequality(bmap);
3008         if (i < 0)
3009                 goto error;
3010         nparam = isl_basic_map_n_param(bmap);
3011         n_in = isl_basic_map_n_in(bmap);
3012         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
3013         isl_int_set_si(bmap->ineq[i][0], -1);
3014         isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
3015         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
3016         return isl_basic_map_finalize(bmap);
3017 error:
3018         isl_basic_map_free(bmap);
3019         return NULL;
3020 }
3021
3022 /* Add a constraint to "bmap" expressing i_pos >= o_pos
3023  */
3024 static __isl_give isl_basic_map *var_more_or_equal(
3025         __isl_take isl_basic_map *bmap, unsigned pos)
3026 {
3027         int i;
3028         unsigned nparam;
3029         unsigned n_in;
3030
3031         i = isl_basic_map_alloc_inequality(bmap);
3032         if (i < 0)
3033                 goto error;
3034         nparam = isl_basic_map_n_param(bmap);
3035         n_in = isl_basic_map_n_in(bmap);
3036         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
3037         isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
3038         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
3039         return isl_basic_map_finalize(bmap);
3040 error:
3041         isl_basic_map_free(bmap);
3042         return NULL;
3043 }
3044
3045 struct isl_basic_map *isl_basic_map_equal(struct isl_dim *dim, unsigned n_equal)
3046 {
3047         int i;
3048         struct isl_basic_map *bmap;
3049         bmap = isl_basic_map_alloc_dim(dim, 0, n_equal, 0);
3050         if (!bmap)
3051                 return NULL;
3052         for (i = 0; i < n_equal && bmap; ++i)
3053                 bmap = var_equal(bmap, i);
3054         return isl_basic_map_finalize(bmap);
3055 }
3056
3057 /* Return a relation on of dimension "dim" expressing i_[0..pos] << o_[0..pos]
3058  */
3059 struct isl_basic_map *isl_basic_map_less_at(struct isl_dim *dim, unsigned pos)
3060 {
3061         int i;
3062         struct isl_basic_map *bmap;
3063         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
3064         if (!bmap)
3065                 return NULL;
3066         for (i = 0; i < pos && bmap; ++i)
3067                 bmap = var_equal(bmap, i);
3068         if (bmap)
3069                 bmap = var_less(bmap, pos);
3070         return isl_basic_map_finalize(bmap);
3071 }
3072
3073 /* Return a relation on of dimension "dim" expressing i_[0..pos] <<= o_[0..pos]
3074  */
3075 __isl_give isl_basic_map *isl_basic_map_less_or_equal_at(
3076         __isl_take isl_dim *dim, unsigned pos)
3077 {
3078         int i;
3079         isl_basic_map *bmap;
3080
3081         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
3082         for (i = 0; i < pos; ++i)
3083                 bmap = var_equal(bmap, i);
3084         bmap = var_less_or_equal(bmap, pos);
3085         return isl_basic_map_finalize(bmap);
3086 }
3087
3088 /* Return a relation on pairs of sets of dimension "dim" expressing i_pos > o_pos
3089  */
3090 struct isl_basic_map *isl_basic_map_more_at(struct isl_dim *dim, unsigned pos)
3091 {
3092         int i;
3093         struct isl_basic_map *bmap;
3094         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
3095         if (!bmap)
3096                 return NULL;
3097         for (i = 0; i < pos && bmap; ++i)
3098                 bmap = var_equal(bmap, i);
3099         if (bmap)
3100                 bmap = var_more(bmap, pos);
3101         return isl_basic_map_finalize(bmap);
3102 }
3103
3104 /* Return a relation on of dimension "dim" expressing i_[0..pos] >>= o_[0..pos]
3105  */
3106 __isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
3107         __isl_take isl_dim *dim, unsigned pos)
3108 {
3109         int i;
3110         isl_basic_map *bmap;
3111
3112         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
3113         for (i = 0; i < pos; ++i)
3114                 bmap = var_equal(bmap, i);
3115         bmap = var_more_or_equal(bmap, pos);
3116         return isl_basic_map_finalize(bmap);
3117 }
3118
3119 static __isl_give isl_map *map_lex_lte_first(__isl_take isl_dim *dims,
3120         unsigned n, int equal)
3121 {
3122         struct isl_map *map;
3123         int i;
3124
3125         if (n == 0 && equal)
3126                 return isl_map_universe(dims);
3127
3128         map = isl_map_alloc_dim(isl_dim_copy(dims), n, ISL_MAP_DISJOINT);
3129
3130         for (i = 0; i + 1 < n; ++i)
3131                 map = isl_map_add_basic_map(map,
3132                                   isl_basic_map_less_at(isl_dim_copy(dims), i));
3133         if (n > 0) {
3134                 if (equal)
3135                         map = isl_map_add_basic_map(map,
3136                               isl_basic_map_less_or_equal_at(dims, n - 1));
3137                 else
3138                         map = isl_map_add_basic_map(map,
3139                               isl_basic_map_less_at(dims, n - 1));
3140         } else
3141                 isl_dim_free(dims);
3142
3143         return map;
3144 }
3145
3146 static __isl_give isl_map *map_lex_lte(__isl_take isl_dim *dims, int equal)
3147 {
3148         if (!dims)
3149                 return NULL;
3150         return map_lex_lte_first(dims, dims->n_out, equal);
3151 }
3152
3153 __isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_dim *dim, unsigned n)
3154 {
3155         return map_lex_lte_first(dim, n, 0);
3156 }
3157
3158 __isl_give isl_map *isl_map_lex_le_first(__isl_take isl_dim *dim, unsigned n)
3159 {
3160         return map_lex_lte_first(dim, n, 1);
3161 }
3162
3163 __isl_give isl_map *isl_map_lex_lt(__isl_take isl_dim *set_dim)
3164 {
3165         return map_lex_lte(isl_dim_map(set_dim), 0);
3166 }
3167
3168 __isl_give isl_map *isl_map_lex_le(__isl_take isl_dim *set_dim)
3169 {
3170         return map_lex_lte(isl_dim_map(set_dim), 1);
3171 }
3172
3173 static __isl_give isl_map *map_lex_gte_first(__isl_take isl_dim *dims,
3174         unsigned n, int equal)
3175 {
3176         struct isl_map *map;
3177         int i;
3178
3179         if (n == 0 && equal)
3180                 return isl_map_universe(dims);
3181
3182         map = isl_map_alloc_dim(isl_dim_copy(dims), n, ISL_MAP_DISJOINT);
3183
3184         for (i = 0; i + 1 < n; ++i)
3185                 map = isl_map_add_basic_map(map,
3186                                   isl_basic_map_more_at(isl_dim_copy(dims), i));
3187         if (n > 0) {
3188                 if (equal)
3189                         map = isl_map_add_basic_map(map,
3190                               isl_basic_map_more_or_equal_at(dims, n - 1));
3191                 else
3192                         map = isl_map_add_basic_map(map,
3193                               isl_basic_map_more_at(dims, n - 1));
3194         } else
3195                 isl_dim_free(dims);
3196
3197         return map;
3198 }
3199
3200 static __isl_give isl_map *map_lex_gte(__isl_take isl_dim *dims, int equal)
3201 {
3202         if (!dims)
3203                 return NULL;
3204         return map_lex_gte_first(dims, dims->n_out, equal);
3205 }
3206
3207 __isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_dim *dim, unsigned n)
3208 {
3209         return map_lex_gte_first(dim, n, 0);
3210 }
3211
3212 __isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_dim *dim, unsigned n)
3213 {
3214         return map_lex_gte_first(dim, n, 1);
3215 }
3216
3217 __isl_give isl_map *isl_map_lex_gt(__isl_take isl_dim *set_dim)
3218 {
3219         return map_lex_gte(isl_dim_map(set_dim), 0);
3220 }
3221
3222 __isl_give isl_map *isl_map_lex_ge(__isl_take isl_dim *set_dim)
3223 {
3224         return map_lex_gte(isl_dim_map(set_dim), 1);
3225 }
3226
3227 __isl_give isl_map *isl_set_lex_le_set(__isl_take isl_set *set1,
3228         __isl_take isl_set *set2)
3229 {
3230         isl_map *map;
3231         map = isl_map_lex_le(isl_set_get_dim(set1));
3232         map = isl_map_intersect_domain(map, set1);
3233         map = isl_map_intersect_range(map, set2);
3234         return map;
3235 }
3236
3237 __isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_set *set1,
3238         __isl_take isl_set *set2)
3239 {
3240         isl_map *map;
3241         map = isl_map_lex_lt(isl_set_get_dim(set1));
3242         map = isl_map_intersect_domain(map, set1);
3243         map = isl_map_intersect_range(map, set2);
3244         return map;
3245 }
3246
3247 __isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_set *set1,
3248         __isl_take isl_set *set2)
3249 {
3250         isl_map *map;
3251         map = isl_map_lex_ge(isl_set_get_dim(set1));
3252         map = isl_map_intersect_domain(map, set1);
3253         map = isl_map_intersect_range(map, set2);
3254         return map;
3255 }
3256
3257 __isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_set *set1,
3258         __isl_take isl_set *set2)
3259 {
3260         isl_map *map;
3261         map = isl_map_lex_gt(isl_set_get_dim(set1));
3262         map = isl_map_intersect_domain(map, set1);
3263         map = isl_map_intersect_range(map, set2);
3264         return map;
3265 }
3266
3267 __isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
3268         __isl_take isl_map *map2)
3269 {
3270         isl_map *map;
3271         map = isl_map_lex_le(isl_dim_range(isl_map_get_dim(map1)));
3272         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3273         map = isl_map_apply_range(map, isl_map_reverse(map2));
3274         return map;
3275 }
3276
3277 __isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
3278         __isl_take isl_map *map2)
3279 {
3280         isl_map *map;
3281         map = isl_map_lex_lt(isl_dim_range(isl_map_get_dim(map1)));
3282         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3283         map = isl_map_apply_range(map, isl_map_reverse(map2));
3284         return map;
3285 }
3286
3287 __isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
3288         __isl_take isl_map *map2)
3289 {
3290         isl_map *map;
3291         map = isl_map_lex_ge(isl_dim_range(isl_map_get_dim(map1)));
3292         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3293         map = isl_map_apply_range(map, isl_map_reverse(map2));
3294         return map;
3295 }
3296
3297 __isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
3298         __isl_take isl_map *map2)
3299 {
3300         isl_map *map;
3301         map = isl_map_lex_gt(isl_dim_range(isl_map_get_dim(map1)));
3302         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3303         map = isl_map_apply_range(map, isl_map_reverse(map2));
3304         return map;
3305 }
3306
3307 struct isl_basic_map *isl_basic_map_from_basic_set(
3308                 struct isl_basic_set *bset, struct isl_dim *dim)
3309 {
3310         struct isl_basic_map *bmap;
3311
3312         bset = isl_basic_set_cow(bset);
3313         if (!bset || !dim)
3314                 goto error;
3315
3316         isl_assert(bset->ctx, isl_dim_compatible(bset->dim, dim), goto error);
3317         isl_dim_free(bset->dim);
3318         bmap = (struct isl_basic_map *) bset;
3319         bmap->dim = dim;
3320         return isl_basic_map_finalize(bmap);
3321 error:
3322         isl_basic_set_free(bset);
3323         isl_dim_free(dim);
3324         return NULL;
3325 }
3326
3327 struct isl_basic_set *isl_basic_set_from_basic_map(struct isl_basic_map *bmap)
3328 {
3329         if (!bmap)
3330                 goto error;
3331         if (bmap->dim->n_in == 0)
3332                 return (struct isl_basic_set *)bmap;
3333         bmap = isl_basic_map_cow(bmap);
3334         if (!bmap)
3335                 goto error;
3336         bmap->dim = isl_dim_as_set_dim(bmap->dim);
3337         if (!bmap->dim)
3338                 goto error;
3339         bmap = isl_basic_map_finalize(bmap);
3340         return (struct isl_basic_set *)bmap;
3341 error:
3342         isl_basic_map_free(bmap);
3343         return NULL;
3344 }
3345
3346 /* For a div d = floor(f/m), add the constraints
3347  *
3348  *              f - m d >= 0
3349  *              -(f-(n-1)) + m d >= 0
3350  *
3351  * Note that the second constraint is the negation of
3352  *
3353  *              f - m d >= n
3354  */
3355 int isl_basic_map_add_div_constraints_var(__isl_keep isl_basic_map *bmap,
3356         unsigned pos, isl_int *div)
3357 {
3358         int i, j;
3359         unsigned total = isl_basic_map_total_dim(bmap);
3360
3361         i = isl_basic_map_alloc_inequality(bmap);
3362         if (i < 0)
3363                 return -1;
3364         isl_seq_cpy(bmap->ineq[i], div + 1, 1 + total);
3365         isl_int_neg(bmap->ineq[i][1 + pos], div[0]);
3366
3367         j = isl_basic_map_alloc_inequality(bmap);
3368         if (j < 0)
3369                 return -1;
3370         isl_seq_neg(bmap->ineq[j], bmap->ineq[i], 1 + total);
3371         isl_int_add(bmap->ineq[j][0], bmap->ineq[j][0], bmap->ineq[j][1 + pos]);
3372         isl_int_sub_ui(bmap->ineq[j][0], bmap->ineq[j][0], 1);
3373         return j;
3374 }
3375
3376 int isl_basic_set_add_div_constraints_var(__isl_keep isl_basic_set *bset,
3377         unsigned pos, isl_int *div)
3378 {
3379         return isl_basic_map_add_div_constraints_var((isl_basic_map *)bset,
3380                                                         pos, div);
3381 }
3382
3383 int isl_basic_map_add_div_constraints(struct isl_basic_map *bmap, unsigned div)
3384 {
3385         unsigned total = isl_basic_map_total_dim(bmap);
3386         unsigned div_pos = total - bmap->n_div + div;
3387
3388         return isl_basic_map_add_div_constraints_var(bmap, div_pos,
3389                                                         bmap->div[div]);
3390 }
3391
3392 struct isl_basic_set *isl_basic_map_underlying_set(
3393                 struct isl_basic_map *bmap)
3394 {
3395         if (!bmap)
3396                 goto error;
3397         if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
3398             bmap->n_div == 0 && !isl_dim_get_tuple_name(bmap->dim, isl_dim_out))
3399                 return (struct isl_basic_set *)bmap;
3400         bmap = isl_basic_map_cow(bmap);
3401         if (!bmap)
3402                 goto error;
3403         bmap->dim = isl_dim_underlying(bmap->dim, bmap->n_div);
3404         if (!bmap->dim)
3405                 goto error;
3406         bmap->extra -= bmap->n_div;
3407         bmap->n_div = 0;
3408         bmap = isl_basic_map_finalize(bmap);
3409         return (struct isl_basic_set *)bmap;
3410 error:
3411         return NULL;
3412 }
3413
3414 __isl_give isl_basic_set *isl_basic_set_underlying_set(
3415                 __isl_take isl_basic_set *bset)
3416 {
3417         return isl_basic_map_underlying_set((isl_basic_map *)bset);
3418 }
3419
3420 struct isl_basic_map *isl_basic_map_overlying_set(
3421         struct isl_basic_set *bset, struct isl_basic_map *like)
3422 {
3423         struct isl_basic_map *bmap;
3424         struct isl_ctx *ctx;
3425         unsigned total;
3426         int i;
3427
3428         if (!bset || !like)
3429                 goto error;
3430         ctx = bset->ctx;
3431         isl_assert(ctx, bset->n_div == 0, goto error);
3432         isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error);
3433         isl_assert(ctx, bset->dim->n_out == isl_basic_map_total_dim(like),
3434                         goto error);
3435         if (isl_dim_equal(bset->dim, like->dim) && like->n_div == 0) {
3436                 isl_basic_map_free(like);
3437                 return (struct isl_basic_map *)bset;
3438         }
3439         bset = isl_basic_set_cow(bset);
3440         if (!bset)
3441                 goto error;
3442         total = bset->dim->n_out + bset->extra;
3443         bmap = (struct isl_basic_map *)bset;
3444         isl_dim_free(bmap->dim);
3445         bmap->dim = isl_dim_copy(like->dim);
3446         if (!bmap->dim)
3447                 goto error;
3448         bmap->n_div = like->n_div;
3449         bmap->extra += like->n_div;
3450         if (bmap->extra) {
3451                 unsigned ltotal;
3452                 ltotal = total - bmap->extra + like->extra;
3453                 if (ltotal > total)
3454                         ltotal = total;
3455                 bmap->block2 = isl_blk_extend(ctx, bmap->block2,
3456                                         bmap->extra * (1 + 1 + total));
3457                 if (isl_blk_is_error(bmap->block2))
3458                         goto error;
3459                 bmap->div = isl_realloc_array(ctx, bmap->div, isl_int *,
3460                                                 bmap->extra);
3461                 if (!bmap->div)
3462                         goto error;
3463                 for (i = 0; i < bmap->extra; ++i)
3464                         bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
3465                 for (i = 0; i < like->n_div; ++i) {
3466                         isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
3467                         isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
3468                 }
3469                 bmap = isl_basic_map_extend_constraints(bmap, 
3470                                                         0, 2 * like->n_div);
3471                 for (i = 0; i < like->n_div; ++i) {
3472                         if (isl_int_is_zero(bmap->div[i][0]))
3473                                 continue;
3474                         if (isl_basic_map_add_div_constraints(bmap, i) < 0)
3475                                 goto error;
3476                 }
3477         }
3478         isl_basic_map_free(like);
3479         bmap = isl_basic_map_simplify(bmap);
3480         bmap = isl_basic_map_finalize(bmap);
3481         return bmap;
3482 error:
3483         isl_basic_map_free(like);
3484         isl_basic_set_free(bset);
3485         return NULL;
3486 }
3487
3488 struct isl_basic_set *isl_basic_set_from_underlying_set(
3489         struct isl_basic_set *bset, struct isl_basic_set *like)
3490 {
3491         return (struct isl_basic_set *)
3492                 isl_basic_map_overlying_set(bset, (struct isl_basic_map *)like);
3493 }
3494
3495 struct isl_set *isl_set_from_underlying_set(
3496         struct isl_set *set, struct isl_basic_set *like)
3497 {
3498         int i;
3499
3500         if (!set || !like)
3501                 goto error;
3502         isl_assert(set->ctx, set->dim->n_out == isl_basic_set_total_dim(like),
3503                     goto error);
3504         if (isl_dim_equal(set->dim, like->dim) && like->n_div == 0) {
3505                 isl_basic_set_free(like);
3506                 return set;
3507         }
3508         set = isl_set_cow(set);
3509         if (!set)
3510                 goto error;
3511         for (i = 0; i < set->n; ++i) {
3512                 set->p[i] = isl_basic_set_from_underlying_set(set->p[i],
3513                                                       isl_basic_set_copy(like));
3514                 if (!set->p[i])
3515                         goto error;
3516         }
3517         isl_dim_free(set->dim);
3518         set->dim = isl_dim_copy(like->dim);
3519         if (!set->dim)
3520                 goto error;
3521         isl_basic_set_free(like);
3522         return set;
3523 error:
3524         isl_basic_set_free(like);
3525         isl_set_free(set);
3526         return NULL;
3527 }
3528
3529 struct isl_set *isl_map_underlying_set(struct isl_map *map)
3530 {
3531         int i;
3532
3533         map = isl_map_cow(map);
3534         if (!map)
3535                 return NULL;
3536         map->dim = isl_dim_cow(map->dim);
3537         if (!map->dim)
3538                 goto error;
3539
3540         for (i = 1; i < map->n; ++i)
3541                 isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,
3542                                 goto error);
3543         for (i = 0; i < map->n; ++i) {
3544                 map->p[i] = (struct isl_basic_map *)
3545                                 isl_basic_map_underlying_set(map->p[i]);
3546                 if (!map->p[i])
3547                         goto error;
3548         }
3549         if (map->n == 0)
3550                 map->dim = isl_dim_underlying(map->dim, 0);
3551         else {
3552                 isl_dim_free(map->dim);
3553                 map->dim = isl_dim_copy(map->p[0]->dim);
3554         }
3555         if (!map->dim)
3556                 goto error;
3557         return (struct isl_set *)map;
3558 error:
3559         isl_map_free(map);
3560         return NULL;
3561 }
3562
3563 struct isl_set *isl_set_to_underlying_set(struct isl_set *set)
3564 {
3565         return (struct isl_set *)isl_map_underlying_set((struct isl_map *)set);
3566 }
3567
3568 static __isl_give isl_basic_map *isl_basic_map_reset_dim(
3569         __isl_take isl_basic_map *bmap, __isl_take isl_dim *dim)
3570 {
3571         bmap = isl_basic_map_cow(bmap);
3572         if (!bmap || !dim)
3573                 goto error;
3574
3575         isl_dim_free(bmap->dim);
3576         bmap->dim = dim;
3577
3578         bmap = isl_basic_map_finalize(bmap);
3579
3580         return bmap;
3581 error:
3582         isl_basic_map_free(bmap);
3583         isl_dim_free(dim);
3584         return NULL;
3585 }
3586
3587 static __isl_give isl_basic_set *isl_basic_set_reset_dim(
3588         __isl_take isl_basic_set *bset, __isl_take isl_dim *dim)
3589 {
3590         return (isl_basic_set *)isl_basic_map_reset_dim((isl_basic_map *)bset,
3591                                                         dim);
3592 }
3593
3594 __isl_give isl_map *isl_map_reset_dim(__isl_take isl_map *map,
3595         __isl_take isl_dim *dim)
3596 {
3597         int i;
3598
3599         map = isl_map_cow(map);
3600         if (!map || !dim)
3601                 goto error;
3602
3603         for (i = 0; i < map->n; ++i) {
3604                 map->p[i] = isl_basic_map_reset_dim(map->p[i],
3605                                                     isl_dim_copy(dim));
3606                 if (!map->p[i])
3607                         goto error;
3608         }
3609         isl_dim_free(map->dim);
3610         map->dim = dim;
3611
3612         return map;
3613 error:
3614         isl_map_free(map);
3615         isl_dim_free(dim);
3616         return NULL;
3617 }
3618
3619 __isl_give isl_set *isl_set_reset_dim(__isl_take isl_set *set,
3620         __isl_take isl_dim *dim)
3621 {
3622         return (struct isl_set *) isl_map_reset_dim((struct isl_map *)set, dim);
3623 }
3624
3625 struct isl_basic_set *isl_basic_map_domain(struct isl_basic_map *bmap)
3626 {
3627         isl_dim *dim;
3628         struct isl_basic_set *domain;
3629         unsigned n_in;
3630         unsigned n_out;
3631
3632         if (!bmap)
3633                 return NULL;
3634         dim = isl_dim_domain(isl_basic_map_get_dim(bmap));
3635
3636         n_in = isl_basic_map_n_in(bmap);
3637         n_out = isl_basic_map_n_out(bmap);
3638         domain = isl_basic_set_from_basic_map(bmap);
3639         domain = isl_basic_set_project_out(domain, isl_dim_set, n_in, n_out);
3640
3641         domain = isl_basic_set_reset_dim(domain, dim);
3642
3643         return domain;
3644 }
3645
3646 struct isl_basic_set *isl_basic_map_range(struct isl_basic_map *bmap)
3647 {
3648         return isl_basic_map_domain(isl_basic_map_reverse(bmap));
3649 }
3650
3651 __isl_give isl_basic_map *isl_basic_map_domain_map(
3652         __isl_take isl_basic_map *bmap)
3653 {
3654         int i, k;
3655         isl_dim *dim;
3656         isl_basic_map *domain;
3657         isl_basic_set *bset;
3658         int nparam, n_in, n_out;
3659         unsigned total;
3660
3661         nparam = isl_basic_map_dim(bmap, isl_dim_param);
3662         n_in = isl_basic_map_dim(bmap, isl_dim_in);
3663         n_out = isl_basic_map_dim(bmap, isl_dim_out);
3664
3665         dim = isl_dim_from_range(isl_dim_domain(isl_basic_map_get_dim(bmap)));
3666         domain = isl_basic_map_universe(dim);
3667
3668         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
3669         bmap = isl_basic_map_apply_range(bmap, domain);
3670         bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
3671
3672         total = isl_basic_map_total_dim(bmap);
3673
3674         for (i = 0; i < n_in; ++i) {
3675                 k = isl_basic_map_alloc_equality(bmap);
3676                 if (k < 0)
3677                         goto error;
3678                 isl_seq_clr(bmap->eq[k], 1 + total);
3679                 isl_int_set_si(bmap->eq[k][1 + nparam + i], -1);
3680                 isl_int_set_si(bmap->eq[k][1 + nparam + n_in + n_out + i], 1);
3681         }
3682
3683         bmap = isl_basic_map_gauss(bmap, NULL);
3684         return isl_basic_map_finalize(bmap);
3685 error:
3686         isl_basic_map_free(bmap);
3687         return NULL;
3688 }
3689
3690 __isl_give isl_basic_map *isl_basic_map_range_map(
3691         __isl_take isl_basic_map *bmap)
3692 {
3693         int i, k;
3694         isl_dim *dim;
3695         isl_basic_map *range;
3696         isl_basic_set *bset;
3697         int nparam, n_in, n_out;
3698         unsigned total;
3699
3700         nparam = isl_basic_map_dim(bmap, isl_dim_param);
3701         n_in = isl_basic_map_dim(bmap, isl_dim_in);
3702         n_out = isl_basic_map_dim(bmap, isl_dim_out);
3703
3704         dim = isl_dim_from_range(isl_dim_range(isl_basic_map_get_dim(bmap)));
3705         range = isl_basic_map_universe(dim);
3706
3707         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
3708         bmap = isl_basic_map_apply_range(bmap, range);
3709         bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
3710
3711         total = isl_basic_map_total_dim(bmap);
3712
3713         for (i = 0; i < n_out; ++i) {
3714                 k = isl_basic_map_alloc_equality(bmap);
3715                 if (k < 0)
3716                         goto error;
3717                 isl_seq_clr(bmap->eq[k], 1 + total);
3718                 isl_int_set_si(bmap->eq[k][1 + nparam + n_in + i], -1);
3719                 isl_int_set_si(bmap->eq[k][1 + nparam + n_in + n_out + i], 1);
3720         }
3721
3722         bmap = isl_basic_map_gauss(bmap, NULL);
3723         return isl_basic_map_finalize(bmap);
3724 error:
3725         isl_basic_map_free(bmap);
3726         return NULL;
3727 }
3728
3729 struct isl_set *isl_map_range(struct isl_map *map)
3730 {
3731         int i;
3732         struct isl_set *set;
3733
3734         if (!map)
3735                 goto error;
3736         if (isl_map_dim(map, isl_dim_in) == 0)
3737                 return (isl_set *)map;
3738
3739         map = isl_map_cow(map);
3740         if (!map)
3741                 goto error;
3742
3743         set = (struct isl_set *) map;
3744         set->dim = isl_dim_drop_inputs(set->dim, 0, set->dim->n_in);
3745         if (!set->dim)
3746                 goto error;
3747         for (i = 0; i < map->n; ++i) {
3748                 set->p[i] = isl_basic_map_range(map->p[i]);
3749                 if (!set->p[i])
3750                         goto error;
3751         }
3752         ISL_F_CLR(set, ISL_MAP_DISJOINT);
3753         ISL_F_CLR(set, ISL_SET_NORMALIZED);
3754         return set;
3755 error:
3756         isl_map_free(map);
3757         return NULL;
3758 }
3759
3760 __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
3761 {
3762         int i;
3763         isl_dim *domain_dim;
3764
3765         map = isl_map_cow(map);
3766         if (!map)
3767                 return NULL;
3768
3769         domain_dim = isl_dim_from_range(isl_dim_domain(isl_map_get_dim(map)));
3770         map->dim = isl_dim_from_domain(isl_dim_wrap(map->dim));
3771         map->dim = isl_dim_join(map->dim, domain_dim);
3772         if (!map->dim)
3773                 goto error;
3774         for (i = 0; i < map->n; ++i) {
3775                 map->p[i] = isl_basic_map_domain_map(map->p[i]);
3776                 if (!map->p[i])
3777                         goto error;
3778         }
3779         ISL_F_CLR(map, ISL_MAP_DISJOINT);
3780         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
3781         return map;
3782 error:
3783         isl_map_free(map);
3784         return NULL;
3785 }
3786
3787 __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
3788 {
3789         int i;
3790         isl_dim *range_dim;
3791
3792         map = isl_map_cow(map);
3793         if (!map)
3794                 return NULL;
3795
3796         range_dim = isl_dim_range(isl_map_get_dim(map));
3797         map->dim = isl_dim_from_domain(isl_dim_wrap(map->dim));
3798         map->dim = isl_dim_join(map->dim, range_dim);
3799         if (!map->dim)
3800                 goto error;
3801         for (i = 0; i < map->n; ++i) {
3802                 map->p[i] = isl_basic_map_range_map(map->p[i]);
3803                 if (!map->p[i])
3804                         goto error;
3805         }
3806         ISL_F_CLR(map, ISL_MAP_DISJOINT);
3807         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
3808         return map;
3809 error:
3810         isl_map_free(map);
3811         return NULL;
3812 }
3813
3814 struct isl_map *isl_map_from_set(struct isl_set *set, struct isl_dim *dim)
3815 {
3816         int i;
3817         struct isl_map *map = NULL;
3818
3819         set = isl_set_cow(set);
3820         if (!set || !dim)
3821                 goto error;
3822         isl_assert(set->ctx, isl_dim_compatible(set->dim, dim), goto error);
3823         map = (struct isl_map *)set;
3824         for (i = 0; i < set->n; ++i) {
3825                 map->p[i] = isl_basic_map_from_basic_set(
3826                                 set->p[i], isl_dim_copy(dim));
3827                 if (!map->p[i])
3828                         goto error;
3829         }
3830         isl_dim_free(map->dim);
3831         map->dim = dim;
3832         return map;
3833 error:
3834         isl_dim_free(dim);
3835         isl_set_free(set);
3836         return NULL;
3837 }
3838
3839 __isl_give isl_basic_map *isl_basic_map_from_domain(
3840         __isl_take isl_basic_set *bset)
3841 {
3842         return isl_basic_map_reverse(isl_basic_map_from_range(bset));
3843 }
3844
3845 __isl_give isl_basic_map *isl_basic_map_from_range(
3846         __isl_take isl_basic_set *bset)
3847 {
3848         return (isl_basic_map *)bset;
3849 }
3850
3851 struct isl_map *isl_map_from_range(struct isl_set *set)
3852 {
3853         return (struct isl_map *)set;
3854 }
3855
3856 __isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set)
3857 {
3858         return isl_map_reverse(isl_map_from_range(set));
3859 }
3860
3861 __isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain,
3862         __isl_take isl_set *range)
3863 {
3864         return isl_map_apply_range(isl_map_from_domain(domain),
3865                                    isl_map_from_range(range));
3866 }
3867
3868 struct isl_set *isl_set_from_map(struct isl_map *map)
3869 {
3870         int i;
3871         struct isl_set *set = NULL;
3872
3873         if (!map)
3874                 return NULL;
3875         map = isl_map_cow(map);
3876         if (!map)
3877                 return NULL;
3878         map->dim = isl_dim_as_set_dim(map->dim);
3879         if (!map->dim)
3880                 goto error;
3881         set = (struct isl_set *)map;
3882         for (i = 0; i < map->n; ++i) {
3883                 set->p[i] = isl_basic_set_from_basic_map(map->p[i]);
3884                 if (!set->p[i])
3885                         goto error;
3886         }
3887         return set;
3888 error:
3889         isl_map_free(map);
3890         return NULL;
3891 }
3892
3893 struct isl_map *isl_map_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
3894 {
3895         struct isl_map *map;
3896
3897         if (!dim)
3898                 return NULL;
3899         isl_assert(dim->ctx, n >= 0, return NULL);
3900         map = isl_alloc(dim->ctx, struct isl_map,
3901                         sizeof(struct isl_map) +
3902                         (n - 1) * sizeof(struct isl_basic_map *));
3903         if (!map)
3904                 goto error;
3905
3906         map->ctx = dim->ctx;
3907         isl_ctx_ref(map->ctx);
3908         map->ref = 1;
3909         map->size = n;
3910         map->n = 0;
3911         map->dim = dim;
3912         map->flags = flags;
3913         return map;
3914 error:
3915         isl_dim_free(dim);
3916         return NULL;
3917 }
3918
3919 struct isl_map *isl_map_alloc(struct isl_ctx *ctx,
3920                 unsigned nparam, unsigned in, unsigned out, int n,
3921                 unsigned flags)
3922 {
3923         struct isl_map *map;
3924         struct isl_dim *dims;
3925
3926         dims = isl_dim_alloc(ctx, nparam, in, out);
3927         if (!dims)
3928                 return NULL;
3929
3930         map = isl_map_alloc_dim(dims, n, flags);
3931         return map;
3932 }
3933
3934 struct isl_basic_map *isl_basic_map_empty(struct isl_dim *dim)
3935 {
3936         struct isl_basic_map *bmap;
3937         bmap = isl_basic_map_alloc_dim(dim, 0, 1, 0);
3938         bmap = isl_basic_map_set_to_empty(bmap);
3939         return bmap;
3940 }
3941
3942 struct isl_basic_set *isl_basic_set_empty(struct isl_dim *dim)
3943 {
3944         struct isl_basic_set *bset;
3945         bset = isl_basic_set_alloc_dim(dim, 0, 1, 0);
3946         bset = isl_basic_set_set_to_empty(bset);
3947         return bset;
3948 }
3949
3950 struct isl_basic_map *isl_basic_map_empty_like(struct isl_basic_map *model)
3951 {
3952         struct isl_basic_map *bmap;
3953         if (!model)
3954                 return NULL;
3955         bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
3956         bmap = isl_basic_map_set_to_empty(bmap);
3957         return bmap;
3958 }
3959
3960 struct isl_basic_map *isl_basic_map_empty_like_map(struct isl_map *model)
3961 {
3962         struct isl_basic_map *bmap;
3963         if (!model)
3964                 return NULL;
3965         bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
3966         bmap = isl_basic_map_set_to_empty(bmap);
3967         return bmap;
3968 }
3969
3970 struct isl_basic_set *isl_basic_set_empty_like(struct isl_basic_set *model)
3971 {
3972         struct isl_basic_set *bset;
3973         if (!model)
3974                 return NULL;
3975         bset = isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
3976         bset = isl_basic_set_set_to_empty(bset);
3977         return bset;
3978 }
3979
3980 struct isl_basic_map *isl_basic_map_universe(struct isl_dim *dim)
3981 {
3982         struct isl_basic_map *bmap;
3983         bmap = isl_basic_map_alloc_dim(dim, 0, 0, 0);
3984         return bmap;
3985 }
3986
3987 struct isl_basic_set *isl_basic_set_universe(struct isl_dim *dim)
3988 {
3989         struct isl_basic_set *bset;
3990         bset = isl_basic_set_alloc_dim(dim, 0, 0, 0);
3991         return bset;
3992 }
3993
3994 __isl_give isl_basic_map *isl_basic_map_universe_like(
3995                 __isl_keep isl_basic_map *model)
3996 {
3997         if (!model)
3998                 return NULL;
3999         return isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 0, 0);
4000 }
4001
4002 struct isl_basic_set *isl_basic_set_universe_like(struct isl_basic_set *model)
4003 {
4004         if (!model)
4005                 return NULL;
4006         return isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 0, 0);
4007 }
4008
4009 __isl_give isl_basic_set *isl_basic_set_universe_like_set(
4010         __isl_keep isl_set *model)
4011 {
4012         if (!model)
4013                 return NULL;
4014         return isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 0, 0);
4015 }
4016
4017 struct isl_map *isl_map_empty(struct isl_dim *dim)
4018 {
4019         return isl_map_alloc_dim(dim, 0, ISL_MAP_DISJOINT);
4020 }
4021
4022 struct isl_map *isl_map_empty_like(struct isl_map *model)
4023 {
4024         if (!model)
4025                 return NULL;
4026         return isl_map_alloc_dim(isl_dim_copy(model->dim), 0, ISL_MAP_DISJOINT);
4027 }
4028
4029 struct isl_map *isl_map_empty_like_basic_map(struct isl_basic_map *model)
4030 {
4031         if (!model)
4032                 return NULL;
4033         return isl_map_alloc_dim(isl_dim_copy(model->dim), 0, ISL_MAP_DISJOINT);
4034 }
4035
4036 struct isl_set *isl_set_empty(struct isl_dim *dim)
4037 {
4038         return isl_set_alloc_dim(dim, 0, ISL_MAP_DISJOINT);
4039 }
4040
4041 struct isl_set *isl_set_empty_like(struct isl_set *model)
4042 {
4043         if (!model)
4044                 return NULL;
4045         return isl_set_empty(isl_dim_copy(model->dim));
4046 }
4047
4048 struct isl_map *isl_map_universe(struct isl_dim *dim)
4049 {
4050         struct isl_map *map;
4051         if (!dim)
4052                 return NULL;
4053         map = isl_map_alloc_dim(isl_dim_copy(dim), 1, ISL_MAP_DISJOINT);
4054         map = isl_map_add_basic_map(map, isl_basic_map_universe(dim));
4055         return map;
4056 }
4057
4058 struct isl_set *isl_set_universe(struct isl_dim *dim)
4059 {
4060         struct isl_set *set;
4061         if (!dim)
4062                 return NULL;
4063         set = isl_set_alloc_dim(isl_dim_copy(dim), 1, ISL_MAP_DISJOINT);
4064         set = isl_set_add_basic_set(set, isl_basic_set_universe(dim));
4065         return set;
4066 }
4067
4068 __isl_give isl_set *isl_set_universe_like(__isl_keep isl_set *model)
4069 {
4070         if (!model)
4071                 return NULL;
4072         return isl_set_universe(isl_dim_copy(model->dim));
4073 }
4074
4075 struct isl_map *isl_map_dup(struct isl_map *map)
4076 {
4077         int i;
4078         struct isl_map *dup;
4079
4080         if (!map)
4081                 return NULL;
4082         dup = isl_map_alloc_dim(isl_dim_copy(map->dim), map->n, map->flags);
4083         for (i = 0; i < map->n; ++i)
4084                 dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
4085         return dup;
4086 }
4087
4088 __isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
4089                                                 __isl_take isl_basic_map *bmap)
4090 {
4091         if (!bmap || !map)
4092                 goto error;
4093         if (isl_basic_map_fast_is_empty(bmap)) {
4094                 isl_basic_map_free(bmap);
4095                 return map;
4096         }
4097         isl_assert(map->ctx, isl_dim_equal(map->dim, bmap->dim), goto error);
4098         isl_assert(map->ctx, map->n < map->size, goto error);
4099         map->p[map->n] = bmap;
4100         map->n++;
4101         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4102         return map;
4103 error:
4104         if (map)
4105                 isl_map_free(map);
4106         if (bmap)
4107                 isl_basic_map_free(bmap);
4108         return NULL;
4109 }
4110
4111 void isl_map_free(struct isl_map *map)
4112 {
4113         int i;
4114
4115         if (!map)
4116                 return;
4117
4118         if (--map->ref > 0)
4119                 return;
4120
4121         isl_ctx_deref(map->ctx);
4122         for (i = 0; i < map->n; ++i)
4123                 isl_basic_map_free(map->p[i]);
4124         isl_dim_free(map->dim);
4125         free(map);
4126 }
4127
4128 struct isl_map *isl_map_extend(struct isl_map *base,
4129                 unsigned nparam, unsigned n_in, unsigned n_out)
4130 {
4131         int i;
4132
4133         base = isl_map_cow(base);
4134         if (!base)
4135                 return NULL;
4136
4137         base->dim = isl_dim_extend(base->dim, nparam, n_in, n_out);
4138         if (!base->dim)
4139                 goto error;
4140         for (i = 0; i < base->n; ++i) {
4141                 base->p[i] = isl_basic_map_extend_dim(base->p[i],
4142                                 isl_dim_copy(base->dim), 0, 0, 0);
4143                 if (!base->p[i])
4144                         goto error;
4145         }
4146         return base;
4147 error:
4148         isl_map_free(base);
4149         return NULL;
4150 }
4151
4152 struct isl_set *isl_set_extend(struct isl_set *base,
4153                 unsigned nparam, unsigned dim)
4154 {
4155         return (struct isl_set *)isl_map_extend((struct isl_map *)base,
4156                                                         nparam, 0, dim);
4157 }
4158
4159 static struct isl_basic_map *isl_basic_map_fix_pos_si(
4160         struct isl_basic_map *bmap, unsigned pos, int value)
4161 {
4162         int j;
4163
4164         bmap = isl_basic_map_cow(bmap);
4165         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
4166         j = isl_basic_map_alloc_equality(bmap);
4167         if (j < 0)
4168                 goto error;
4169         isl_seq_clr(bmap->eq[j] + 1, isl_basic_map_total_dim(bmap));
4170         isl_int_set_si(bmap->eq[j][pos], -1);
4171         isl_int_set_si(bmap->eq[j][0], value);
4172         bmap = isl_basic_map_simplify(bmap);
4173         return isl_basic_map_finalize(bmap);
4174 error:
4175         isl_basic_map_free(bmap);
4176         return NULL;
4177 }
4178
4179 static __isl_give isl_basic_map *isl_basic_map_fix_pos(
4180         __isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
4181 {
4182         int j;
4183
4184         bmap = isl_basic_map_cow(bmap);
4185         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
4186         j = isl_basic_map_alloc_equality(bmap);
4187         if (j < 0)
4188                 goto error;
4189         isl_seq_clr(bmap->eq[j] + 1, isl_basic_map_total_dim(bmap));
4190         isl_int_set_si(bmap->eq[j][pos], -1);
4191         isl_int_set(bmap->eq[j][0], value);
4192         bmap = isl_basic_map_simplify(bmap);
4193         return isl_basic_map_finalize(bmap);
4194 error:
4195         isl_basic_map_free(bmap);
4196         return NULL;
4197 }
4198
4199 struct isl_basic_map *isl_basic_map_fix_si(struct isl_basic_map *bmap,
4200                 enum isl_dim_type type, unsigned pos, int value)
4201 {
4202         if (!bmap)
4203                 return NULL;
4204         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
4205         return isl_basic_map_fix_pos_si(bmap,
4206                 isl_basic_map_offset(bmap, type) + pos, value);
4207 error:
4208         isl_basic_map_free(bmap);
4209         return NULL;
4210 }
4211
4212 __isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
4213                 enum isl_dim_type type, unsigned pos, isl_int value)
4214 {
4215         if (!bmap)
4216                 return NULL;
4217         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
4218         return isl_basic_map_fix_pos(bmap,
4219                 isl_basic_map_offset(bmap, type) + pos, value);
4220 error:
4221         isl_basic_map_free(bmap);
4222         return NULL;
4223 }
4224
4225 struct isl_basic_set *isl_basic_set_fix_si(struct isl_basic_set *bset,
4226                 enum isl_dim_type type, unsigned pos, int value)
4227 {
4228         return (struct isl_basic_set *)
4229                 isl_basic_map_fix_si((struct isl_basic_map *)bset,
4230                                         type, pos, value);
4231 }
4232
4233 __isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset,
4234                 enum isl_dim_type type, unsigned pos, isl_int value)
4235 {
4236         return (struct isl_basic_set *)
4237                 isl_basic_map_fix((struct isl_basic_map *)bset,
4238                                         type, pos, value);
4239 }
4240
4241 struct isl_basic_map *isl_basic_map_fix_input_si(struct isl_basic_map *bmap,
4242                 unsigned input, int value)
4243 {
4244         return isl_basic_map_fix_si(bmap, isl_dim_in, input, value);
4245 }
4246
4247 struct isl_basic_set *isl_basic_set_fix_dim_si(struct isl_basic_set *bset,
4248                 unsigned dim, int value)
4249 {
4250         return (struct isl_basic_set *)
4251                 isl_basic_map_fix_si((struct isl_basic_map *)bset,
4252                                         isl_dim_set, dim, value);
4253 }
4254
4255 struct isl_map *isl_map_fix_si(struct isl_map *map,
4256                 enum isl_dim_type type, unsigned pos, int value)
4257 {
4258         int i;
4259
4260         map = isl_map_cow(map);
4261         if (!map)
4262                 return NULL;
4263
4264         isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error);
4265         for (i = 0; i < map->n; ++i) {
4266                 map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
4267                 if (!map->p[i])
4268                         goto error;
4269         }
4270         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4271         return map;
4272 error:
4273         isl_map_free(map);
4274         return NULL;
4275 }
4276
4277 __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set,
4278                 enum isl_dim_type type, unsigned pos, int value)
4279 {
4280         return (struct isl_set *)
4281                 isl_map_fix_si((struct isl_map *)set, type, pos, value);
4282 }
4283
4284 __isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
4285                 enum isl_dim_type type, unsigned pos, isl_int value)
4286 {
4287         int i;
4288
4289         map = isl_map_cow(map);
4290         if (!map)
4291                 return NULL;
4292
4293         isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error);
4294         for (i = 0; i < map->n; ++i) {
4295                 map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
4296                 if (!map->p[i])
4297                         goto error;
4298         }
4299         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4300         return map;
4301 error:
4302         isl_map_free(map);
4303         return NULL;
4304 }
4305
4306 __isl_give isl_set *isl_set_fix(__isl_take isl_set *set,
4307                 enum isl_dim_type type, unsigned pos, isl_int value)
4308 {
4309         return (struct isl_set *)isl_map_fix((isl_map *)set, type, pos, value);
4310 }
4311
4312 struct isl_map *isl_map_fix_input_si(struct isl_map *map,
4313                 unsigned input, int value)
4314 {
4315         return isl_map_fix_si(map, isl_dim_in, input, value);
4316 }
4317
4318 struct isl_set *isl_set_fix_dim_si(struct isl_set *set, unsigned dim, int value)
4319 {
4320         return (struct isl_set *)
4321                 isl_map_fix_si((struct isl_map *)set, isl_dim_set, dim, value);
4322 }
4323
4324 __isl_give isl_basic_map *isl_basic_map_lower_bound_si(
4325                 __isl_take isl_basic_map *bmap,
4326                 enum isl_dim_type type, unsigned pos, int value)
4327 {
4328         int j;
4329
4330         if (!bmap)
4331                 return NULL;
4332         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
4333         pos += isl_basic_map_offset(bmap, type);
4334         bmap = isl_basic_map_cow(bmap);
4335         bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
4336         j = isl_basic_map_alloc_inequality(bmap);
4337         if (j < 0)
4338                 goto error;
4339         isl_seq_clr(bmap->ineq[j], 1 + isl_basic_map_total_dim(bmap));
4340         isl_int_set_si(bmap->ineq[j][pos], 1);
4341         isl_int_set_si(bmap->ineq[j][0], -value);
4342         bmap = isl_basic_map_simplify(bmap);
4343         return isl_basic_map_finalize(bmap);
4344 error:
4345         isl_basic_map_free(bmap);
4346         return NULL;
4347 }
4348
4349 struct isl_basic_set *isl_basic_set_lower_bound_dim(struct isl_basic_set *bset,
4350         unsigned dim, isl_int value)
4351 {
4352         int j;
4353
4354         bset = isl_basic_set_cow(bset);
4355         bset = isl_basic_set_extend_constraints(bset, 0, 1);
4356         j = isl_basic_set_alloc_inequality(bset);
4357         if (j < 0)
4358                 goto error;
4359         isl_seq_clr(bset->ineq[j], 1 + isl_basic_set_total_dim(bset));
4360         isl_int_set_si(bset->ineq[j][1 + isl_basic_set_n_param(bset) + dim], 1);
4361         isl_int_neg(bset->ineq[j][0], value);
4362         bset = isl_basic_set_simplify(bset);
4363         return isl_basic_set_finalize(bset);
4364 error:
4365         isl_basic_set_free(bset);
4366         return NULL;
4367 }
4368
4369 __isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
4370                 enum isl_dim_type type, unsigned pos, int value)
4371 {
4372         int i;
4373
4374         map = isl_map_cow(map);
4375         if (!map)
4376                 return NULL;
4377
4378         isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error);
4379         for (i = 0; i < map->n; ++i) {
4380                 map->p[i] = isl_basic_map_lower_bound_si(map->p[i],
4381                                                          type, pos, value);
4382                 if (!map->p[i])
4383                         goto error;
4384         }
4385         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4386         return map;
4387 error:
4388         isl_map_free(map);
4389         return NULL;
4390 }
4391
4392 __isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set,
4393                 enum isl_dim_type type, unsigned pos, int value)
4394 {
4395         return (struct isl_set *)
4396                 isl_map_lower_bound_si((struct isl_map *)set, type, pos, value);
4397 }
4398
4399 struct isl_set *isl_set_lower_bound_dim(struct isl_set *set, unsigned dim,
4400                                         isl_int value)
4401 {
4402         int i;
4403
4404         set = isl_set_cow(set);
4405         if (!set)
4406                 return NULL;
4407
4408         isl_assert(set->ctx, dim < isl_set_n_dim(set), goto error);
4409         for (i = 0; i < set->n; ++i) {
4410                 set->p[i] = isl_basic_set_lower_bound_dim(set->p[i], dim, value);
4411                 if (!set->p[i])
4412                         goto error;
4413         }
4414         return set;
4415 error:
4416         isl_set_free(set);
4417         return NULL;
4418 }
4419
4420 struct isl_map *isl_map_reverse(struct isl_map *map)
4421 {
4422         int i;
4423
4424         map = isl_map_cow(map);
4425         if (!map)
4426                 return NULL;
4427
4428         map->dim = isl_dim_reverse(map->dim);
4429         if (!map->dim)
4430                 goto error;
4431         for (i = 0; i < map->n; ++i) {
4432                 map->p[i] = isl_basic_map_reverse(map->p[i]);
4433                 if (!map->p[i])
4434                         goto error;
4435         }
4436         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4437         return map;
4438 error:
4439         isl_map_free(map);
4440         return NULL;
4441 }
4442
4443 static struct isl_map *isl_basic_map_partial_lexopt(
4444                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
4445                 struct isl_set **empty, int max)
4446 {
4447         if (!bmap)
4448                 goto error;
4449         if (bmap->ctx->opt->pip == ISL_PIP_PIP)
4450                 return isl_pip_basic_map_lexopt(bmap, dom, empty, max);
4451         else
4452                 return isl_tab_basic_map_partial_lexopt(bmap, dom, empty, max);
4453 error:
4454         isl_basic_map_free(bmap);
4455         isl_basic_set_free(dom);
4456         if (empty)
4457                 *empty = NULL;
4458         return NULL;
4459 }
4460
4461 struct isl_map *isl_basic_map_partial_lexmax(
4462                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
4463                 struct isl_set **empty)
4464 {
4465         return isl_basic_map_partial_lexopt(bmap, dom, empty, 1);
4466 }
4467
4468 struct isl_map *isl_basic_map_partial_lexmin(
4469                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
4470                 struct isl_set **empty)
4471 {
4472         return isl_basic_map_partial_lexopt(bmap, dom, empty, 0);
4473 }
4474
4475 struct isl_set *isl_basic_set_partial_lexmin(
4476                 struct isl_basic_set *bset, struct isl_basic_set *dom,
4477                 struct isl_set **empty)
4478 {
4479         return (struct isl_set *)
4480                 isl_basic_map_partial_lexmin((struct isl_basic_map *)bset,
4481                         dom, empty);
4482 }
4483
4484 struct isl_set *isl_basic_set_partial_lexmax(
4485                 struct isl_basic_set *bset, struct isl_basic_set *dom,
4486                 struct isl_set **empty)
4487 {
4488         return (struct isl_set *)
4489                 isl_basic_map_partial_lexmax((struct isl_basic_map *)bset,
4490                         dom, empty);
4491 }
4492
4493 /* Given a basic map "bmap", compute the lexicograhically minimal
4494  * (or maximal) image element for each domain element in dom.
4495  * Set *empty to those elements in dom that do not have an image element.
4496  *
4497  * We first make sure the basic sets in dom are disjoint and then
4498  * simply collect the results over each of the basic sets separately.
4499  * We could probably improve the efficiency a bit by moving the union
4500  * domain down into the parametric integer programming.
4501  */
4502 static __isl_give isl_map *basic_map_partial_lexopt(
4503                 __isl_take isl_basic_map *bmap, __isl_take isl_set *dom,
4504                 __isl_give isl_set **empty, int max)
4505 {
4506         int i;
4507         struct isl_map *res;
4508
4509         dom = isl_set_make_disjoint(dom);
4510         if (!dom)
4511                 goto error;
4512
4513         if (isl_set_fast_is_empty(dom)) {
4514                 res = isl_map_empty_like_basic_map(bmap);
4515                 *empty = isl_set_empty_like(dom);
4516                 isl_set_free(dom);
4517                 isl_basic_map_free(bmap);
4518                 return res;
4519         }
4520
4521         res = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap),
4522                         isl_basic_set_copy(dom->p[0]), empty, max);
4523                 
4524         for (i = 1; i < dom->n; ++i) {
4525                 struct isl_map *res_i;
4526                 struct isl_set *empty_i;
4527
4528                 res_i = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap),
4529                                 isl_basic_set_copy(dom->p[i]), &empty_i, max);
4530
4531                 res = isl_map_union_disjoint(res, res_i);
4532                 *empty = isl_set_union_disjoint(*empty, empty_i);
4533         }
4534
4535         isl_set_free(dom);
4536         isl_basic_map_free(bmap);
4537         return res;
4538 error:
4539         *empty = NULL;
4540         isl_set_free(dom);
4541         isl_basic_map_free(bmap);
4542         return NULL;
4543 }
4544
4545 /* Given a map "map", compute the lexicograhically minimal
4546  * (or maximal) image element for each domain element in dom.
4547  * Set *empty to those elements in dom that do not have an image element.
4548  *
4549  * We first compute the lexicographically minimal or maximal element
4550  * in the first basic map.  This results in a partial solution "res"
4551  * and a subset "todo" of dom that still need to be handled.
4552  * We then consider each of the remaining maps in "map" and successively
4553  * improve both "res" and "todo".
4554  *
4555  * Let res^k and todo^k be the results after k steps and let i = k + 1.
4556  * Assume we are computing the lexicographical maximum.
4557  * We first intersect basic map i with a relation that maps elements
4558  * to elements that are lexicographically larger than the image elements
4559  * in res^k and the compute the maximum image element of this intersection.
4560  * The result ("better") corresponds to those image elements in basic map i
4561  * that are better than what we had before.  The remainder ("keep") are the
4562  * domain elements for which the image element in res_k was better.
4563  * We also compute the lexicographical maximum of basic map i in todo^k.
4564  * res^i is the result of the operation + better + those elements in
4565  *              res^k that we should keep
4566  * todo^i is the remainder of the maximum operation on todo^k.
4567  */
4568 static __isl_give isl_map *isl_map_partial_lexopt(
4569                 __isl_take isl_map *map, __isl_take isl_set *dom,
4570                 __isl_give isl_set **empty, int max)
4571 {
4572         int i;
4573         struct isl_map *res;
4574         struct isl_set *todo;
4575
4576         if (!map || !dom)
4577                 goto error;
4578
4579         if (isl_map_fast_is_empty(map)) {
4580                 if (empty)
4581                         *empty = dom;
4582                 else
4583                         isl_set_free(dom);
4584                 return map;
4585         }
4586
4587         res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
4588                                         isl_set_copy(dom), &todo, max);
4589
4590         for (i = 1; i < map->n; ++i) {
4591                 struct isl_map *lt;
4592                 struct isl_map *better;
4593                 struct isl_set *keep;
4594                 struct isl_map *res_i;
4595                 struct isl_set *todo_i;
4596                 struct isl_dim *dim = isl_map_get_dim(res);
4597
4598                 dim = isl_dim_range(dim);
4599                 if (max)
4600                         lt = isl_map_lex_lt(dim);
4601                 else
4602                         lt = isl_map_lex_gt(dim);
4603                 lt = isl_map_apply_range(isl_map_copy(res), lt);
4604                 lt = isl_map_intersect(lt,
4605                         isl_map_from_basic_map(isl_basic_map_copy(map->p[i])));
4606                 better = isl_map_partial_lexopt(lt,
4607                         isl_map_domain(isl_map_copy(res)),
4608                         &keep, max);
4609
4610                 res_i = basic_map_partial_lexopt(isl_basic_map_copy(map->p[i]),
4611                                                 todo, &todo_i, max);
4612
4613                 res = isl_map_intersect_domain(res, keep);
4614                 res = isl_map_union_disjoint(res, res_i);
4615                 res = isl_map_union_disjoint(res, better);
4616                 todo = todo_i;
4617         }
4618
4619         isl_set_free(dom);
4620         isl_map_free(map);
4621
4622         if (empty)
4623                 *empty = todo;
4624         else
4625                 isl_set_free(todo);
4626
4627         return res;
4628 error:
4629         if (empty)
4630                 *empty = NULL;
4631         isl_set_free(dom);
4632         isl_map_free(map);
4633         return NULL;
4634 }
4635
4636 __isl_give isl_map *isl_map_partial_lexmax(
4637                 __isl_take isl_map *map, __isl_take isl_set *dom,
4638                 __isl_give isl_set **empty)
4639 {
4640         return isl_map_partial_lexopt(map, dom, empty, 1);
4641 }
4642
4643 __isl_give isl_map *isl_map_partial_lexmin(
4644                 __isl_take isl_map *map, __isl_take isl_set *dom,
4645                 __isl_give isl_set **empty)
4646 {
4647         return isl_map_partial_lexopt(map, dom, empty, 0);
4648 }
4649
4650 __isl_give isl_set *isl_set_partial_lexmin(
4651                 __isl_take isl_set *set, __isl_take isl_set *dom,
4652                 __isl_give isl_set **empty)
4653 {
4654         return (struct isl_set *)
4655                 isl_map_partial_lexmin((struct isl_map *)set,
4656                         dom, empty);
4657 }
4658
4659 __isl_give isl_set *isl_set_partial_lexmax(
4660                 __isl_take isl_set *set, __isl_take isl_set *dom,
4661                 __isl_give isl_set **empty)
4662 {
4663         return (struct isl_set *)
4664                 isl_map_partial_lexmax((struct isl_map *)set,
4665                         dom, empty);
4666 }
4667
4668 __isl_give isl_map *isl_basic_map_lexopt(__isl_take isl_basic_map *bmap, int max)
4669 {
4670         struct isl_basic_set *dom = NULL;
4671         struct isl_dim *dom_dim;
4672
4673         if (!bmap)
4674                 goto error;
4675         dom_dim = isl_dim_domain(isl_dim_copy(bmap->dim));
4676         dom = isl_basic_set_universe(dom_dim);
4677         return isl_basic_map_partial_lexopt(bmap, dom, NULL, max);
4678 error:
4679         isl_basic_map_free(bmap);
4680         return NULL;
4681 }
4682
4683 __isl_give isl_map *isl_basic_map_lexmin(__isl_take isl_basic_map *bmap)
4684 {
4685         return isl_basic_map_lexopt(bmap, 0);
4686 }
4687
4688 __isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
4689 {
4690         return isl_basic_map_lexopt(bmap, 1);
4691 }
4692
4693 __isl_give isl_set *isl_basic_set_lexmin(__isl_take isl_basic_set *bset)
4694 {
4695         return (isl_set *)isl_basic_map_lexmin((isl_basic_map *)bset);
4696 }
4697
4698 __isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset)
4699 {
4700         return (isl_set *)isl_basic_map_lexmax((isl_basic_map *)bset);
4701 }
4702
4703 __isl_give isl_map *isl_map_lexopt(__isl_take isl_map *map, int max)
4704 {
4705         struct isl_set *dom = NULL;
4706         struct isl_dim *dom_dim;
4707
4708         if (!map)
4709                 goto error;
4710         dom_dim = isl_dim_domain(isl_dim_copy(map->dim));
4711         dom = isl_set_universe(dom_dim);
4712         return isl_map_partial_lexopt(map, dom, NULL, max);
4713 error:
4714         isl_map_free(map);
4715         return NULL;
4716 }
4717
4718 __isl_give isl_map *isl_map_lexmin(__isl_take isl_map *map)
4719 {
4720         return isl_map_lexopt(map, 0);
4721 }
4722
4723 __isl_give isl_map *isl_map_lexmax(__isl_take isl_map *map)
4724 {
4725         return isl_map_lexopt(map, 1);
4726 }
4727
4728 __isl_give isl_set *isl_set_lexmin(__isl_take isl_set *set)
4729 {
4730         return (isl_set *)isl_map_lexmin((isl_map *)set);
4731 }
4732
4733 __isl_give isl_set *isl_set_lexmax(__isl_take isl_set *set)
4734 {
4735         return (isl_set *)isl_map_lexmax((isl_map *)set);
4736 }
4737
4738 /* Apply a preimage specified by "mat" on the parameters of "bset".
4739  * bset is assumed to have only parameters and divs.
4740  */
4741 static struct isl_basic_set *basic_set_parameter_preimage(
4742         struct isl_basic_set *bset, struct isl_mat *mat)
4743 {
4744         unsigned nparam;
4745
4746         if (!bset || !mat)
4747                 goto error;
4748
4749         bset->dim = isl_dim_cow(bset->dim);
4750         if (!bset->dim)
4751                 goto error;
4752
4753         nparam = isl_basic_set_dim(bset, isl_dim_param);
4754
4755         isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error);
4756
4757         bset->dim->nparam = 0;
4758         bset->dim->n_out = nparam;
4759         bset = isl_basic_set_preimage(bset, mat);
4760         if (bset) {
4761                 bset->dim->nparam = bset->dim->n_out;
4762                 bset->dim->n_out = 0;
4763         }
4764         return bset;
4765 error:
4766         isl_mat_free(mat);
4767         isl_basic_set_free(bset);
4768         return NULL;
4769 }
4770
4771 /* Apply a preimage specified by "mat" on the parameters of "set".
4772  * set is assumed to have only parameters and divs.
4773  */
4774 static struct isl_set *set_parameter_preimage(
4775         struct isl_set *set, struct isl_mat *mat)
4776 {
4777         struct isl_dim *dim = NULL;
4778         unsigned nparam;
4779
4780         if (!set || !mat)
4781                 goto error;
4782
4783         dim = isl_dim_copy(set->dim);
4784         dim = isl_dim_cow(dim);
4785         if (!dim)
4786                 goto error;
4787
4788         nparam = isl_set_dim(set, isl_dim_param);
4789
4790         isl_assert(set->ctx, mat->n_row == 1 + nparam, goto error);
4791
4792         dim->nparam = 0;
4793         dim->n_out = nparam;
4794         isl_set_reset_dim(set, dim);
4795         set = isl_set_preimage(set, mat);
4796         if (!set)
4797                 goto error2;
4798         dim = isl_dim_copy(set->dim);
4799         dim = isl_dim_cow(dim);
4800         if (!dim)
4801                 goto error2;
4802         dim->nparam = dim->n_out;
4803         dim->n_out = 0;
4804         isl_set_reset_dim(set, dim);
4805         return set;
4806 error:
4807         isl_dim_free(dim);
4808         isl_mat_free(mat);
4809 error2:
4810         isl_set_free(set);
4811         return NULL;
4812 }
4813
4814 /* Intersect the basic set "bset" with the affine space specified by the
4815  * equalities in "eq".
4816  */
4817 static struct isl_basic_set *basic_set_append_equalities(
4818         struct isl_basic_set *bset, struct isl_mat *eq)
4819 {
4820         int i, k;
4821         unsigned len;
4822
4823         if (!bset || !eq)
4824                 goto error;
4825
4826         bset = isl_basic_set_extend_dim(bset, isl_dim_copy(bset->dim), 0,
4827                                         eq->n_row, 0);
4828         if (!bset)
4829                 goto error;
4830
4831         len = 1 + isl_dim_total(bset->dim) + bset->extra;
4832         for (i = 0; i < eq->n_row; ++i) {
4833                 k = isl_basic_set_alloc_equality(bset);
4834                 if (k < 0)
4835                         goto error;
4836                 isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
4837                 isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
4838         }
4839         isl_mat_free(eq);
4840
4841         bset = isl_basic_set_gauss(bset, NULL);
4842         bset = isl_basic_set_finalize(bset);
4843
4844         return bset;
4845 error:
4846         isl_mat_free(eq);
4847         isl_basic_set_free(bset);
4848         return NULL;
4849 }
4850
4851 /* Intersect the set "set" with the affine space specified by the
4852  * equalities in "eq".
4853  */
4854 static struct isl_set *set_append_equalities(struct isl_set *set,
4855         struct isl_mat *eq)
4856 {
4857         int i;
4858
4859         if (!set || !eq)
4860                 goto error;
4861
4862         for (i = 0; i < set->n; ++i) {
4863                 set->p[i] = basic_set_append_equalities(set->p[i],
4864                                         isl_mat_copy(eq));
4865                 if (!set->p[i])
4866                         goto error;
4867         }
4868         isl_mat_free(eq);
4869         return set;
4870 error:
4871         isl_mat_free(eq);
4872         isl_set_free(set);
4873         return NULL;
4874 }
4875
4876 /* Project the given basic set onto its parameter domain, possibly introducing
4877  * new, explicit, existential variables in the constraints.
4878  * The input has parameters and (possibly implicit) existential variables.
4879  * The output has the same parameters, but only
4880  * explicit existentially quantified variables.
4881  *
4882  * The actual projection is performed by pip, but pip doesn't seem
4883  * to like equalities very much, so we first remove the equalities
4884  * among the parameters by performing a variable compression on
4885  * the parameters.  Afterward, an inverse transformation is performed
4886  * and the equalities among the parameters are inserted back in.
4887  */
4888 static struct isl_set *parameter_compute_divs(struct isl_basic_set *bset)
4889 {
4890         int i, j;
4891         struct isl_mat *eq;
4892         struct isl_mat *T, *T2;
4893         struct isl_set *set;
4894         unsigned nparam, n_div;
4895
4896         bset = isl_basic_set_cow(bset);
4897         if (!bset)
4898                 return NULL;
4899
4900         if (bset->n_eq == 0)
4901                 return isl_basic_set_lexmin(bset);
4902
4903         isl_basic_set_gauss(bset, NULL);
4904
4905         nparam = isl_basic_set_dim(bset, isl_dim_param);
4906         n_div = isl_basic_set_dim(bset, isl_dim_div);
4907
4908         for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
4909                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + j]))
4910                         ++i;
4911         }
4912         if (i == bset->n_eq)
4913                 return isl_basic_set_lexmin(bset);
4914
4915         eq = isl_mat_sub_alloc(bset->ctx, bset->eq, i, bset->n_eq - i,
4916                 0, 1 + nparam);
4917         eq = isl_mat_cow(eq);
4918         T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
4919         if (T && T->n_col == 0) {
4920                 isl_mat_free(T);
4921                 isl_mat_free(T2);
4922                 isl_mat_free(eq);
4923                 bset = isl_basic_set_set_to_empty(bset);
4924                 return isl_set_from_basic_set(bset);
4925         }
4926         bset = basic_set_parameter_preimage(bset, T);
4927
4928         set = isl_basic_set_lexmin(bset);
4929         set = set_parameter_preimage(set, T2);
4930         set = set_append_equalities(set, eq);
4931         return set;
4932 }
4933
4934 /* Compute an explicit representation for all the existentially
4935  * quantified variables.
4936  * The input and output dimensions are first turned into parameters.
4937  * compute_divs then returns a map with the same parameters and
4938  * no input or output dimensions and the dimension specification
4939  * is reset to that of the input.
4940  */
4941 static struct isl_map *compute_divs(struct isl_basic_map *bmap)
4942 {
4943         struct isl_basic_set *bset;
4944         struct isl_set *set;
4945         struct isl_map *map;
4946         struct isl_dim *dim, *orig_dim = NULL;
4947         unsigned         nparam;
4948         unsigned         n_in;
4949         unsigned         n_out;
4950
4951         bmap = isl_basic_map_cow(bmap);
4952         if (!bmap)
4953                 return NULL;
4954
4955         nparam = isl_basic_map_dim(bmap, isl_dim_param);
4956         n_in = isl_basic_map_dim(bmap, isl_dim_in);
4957         n_out = isl_basic_map_dim(bmap, isl_dim_out);
4958         dim = isl_dim_set_alloc(bmap->ctx, nparam + n_in + n_out, 0);
4959         if (!dim)
4960                 goto error;
4961
4962         orig_dim = bmap->dim;
4963         bmap->dim = dim;
4964         bset = (struct isl_basic_set *)bmap;
4965
4966         set = parameter_compute_divs(bset);
4967         map = (struct isl_map *)set;
4968         map = isl_map_reset_dim(map, orig_dim);
4969
4970         return map;
4971 error:
4972         isl_basic_map_free(bmap);
4973         return NULL;
4974 }
4975
4976 static int basic_map_divs_known(__isl_keep isl_basic_map *bmap)
4977 {
4978         int i;
4979         unsigned off;
4980
4981         if (!bmap)
4982                 return -1;
4983
4984         off = isl_dim_total(bmap->dim);
4985         for (i = 0; i < bmap->n_div; ++i) {
4986                 if (isl_int_is_zero(bmap->div[i][0]))
4987                         return 0;
4988                 isl_assert(bmap->ctx, isl_int_is_zero(bmap->div[i][1+1+off+i]),
4989                                 return -1);
4990         }
4991         return 1;
4992 }
4993
4994 static int map_divs_known(__isl_keep isl_map *map)
4995 {
4996         int i;
4997
4998         if (!map)
4999                 return -1;
5000
5001         for (i = 0; i < map->n; ++i) {
5002                 int known = basic_map_divs_known(map->p[i]);
5003                 if (known <= 0)
5004                         return known;
5005         }
5006
5007         return 1;
5008 }
5009
5010 /* If bmap contains any unknown divs, then compute explicit
5011  * expressions for them.  However, this computation may be
5012  * quite expensive, so first try to remove divs that aren't
5013  * strictly needed.
5014  */
5015 struct isl_map *isl_basic_map_compute_divs(struct isl_basic_map *bmap)
5016 {
5017         int i;
5018         int known;
5019         struct isl_map *map;
5020
5021         known = basic_map_divs_known(bmap);
5022         if (known < 0)
5023                 goto error;
5024         if (known)
5025                 return isl_map_from_basic_map(bmap);
5026
5027         bmap = isl_basic_map_drop_redundant_divs(bmap);
5028
5029         known = basic_map_divs_known(bmap);
5030         if (known < 0)
5031                 goto error;
5032         if (known)
5033                 return isl_map_from_basic_map(bmap);
5034
5035         map = compute_divs(bmap);
5036         return map;
5037 error:
5038         isl_basic_map_free(bmap);
5039         return NULL;
5040 }
5041
5042 struct isl_map *isl_map_compute_divs(struct isl_map *map)
5043 {
5044         int i;
5045         int known;
5046         struct isl_map *res;
5047
5048         if (!map)
5049                 return NULL;
5050         if (map->n == 0)
5051                 return map;
5052
5053         known = map_divs_known(map);
5054         if (known < 0) {
5055                 isl_map_free(map);
5056                 return NULL;
5057         }
5058         if (known)
5059                 return map;
5060
5061         res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
5062         for (i = 1 ; i < map->n; ++i) {
5063                 struct isl_map *r2;
5064                 r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
5065                 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
5066                         res = isl_map_union_disjoint(res, r2);
5067                 else
5068                         res = isl_map_union(res, r2);
5069         }
5070         isl_map_free(map);
5071
5072         return res;
5073 }
5074
5075 struct isl_set *isl_basic_set_compute_divs(struct isl_basic_set *bset)
5076 {
5077         return (struct isl_set *)
5078                 isl_basic_map_compute_divs((struct isl_basic_map *)bset);
5079 }
5080
5081 struct isl_set *isl_set_compute_divs(struct isl_set *set)
5082 {
5083         return (struct isl_set *)
5084                 isl_map_compute_divs((struct isl_map *)set);
5085 }
5086
5087 struct isl_set *isl_map_domain(struct isl_map *map)
5088 {
5089         int i;
5090         struct isl_set *set;
5091
5092         if (!map)
5093                 goto error;
5094
5095         map = isl_map_cow(map);
5096         if (!map)
5097                 return NULL;
5098
5099         set = (struct isl_set *)map;
5100         set->dim = isl_dim_domain(set->dim);
5101         if (!set->dim)
5102                 goto error;
5103         for (i = 0; i < map->n; ++i) {
5104                 set->p[i] = isl_basic_map_domain(map->p[i]);
5105                 if (!set->p[i])
5106                         goto error;
5107         }
5108         ISL_F_CLR(set, ISL_MAP_DISJOINT);
5109         ISL_F_CLR(set, ISL_SET_NORMALIZED);
5110         return set;
5111 error:
5112         isl_map_free(map);
5113         return NULL;
5114 }
5115
5116 struct isl_map *isl_map_union_disjoint(
5117                         struct isl_map *map1, struct isl_map *map2)
5118 {
5119         int i;
5120         unsigned flags = 0;
5121         struct isl_map *map = NULL;
5122
5123         if (!map1 || !map2)
5124                 goto error;
5125
5126         if (map1->n == 0) {
5127                 isl_map_free(map1);
5128                 return map2;
5129         }
5130         if (map2->n == 0) {
5131                 isl_map_free(map2);
5132                 return map1;
5133         }
5134
5135         isl_assert(map1->ctx, isl_dim_equal(map1->dim, map2->dim), goto error);
5136
5137         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
5138             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
5139                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
5140
5141         map = isl_map_alloc_dim(isl_dim_copy(map1->dim),
5142                                 map1->n + map2->n, flags);
5143         if (!map)
5144                 goto error;
5145         for (i = 0; i < map1->n; ++i) {
5146                 map = isl_map_add_basic_map(map,
5147                                   isl_basic_map_copy(map1->p[i]));
5148                 if (!map)
5149                         goto error;
5150         }
5151         for (i = 0; i < map2->n; ++i) {
5152                 map = isl_map_add_basic_map(map,
5153                                   isl_basic_map_copy(map2->p[i]));
5154                 if (!map)
5155                         goto error;
5156         }
5157         isl_map_free(map1);
5158         isl_map_free(map2);
5159         return map;
5160 error:
5161         isl_map_free(map);
5162         isl_map_free(map1);
5163         isl_map_free(map2);
5164         return NULL;
5165 }
5166
5167 struct isl_map *isl_map_union(struct isl_map *map1, struct isl_map *map2)
5168 {
5169         map1 = isl_map_union_disjoint(map1, map2);
5170         if (!map1)
5171                 return NULL;
5172         if (map1->n > 1)
5173                 ISL_F_CLR(map1, ISL_MAP_DISJOINT);
5174         return map1;
5175 }
5176
5177 struct isl_set *isl_set_union_disjoint(
5178                         struct isl_set *set1, struct isl_set *set2)
5179 {
5180         return (struct isl_set *)
5181                 isl_map_union_disjoint(
5182                         (struct isl_map *)set1, (struct isl_map *)set2);
5183 }
5184
5185 struct isl_set *isl_set_union(struct isl_set *set1, struct isl_set *set2)
5186 {
5187         return (struct isl_set *)
5188                 isl_map_union((struct isl_map *)set1, (struct isl_map *)set2);
5189 }
5190
5191 struct isl_map *isl_map_intersect_range(
5192                 struct isl_map *map, struct isl_set *set)
5193 {
5194         unsigned flags = 0;
5195         struct isl_map *result;
5196         int i, j;
5197
5198         if (!map || !set)
5199                 goto error;
5200
5201         if (ISL_F_ISSET(map, ISL_MAP_DISJOINT) &&
5202             ISL_F_ISSET(set, ISL_MAP_DISJOINT))
5203                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
5204
5205         result = isl_map_alloc_dim(isl_dim_copy(map->dim),
5206                                         map->n * set->n, flags);
5207         if (!result)
5208                 goto error;
5209         for (i = 0; i < map->n; ++i)
5210                 for (j = 0; j < set->n; ++j) {
5211                         result = isl_map_add_basic_map(result,
5212                             isl_basic_map_intersect_range(
5213                                 isl_basic_map_copy(map->p[i]),
5214                                 isl_basic_set_copy(set->p[j])));
5215                         if (!result)
5216                                 goto error;
5217                 }
5218         isl_map_free(map);
5219         isl_set_free(set);
5220         return result;
5221 error:
5222         isl_map_free(map);
5223         isl_set_free(set);
5224         return NULL;
5225 }
5226
5227 struct isl_map *isl_map_intersect_domain(
5228                 struct isl_map *map, struct isl_set *set)
5229 {
5230         return isl_map_reverse(
5231                 isl_map_intersect_range(isl_map_reverse(map), set));
5232 }
5233
5234 struct isl_map *isl_map_apply_domain(
5235                 struct isl_map *map1, struct isl_map *map2)
5236 {
5237         if (!map1 || !map2)
5238                 goto error;
5239         map1 = isl_map_reverse(map1);
5240         map1 = isl_map_apply_range(map1, map2);
5241         return isl_map_reverse(map1);
5242 error:
5243         isl_map_free(map1);
5244         isl_map_free(map2);
5245         return NULL;
5246 }
5247
5248 struct isl_map *isl_map_apply_range(
5249                 struct isl_map *map1, struct isl_map *map2)
5250 {
5251         struct isl_dim *dim_result;
5252         struct isl_map *result;
5253         int i, j;
5254
5255         if (!map1 || !map2)
5256                 goto error;
5257
5258         dim_result = isl_dim_join(isl_dim_copy(map1->dim),
5259                                   isl_dim_copy(map2->dim));
5260
5261         result = isl_map_alloc_dim(dim_result, map1->n * map2->n, 0);
5262         if (!result)
5263                 goto error;
5264         for (i = 0; i < map1->n; ++i)
5265                 for (j = 0; j < map2->n; ++j) {
5266                         result = isl_map_add_basic_map(result,
5267                             isl_basic_map_apply_range(
5268                                 isl_basic_map_copy(map1->p[i]),
5269                                 isl_basic_map_copy(map2->p[j])));
5270                         if (!result)
5271                                 goto error;
5272                 }
5273         isl_map_free(map1);
5274         isl_map_free(map2);
5275         if (result && result->n <= 1)
5276                 ISL_F_SET(result, ISL_MAP_DISJOINT);
5277         return result;
5278 error:
5279         isl_map_free(map1);
5280         isl_map_free(map2);
5281         return NULL;
5282 }
5283
5284 /*
5285  * returns range - domain
5286  */
5287 struct isl_basic_set *isl_basic_map_deltas(struct isl_basic_map *bmap)
5288 {
5289         isl_dim *dims, *target_dim;
5290         struct isl_basic_set *bset;
5291         unsigned dim;
5292         unsigned nparam;
5293         int i;
5294
5295         if (!bmap)
5296                 goto error;
5297         isl_assert(bmap->ctx, isl_dim_tuple_match(bmap->dim, isl_dim_in,
5298                                                   bmap->dim, isl_dim_out),
5299                    goto error);
5300         target_dim = isl_dim_domain(isl_basic_map_get_dim(bmap));
5301         dim = isl_basic_map_n_in(bmap);
5302         nparam = isl_basic_map_n_param(bmap);
5303         bset = isl_basic_set_from_basic_map(bmap);
5304         bset = isl_basic_set_cow(bset);
5305         dims = isl_basic_set_get_dim(bset);
5306         dims = isl_dim_add(dims, isl_dim_set, dim);
5307         bset = isl_basic_set_extend_dim(bset, dims, 0, dim, 0);
5308         bset = isl_basic_set_swap_vars(bset, 2*dim);
5309         for (i = 0; i < dim; ++i) {
5310                 int j = isl_basic_map_alloc_equality(
5311                                             (struct isl_basic_map *)bset);
5312                 if (j < 0)
5313                         goto error;
5314                 isl_seq_clr(bset->eq[j], 1 + isl_basic_set_total_dim(bset));
5315                 isl_int_set_si(bset->eq[j][1+nparam+i], 1);
5316                 isl_int_set_si(bset->eq[j][1+nparam+dim+i], 1);
5317                 isl_int_set_si(bset->eq[j][1+nparam+2*dim+i], -1);
5318         }
5319         bset = isl_basic_set_project_out(bset, isl_dim_set, dim, 2*dim);
5320         bset = isl_basic_set_reset_dim(bset, target_dim);
5321         return bset;
5322 error:
5323         isl_basic_map_free(bmap);
5324         return NULL;
5325 }
5326
5327 /*
5328  * returns range - domain
5329  */
5330 struct isl_set *isl_map_deltas(struct isl_map *map)
5331 {
5332         int i;
5333         isl_dim *dim;
5334         struct isl_set *result;
5335
5336         if (!map)
5337                 return NULL;
5338
5339         isl_assert(map->ctx, isl_dim_tuple_match(map->dim, isl_dim_in,
5340                                                  map->dim, isl_dim_out),
5341                    goto error);
5342         dim = isl_map_get_dim(map);
5343         dim = isl_dim_domain(dim);
5344         result = isl_set_alloc_dim(dim, map->n, map->flags);
5345         if (!result)
5346                 goto error;
5347         for (i = 0; i < map->n; ++i)
5348                 result = isl_set_add_basic_set(result,
5349                           isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
5350         isl_map_free(map);
5351         return result;
5352 error:
5353         isl_map_free(map);
5354         return NULL;
5355 }
5356
5357 static struct isl_basic_map *basic_map_identity(struct isl_dim *dims)
5358 {
5359         struct isl_basic_map *bmap;
5360         unsigned nparam;
5361         unsigned dim;
5362         int i;
5363
5364         if (!dims)
5365                 return NULL;
5366
5367         nparam = dims->nparam;
5368         dim = dims->n_out;
5369         bmap = isl_basic_map_alloc_dim(dims, 0, dim, 0);
5370         if (!bmap)
5371                 goto error;
5372
5373         for (i = 0; i < dim; ++i) {
5374                 int j = isl_basic_map_alloc_equality(bmap);
5375                 if (j < 0)
5376                         goto error;
5377                 isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
5378                 isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
5379                 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], -1);
5380         }
5381         return isl_basic_map_finalize(bmap);
5382 error:
5383         isl_basic_map_free(bmap);
5384         return NULL;
5385 }
5386
5387 struct isl_basic_map *isl_basic_map_identity(struct isl_dim *set_dim)
5388 {
5389         struct isl_dim *dim = isl_dim_map(set_dim);
5390         if (!dim)
5391                 return NULL;
5392         return basic_map_identity(dim);
5393 }
5394
5395 struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model)
5396 {
5397         if (!model || !model->dim)
5398                 return NULL;
5399         isl_assert(model->ctx,
5400                         model->dim->n_in == model->dim->n_out, return NULL);
5401         return basic_map_identity(isl_dim_copy(model->dim));
5402 }
5403
5404 static struct isl_map *map_identity(struct isl_dim *dim)
5405 {
5406         struct isl_map *map = isl_map_alloc_dim(dim, 1, ISL_MAP_DISJOINT);
5407         return isl_map_add_basic_map(map, basic_map_identity(isl_dim_copy(dim)));
5408 }
5409
5410 struct isl_map *isl_map_identity(struct isl_dim *set_dim)
5411 {
5412         struct isl_dim *dim = isl_dim_map(set_dim);
5413         if (!dim)
5414                 return NULL;
5415         return map_identity(dim);
5416 }
5417
5418 struct isl_map *isl_map_identity_like(struct isl_map *model)
5419 {
5420         if (!model || !model->dim)
5421                 return NULL;
5422         isl_assert(model->ctx,
5423                         model->dim->n_in == model->dim->n_out, return NULL);
5424         return map_identity(isl_dim_copy(model->dim));
5425 }
5426
5427 struct isl_map *isl_map_identity_like_basic_map(struct isl_basic_map *model)
5428 {
5429         if (!model || !model->dim)
5430                 return NULL;
5431         isl_assert(model->ctx,
5432                         model->dim->n_in == model->dim->n_out, return NULL);
5433         return map_identity(isl_dim_copy(model->dim));
5434 }
5435
5436 /* Construct a basic set with all set dimensions having only non-negative
5437  * values.
5438  */
5439 struct isl_basic_set *isl_basic_set_positive_orthant(struct isl_dim *dims)
5440 {
5441         int i;
5442         unsigned nparam;
5443         unsigned dim;
5444         struct isl_basic_set *bset;
5445
5446         if (!dims)
5447                 return NULL;
5448         nparam = dims->nparam;
5449         dim = dims->n_out;
5450         bset = isl_basic_set_alloc_dim(dims, 0, 0, dim);
5451         if (!bset)
5452                 return NULL;
5453         for (i = 0; i < dim; ++i) {
5454                 int k = isl_basic_set_alloc_inequality(bset);
5455                 if (k < 0)
5456                         goto error;
5457                 isl_seq_clr(bset->ineq[k], 1 + isl_basic_set_total_dim(bset));
5458                 isl_int_set_si(bset->ineq[k][1 + nparam + i], 1);
5459         }
5460         return bset;
5461 error:
5462         isl_basic_set_free(bset);
5463         return NULL;
5464 }
5465
5466 __isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set,
5467         enum isl_dim_type type, unsigned first, unsigned n)
5468 {
5469         int i;
5470         isl_basic_set *nonneg = NULL;
5471         isl_basic_set *neg = NULL;
5472
5473         if (!set)
5474                 return NULL;
5475         if (n == 0)
5476                 return set;
5477
5478         isl_assert(set->ctx, first + n <= isl_set_dim(set, type), goto error);
5479
5480         for (i = 0; i < n; ++i) {
5481                 int k;
5482
5483                 neg = NULL;
5484                 nonneg = isl_basic_set_alloc_dim(isl_set_get_dim(set), 0, 0, 1);
5485                 k = isl_basic_set_alloc_inequality(nonneg);
5486                 if (k < 0)
5487                         goto error;
5488                 isl_seq_clr(nonneg->ineq[k], 1 + isl_basic_set_total_dim(nonneg));
5489                 isl_int_set_si(nonneg->ineq[k][pos(set->dim, type) + first + i], 1);
5490
5491                 neg = isl_basic_set_alloc_dim(isl_set_get_dim(set), 0, 0, 1);
5492                 k = isl_basic_set_alloc_inequality(neg);
5493                 if (k < 0)
5494                         goto error;
5495                 isl_seq_clr(neg->ineq[k], 1 + isl_basic_set_total_dim(neg));
5496                 isl_int_set_si(neg->ineq[k][0], -1);
5497                 isl_int_set_si(neg->ineq[k][pos(set->dim, type) + first + i], -1);
5498
5499                 set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
5500         }
5501
5502         return set;
5503 error:
5504         isl_basic_set_free(nonneg);
5505         isl_basic_set_free(neg);
5506         isl_set_free(set);
5507         return NULL;
5508 }
5509
5510 int isl_set_is_equal(struct isl_set *set1, struct isl_set *set2)
5511 {
5512         return isl_map_is_equal((struct isl_map *)set1, (struct isl_map *)set2);
5513 }
5514
5515 int isl_basic_map_is_subset(
5516                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
5517 {
5518         int is_subset;
5519         struct isl_map *map1;
5520         struct isl_map *map2;
5521
5522         if (!bmap1 || !bmap2)
5523                 return -1;
5524
5525         map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
5526         map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
5527
5528         is_subset = isl_map_is_subset(map1, map2);
5529
5530         isl_map_free(map1);
5531         isl_map_free(map2);
5532
5533         return is_subset;
5534 }
5535
5536 int isl_basic_map_is_equal(
5537                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
5538 {
5539         int is_subset;
5540
5541         if (!bmap1 || !bmap2)
5542                 return -1;
5543         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
5544         if (is_subset != 1)
5545                 return is_subset;
5546         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
5547         return is_subset;
5548 }
5549
5550 int isl_basic_set_is_equal(
5551                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
5552 {
5553         return isl_basic_map_is_equal(
5554                 (struct isl_basic_map *)bset1, (struct isl_basic_map *)bset2);
5555 }
5556
5557 int isl_map_is_empty(struct isl_map *map)
5558 {
5559         int i;
5560         int is_empty;
5561
5562         if (!map)
5563                 return -1;
5564         for (i = 0; i < map->n; ++i) {
5565                 is_empty = isl_basic_map_is_empty(map->p[i]);
5566                 if (is_empty < 0)
5567                         return -1;
5568                 if (!is_empty)
5569                         return 0;
5570         }
5571         return 1;
5572 }
5573
5574 int isl_map_fast_is_empty(struct isl_map *map)
5575 {
5576         return map ? map->n == 0 : -1;
5577 }
5578
5579 int isl_set_fast_is_empty(struct isl_set *set)
5580 {
5581         return set ? set->n == 0 : -1;
5582 }
5583
5584 int isl_set_is_empty(struct isl_set *set)
5585 {
5586         return isl_map_is_empty((struct isl_map *)set);
5587 }
5588
5589 int isl_map_has_equal_dim(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
5590 {
5591         if (!map1 || !map2)
5592                 return -1;
5593
5594         return isl_dim_equal(map1->dim, map2->dim);
5595 }
5596
5597 int isl_set_has_equal_dim(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
5598 {
5599         if (!set1 || !set2)
5600                 return -1;
5601
5602         return isl_dim_equal(set1->dim, set2->dim);
5603 }
5604
5605 int isl_map_is_equal(struct isl_map *map1, struct isl_map *map2)
5606 {
5607         int is_subset;
5608
5609         if (!map1 || !map2)
5610                 return -1;
5611         is_subset = isl_map_is_subset(map1, map2);
5612         if (is_subset != 1)
5613                 return is_subset;
5614         is_subset = isl_map_is_subset(map2, map1);
5615         return is_subset;
5616 }
5617
5618 int isl_basic_map_is_strict_subset(
5619                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
5620 {
5621         int is_subset;
5622
5623         if (!bmap1 || !bmap2)
5624                 return -1;
5625         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
5626         if (is_subset != 1)
5627                 return is_subset;
5628         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
5629         if (is_subset == -1)
5630                 return is_subset;
5631         return !is_subset;
5632 }
5633
5634 int isl_map_is_strict_subset(struct isl_map *map1, struct isl_map *map2)
5635 {
5636         int is_subset;
5637
5638         if (!map1 || !map2)
5639                 return -1;
5640         is_subset = isl_map_is_subset(map1, map2);
5641         if (is_subset != 1)
5642                 return is_subset;
5643         is_subset = isl_map_is_subset(map2, map1);
5644         if (is_subset == -1)
5645                 return is_subset;
5646         return !is_subset;
5647 }
5648
5649 int isl_set_is_strict_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
5650 {
5651         return isl_map_is_strict_subset((isl_map *)set1, (isl_map *)set2);
5652 }
5653
5654 int isl_basic_map_is_universe(struct isl_basic_map *bmap)
5655 {
5656         if (!bmap)
5657                 return -1;
5658         return bmap->n_eq == 0 && bmap->n_ineq == 0;
5659 }
5660
5661 int isl_basic_set_is_universe(struct isl_basic_set *bset)
5662 {
5663         if (!bset)
5664                 return -1;
5665         return bset->n_eq == 0 && bset->n_ineq == 0;
5666 }
5667
5668 int isl_map_fast_is_universe(__isl_keep isl_map *map)
5669 {
5670         int i;
5671
5672         if (!map)
5673                 return -1;
5674
5675         for (i = 0; i < map->n; ++i) {
5676                 int r = isl_basic_map_is_universe(map->p[i]);
5677                 if (r < 0 || r)
5678                         return r;
5679         }
5680
5681         return 0;
5682 }
5683
5684 int isl_set_fast_is_universe(__isl_keep isl_set *set)
5685 {
5686         return isl_map_fast_is_universe((isl_map *) set);
5687 }
5688
5689 int isl_basic_map_is_empty(struct isl_basic_map *bmap)
5690 {
5691         struct isl_basic_set *bset = NULL;
5692         struct isl_vec *sample = NULL;
5693         int empty;
5694         unsigned total;
5695
5696         if (!bmap)
5697                 return -1;
5698
5699         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
5700                 return 1;
5701
5702         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
5703                 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
5704                 copy = isl_basic_map_remove_redundancies(copy);
5705                 empty = ISL_F_ISSET(copy, ISL_BASIC_MAP_EMPTY);
5706                 isl_basic_map_free(copy);
5707                 return empty;
5708         }
5709
5710         total = 1 + isl_basic_map_total_dim(bmap);
5711         if (bmap->sample && bmap->sample->size == total) {
5712                 int contains = isl_basic_map_contains(bmap, bmap->sample);
5713                 if (contains < 0)
5714                         return -1;
5715                 if (contains)
5716                         return 0;
5717         }
5718         isl_vec_free(bmap->sample);
5719         bmap->sample = NULL;
5720         bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
5721         if (!bset)
5722                 return -1;
5723         sample = isl_basic_set_sample_vec(bset);
5724         if (!sample)
5725                 return -1;
5726         empty = sample->size == 0;
5727         isl_vec_free(bmap->sample);
5728         bmap->sample = sample;
5729         if (empty)
5730                 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
5731
5732         return empty;
5733 }
5734
5735 int isl_basic_map_fast_is_empty(struct isl_basic_map *bmap)
5736 {
5737         if (!bmap)
5738                 return -1;
5739         return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY);
5740 }
5741
5742 int isl_basic_set_fast_is_empty(struct isl_basic_set *bset)
5743 {
5744         if (!bset)
5745                 return -1;
5746         return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY);
5747 }
5748
5749 int isl_basic_set_is_empty(struct isl_basic_set *bset)
5750 {
5751         return isl_basic_map_is_empty((struct isl_basic_map *)bset);
5752 }
5753
5754 struct isl_map *isl_basic_map_union(
5755         struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
5756 {
5757         struct isl_map *map;
5758         if (!bmap1 || !bmap2)
5759                 return NULL;
5760
5761         isl_assert(bmap1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim), goto error);
5762
5763         map = isl_map_alloc_dim(isl_dim_copy(bmap1->dim), 2, 0);
5764         if (!map)
5765                 goto error;
5766         map = isl_map_add_basic_map(map, bmap1);
5767         map = isl_map_add_basic_map(map, bmap2);
5768         return map;
5769 error:
5770         isl_basic_map_free(bmap1);
5771         isl_basic_map_free(bmap2);
5772         return NULL;
5773 }
5774
5775 struct isl_set *isl_basic_set_union(
5776                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
5777 {
5778         return (struct isl_set *)isl_basic_map_union(
5779                                             (struct isl_basic_map *)bset1,
5780                                             (struct isl_basic_map *)bset2);
5781 }
5782
5783 /* Order divs such that any div only depends on previous divs */
5784 struct isl_basic_map *isl_basic_map_order_divs(struct isl_basic_map *bmap)
5785 {
5786         int i;
5787         unsigned off;
5788
5789         if (!bmap)
5790                 return NULL;
5791
5792         off = isl_dim_total(bmap->dim);
5793
5794         for (i = 0; i < bmap->n_div; ++i) {
5795                 int pos;
5796                 if (isl_int_is_zero(bmap->div[i][0]))
5797                         continue;
5798                 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
5799                                                             bmap->n_div-i);
5800                 if (pos == -1)
5801                         continue;
5802                 isl_basic_map_swap_div(bmap, i, i + pos);
5803                 --i;
5804         }
5805         return bmap;
5806 }
5807
5808 struct isl_basic_set *isl_basic_set_order_divs(struct isl_basic_set *bset)
5809 {
5810         return (struct isl_basic_set *)
5811                 isl_basic_map_order_divs((struct isl_basic_map *)bset);
5812 }
5813
5814 __isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
5815 {
5816         int i;
5817
5818         if (!map)
5819                 return 0;
5820
5821         for (i = 0; i < map->n; ++i) {
5822                 map->p[i] = isl_basic_map_order_divs(map->p[i]);
5823                 if (!map->p[i])
5824                         goto error;
5825         }
5826
5827         return map;
5828 error:
5829         isl_map_free(map);
5830         return NULL;
5831 }
5832
5833 /* Look for a div in dst that corresponds to the div "div" in src.
5834  * The divs before "div" in src and dst are assumed to be the same.
5835  * 
5836  * Returns -1 if no corresponding div was found and the position
5837  * of the corresponding div in dst otherwise.
5838  */
5839 static int find_div(struct isl_basic_map *dst,
5840                         struct isl_basic_map *src, unsigned div)
5841 {
5842         int i;
5843
5844         unsigned total = isl_dim_total(src->dim);
5845
5846         isl_assert(dst->ctx, div <= dst->n_div, return -1);
5847         for (i = div; i < dst->n_div; ++i)
5848                 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total+div) &&
5849                     isl_seq_first_non_zero(dst->div[i]+1+1+total+div,
5850                                                 dst->n_div - div) == -1)
5851                         return i;
5852         return -1;
5853 }
5854
5855 struct isl_basic_map *isl_basic_map_align_divs(
5856                 struct isl_basic_map *dst, struct isl_basic_map *src)
5857 {
5858         int i;
5859         unsigned total = isl_dim_total(src->dim);
5860
5861         if (!dst || !src)
5862                 goto error;
5863
5864         if (src->n_div == 0)
5865                 return dst;
5866
5867         for (i = 0; i < src->n_div; ++i)
5868                 isl_assert(src->ctx, !isl_int_is_zero(src->div[i][0]), goto error);
5869
5870         src = isl_basic_map_order_divs(src);
5871         dst = isl_basic_map_cow(dst);
5872         dst = isl_basic_map_extend_dim(dst, isl_dim_copy(dst->dim),
5873                         src->n_div, 0, 2 * src->n_div);
5874         if (!dst)
5875                 return NULL;
5876         for (i = 0; i < src->n_div; ++i) {
5877                 int j = find_div(dst, src, i);
5878                 if (j < 0) {
5879                         j = isl_basic_map_alloc_div(dst);
5880                         if (j < 0)
5881                                 goto error;
5882                         isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i);
5883                         isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i);
5884                         if (isl_basic_map_add_div_constraints(dst, j) < 0)
5885                                 goto error;
5886                 }
5887                 if (j != i)
5888                         isl_basic_map_swap_div(dst, i, j);
5889         }
5890         return dst;
5891 error:
5892         isl_basic_map_free(dst);
5893         return NULL;
5894 }
5895
5896 struct isl_basic_set *isl_basic_set_align_divs(
5897                 struct isl_basic_set *dst, struct isl_basic_set *src)
5898 {
5899         return (struct isl_basic_set *)isl_basic_map_align_divs(
5900                 (struct isl_basic_map *)dst, (struct isl_basic_map *)src);
5901 }
5902
5903 struct isl_map *isl_map_align_divs(struct isl_map *map)
5904 {
5905         int i;
5906
5907         if (!map)
5908                 return NULL;
5909         if (map->n == 0)
5910                 return map;
5911         map = isl_map_compute_divs(map);
5912         map = isl_map_cow(map);
5913         if (!map)
5914                 return NULL;
5915
5916         for (i = 1; i < map->n; ++i)
5917                 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
5918         for (i = 1; i < map->n; ++i)
5919                 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
5920
5921         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
5922         return map;
5923 }
5924
5925 struct isl_set *isl_set_align_divs(struct isl_set *set)
5926 {
5927         return (struct isl_set *)isl_map_align_divs((struct isl_map *)set);
5928 }
5929
5930 struct isl_set *isl_set_apply(struct isl_set *set, struct isl_map *map)
5931 {
5932         if (!set || !map)
5933                 goto error;
5934         isl_assert(set->ctx, isl_map_compatible_domain(map, set), goto error);
5935         map = isl_map_intersect_domain(map, set);
5936         set = isl_map_range(map);
5937         return set;
5938 error:
5939         isl_set_free(set);
5940         isl_map_free(map);
5941         return NULL;
5942 }
5943
5944 /* There is no need to cow as removing empty parts doesn't change
5945  * the meaning of the set.
5946  */
5947 struct isl_map *isl_map_remove_empty_parts(struct isl_map *map)
5948 {
5949         int i;
5950
5951         if (!map)
5952                 return NULL;
5953
5954         for (i = map->n-1; i >= 0; --i) {
5955                 if (!ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_EMPTY))
5956                         continue;
5957                 isl_basic_map_free(map->p[i]);
5958                 if (i != map->n-1) {
5959                         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
5960                         map->p[i] = map->p[map->n-1];
5961                 }
5962                 map->n--;
5963         }
5964
5965         return map;
5966 }
5967
5968 struct isl_set *isl_set_remove_empty_parts(struct isl_set *set)
5969 {
5970         return (struct isl_set *)
5971                 isl_map_remove_empty_parts((struct isl_map *)set);
5972 }
5973
5974 struct isl_basic_map *isl_map_copy_basic_map(struct isl_map *map)
5975 {
5976         struct isl_basic_map *bmap;
5977         if (!map || map->n == 0)
5978                 return NULL;
5979         bmap = map->p[map->n-1];
5980         isl_assert(map->ctx, ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL), return NULL);
5981         return isl_basic_map_copy(bmap);
5982 }
5983
5984 struct isl_basic_set *isl_set_copy_basic_set(struct isl_set *set)
5985 {
5986         return (struct isl_basic_set *)
5987                 isl_map_copy_basic_map((struct isl_map *)set);
5988 }
5989
5990 __isl_give isl_map *isl_map_drop_basic_map(__isl_take isl_map *map,
5991                                                 __isl_keep isl_basic_map *bmap)
5992 {
5993         int i;
5994
5995         if (!map || !bmap)
5996                 goto error;
5997         for (i = map->n-1; i >= 0; --i) {
5998                 if (map->p[i] != bmap)
5999                         continue;
6000                 map = isl_map_cow(map);
6001                 if (!map)
6002                         goto error;
6003                 isl_basic_map_free(map->p[i]);
6004                 if (i != map->n-1) {
6005                         ISL_F_CLR(map, ISL_SET_NORMALIZED);
6006                         map->p[i] = map->p[map->n-1];
6007                 }
6008                 map->n--;
6009                 return map;
6010         }
6011         return map;
6012 error:
6013         isl_map_free(map);
6014         return NULL;
6015 }
6016
6017 struct isl_set *isl_set_drop_basic_set(struct isl_set *set,
6018                                                 struct isl_basic_set *bset)
6019 {
6020         return (struct isl_set *)isl_map_drop_basic_map((struct isl_map *)set,
6021                                                 (struct isl_basic_map *)bset);
6022 }
6023
6024 /* Given two basic sets bset1 and bset2, compute the maximal difference
6025  * between the values of dimension pos in bset1 and those in bset2
6026  * for any common value of the parameters and dimensions preceding pos.
6027  */
6028 static enum isl_lp_result basic_set_maximal_difference_at(
6029         __isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2,
6030         int pos, isl_int *opt)
6031 {
6032         struct isl_dim *dims;
6033         struct isl_basic_map *bmap1 = NULL;
6034         struct isl_basic_map *bmap2 = NULL;
6035         struct isl_ctx *ctx;
6036         struct isl_vec *obj;
6037         unsigned total;
6038         unsigned nparam;
6039         unsigned dim1, dim2;
6040         enum isl_lp_result res;
6041
6042         if (!bset1 || !bset2)
6043                 return isl_lp_error;
6044
6045         nparam = isl_basic_set_n_param(bset1);
6046         dim1 = isl_basic_set_n_dim(bset1);
6047         dim2 = isl_basic_set_n_dim(bset2);
6048         dims = isl_dim_alloc(bset1->ctx, nparam, pos, dim1 - pos);
6049         bmap1 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset1), dims);
6050         dims = isl_dim_alloc(bset2->ctx, nparam, pos, dim2 - pos);
6051         bmap2 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset2), dims);
6052         if (!bmap1 || !bmap2)
6053                 goto error;
6054         bmap1 = isl_basic_map_cow(bmap1);
6055         bmap1 = isl_basic_map_extend(bmap1, nparam,
6056                         pos, (dim1 - pos) + (dim2 - pos),
6057                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
6058         bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos);
6059         if (!bmap1)
6060                 goto error;
6061         total = isl_basic_map_total_dim(bmap1);
6062         ctx = bmap1->ctx;
6063         obj = isl_vec_alloc(ctx, 1 + total);
6064         isl_seq_clr(obj->block.data, 1 + total);
6065         isl_int_set_si(obj->block.data[1+nparam+pos], 1);
6066         isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
6067         if (!obj)
6068                 goto error;
6069         res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
6070                                         opt, NULL, NULL);
6071         isl_basic_map_free(bmap1);
6072         isl_vec_free(obj);
6073         return res;
6074 error:
6075         isl_basic_map_free(bmap1);
6076         isl_basic_map_free(bmap2);
6077         return isl_lp_error;
6078 }
6079
6080 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
6081  * for any common value of the parameters and dimensions preceding pos
6082  * in both basic sets, the values of dimension pos in bset1 are
6083  * smaller or larger than those in bset2.
6084  *
6085  * Returns
6086  *       1 if bset1 follows bset2
6087  *      -1 if bset1 precedes bset2
6088  *       0 if bset1 and bset2 are incomparable
6089  *      -2 if some error occurred.
6090  */
6091 int isl_basic_set_compare_at(struct isl_basic_set *bset1,
6092         struct isl_basic_set *bset2, int pos)
6093 {
6094         isl_int opt;
6095         enum isl_lp_result res;
6096         int cmp;
6097
6098         isl_int_init(opt);
6099
6100         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
6101
6102         if (res == isl_lp_empty)
6103                 cmp = 0;
6104         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
6105                   res == isl_lp_unbounded)
6106                 cmp = 1;
6107         else if (res == isl_lp_ok && isl_int_is_neg(opt))
6108                 cmp = -1;
6109         else
6110                 cmp = -2;
6111
6112         isl_int_clear(opt);
6113         return cmp;
6114 }
6115
6116 /* Given two basic sets bset1 and bset2, check whether
6117  * for any common value of the parameters and dimensions preceding pos
6118  * there is a value of dimension pos in bset1 that is larger
6119  * than a value of the same dimension in bset2.
6120  *
6121  * Return
6122  *       1 if there exists such a pair
6123  *       0 if there is no such pair, but there is a pair of equal values
6124  *      -1 otherwise
6125  *      -2 if some error occurred.
6126  */
6127 int isl_basic_set_follows_at(__isl_keep isl_basic_set *bset1,
6128         __isl_keep isl_basic_set *bset2, int pos)
6129 {
6130         isl_int opt;
6131         enum isl_lp_result res;
6132         int cmp;
6133
6134         isl_int_init(opt);
6135
6136         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
6137
6138         if (res == isl_lp_empty)
6139                 cmp = -1;
6140         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
6141                   res == isl_lp_unbounded)
6142                 cmp = 1;
6143         else if (res == isl_lp_ok && isl_int_is_neg(opt))
6144                 cmp = -1;
6145         else if (res == isl_lp_ok)
6146                 cmp = 0;
6147         else
6148                 cmp = -2;
6149
6150         isl_int_clear(opt);
6151         return cmp;
6152 }
6153
6154 /* Given two sets set1 and set2, check whether
6155  * for any common value of the parameters and dimensions preceding pos
6156  * there is a value of dimension pos in set1 that is larger
6157  * than a value of the same dimension in set2.
6158  *
6159  * Return
6160  *       1 if there exists such a pair
6161  *       0 if there is no such pair, but there is a pair of equal values
6162  *      -1 otherwise
6163  *      -2 if some error occurred.
6164  */
6165 int isl_set_follows_at(__isl_keep isl_set *set1,
6166         __isl_keep isl_set *set2, int pos)
6167 {
6168         int i, j;
6169         int follows = -1;
6170
6171         if (!set1 || !set2)
6172                 return -2;
6173
6174         for (i = 0; i < set1->n; ++i)
6175                 for (j = 0; j < set2->n; ++j) {
6176                         int f;
6177                         f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
6178                         if (f == 1 || f == -2)
6179                                 return f;
6180                         if (f > follows)
6181                                 follows = f;
6182                 }
6183
6184         return follows;
6185 }
6186
6187 static int isl_basic_map_fast_has_fixed_var(struct isl_basic_map *bmap,
6188         unsigned pos, isl_int *val)
6189 {
6190         int i;
6191         int d;
6192         unsigned total;
6193
6194         if (!bmap)
6195                 return -1;
6196         total = isl_basic_map_total_dim(bmap);
6197         for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
6198                 for (; d+1 > pos; --d)
6199                         if (!isl_int_is_zero(bmap->eq[i][1+d]))
6200                                 break;
6201                 if (d != pos)
6202                         continue;
6203                 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
6204                         return 0;
6205                 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
6206                         return 0;
6207                 if (!isl_int_is_one(bmap->eq[i][1+d]))
6208                         return 0;
6209                 if (val)
6210                         isl_int_neg(*val, bmap->eq[i][0]);
6211                 return 1;
6212         }
6213         return 0;
6214 }
6215
6216 static int isl_map_fast_has_fixed_var(struct isl_map *map,
6217         unsigned pos, isl_int *val)
6218 {
6219         int i;
6220         isl_int v;
6221         isl_int tmp;
6222         int fixed;
6223
6224         if (!map)
6225                 return -1;
6226         if (map->n == 0)
6227                 return 0;
6228         if (map->n == 1)
6229                 return isl_basic_map_fast_has_fixed_var(map->p[0], pos, val); 
6230         isl_int_init(v);
6231         isl_int_init(tmp);
6232         fixed = isl_basic_map_fast_has_fixed_var(map->p[0], pos, &v); 
6233         for (i = 1; fixed == 1 && i < map->n; ++i) {
6234                 fixed = isl_basic_map_fast_has_fixed_var(map->p[i], pos, &tmp); 
6235                 if (fixed == 1 && isl_int_ne(tmp, v))
6236                         fixed = 0;
6237         }
6238         if (val)
6239                 isl_int_set(*val, v);
6240         isl_int_clear(tmp);
6241         isl_int_clear(v);
6242         return fixed;
6243 }
6244
6245 static int isl_basic_set_fast_has_fixed_var(struct isl_basic_set *bset,
6246         unsigned pos, isl_int *val)
6247 {
6248         return isl_basic_map_fast_has_fixed_var((struct isl_basic_map *)bset,
6249                                                 pos, val);
6250 }
6251
6252 static int isl_set_fast_has_fixed_var(struct isl_set *set, unsigned pos,
6253         isl_int *val)
6254 {
6255         return isl_map_fast_has_fixed_var((struct isl_map *)set, pos, val);
6256 }
6257
6258 int isl_basic_map_fast_is_fixed(struct isl_basic_map *bmap,
6259         enum isl_dim_type type, unsigned pos, isl_int *val)
6260 {
6261         if (pos >= isl_basic_map_dim(bmap, type))
6262                 return -1;
6263         return isl_basic_map_fast_has_fixed_var(bmap,
6264                 isl_basic_map_offset(bmap, type) - 1 + pos, val);
6265 }
6266
6267 int isl_map_fast_is_fixed(struct isl_map *map,
6268         enum isl_dim_type type, unsigned pos, isl_int *val)
6269 {
6270         if (pos >= isl_map_dim(map, type))
6271                 return -1;
6272         return isl_map_fast_has_fixed_var(map,
6273                 map_offset(map, type) - 1 + pos, val);
6274 }
6275
6276 /* Check if dimension dim has fixed value and if so and if val is not NULL,
6277  * then return this fixed value in *val.
6278  */
6279 int isl_basic_set_fast_dim_is_fixed(struct isl_basic_set *bset, unsigned dim,
6280         isl_int *val)
6281 {
6282         return isl_basic_set_fast_has_fixed_var(bset,
6283                                         isl_basic_set_n_param(bset) + dim, val);
6284 }
6285
6286 /* Check if dimension dim has fixed value and if so and if val is not NULL,
6287  * then return this fixed value in *val.
6288  */
6289 int isl_set_fast_dim_is_fixed(struct isl_set *set, unsigned dim, isl_int *val)
6290 {
6291         return isl_set_fast_has_fixed_var(set, isl_set_n_param(set) + dim, val);
6292 }
6293
6294 /* Check if input variable in has fixed value and if so and if val is not NULL,
6295  * then return this fixed value in *val.
6296  */
6297 int isl_map_fast_input_is_fixed(struct isl_map *map, unsigned in, isl_int *val)
6298 {
6299         return isl_map_fast_has_fixed_var(map, isl_map_n_param(map) + in, val);
6300 }
6301
6302 /* Check if dimension dim has an (obvious) fixed lower bound and if so
6303  * and if val is not NULL, then return this lower bound in *val.
6304  */
6305 int isl_basic_set_fast_dim_has_fixed_lower_bound(struct isl_basic_set *bset,
6306         unsigned dim, isl_int *val)
6307 {
6308         int i, i_eq = -1, i_ineq = -1;
6309         isl_int *c;
6310         unsigned total;
6311         unsigned nparam;
6312
6313         if (!bset)
6314                 return -1;
6315         total = isl_basic_set_total_dim(bset);
6316         nparam = isl_basic_set_n_param(bset);
6317         for (i = 0; i < bset->n_eq; ++i) {
6318                 if (isl_int_is_zero(bset->eq[i][1+nparam+dim]))
6319                         continue;
6320                 if (i_eq != -1)
6321                         return 0;
6322                 i_eq = i;
6323         }
6324         for (i = 0; i < bset->n_ineq; ++i) {
6325                 if (!isl_int_is_pos(bset->ineq[i][1+nparam+dim]))
6326                         continue;
6327                 if (i_eq != -1 || i_ineq != -1)
6328                         return 0;
6329                 i_ineq = i;
6330         }
6331         if (i_eq == -1 && i_ineq == -1)
6332                 return 0;
6333         c = i_eq != -1 ? bset->eq[i_eq] : bset->ineq[i_ineq];
6334         /* The coefficient should always be one due to normalization. */
6335         if (!isl_int_is_one(c[1+nparam+dim]))
6336                 return 0;
6337         if (isl_seq_first_non_zero(c+1, nparam+dim) != -1)
6338                 return 0;
6339         if (isl_seq_first_non_zero(c+1+nparam+dim+1,
6340                                         total - nparam - dim - 1) != -1)
6341                 return 0;
6342         if (val)
6343                 isl_int_neg(*val, c[0]);
6344         return 1;
6345 }
6346
6347 int isl_set_fast_dim_has_fixed_lower_bound(struct isl_set *set,
6348         unsigned dim, isl_int *val)
6349 {
6350         int i;
6351         isl_int v;
6352         isl_int tmp;
6353         int fixed;
6354
6355         if (!set)
6356                 return -1;
6357         if (set->n == 0)
6358                 return 0;
6359         if (set->n == 1)
6360                 return isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
6361                                                                 dim, val);
6362         isl_int_init(v);
6363         isl_int_init(tmp);
6364         fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
6365                                                                 dim, &v);
6366         for (i = 1; fixed == 1 && i < set->n; ++i) {
6367                 fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[i],
6368                                                                 dim, &tmp);
6369                 if (fixed == 1 && isl_int_ne(tmp, v))
6370                         fixed = 0;
6371         }
6372         if (val)
6373                 isl_int_set(*val, v);
6374         isl_int_clear(tmp);
6375         isl_int_clear(v);
6376         return fixed;
6377 }
6378
6379 struct constraint {
6380         unsigned        size;
6381         isl_int         *c;
6382 };
6383
6384 static int qsort_constraint_cmp(const void *p1, const void *p2)
6385 {
6386         const struct constraint *c1 = (const struct constraint *)p1;
6387         const struct constraint *c2 = (const struct constraint *)p2;
6388         unsigned size = isl_min(c1->size, c2->size);
6389         return isl_seq_cmp(c1->c, c2->c, size);
6390 }
6391
6392 static struct isl_basic_map *isl_basic_map_sort_constraints(
6393         struct isl_basic_map *bmap)
6394 {
6395         int i;
6396         struct constraint *c;
6397         unsigned total;
6398
6399         if (!bmap)
6400                 return NULL;
6401         total = isl_basic_map_total_dim(bmap);
6402         c = isl_alloc_array(bmap->ctx, struct constraint, bmap->n_ineq);
6403         if (!c)
6404                 goto error;
6405         for (i = 0; i < bmap->n_ineq; ++i) {
6406                 c[i].size = total;
6407                 c[i].c = bmap->ineq[i];
6408         }
6409         qsort(c, bmap->n_ineq, sizeof(struct constraint), qsort_constraint_cmp);
6410         for (i = 0; i < bmap->n_ineq; ++i)
6411                 bmap->ineq[i] = c[i].c;
6412         free(c);
6413         return bmap;
6414 error:
6415         isl_basic_map_free(bmap);
6416         return NULL;
6417 }
6418
6419 __isl_give isl_basic_set *isl_basic_set_sort_constraints(
6420         __isl_take isl_basic_set *bset)
6421 {
6422         return (struct isl_basic_set *)isl_basic_map_sort_constraints(
6423                                                 (struct isl_basic_map *)bset);
6424 }
6425
6426 struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap)
6427 {
6428         if (!bmap)
6429                 return NULL;
6430         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED))
6431                 return bmap;
6432         bmap = isl_basic_map_remove_redundancies(bmap);
6433         bmap = isl_basic_map_sort_constraints(bmap);
6434         ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
6435         return bmap;
6436 }
6437
6438 struct isl_basic_set *isl_basic_set_normalize(struct isl_basic_set *bset)
6439 {
6440         return (struct isl_basic_set *)isl_basic_map_normalize(
6441                                                 (struct isl_basic_map *)bset);
6442 }
6443
6444 int isl_basic_map_fast_cmp(const __isl_keep isl_basic_map *bmap1,
6445         const __isl_keep isl_basic_map *bmap2)
6446 {
6447         int i, cmp;
6448         unsigned total;
6449
6450         if (bmap1 == bmap2)
6451                 return 0;
6452         if (isl_basic_map_n_param(bmap1) != isl_basic_map_n_param(bmap2))
6453                 return isl_basic_map_n_param(bmap1) - isl_basic_map_n_param(bmap2);
6454         if (isl_basic_map_n_in(bmap1) != isl_basic_map_n_in(bmap2))
6455                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
6456         if (isl_basic_map_n_out(bmap1) != isl_basic_map_n_out(bmap2))
6457                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
6458         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
6459             ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
6460                 return 0;
6461         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
6462                 return 1;
6463         if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
6464                 return -1;
6465         if (bmap1->n_eq != bmap2->n_eq)
6466                 return bmap1->n_eq - bmap2->n_eq;
6467         if (bmap1->n_ineq != bmap2->n_ineq)
6468                 return bmap1->n_ineq - bmap2->n_ineq;
6469         if (bmap1->n_div != bmap2->n_div)
6470                 return bmap1->n_div - bmap2->n_div;
6471         total = isl_basic_map_total_dim(bmap1);
6472         for (i = 0; i < bmap1->n_eq; ++i) {
6473                 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
6474                 if (cmp)
6475                         return cmp;
6476         }
6477         for (i = 0; i < bmap1->n_ineq; ++i) {
6478                 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
6479                 if (cmp)
6480                         return cmp;
6481         }
6482         for (i = 0; i < bmap1->n_div; ++i) {
6483                 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
6484                 if (cmp)
6485                         return cmp;
6486         }
6487         return 0;
6488 }
6489
6490 int isl_basic_map_fast_is_equal(__isl_keep isl_basic_map *bmap1,
6491         __isl_keep isl_basic_map *bmap2)
6492 {
6493         return isl_basic_map_fast_cmp(bmap1, bmap2) == 0;
6494 }
6495
6496 int isl_basic_set_fast_is_equal(__isl_keep isl_basic_set *bset1,
6497         __isl_keep isl_basic_set *bset2)
6498 {
6499         return isl_basic_map_fast_is_equal((isl_basic_map *)bset1,
6500                                             (isl_basic_map *)bset2);
6501 }
6502
6503 static int qsort_bmap_cmp(const void *p1, const void *p2)
6504 {
6505         const struct isl_basic_map *bmap1 = *(const struct isl_basic_map **)p1;
6506         const struct isl_basic_map *bmap2 = *(const struct isl_basic_map **)p2;
6507
6508         return isl_basic_map_fast_cmp(bmap1, bmap2);
6509 }
6510
6511 /* We normalize in place, but if anything goes wrong we need
6512  * to return NULL, so we need to make sure we don't change the
6513  * meaning of any possible other copies of map.
6514  */
6515 struct isl_map *isl_map_normalize(struct isl_map *map)
6516 {
6517         int i, j;
6518         struct isl_basic_map *bmap;
6519
6520         if (!map)
6521                 return NULL;
6522         if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED))
6523                 return map;
6524         for (i = 0; i < map->n; ++i) {
6525                 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
6526                 if (!bmap)
6527                         goto error;
6528                 isl_basic_map_free(map->p[i]);
6529                 map->p[i] = bmap;
6530         }
6531         qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
6532         ISL_F_SET(map, ISL_MAP_NORMALIZED);
6533         map = isl_map_remove_empty_parts(map);
6534         if (!map)
6535                 return NULL;
6536         for (i = map->n - 1; i >= 1; --i) {
6537                 if (!isl_basic_map_fast_is_equal(map->p[i-1], map->p[i]))
6538                         continue;
6539                 isl_basic_map_free(map->p[i-1]);
6540                 for (j = i; j < map->n; ++j)
6541                         map->p[j-1] = map->p[j];
6542                 map->n--;
6543         }
6544         return map;
6545 error:
6546         isl_map_free(map);
6547         return NULL;
6548
6549 }
6550
6551 struct isl_set *isl_set_normalize(struct isl_set *set)
6552 {
6553         return (struct isl_set *)isl_map_normalize((struct isl_map *)set);
6554 }
6555
6556 int isl_map_fast_is_equal(struct isl_map *map1, struct isl_map *map2)
6557 {
6558         int i;
6559         int equal;
6560
6561         if (!map1 || !map2)
6562                 return -1;
6563
6564         if (map1 == map2)
6565                 return 1;
6566         if (!isl_dim_equal(map1->dim, map2->dim))
6567                 return 0;
6568
6569         map1 = isl_map_copy(map1);
6570         map2 = isl_map_copy(map2);
6571         map1 = isl_map_normalize(map1);
6572         map2 = isl_map_normalize(map2);
6573         if (!map1 || !map2)
6574                 goto error;
6575         equal = map1->n == map2->n;
6576         for (i = 0; equal && i < map1->n; ++i) {
6577                 equal = isl_basic_map_fast_is_equal(map1->p[i], map2->p[i]);
6578                 if (equal < 0)
6579                         goto error;
6580         }
6581         isl_map_free(map1);
6582         isl_map_free(map2);
6583         return equal;
6584 error:
6585         isl_map_free(map1);
6586         isl_map_free(map2);
6587         return -1;
6588 }
6589
6590 int isl_set_fast_is_equal(struct isl_set *set1, struct isl_set *set2)
6591 {
6592         return isl_map_fast_is_equal((struct isl_map *)set1,
6593                                                 (struct isl_map *)set2);
6594 }
6595
6596 /* Return an interval that ranges from min to max (inclusive)
6597  */
6598 struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx,
6599         isl_int min, isl_int max)
6600 {
6601         int k;
6602         struct isl_basic_set *bset = NULL;
6603
6604         bset = isl_basic_set_alloc(ctx, 0, 1, 0, 0, 2);
6605         if (!bset)
6606                 goto error;
6607
6608         k = isl_basic_set_alloc_inequality(bset);
6609         if (k < 0)
6610                 goto error;
6611         isl_int_set_si(bset->ineq[k][1], 1);
6612         isl_int_neg(bset->ineq[k][0], min);
6613
6614         k = isl_basic_set_alloc_inequality(bset);
6615         if (k < 0)
6616                 goto error;
6617         isl_int_set_si(bset->ineq[k][1], -1);
6618         isl_int_set(bset->ineq[k][0], max);
6619
6620         return bset;
6621 error:
6622         isl_basic_set_free(bset);
6623         return NULL;
6624 }
6625
6626 /* Return the Cartesian product of the basic sets in list (in the given order).
6627  */
6628 struct isl_basic_set *isl_basic_set_product(struct isl_basic_set_list *list)
6629 {
6630         int i;
6631         unsigned dim;
6632         unsigned nparam;
6633         unsigned extra;
6634         unsigned n_eq;
6635         unsigned n_ineq;
6636         struct isl_basic_set *product = NULL;
6637
6638         if (!list)
6639                 goto error;
6640         isl_assert(list->ctx, list->n > 0, goto error);
6641         isl_assert(list->ctx, list->p[0], goto error);
6642         nparam = isl_basic_set_n_param(list->p[0]);
6643         dim = isl_basic_set_n_dim(list->p[0]);
6644         extra = list->p[0]->n_div;
6645         n_eq = list->p[0]->n_eq;
6646         n_ineq = list->p[0]->n_ineq;
6647         for (i = 1; i < list->n; ++i) {
6648                 isl_assert(list->ctx, list->p[i], goto error);
6649                 isl_assert(list->ctx,
6650                     nparam == isl_basic_set_n_param(list->p[i]), goto error);
6651                 dim += isl_basic_set_n_dim(list->p[i]);
6652                 extra += list->p[i]->n_div;
6653                 n_eq += list->p[i]->n_eq;
6654                 n_ineq += list->p[i]->n_ineq;
6655         }
6656         product = isl_basic_set_alloc(list->ctx, nparam, dim, extra,
6657                                         n_eq, n_ineq);
6658         if (!product)
6659                 goto error;
6660         dim = 0;
6661         for (i = 0; i < list->n; ++i) {
6662                 isl_basic_set_add_constraints(product,
6663                                         isl_basic_set_copy(list->p[i]), dim);
6664                 dim += isl_basic_set_n_dim(list->p[i]);
6665         }
6666         isl_basic_set_list_free(list);
6667         return product;
6668 error:
6669         isl_basic_set_free(product);
6670         isl_basic_set_list_free(list);
6671         return NULL;
6672 }
6673
6674 struct isl_basic_map *isl_basic_map_product(
6675                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
6676 {
6677         struct isl_dim *dim_result = NULL;
6678         struct isl_basic_map *bmap;
6679         unsigned in1, in2, out1, out2, nparam, total, pos;
6680         struct isl_dim_map *dim_map1, *dim_map2;
6681
6682         if (!bmap1 || !bmap2)
6683                 goto error;
6684
6685         isl_assert(bmap1->ctx, isl_dim_match(bmap1->dim, isl_dim_param,
6686                                      bmap2->dim, isl_dim_param), goto error);
6687         dim_result = isl_dim_product(isl_dim_copy(bmap1->dim),
6688                                                    isl_dim_copy(bmap2->dim));
6689
6690         in1 = isl_basic_map_n_in(bmap1);
6691         in2 = isl_basic_map_n_in(bmap2);
6692         out1 = isl_basic_map_n_out(bmap1);
6693         out2 = isl_basic_map_n_out(bmap2);
6694         nparam = isl_basic_map_n_param(bmap1);
6695
6696         total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
6697         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
6698         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
6699         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
6700         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
6701         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
6702         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
6703         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
6704         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
6705         isl_dim_map_div(dim_map1, bmap1, pos += out2);
6706         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
6707
6708         bmap = isl_basic_map_alloc_dim(dim_result,
6709                         bmap1->n_div + bmap2->n_div,
6710                         bmap1->n_eq + bmap2->n_eq,
6711                         bmap1->n_ineq + bmap2->n_ineq);
6712         bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
6713         bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
6714         bmap = isl_basic_map_simplify(bmap);
6715         return isl_basic_map_finalize(bmap);
6716 error:
6717         isl_basic_map_free(bmap1);
6718         isl_basic_map_free(bmap2);
6719         return NULL;
6720 }
6721
6722 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
6723  */
6724 struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2)
6725 {
6726         unsigned flags = 0;
6727         struct isl_map *result;
6728         int i, j;
6729
6730         if (!map1 || !map2)
6731                 goto error;
6732
6733         isl_assert(map1->ctx, isl_dim_match(map1->dim, isl_dim_param,
6734                                          map2->dim, isl_dim_param), goto error);
6735
6736         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
6737             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
6738                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
6739
6740         result = isl_map_alloc_dim(isl_dim_product(isl_dim_copy(map1->dim),
6741                                                    isl_dim_copy(map2->dim)),
6742                                 map1->n * map2->n, flags);
6743         if (!result)
6744                 goto error;
6745         for (i = 0; i < map1->n; ++i)
6746                 for (j = 0; j < map2->n; ++j) {
6747                         struct isl_basic_map *part;
6748                         part = isl_basic_map_product(
6749                                     isl_basic_map_copy(map1->p[i]),
6750                                     isl_basic_map_copy(map2->p[j]));
6751                         if (isl_basic_map_is_empty(part))
6752                                 isl_basic_map_free(part);
6753                         else
6754                                 result = isl_map_add_basic_map(result, part);
6755                         if (!result)
6756                                 goto error;
6757                 }
6758         isl_map_free(map1);
6759         isl_map_free(map2);
6760         return result;
6761 error:
6762         isl_map_free(map1);
6763         isl_map_free(map2);
6764         return NULL;
6765 }
6766
6767 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
6768  */
6769 __isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
6770         __isl_take isl_map *map2)
6771 {
6772         isl_map *prod;
6773
6774         prod = isl_map_product(map1, map2);
6775         prod = isl_map_flatten(prod);
6776         return prod;
6777 }
6778
6779 /* Given two set A and B, construct its Cartesian product A x B.
6780  */
6781 struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2)
6782 {
6783         return (struct isl_set *)isl_map_product((struct isl_map *)set1,
6784                                                  (struct isl_map *)set2);
6785 }
6786
6787 __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
6788         __isl_take isl_set *set2)
6789 {
6790         return (isl_set *)isl_map_flat_product((isl_map *)set1, (isl_map *)set2);
6791 }
6792
6793 uint32_t isl_basic_set_get_hash(struct isl_basic_set *bset)
6794 {
6795         int i;
6796         uint32_t hash = isl_hash_init();
6797         unsigned total;
6798
6799         if (!bset)
6800                 return 0;
6801         bset = isl_basic_set_copy(bset);
6802         bset = isl_basic_set_normalize(bset);
6803         if (!bset)
6804                 return 0;
6805         total = isl_basic_set_total_dim(bset);
6806         isl_hash_byte(hash, bset->n_eq & 0xFF);
6807         for (i = 0; i < bset->n_eq; ++i) {
6808                 uint32_t c_hash;
6809                 c_hash = isl_seq_get_hash(bset->eq[i], 1 + total);
6810                 isl_hash_hash(hash, c_hash);
6811         }
6812         isl_hash_byte(hash, bset->n_ineq & 0xFF);
6813         for (i = 0; i < bset->n_ineq; ++i) {
6814                 uint32_t c_hash;
6815                 c_hash = isl_seq_get_hash(bset->ineq[i], 1 + total);
6816                 isl_hash_hash(hash, c_hash);
6817         }
6818         isl_hash_byte(hash, bset->n_div & 0xFF);
6819         for (i = 0; i < bset->n_div; ++i) {
6820                 uint32_t c_hash;
6821                 if (isl_int_is_zero(bset->div[i][0]))
6822                         continue;
6823                 isl_hash_byte(hash, i & 0xFF);
6824                 c_hash = isl_seq_get_hash(bset->div[i], 1 + 1 + total);
6825                 isl_hash_hash(hash, c_hash);
6826         }
6827         isl_basic_set_free(bset);
6828         return hash;
6829 }
6830
6831 uint32_t isl_set_get_hash(struct isl_set *set)
6832 {
6833         int i;
6834         uint32_t hash;
6835
6836         if (!set)
6837                 return 0;
6838         set = isl_set_copy(set);
6839         set = isl_set_normalize(set);
6840         if (!set)
6841                 return 0;
6842
6843         hash = isl_hash_init();
6844         for (i = 0; i < set->n; ++i) {
6845                 uint32_t bset_hash;
6846                 bset_hash = isl_basic_set_get_hash(set->p[i]);
6847                 isl_hash_hash(hash, bset_hash);
6848         }
6849                 
6850         isl_set_free(set);
6851
6852         return hash;
6853 }
6854
6855 /* Check if the value for dimension dim is completely determined
6856  * by the values of the other parameters and variables.
6857  * That is, check if dimension dim is involved in an equality.
6858  */
6859 int isl_basic_set_dim_is_unique(struct isl_basic_set *bset, unsigned dim)
6860 {
6861         int i;
6862         unsigned nparam;
6863
6864         if (!bset)
6865                 return -1;
6866         nparam = isl_basic_set_n_param(bset);
6867         for (i = 0; i < bset->n_eq; ++i)
6868                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + dim]))
6869                         return 1;
6870         return 0;
6871 }
6872
6873 /* Check if the value for dimension dim is completely determined
6874  * by the values of the other parameters and variables.
6875  * That is, check if dimension dim is involved in an equality
6876  * for each of the subsets.
6877  */
6878 int isl_set_dim_is_unique(struct isl_set *set, unsigned dim)
6879 {
6880         int i;
6881
6882         if (!set)
6883                 return -1;
6884         for (i = 0; i < set->n; ++i) {
6885                 int unique;
6886                 unique = isl_basic_set_dim_is_unique(set->p[i], dim);
6887                 if (unique != 1)
6888                         return unique;
6889         }
6890         return 1;
6891 }
6892
6893 int isl_map_foreach_basic_map(__isl_keep isl_map *map,
6894         int (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
6895 {
6896         int i;
6897
6898         if (!map)
6899                 return -1;
6900
6901         for (i = 0; i < map->n; ++i)
6902                 if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
6903                         return -1;
6904
6905         return 0;
6906 }
6907
6908 int isl_set_foreach_basic_set(__isl_keep isl_set *set,
6909         int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user)
6910 {
6911         int i;
6912
6913         if (!set)
6914                 return -1;
6915
6916         for (i = 0; i < set->n; ++i)
6917                 if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
6918                         return -1;
6919
6920         return 0;
6921 }
6922
6923 __isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset)
6924 {
6925         struct isl_dim *dim;
6926
6927         if (!bset)
6928                 return NULL;
6929
6930         if (bset->n_div == 0)
6931                 return bset;
6932
6933         bset = isl_basic_set_cow(bset);
6934         if (!bset)
6935                 return NULL;
6936
6937         dim = isl_basic_set_get_dim(bset);
6938         dim = isl_dim_add(dim, isl_dim_set, bset->n_div);
6939         if (!dim)
6940                 goto error;
6941         isl_dim_free(bset->dim);
6942         bset->dim = dim;
6943         bset->n_div = 0;
6944
6945         bset = isl_basic_set_finalize(bset);
6946
6947         return bset;
6948 error:
6949         isl_basic_set_free(bset);
6950         return NULL;
6951 }
6952
6953 __isl_give isl_set *isl_set_lift(__isl_take isl_set *set)
6954 {
6955         int i;
6956         struct isl_dim *dim;
6957         unsigned n_div;
6958
6959         set = isl_set_align_divs(set);
6960
6961         if (!set)
6962                 return NULL;
6963         if (set->n == 0 || set->p[0]->n_div == 0)
6964                 return set;
6965
6966         set = isl_set_cow(set);
6967         if (!set)
6968                 return NULL;
6969
6970         n_div = set->p[0]->n_div;
6971         dim = isl_set_get_dim(set);
6972         dim = isl_dim_add(dim, isl_dim_set, n_div);
6973         if (!dim)
6974                 goto error;
6975         isl_dim_free(set->dim);
6976         set->dim = dim;
6977
6978         for (i = 0; i < set->n; ++i) {
6979                 set->p[i] = isl_basic_set_lift(set->p[i]);
6980                 if (!set->p[i])
6981                         goto error;
6982         }
6983
6984         return set;
6985 error:
6986         isl_set_free(set);
6987         return NULL;
6988 }
6989
6990 __isl_give isl_map *isl_set_lifting(__isl_take isl_set *set)
6991 {
6992         struct isl_dim *dim;
6993         struct isl_basic_map *bmap;
6994         unsigned n_set;
6995         unsigned n_div;
6996         unsigned n_param;
6997         unsigned total;
6998         int i, k, l;
6999
7000         set = isl_set_align_divs(set);
7001
7002         if (!set)
7003                 return NULL;
7004
7005         dim = isl_set_get_dim(set);
7006         if (set->n == 0 || set->p[0]->n_div == 0) {
7007                 isl_set_free(set);
7008                 return isl_map_identity(dim);
7009         }
7010
7011         n_div = set->p[0]->n_div;
7012         dim = isl_dim_map(dim);
7013         n_param = isl_dim_size(dim, isl_dim_param);
7014         n_set = isl_dim_size(dim, isl_dim_in);
7015         dim = isl_dim_extend(dim, n_param, n_set, n_set + n_div);
7016         bmap = isl_basic_map_alloc_dim(dim, 0, n_set, 2 * n_div);
7017         for (i = 0; i < n_set; ++i)
7018                 bmap = var_equal(bmap, i);
7019
7020         total = n_param + n_set + n_set + n_div;
7021         for (i = 0; i < n_div; ++i) {
7022                 k = isl_basic_map_alloc_inequality(bmap);
7023                 if (k < 0)
7024                         goto error;
7025                 isl_seq_cpy(bmap->ineq[k], set->p[0]->div[i]+1, 1+n_param);
7026                 isl_seq_clr(bmap->ineq[k]+1+n_param, n_set);
7027                 isl_seq_cpy(bmap->ineq[k]+1+n_param+n_set,
7028                             set->p[0]->div[i]+1+1+n_param, n_set + n_div);
7029                 isl_int_neg(bmap->ineq[k][1+n_param+n_set+n_set+i],
7030                             set->p[0]->div[i][0]);
7031
7032                 l = isl_basic_map_alloc_inequality(bmap);
7033                 if (l < 0)
7034                         goto error;
7035                 isl_seq_neg(bmap->ineq[l], bmap->ineq[k], 1 + total);
7036                 isl_int_add(bmap->ineq[l][0], bmap->ineq[l][0],
7037                             set->p[0]->div[i][0]);
7038                 isl_int_sub_ui(bmap->ineq[l][0], bmap->ineq[l][0], 1);
7039         }
7040
7041         isl_set_free(set);
7042         return isl_map_from_basic_map(bmap);
7043 error:
7044         isl_set_free(set);
7045         isl_basic_map_free(bmap);
7046         return NULL;
7047 }
7048
7049 int isl_basic_set_size(__isl_keep isl_basic_set *bset)
7050 {
7051         unsigned dim;
7052         int size = 0;
7053
7054         if (!bset)
7055                 return -1;
7056
7057         dim = isl_basic_set_total_dim(bset);
7058         size += bset->n_eq * (1 + dim);
7059         size += bset->n_ineq * (1 + dim);
7060         size += bset->n_div * (2 + dim);
7061
7062         return size;
7063 }
7064
7065 int isl_set_size(__isl_keep isl_set *set)
7066 {
7067         int i;
7068         int size = 0;
7069
7070         if (!set)
7071                 return -1;
7072
7073         for (i = 0; i < set->n; ++i)
7074                 size += isl_basic_set_size(set->p[i]);
7075
7076         return size;
7077 }
7078
7079 int isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
7080         enum isl_dim_type type, unsigned pos)
7081 {
7082         int i;
7083         int lower, upper;
7084
7085         if (!bmap)
7086                 return -1;
7087
7088         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), return -1);
7089
7090         pos += isl_basic_map_offset(bmap, type);
7091
7092         for (i = 0; i < bmap->n_eq; ++i)
7093                 if (!isl_int_is_zero(bmap->eq[i][pos]))
7094                         return 1;
7095
7096         lower = upper = 0;
7097         for (i = 0; i < bmap->n_ineq; ++i) {
7098                 int sgn = isl_int_sgn(bmap->ineq[i][pos]);
7099                 if (sgn > 0)
7100                         lower = 1;
7101                 if (sgn < 0)
7102                         upper = 1;
7103         }
7104
7105         return lower && upper;
7106 }
7107
7108 int isl_map_dim_is_bounded(__isl_keep isl_map *map,
7109         enum isl_dim_type type, unsigned pos)
7110 {
7111         int i;
7112
7113         if (!map)
7114                 return -1;
7115
7116         for (i = 0; i < map->n; ++i) {
7117                 int bounded;
7118                 bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
7119                 if (bounded < 0 || !bounded)
7120                         return bounded;
7121         }
7122
7123         return 1;
7124 }
7125
7126 /* Return 1 if the specified dim is involved in both an upper bound
7127  * and a lower bound.
7128  */
7129 int isl_set_dim_is_bounded(__isl_keep isl_set *set,
7130         enum isl_dim_type type, unsigned pos)
7131 {
7132         return isl_map_dim_is_bounded((isl_map *)set, type, pos);
7133 }
7134
7135 /* For each of the "n" variables starting at "first", determine
7136  * the sign of the variable and put the results in the first "n"
7137  * elements of the array "signs".
7138  * Sign
7139  *      1 means that the variable is non-negative
7140  *      -1 means that the variable is non-positive
7141  *      0 means the variable attains both positive and negative values.
7142  */
7143 int isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset,
7144         unsigned first, unsigned n, int *signs)
7145 {
7146         isl_vec *bound = NULL;
7147         struct isl_tab *tab = NULL;
7148         struct isl_tab_undo *snap;
7149         int i;
7150
7151         if (!bset || !signs)
7152                 return -1;
7153
7154         bound = isl_vec_alloc(bset->ctx, 1 + isl_basic_set_total_dim(bset));
7155         tab = isl_tab_from_basic_set(bset);
7156         if (!bound || !tab)
7157                 goto error;
7158
7159         isl_seq_clr(bound->el, bound->size);
7160         isl_int_set_si(bound->el[0], -1);
7161
7162         snap = isl_tab_snap(tab);
7163         for (i = 0; i < n; ++i) {
7164                 int empty;
7165
7166                 isl_int_set_si(bound->el[1 + first + i], -1);
7167                 if (isl_tab_add_ineq(tab, bound->el) < 0)
7168                         goto error;
7169                 empty = tab->empty;
7170                 isl_int_set_si(bound->el[1 + first + i], 0);
7171                 if (isl_tab_rollback(tab, snap) < 0)
7172                         goto error;
7173
7174                 if (empty) {
7175                         signs[i] = 1;
7176                         continue;
7177                 }
7178
7179                 isl_int_set_si(bound->el[1 + first + i], 1);
7180                 if (isl_tab_add_ineq(tab, bound->el) < 0)
7181                         goto error;
7182                 empty = tab->empty;
7183                 isl_int_set_si(bound->el[1 + first + i], 0);
7184                 if (isl_tab_rollback(tab, snap) < 0)
7185                         goto error;
7186
7187                 signs[i] = empty ? -1 : 0;
7188         }
7189
7190         isl_tab_free(tab);
7191         isl_vec_free(bound);
7192         return 0;
7193 error:
7194         isl_tab_free(tab);
7195         isl_vec_free(bound);
7196         return -1;
7197 }
7198
7199 int isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset,
7200         enum isl_dim_type type, unsigned first, unsigned n, int *signs)
7201 {
7202         if (!bset || !signs)
7203                 return -1;
7204         isl_assert(bset->ctx, first + n <= isl_basic_set_dim(bset, type),
7205                 return -1);
7206
7207         first += pos(bset->dim, type) - 1;
7208         return isl_basic_set_vars_get_sign(bset, first, n, signs);
7209 }
7210
7211 /* Check if the given map is single-valued.
7212  * We simply compute
7213  *
7214  *      M \circ M^-1
7215  *
7216  * and check if the result is a subset of the identity mapping.
7217  */
7218 int isl_map_is_single_valued(__isl_keep isl_map *map)
7219 {
7220         isl_map *test;
7221         isl_map *id;
7222         int sv;
7223
7224         test = isl_map_reverse(isl_map_copy(map));
7225         test = isl_map_apply_range(test, isl_map_copy(map));
7226
7227         id = isl_map_identity(isl_dim_range(isl_map_get_dim(map)));
7228
7229         sv = isl_map_is_subset(test, id);
7230
7231         isl_map_free(test);
7232         isl_map_free(id);
7233
7234         return sv;
7235 }
7236
7237 int isl_map_is_bijective(__isl_keep isl_map *map)
7238 {
7239         int sv;
7240
7241         sv = isl_map_is_single_valued(map);
7242         if (sv < 0 || !sv)
7243                 return sv;
7244
7245         map = isl_map_copy(map);
7246         map = isl_map_reverse(map);
7247         sv = isl_map_is_single_valued(map);
7248         isl_map_free(map);
7249
7250         return sv;
7251 }
7252
7253 int isl_set_is_singleton(__isl_keep isl_set *set)
7254 {
7255         return isl_map_is_single_valued((isl_map *)set);
7256 }
7257
7258 int isl_map_is_translation(__isl_keep isl_map *map)
7259 {
7260         int ok;
7261         isl_set *delta;
7262
7263         delta = isl_map_deltas(isl_map_copy(map));
7264         ok = isl_set_is_singleton(delta);
7265         isl_set_free(delta);
7266
7267         return ok;
7268 }
7269
7270 static int unique(isl_int *p, unsigned pos, unsigned len)
7271 {
7272         if (isl_seq_first_non_zero(p, pos) != -1)
7273                 return 0;
7274         if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
7275                 return 0;
7276         return 1;
7277 }
7278
7279 int isl_basic_set_is_box(__isl_keep isl_basic_set *bset)
7280 {
7281         int i, j;
7282         unsigned nvar;
7283         unsigned ovar;
7284
7285         if (!bset)
7286                 return -1;
7287
7288         if (isl_basic_set_dim(bset, isl_dim_div) != 0)
7289                 return 0;
7290
7291         nvar = isl_basic_set_dim(bset, isl_dim_set);
7292         ovar = isl_dim_offset(bset->dim, isl_dim_set);
7293         for (j = 0; j < nvar; ++j) {
7294                 int lower = 0, upper = 0;
7295                 for (i = 0; i < bset->n_eq; ++i) {
7296                         if (isl_int_is_zero(bset->eq[i][1 + ovar + j]))
7297                                 continue;
7298                         if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
7299                                 return 0;
7300                         break;
7301                 }
7302                 if (i < bset->n_eq)
7303                         continue;
7304                 for (i = 0; i < bset->n_ineq; ++i) {
7305                         if (isl_int_is_zero(bset->ineq[i][1 + ovar + j]))
7306                                 continue;
7307                         if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
7308                                 return 0;
7309                         if (isl_int_is_pos(bset->ineq[i][1 + ovar + j]))
7310                                 lower = 1;
7311                         else
7312                                 upper = 1;
7313                 }
7314                 if (!lower || !upper)
7315                         return 0;
7316         }
7317
7318         return 1;
7319 }
7320
7321 int isl_set_is_box(__isl_keep isl_set *set)
7322 {
7323         if (!set)
7324                 return -1;
7325         if (set->n != 1)
7326                 return 0;
7327
7328         return isl_basic_set_is_box(set->p[0]);
7329 }
7330
7331 int isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset)
7332 {
7333         if (!bset)
7334                 return -1;
7335         
7336         return isl_dim_is_wrapping(bset->dim);
7337 }
7338
7339 int isl_set_is_wrapping(__isl_keep isl_set *set)
7340 {
7341         if (!set)
7342                 return -1;
7343         
7344         return isl_dim_is_wrapping(set->dim);
7345 }
7346
7347 __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
7348 {
7349         bmap = isl_basic_map_cow(bmap);
7350         if (!bmap)
7351                 return NULL;
7352
7353         bmap->dim = isl_dim_wrap(bmap->dim);
7354         if (!bmap->dim)
7355                 goto error;
7356
7357         bmap = isl_basic_map_finalize(bmap);
7358
7359         return (isl_basic_set *)bmap;
7360 error:
7361         isl_basic_map_free(bmap);
7362         return NULL;
7363 }
7364
7365 __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map)
7366 {
7367         int i;
7368
7369         map = isl_map_cow(map);
7370         if (!map)
7371                 return NULL;
7372
7373         for (i = 0; i < map->n; ++i) {
7374                 map->p[i] = (isl_basic_map *)isl_basic_map_wrap(map->p[i]);
7375                 if (!map->p[i])
7376                         goto error;
7377         }
7378         map->dim = isl_dim_wrap(map->dim);
7379         if (!map->dim)
7380                 goto error;
7381
7382         return (isl_set *)map;
7383 error:
7384         isl_map_free(map);
7385         return NULL;
7386 }
7387
7388 __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset)
7389 {
7390         bset = isl_basic_set_cow(bset);
7391         if (!bset)
7392                 return NULL;
7393
7394         bset->dim = isl_dim_unwrap(bset->dim);
7395         if (!bset->dim)
7396                 goto error;
7397
7398         bset = isl_basic_set_finalize(bset);
7399
7400         return (isl_basic_map *)bset;
7401 error:
7402         isl_basic_set_free(bset);
7403         return NULL;
7404 }
7405
7406 __isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set)
7407 {
7408         int i;
7409
7410         if (!set)
7411                 return NULL;
7412
7413         if (!isl_set_is_wrapping(set))
7414                 isl_die(set->ctx, isl_error_invalid, "not a wrapping set",
7415                         goto error);
7416
7417         set = isl_set_cow(set);
7418         if (!set)
7419                 return NULL;
7420
7421         for (i = 0; i < set->n; ++i) {
7422                 set->p[i] = (isl_basic_set *)isl_basic_set_unwrap(set->p[i]);
7423                 if (!set->p[i])
7424                         goto error;
7425         }
7426
7427         set->dim = isl_dim_unwrap(set->dim);
7428         if (!set->dim)
7429                 goto error;
7430
7431         return (isl_map *)set;
7432 error:
7433         isl_set_free(set);
7434         return NULL;
7435 }
7436
7437 __isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
7438         enum isl_dim_type type)
7439 {
7440         if (!bmap)
7441                 return NULL;
7442
7443         if (!isl_dim_is_named_or_nested(bmap->dim, type))
7444                 return bmap;
7445
7446         bmap = isl_basic_map_cow(bmap);
7447         if (!bmap)
7448                 return NULL;
7449
7450         bmap->dim = isl_dim_reset(bmap->dim, type);
7451         if (!bmap->dim)
7452                 goto error;
7453
7454         bmap = isl_basic_map_finalize(bmap);
7455
7456         return bmap;
7457 error:
7458         isl_basic_map_free(bmap);
7459         return NULL;
7460 }
7461
7462 __isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
7463         enum isl_dim_type type)
7464 {
7465         int i;
7466
7467         if (!map)
7468                 return NULL;
7469
7470         if (!isl_dim_is_named_or_nested(map->dim, type))
7471                 return map;
7472
7473         map = isl_map_cow(map);
7474         if (!map)
7475                 return NULL;
7476
7477         for (i = 0; i < map->n; ++i) {
7478                 map->p[i] = isl_basic_map_reset(map->p[i], type);
7479                 if (!map->p[i])
7480                         goto error;
7481         }
7482         map->dim = isl_dim_reset(map->dim, type);
7483         if (!map->dim)
7484                 goto error;
7485
7486         return map;
7487 error:
7488         isl_map_free(map);
7489         return NULL;
7490 }
7491
7492 __isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
7493 {
7494         if (!bmap)
7495                 return NULL;
7496
7497         if (!bmap->dim->nested[0] && !bmap->dim->nested[1])
7498                 return bmap;
7499
7500         bmap = isl_basic_map_cow(bmap);
7501         if (!bmap)
7502                 return NULL;
7503
7504         bmap->dim = isl_dim_flatten(bmap->dim);
7505         if (!bmap->dim)
7506                 goto error;
7507
7508         bmap = isl_basic_map_finalize(bmap);
7509
7510         return bmap;
7511 error:
7512         isl_basic_map_free(bmap);
7513         return NULL;
7514 }
7515
7516 __isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
7517 {
7518         int i;
7519
7520         if (!map)
7521                 return NULL;
7522
7523         if (!map->dim->nested[0] && !map->dim->nested[1])
7524                 return map;
7525
7526         map = isl_map_cow(map);
7527         if (!map)
7528                 return NULL;
7529
7530         for (i = 0; i < map->n; ++i) {
7531                 map->p[i] = isl_basic_map_flatten(map->p[i]);
7532                 if (!map->p[i])
7533                         goto error;
7534         }
7535         map->dim = isl_dim_flatten(map->dim);
7536         if (!map->dim)
7537                 goto error;
7538
7539         return map;
7540 error:
7541         isl_map_free(map);
7542         return NULL;
7543 }
7544
7545 /* Extend the given dim_map with mappings for the divs in bmap.
7546  */
7547 static __isl_give struct isl_dim_map *extend_dim_map(
7548         __isl_keep struct isl_dim_map *dim_map,
7549         __isl_keep isl_basic_map *bmap)
7550 {
7551         int i;
7552         struct isl_dim_map *res;
7553         int offset;
7554
7555         offset = isl_basic_map_offset(bmap, isl_dim_div);
7556
7557         res = isl_dim_map_alloc(bmap->ctx, dim_map->len - 1 + bmap->n_div);
7558         if (!res)
7559                 return NULL;
7560
7561         for (i = 0; i < dim_map->len; ++i)
7562                 res->pos[i] = dim_map->pos[i];
7563         for (i = 0; i < bmap->n_div; ++i)
7564                 res->pos[dim_map->len + i] = offset + i;
7565
7566         return res;
7567 }
7568
7569 /* Extract a dim_map from a reordering.
7570  * We essentially need to reverse the mapping, and add an offset
7571  * of 1 for the constant term.
7572  */
7573 __isl_give struct isl_dim_map *isl_dim_map_from_reordering(
7574         __isl_keep isl_reordering *exp)
7575 {
7576         int i;
7577         struct isl_dim_map *dim_map;
7578
7579         if (!exp)
7580                 return NULL;
7581
7582         dim_map = isl_dim_map_alloc(exp->dim->ctx, isl_dim_total(exp->dim));
7583         if (!dim_map)
7584                 return NULL;
7585
7586         for (i = 0; i < exp->len; ++i)
7587                 dim_map->pos[1 + exp->pos[i]] = 1 + i;
7588
7589         return dim_map;
7590 }
7591
7592 /* Reorder the dimensions of "bmap" according to the given dim_map
7593  * and set the dimension specification to "dim".
7594  */
7595 __isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
7596         __isl_take isl_dim *dim, __isl_take struct isl_dim_map *dim_map)
7597 {
7598         isl_basic_map *res;
7599
7600         bmap = isl_basic_map_cow(bmap);
7601         if (!bmap || !dim || !dim_map)
7602                 goto error;
7603
7604         res = isl_basic_map_alloc_dim(dim,
7605                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
7606         res = add_constraints_dim_map(res, bmap, dim_map);
7607         res = isl_basic_map_finalize(res);
7608         return res;
7609 error:
7610         free(dim_map);
7611         isl_basic_map_free(bmap);
7612         isl_dim_free(dim);
7613         return NULL;
7614 }
7615
7616 /* Reorder the dimensions of "map" according to given reordering.
7617  */
7618 __isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
7619         __isl_take isl_reordering *r)
7620 {
7621         int i;
7622         struct isl_dim_map *dim_map;
7623
7624         map = isl_map_cow(map);
7625         dim_map = isl_dim_map_from_reordering(r);
7626         if (!map || !r || !dim_map)
7627                 goto error;
7628
7629         for (i = 0; i < map->n; ++i) {
7630                 struct isl_dim_map *dim_map_i;
7631
7632                 dim_map_i = extend_dim_map(dim_map, map->p[i]);
7633
7634                 map->p[i] = isl_basic_map_realign(map->p[i],
7635                                             isl_dim_copy(r->dim), dim_map_i);
7636
7637                 if (!map->p[i])
7638                         goto error;
7639         }
7640
7641         map = isl_map_reset_dim(map, isl_dim_copy(r->dim));
7642
7643         isl_reordering_free(r);
7644         free(dim_map);
7645         return map;
7646 error:
7647         free(dim_map);
7648         isl_map_free(map);
7649         isl_reordering_free(r);
7650         return NULL;
7651 }
7652
7653 __isl_give isl_set *isl_set_realign(__isl_take isl_set *set,
7654         __isl_take isl_reordering *r)
7655 {
7656         return (isl_set *)isl_map_realign((isl_map *)set, r);
7657 }
7658
7659 __isl_give isl_mat *isl_basic_map_equalities_matrix(
7660                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
7661                 enum isl_dim_type c2, enum isl_dim_type c3,
7662                 enum isl_dim_type c4, enum isl_dim_type c5)
7663 {
7664         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
7665         struct isl_mat *mat;
7666         int i, j, k;
7667         int pos;
7668
7669         if (!bmap)
7670                 return NULL;
7671         mat = isl_mat_alloc(bmap->ctx, bmap->n_eq,
7672                                 isl_basic_map_total_dim(bmap) + 1);
7673         if (!mat)
7674                 return NULL;
7675         for (i = 0; i < bmap->n_eq; ++i)
7676                 for (j = 0, pos = 0; j < 5; ++j) {
7677                         int off = isl_basic_map_offset(bmap, c[j]);
7678                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
7679                                 isl_int_set(mat->row[i][pos],
7680                                             bmap->eq[i][off + k]);
7681                                 ++pos;
7682                         }
7683                 }
7684
7685         return mat;
7686 }
7687
7688 __isl_give isl_mat *isl_basic_map_inequalities_matrix(
7689                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
7690                 enum isl_dim_type c2, enum isl_dim_type c3,
7691                 enum isl_dim_type c4, enum isl_dim_type c5)
7692 {
7693         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
7694         struct isl_mat *mat;
7695         int i, j, k;
7696         int pos;
7697
7698         if (!bmap)
7699                 return NULL;
7700         mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq,
7701                                 isl_basic_map_total_dim(bmap) + 1);
7702         if (!mat)
7703                 return NULL;
7704         for (i = 0; i < bmap->n_ineq; ++i)
7705                 for (j = 0, pos = 0; j < 5; ++j) {
7706                         int off = isl_basic_map_offset(bmap, c[j]);
7707                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
7708                                 isl_int_set(mat->row[i][pos],
7709                                             bmap->ineq[i][off + k]);
7710                                 ++pos;
7711                         }
7712                 }
7713
7714         return mat;
7715 }
7716
7717 __isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
7718         __isl_take isl_dim *dim,
7719         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
7720         enum isl_dim_type c2, enum isl_dim_type c3,
7721         enum isl_dim_type c4, enum isl_dim_type c5)
7722 {
7723         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
7724         isl_basic_map *bmap;
7725         unsigned total;
7726         unsigned extra;
7727         int i, j, k, l;
7728         int pos;
7729
7730         if (!dim || !eq || !ineq)
7731                 goto error;
7732
7733         if (eq->n_col != ineq->n_col)
7734                 isl_die(dim->ctx, isl_error_invalid,
7735                         "equalities and inequalities matrices should have "
7736                         "same number of columns", goto error);
7737
7738         total = 1 + isl_dim_total(dim);
7739
7740         if (eq->n_col < total)
7741                 isl_die(dim->ctx, isl_error_invalid,
7742                         "number of columns too small", goto error);
7743
7744         extra = eq->n_col - total;
7745
7746         bmap = isl_basic_map_alloc_dim(isl_dim_copy(dim), extra,
7747                                        eq->n_row, ineq->n_row);
7748         if (!bmap)
7749                 goto error;
7750         for (i = 0; i < extra; ++i)
7751                 if (isl_basic_map_alloc_div(bmap) < 0)
7752                         goto error;
7753         for (i = 0; i < eq->n_row; ++i) {
7754                 l = isl_basic_map_alloc_equality(bmap);
7755                 if (l < 0)
7756                         goto error;
7757                 for (j = 0, pos = 0; j < 5; ++j) {
7758                         int off = isl_basic_map_offset(bmap, c[j]);
7759                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
7760                                 isl_int_set(bmap->eq[l][off + k], 
7761                                             eq->row[i][pos]);
7762                                 ++pos;
7763                         }
7764                 }
7765         }
7766         for (i = 0; i < ineq->n_row; ++i) {
7767                 l = isl_basic_map_alloc_inequality(bmap);
7768                 if (l < 0)
7769                         goto error;
7770                 for (j = 0, pos = 0; j < 5; ++j) {
7771                         int off = isl_basic_map_offset(bmap, c[j]);
7772                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
7773                                 isl_int_set(bmap->ineq[l][off + k], 
7774                                             ineq->row[i][pos]);
7775                                 ++pos;
7776                         }
7777                 }
7778         }
7779
7780         isl_dim_free(dim);
7781         isl_mat_free(eq);
7782         isl_mat_free(ineq);
7783
7784         return bmap;
7785 error:
7786         isl_dim_free(dim);
7787         isl_mat_free(eq);
7788         isl_mat_free(ineq);
7789         return NULL;
7790 }
7791
7792 __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices(
7793         __isl_take isl_dim *dim,
7794         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
7795         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
7796 {
7797         return (isl_basic_set*)
7798             isl_basic_map_from_constraint_matrices(dim, eq, ineq,
7799                                                    c1, c2, c3, c4, isl_dim_in);
7800 }