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