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