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