isl_basic_map_intersect: reuse sample value of either basic map if possible
[platform/upstream/isl.git] / isl_map.c
1 #include <string.h>
2 #include <strings.h>
3 #include "isl_ctx.h"
4 #include "isl_blk.h"
5 #include "isl_dim.h"
6 #include "isl_list.h"
7 #include "isl_lp.h"
8 #include "isl_seq.h"
9 #include "isl_set.h"
10 #include "isl_map.h"
11 #include "isl_map_private.h"
12 #include "isl_map_piplib.h"
13 #include "isl_sample.h"
14 #include "isl_vec.h"
15
16 /* Maps dst positions to src positions */
17 struct isl_dim_map {
18         unsigned len;
19         int pos[1];
20 };
21
22 static struct isl_dim_map *isl_dim_map_alloc(struct isl_ctx *ctx, unsigned len)
23 {
24         int i;
25         struct isl_dim_map *dim_map;
26         dim_map = isl_alloc(ctx, struct isl_dim_map,
27                                 sizeof(struct isl_dim_map) + len * sizeof(int));
28         if (!dim_map)
29                 return NULL;
30         dim_map->len = 1 + len;
31         dim_map->pos[0] = 0;
32         for (i = 0; i < len; ++i)
33                 dim_map->pos[1 + i] = -1;
34         return dim_map;
35 }
36
37 static unsigned n(struct isl_dim *dim, enum isl_dim_type type)
38 {
39         switch (type) {
40         case isl_dim_param:     return dim->nparam;
41         case isl_dim_in:        return dim->n_in;
42         case isl_dim_out:       return dim->n_out;
43         }
44 }
45
46 static unsigned pos(struct isl_dim *dim, enum isl_dim_type type)
47 {
48         switch (type) {
49         case isl_dim_param:     return 1;
50         case isl_dim_in:        return 1 + dim->nparam;
51         case isl_dim_out:       return 1 + dim->nparam + dim->n_in;
52         }
53 }
54
55 static void isl_dim_map_dim(struct isl_dim_map *dim_map, struct isl_dim *dim,
56                 enum isl_dim_type type, unsigned dst_pos)
57 {
58         int i;
59         unsigned src_pos;
60
61         if (!dim_map || !dim)
62                 return;
63         
64         src_pos = pos(dim, type);
65         for (i = 0; i < n(dim, type); ++i)
66                 dim_map->pos[1 + dst_pos + i] = src_pos + i;
67 }
68
69 static void isl_dim_map_div(struct isl_dim_map *dim_map,
70                 struct isl_basic_map *bmap, unsigned dst_pos)
71 {
72         int i;
73         unsigned src_pos;
74
75         if (!dim_map || !bmap)
76                 return;
77         
78         src_pos = 1 + isl_dim_total(bmap->dim);
79         for (i = 0; i < bmap->n_div; ++i)
80                 dim_map->pos[1 + dst_pos + i] = src_pos + i;
81 }
82
83 static void isl_dim_map_dump(struct isl_dim_map *dim_map)
84 {
85         int i;
86
87         for (i = 0; i < dim_map->len; ++i)
88                 fprintf(stderr, "%d -> %d; ", i, dim_map->pos[i]);
89         fprintf(stderr, "\n");
90 }
91
92 unsigned isl_basic_map_dim(const struct isl_basic_map *bmap,
93                                 enum isl_dim_type type)
94 {
95         struct isl_dim *dim = bmap->dim;
96         switch (type) {
97         case isl_dim_param:
98         case isl_dim_in:
99         case isl_dim_out:       return isl_dim_size(bmap->dim, type);
100         case isl_dim_div:       return bmap->n_div;
101         case isl_dim_all:       return isl_basic_map_total_dim(bmap);
102         }
103 }
104
105 unsigned isl_map_dim(const struct isl_map *map, enum isl_dim_type type)
106 {
107         return n(map->dim, type);
108 }
109
110 unsigned isl_basic_map_offset(struct isl_basic_map *bmap,
111                                         enum isl_dim_type type)
112 {
113         struct isl_dim *dim = bmap->dim;
114         switch (type) {
115         case isl_dim_param:     return 1;
116         case isl_dim_in:        return 1 + dim->nparam;
117         case isl_dim_out:       return 1 + dim->nparam + dim->n_in;
118         case isl_dim_div:       return 1 + dim->nparam + dim->n_in + dim->n_out;
119         }
120 }
121
122 static unsigned map_offset(struct isl_map *map, enum isl_dim_type type)
123 {
124         return pos(map->dim, type);
125 }
126
127 unsigned isl_basic_set_dim(const struct isl_basic_set *bset,
128                                 enum isl_dim_type type)
129 {
130         return isl_basic_map_dim((const struct isl_basic_map*)bset, type);
131 }
132
133 unsigned isl_basic_set_n_dim(const struct isl_basic_set *bset)
134 {
135         return bset->dim->n_out;
136 }
137
138 unsigned isl_basic_set_n_param(const struct isl_basic_set *bset)
139 {
140         return bset->dim->nparam;
141 }
142
143 unsigned isl_basic_set_total_dim(const struct isl_basic_set *bset)
144 {
145         return isl_dim_total(bset->dim) + bset->n_div;
146 }
147
148 unsigned isl_set_n_dim(const struct isl_set *set)
149 {
150         return set->dim->n_out;
151 }
152
153 unsigned isl_set_n_param(const struct isl_set *set)
154 {
155         return set->dim->nparam;
156 }
157
158 unsigned isl_basic_map_n_in(const struct isl_basic_map *bmap)
159 {
160         return bmap->dim->n_in;
161 }
162
163 unsigned isl_basic_map_n_out(const struct isl_basic_map *bmap)
164 {
165         return bmap->dim->n_out;
166 }
167
168 unsigned isl_basic_map_n_param(const struct isl_basic_map *bmap)
169 {
170         return bmap->dim->nparam;
171 }
172
173 unsigned isl_basic_map_n_div(const struct isl_basic_map *bmap)
174 {
175         return bmap->n_div;
176 }
177
178 unsigned isl_basic_map_total_dim(const struct isl_basic_map *bmap)
179 {
180         return isl_dim_total(bmap->dim) + bmap->n_div;
181 }
182
183 unsigned isl_map_n_in(const struct isl_map *map)
184 {
185         return map->dim->n_in;
186 }
187
188 unsigned isl_map_n_out(const struct isl_map *map)
189 {
190         return map->dim->n_out;
191 }
192
193 unsigned isl_map_n_param(const struct isl_map *map)
194 {
195         return map->dim->nparam;
196 }
197
198 int isl_map_compatible_domain(struct isl_map *map, struct isl_set *set)
199 {
200         return map->dim->n_in == set->dim->n_out &&
201                map->dim->nparam == set->dim->nparam;
202 }
203
204 int isl_basic_map_compatible_domain(struct isl_basic_map *bmap,
205                 struct isl_basic_set *bset)
206 {
207         return bmap->dim->n_in == bset->dim->n_out &&
208                bmap->dim->nparam == bset->dim->nparam;
209 }
210
211 int isl_basic_map_compatible_range(struct isl_basic_map *bmap,
212                 struct isl_basic_set *bset)
213 {
214         return bmap->dim->n_out == bset->dim->n_out &&
215                bmap->dim->nparam == bset->dim->nparam;
216 }
217
218 static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx,
219                 struct isl_basic_map *bmap, unsigned extra,
220                 unsigned n_eq, unsigned n_ineq)
221 {
222         int i;
223         size_t row_size = 1 + isl_dim_total(bmap->dim) + extra;
224
225         bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size);
226         if (isl_blk_is_error(bmap->block)) {
227                 free(bmap);
228                 return NULL;
229         }
230
231         bmap->ineq = isl_alloc_array(ctx, isl_int *, n_ineq + n_eq);
232         if (!bmap->ineq) {
233                 isl_blk_free(ctx, bmap->block);
234                 free(bmap);
235                 return NULL;
236         }
237
238         if (extra == 0) {
239                 bmap->block2 = isl_blk_empty();
240                 bmap->div = NULL;
241         } else {
242                 bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
243                 if (isl_blk_is_error(bmap->block2)) {
244                         free(bmap->ineq);
245                         isl_blk_free(ctx, bmap->block);
246                         free(bmap);
247                         return NULL;
248                 }
249
250                 bmap->div = isl_alloc_array(ctx, isl_int *, extra);
251                 if (!bmap->div) {
252                         isl_blk_free(ctx, bmap->block2);
253                         free(bmap->ineq);
254                         isl_blk_free(ctx, bmap->block);
255                         free(bmap);
256                         return NULL;
257                 }
258         }
259
260         for (i = 0; i < n_ineq + n_eq; ++i)
261                 bmap->ineq[i] = bmap->block.data + i * row_size;
262
263         for (i = 0; i < extra; ++i)
264                 bmap->div[i] = bmap->block2.data + i * (1 + row_size);
265
266         bmap->ctx = ctx;
267         isl_ctx_ref(ctx);
268         bmap->ref = 1;
269         bmap->flags = 0;
270         bmap->c_size = n_eq + n_ineq;
271         bmap->eq = bmap->ineq + n_ineq;
272         bmap->extra = extra;
273         bmap->n_eq = 0;
274         bmap->n_ineq = 0;
275         bmap->n_div = 0;
276         bmap->sample = NULL;
277
278         return bmap;
279 error:
280         isl_basic_map_free(bmap);
281         return NULL;
282 }
283
284 struct isl_basic_set *isl_basic_set_alloc(struct isl_ctx *ctx,
285                 unsigned nparam, unsigned dim, unsigned extra,
286                 unsigned n_eq, unsigned n_ineq)
287 {
288         struct isl_basic_map *bmap;
289         bmap = isl_basic_map_alloc(ctx, nparam, 0, dim, extra, n_eq, n_ineq);
290         return (struct isl_basic_set *)bmap;
291 }
292
293 struct isl_basic_set *isl_basic_set_alloc_dim(struct isl_dim *dim,
294                 unsigned extra, unsigned n_eq, unsigned n_ineq)
295 {
296         struct isl_basic_map *bmap;
297         if (!dim)
298                 return NULL;
299         isl_assert(dim->ctx, dim->n_in == 0, return NULL);
300         bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
301         return (struct isl_basic_set *)bmap;
302 }
303
304 struct isl_basic_map *isl_basic_map_alloc_dim(struct isl_dim *dim,
305                 unsigned extra, unsigned n_eq, unsigned n_ineq)
306 {
307         struct isl_basic_map *bmap;
308
309         if (!dim)
310                 return NULL;
311         bmap = isl_alloc_type(dim->ctx, struct isl_basic_map);
312         if (!bmap)
313                 goto error;
314         bmap->dim = dim;
315
316         return basic_map_init(dim->ctx, bmap, extra, n_eq, n_ineq);
317 error:
318         isl_dim_free(dim);
319         return NULL;
320 }
321
322 struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx,
323                 unsigned nparam, unsigned in, unsigned out, unsigned extra,
324                 unsigned n_eq, unsigned n_ineq)
325 {
326         struct isl_basic_map *bmap;
327         struct isl_dim *dim;
328
329         dim = isl_dim_alloc(ctx, nparam, in, out);
330         if (!dim)
331                 return NULL;
332
333         bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
334         return bmap;
335 }
336
337 static void dup_constraints(
338                 struct isl_basic_map *dst, struct isl_basic_map *src)
339 {
340         int i;
341         unsigned total = isl_basic_map_total_dim(src);
342
343         for (i = 0; i < src->n_eq; ++i) {
344                 int j = isl_basic_map_alloc_equality(dst);
345                 isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
346         }
347
348         for (i = 0; i < src->n_ineq; ++i) {
349                 int j = isl_basic_map_alloc_inequality(dst);
350                 isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
351         }
352
353         for (i = 0; i < src->n_div; ++i) {
354                 int j = isl_basic_map_alloc_div(dst);
355                 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
356         }
357         ISL_F_SET(dst, ISL_BASIC_SET_FINAL);
358 }
359
360 struct isl_basic_map *isl_basic_map_dup(struct isl_basic_map *bmap)
361 {
362         struct isl_basic_map *dup;
363
364         if (!bmap)
365                 return NULL;
366         dup = isl_basic_map_alloc_dim(isl_dim_copy(bmap->dim),
367                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
368         if (!dup)
369                 return NULL;
370         dup->flags = bmap->flags;
371         dup_constraints(dup, bmap);
372         dup->sample = isl_vec_copy(bmap->ctx, bmap->sample);
373         return dup;
374 }
375
376 struct isl_basic_set *isl_basic_set_dup(struct isl_basic_set *bset)
377 {
378         struct isl_basic_map *dup;
379
380         dup = isl_basic_map_dup((struct isl_basic_map *)bset);
381         return (struct isl_basic_set *)dup;
382 }
383
384 struct isl_basic_set *isl_basic_set_copy(struct isl_basic_set *bset)
385 {
386         if (!bset)
387                 return NULL;
388
389         if (ISL_F_ISSET(bset, ISL_BASIC_SET_FINAL)) {
390                 bset->ref++;
391                 return bset;
392         }
393         return isl_basic_set_dup(bset);
394 }
395
396 struct isl_set *isl_set_copy(struct isl_set *set)
397 {
398         if (!set)
399                 return NULL;
400
401         set->ref++;
402         return set;
403 }
404
405 struct isl_basic_map *isl_basic_map_copy(struct isl_basic_map *bmap)
406 {
407         if (!bmap)
408                 return NULL;
409
410         if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)) {
411                 bmap->ref++;
412                 return bmap;
413         }
414         return isl_basic_map_dup(bmap);
415 }
416
417 struct isl_map *isl_map_copy(struct isl_map *map)
418 {
419         if (!map)
420                 return NULL;
421
422         map->ref++;
423         return map;
424 }
425
426 void isl_basic_map_free(struct isl_basic_map *bmap)
427 {
428         if (!bmap)
429                 return;
430
431         if (--bmap->ref > 0)
432                 return;
433
434         isl_ctx_deref(bmap->ctx);
435         free(bmap->div);
436         isl_blk_free(bmap->ctx, bmap->block2);
437         free(bmap->ineq);
438         isl_blk_free(bmap->ctx, bmap->block);
439         isl_vec_free(bmap->ctx, bmap->sample);
440         isl_dim_free(bmap->dim);
441         free(bmap);
442 }
443
444 void isl_basic_set_free(struct isl_basic_set *bset)
445 {
446         isl_basic_map_free((struct isl_basic_map *)bset);
447 }
448
449 int isl_basic_map_alloc_equality(struct isl_basic_map *bmap)
450 {
451         struct isl_ctx *ctx;
452         if (!bmap)
453                 return -1;
454         ctx = bmap->ctx;
455         isl_assert(ctx, bmap->n_eq + bmap->n_ineq < bmap->c_size, return -1);
456         isl_assert(ctx, (bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size,
457                         return -1);
458         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
459         if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
460                 isl_int *t;
461                 int j = isl_basic_map_alloc_inequality(bmap);
462                 if (j < 0)
463                         return -1;
464                 t = bmap->ineq[j];
465                 bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
466                 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
467                 bmap->eq[-1] = t;
468                 bmap->n_eq++;
469                 bmap->n_ineq--;
470                 bmap->eq--;
471                 return 0;
472         }
473         isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + isl_basic_map_total_dim(bmap),
474                       bmap->extra - bmap->n_div);
475         return bmap->n_eq++;
476 }
477
478 int isl_basic_set_alloc_equality(struct isl_basic_set *bset)
479 {
480         return isl_basic_map_alloc_equality((struct isl_basic_map *)bset);
481 }
482
483 int isl_basic_map_free_equality(struct isl_basic_map *bmap, unsigned n)
484 {
485         if (!bmap)
486                 return -1;
487         isl_assert(bmap->ctx, n <= bmap->n_eq, return -1);
488         bmap->n_eq -= n;
489         return 0;
490 }
491
492 int isl_basic_map_drop_equality(struct isl_basic_map *bmap, unsigned pos)
493 {
494         isl_int *t;
495         if (!bmap)
496                 return -1;
497         isl_assert(bmap->ctx, pos < bmap->n_eq, return -1);
498
499         if (pos != bmap->n_eq - 1) {
500                 t = bmap->eq[pos];
501                 bmap->eq[pos] = bmap->eq[bmap->n_eq - 1];
502                 bmap->eq[bmap->n_eq - 1] = t;
503         }
504         bmap->n_eq--;
505         return 0;
506 }
507
508 int isl_basic_set_drop_equality(struct isl_basic_set *bset, unsigned pos)
509 {
510         return isl_basic_map_drop_equality((struct isl_basic_map *)bset, pos);
511 }
512
513 void isl_basic_map_inequality_to_equality(
514                 struct isl_basic_map *bmap, unsigned pos)
515 {
516         isl_int *t;
517
518         t = bmap->ineq[pos];
519         bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
520         bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
521         bmap->eq[-1] = t;
522         bmap->n_eq++;
523         bmap->n_ineq--;
524         bmap->eq--;
525         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
526         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
527         ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
528 }
529
530 int isl_basic_map_alloc_inequality(struct isl_basic_map *bmap)
531 {
532         struct isl_ctx *ctx;
533         if (!bmap)
534                 return -1;
535         ctx = bmap->ctx;
536         isl_assert(ctx, bmap->n_ineq < bmap->eq - bmap->ineq, return -1);
537         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
538         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
539         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
540         ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
541         isl_seq_clr(bmap->ineq[bmap->n_ineq] +
542                       1 + isl_basic_map_total_dim(bmap),
543                       bmap->extra - bmap->n_div);
544         return bmap->n_ineq++;
545 }
546
547 int isl_basic_set_alloc_inequality(struct isl_basic_set *bset)
548 {
549         return isl_basic_map_alloc_inequality((struct isl_basic_map *)bset);
550 }
551
552 int isl_basic_map_free_inequality(struct isl_basic_map *bmap, unsigned n)
553 {
554         if (!bmap)
555                 return -1;
556         isl_assert(bmap->ctx, n <= bmap->n_ineq, return -1);
557         bmap->n_ineq -= n;
558         return 0;
559 }
560
561 int isl_basic_set_free_inequality(struct isl_basic_set *bset, unsigned n)
562 {
563         return isl_basic_map_free_inequality((struct isl_basic_map *)bset, n);
564 }
565
566 int isl_basic_map_drop_inequality(struct isl_basic_map *bmap, unsigned pos)
567 {
568         isl_int *t;
569         if (!bmap)
570                 return -1;
571         isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
572
573         if (pos != bmap->n_ineq - 1) {
574                 t = bmap->ineq[pos];
575                 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
576                 bmap->ineq[bmap->n_ineq - 1] = t;
577                 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
578         }
579         bmap->n_ineq--;
580         return 0;
581 }
582
583 int isl_basic_set_drop_inequality(struct isl_basic_set *bset, unsigned pos)
584 {
585         return isl_basic_map_drop_inequality((struct isl_basic_map *)bset, pos);
586 }
587
588 int isl_basic_map_alloc_div(struct isl_basic_map *bmap)
589 {
590         if (!bmap)
591                 return -1;
592         isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1);
593         isl_seq_clr(bmap->div[bmap->n_div] +
594                       1 + 1 + isl_basic_map_total_dim(bmap),
595                       bmap->extra - bmap->n_div);
596         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
597         return bmap->n_div++;
598 }
599
600 int isl_basic_map_free_div(struct isl_basic_map *bmap, unsigned n)
601 {
602         if (!bmap)
603                 return -1;
604         isl_assert(bmap->ctx, n <= bmap->n_div, return -1);
605         bmap->n_div -= n;
606         return 0;
607 }
608
609 /* Copy constraint from src to dst, putting the vars of src at offset
610  * dim_off in dst and the divs of src at offset div_off in dst.
611  * If both sets are actually map, then dim_off applies to the input
612  * variables.
613  */
614 static void copy_constraint(struct isl_basic_map *dst_map, isl_int *dst,
615                             struct isl_basic_map *src_map, isl_int *src,
616                             unsigned in_off, unsigned out_off, unsigned div_off)
617 {
618         unsigned src_nparam = isl_basic_map_n_param(src_map);
619         unsigned dst_nparam = isl_basic_map_n_param(dst_map);
620         unsigned src_in = isl_basic_map_n_in(src_map);
621         unsigned dst_in = isl_basic_map_n_in(dst_map);
622         unsigned src_out = isl_basic_map_n_out(src_map);
623         unsigned dst_out = isl_basic_map_n_out(dst_map);
624         isl_int_set(dst[0], src[0]);
625         isl_seq_cpy(dst+1, src+1, isl_min(dst_nparam, src_nparam));
626         if (dst_nparam > src_nparam)
627                 isl_seq_clr(dst+1+src_nparam,
628                                 dst_nparam - src_nparam);
629         isl_seq_clr(dst+1+dst_nparam, in_off);
630         isl_seq_cpy(dst+1+dst_nparam+in_off,
631                     src+1+src_nparam,
632                     isl_min(dst_in-in_off, src_in));
633         if (dst_in-in_off > src_in)
634                 isl_seq_clr(dst+1+dst_nparam+in_off+src_in,
635                                 dst_in - in_off - src_in);
636         isl_seq_clr(dst+1+dst_nparam+dst_in, out_off);
637         isl_seq_cpy(dst+1+dst_nparam+dst_in+out_off,
638                     src+1+src_nparam+src_in,
639                     isl_min(dst_out-out_off, src_out));
640         if (dst_out-out_off > src_out)
641                 isl_seq_clr(dst+1+dst_nparam+dst_in+out_off+src_out,
642                                 dst_out - out_off - src_out);
643         isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out, div_off);
644         isl_seq_cpy(dst+1+dst_nparam+dst_in+dst_out+div_off,
645                     src+1+src_nparam+src_in+src_out,
646                     isl_min(dst_map->extra-div_off, src_map->n_div));
647         if (dst_map->n_div-div_off > src_map->n_div)
648                 isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out+
649                                 div_off+src_map->n_div,
650                                 dst_map->n_div - div_off - src_map->n_div);
651 }
652
653 static void copy_div(struct isl_basic_map *dst_map, isl_int *dst,
654                      struct isl_basic_map *src_map, isl_int *src,
655                      unsigned in_off, unsigned out_off, unsigned div_off)
656 {
657         isl_int_set(dst[0], src[0]);
658         copy_constraint(dst_map, dst+1, src_map, src+1, in_off, out_off, div_off);
659 }
660
661 static struct isl_basic_map *add_constraints(struct isl_basic_map *bmap1,
662                 struct isl_basic_map *bmap2, unsigned i_pos, unsigned o_pos)
663 {
664         int i;
665         unsigned div_off;
666
667         if (!bmap1 || !bmap2)
668                 goto error;
669
670         div_off = bmap1->n_div;
671
672         for (i = 0; i < bmap2->n_eq; ++i) {
673                 int i1 = isl_basic_map_alloc_equality(bmap1);
674                 if (i1 < 0)
675                         goto error;
676                 copy_constraint(bmap1, bmap1->eq[i1], bmap2, bmap2->eq[i],
677                                 i_pos, o_pos, div_off);
678         }
679
680         for (i = 0; i < bmap2->n_ineq; ++i) {
681                 int i1 = isl_basic_map_alloc_inequality(bmap1);
682                 if (i1 < 0)
683                         goto error;
684                 copy_constraint(bmap1, bmap1->ineq[i1], bmap2, bmap2->ineq[i],
685                                 i_pos, o_pos, div_off);
686         }
687
688         for (i = 0; i < bmap2->n_div; ++i) {
689                 int i1 = isl_basic_map_alloc_div(bmap1);
690                 if (i1 < 0)
691                         goto error;
692                 copy_div(bmap1, bmap1->div[i1], bmap2, bmap2->div[i],
693                          i_pos, o_pos, div_off);
694         }
695
696         isl_basic_map_free(bmap2);
697
698         return bmap1;
699
700 error:
701         isl_basic_map_free(bmap1);
702         isl_basic_map_free(bmap2);
703         return NULL;
704 }
705
706 static void copy_constraint_dim_map(isl_int *dst, isl_int *src,
707                                         struct isl_dim_map *dim_map)
708 {
709         int i;
710
711         for (i = 0; i < dim_map->len; ++i) {
712                 if (dim_map->pos[i] < 0)
713                         isl_int_set_si(dst[i], 0);
714                 else
715                         isl_int_set(dst[i], src[dim_map->pos[i]]);
716         }
717 }
718
719 static void copy_div_dim_map(isl_int *dst, isl_int *src,
720                                         struct isl_dim_map *dim_map)
721 {
722         isl_int_set(dst[0], src[0]);
723         copy_constraint_dim_map(dst+1, src+1, dim_map);
724 }
725
726 static struct isl_basic_map *add_constraints_dim_map(struct isl_basic_map *dst,
727                 struct isl_basic_map *src, struct isl_dim_map *dim_map)
728 {
729         int i;
730
731         if (!src || !dst || !dim_map)
732                 goto error;
733
734         for (i = 0; i < src->n_eq; ++i) {
735                 int i1 = isl_basic_map_alloc_equality(dst);
736                 if (i1 < 0)
737                         goto error;
738                 copy_constraint_dim_map(dst->eq[i1], src->eq[i], dim_map);
739         }
740
741         for (i = 0; i < src->n_ineq; ++i) {
742                 int i1 = isl_basic_map_alloc_inequality(dst);
743                 if (i1 < 0)
744                         goto error;
745                 copy_constraint_dim_map(dst->ineq[i1], src->ineq[i], dim_map);
746         }
747
748         for (i = 0; i < src->n_div; ++i) {
749                 int i1 = isl_basic_map_alloc_div(dst);
750                 if (i1 < 0)
751                         goto error;
752                 copy_div_dim_map(dst->div[i1], src->div[i], dim_map);
753         }
754
755         free(dim_map);
756         isl_basic_map_free(src);
757
758         return dst;
759 error:
760         free(dim_map);
761         isl_basic_map_free(src);
762         isl_basic_map_free(dst);
763         return NULL;
764 }
765
766 struct isl_basic_set *isl_basic_set_add_constraints(struct isl_basic_set *bset1,
767                 struct isl_basic_set *bset2, unsigned pos)
768 {
769         return (struct isl_basic_set *)
770                 add_constraints((struct isl_basic_map *)bset1,
771                                 (struct isl_basic_map *)bset2, 0, pos);
772 }
773
774 struct isl_basic_map *isl_basic_map_extend_dim(struct isl_basic_map *base,
775                 struct isl_dim *dim, unsigned extra,
776                 unsigned n_eq, unsigned n_ineq)
777 {
778         struct isl_basic_map *ext;
779         unsigned flags;
780         int dims_ok;
781
782         if (!dim)
783                 goto error;
784
785         base = isl_basic_map_cow(base);
786         if (!base)
787                 goto error;
788
789         dims_ok = isl_dim_equal(base->dim, dim) &&
790                   base->extra >= base->n_div + extra;
791
792         if (dims_ok && n_eq == 0 && n_ineq == 0) {
793                 isl_dim_free(dim);
794                 return base;
795         }
796
797         isl_assert(base->ctx, base->dim->nparam <= dim->nparam, goto error);
798         isl_assert(base->ctx, base->dim->n_in <= dim->n_in, goto error);
799         isl_assert(base->ctx, base->dim->n_out <= dim->n_out, goto error);
800         extra += base->extra;
801         n_eq += base->n_eq;
802         n_ineq += base->n_ineq;
803
804         ext = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
805         dim = NULL;
806         if (!ext)
807                 goto error;
808
809         flags = base->flags;
810         ext = add_constraints(ext, base, 0, 0);
811         if (ext) {
812                 ext->flags = flags;
813                 ISL_F_CLR(ext, ISL_BASIC_SET_FINAL);
814         }
815
816         return ext;
817
818 error:
819         isl_dim_free(dim);
820         isl_basic_map_free(base);
821         return NULL;
822 }
823
824 struct isl_basic_map *isl_basic_map_extend_constraints(
825                 struct isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
826 {
827         if (!base)
828                 return NULL;
829         return isl_basic_map_extend_dim(base, isl_dim_copy(base->dim),
830                                         0, n_eq, n_ineq);
831 }
832
833 struct isl_basic_map *isl_basic_map_extend(struct isl_basic_map *base,
834                 unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra,
835                 unsigned n_eq, unsigned n_ineq)
836 {
837         struct isl_basic_map *bmap;
838         struct isl_dim *dim;
839
840         if (!base)
841                 return NULL;
842         dim = isl_dim_alloc(base->ctx, nparam, n_in, n_out);
843         if (!dim)
844                 return NULL;
845
846         bmap = isl_basic_map_extend_dim(base, dim, extra, n_eq, n_ineq);
847         return bmap;
848 }
849
850 struct isl_basic_set *isl_basic_set_extend(struct isl_basic_set *base,
851                 unsigned nparam, unsigned dim, unsigned extra,
852                 unsigned n_eq, unsigned n_ineq)
853 {
854         return (struct isl_basic_set *)
855                 isl_basic_map_extend((struct isl_basic_map *)base,
856                                         nparam, 0, dim, extra, n_eq, n_ineq);
857 }
858
859 struct isl_basic_set *isl_basic_set_extend_constraints(
860                 struct isl_basic_set *base, unsigned n_eq, unsigned n_ineq)
861 {
862         return (struct isl_basic_set *)
863                 isl_basic_map_extend_constraints((struct isl_basic_map *)base,
864                                                     n_eq, n_ineq);
865 }
866
867 struct isl_basic_set *isl_basic_set_cow(struct isl_basic_set *bset)
868 {
869         return (struct isl_basic_set *)
870                 isl_basic_map_cow((struct isl_basic_map *)bset);
871 }
872
873 struct isl_basic_map *isl_basic_map_cow(struct isl_basic_map *bmap)
874 {
875         if (!bmap)
876                 return NULL;
877
878         if (bmap->ref > 1) {
879                 bmap->ref--;
880                 bmap = isl_basic_map_dup(bmap);
881         }
882         ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL);
883         return bmap;
884 }
885
886 struct isl_set *isl_set_cow(struct isl_set *set)
887 {
888         if (!set)
889                 return NULL;
890
891         if (set->ref == 1)
892                 return set;
893         set->ref--;
894         return isl_set_dup(set);
895 }
896
897 struct isl_map *isl_map_cow(struct isl_map *map)
898 {
899         if (!map)
900                 return NULL;
901
902         if (map->ref == 1)
903                 return map;
904         map->ref--;
905         return isl_map_dup(map);
906 }
907
908 static void swap_vars(struct isl_blk blk, isl_int *a,
909                         unsigned a_len, unsigned b_len)
910 {
911         isl_seq_cpy(blk.data, a+a_len, b_len);
912         isl_seq_cpy(blk.data+b_len, a, a_len);
913         isl_seq_cpy(a, blk.data, b_len+a_len);
914 }
915
916 struct isl_basic_set *isl_basic_set_swap_vars(
917                 struct isl_basic_set *bset, unsigned n)
918 {
919         int i;
920         struct isl_blk blk;
921         unsigned dim;
922         unsigned nparam;
923
924         if (!bset)
925                 goto error;
926
927         nparam = isl_basic_set_n_param(bset);
928         dim = isl_basic_set_n_dim(bset);
929         isl_assert(bset->ctx, n <= dim, goto error);
930
931         if (n == dim)
932                 return bset;
933
934         bset = isl_basic_set_cow(bset);
935         if (!bset)
936                 return NULL;
937
938         blk = isl_blk_alloc(bset->ctx, dim);
939         if (isl_blk_is_error(blk))
940                 goto error;
941
942         for (i = 0; i < bset->n_eq; ++i)
943                 swap_vars(blk,
944                           bset->eq[i]+1+nparam, n, dim - n);
945
946         for (i = 0; i < bset->n_ineq; ++i)
947                 swap_vars(blk,
948                           bset->ineq[i]+1+nparam, n, dim - n);
949
950         for (i = 0; i < bset->n_div; ++i)
951                 swap_vars(blk,
952                           bset->div[i]+1+1+nparam, n, dim - n);
953
954         isl_blk_free(bset->ctx, blk);
955
956         ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED);
957         return bset;
958
959 error:
960         isl_basic_set_free(bset);
961         return NULL;
962 }
963
964 struct isl_set *isl_set_swap_vars(struct isl_set *set, unsigned n)
965 {
966         int i;
967         set = isl_set_cow(set);
968         if (!set)
969                 return NULL;
970
971         for (i = 0; i < set->n; ++i) {
972                 set->p[i] = isl_basic_set_swap_vars(set->p[i], n);
973                 if (!set->p[i]) {
974                         isl_set_free(set);
975                         return NULL;
976                 }
977         }
978         ISL_F_CLR(set, ISL_SET_NORMALIZED);
979         return set;
980 }
981
982 struct isl_basic_map *isl_basic_map_set_to_empty(struct isl_basic_map *bmap)
983 {
984         int i = 0;
985         unsigned total;
986         if (!bmap)
987                 goto error;
988         total = isl_basic_map_total_dim(bmap);
989         isl_basic_map_free_div(bmap, bmap->n_div);
990         isl_basic_map_free_inequality(bmap, bmap->n_ineq);
991         if (bmap->n_eq > 0)
992                 isl_basic_map_free_equality(bmap, bmap->n_eq-1);
993         else {
994                 isl_basic_map_alloc_equality(bmap);
995                 if (i < 0)
996                         goto error;
997         }
998         isl_int_set_si(bmap->eq[i][0], 1);
999         isl_seq_clr(bmap->eq[i]+1, total);
1000         ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
1001         return isl_basic_map_finalize(bmap);
1002 error:
1003         isl_basic_map_free(bmap);
1004         return NULL;
1005 }
1006
1007 struct isl_basic_set *isl_basic_set_set_to_empty(struct isl_basic_set *bset)
1008 {
1009         return (struct isl_basic_set *)
1010                 isl_basic_map_set_to_empty((struct isl_basic_map *)bset);
1011 }
1012
1013 static void swap_div(struct isl_basic_map *bmap, int a, int b)
1014 {
1015         int i;
1016         unsigned off = isl_dim_total(bmap->dim);
1017         isl_int *t = bmap->div[a];
1018         bmap->div[a] = bmap->div[b];
1019         bmap->div[b] = t;
1020
1021         for (i = 0; i < bmap->n_eq; ++i)
1022                 isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]);
1023
1024         for (i = 0; i < bmap->n_ineq; ++i)
1025                 isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]);
1026
1027         for (i = 0; i < bmap->n_div; ++i)
1028                 isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]);
1029         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1030 }
1031
1032 /* Eliminate the specified n dimensions starting at first from the
1033  * constraints using Fourier-Motzkin, The dimensions themselves
1034  * are not removed.
1035  */
1036 struct isl_set *isl_set_eliminate_dims(struct isl_set *set,
1037         unsigned first, unsigned n)
1038 {
1039         int i;
1040         unsigned nparam;
1041
1042         if (!set)
1043                 return NULL;
1044         if (n == 0)
1045                 return set;
1046
1047         set = isl_set_cow(set);
1048         if (!set)
1049                 return NULL;
1050         isl_assert(set->ctx, first+n <= isl_set_n_dim(set), goto error);
1051         nparam = isl_set_n_param(set);
1052         
1053         for (i = 0; i < set->n; ++i) {
1054                 set->p[i] = isl_basic_set_eliminate_vars(set->p[i],
1055                                                             nparam + first, n);
1056                 if (!set->p[i])
1057                         goto error;
1058         }
1059         return set;
1060 error:
1061         isl_set_free(set);
1062         return NULL;
1063 }
1064
1065 /* Project out n dimensions starting at first using Fourier-Motzkin */
1066 struct isl_set *isl_set_remove_dims(struct isl_set *set,
1067         unsigned first, unsigned n)
1068 {
1069         set = isl_set_eliminate_dims(set, first, n);
1070         set = isl_set_drop_dims(set, first, n);
1071         return set;
1072 }
1073
1074 struct isl_basic_set *isl_basic_set_remove_divs(struct isl_basic_set *bset)
1075 {
1076         bset = isl_basic_set_eliminate_vars(bset, isl_dim_total(bset->dim),
1077                                                 bset->n_div);
1078         if (!bset)
1079                 return NULL;
1080         bset->n_div = 0;
1081         return bset;
1082 }
1083
1084 struct isl_set *isl_set_remove_divs(struct isl_set *set)
1085 {
1086         int i;
1087
1088         if (!set)
1089                 return NULL;
1090         if (set->n == 0)
1091                 return set;
1092
1093         set = isl_set_cow(set);
1094         if (!set)
1095                 return NULL;
1096         
1097         for (i = 0; i < set->n; ++i) {
1098                 set->p[i] = isl_basic_set_remove_divs(set->p[i]);
1099                 if (!set->p[i])
1100                         goto error;
1101         }
1102         return set;
1103 error:
1104         isl_set_free(set);
1105         return NULL;
1106 }
1107
1108 struct isl_basic_map *isl_basic_map_remove(struct isl_basic_map *bmap,
1109         enum isl_dim_type type, unsigned first, unsigned n)
1110 {
1111         if (!bmap)
1112                 return NULL;
1113         isl_assert(bmap->ctx, first + n <= isl_basic_map_dim(bmap, type),
1114                         goto error);
1115         if (n == 0)
1116                 return bmap;
1117         bmap = isl_basic_map_eliminate_vars(bmap,
1118                         isl_basic_map_offset(bmap, type) - 1 + first, n);
1119         bmap = isl_basic_map_drop(bmap, type, first, n);
1120         return bmap;
1121 error:
1122         isl_basic_map_free(bmap);
1123         return NULL;
1124 }
1125
1126 struct isl_map *isl_map_remove(struct isl_map *map,
1127         enum isl_dim_type type, unsigned first, unsigned n)
1128 {
1129         int i;
1130         unsigned nparam;
1131
1132         if (n == 0)
1133                 return map;
1134
1135         map = isl_map_cow(map);
1136         if (!map)
1137                 return NULL;
1138         isl_assert(map->ctx, first + n <= isl_map_dim(map, type), goto error);
1139         
1140         for (i = 0; i < map->n; ++i) {
1141                 map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
1142                         isl_basic_map_offset(map->p[i], type) - 1 + first, n);
1143                 if (!map->p[i])
1144                         goto error;
1145         }
1146         map = isl_map_drop(map, type, first, n);
1147         return map;
1148 error:
1149         isl_map_free(map);
1150         return NULL;
1151 }
1152
1153 /* Project out n inputs starting at first using Fourier-Motzkin */
1154 struct isl_map *isl_map_remove_inputs(struct isl_map *map,
1155         unsigned first, unsigned n)
1156 {
1157         return isl_map_remove(map, isl_dim_in, first, n);
1158 }
1159
1160 /* Project out n dimensions starting at first using Fourier-Motzkin */
1161 struct isl_basic_set *isl_basic_set_remove_dims(struct isl_basic_set *bset,
1162         unsigned first, unsigned n)
1163 {
1164         unsigned nparam = isl_basic_set_n_param(bset);
1165         bset = isl_basic_set_eliminate_vars(bset, nparam + first, n);
1166         bset = isl_basic_set_drop_dims(bset, first, n);
1167         return bset;
1168 }
1169
1170 static void dump_term(struct isl_basic_map *bmap,
1171                         isl_int c, int pos, FILE *out)
1172 {
1173         const char *name;
1174         unsigned in = isl_basic_map_n_in(bmap);
1175         unsigned dim = in + isl_basic_map_n_out(bmap);
1176         unsigned nparam = isl_basic_map_n_param(bmap);
1177         if (!pos)
1178                 isl_int_print(out, c, 0);
1179         else {
1180                 if (!isl_int_is_one(c))
1181                         isl_int_print(out, c, 0);
1182                 if (pos < 1 + nparam) {
1183                         name = isl_dim_get_name(bmap->dim,
1184                                                 isl_dim_param, pos - 1);
1185                         if (name)
1186                                 fprintf(out, "%s", name);
1187                         else
1188                                 fprintf(out, "p%d", pos - 1);
1189                 } else if (pos < 1 + nparam + in)
1190                         fprintf(out, "i%d", pos - 1 - nparam);
1191                 else if (pos < 1 + nparam + dim)
1192                         fprintf(out, "o%d", pos - 1 - nparam - in);
1193                 else
1194                         fprintf(out, "e%d", pos - 1 - nparam - dim);
1195         }
1196 }
1197
1198 static void dump_constraint_sign(struct isl_basic_map *bmap, isl_int *c,
1199                                 int sign, FILE *out)
1200 {
1201         int i;
1202         int first;
1203         unsigned len = 1 + isl_basic_map_total_dim(bmap);
1204         isl_int v;
1205
1206         isl_int_init(v);
1207         for (i = 0, first = 1; i < len; ++i) {
1208                 if (isl_int_sgn(c[i]) * sign <= 0)
1209                         continue;
1210                 if (!first)
1211                         fprintf(out, " + ");
1212                 first = 0;
1213                 isl_int_abs(v, c[i]);
1214                 dump_term(bmap, v, i, out);
1215         }
1216         isl_int_clear(v);
1217         if (first)
1218                 fprintf(out, "0");
1219 }
1220
1221 static void dump_constraint(struct isl_basic_map *bmap, isl_int *c,
1222                                 const char *op, FILE *out, int indent)
1223 {
1224         int i;
1225
1226         fprintf(out, "%*s", indent, "");
1227
1228         dump_constraint_sign(bmap, c, 1, out);
1229         fprintf(out, " %s ", op);
1230         dump_constraint_sign(bmap, c, -1, out);
1231
1232         fprintf(out, "\n");
1233
1234         for (i = bmap->n_div; i < bmap->extra; ++i) {
1235                 if (isl_int_is_zero(c[1+isl_dim_total(bmap->dim)+i]))
1236                         continue;
1237                 fprintf(out, "%*s", indent, "");
1238                 fprintf(out, "ERROR: unused div coefficient not zero\n");
1239                 abort();
1240         }
1241 }
1242
1243 static void dump_constraints(struct isl_basic_map *bmap,
1244                                 isl_int **c, unsigned n,
1245                                 const char *op, FILE *out, int indent)
1246 {
1247         int i;
1248
1249         for (i = 0; i < n; ++i)
1250                 dump_constraint(bmap, c[i], op, out, indent);
1251 }
1252
1253 static void dump_affine(struct isl_basic_map *bmap, isl_int *exp, FILE *out)
1254 {
1255         int j;
1256         int first = 1;
1257         unsigned total = isl_basic_map_total_dim(bmap);
1258
1259         for (j = 0; j < 1 + total; ++j) {
1260                 if (isl_int_is_zero(exp[j]))
1261                         continue;
1262                 if (!first && isl_int_is_pos(exp[j]))
1263                         fprintf(out, "+");
1264                 dump_term(bmap, exp[j], j, out);
1265                 first = 0;
1266         }
1267 }
1268
1269 static void dump(struct isl_basic_map *bmap, FILE *out, int indent)
1270 {
1271         int i;
1272
1273         dump_constraints(bmap, bmap->eq, bmap->n_eq, "=", out, indent);
1274         dump_constraints(bmap, bmap->ineq, bmap->n_ineq, ">=", out, indent);
1275
1276         for (i = 0; i < bmap->n_div; ++i) {
1277                 fprintf(out, "%*s", indent, "");
1278                 fprintf(out, "e%d = [(", i);
1279                 dump_affine(bmap, bmap->div[i]+1, out);
1280                 fprintf(out, ")/");
1281                 isl_int_print(out, bmap->div[i][0], 0);
1282                 fprintf(out, "]\n");
1283         }
1284 }
1285
1286 void isl_basic_set_dump(struct isl_basic_set *bset, FILE *out, int indent)
1287 {
1288         if (!bset) {
1289                 fprintf(out, "null basic set\n");
1290                 return;
1291         }
1292
1293         fprintf(out, "%*s", indent, "");
1294         fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
1295                         bset->ref, bset->dim->nparam, bset->dim->n_out,
1296                         bset->extra, bset->flags);
1297         dump((struct isl_basic_map *)bset, out, indent);
1298 }
1299
1300 void isl_basic_map_dump(struct isl_basic_map *bmap, FILE *out, int indent)
1301 {
1302         if (!bmap) {
1303                 fprintf(out, "null basic map\n");
1304                 return;
1305         }
1306
1307         fprintf(out, "%*s", indent, "");
1308         fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
1309                         "flags: %x, n_name: %d\n",
1310                 bmap->ref,
1311                 bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
1312                 bmap->extra, bmap->flags, bmap->dim->n_name);
1313         dump(bmap, out, indent);
1314 }
1315
1316 int isl_inequality_negate(struct isl_basic_map *bmap, unsigned pos)
1317 {
1318         unsigned total;
1319         if (!bmap)
1320                 return -1;
1321         total = isl_basic_map_total_dim(bmap);
1322         isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
1323         isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
1324         isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1);
1325         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1326         return 0;
1327 }
1328
1329 struct isl_set *isl_set_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
1330 {
1331         struct isl_set *set;
1332
1333         if (!dim)
1334                 return NULL;
1335         isl_assert(dim->ctx, dim->n_in == 0, return NULL);
1336         isl_assert(dim->ctx, n >= 0, return NULL);
1337         set = isl_alloc(dim->ctx, struct isl_set,
1338                         sizeof(struct isl_set) +
1339                         n * sizeof(struct isl_basic_set *));
1340         if (!set)
1341                 goto error;
1342
1343         set->ctx = dim->ctx;
1344         isl_ctx_ref(set->ctx);
1345         set->ref = 1;
1346         set->size = n;
1347         set->n = 0;
1348         set->dim = dim;
1349         set->flags = flags;
1350         return set;
1351 error:
1352         isl_dim_free(dim);
1353         return NULL;
1354 }
1355
1356 struct isl_set *isl_set_alloc(struct isl_ctx *ctx,
1357                 unsigned nparam, unsigned dim, int n, unsigned flags)
1358 {
1359         struct isl_set *set;
1360         struct isl_dim *dims;
1361
1362         dims = isl_dim_alloc(ctx, nparam, 0, dim);
1363         if (!dims)
1364                 return NULL;
1365
1366         set = isl_set_alloc_dim(dims, n, flags);
1367         return set;
1368 }
1369
1370 struct isl_set *isl_set_dup(struct isl_set *set)
1371 {
1372         int i;
1373         struct isl_set *dup;
1374
1375         if (!set)
1376                 return NULL;
1377
1378         dup = isl_set_alloc_dim(isl_dim_copy(set->dim), set->n, set->flags);
1379         if (!dup)
1380                 return NULL;
1381         for (i = 0; i < set->n; ++i)
1382                 dup = isl_set_add(dup, isl_basic_set_copy(set->p[i]));
1383         return dup;
1384 }
1385
1386 struct isl_set *isl_set_from_basic_set(struct isl_basic_set *bset)
1387 {
1388         struct isl_set *set;
1389
1390         if (!bset)
1391                 return NULL;
1392
1393         set = isl_set_alloc_dim(isl_dim_copy(bset->dim), 1, ISL_MAP_DISJOINT);
1394         if (!set) {
1395                 isl_basic_set_free(bset);
1396                 return NULL;
1397         }
1398         return isl_set_add(set, bset);
1399 }
1400
1401 struct isl_map *isl_map_from_basic_map(struct isl_basic_map *bmap)
1402 {
1403         struct isl_map *map;
1404
1405         if (!bmap)
1406                 return NULL;
1407
1408         map = isl_map_alloc_dim(isl_dim_copy(bmap->dim), 1, ISL_MAP_DISJOINT);
1409         if (!map) {
1410                 isl_basic_map_free(bmap);
1411                 return NULL;
1412         }
1413         return isl_map_add(map, bmap);
1414 }
1415
1416 struct isl_set *isl_set_add(struct isl_set *set, struct isl_basic_set *bset)
1417 {
1418         if (!bset || !set)
1419                 goto error;
1420         isl_assert(set->ctx, isl_dim_equal(set->dim, bset->dim), goto error);
1421         isl_assert(set->ctx, set->n < set->size, goto error);
1422         set->p[set->n] = bset;
1423         set->n++;
1424         return set;
1425 error:
1426         if (set)
1427                 isl_set_free(set);
1428         if (bset)
1429                 isl_basic_set_free(bset);
1430         return NULL;
1431 }
1432
1433 void isl_set_free(struct isl_set *set)
1434 {
1435         int i;
1436
1437         if (!set)
1438                 return;
1439
1440         if (--set->ref > 0)
1441                 return;
1442
1443         isl_ctx_deref(set->ctx);
1444         for (i = 0; i < set->n; ++i)
1445                 isl_basic_set_free(set->p[i]);
1446         isl_dim_free(set->dim);
1447         free(set);
1448 }
1449
1450 void isl_set_dump(struct isl_set *set, FILE *out, int indent)
1451 {
1452         int i;
1453
1454         if (!set) {
1455                 fprintf(out, "null set\n");
1456                 return;
1457         }
1458
1459         fprintf(out, "%*s", indent, "");
1460         fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
1461                         set->ref, set->n, set->dim->nparam, set->dim->n_out,
1462                         set->flags);
1463         for (i = 0; i < set->n; ++i) {
1464                 fprintf(out, "%*s", indent, "");
1465                 fprintf(out, "basic set %d:\n", i);
1466                 isl_basic_set_dump(set->p[i], out, indent+4);
1467         }
1468 }
1469
1470 void isl_map_dump(struct isl_map *map, FILE *out, int indent)
1471 {
1472         int i;
1473
1474         if (!map) {
1475                 fprintf(out, "null map\n");
1476                 return;
1477         }
1478
1479         fprintf(out, "%*s", indent, "");
1480         fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
1481                      "flags: %x, n_name: %d\n",
1482                         map->ref, map->n, map->dim->nparam, map->dim->n_in,
1483                         map->dim->n_out, map->flags, map->dim->n_name);
1484         for (i = 0; i < map->n; ++i) {
1485                 fprintf(out, "%*s", indent, "");
1486                 fprintf(out, "basic map %d:\n", i);
1487                 isl_basic_map_dump(map->p[i], out, indent+4);
1488         }
1489 }
1490
1491 struct isl_basic_map *isl_basic_map_intersect_domain(
1492                 struct isl_basic_map *bmap, struct isl_basic_set *bset)
1493 {
1494         struct isl_basic_map *bmap_domain;
1495         struct isl_dim *dim;
1496
1497         if (!bmap || !bset)
1498                 goto error;
1499
1500         isl_assert(bset->ctx, isl_dim_match(bmap->dim, isl_dim_param,
1501                                         bset->dim, isl_dim_param), goto error);
1502
1503         if (isl_dim_size(bset->dim, isl_dim_set) != 0)
1504                 isl_assert(bset->ctx,
1505                     isl_basic_map_compatible_domain(bmap, bset), goto error);
1506
1507         bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
1508                         bset->n_div, bset->n_eq, bset->n_ineq);
1509         if (!bmap)
1510                 goto error;
1511         dim = isl_dim_reverse(isl_dim_copy(bset->dim));
1512         bmap_domain = isl_basic_map_from_basic_set(bset, dim);
1513         bmap = add_constraints(bmap, bmap_domain, 0, 0);
1514
1515         bmap = isl_basic_map_simplify(bmap);
1516         return isl_basic_map_finalize(bmap);
1517 error:
1518         isl_basic_map_free(bmap);
1519         isl_basic_set_free(bset);
1520         return NULL;
1521 }
1522
1523 struct isl_basic_map *isl_basic_map_intersect_range(
1524                 struct isl_basic_map *bmap, struct isl_basic_set *bset)
1525 {
1526         struct isl_basic_map *bmap_range;
1527
1528         if (!bmap || !bset)
1529                 goto error;
1530
1531         isl_assert(bset->ctx, isl_dim_match(bmap->dim, isl_dim_param,
1532                                         bset->dim, isl_dim_param), goto error);
1533
1534         if (isl_dim_size(bset->dim, isl_dim_set) != 0)
1535                 isl_assert(bset->ctx,
1536                     isl_basic_map_compatible_range(bmap, bset), goto error);
1537
1538         bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
1539                         bset->n_div, bset->n_eq, bset->n_ineq);
1540         if (!bmap)
1541                 goto error;
1542         bmap_range = isl_basic_map_from_basic_set(bset, isl_dim_copy(bset->dim));
1543         bmap = add_constraints(bmap, bmap_range, 0, 0);
1544
1545         bmap = isl_basic_map_simplify(bmap);
1546         return isl_basic_map_finalize(bmap);
1547 error:
1548         isl_basic_map_free(bmap);
1549         isl_basic_set_free(bset);
1550         return NULL;
1551 }
1552
1553 static int basic_map_contains(struct isl_basic_map *bmap, struct isl_vec *vec)
1554 {
1555         int i;
1556         unsigned total;
1557         isl_int s;
1558
1559         total = 1 + isl_basic_map_total_dim(bmap);
1560         if (total != vec->size)
1561                 return -1;
1562
1563         isl_int_init(s);
1564
1565         for (i = 0; i < bmap->n_eq; ++i) {
1566                 isl_seq_inner_product(vec->block.data, bmap->eq[i], total, &s);
1567                 if (!isl_int_is_zero(s)) {
1568                         isl_int_clear(s);
1569                         return 0;
1570                 }
1571         }
1572
1573         for (i = 0; i < bmap->n_ineq; ++i) {
1574                 isl_seq_inner_product(vec->block.data, bmap->ineq[i], total, &s);
1575                 if (isl_int_is_neg(s)) {
1576                         isl_int_clear(s);
1577                         return 0;
1578                 }
1579         }
1580
1581         isl_int_clear(s);
1582
1583         return 1;
1584 }
1585
1586 struct isl_basic_map *isl_basic_map_intersect(
1587                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
1588 {
1589         struct isl_vec *sample = NULL;
1590
1591         if (!bmap1 || !bmap2)
1592                 goto error;
1593
1594         isl_assert(bmap1->ctx, isl_dim_match(bmap1->dim, isl_dim_param,
1595                                      bmap2->dim, isl_dim_param), goto error);
1596         if (isl_dim_total(bmap1->dim) ==
1597                                 isl_dim_size(bmap1->dim, isl_dim_param) &&
1598             isl_dim_total(bmap2->dim) !=
1599                                 isl_dim_size(bmap2->dim, isl_dim_param))
1600                 return isl_basic_map_intersect(bmap2, bmap1);
1601
1602         if (isl_dim_total(bmap2->dim) !=
1603                                         isl_dim_size(bmap2->dim, isl_dim_param))
1604                 isl_assert(bmap1->ctx,
1605                             isl_dim_equal(bmap1->dim, bmap2->dim), goto error);
1606
1607         if (bmap1->sample &&
1608             basic_map_contains(bmap1, bmap1->sample) > 0 &&
1609             basic_map_contains(bmap2, bmap1->sample) > 0)
1610                 sample = isl_vec_copy(bmap1->ctx, bmap1->sample);
1611         else if (bmap2->sample &&
1612             basic_map_contains(bmap1, bmap2->sample) > 0 &&
1613             basic_map_contains(bmap2, bmap2->sample) > 0)
1614                 sample = isl_vec_copy(bmap2->ctx, bmap2->sample);
1615
1616         bmap1 = isl_basic_map_extend_dim(bmap1, isl_dim_copy(bmap1->dim),
1617                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
1618         if (!bmap1)
1619                 goto error;
1620         bmap1 = add_constraints(bmap1, bmap2, 0, 0);
1621
1622         if (sample) {
1623                 isl_vec_free(bmap1->ctx, bmap1->sample);
1624                 bmap1->sample = sample;
1625         }
1626
1627         bmap1 = isl_basic_map_simplify(bmap1);
1628         return isl_basic_map_finalize(bmap1);
1629 error:
1630         if (sample)
1631                 isl_vec_free(bmap1->ctx, sample);
1632         isl_basic_map_free(bmap1);
1633         isl_basic_map_free(bmap2);
1634         return NULL;
1635 }
1636
1637 struct isl_basic_set *isl_basic_set_intersect(
1638                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
1639 {
1640         return (struct isl_basic_set *)
1641                 isl_basic_map_intersect(
1642                         (struct isl_basic_map *)bset1,
1643                         (struct isl_basic_map *)bset2);
1644 }
1645
1646 struct isl_map *isl_map_intersect(struct isl_map *map1, struct isl_map *map2)
1647 {
1648         unsigned flags = 0;
1649         struct isl_map *result;
1650         int i, j;
1651
1652         if (!map1 || !map2)
1653                 goto error;
1654
1655         isl_assert(map1->ctx, isl_dim_match(map1->dim, isl_dim_param,
1656                                          map2->dim, isl_dim_param), goto error);
1657         if (isl_dim_total(map1->dim) ==
1658                                 isl_dim_size(map1->dim, isl_dim_param) &&
1659             isl_dim_total(map2->dim) != isl_dim_size(map2->dim, isl_dim_param))
1660                 return isl_map_intersect(map2, map1);
1661
1662         if (isl_dim_total(map2->dim) != isl_dim_size(map2->dim, isl_dim_param))
1663                 isl_assert(map1->ctx,
1664                             isl_dim_equal(map1->dim, map2->dim), goto error);
1665
1666         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
1667             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
1668                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
1669
1670         result = isl_map_alloc_dim(isl_dim_copy(map1->dim),
1671                                 map1->n * map2->n, flags);
1672         if (!result)
1673                 goto error;
1674         for (i = 0; i < map1->n; ++i)
1675                 for (j = 0; j < map2->n; ++j) {
1676                         struct isl_basic_map *part;
1677                         part = isl_basic_map_intersect(
1678                                     isl_basic_map_copy(map1->p[i]),
1679                                     isl_basic_map_copy(map2->p[j]));
1680                         if (isl_basic_map_is_empty(part))
1681                                 isl_basic_map_free(part);
1682                         else
1683                                 result = isl_map_add(result, part);
1684                         if (!result)
1685                                 goto error;
1686                 }
1687         isl_map_free(map1);
1688         isl_map_free(map2);
1689         return result;
1690 error:
1691         isl_map_free(map1);
1692         isl_map_free(map2);
1693         return NULL;
1694 }
1695
1696 struct isl_set *isl_set_intersect(struct isl_set *set1, struct isl_set *set2)
1697 {
1698         return (struct isl_set *)
1699                 isl_map_intersect((struct isl_map *)set1,
1700                                   (struct isl_map *)set2);
1701 }
1702
1703 struct isl_basic_map *isl_basic_map_reverse(struct isl_basic_map *bmap)
1704 {
1705         struct isl_dim *dim;
1706         struct isl_basic_set *bset;
1707         unsigned in;
1708
1709         if (!bmap)
1710                 return NULL;
1711         bmap = isl_basic_map_cow(bmap);
1712         if (!bmap)
1713                 return NULL;
1714         dim = isl_dim_reverse(isl_dim_copy(bmap->dim));
1715         in = isl_basic_map_n_in(bmap);
1716         bset = isl_basic_set_from_basic_map(bmap);
1717         bset = isl_basic_set_swap_vars(bset, in);
1718         return isl_basic_map_from_basic_set(bset, dim);
1719 }
1720
1721 /* Turn final n dimensions into existentially quantified variables.
1722  */
1723 struct isl_basic_set *isl_basic_set_project_out(
1724                 struct isl_basic_set *bset, unsigned n, unsigned flags)
1725 {
1726         int i;
1727         size_t row_size;
1728         isl_int **new_div;
1729         isl_int *old;
1730
1731         if (!bset)
1732                 return NULL;
1733
1734         isl_assert(bset->ctx, n <= isl_basic_set_n_dim(bset), goto error);
1735
1736         if (n == 0)
1737                 return bset;
1738
1739         bset = isl_basic_set_cow(bset);
1740
1741         row_size = 1 + isl_dim_total(bset->dim) + bset->extra;
1742         old = bset->block2.data;
1743         bset->block2 = isl_blk_extend(bset->ctx, bset->block2,
1744                                         (bset->extra + n) * (1 + row_size));
1745         if (!bset->block2.data)
1746                 goto error;
1747         new_div = isl_alloc_array(ctx, isl_int *, bset->extra + n);
1748         if (!new_div)
1749                 goto error;
1750         for (i = 0; i < n; ++i) {
1751                 new_div[i] = bset->block2.data +
1752                                 (bset->extra + i) * (1 + row_size);
1753                 isl_seq_clr(new_div[i], 1 + row_size);
1754         }
1755         for (i = 0; i < bset->extra; ++i)
1756                 new_div[n + i] = bset->block2.data + (bset->div[i] - old);
1757         free(bset->div);
1758         bset->div = new_div;
1759         bset->n_div += n;
1760         bset->extra += n;
1761         bset->dim = isl_dim_drop_outputs(bset->dim,
1762                                             isl_basic_set_n_dim(bset) - n, n);
1763         if (!bset->dim)
1764                 goto error;
1765         bset = isl_basic_set_simplify(bset);
1766         return isl_basic_set_finalize(bset);
1767 error:
1768         isl_basic_set_free(bset);
1769         return NULL;
1770 }
1771
1772 struct isl_basic_map *add_divs(struct isl_basic_map *bmap, unsigned n)
1773 {
1774         int i, j;
1775
1776         for (i = 0; i < n; ++i) {
1777                 j = isl_basic_map_alloc_div(bmap);
1778                 if (j < 0)
1779                         goto error;
1780                 isl_seq_clr(bmap->div[j], 1+1+isl_basic_map_total_dim(bmap));
1781         }
1782         return bmap;
1783 error:
1784         isl_basic_map_free(bmap);
1785         return NULL;
1786 }
1787
1788 struct isl_basic_map *isl_basic_map_apply_range(
1789                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
1790 {
1791         struct isl_dim *dim_result = NULL;
1792         struct isl_basic_map *bmap;
1793         unsigned n_in, n_out, n, nparam, total, pos;
1794         struct isl_dim_map *dim_map1, *dim_map2;
1795
1796         if (!bmap1 || !bmap2)
1797                 goto error;
1798
1799         dim_result = isl_dim_join(isl_dim_copy(bmap1->dim),
1800                                   isl_dim_copy(bmap2->dim));
1801
1802         n_in = isl_basic_map_n_in(bmap1);
1803         n_out = isl_basic_map_n_out(bmap2);
1804         n = isl_basic_map_n_out(bmap1);
1805         nparam = isl_basic_map_n_param(bmap1);
1806
1807         total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
1808         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
1809         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
1810         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
1811         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
1812         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
1813         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
1814         isl_dim_map_div(dim_map1, bmap1, pos += n_out);
1815         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
1816         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
1817         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
1818
1819         bmap = isl_basic_map_alloc_dim(dim_result,
1820                         bmap1->n_div + bmap2->n_div + n,
1821                         bmap1->n_eq + bmap2->n_eq,
1822                         bmap1->n_ineq + bmap2->n_ineq);
1823         bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
1824         bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
1825         bmap = add_divs(bmap, n);
1826         bmap = isl_basic_map_simplify(bmap);
1827         return isl_basic_map_finalize(bmap);
1828 error:
1829         isl_basic_map_free(bmap1);
1830         isl_basic_map_free(bmap2);
1831         return NULL;
1832 }
1833
1834 struct isl_basic_set *isl_basic_set_apply(
1835                 struct isl_basic_set *bset, struct isl_basic_map *bmap)
1836 {
1837         if (!bset || !bmap)
1838                 goto error;
1839
1840         isl_assert(set->ctx, isl_basic_map_compatible_domain(bmap, bset),
1841                     goto error);
1842
1843         return (struct isl_basic_set *)
1844                 isl_basic_map_apply_range((struct isl_basic_map *)bset, bmap);
1845 error:
1846         isl_basic_set_free(bset);
1847         isl_basic_map_free(bmap);
1848         return NULL;
1849 }
1850
1851 struct isl_basic_map *isl_basic_map_apply_domain(
1852                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
1853 {
1854         if (!bmap1 || !bmap2)
1855                 goto error;
1856
1857         isl_assert(ctx,
1858             isl_basic_map_n_in(bmap1) == isl_basic_map_n_in(bmap2), goto error);
1859         isl_assert(ctx,
1860             isl_basic_map_n_param(bmap1) == isl_basic_map_n_param(bmap2),
1861             goto error);
1862
1863         bmap1 = isl_basic_map_reverse(bmap1);
1864         bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
1865         return isl_basic_map_reverse(bmap1);
1866 error:
1867         isl_basic_map_free(bmap1);
1868         isl_basic_map_free(bmap2);
1869         return NULL;
1870 }
1871
1872 /* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
1873  * A \cap B -> f(A) + f(B)
1874  */
1875 struct isl_basic_map *isl_basic_map_sum(
1876                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
1877 {
1878         unsigned n_in, n_out, nparam, total, pos;
1879         struct isl_basic_map *bmap = NULL;
1880         struct isl_dim_map *dim_map1, *dim_map2;
1881         int i;
1882
1883         if (!bmap1 || !bmap2)
1884                 goto error;
1885
1886         isl_assert(bmap1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim),
1887                 goto error);
1888
1889         nparam = isl_basic_map_n_param(bmap1);
1890         n_in = isl_basic_map_n_in(bmap1);
1891         n_out = isl_basic_map_n_out(bmap1);
1892
1893         total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
1894         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
1895         dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
1896         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
1897         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
1898         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
1899         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
1900         isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
1901         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
1902         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
1903         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
1904
1905         bmap = isl_basic_map_alloc_dim(isl_dim_copy(bmap1->dim),
1906                         bmap1->n_div + bmap2->n_div + 2 * n_out,
1907                         bmap1->n_eq + bmap2->n_eq + n_out,
1908                         bmap1->n_ineq + bmap2->n_ineq);
1909         for (i = 0; i < n_out; ++i) {
1910                 int j = isl_basic_map_alloc_equality(bmap);
1911                 if (j < 0)
1912                         goto error;
1913                 isl_seq_clr(bmap->eq[j], 1+total);
1914                 isl_int_set_si(bmap->eq[j][1+nparam+n_in+i], -1);
1915                 isl_int_set_si(bmap->eq[j][1+pos+i], 1);
1916                 isl_int_set_si(bmap->eq[j][1+pos-n_out+i], 1);
1917         }
1918         bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
1919         bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
1920         bmap = add_divs(bmap, 2 * n_out);
1921
1922         bmap = isl_basic_map_simplify(bmap);
1923         return isl_basic_map_finalize(bmap);
1924 error:
1925         isl_basic_map_free(bmap);
1926         isl_basic_map_free(bmap1);
1927         isl_basic_map_free(bmap2);
1928         return NULL;
1929 }
1930
1931 /* Given a basic map A -> f(A), construct A -> -f(A).
1932  */
1933 struct isl_basic_map *isl_basic_map_neg(struct isl_basic_map *bmap)
1934 {
1935         int i, j;
1936         unsigned off, n;
1937
1938         bmap = isl_basic_map_cow(bmap);
1939         if (!bmap)
1940                 return NULL;
1941
1942         n = isl_basic_map_dim(bmap, isl_dim_out);
1943         off = isl_basic_map_offset(bmap, isl_dim_out);
1944         for (i = 0; i < bmap->n_eq; ++i)
1945                 for (j = 0; j < n; ++j)
1946                         isl_int_neg(bmap->eq[i][off+j], bmap->eq[i][off+j]);
1947         for (i = 0; i < bmap->n_ineq; ++i)
1948                 for (j = 0; j < n; ++j)
1949                         isl_int_neg(bmap->ineq[i][off+j], bmap->ineq[i][off+j]);
1950         for (i = 0; i < bmap->n_div; ++i)
1951                 for (j = 0; j < n; ++j)
1952                         isl_int_neg(bmap->div[i][1+off+j], bmap->div[i][1+off+j]);
1953         return isl_basic_map_finalize(bmap);
1954 }
1955
1956 /* Given a basic map A -> f(A) and an integer d, construct a basic map
1957  * A -> floor(f(A)/d).
1958  */
1959 struct isl_basic_map *isl_basic_map_floordiv(struct isl_basic_map *bmap,
1960                 isl_int d)
1961 {
1962         unsigned n_in, n_out, nparam, total, pos;
1963         struct isl_basic_map *result = NULL;
1964         struct isl_dim_map *dim_map;
1965         int i;
1966
1967         if (!bmap)
1968                 return NULL;
1969
1970         nparam = isl_basic_map_n_param(bmap);
1971         n_in = isl_basic_map_n_in(bmap);
1972         n_out = isl_basic_map_n_out(bmap);
1973
1974         total = nparam + n_in + n_out + bmap->n_div + n_out;
1975         dim_map = isl_dim_map_alloc(bmap->ctx, total);
1976         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
1977         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
1978         isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
1979         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
1980
1981         result = isl_basic_map_alloc_dim(isl_dim_copy(bmap->dim),
1982                         bmap->n_div + n_out,
1983                         bmap->n_eq, bmap->n_ineq + 2 * n_out);
1984         result = add_constraints_dim_map(result, bmap, dim_map);
1985         result = add_divs(result, n_out);
1986         for (i = 0; i < n_out; ++i) {
1987                 int j;
1988                 j = isl_basic_map_alloc_inequality(result);
1989                 if (j < 0)
1990                         goto error;
1991                 isl_seq_clr(result->ineq[j], 1+total);
1992                 isl_int_neg(result->ineq[j][1+nparam+n_in+i], d);
1993                 isl_int_set_si(result->ineq[j][1+pos+i], 1);
1994                 j = isl_basic_map_alloc_inequality(result);
1995                 if (j < 0)
1996                         goto error;
1997                 isl_seq_clr(result->ineq[j], 1+total);
1998                 isl_int_set(result->ineq[j][1+nparam+n_in+i], d);
1999                 isl_int_set_si(result->ineq[j][1+pos+i], -1);
2000                 isl_int_sub_ui(result->ineq[j][0], d, 1);
2001         }
2002
2003         result = isl_basic_map_simplify(result);
2004         return isl_basic_map_finalize(result);
2005 error:
2006         isl_basic_map_free(result);
2007         return NULL;
2008 }
2009
2010 static struct isl_basic_map *var_equal(struct isl_basic_map *bmap, unsigned pos)
2011 {
2012         int i;
2013         unsigned nparam;
2014         unsigned n_in;
2015
2016         i = isl_basic_map_alloc_equality(bmap);
2017         if (i < 0)
2018                 goto error;
2019         nparam = isl_basic_map_n_param(bmap);
2020         n_in = isl_basic_map_n_in(bmap);
2021         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
2022         isl_int_set_si(bmap->eq[i][1+nparam+pos], -1);
2023         isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1);
2024         return isl_basic_map_finalize(bmap);
2025 error:
2026         isl_basic_map_free(bmap);
2027         return NULL;
2028 }
2029
2030 static struct isl_basic_map *var_more(struct isl_basic_map *bmap, unsigned pos)
2031 {
2032         int i;
2033         unsigned nparam;
2034         unsigned n_in;
2035
2036         i = isl_basic_map_alloc_inequality(bmap);
2037         if (i < 0)
2038                 goto error;
2039         nparam = isl_basic_map_n_param(bmap);
2040         n_in = isl_basic_map_n_in(bmap);
2041         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
2042         isl_int_set_si(bmap->ineq[i][0], -1);
2043         isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
2044         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
2045         return isl_basic_map_finalize(bmap);
2046 error:
2047         isl_basic_map_free(bmap);
2048         return NULL;
2049 }
2050
2051 static struct isl_basic_map *var_less(struct isl_basic_map *bmap, unsigned pos)
2052 {
2053         int i;
2054         unsigned nparam;
2055         unsigned n_in;
2056
2057         i = isl_basic_map_alloc_inequality(bmap);
2058         if (i < 0)
2059                 goto error;
2060         nparam = isl_basic_map_n_param(bmap);
2061         n_in = isl_basic_map_n_in(bmap);
2062         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
2063         isl_int_set_si(bmap->ineq[i][0], -1);
2064         isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
2065         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
2066         return isl_basic_map_finalize(bmap);
2067 error:
2068         isl_basic_map_free(bmap);
2069         return NULL;
2070 }
2071
2072 struct isl_basic_map *isl_basic_map_equal(struct isl_dim *dim, unsigned n_equal)
2073 {
2074         int i;
2075         struct isl_basic_map *bmap;
2076         bmap = isl_basic_map_alloc_dim(dim, 0, n_equal, 0);
2077         if (!bmap)
2078                 return NULL;
2079         for (i = 0; i < n_equal && bmap; ++i)
2080                 bmap = var_equal(bmap, i);
2081         return isl_basic_map_finalize(bmap);
2082 }
2083
2084 struct isl_basic_map *isl_basic_map_less_at(struct isl_dim *dim, unsigned pos)
2085 {
2086         int i;
2087         struct isl_basic_map *bmap;
2088         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
2089         if (!bmap)
2090                 return NULL;
2091         for (i = 0; i < pos && bmap; ++i)
2092                 bmap = var_equal(bmap, i);
2093         if (bmap)
2094                 bmap = var_less(bmap, pos);
2095         return isl_basic_map_finalize(bmap);
2096 }
2097
2098 struct isl_basic_map *isl_basic_map_more_at(struct isl_dim *dim, unsigned pos)
2099 {
2100         int i;
2101         struct isl_basic_map *bmap;
2102         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
2103         if (!bmap)
2104                 return NULL;
2105         for (i = 0; i < pos && bmap; ++i)
2106                 bmap = var_equal(bmap, i);
2107         if (bmap)
2108                 bmap = var_more(bmap, pos);
2109         return isl_basic_map_finalize(bmap);
2110 }
2111
2112 struct isl_basic_map *isl_basic_map_from_basic_set(
2113                 struct isl_basic_set *bset, struct isl_dim *dim)
2114 {
2115         struct isl_basic_map *bmap;
2116
2117         bset = isl_basic_set_cow(bset);
2118         if (!bset || !dim)
2119                 goto error;
2120
2121         isl_assert(bset->ctx, isl_dim_compatible(bset->dim, dim), goto error);
2122         isl_dim_free(bset->dim);
2123         bmap = (struct isl_basic_map *) bset;
2124         bmap->dim = dim;
2125         return isl_basic_map_finalize(bmap);
2126 error:
2127         isl_basic_set_free(bset);
2128         isl_dim_free(dim);
2129         return NULL;
2130 }
2131
2132 struct isl_basic_set *isl_basic_set_from_basic_map(struct isl_basic_map *bmap)
2133 {
2134         if (!bmap)
2135                 goto error;
2136         if (bmap->dim->n_in == 0)
2137                 return (struct isl_basic_set *)bmap;
2138         bmap = isl_basic_map_cow(bmap);
2139         if (!bmap)
2140                 goto error;
2141         bmap->dim = isl_dim_cow(bmap->dim);
2142         if (!bmap->dim)
2143                 goto error;
2144         bmap->dim->n_out += bmap->dim->n_in;
2145         bmap->dim->n_in = 0;
2146         bmap = isl_basic_map_finalize(bmap);
2147         return (struct isl_basic_set *)bmap;
2148 error:
2149         isl_basic_map_free(bmap);
2150         return NULL;
2151 }
2152
2153 /* For a div d = floor(f/m), add the constraints
2154  *
2155  *              f - m d >= 0
2156  *              -(f-(n-1)) + m d >= 0
2157  *
2158  * Note that the second constraint is the negation of
2159  *
2160  *              f - m d >= n
2161  */
2162 static int add_div_constraints(struct isl_basic_map *bmap, unsigned div)
2163 {
2164         int i, j;
2165         unsigned total = isl_basic_map_total_dim(bmap);
2166         unsigned div_pos = 1 + total - bmap->n_div + div;
2167
2168         i = isl_basic_map_alloc_inequality(bmap);
2169         if (i < 0)
2170                 return -1;
2171         isl_seq_cpy(bmap->ineq[i], bmap->div[div]+1, 1+total);
2172         isl_int_neg(bmap->ineq[i][div_pos], bmap->div[div][0]);
2173
2174         j = isl_basic_map_alloc_inequality(bmap);
2175         if (j < 0)
2176                 return -1;
2177         isl_seq_neg(bmap->ineq[j], bmap->ineq[i], 1 + total);
2178         isl_int_add(bmap->ineq[j][0], bmap->ineq[j][0], bmap->ineq[j][div_pos]);
2179         isl_int_sub_ui(bmap->ineq[j][0], bmap->ineq[j][0], 1);
2180         return j;
2181 }
2182
2183 struct isl_basic_set *isl_basic_map_underlying_set(
2184                 struct isl_basic_map *bmap)
2185 {
2186         if (!bmap)
2187                 goto error;
2188         if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 && bmap->n_div == 0)
2189                 return (struct isl_basic_set *)bmap;
2190         bmap = isl_basic_map_cow(bmap);
2191         if (!bmap)
2192                 goto error;
2193         bmap->dim = isl_dim_underlying(bmap->dim, bmap->n_div);
2194         if (!bmap->dim)
2195                 goto error;
2196         bmap->extra -= bmap->n_div;
2197         bmap->n_div = 0;
2198         bmap = isl_basic_map_finalize(bmap);
2199         return (struct isl_basic_set *)bmap;
2200 error:
2201         return NULL;
2202 }
2203
2204 struct isl_basic_map *isl_basic_map_overlying_set(
2205         struct isl_basic_set *bset, struct isl_basic_map *like)
2206 {
2207         struct isl_basic_map *bmap;
2208         struct isl_ctx *ctx;
2209         unsigned total;
2210         int i;
2211
2212         if (!bset || !like)
2213                 goto error;
2214         ctx = bset->ctx;
2215         isl_assert(ctx, bset->n_div == 0, goto error);
2216         isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error);
2217         isl_assert(ctx, bset->dim->n_out == isl_basic_map_total_dim(like),
2218                         goto error);
2219         if (isl_dim_equal(bset->dim, like->dim) && like->n_div == 0) {
2220                 isl_basic_map_free(like);
2221                 return (struct isl_basic_map *)bset;
2222         }
2223         bset = isl_basic_set_cow(bset);
2224         if (!bset)
2225                 goto error;
2226         total = bset->dim->n_out + bset->extra;
2227         bmap = (struct isl_basic_map *)bset;
2228         isl_dim_free(bmap->dim);
2229         bmap->dim = isl_dim_copy(like->dim);
2230         if (!bmap->dim)
2231                 goto error;
2232         bmap->n_div = like->n_div;
2233         bmap->extra += like->n_div;
2234         if (bmap->extra) {
2235                 unsigned ltotal;
2236                 ltotal = total - bmap->extra + like->extra;
2237                 if (ltotal > total)
2238                         ltotal = total;
2239                 bmap->block2 = isl_blk_extend(ctx, bmap->block2,
2240                                         bmap->extra * (1 + 1 + total));
2241                 if (isl_blk_is_error(bmap->block2))
2242                         goto error;
2243                 bmap->div = isl_realloc_array(ctx, bmap->div, isl_int *,
2244                                                 bmap->extra);
2245                 if (!bmap->div)
2246                         goto error;
2247                 for (i = 0; i < bmap->extra; ++i)
2248                         bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
2249                 for (i = 0; i < like->n_div; ++i) {
2250                         isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
2251                         isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
2252                 }
2253                 bmap = isl_basic_map_extend_constraints(bmap, 
2254                                                         0, 2 * like->n_div);
2255                 for (i = 0; i < like->n_div; ++i) {
2256                         if (isl_int_is_zero(bmap->div[i][0]))
2257                                 continue;
2258                         if (add_div_constraints(bmap, i) < 0)
2259                                 goto error;
2260                 }
2261         }
2262         isl_basic_map_free(like);
2263         bmap = isl_basic_map_simplify(bmap);
2264         bmap = isl_basic_map_finalize(bmap);
2265         return bmap;
2266 error:
2267         isl_basic_map_free(like);
2268         isl_basic_set_free(bset);
2269         return NULL;
2270 }
2271
2272 struct isl_basic_set *isl_basic_set_from_underlying_set(
2273         struct isl_basic_set *bset, struct isl_basic_set *like)
2274 {
2275         return (struct isl_basic_set *)
2276                 isl_basic_map_overlying_set(bset, (struct isl_basic_map *)like);
2277 }
2278
2279 struct isl_set *isl_set_from_underlying_set(
2280         struct isl_set *set, struct isl_basic_set *like)
2281 {
2282         int i;
2283
2284         if (!set || !like)
2285                 goto error;
2286         isl_assert(set->ctx, set->dim->n_out == isl_basic_set_total_dim(like),
2287                     goto error);
2288         if (isl_dim_equal(set->dim, like->dim) && like->n_div == 0) {
2289                 isl_basic_set_free(like);
2290                 return set;
2291         }
2292         set = isl_set_cow(set);
2293         if (!set)
2294                 goto error;
2295         for (i = 0; i < set->n; ++i) {
2296                 set->p[i] = isl_basic_set_from_underlying_set(set->p[i],
2297                                                       isl_basic_set_copy(like));
2298                 if (!set->p[i])
2299                         goto error;
2300         }
2301         isl_dim_free(set->dim);
2302         set->dim = isl_dim_copy(like->dim);
2303         if (!set->dim)
2304                 goto error;
2305         isl_basic_set_free(like);
2306         return set;
2307 error:
2308         isl_basic_set_free(like);
2309         isl_set_free(set);
2310         return NULL;
2311 }
2312
2313 struct isl_set *isl_map_underlying_set(struct isl_map *map)
2314 {
2315         int i;
2316
2317         map = isl_map_cow(map);
2318         if (!map)
2319                 return NULL;
2320         map->dim = isl_dim_cow(map->dim);
2321         if (!map->dim)
2322                 goto error;
2323
2324         for (i = 1; i < map->n; ++i)
2325                 isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,
2326                                 goto error);
2327         for (i = 0; i < map->n; ++i) {
2328                 map->p[i] = (struct isl_basic_map *)
2329                                 isl_basic_map_underlying_set(map->p[i]);
2330                 if (!map->p[i])
2331                         goto error;
2332         }
2333         if (map->n == 0)
2334                 map->dim = isl_dim_underlying(map->dim, 0);
2335         else {
2336                 isl_dim_free(map->dim);
2337                 map->dim = isl_dim_copy(map->p[0]->dim);
2338         }
2339         if (!map->dim)
2340                 goto error;
2341         return (struct isl_set *)map;
2342 error:
2343         isl_map_free(map);
2344         return NULL;
2345 }
2346
2347 struct isl_set *isl_set_to_underlying_set(struct isl_set *set)
2348 {
2349         return (struct isl_set *)isl_map_underlying_set((struct isl_map *)set);
2350 }
2351
2352 struct isl_basic_set *isl_basic_map_domain(struct isl_basic_map *bmap)
2353 {
2354         struct isl_basic_set *domain;
2355         unsigned n_out;
2356         if (!bmap)
2357                 return NULL;
2358         n_out = isl_basic_map_n_out(bmap);
2359         domain = isl_basic_set_from_basic_map(bmap);
2360         return isl_basic_set_project_out(domain, n_out, 0);
2361 }
2362
2363 struct isl_basic_set *isl_basic_map_range(struct isl_basic_map *bmap)
2364 {
2365         return isl_basic_map_domain(isl_basic_map_reverse(bmap));
2366 }
2367
2368 struct isl_set *isl_map_range(struct isl_map *map)
2369 {
2370         int i;
2371         struct isl_set *set;
2372
2373         if (!map)
2374                 goto error;
2375         map = isl_map_cow(map);
2376         if (!map)
2377                 goto error;
2378
2379         set = (struct isl_set *) map;
2380         if (set->dim->n_in != 0) {
2381                 set->dim = isl_dim_drop_inputs(set->dim, 0, set->dim->n_in);
2382                 if (!set->dim)
2383                         goto error;
2384         }
2385         for (i = 0; i < map->n; ++i) {
2386                 set->p[i] = isl_basic_map_range(map->p[i]);
2387                 if (!set->p[i])
2388                         goto error;
2389         }
2390         ISL_F_CLR(set, ISL_MAP_DISJOINT);
2391         ISL_F_CLR(set, ISL_SET_NORMALIZED);
2392         return set;
2393 error:
2394         isl_map_free(map);
2395         return NULL;
2396 }
2397
2398 struct isl_map *isl_map_from_set(struct isl_set *set, struct isl_dim *dim)
2399 {
2400         int i;
2401         struct isl_map *map = NULL;
2402
2403         set = isl_set_cow(set);
2404         if (!set || !dim)
2405                 goto error;
2406         isl_assert(set->ctx, isl_dim_compatible(set->dim, dim), goto error);
2407         map = (struct isl_map *)set;
2408         for (i = 0; i < set->n; ++i) {
2409                 map->p[i] = isl_basic_map_from_basic_set(
2410                                 set->p[i], isl_dim_copy(dim));
2411                 if (!map->p[i])
2412                         goto error;
2413         }
2414         isl_dim_free(map->dim);
2415         map->dim = dim;
2416         return map;
2417 error:
2418         isl_dim_free(dim);
2419         isl_set_free(set);
2420         return NULL;
2421 }
2422
2423 struct isl_map *isl_map_from_range(struct isl_set *set)
2424 {
2425         return (struct isl_map *)set;
2426 }
2427
2428 struct isl_set *isl_set_from_map(struct isl_map *map)
2429 {
2430         int i;
2431         struct isl_set *set = NULL;
2432
2433         if (!map)
2434                 return NULL;
2435         map = isl_map_cow(map);
2436         if (!map)
2437                 return NULL;
2438         map->dim = isl_dim_cow(map->dim);
2439         if (!map->dim)
2440                 goto error;
2441         map->dim->n_out += map->dim->n_in;
2442         map->dim->n_in = 0;
2443         set = (struct isl_set *)map;
2444         for (i = 0; i < map->n; ++i) {
2445                 set->p[i] = isl_basic_set_from_basic_map(map->p[i]);
2446                 if (!set->p[i])
2447                         goto error;
2448         }
2449         return set;
2450 error:
2451         isl_map_free(map);
2452         return NULL;
2453 }
2454
2455 struct isl_map *isl_map_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
2456 {
2457         struct isl_map *map;
2458
2459         if (!dim)
2460                 return NULL;
2461         isl_assert(dim->ctx, n >= 0, return NULL);
2462         map = isl_alloc(dim->ctx, struct isl_map,
2463                         sizeof(struct isl_map) +
2464                         n * sizeof(struct isl_basic_map *));
2465         if (!map)
2466                 goto error;
2467
2468         map->ctx = dim->ctx;
2469         isl_ctx_ref(map->ctx);
2470         map->ref = 1;
2471         map->size = n;
2472         map->n = 0;
2473         map->dim = dim;
2474         map->flags = flags;
2475         return map;
2476 error:
2477         isl_dim_free(dim);
2478         return NULL;
2479 }
2480
2481 struct isl_map *isl_map_alloc(struct isl_ctx *ctx,
2482                 unsigned nparam, unsigned in, unsigned out, int n,
2483                 unsigned flags)
2484 {
2485         struct isl_map *map;
2486         struct isl_dim *dims;
2487
2488         dims = isl_dim_alloc(ctx, nparam, in, out);
2489         if (!dims)
2490                 return NULL;
2491
2492         map = isl_map_alloc_dim(dims, n, flags);
2493         return map;
2494 }
2495
2496 struct isl_basic_map *isl_basic_map_empty(struct isl_ctx *ctx,
2497                 unsigned nparam, unsigned in, unsigned out)
2498 {
2499         struct isl_basic_map *bmap;
2500         bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, 1, 0);
2501         bmap = isl_basic_map_set_to_empty(bmap);
2502         return bmap;
2503 }
2504
2505 struct isl_basic_set *isl_basic_set_empty(struct isl_dim *dim)
2506 {
2507         struct isl_basic_set *bset;
2508         bset = isl_basic_set_alloc_dim(dim, 0, 1, 0);
2509         bset = isl_basic_set_set_to_empty(bset);
2510         return bset;
2511 }
2512
2513 struct isl_basic_map *isl_basic_map_empty_like(struct isl_basic_map *model)
2514 {
2515         struct isl_basic_map *bmap;
2516         if (!model)
2517                 return NULL;
2518         bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
2519         bmap = isl_basic_map_set_to_empty(bmap);
2520         return bmap;
2521 }
2522
2523 struct isl_basic_map *isl_basic_map_empty_like_map(struct isl_map *model)
2524 {
2525         struct isl_basic_map *bmap;
2526         if (!model)
2527                 return NULL;
2528         bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
2529         bmap = isl_basic_map_set_to_empty(bmap);
2530         return bmap;
2531 }
2532
2533 struct isl_basic_set *isl_basic_set_empty_like(struct isl_basic_set *model)
2534 {
2535         struct isl_basic_set *bset;
2536         if (!model)
2537                 return NULL;
2538         bset = isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
2539         bset = isl_basic_set_set_to_empty(bset);
2540         return bset;
2541 }
2542
2543 struct isl_basic_map *isl_basic_map_universe(struct isl_dim *dim)
2544 {
2545         struct isl_basic_map *bmap;
2546         bmap = isl_basic_map_alloc_dim(dim, 0, 0, 0);
2547         return bmap;
2548 }
2549
2550 struct isl_basic_set *isl_basic_set_universe(struct isl_dim *dim)
2551 {
2552         struct isl_basic_set *bset;
2553         bset = isl_basic_set_alloc_dim(dim, 0, 0, 0);
2554         return bset;
2555 }
2556
2557 struct isl_basic_set *isl_basic_set_universe_like(struct isl_basic_set *model)
2558 {
2559         if (!model)
2560                 return NULL;
2561         return isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 0, 0);
2562 }
2563
2564 struct isl_map *isl_map_empty(struct isl_dim *dim)
2565 {
2566         return isl_map_alloc_dim(dim, 0, ISL_MAP_DISJOINT);
2567 }
2568
2569 struct isl_map *isl_map_empty_like(struct isl_map *model)
2570 {
2571         if (!model)
2572                 return NULL;
2573         return isl_map_alloc_dim(isl_dim_copy(model->dim), 0, ISL_MAP_DISJOINT);
2574 }
2575
2576 struct isl_map *isl_map_empty_like_basic_map(struct isl_basic_map *model)
2577 {
2578         if (!model)
2579                 return NULL;
2580         return isl_map_alloc_dim(isl_dim_copy(model->dim), 0, ISL_MAP_DISJOINT);
2581 }
2582
2583 struct isl_set *isl_set_empty(struct isl_dim *dim)
2584 {
2585         return isl_set_alloc_dim(dim, 0, ISL_MAP_DISJOINT);
2586 }
2587
2588 struct isl_set *isl_set_empty_like(struct isl_set *model)
2589 {
2590         if (!model)
2591                 return NULL;
2592         return isl_set_empty(isl_dim_copy(model->dim));
2593 }
2594
2595 struct isl_set *isl_set_universe(struct isl_dim *dim)
2596 {
2597         struct isl_set *set;
2598         if (!dim)
2599                 return NULL;
2600         set = isl_set_alloc_dim(isl_dim_copy(dim), 1, ISL_MAP_DISJOINT);
2601         set = isl_set_add(set, isl_basic_set_universe(dim));
2602         return set;
2603 }
2604
2605 struct isl_map *isl_map_dup(struct isl_map *map)
2606 {
2607         int i;
2608         struct isl_map *dup;
2609
2610         if (!map)
2611                 return NULL;
2612         dup = isl_map_alloc_dim(isl_dim_copy(map->dim), map->n, map->flags);
2613         for (i = 0; i < map->n; ++i)
2614                 dup = isl_map_add(dup, isl_basic_map_copy(map->p[i]));
2615         return dup;
2616 }
2617
2618 struct isl_map *isl_map_add(struct isl_map *map, struct isl_basic_map *bmap)
2619 {
2620         if (!bmap || !map)
2621                 goto error;
2622         isl_assert(map->ctx, isl_dim_equal(map->dim, bmap->dim), goto error);
2623         isl_assert(map->ctx, map->n < map->size, goto error);
2624         map->p[map->n] = bmap;
2625         map->n++;
2626         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
2627         return map;
2628 error:
2629         if (map)
2630                 isl_map_free(map);
2631         if (bmap)
2632                 isl_basic_map_free(bmap);
2633         return NULL;
2634 }
2635
2636 void isl_map_free(struct isl_map *map)
2637 {
2638         int i;
2639
2640         if (!map)
2641                 return;
2642
2643         if (--map->ref > 0)
2644                 return;
2645
2646         isl_ctx_deref(map->ctx);
2647         for (i = 0; i < map->n; ++i)
2648                 isl_basic_map_free(map->p[i]);
2649         isl_dim_free(map->dim);
2650         free(map);
2651 }
2652
2653 struct isl_map *isl_map_extend(struct isl_map *base,
2654                 unsigned nparam, unsigned n_in, unsigned n_out)
2655 {
2656         int i;
2657
2658         base = isl_map_cow(base);
2659         if (!base)
2660                 return NULL;
2661
2662         base->dim = isl_dim_extend(base->dim, nparam, n_in, n_out);
2663         if (!base->dim)
2664                 goto error;
2665         for (i = 0; i < base->n; ++i) {
2666                 base->p[i] = isl_basic_map_extend_dim(base->p[i],
2667                                 isl_dim_copy(base->dim), 0, 0, 0);
2668                 if (!base->p[i])
2669                         goto error;
2670         }
2671         return base;
2672 error:
2673         isl_map_free(base);
2674         return NULL;
2675 }
2676
2677 struct isl_set *isl_set_extend(struct isl_set *base,
2678                 unsigned nparam, unsigned dim)
2679 {
2680         return (struct isl_set *)isl_map_extend((struct isl_map *)base,
2681                                                         nparam, 0, dim);
2682 }
2683
2684 static struct isl_basic_map *isl_basic_map_fix_pos(struct isl_basic_map *bmap,
2685                 unsigned pos, int value)
2686 {
2687         int j;
2688
2689         bmap = isl_basic_map_cow(bmap);
2690         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
2691         j = isl_basic_map_alloc_equality(bmap);
2692         if (j < 0)
2693                 goto error;
2694         isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
2695         isl_int_set_si(bmap->eq[j][pos], -1);
2696         isl_int_set_si(bmap->eq[j][0], value);
2697         bmap = isl_basic_map_simplify(bmap);
2698         return isl_basic_map_finalize(bmap);
2699 error:
2700         isl_basic_map_free(bmap);
2701         return NULL;
2702 }
2703
2704 struct isl_basic_map *isl_basic_map_fix_si(struct isl_basic_map *bmap,
2705                 enum isl_dim_type type, unsigned pos, int value)
2706 {
2707         if (!bmap)
2708                 return NULL;
2709         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
2710         return isl_basic_map_fix_pos(bmap, isl_basic_map_offset(bmap, type) + pos,
2711                                         value);
2712 error:
2713         isl_basic_map_free(bmap);
2714         return NULL;
2715 }
2716
2717 struct isl_basic_set *isl_basic_set_fix_si(struct isl_basic_set *bset,
2718                 enum isl_dim_type type, unsigned pos, int value)
2719 {
2720         return (struct isl_basic_set *)
2721                 isl_basic_map_fix_si((struct isl_basic_map *)bset,
2722                                         type, pos, value);
2723 }
2724
2725 struct isl_basic_map *isl_basic_map_fix_input_si(struct isl_basic_map *bmap,
2726                 unsigned input, int value)
2727 {
2728         return isl_basic_map_fix_si(bmap, isl_dim_in, input, value);
2729 }
2730
2731 struct isl_basic_set *isl_basic_set_fix_dim_si(struct isl_basic_set *bset,
2732                 unsigned dim, int value)
2733 {
2734         return (struct isl_basic_set *)
2735                 isl_basic_map_fix_si((struct isl_basic_map *)bset,
2736                                         isl_dim_set, dim, value);
2737 }
2738
2739 struct isl_map *isl_map_fix_si(struct isl_map *map,
2740                 enum isl_dim_type type, unsigned pos, int value)
2741 {
2742         int i;
2743
2744         map = isl_map_cow(map);
2745         if (!map)
2746                 return NULL;
2747
2748         isl_assert(ctx, pos < isl_map_dim(map, type), goto error);
2749         for (i = 0; i < map->n; ++i) {
2750                 map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
2751                 if (!map->p[i])
2752                         goto error;
2753         }
2754         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
2755         return map;
2756 error:
2757         isl_map_free(map);
2758         return NULL;
2759 }
2760
2761 struct isl_map *isl_map_fix_input_si(struct isl_map *map,
2762                 unsigned input, int value)
2763 {
2764         return isl_map_fix_si(map, isl_dim_in, input, value);
2765 }
2766
2767 struct isl_set *isl_set_fix_dim_si(struct isl_set *set, unsigned dim, int value)
2768 {
2769         return (struct isl_set *)
2770                 isl_map_fix_si((struct isl_map *)set, isl_dim_set, dim, value);
2771 }
2772
2773 struct isl_basic_set *isl_basic_set_lower_bound_dim(struct isl_basic_set *bset,
2774         unsigned dim, isl_int value)
2775 {
2776         int j;
2777         unsigned nparam;
2778
2779         bset = isl_basic_set_cow(bset);
2780         bset = isl_basic_set_extend_constraints(bset, 0, 1);
2781         j = isl_basic_set_alloc_inequality(bset);
2782         if (j < 0)
2783                 goto error;
2784         isl_seq_clr(bset->ineq[j], 1 + isl_basic_set_total_dim(bset));
2785         isl_int_set_si(bset->ineq[j][1 + isl_basic_set_n_param(bset) + dim], 1);
2786         isl_int_neg(bset->ineq[j][0], value);
2787         bset = isl_basic_set_simplify(bset);
2788         return isl_basic_set_finalize(bset);
2789 error:
2790         isl_basic_set_free(bset);
2791         return NULL;
2792 }
2793
2794 struct isl_set *isl_set_lower_bound_dim(struct isl_set *set, unsigned dim,
2795                                         isl_int value)
2796 {
2797         int i;
2798
2799         set = isl_set_cow(set);
2800         if (!set)
2801                 return NULL;
2802
2803         isl_assert(set->ctx, dim < isl_set_n_dim(set), goto error);
2804         for (i = 0; i < set->n; ++i) {
2805                 set->p[i] = isl_basic_set_lower_bound_dim(set->p[i], dim, value);
2806                 if (!set->p[i])
2807                         goto error;
2808         }
2809         return set;
2810 error:
2811         isl_set_free(set);
2812         return NULL;
2813 }
2814
2815 struct isl_map *isl_map_reverse(struct isl_map *map)
2816 {
2817         int i;
2818         unsigned t;
2819
2820         map = isl_map_cow(map);
2821         if (!map)
2822                 return NULL;
2823
2824         map->dim = isl_dim_reverse(map->dim);
2825         if (!map->dim)
2826                 goto error;
2827         for (i = 0; i < map->n; ++i) {
2828                 map->p[i] = isl_basic_map_reverse(map->p[i]);
2829                 if (!map->p[i])
2830                         goto error;
2831         }
2832         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
2833         return map;
2834 error:
2835         isl_map_free(map);
2836         return NULL;
2837 }
2838
2839 struct isl_map *isl_basic_map_lexmax(
2840                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
2841                 struct isl_set **empty)
2842 {
2843         return isl_pip_basic_map_lexmax(bmap, dom, empty);
2844 }
2845
2846 struct isl_map *isl_basic_map_lexmin(
2847                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
2848                 struct isl_set **empty)
2849 {
2850         return isl_pip_basic_map_lexmin(bmap, dom, empty);
2851 }
2852
2853 struct isl_set *isl_basic_set_lexmin(struct isl_basic_set *bset)
2854 {
2855         struct isl_basic_map *bmap = NULL;
2856         struct isl_basic_set *dom = NULL;
2857         struct isl_map *min;
2858         struct isl_dim *param_dim;
2859
2860         if (!bset)
2861                 goto error;
2862         bmap = isl_basic_map_from_basic_set(bset, isl_dim_copy(bset->dim));
2863         if (!bmap)
2864                 goto error;
2865         param_dim = isl_dim_domain(isl_dim_copy(bmap->dim));
2866         dom = isl_basic_set_universe(param_dim);
2867         if (!dom)
2868                 goto error;
2869         min = isl_basic_map_lexmin(bmap, dom, NULL);
2870         return isl_map_range(min);
2871 error:
2872         isl_basic_map_free(bmap);
2873         return NULL;
2874 }
2875
2876 struct isl_map *isl_basic_map_compute_divs(struct isl_basic_map *bmap)
2877 {
2878         int i;
2879         unsigned off;
2880
2881         if (!bmap)
2882                 return NULL;
2883         off = isl_dim_total(bmap->dim);
2884         for (i = 0; i < bmap->n_div; ++i) {
2885                 if (isl_int_is_zero(bmap->div[i][0]))
2886                         return isl_pip_basic_map_compute_divs(bmap);
2887                 isl_assert(bmap->ctx, isl_int_is_zero(bmap->div[i][1+1+off+i]),
2888                                 goto error);
2889         }
2890         return isl_map_from_basic_map(bmap);
2891 error:
2892         isl_basic_map_free(bmap);
2893         return NULL;
2894 }
2895
2896 struct isl_map *isl_map_compute_divs(struct isl_map *map)
2897 {
2898         int i;
2899         struct isl_map *res;
2900
2901         if (!map)
2902                 return NULL;
2903         if (map->n == 0)
2904                 return map;
2905         res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
2906         for (i = 1 ; i < map->n; ++i) {
2907                 struct isl_map *r2;
2908                 r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
2909                 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
2910                         res = isl_map_union_disjoint(res, r2);
2911                 else
2912                         res = isl_map_union(res, r2);
2913         }
2914         isl_map_free(map);
2915
2916         return res;
2917 }
2918
2919 struct isl_set *isl_basic_set_compute_divs(struct isl_basic_set *bset)
2920 {
2921         return (struct isl_set *)
2922                 isl_basic_map_compute_divs((struct isl_basic_map *)bset);
2923 }
2924
2925 struct isl_set *isl_set_compute_divs(struct isl_set *set)
2926 {
2927         return (struct isl_set *)
2928                 isl_map_compute_divs((struct isl_map *)set);
2929 }
2930
2931 struct isl_set *isl_map_domain(struct isl_map *map)
2932 {
2933         int i;
2934         struct isl_set *set;
2935
2936         if (!map)
2937                 goto error;
2938
2939         map = isl_map_cow(map);
2940         if (!map)
2941                 return NULL;
2942
2943         set = (struct isl_set *)map;
2944         set->dim = isl_dim_domain(set->dim);
2945         if (!set->dim)
2946                 goto error;
2947         for (i = 0; i < map->n; ++i) {
2948                 set->p[i] = isl_basic_map_domain(map->p[i]);
2949                 if (!set->p[i])
2950                         goto error;
2951         }
2952         ISL_F_CLR(set, ISL_MAP_DISJOINT);
2953         ISL_F_CLR(set, ISL_SET_NORMALIZED);
2954         return set;
2955 error:
2956         isl_map_free(map);
2957         return NULL;
2958 }
2959
2960 struct isl_map *isl_map_union_disjoint(
2961                         struct isl_map *map1, struct isl_map *map2)
2962 {
2963         int i;
2964         unsigned flags = 0;
2965         struct isl_map *map = NULL;
2966
2967         if (!map1 || !map2)
2968                 goto error;
2969
2970         if (map1->n == 0) {
2971                 isl_map_free(map1);
2972                 return map2;
2973         }
2974         if (map2->n == 0) {
2975                 isl_map_free(map2);
2976                 return map1;
2977         }
2978
2979         isl_assert(map1->ctx, isl_dim_equal(map1->dim, map2->dim), goto error);
2980
2981         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
2982             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
2983                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
2984
2985         map = isl_map_alloc_dim(isl_dim_copy(map1->dim),
2986                                 map1->n + map2->n, flags);
2987         if (!map)
2988                 goto error;
2989         for (i = 0; i < map1->n; ++i) {
2990                 map = isl_map_add(map,
2991                                   isl_basic_map_copy(map1->p[i]));
2992                 if (!map)
2993                         goto error;
2994         }
2995         for (i = 0; i < map2->n; ++i) {
2996                 map = isl_map_add(map,
2997                                   isl_basic_map_copy(map2->p[i]));
2998                 if (!map)
2999                         goto error;
3000         }
3001         isl_map_free(map1);
3002         isl_map_free(map2);
3003         return map;
3004 error:
3005         isl_map_free(map);
3006         isl_map_free(map1);
3007         isl_map_free(map2);
3008         return NULL;
3009 }
3010
3011 struct isl_map *isl_map_union(struct isl_map *map1, struct isl_map *map2)
3012 {
3013         map1 = isl_map_union_disjoint(map1, map2);
3014         if (!map1)
3015                 return NULL;
3016         if (map1->n > 1)
3017                 ISL_F_CLR(map1, ISL_MAP_DISJOINT);
3018         return map1;
3019 }
3020
3021 struct isl_set *isl_set_union_disjoint(
3022                         struct isl_set *set1, struct isl_set *set2)
3023 {
3024         return (struct isl_set *)
3025                 isl_map_union_disjoint(
3026                         (struct isl_map *)set1, (struct isl_map *)set2);
3027 }
3028
3029 struct isl_set *isl_set_union(struct isl_set *set1, struct isl_set *set2)
3030 {
3031         return (struct isl_set *)
3032                 isl_map_union((struct isl_map *)set1, (struct isl_map *)set2);
3033 }
3034
3035 struct isl_map *isl_map_intersect_range(
3036                 struct isl_map *map, struct isl_set *set)
3037 {
3038         unsigned flags = 0;
3039         struct isl_map *result;
3040         int i, j;
3041
3042         if (!map || !set)
3043                 goto error;
3044
3045         if (ISL_F_ISSET(map, ISL_MAP_DISJOINT) &&
3046             ISL_F_ISSET(set, ISL_MAP_DISJOINT))
3047                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
3048
3049         result = isl_map_alloc_dim(isl_dim_copy(map->dim),
3050                                         map->n * set->n, flags);
3051         if (!result)
3052                 goto error;
3053         for (i = 0; i < map->n; ++i)
3054                 for (j = 0; j < set->n; ++j) {
3055                         result = isl_map_add(result,
3056                             isl_basic_map_intersect_range(
3057                                 isl_basic_map_copy(map->p[i]),
3058                                 isl_basic_set_copy(set->p[j])));
3059                         if (!result)
3060                                 goto error;
3061                 }
3062         isl_map_free(map);
3063         isl_set_free(set);
3064         return result;
3065 error:
3066         isl_map_free(map);
3067         isl_set_free(set);
3068         return NULL;
3069 }
3070
3071 struct isl_map *isl_map_intersect_domain(
3072                 struct isl_map *map, struct isl_set *set)
3073 {
3074         return isl_map_reverse(
3075                 isl_map_intersect_range(isl_map_reverse(map), set));
3076 }
3077
3078 struct isl_map *isl_map_apply_domain(
3079                 struct isl_map *map1, struct isl_map *map2)
3080 {
3081         if (!map1 || !map2)
3082                 goto error;
3083         map1 = isl_map_reverse(map1);
3084         map1 = isl_map_apply_range(map1, map2);
3085         return isl_map_reverse(map1);
3086 error:
3087         isl_map_free(map1);
3088         isl_map_free(map2);
3089         return NULL;
3090 }
3091
3092 struct isl_map *isl_map_apply_range(
3093                 struct isl_map *map1, struct isl_map *map2)
3094 {
3095         struct isl_dim *dim_result;
3096         struct isl_map *result;
3097         int i, j;
3098         unsigned nparam;
3099         unsigned n_in;
3100         unsigned n_out;
3101
3102         if (!map1 || !map2)
3103                 goto error;
3104
3105         dim_result = isl_dim_join(isl_dim_copy(map1->dim),
3106                                   isl_dim_copy(map2->dim));
3107
3108         result = isl_map_alloc_dim(dim_result, map1->n * map2->n, 0);
3109         if (!result)
3110                 goto error;
3111         for (i = 0; i < map1->n; ++i)
3112                 for (j = 0; j < map2->n; ++j) {
3113                         result = isl_map_add(result,
3114                             isl_basic_map_apply_range(
3115                                 isl_basic_map_copy(map1->p[i]),
3116                                 isl_basic_map_copy(map2->p[j])));
3117                         if (!result)
3118                                 goto error;
3119                 }
3120         isl_map_free(map1);
3121         isl_map_free(map2);
3122         if (result && result->n <= 1)
3123                 ISL_F_SET(result, ISL_MAP_DISJOINT);
3124         return result;
3125 error:
3126         isl_map_free(map1);
3127         isl_map_free(map2);
3128         return NULL;
3129 }
3130
3131 /*
3132  * returns range - domain
3133  */
3134 struct isl_basic_set *isl_basic_map_deltas(struct isl_basic_map *bmap)
3135 {
3136         struct isl_basic_set *bset;
3137         unsigned dim;
3138         unsigned nparam;
3139         int i;
3140
3141         if (!bmap)
3142                 goto error;
3143         dim = isl_basic_map_n_in(bmap);
3144         nparam = isl_basic_map_n_param(bmap);
3145         isl_assert(bmap->ctx, dim == isl_basic_map_n_out(bmap), goto error);
3146         bset = isl_basic_set_from_basic_map(bmap);
3147         bset = isl_basic_set_extend(bset, nparam, 3*dim, 0, dim, 0);
3148         bset = isl_basic_set_swap_vars(bset, 2*dim);
3149         for (i = 0; i < dim; ++i) {
3150                 int j = isl_basic_map_alloc_equality(
3151                                             (struct isl_basic_map *)bset);
3152                 if (j < 0)
3153                         goto error;
3154                 isl_seq_clr(bset->eq[j], 1 + isl_basic_set_total_dim(bset));
3155                 isl_int_set_si(bset->eq[j][1+nparam+i], 1);
3156                 isl_int_set_si(bset->eq[j][1+nparam+dim+i], 1);
3157                 isl_int_set_si(bset->eq[j][1+nparam+2*dim+i], -1);
3158         }
3159         return isl_basic_set_project_out(bset, 2*dim, 0);
3160 error:
3161         isl_basic_map_free(bmap);
3162         return NULL;
3163 }
3164
3165 /*
3166  * returns range - domain
3167  */
3168 struct isl_set *isl_map_deltas(struct isl_map *map)
3169 {
3170         int i;
3171         struct isl_set *result;
3172
3173         if (!map)
3174                 return NULL;
3175
3176         isl_assert(map->ctx, isl_map_n_in(map) == isl_map_n_out(map), goto error);
3177         result = isl_set_alloc(map->ctx, isl_map_n_param(map),
3178                                         isl_map_n_in(map), map->n, map->flags);
3179         if (!result)
3180                 goto error;
3181         for (i = 0; i < map->n; ++i)
3182                 result = isl_set_add(result,
3183                           isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
3184         isl_map_free(map);
3185         return result;
3186 error:
3187         isl_map_free(map);
3188         return NULL;
3189 }
3190
3191 static struct isl_basic_map *basic_map_identity(struct isl_dim *dims)
3192 {
3193         struct isl_basic_map *bmap;
3194         unsigned nparam;
3195         unsigned dim;
3196         int i;
3197
3198         if (!dims)
3199                 return NULL;
3200
3201         nparam = dims->nparam;
3202         dim = dims->n_out;
3203         bmap = isl_basic_map_alloc_dim(dims, 0, dim, 0);
3204         if (!bmap)
3205                 goto error;
3206
3207         for (i = 0; i < dim; ++i) {
3208                 int j = isl_basic_map_alloc_equality(bmap);
3209                 if (j < 0)
3210                         goto error;
3211                 isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
3212                 isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
3213                 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], -1);
3214         }
3215         return isl_basic_map_finalize(bmap);
3216 error:
3217         isl_basic_map_free(bmap);
3218         return NULL;
3219 }
3220
3221 struct isl_basic_map *isl_basic_map_identity(struct isl_dim *set_dim)
3222 {
3223         struct isl_dim *dim = isl_dim_map(set_dim);
3224         if (!dim)
3225                 return NULL;
3226         return basic_map_identity(dim);
3227 }
3228
3229 struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model)
3230 {
3231         if (!model || !model->dim)
3232                 return NULL;
3233         isl_assert(model->ctx,
3234                         model->dim->n_in == model->dim->n_out, return NULL);
3235         return basic_map_identity(isl_dim_copy(model->dim));
3236 }
3237
3238 static struct isl_map *map_identity(struct isl_dim *dim)
3239 {
3240         struct isl_map *map = isl_map_alloc_dim(dim, 1, ISL_MAP_DISJOINT);
3241         return isl_map_add(map, basic_map_identity(isl_dim_copy(dim)));
3242 }
3243
3244 struct isl_map *isl_map_identity(struct isl_dim *set_dim)
3245 {
3246         struct isl_dim *dim = isl_dim_map(set_dim);
3247         if (!dim)
3248                 return NULL;
3249         return map_identity(dim);
3250 }
3251
3252 struct isl_map *isl_map_identity_like(struct isl_basic_map *model)
3253 {
3254         if (!model || !model->dim)
3255                 return NULL;
3256         isl_assert(model->ctx,
3257                         model->dim->n_in == model->dim->n_out, return NULL);
3258         return map_identity(isl_dim_copy(model->dim));
3259 }
3260
3261 int isl_set_is_equal(struct isl_set *set1, struct isl_set *set2)
3262 {
3263         return isl_map_is_equal((struct isl_map *)set1, (struct isl_map *)set2);
3264 }
3265
3266 int isl_set_is_subset(struct isl_set *set1, struct isl_set *set2)
3267 {
3268         return isl_map_is_subset(
3269                         (struct isl_map *)set1, (struct isl_map *)set2);
3270 }
3271
3272 int isl_basic_map_is_subset(
3273                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
3274 {
3275         int is_subset;
3276         struct isl_map *map1;
3277         struct isl_map *map2;
3278
3279         if (!bmap1 || !bmap2)
3280                 return -1;
3281
3282         map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
3283         map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
3284
3285         is_subset = isl_map_is_subset(map1, map2);
3286
3287         isl_map_free(map1);
3288         isl_map_free(map2);
3289
3290         return is_subset;
3291 }
3292
3293 int isl_basic_map_is_equal(
3294                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
3295 {
3296         int is_subset;
3297
3298         if (!bmap1 || !bmap2)
3299                 return -1;
3300         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
3301         if (is_subset != 1)
3302                 return is_subset;
3303         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
3304         return is_subset;
3305 }
3306
3307 int isl_basic_set_is_equal(
3308                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
3309 {
3310         return isl_basic_map_is_equal(
3311                 (struct isl_basic_map *)bset1, (struct isl_basic_map *)bset2);
3312 }
3313
3314 int isl_map_is_empty(struct isl_map *map)
3315 {
3316         int i;
3317         int is_empty;
3318
3319         if (!map)
3320                 return -1;
3321         for (i = 0; i < map->n; ++i) {
3322                 is_empty = isl_basic_map_is_empty(map->p[i]);
3323                 if (is_empty < 0)
3324                         return -1;
3325                 if (!is_empty)
3326                         return 0;
3327         }
3328         return 1;
3329 }
3330
3331 int isl_map_fast_is_empty(struct isl_map *map)
3332 {
3333         return map->n == 0;
3334 }
3335
3336 int isl_set_is_empty(struct isl_set *set)
3337 {
3338         return isl_map_is_empty((struct isl_map *)set);
3339 }
3340
3341 int isl_map_is_subset(struct isl_map *map1, struct isl_map *map2)
3342 {
3343         int i;
3344         int is_subset = 0;
3345         struct isl_map *diff;
3346
3347         if (!map1 || !map2)
3348                 return -1;
3349
3350         if (isl_map_is_empty(map1))
3351                 return 1;
3352
3353         if (isl_map_is_empty(map2))
3354                 return 0;
3355
3356         diff = isl_map_subtract(isl_map_copy(map1), isl_map_copy(map2));
3357         if (!diff)
3358                 return -1;
3359
3360         is_subset = isl_map_is_empty(diff);
3361         isl_map_free(diff);
3362
3363         return is_subset;
3364 }
3365
3366 int isl_map_is_equal(struct isl_map *map1, struct isl_map *map2)
3367 {
3368         int is_subset;
3369
3370         if (!map1 || !map2)
3371                 return -1;
3372         is_subset = isl_map_is_subset(map1, map2);
3373         if (is_subset != 1)
3374                 return is_subset;
3375         is_subset = isl_map_is_subset(map2, map1);
3376         return is_subset;
3377 }
3378
3379 int isl_basic_map_is_strict_subset(
3380                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
3381 {
3382         int is_subset;
3383
3384         if (!bmap1 || !bmap2)
3385                 return -1;
3386         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
3387         if (is_subset != 1)
3388                 return is_subset;
3389         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
3390         if (is_subset == -1)
3391                 return is_subset;
3392         return !is_subset;
3393 }
3394
3395 int isl_basic_map_is_universe(struct isl_basic_map *bmap)
3396 {
3397         if (!bmap)
3398                 return -1;
3399         return bmap->n_eq == 0 && bmap->n_ineq == 0;
3400 }
3401
3402 int isl_basic_map_is_empty(struct isl_basic_map *bmap)
3403 {
3404         struct isl_basic_set *bset = NULL;
3405         struct isl_vec *sample = NULL;
3406         int empty;
3407         unsigned total;
3408
3409         if (!bmap)
3410                 return -1;
3411
3412         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
3413                 return 1;
3414
3415         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
3416                 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
3417                 copy = isl_basic_map_convex_hull(copy);
3418                 empty = ISL_F_ISSET(copy, ISL_BASIC_MAP_EMPTY);
3419                 isl_basic_map_free(copy);
3420                 return empty;
3421         }
3422
3423         total = 1 + isl_basic_map_total_dim(bmap);
3424         if (bmap->sample && bmap->sample->size == total) {
3425                 int contains = basic_map_contains(bmap, bmap->sample);
3426                 if (contains < 0)
3427                         return -1;
3428                 if (contains)
3429                         return 0;
3430         }
3431         bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
3432         if (!bset)
3433                 return -1;
3434         sample = isl_basic_set_sample(bset);
3435         if (!sample)
3436                 return -1;
3437         empty = sample->size == 0;
3438         if (bmap->sample)
3439                 isl_vec_free(bmap->ctx, bmap->sample);
3440         bmap->sample = sample;
3441
3442         return empty;
3443 }
3444
3445 int isl_basic_set_is_empty(struct isl_basic_set *bset)
3446 {
3447         return isl_basic_map_is_empty((struct isl_basic_map *)bset);
3448 }
3449
3450 struct isl_map *isl_basic_map_union(
3451         struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
3452 {
3453         struct isl_map *map;
3454         if (!bmap1 || !bmap2)
3455                 return NULL;
3456
3457         isl_assert(map1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim), goto error);
3458
3459         map = isl_map_alloc_dim(isl_dim_copy(bmap1->dim), 2, 0);
3460         if (!map)
3461                 goto error;
3462         map = isl_map_add(map, bmap1);
3463         map = isl_map_add(map, bmap2);
3464         return map;
3465 error:
3466         isl_basic_map_free(bmap1);
3467         isl_basic_map_free(bmap2);
3468         return NULL;
3469 }
3470
3471 struct isl_set *isl_basic_set_union(
3472                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
3473 {
3474         return (struct isl_set *)isl_basic_map_union(
3475                                             (struct isl_basic_map *)bset1,
3476                                             (struct isl_basic_map *)bset2);
3477 }
3478
3479 /* Order divs such that any div only depends on previous divs */
3480 static struct isl_basic_map *order_divs(struct isl_basic_map *bmap)
3481 {
3482         int i;
3483         unsigned off = isl_dim_total(bmap->dim);
3484
3485         for (i = 0; i < bmap->n_div; ++i) {
3486                 int pos;
3487                 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
3488                                                             bmap->n_div-i);
3489                 if (pos == -1)
3490                         continue;
3491                 swap_div(bmap, i, pos);
3492                 --i;
3493         }
3494         return bmap;
3495 }
3496
3497 /* Look for a div in dst that corresponds to the div "div" in src.
3498  * The divs before "div" in src and dst are assumed to be the same.
3499  * 
3500  * Returns -1 if no corresponding div was found and the position
3501  * of the corresponding div in dst otherwise.
3502  */
3503 static int find_div(struct isl_basic_map *dst,
3504                         struct isl_basic_map *src, unsigned div)
3505 {
3506         int i;
3507
3508         unsigned total = isl_dim_total(src->dim);
3509
3510         isl_assert(dst->ctx, div <= dst->n_div, return -1);
3511         for (i = div; i < dst->n_div; ++i)
3512                 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total+div) &&
3513                     isl_seq_first_non_zero(dst->div[i]+1+1+total+div,
3514                                                 dst->n_div - div) == -1)
3515                         return i;
3516         return -1;
3517 }
3518
3519 struct isl_basic_map *isl_basic_map_align_divs(
3520                 struct isl_basic_map *dst, struct isl_basic_map *src)
3521 {
3522         int i;
3523         unsigned total = isl_dim_total(src->dim);
3524
3525         if (!dst || !src)
3526                 goto error;
3527
3528         if (src->n_div == 0)
3529                 return dst;
3530
3531         for (i = 0; i < src->n_div; ++i)
3532                 isl_assert(src->ctx, !isl_int_is_zero(src->div[i][0]), goto error);
3533
3534         src = order_divs(src);
3535         dst = isl_basic_map_extend_dim(dst, isl_dim_copy(dst->dim),
3536                         src->n_div, 0, 2 * src->n_div);
3537         if (!dst)
3538                 return NULL;
3539         for (i = 0; i < src->n_div; ++i) {
3540                 int j = find_div(dst, src, i);
3541                 if (j < 0) {
3542                         j = isl_basic_map_alloc_div(dst);
3543                         if (j < 0)
3544                                 goto error;
3545                         isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i);
3546                         isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i);
3547                         if (add_div_constraints(dst, j) < 0)
3548                                 goto error;
3549                 }
3550                 if (j != i)
3551                         swap_div(dst, i, j);
3552         }
3553         return dst;
3554 error:
3555         isl_basic_map_free(dst);
3556         return NULL;
3557 }
3558
3559 struct isl_basic_set *isl_basic_set_align_divs(
3560                 struct isl_basic_set *dst, struct isl_basic_set *src)
3561 {
3562         return (struct isl_basic_set *)isl_basic_map_align_divs(
3563                 (struct isl_basic_map *)dst, (struct isl_basic_map *)src);
3564 }
3565
3566 struct isl_map *isl_map_align_divs(struct isl_map *map)
3567 {
3568         int i;
3569
3570         map = isl_map_compute_divs(map);
3571         map = isl_map_cow(map);
3572         if (!map)
3573                 return NULL;
3574
3575         for (i = 1; i < map->n; ++i)
3576                 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
3577         for (i = 1; i < map->n; ++i)
3578                 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
3579
3580         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
3581         return map;
3582 }
3583
3584 static struct isl_map *add_cut_constraint(struct isl_map *dst,
3585                 struct isl_basic_map *src, isl_int *c,
3586                 unsigned len, int oppose)
3587 {
3588         struct isl_basic_map *copy = NULL;
3589         int is_empty;
3590         int k;
3591         unsigned total;
3592
3593         copy = isl_basic_map_copy(src);
3594         copy = isl_basic_map_cow(copy);
3595         if (!copy)
3596                 goto error;
3597         copy = isl_basic_map_extend_constraints(copy, 0, 1);
3598         k = isl_basic_map_alloc_inequality(copy);
3599         if (k < 0)
3600                 goto error;
3601         if (oppose)
3602                 isl_seq_neg(copy->ineq[k], c, len);
3603         else
3604                 isl_seq_cpy(copy->ineq[k], c, len);
3605         total = 1 + isl_basic_map_total_dim(copy);
3606         isl_seq_clr(copy->ineq[k]+len, total - len);
3607         isl_inequality_negate(copy, k);
3608         copy = isl_basic_map_simplify(copy);
3609         copy = isl_basic_map_finalize(copy);
3610         is_empty = isl_basic_map_is_empty(copy);
3611         if (is_empty < 0)
3612                 goto error;
3613         if (!is_empty)
3614                 dst = isl_map_add(dst, copy);
3615         else
3616                 isl_basic_map_free(copy);
3617         return dst;
3618 error:
3619         isl_basic_map_free(copy);
3620         isl_map_free(dst);
3621         return NULL;
3622 }
3623
3624 static struct isl_map *subtract(struct isl_map *map, struct isl_basic_map *bmap)
3625 {
3626         int i, j, k;
3627         unsigned flags = 0;
3628         struct isl_map *rest = NULL;
3629         unsigned max;
3630         unsigned total = isl_basic_map_total_dim(bmap);
3631
3632         assert(bmap);
3633
3634         if (!map)
3635                 goto error;
3636
3637         if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
3638                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
3639
3640         max = map->n * (2 * bmap->n_eq + bmap->n_ineq);
3641         rest = isl_map_alloc_dim(isl_dim_copy(map->dim), max, flags);
3642         if (!rest)
3643                 goto error;
3644
3645         for (i = 0; i < map->n; ++i) {
3646                 map->p[i] = isl_basic_map_align_divs(map->p[i], bmap);
3647                 if (!map->p[i])
3648                         goto error;
3649         }
3650
3651         for (j = 0; j < map->n; ++j)
3652                 map->p[j] = isl_basic_map_cow(map->p[j]);
3653
3654         for (i = 0; i < bmap->n_eq; ++i) {
3655                 for (j = 0; j < map->n; ++j) {
3656                         rest = add_cut_constraint(rest,
3657                                 map->p[j], bmap->eq[i], 1+total, 0);
3658                         if (!rest)
3659                                 goto error;
3660
3661                         rest = add_cut_constraint(rest,
3662                                 map->p[j], bmap->eq[i], 1+total, 1);
3663                         if (!rest)
3664                                 goto error;
3665
3666                         map->p[j] = isl_basic_map_extend_constraints(map->p[j],
3667                                 1, 0);
3668                         if (!map->p[j])
3669                                 goto error;
3670                         k = isl_basic_map_alloc_equality(map->p[j]);
3671                         if (k < 0)
3672                                 goto error;
3673                         isl_seq_cpy(map->p[j]->eq[k], bmap->eq[i], 1+total);
3674                         isl_seq_clr(map->p[j]->eq[k]+1+total,
3675                                         map->p[j]->n_div - bmap->n_div);
3676                 }
3677         }
3678
3679         for (i = 0; i < bmap->n_ineq; ++i) {
3680                 for (j = 0; j < map->n; ++j) {
3681                         rest = add_cut_constraint(rest,
3682                                 map->p[j], bmap->ineq[i], 1+total, 0);
3683                         if (!rest)
3684                                 goto error;
3685
3686                         map->p[j] = isl_basic_map_extend_constraints(map->p[j],
3687                                 0, 1);
3688                         if (!map->p[j])
3689                                 goto error;
3690                         k = isl_basic_map_alloc_inequality(map->p[j]);
3691                         if (k < 0)
3692                                 goto error;
3693                         isl_seq_cpy(map->p[j]->ineq[k], bmap->ineq[i], 1+total);
3694                         isl_seq_clr(map->p[j]->ineq[k]+1+total,
3695                                         map->p[j]->n_div - bmap->n_div);
3696                 }
3697         }
3698
3699         isl_map_free(map);
3700         return rest;
3701 error:
3702         isl_map_free(map);
3703         isl_map_free(rest);
3704         return NULL;
3705 }
3706
3707 struct isl_map *isl_map_subtract(struct isl_map *map1, struct isl_map *map2)
3708 {
3709         int i;
3710         if (!map1 || !map2)
3711                 goto error;
3712
3713         isl_assert(map1->ctx, isl_dim_equal(map1->dim, map2->dim), goto error);
3714
3715         if (isl_map_is_empty(map2)) {
3716                 isl_map_free(map2);
3717                 return map1;
3718         }
3719
3720         map1 = isl_map_compute_divs(map1);
3721         map2 = isl_map_compute_divs(map2);
3722         if (!map1 || !map2)
3723                 goto error;
3724
3725         for (i = 0; map1 && i < map2->n; ++i)
3726                 map1 = subtract(map1, map2->p[i]);
3727
3728         isl_map_free(map2);
3729         return map1;
3730 error:
3731         isl_map_free(map1);
3732         isl_map_free(map2);
3733         return NULL;
3734 }
3735
3736 struct isl_set *isl_set_subtract(struct isl_set *set1, struct isl_set *set2)
3737 {
3738         return (struct isl_set *)
3739                 isl_map_subtract(
3740                         (struct isl_map *)set1, (struct isl_map *)set2);
3741 }
3742
3743 struct isl_set *isl_set_apply(struct isl_set *set, struct isl_map *map)
3744 {
3745         if (!set || !map)
3746                 goto error;
3747         isl_assert(set->ctx, isl_map_compatible_domain(map, set), goto error);
3748         map = isl_map_intersect_domain(map, set);
3749         set = isl_map_range(map);
3750         return set;
3751 error:
3752         isl_set_free(set);
3753         isl_map_free(map);
3754         return NULL;
3755 }
3756
3757 /* There is no need to cow as removing empty parts doesn't change
3758  * the meaning of the set.
3759  */
3760 struct isl_map *isl_map_remove_empty_parts(struct isl_map *map)
3761 {
3762         int i;
3763
3764         if (!map)
3765                 return NULL;
3766
3767         for (i = map->n-1; i >= 0; --i) {
3768                 if (!ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_EMPTY))
3769                         continue;
3770                 isl_basic_map_free(map->p[i]);
3771                 if (i != map->n-1) {
3772                         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
3773                         map->p[i] = map->p[map->n-1];
3774                 }
3775                 map->n--;
3776         }
3777
3778         return map;
3779 }
3780
3781 struct isl_set *isl_set_remove_empty_parts(struct isl_set *set)
3782 {
3783         return (struct isl_set *)
3784                 isl_map_remove_empty_parts((struct isl_map *)set);
3785 }
3786
3787 struct isl_basic_map *isl_map_copy_basic_map(struct isl_map *map)
3788 {
3789         struct isl_basic_map *bmap;
3790         if (!map || map->n == 0)
3791                 return NULL;
3792         bmap = map->p[map->n-1];
3793         isl_assert(map->ctx, ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL), return NULL);
3794         return isl_basic_map_copy(bmap);
3795 }
3796
3797 struct isl_basic_set *isl_set_copy_basic_set(struct isl_set *set)
3798 {
3799         (struct isl_basic_set *)isl_map_copy_basic_map((struct isl_map *)set);
3800 }
3801
3802 struct isl_map *isl_map_drop_basic_map(struct isl_map *map,
3803                                                 struct isl_basic_map *bmap)
3804 {
3805         int i;
3806
3807         if (!map || !bmap)
3808                 goto error;
3809         for (i = map->n-1; i >= 0; --i) {
3810                 if (map->p[i] != bmap)
3811                         continue;
3812                 map = isl_map_cow(map);
3813                 if (!map)
3814                         goto error;
3815                 isl_basic_map_free(map->p[i]);
3816                 if (i != map->n-1) {
3817                         ISL_F_CLR(map, ISL_SET_NORMALIZED);
3818                         map->p[i] = map->p[map->n-1];
3819                 }
3820                 map->n--;
3821                 return map;
3822         }
3823         isl_basic_map_free(bmap);
3824         return map;
3825 error:
3826         isl_map_free(map);
3827         isl_basic_map_free(bmap);
3828         return NULL;
3829 }
3830
3831 struct isl_set *isl_set_drop_basic_set(struct isl_set *set,
3832                                                 struct isl_basic_set *bset)
3833 {
3834         (struct isl_set *)isl_map_drop_basic_map((struct isl_map *)set,
3835                                                 (struct isl_basic_map *)bset);
3836 }
3837
3838 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
3839  * for any common value of the parameters and dimensions preceding dim
3840  * in both basic sets, the values of dimension pos in bset1 are
3841  * smaller or larger than those in bset2.
3842  *
3843  * Returns
3844  *       1 if bset1 follows bset2
3845  *      -1 if bset1 precedes bset2
3846  *       0 if bset1 and bset2 are incomparable
3847  *      -2 if some error occurred.
3848  */
3849 int isl_basic_set_compare_at(struct isl_basic_set *bset1,
3850         struct isl_basic_set *bset2, int pos)
3851 {
3852         struct isl_dim *dims;
3853         struct isl_basic_map *bmap1 = NULL;
3854         struct isl_basic_map *bmap2 = NULL;
3855         struct isl_ctx *ctx;
3856         struct isl_vec *obj;
3857         unsigned total;
3858         unsigned nparam;
3859         unsigned dim1, dim2;
3860         isl_int num, den;
3861         enum isl_lp_result res;
3862         int cmp;
3863
3864         if (!bset1 || !bset2)
3865                 return -2;
3866
3867         nparam = isl_basic_set_n_param(bset1);
3868         dim1 = isl_basic_set_n_dim(bset1);
3869         dim2 = isl_basic_set_n_dim(bset2);
3870         dims = isl_dim_alloc(bset1->ctx, nparam, pos, dim1 - pos);
3871         bmap1 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset1), dims);
3872         dims = isl_dim_alloc(bset2->ctx, nparam, pos, dim2 - pos);
3873         bmap2 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset2), dims);
3874         if (!bmap1 || !bmap2)
3875                 goto error;
3876         bmap1 = isl_basic_map_extend(bmap1, nparam,
3877                         pos, (dim1 - pos) + (dim2 - pos),
3878                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
3879         bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos);
3880         if (!bmap1)
3881                 goto error;
3882         total = isl_basic_map_total_dim(bmap1);
3883         ctx = bmap1->ctx;
3884         obj = isl_vec_alloc(ctx, total);
3885         isl_seq_clr(obj->block.data, total);
3886         isl_int_set_si(obj->block.data[nparam+pos], 1);
3887         isl_int_set_si(obj->block.data[nparam+pos+(dim1-pos)], -1);
3888         if (!obj)
3889                 goto error;
3890         isl_int_init(num);
3891         isl_int_init(den);
3892         res = isl_solve_lp(bmap1, 0, obj->block.data, ctx->one, &num, &den);
3893         if (res == isl_lp_empty)
3894                 cmp = 0;
3895         else if (res == isl_lp_ok && isl_int_is_pos(num))
3896                 cmp = 1;
3897         else if ((res == isl_lp_ok && isl_int_is_neg(num)) ||
3898                   res == isl_lp_unbounded)
3899                 cmp = -1;
3900         else
3901                 cmp = -2;
3902         isl_int_clear(num);
3903         isl_int_clear(den);
3904         isl_basic_map_free(bmap1);
3905         isl_vec_free(ctx, obj);
3906         return cmp;
3907 error:
3908         isl_basic_map_free(bmap1);
3909         isl_basic_map_free(bmap2);
3910         return -2;
3911 }
3912
3913 static int isl_basic_map_fast_has_fixed_var(struct isl_basic_map *bmap,
3914         unsigned pos, isl_int *val)
3915 {
3916         int i;
3917         int d;
3918         unsigned total;
3919
3920         if (!bmap)
3921                 return -1;
3922         total = isl_basic_map_total_dim(bmap);
3923         for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
3924                 for (; d+1 > pos; --d)
3925                         if (!isl_int_is_zero(bmap->eq[i][1+d]))
3926                                 break;
3927                 if (d != pos)
3928                         continue;
3929                 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
3930                         return 0;
3931                 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
3932                         return 0;
3933                 if (!isl_int_is_one(bmap->eq[i][1+d]))
3934                         return 0;
3935                 if (val)
3936                         isl_int_neg(*val, bmap->eq[i][0]);
3937                 return 1;
3938         }
3939         return 0;
3940 }
3941
3942 static int isl_map_fast_has_fixed_var(struct isl_map *map,
3943         unsigned pos, isl_int *val)
3944 {
3945         int i;
3946         isl_int v;
3947         isl_int tmp;
3948         int fixed;
3949
3950         if (!map)
3951                 return -1;
3952         if (map->n == 0)
3953                 return 0;
3954         if (map->n == 1)
3955                 return isl_basic_map_fast_has_fixed_var(map->p[0], pos, val); 
3956         isl_int_init(v);
3957         isl_int_init(tmp);
3958         fixed = isl_basic_map_fast_has_fixed_var(map->p[0], pos, &v); 
3959         for (i = 1; fixed == 1 && i < map->n; ++i) {
3960                 fixed = isl_basic_map_fast_has_fixed_var(map->p[i], pos, &tmp); 
3961                 if (fixed == 1 && isl_int_ne(tmp, v))
3962                         fixed = 0;
3963         }
3964         if (val)
3965                 isl_int_set(*val, v);
3966         isl_int_clear(tmp);
3967         isl_int_clear(v);
3968         return fixed;
3969 }
3970
3971 static int isl_set_fast_has_fixed_var(struct isl_set *set, unsigned pos,
3972         isl_int *val)
3973 {
3974         return isl_map_fast_has_fixed_var((struct isl_map *)set, pos, val);
3975 }
3976
3977 int isl_basic_map_fast_is_fixed(struct isl_basic_map *bmap,
3978         enum isl_dim_type type, unsigned pos, isl_int *val)
3979 {
3980         if (pos >= isl_basic_map_dim(bmap, type))
3981                 return -1;
3982         return isl_basic_map_fast_has_fixed_var(bmap,
3983                 isl_basic_map_offset(bmap, type) - 1 + pos, val);
3984 }
3985
3986 /* Check if dimension dim has fixed value and if so and if val is not NULL,
3987  * then return this fixed value in *val.
3988  */
3989 int isl_set_fast_dim_is_fixed(struct isl_set *set, unsigned dim, isl_int *val)
3990 {
3991         return isl_set_fast_has_fixed_var(set, isl_set_n_param(set) + dim, val);
3992 }
3993
3994 /* Check if input variable in has fixed value and if so and if val is not NULL,
3995  * then return this fixed value in *val.
3996  */
3997 int isl_map_fast_input_is_fixed(struct isl_map *map, unsigned in, isl_int *val)
3998 {
3999         return isl_map_fast_has_fixed_var(map, isl_map_n_param(map) + in, val);
4000 }
4001
4002 /* Check if dimension dim has an (obvious) fixed lower bound and if so
4003  * and if val is not NULL, then return this lower bound in *val.
4004  */
4005 int isl_basic_set_fast_dim_has_fixed_lower_bound(struct isl_basic_set *bset,
4006         unsigned dim, isl_int *val)
4007 {
4008         int i, i_eq = -1, i_ineq = -1;
4009         isl_int *c;
4010         unsigned total;
4011         unsigned nparam;
4012
4013         if (!bset)
4014                 return -1;
4015         total = isl_basic_set_total_dim(bset);
4016         nparam = isl_basic_set_n_param(bset);
4017         for (i = 0; i < bset->n_eq; ++i) {
4018                 if (isl_int_is_zero(bset->eq[i][1+nparam+dim]))
4019                         continue;
4020                 if (i_eq != -1)
4021                         return 0;
4022                 i_eq = i;
4023         }
4024         for (i = 0; i < bset->n_ineq; ++i) {
4025                 if (!isl_int_is_pos(bset->ineq[i][1+nparam+dim]))
4026                         continue;
4027                 if (i_eq != -1 || i_ineq != -1)
4028                         return 0;
4029                 i_ineq = i;
4030         }
4031         if (i_eq == -1 && i_ineq == -1)
4032                 return 0;
4033         c = i_eq != -1 ? bset->eq[i_eq] : bset->ineq[i_ineq];
4034         /* The coefficient should always be one due to normalization. */
4035         if (!isl_int_is_one(c[1+nparam+dim]))
4036                 return 0;
4037         if (isl_seq_first_non_zero(c+1, nparam+dim) != -1)
4038                 return 0;
4039         if (isl_seq_first_non_zero(c+1+nparam+dim+1,
4040                                         total - nparam - dim - 1) != -1)
4041                 return 0;
4042         if (val)
4043                 isl_int_neg(*val, c[0]);
4044         return 1;
4045 }
4046
4047 int isl_set_fast_dim_has_fixed_lower_bound(struct isl_set *set,
4048         unsigned dim, isl_int *val)
4049 {
4050         int i;
4051         isl_int v;
4052         isl_int tmp;
4053         int fixed;
4054
4055         if (!set)
4056                 return -1;
4057         if (set->n == 0)
4058                 return 0;
4059         if (set->n == 1)
4060                 return isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
4061                                                                 dim, val);
4062         isl_int_init(v);
4063         isl_int_init(tmp);
4064         fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
4065                                                                 dim, &v);
4066         for (i = 1; fixed == 1 && i < set->n; ++i) {
4067                 fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[i],
4068                                                                 dim, &tmp);
4069                 if (fixed == 1 && isl_int_ne(tmp, v))
4070                         fixed = 0;
4071         }
4072         if (val)
4073                 isl_int_set(*val, v);
4074         isl_int_clear(tmp);
4075         isl_int_clear(v);
4076         return fixed;
4077 }
4078
4079 struct constraint {
4080         unsigned        size;
4081         isl_int         *c;
4082 };
4083
4084 static int qsort_constraint_cmp(const void *p1, const void *p2)
4085 {
4086         const struct constraint *c1 = (const struct constraint *)p1;
4087         const struct constraint *c2 = (const struct constraint *)p2;
4088         unsigned size = isl_min(c1->size, c2->size);
4089         return isl_seq_cmp(c1->c, c2->c, size);
4090 }
4091
4092 static struct isl_basic_map *isl_basic_map_sort_constraints(
4093         struct isl_basic_map *bmap)
4094 {
4095         int i;
4096         struct constraint *c;
4097         unsigned total;
4098
4099         if (!bmap)
4100                 return NULL;
4101         total = isl_basic_map_total_dim(bmap);
4102         c = isl_alloc_array(bmap->ctx, struct constraint, bmap->n_ineq);
4103         if (!c)
4104                 goto error;
4105         for (i = 0; i < bmap->n_ineq; ++i) {
4106                 c[i].size = total;
4107                 c[i].c = bmap->ineq[i];
4108         }
4109         qsort(c, bmap->n_ineq, sizeof(struct constraint), qsort_constraint_cmp);
4110         for (i = 0; i < bmap->n_ineq; ++i)
4111                 bmap->ineq[i] = c[i].c;
4112         free(c);
4113         return bmap;
4114 error:
4115         isl_basic_map_free(bmap);
4116         return NULL;
4117 }
4118
4119 struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap)
4120 {
4121         if (!bmap)
4122                 return NULL;
4123         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED))
4124                 return bmap;
4125         bmap = isl_basic_map_convex_hull(bmap);
4126         bmap = isl_basic_map_sort_constraints(bmap);
4127         ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
4128         return bmap;
4129 }
4130
4131 struct isl_basic_set *isl_basic_set_normalize(struct isl_basic_set *bset)
4132 {
4133         return (struct isl_basic_set *)isl_basic_map_normalize(
4134                                                 (struct isl_basic_map *)bset);
4135 }
4136
4137 static int isl_basic_map_fast_cmp(const struct isl_basic_map *bmap1,
4138         const struct isl_basic_map *bmap2)
4139 {
4140         int i, cmp;
4141         unsigned total;
4142
4143         if (bmap1 == bmap2)
4144                 return 0;
4145         if (isl_basic_map_n_param(bmap1) != isl_basic_map_n_param(bmap2))
4146                 return isl_basic_map_n_param(bmap1) - isl_basic_map_n_param(bmap2);
4147         if (isl_basic_map_n_in(bmap1) != isl_basic_map_n_in(bmap2))
4148                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
4149         if (isl_basic_map_n_out(bmap1) != isl_basic_map_n_out(bmap2))
4150                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
4151         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
4152             ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
4153                 return 0;
4154         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
4155                 return 1;
4156         if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
4157                 return -1;
4158         if (bmap1->n_eq != bmap2->n_eq)
4159                 return bmap1->n_eq - bmap2->n_eq;
4160         if (bmap1->n_ineq != bmap2->n_ineq)
4161                 return bmap1->n_ineq - bmap2->n_ineq;
4162         if (bmap1->n_div != bmap2->n_div)
4163                 return bmap1->n_div - bmap2->n_div;
4164         total = isl_basic_map_total_dim(bmap1);
4165         for (i = 0; i < bmap1->n_eq; ++i) {
4166                 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
4167                 if (cmp)
4168                         return cmp;
4169         }
4170         for (i = 0; i < bmap1->n_ineq; ++i) {
4171                 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
4172                 if (cmp)
4173                         return cmp;
4174         }
4175         for (i = 0; i < bmap1->n_div; ++i) {
4176                 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
4177                 if (cmp)
4178                         return cmp;
4179         }
4180         return 0;
4181 }
4182
4183 static int isl_basic_map_fast_is_equal(struct isl_basic_map *bmap1,
4184         struct isl_basic_map *bmap2)
4185 {
4186         return isl_basic_map_fast_cmp(bmap1, bmap2) == 0;
4187 }
4188
4189 static int qsort_bmap_cmp(const void *p1, const void *p2)
4190 {
4191         const struct isl_basic_map *bmap1 = *(const struct isl_basic_map **)p1;
4192         const struct isl_basic_map *bmap2 = *(const struct isl_basic_map **)p2;
4193
4194         return isl_basic_map_fast_cmp(bmap1, bmap2);
4195 }
4196
4197 /* We normalize in place, but if anything goes wrong we need
4198  * to return NULL, so we need to make sure we don't change the
4199  * meaning of any possible other copies of map.
4200  */
4201 struct isl_map *isl_map_normalize(struct isl_map *map)
4202 {
4203         int i, j;
4204         struct isl_basic_map *bmap;
4205
4206         if (!map)
4207                 return NULL;
4208         if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED))
4209                 return map;
4210         for (i = 0; i < map->n; ++i) {
4211                 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
4212                 if (!bmap)
4213                         goto error;
4214                 isl_basic_map_free(map->p[i]);
4215                 map->p[i] = bmap;
4216         }
4217         qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
4218         ISL_F_SET(map, ISL_MAP_NORMALIZED);
4219         map = isl_map_remove_empty_parts(map);
4220         if (!map)
4221                 return NULL;
4222         for (i = map->n - 1; i >= 1; --i) {
4223                 if (!isl_basic_map_fast_is_equal(map->p[i-1], map->p[i]))
4224                         continue;
4225                 isl_basic_map_free(map->p[i-1]);
4226                 for (j = i; j < map->n; ++j)
4227                         map->p[j-1] = map->p[j];
4228                 map->n--;
4229         }
4230         return map;
4231 error:
4232         isl_map_free(map);
4233         return NULL;
4234
4235 }
4236
4237 struct isl_set *isl_set_normalize(struct isl_set *set)
4238 {
4239         return (struct isl_set *)isl_map_normalize((struct isl_map *)set);
4240 }
4241
4242 int isl_map_fast_is_equal(struct isl_map *map1, struct isl_map *map2)
4243 {
4244         int i;
4245         int equal;
4246
4247         if (!map1 || !map2)
4248                 return -1;
4249
4250         if (map1 == map2)
4251                 return 1;
4252         if (!isl_dim_equal(map1->dim, map2->dim))
4253                 return 0;
4254
4255         map1 = isl_map_copy(map1);
4256         map2 = isl_map_copy(map2);
4257         map1 = isl_map_normalize(map1);
4258         map2 = isl_map_normalize(map2);
4259         if (!map1 || !map2)
4260                 goto error;
4261         equal = map1->n == map2->n;
4262         for (i = 0; equal && i < map1->n; ++i) {
4263                 equal = isl_basic_map_fast_is_equal(map1->p[i], map2->p[i]);
4264                 if (equal < 0)
4265                         goto error;
4266         }
4267         isl_map_free(map1);
4268         isl_map_free(map2);
4269         return equal;
4270 error:
4271         isl_map_free(map1);
4272         isl_map_free(map2);
4273         return -1;
4274 }
4275
4276 int isl_set_fast_is_equal(struct isl_set *set1, struct isl_set *set2)
4277 {
4278         return isl_map_fast_is_equal((struct isl_map *)set1,
4279                                                 (struct isl_map *)set2);
4280 }
4281
4282 /* Return an interval that ranges from min to max (inclusive)
4283  */
4284 struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx,
4285         isl_int min, isl_int max)
4286 {
4287         int k;
4288         struct isl_basic_set *bset = NULL;
4289
4290         bset = isl_basic_set_alloc(ctx, 0, 1, 0, 0, 2);
4291         if (!bset)
4292                 goto error;
4293
4294         k = isl_basic_set_alloc_inequality(bset);
4295         if (k < 0)
4296                 goto error;
4297         isl_int_set_si(bset->ineq[k][1], 1);
4298         isl_int_neg(bset->ineq[k][0], min);
4299
4300         k = isl_basic_set_alloc_inequality(bset);
4301         if (k < 0)
4302                 goto error;
4303         isl_int_set_si(bset->ineq[k][1], -1);
4304         isl_int_set(bset->ineq[k][0], max);
4305
4306         return bset;
4307 error:
4308         isl_basic_set_free(bset);
4309         return NULL;
4310 }
4311
4312 /* Return the Cartesian product of the basic sets in list (in the given order).
4313  */
4314 struct isl_basic_set *isl_basic_set_product(struct isl_basic_set_list *list)
4315 {
4316         int i;
4317         unsigned dim;
4318         unsigned nparam;
4319         unsigned extra;
4320         unsigned n_eq;
4321         unsigned n_ineq;
4322         struct isl_basic_set *product = NULL;
4323
4324         if (!list)
4325                 goto error;
4326         isl_assert(list->ctx, list->n > 0, goto error);
4327         isl_assert(list->ctx, list->p[0], goto error);
4328         nparam = isl_basic_set_n_param(list->p[0]);
4329         dim = isl_basic_set_n_dim(list->p[0]);
4330         extra = list->p[0]->n_div;
4331         n_eq = list->p[0]->n_eq;
4332         n_ineq = list->p[0]->n_ineq;
4333         for (i = 1; i < list->n; ++i) {
4334                 isl_assert(list->ctx, list->p[i], goto error);
4335                 isl_assert(list->ctx,
4336                     nparam == isl_basic_set_n_param(list->p[i]), goto error);
4337                 dim += isl_basic_set_n_dim(list->p[i]);
4338                 extra += list->p[i]->n_div;
4339                 n_eq += list->p[i]->n_eq;
4340                 n_ineq += list->p[i]->n_ineq;
4341         }
4342         product = isl_basic_set_alloc(list->ctx, nparam, dim, extra,
4343                                         n_eq, n_ineq);
4344         if (!product)
4345                 goto error;
4346         dim = 0;
4347         for (i = 0; i < list->n; ++i) {
4348                 isl_basic_set_add_constraints(product,
4349                                         isl_basic_set_copy(list->p[i]), dim);
4350                 dim += isl_basic_set_n_dim(list->p[i]);
4351         }
4352         isl_basic_set_list_free(list);
4353         return product;
4354 error:
4355         isl_basic_set_free(product);
4356         isl_basic_set_list_free(list);
4357         return NULL;
4358 }
4359
4360 struct isl_basic_map *isl_basic_map_product(
4361                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
4362 {
4363         struct isl_dim *dim_result = NULL;
4364         struct isl_basic_map *bmap;
4365         unsigned in1, in2, out1, out2, nparam, total, pos;
4366         struct isl_dim_map *dim_map1, *dim_map2;
4367
4368         if (!bmap1 || !bmap2)
4369                 goto error;
4370
4371         isl_assert(map1->ctx, isl_dim_match(bmap1->dim, isl_dim_param,
4372                                      bmap2->dim, isl_dim_param), goto error);
4373         dim_result = isl_dim_product(isl_dim_copy(bmap1->dim),
4374                                                    isl_dim_copy(bmap2->dim));
4375
4376         in1 = isl_basic_map_n_in(bmap1);
4377         in2 = isl_basic_map_n_in(bmap2);
4378         out1 = isl_basic_map_n_out(bmap1);
4379         out2 = isl_basic_map_n_out(bmap2);
4380         nparam = isl_basic_map_n_param(bmap1);
4381
4382         total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
4383         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4384         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
4385         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4386         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
4387         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4388         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
4389         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
4390         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
4391         isl_dim_map_div(dim_map1, bmap1, pos += out2);
4392         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4393
4394         bmap = isl_basic_map_alloc_dim(dim_result,
4395                         bmap1->n_div + bmap2->n_div,
4396                         bmap1->n_eq + bmap2->n_eq,
4397                         bmap1->n_ineq + bmap2->n_ineq);
4398         bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
4399         bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
4400         bmap = isl_basic_map_simplify(bmap);
4401         return isl_basic_map_finalize(bmap);
4402 error:
4403         isl_basic_map_free(bmap1);
4404         isl_basic_map_free(bmap2);
4405         return NULL;
4406 }
4407
4408 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
4409  */
4410 struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2)
4411 {
4412         unsigned flags = 0;
4413         struct isl_map *result;
4414         int i, j;
4415
4416         if (!map1 || !map2)
4417                 goto error;
4418
4419         isl_assert(map1->ctx, isl_dim_match(map1->dim, isl_dim_param,
4420                                          map2->dim, isl_dim_param), goto error);
4421
4422         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
4423             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
4424                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
4425
4426         result = isl_map_alloc_dim(isl_dim_product(isl_dim_copy(map1->dim),
4427                                                    isl_dim_copy(map2->dim)),
4428                                 map1->n * map2->n, flags);
4429         if (!result)
4430                 goto error;
4431         for (i = 0; i < map1->n; ++i)
4432                 for (j = 0; j < map2->n; ++j) {
4433                         struct isl_basic_map *part;
4434                         part = isl_basic_map_product(
4435                                     isl_basic_map_copy(map1->p[i]),
4436                                     isl_basic_map_copy(map2->p[j]));
4437                         if (isl_basic_map_is_empty(part))
4438                                 isl_basic_map_free(part);
4439                         else
4440                                 result = isl_map_add(result, part);
4441                         if (!result)
4442                                 goto error;
4443                 }
4444         isl_map_free(map1);
4445         isl_map_free(map2);
4446         return result;
4447 error:
4448         isl_map_free(map1);
4449         isl_map_free(map2);
4450         return NULL;
4451 }
4452
4453 uint32_t isl_basic_set_get_hash(struct isl_basic_set *bset)
4454 {
4455         int i;
4456         uint32_t hash;
4457         unsigned total;
4458
4459         if (!bset)
4460                 return 0;
4461         bset = isl_basic_set_copy(bset);
4462         bset = isl_basic_set_normalize(bset);
4463         if (!bset)
4464                 return 0;
4465         total = isl_basic_set_total_dim(bset);
4466         isl_hash_byte(hash, bset->n_eq & 0xFF);
4467         for (i = 0; i < bset->n_eq; ++i) {
4468                 uint32_t c_hash;
4469                 c_hash = isl_seq_get_hash(bset->eq[i], 1 + total);
4470                 isl_hash_hash(hash, c_hash);
4471         }
4472         isl_hash_byte(hash, bset->n_ineq & 0xFF);
4473         for (i = 0; i < bset->n_ineq; ++i) {
4474                 uint32_t c_hash;
4475                 c_hash = isl_seq_get_hash(bset->ineq[i], 1 + total);
4476                 isl_hash_hash(hash, c_hash);
4477         }
4478         isl_hash_byte(hash, bset->n_div & 0xFF);
4479         for (i = 0; i < bset->n_div; ++i) {
4480                 uint32_t c_hash;
4481                 if (isl_int_is_zero(bset->div[i][0]))
4482                         continue;
4483                 isl_hash_byte(hash, i & 0xFF);
4484                 c_hash = isl_seq_get_hash(bset->div[i], 1 + 1 + total);
4485                 isl_hash_hash(hash, c_hash);
4486         }
4487         isl_basic_set_free(bset);
4488         return hash;
4489 }
4490
4491 uint32_t isl_set_get_hash(struct isl_set *set)
4492 {
4493         int i;
4494         uint32_t hash;
4495
4496         if (!set)
4497                 return 0;
4498         set = isl_set_copy(set);
4499         set = isl_set_normalize(set);
4500         if (!set)
4501                 return 0;
4502
4503         hash = isl_hash_init();
4504         for (i = 0; i < set->n; ++i) {
4505                 uint32_t bset_hash;
4506                 bset_hash = isl_basic_set_get_hash(set->p[i]);
4507                 isl_hash_hash(hash, bset_hash);
4508         }
4509                 
4510         isl_set_free(set);
4511
4512         return hash;
4513 }
4514
4515 /* Check if the value for dimension dim is completely determined
4516  * by the values of the other parameters and variables.
4517  * That is, check if dimension dim is involved in an equality.
4518  */
4519 int isl_basic_set_dim_is_unique(struct isl_basic_set *bset, unsigned dim)
4520 {
4521         int i;
4522         unsigned nparam;
4523
4524         if (!bset)
4525                 return -1;
4526         nparam = isl_basic_set_n_param(bset);
4527         for (i = 0; i < bset->n_eq; ++i)
4528                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + dim]))
4529                         return 1;
4530         return 0;
4531 }
4532
4533 /* Check if the value for dimension dim is completely determined
4534  * by the values of the other parameters and variables.
4535  * That is, check if dimension dim is involved in an equality
4536  * for each of the subsets.
4537  */
4538 int isl_set_dim_is_unique(struct isl_set *set, unsigned dim)
4539 {
4540         int i;
4541
4542         if (!set)
4543                 return -1;
4544         for (i = 0; i < set->n; ++i) {
4545                 int unique;
4546                 unique = isl_basic_set_dim_is_unique(set->p[i], dim);
4547                 if (unique != 1)
4548                         return unique;
4549         }
4550         return 1;
4551 }