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