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