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