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