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