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