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