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