add isl_basic_map_remove_divs
[platform/upstream/isl.git] / isl_map.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2010      INRIA Saclay
4  *
5  * Use of this software is governed by the GNU LGPLv2.1 license
6  *
7  * Written by Sven Verdoolaege, K.U.Leuven, Departement
8  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France 
11  */
12
13 #include <string.h>
14 #include <strings.h>
15 #include "isl_ctx.h"
16 #include "isl_blk.h"
17 #include "isl_dim_private.h"
18 #include "isl_equalities.h"
19 #include "isl_list.h"
20 #include "isl_lp.h"
21 #include "isl_seq.h"
22 #include "isl_set.h"
23 #include "isl_map.h"
24 #include "isl_map_private.h"
25 #include "isl_map_piplib.h"
26 #include <isl_reordering.h>
27 #include "isl_sample.h"
28 #include "isl_tab.h"
29 #include "isl_vec.h"
30 #include <isl_mat_private.h>
31
32 /* Maps dst positions to src positions */
33 struct isl_dim_map {
34         unsigned len;
35         int pos[1];
36 };
37
38 static struct isl_dim_map *isl_dim_map_alloc(struct isl_ctx *ctx, unsigned len)
39 {
40         int i;
41         struct isl_dim_map *dim_map;
42         dim_map = isl_alloc(ctx, struct isl_dim_map,
43                                 sizeof(struct isl_dim_map) + len * sizeof(int));
44         if (!dim_map)
45                 return NULL;
46         dim_map->len = 1 + len;
47         dim_map->pos[0] = 0;
48         for (i = 0; i < len; ++i)
49                 dim_map->pos[1 + i] = -1;
50         return dim_map;
51 }
52
53 static unsigned n(struct isl_dim *dim, enum isl_dim_type type)
54 {
55         switch (type) {
56         case isl_dim_param:     return dim->nparam;
57         case isl_dim_in:        return dim->n_in;
58         case isl_dim_out:       return dim->n_out;
59         case isl_dim_all:       return dim->nparam + dim->n_in + dim->n_out;
60         default:                return 0;
61         }
62 }
63
64 static unsigned pos(struct isl_dim *dim, enum isl_dim_type type)
65 {
66         switch (type) {
67         case isl_dim_param:     return 1;
68         case isl_dim_in:        return 1 + dim->nparam;
69         case isl_dim_out:       return 1 + dim->nparam + dim->n_in;
70         default:                return 0;
71         }
72 }
73
74 static void isl_dim_map_dim_range(struct isl_dim_map *dim_map,
75         struct isl_dim *dim, enum isl_dim_type type,
76         unsigned first, unsigned n, unsigned dst_pos)
77 {
78         int i;
79         unsigned src_pos;
80
81         if (!dim_map || !dim)
82                 return;
83         
84         src_pos = pos(dim, type);
85         for (i = 0; i < n; ++i)
86                 dim_map->pos[1 + dst_pos + i] = src_pos + first + i;
87 }
88
89 static void isl_dim_map_dim(struct isl_dim_map *dim_map, struct isl_dim *dim,
90                 enum isl_dim_type type, unsigned dst_pos)
91 {
92         isl_dim_map_dim_range(dim_map, dim, type, 0, n(dim, type), dst_pos);
93 }
94
95 static void isl_dim_map_div(struct isl_dim_map *dim_map,
96                 struct isl_basic_map *bmap, unsigned dst_pos)
97 {
98         int i;
99         unsigned src_pos;
100
101         if (!dim_map || !bmap)
102                 return;
103         
104         src_pos = 1 + isl_dim_total(bmap->dim);
105         for (i = 0; i < bmap->n_div; ++i)
106                 dim_map->pos[1 + dst_pos + i] = src_pos + i;
107 }
108
109 static void isl_dim_map_dump(struct isl_dim_map *dim_map)
110 {
111         int i;
112
113         for (i = 0; i < dim_map->len; ++i)
114                 fprintf(stderr, "%d -> %d; ", i, dim_map->pos[i]);
115         fprintf(stderr, "\n");
116 }
117
118 unsigned isl_basic_map_dim(const struct isl_basic_map *bmap,
119                                 enum isl_dim_type type)
120 {
121         if (!bmap)
122                 return 0;
123         switch (type) {
124         case isl_dim_cst:       return 1;
125         case isl_dim_param:
126         case isl_dim_in:
127         case isl_dim_out:       return isl_dim_size(bmap->dim, type);
128         case isl_dim_div:       return bmap->n_div;
129         case isl_dim_all:       return isl_basic_map_total_dim(bmap);
130         default:                return 0;
131         }
132 }
133
134 unsigned isl_map_dim(const struct isl_map *map, enum isl_dim_type type)
135 {
136         return map ? n(map->dim, type) : 0;
137 }
138
139 unsigned isl_set_dim(const struct isl_set *set, enum isl_dim_type type)
140 {
141         return set ? n(set->dim, type) : 0;
142 }
143
144 unsigned isl_basic_map_offset(struct isl_basic_map *bmap,
145                                         enum isl_dim_type type)
146 {
147         struct isl_dim *dim = bmap->dim;
148         switch (type) {
149         case isl_dim_cst:       return 0;
150         case isl_dim_param:     return 1;
151         case isl_dim_in:        return 1 + dim->nparam;
152         case isl_dim_out:       return 1 + dim->nparam + dim->n_in;
153         case isl_dim_div:       return 1 + dim->nparam + dim->n_in + dim->n_out;
154         default:                return 0;
155         }
156 }
157
158 static unsigned map_offset(struct isl_map *map, enum isl_dim_type type)
159 {
160         return pos(map->dim, type);
161 }
162
163 unsigned isl_basic_set_dim(const struct isl_basic_set *bset,
164                                 enum isl_dim_type type)
165 {
166         return isl_basic_map_dim((const struct isl_basic_map*)bset, type);
167 }
168
169 unsigned isl_basic_set_n_dim(const struct isl_basic_set *bset)
170 {
171         return isl_basic_set_dim(bset, isl_dim_set);
172 }
173
174 unsigned isl_basic_set_n_param(const struct isl_basic_set *bset)
175 {
176         return isl_basic_set_dim(bset, isl_dim_param);
177 }
178
179 unsigned isl_basic_set_total_dim(const struct isl_basic_set *bset)
180 {
181         return isl_dim_total(bset->dim) + bset->n_div;
182 }
183
184 unsigned isl_set_n_dim(const struct isl_set *set)
185 {
186         return isl_set_dim(set, isl_dim_set);
187 }
188
189 unsigned isl_set_n_param(const struct isl_set *set)
190 {
191         return isl_set_dim(set, isl_dim_param);
192 }
193
194 unsigned isl_basic_map_n_in(const struct isl_basic_map *bmap)
195 {
196         return bmap ? bmap->dim->n_in : 0;
197 }
198
199 unsigned isl_basic_map_n_out(const struct isl_basic_map *bmap)
200 {
201         return bmap ? bmap->dim->n_out : 0;
202 }
203
204 unsigned isl_basic_map_n_param(const struct isl_basic_map *bmap)
205 {
206         return bmap ? bmap->dim->nparam : 0;
207 }
208
209 unsigned isl_basic_map_n_div(const struct isl_basic_map *bmap)
210 {
211         return bmap ? bmap->n_div : 0;
212 }
213
214 unsigned isl_basic_map_total_dim(const struct isl_basic_map *bmap)
215 {
216         return bmap ? isl_dim_total(bmap->dim) + bmap->n_div : 0;
217 }
218
219 unsigned isl_map_n_in(const struct isl_map *map)
220 {
221         return map->dim->n_in;
222 }
223
224 unsigned isl_map_n_out(const struct isl_map *map)
225 {
226         return map->dim->n_out;
227 }
228
229 unsigned isl_map_n_param(const struct isl_map *map)
230 {
231         return map->dim->nparam;
232 }
233
234 int isl_map_compatible_domain(struct isl_map *map, struct isl_set *set)
235 {
236         int m;
237         if (!map || !set)
238                 return -1;
239         m = isl_dim_match(map->dim, isl_dim_param, set->dim, isl_dim_param);
240         if (m < 0 || !m)
241                 return m;
242         return isl_dim_tuple_match(map->dim, isl_dim_in, set->dim, isl_dim_set);
243 }
244
245 int isl_basic_map_compatible_domain(struct isl_basic_map *bmap,
246                 struct isl_basic_set *bset)
247 {
248         int m;
249         if (!bmap || !bset)
250                 return -1;
251         m = isl_dim_match(bmap->dim, isl_dim_param, bset->dim, isl_dim_param);
252         if (m < 0 || !m)
253                 return m;
254         return isl_dim_tuple_match(bmap->dim, isl_dim_in, bset->dim, isl_dim_set);
255 }
256
257 int isl_basic_map_compatible_range(struct isl_basic_map *bmap,
258                 struct isl_basic_set *bset)
259 {
260         int m;
261         if (!bmap || !bset)
262                 return -1;
263         m = isl_dim_match(bmap->dim, isl_dim_param, bset->dim, isl_dim_param);
264         if (m < 0 || !m)
265                 return m;
266         return isl_dim_tuple_match(bmap->dim, isl_dim_out, bset->dim, isl_dim_set);
267 }
268
269 isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap)
270 {
271         return bmap ? bmap->ctx : NULL;
272 }
273
274 isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_set *bset)
275 {
276         return bset ? bset->ctx : NULL;
277 }
278
279 isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map)
280 {
281         return map ? map->ctx : NULL;
282 }
283
284 isl_ctx *isl_set_get_ctx(__isl_keep isl_set *set)
285 {
286         return set ? set->ctx : NULL;
287 }
288
289 struct isl_dim *isl_basic_map_get_dim(struct isl_basic_map *bmap)
290 {
291         if (!bmap)
292                 return NULL;
293         return isl_dim_copy(bmap->dim);
294 }
295
296 struct isl_dim *isl_basic_set_get_dim(struct isl_basic_set *bset)
297 {
298         if (!bset)
299                 return NULL;
300         return isl_dim_copy(bset->dim);
301 }
302
303 struct isl_dim *isl_map_get_dim(struct isl_map *map)
304 {
305         if (!map)
306                 return NULL;
307         return isl_dim_copy(map->dim);
308 }
309
310 struct isl_dim *isl_set_get_dim(struct isl_set *set)
311 {
312         if (!set)
313                 return NULL;
314         return isl_dim_copy(set->dim);
315 }
316
317 __isl_give isl_basic_map *isl_basic_map_set_tuple_name(
318         __isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s)
319 {
320         bmap = isl_basic_map_cow(bmap);
321         if (!bmap)
322                 return NULL;
323         bmap->dim = isl_dim_set_tuple_name(bmap->dim, type, s);
324         if (!bmap->dim)
325                 goto error;
326         return bmap;
327 error:
328         isl_basic_map_free(bmap);
329         return NULL;
330 }
331
332 __isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map,
333         enum isl_dim_type type, const char *s)
334 {
335         int i;
336
337         map = isl_map_cow(map);
338         if (!map)
339                 return NULL;
340
341         map->dim = isl_dim_set_tuple_name(map->dim, type, s);
342         if (!map->dim)
343                 goto error;
344
345         for (i = 0; i < map->n; ++i) {
346                 map->p[i] = isl_basic_map_set_tuple_name(map->p[i], type, s);
347                 if (!map->p[i])
348                         goto error;
349         }
350
351         return map;
352 error:
353         isl_map_free(map);
354         return NULL;
355 }
356
357 __isl_give isl_set *isl_set_set_tuple_name(__isl_take isl_set *set,
358         const char *s)
359 {
360         return (isl_set *)isl_map_set_tuple_name((isl_map *)set, isl_dim_set, s);
361 }
362
363 __isl_give isl_basic_map *isl_basic_map_set_dim_name(
364         __isl_take isl_basic_map *bmap,
365         enum isl_dim_type type, unsigned pos, const char *s)
366 {
367         if (!bmap)
368                 return NULL;
369         bmap->dim = isl_dim_set_name(bmap->dim, type, pos, s);
370         if (!bmap->dim)
371                 goto error;
372         return bmap;
373 error:
374         isl_basic_map_free(bmap);
375         return NULL;
376 }
377
378 __isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map,
379         enum isl_dim_type type, unsigned pos, const char *s)
380 {
381         int i;
382
383         if (!map)
384                 return NULL;
385
386         map->dim = isl_dim_set_name(map->dim, type, pos, s);
387         if (!map->dim)
388                 goto error;
389
390         for (i = 0; i < map->n; ++i) {
391                 map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s);
392                 if (!map->p[i])
393                         goto error;
394         }
395
396         return map;
397 error:
398         isl_map_free(map);
399         return NULL;
400 }
401
402 __isl_give isl_basic_set *isl_basic_set_set_dim_name(
403         __isl_take isl_basic_set *bset,
404         enum isl_dim_type type, unsigned pos, const char *s)
405 {
406         return (isl_basic_set *)isl_basic_map_set_dim_name(
407                 (isl_basic_map *)bset, type, pos, s);
408 }
409
410 __isl_give isl_set *isl_set_set_dim_name(__isl_take isl_set *set,
411         enum isl_dim_type type, unsigned pos, const char *s)
412 {
413         return (isl_set *)isl_map_set_dim_name((isl_map *)set, type, pos, s);
414 }
415
416 int isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap)
417 {
418         if (!bmap)
419                 return -1;
420         return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
421 }
422
423 static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx,
424                 struct isl_basic_map *bmap, unsigned extra,
425                 unsigned n_eq, unsigned n_ineq)
426 {
427         int i;
428         size_t row_size = 1 + isl_dim_total(bmap->dim) + extra;
429
430         bmap->ctx = ctx;
431         isl_ctx_ref(ctx);
432
433         bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size);
434         if (isl_blk_is_error(bmap->block))
435                 goto error;
436
437         bmap->ineq = isl_alloc_array(ctx, isl_int *, n_ineq + n_eq);
438         if (!bmap->ineq)
439                 goto error;
440
441         if (extra == 0) {
442                 bmap->block2 = isl_blk_empty();
443                 bmap->div = NULL;
444         } else {
445                 bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
446                 if (isl_blk_is_error(bmap->block2))
447                         goto error;
448
449                 bmap->div = isl_alloc_array(ctx, isl_int *, extra);
450                 if (!bmap->div)
451                         goto error;
452         }
453
454         for (i = 0; i < n_ineq + n_eq; ++i)
455                 bmap->ineq[i] = bmap->block.data + i * row_size;
456
457         for (i = 0; i < extra; ++i)
458                 bmap->div[i] = bmap->block2.data + i * (1 + row_size);
459
460         bmap->ref = 1;
461         bmap->flags = 0;
462         bmap->c_size = n_eq + n_ineq;
463         bmap->eq = bmap->ineq + n_ineq;
464         bmap->extra = extra;
465         bmap->n_eq = 0;
466         bmap->n_ineq = 0;
467         bmap->n_div = 0;
468         bmap->sample = NULL;
469
470         return bmap;
471 error:
472         isl_basic_map_free(bmap);
473         return NULL;
474 }
475
476 struct isl_basic_set *isl_basic_set_alloc(struct isl_ctx *ctx,
477                 unsigned nparam, unsigned dim, unsigned extra,
478                 unsigned n_eq, unsigned n_ineq)
479 {
480         struct isl_basic_map *bmap;
481         bmap = isl_basic_map_alloc(ctx, nparam, 0, dim, extra, n_eq, n_ineq);
482         return (struct isl_basic_set *)bmap;
483 }
484
485 struct isl_basic_set *isl_basic_set_alloc_dim(struct isl_dim *dim,
486                 unsigned extra, unsigned n_eq, unsigned n_ineq)
487 {
488         struct isl_basic_map *bmap;
489         if (!dim)
490                 return NULL;
491         isl_assert(dim->ctx, dim->n_in == 0, return NULL);
492         bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
493         return (struct isl_basic_set *)bmap;
494 }
495
496 struct isl_basic_map *isl_basic_map_alloc_dim(struct isl_dim *dim,
497                 unsigned extra, unsigned n_eq, unsigned n_ineq)
498 {
499         struct isl_basic_map *bmap;
500
501         if (!dim)
502                 return NULL;
503         bmap = isl_calloc_type(dim->ctx, struct isl_basic_map);
504         if (!bmap)
505                 goto error;
506         bmap->dim = dim;
507
508         return basic_map_init(dim->ctx, bmap, extra, n_eq, n_ineq);
509 error:
510         isl_dim_free(dim);
511         return NULL;
512 }
513
514 struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx,
515                 unsigned nparam, unsigned in, unsigned out, unsigned extra,
516                 unsigned n_eq, unsigned n_ineq)
517 {
518         struct isl_basic_map *bmap;
519         struct isl_dim *dim;
520
521         dim = isl_dim_alloc(ctx, nparam, in, out);
522         if (!dim)
523                 return NULL;
524
525         bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
526         return bmap;
527 }
528
529 static void dup_constraints(
530                 struct isl_basic_map *dst, struct isl_basic_map *src)
531 {
532         int i;
533         unsigned total = isl_basic_map_total_dim(src);
534
535         for (i = 0; i < src->n_eq; ++i) {
536                 int j = isl_basic_map_alloc_equality(dst);
537                 isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
538         }
539
540         for (i = 0; i < src->n_ineq; ++i) {
541                 int j = isl_basic_map_alloc_inequality(dst);
542                 isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
543         }
544
545         for (i = 0; i < src->n_div; ++i) {
546                 int j = isl_basic_map_alloc_div(dst);
547                 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
548         }
549         ISL_F_SET(dst, ISL_BASIC_SET_FINAL);
550 }
551
552 struct isl_basic_map *isl_basic_map_dup(struct isl_basic_map *bmap)
553 {
554         struct isl_basic_map *dup;
555
556         if (!bmap)
557                 return NULL;
558         dup = isl_basic_map_alloc_dim(isl_dim_copy(bmap->dim),
559                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
560         if (!dup)
561                 return NULL;
562         dup_constraints(dup, bmap);
563         dup->flags = bmap->flags;
564         dup->sample = isl_vec_copy(bmap->sample);
565         return dup;
566 }
567
568 struct isl_basic_set *isl_basic_set_dup(struct isl_basic_set *bset)
569 {
570         struct isl_basic_map *dup;
571
572         dup = isl_basic_map_dup((struct isl_basic_map *)bset);
573         return (struct isl_basic_set *)dup;
574 }
575
576 struct isl_basic_set *isl_basic_set_copy(struct isl_basic_set *bset)
577 {
578         if (!bset)
579                 return NULL;
580
581         if (ISL_F_ISSET(bset, ISL_BASIC_SET_FINAL)) {
582                 bset->ref++;
583                 return bset;
584         }
585         return isl_basic_set_dup(bset);
586 }
587
588 struct isl_set *isl_set_copy(struct isl_set *set)
589 {
590         if (!set)
591                 return NULL;
592
593         set->ref++;
594         return set;
595 }
596
597 struct isl_basic_map *isl_basic_map_copy(struct isl_basic_map *bmap)
598 {
599         if (!bmap)
600                 return NULL;
601
602         if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)) {
603                 bmap->ref++;
604                 return bmap;
605         }
606         bmap = isl_basic_map_dup(bmap);
607         if (bmap)
608                 ISL_F_SET(bmap, ISL_BASIC_SET_FINAL);
609         return bmap;
610 }
611
612 struct isl_map *isl_map_copy(struct isl_map *map)
613 {
614         if (!map)
615                 return NULL;
616
617         map->ref++;
618         return map;
619 }
620
621 void isl_basic_map_free(struct isl_basic_map *bmap)
622 {
623         if (!bmap)
624                 return;
625
626         if (--bmap->ref > 0)
627                 return;
628
629         isl_ctx_deref(bmap->ctx);
630         free(bmap->div);
631         isl_blk_free(bmap->ctx, bmap->block2);
632         free(bmap->ineq);
633         isl_blk_free(bmap->ctx, bmap->block);
634         isl_vec_free(bmap->sample);
635         isl_dim_free(bmap->dim);
636         free(bmap);
637 }
638
639 void isl_basic_set_free(struct isl_basic_set *bset)
640 {
641         isl_basic_map_free((struct isl_basic_map *)bset);
642 }
643
644 static int room_for_con(struct isl_basic_map *bmap, unsigned n)
645 {
646         return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size;
647 }
648
649 int isl_basic_map_alloc_equality(struct isl_basic_map *bmap)
650 {
651         struct isl_ctx *ctx;
652         if (!bmap)
653                 return -1;
654         ctx = bmap->ctx;
655         isl_assert(ctx, room_for_con(bmap, 1), return -1);
656         isl_assert(ctx, (bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size,
657                         return -1);
658         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
659         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
660         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
661         ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
662         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
663         if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
664                 isl_int *t;
665                 int j = isl_basic_map_alloc_inequality(bmap);
666                 if (j < 0)
667                         return -1;
668                 t = bmap->ineq[j];
669                 bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
670                 bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
671                 bmap->eq[-1] = t;
672                 bmap->n_eq++;
673                 bmap->n_ineq--;
674                 bmap->eq--;
675                 return 0;
676         }
677         isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + isl_basic_map_total_dim(bmap),
678                       bmap->extra - bmap->n_div);
679         return bmap->n_eq++;
680 }
681
682 int isl_basic_set_alloc_equality(struct isl_basic_set *bset)
683 {
684         return isl_basic_map_alloc_equality((struct isl_basic_map *)bset);
685 }
686
687 int isl_basic_map_free_equality(struct isl_basic_map *bmap, unsigned n)
688 {
689         if (!bmap)
690                 return -1;
691         isl_assert(bmap->ctx, n <= bmap->n_eq, return -1);
692         bmap->n_eq -= n;
693         return 0;
694 }
695
696 int isl_basic_set_free_equality(struct isl_basic_set *bset, unsigned n)
697 {
698         return isl_basic_map_free_equality((struct isl_basic_map *)bset, n);
699 }
700
701 int isl_basic_map_drop_equality(struct isl_basic_map *bmap, unsigned pos)
702 {
703         isl_int *t;
704         if (!bmap)
705                 return -1;
706         isl_assert(bmap->ctx, pos < bmap->n_eq, return -1);
707
708         if (pos != bmap->n_eq - 1) {
709                 t = bmap->eq[pos];
710                 bmap->eq[pos] = bmap->eq[bmap->n_eq - 1];
711                 bmap->eq[bmap->n_eq - 1] = t;
712         }
713         bmap->n_eq--;
714         return 0;
715 }
716
717 int isl_basic_set_drop_equality(struct isl_basic_set *bset, unsigned pos)
718 {
719         return isl_basic_map_drop_equality((struct isl_basic_map *)bset, pos);
720 }
721
722 void isl_basic_map_inequality_to_equality(
723                 struct isl_basic_map *bmap, unsigned pos)
724 {
725         isl_int *t;
726
727         t = bmap->ineq[pos];
728         bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
729         bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
730         bmap->eq[-1] = t;
731         bmap->n_eq++;
732         bmap->n_ineq--;
733         bmap->eq--;
734         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
735         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
736         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
737         ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
738 }
739
740 static int room_for_ineq(struct isl_basic_map *bmap, unsigned n)
741 {
742         return bmap->n_ineq + n <= bmap->eq - bmap->ineq;
743 }
744
745 int isl_basic_map_alloc_inequality(struct isl_basic_map *bmap)
746 {
747         struct isl_ctx *ctx;
748         if (!bmap)
749                 return -1;
750         ctx = bmap->ctx;
751         isl_assert(ctx, room_for_ineq(bmap, 1), return -1);
752         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
753         ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
754         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
755         ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
756         isl_seq_clr(bmap->ineq[bmap->n_ineq] +
757                       1 + isl_basic_map_total_dim(bmap),
758                       bmap->extra - bmap->n_div);
759         return bmap->n_ineq++;
760 }
761
762 int isl_basic_set_alloc_inequality(struct isl_basic_set *bset)
763 {
764         return isl_basic_map_alloc_inequality((struct isl_basic_map *)bset);
765 }
766
767 int isl_basic_map_free_inequality(struct isl_basic_map *bmap, unsigned n)
768 {
769         if (!bmap)
770                 return -1;
771         isl_assert(bmap->ctx, n <= bmap->n_ineq, return -1);
772         bmap->n_ineq -= n;
773         return 0;
774 }
775
776 int isl_basic_set_free_inequality(struct isl_basic_set *bset, unsigned n)
777 {
778         return isl_basic_map_free_inequality((struct isl_basic_map *)bset, n);
779 }
780
781 int isl_basic_map_drop_inequality(struct isl_basic_map *bmap, unsigned pos)
782 {
783         isl_int *t;
784         if (!bmap)
785                 return -1;
786         isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
787
788         if (pos != bmap->n_ineq - 1) {
789                 t = bmap->ineq[pos];
790                 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
791                 bmap->ineq[bmap->n_ineq - 1] = t;
792                 ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
793         }
794         bmap->n_ineq--;
795         return 0;
796 }
797
798 int isl_basic_set_drop_inequality(struct isl_basic_set *bset, unsigned pos)
799 {
800         return isl_basic_map_drop_inequality((struct isl_basic_map *)bset, pos);
801 }
802
803 __isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap,
804         isl_int *eq)
805 {
806         int k;
807
808         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
809         if (!bmap)
810                 return NULL;
811         k = isl_basic_map_alloc_equality(bmap);
812         if (k < 0)
813                 goto error;
814         isl_seq_cpy(bmap->eq[k], eq, 1 + isl_basic_map_total_dim(bmap));
815         return bmap;
816 error:
817         isl_basic_map_free(bmap);
818         return NULL;
819 }
820
821 __isl_give isl_basic_set *isl_basic_set_add_eq(__isl_take isl_basic_set *bset,
822         isl_int *eq)
823 {
824         return (isl_basic_set *)
825                 isl_basic_map_add_eq((isl_basic_map *)bset, eq);
826 }
827
828 __isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap,
829         isl_int *ineq)
830 {
831         int k;
832
833         bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
834         if (!bmap)
835                 return NULL;
836         k = isl_basic_map_alloc_inequality(bmap);
837         if (k < 0)
838                 goto error;
839         isl_seq_cpy(bmap->ineq[k], ineq, 1 + isl_basic_map_total_dim(bmap));
840         return bmap;
841 error:
842         isl_basic_map_free(bmap);
843         return NULL;
844 }
845
846 __isl_give isl_basic_set *isl_basic_set_add_ineq(__isl_take isl_basic_set *bset,
847         isl_int *ineq)
848 {
849         return (isl_basic_set *)
850                 isl_basic_map_add_ineq((isl_basic_map *)bset, ineq);
851 }
852
853 int isl_basic_map_alloc_div(struct isl_basic_map *bmap)
854 {
855         if (!bmap)
856                 return -1;
857         isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1);
858         isl_seq_clr(bmap->div[bmap->n_div] +
859                       1 + 1 + isl_basic_map_total_dim(bmap),
860                       bmap->extra - bmap->n_div);
861         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
862         return bmap->n_div++;
863 }
864
865 int isl_basic_set_alloc_div(struct isl_basic_set *bset)
866 {
867         return isl_basic_map_alloc_div((struct isl_basic_map *)bset);
868 }
869
870 int isl_basic_map_free_div(struct isl_basic_map *bmap, unsigned n)
871 {
872         if (!bmap)
873                 return -1;
874         isl_assert(bmap->ctx, n <= bmap->n_div, return -1);
875         bmap->n_div -= n;
876         return 0;
877 }
878
879 int isl_basic_set_free_div(struct isl_basic_set *bset, unsigned n)
880 {
881         return isl_basic_map_free_div((struct isl_basic_map *)bset, n);
882 }
883
884 /* Copy constraint from src to dst, putting the vars of src at offset
885  * dim_off in dst and the divs of src at offset div_off in dst.
886  * If both sets are actually map, then dim_off applies to the input
887  * variables.
888  */
889 static void copy_constraint(struct isl_basic_map *dst_map, isl_int *dst,
890                             struct isl_basic_map *src_map, isl_int *src,
891                             unsigned in_off, unsigned out_off, unsigned div_off)
892 {
893         unsigned src_nparam = isl_basic_map_n_param(src_map);
894         unsigned dst_nparam = isl_basic_map_n_param(dst_map);
895         unsigned src_in = isl_basic_map_n_in(src_map);
896         unsigned dst_in = isl_basic_map_n_in(dst_map);
897         unsigned src_out = isl_basic_map_n_out(src_map);
898         unsigned dst_out = isl_basic_map_n_out(dst_map);
899         isl_int_set(dst[0], src[0]);
900         isl_seq_cpy(dst+1, src+1, isl_min(dst_nparam, src_nparam));
901         if (dst_nparam > src_nparam)
902                 isl_seq_clr(dst+1+src_nparam,
903                                 dst_nparam - src_nparam);
904         isl_seq_clr(dst+1+dst_nparam, in_off);
905         isl_seq_cpy(dst+1+dst_nparam+in_off,
906                     src+1+src_nparam,
907                     isl_min(dst_in-in_off, src_in));
908         if (dst_in-in_off > src_in)
909                 isl_seq_clr(dst+1+dst_nparam+in_off+src_in,
910                                 dst_in - in_off - src_in);
911         isl_seq_clr(dst+1+dst_nparam+dst_in, out_off);
912         isl_seq_cpy(dst+1+dst_nparam+dst_in+out_off,
913                     src+1+src_nparam+src_in,
914                     isl_min(dst_out-out_off, src_out));
915         if (dst_out-out_off > src_out)
916                 isl_seq_clr(dst+1+dst_nparam+dst_in+out_off+src_out,
917                                 dst_out - out_off - src_out);
918         isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out, div_off);
919         isl_seq_cpy(dst+1+dst_nparam+dst_in+dst_out+div_off,
920                     src+1+src_nparam+src_in+src_out,
921                     isl_min(dst_map->extra-div_off, src_map->n_div));
922         if (dst_map->n_div-div_off > src_map->n_div)
923                 isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out+
924                                 div_off+src_map->n_div,
925                                 dst_map->n_div - div_off - src_map->n_div);
926 }
927
928 static void copy_div(struct isl_basic_map *dst_map, isl_int *dst,
929                      struct isl_basic_map *src_map, isl_int *src,
930                      unsigned in_off, unsigned out_off, unsigned div_off)
931 {
932         isl_int_set(dst[0], src[0]);
933         copy_constraint(dst_map, dst+1, src_map, src+1, in_off, out_off, div_off);
934 }
935
936 static struct isl_basic_map *add_constraints(struct isl_basic_map *bmap1,
937                 struct isl_basic_map *bmap2, unsigned i_pos, unsigned o_pos)
938 {
939         int i;
940         unsigned div_off;
941
942         if (!bmap1 || !bmap2)
943                 goto error;
944
945         div_off = bmap1->n_div;
946
947         for (i = 0; i < bmap2->n_eq; ++i) {
948                 int i1 = isl_basic_map_alloc_equality(bmap1);
949                 if (i1 < 0)
950                         goto error;
951                 copy_constraint(bmap1, bmap1->eq[i1], bmap2, bmap2->eq[i],
952                                 i_pos, o_pos, div_off);
953         }
954
955         for (i = 0; i < bmap2->n_ineq; ++i) {
956                 int i1 = isl_basic_map_alloc_inequality(bmap1);
957                 if (i1 < 0)
958                         goto error;
959                 copy_constraint(bmap1, bmap1->ineq[i1], bmap2, bmap2->ineq[i],
960                                 i_pos, o_pos, div_off);
961         }
962
963         for (i = 0; i < bmap2->n_div; ++i) {
964                 int i1 = isl_basic_map_alloc_div(bmap1);
965                 if (i1 < 0)
966                         goto error;
967                 copy_div(bmap1, bmap1->div[i1], bmap2, bmap2->div[i],
968                          i_pos, o_pos, div_off);
969         }
970
971         isl_basic_map_free(bmap2);
972
973         return bmap1;
974
975 error:
976         isl_basic_map_free(bmap1);
977         isl_basic_map_free(bmap2);
978         return NULL;
979 }
980
981 static void copy_constraint_dim_map(isl_int *dst, isl_int *src,
982                                         struct isl_dim_map *dim_map)
983 {
984         int i;
985
986         for (i = 0; i < dim_map->len; ++i) {
987                 if (dim_map->pos[i] < 0)
988                         isl_int_set_si(dst[i], 0);
989                 else
990                         isl_int_set(dst[i], src[dim_map->pos[i]]);
991         }
992 }
993
994 static void copy_div_dim_map(isl_int *dst, isl_int *src,
995                                         struct isl_dim_map *dim_map)
996 {
997         isl_int_set(dst[0], src[0]);
998         copy_constraint_dim_map(dst+1, src+1, dim_map);
999 }
1000
1001 static struct isl_basic_map *add_constraints_dim_map(struct isl_basic_map *dst,
1002                 struct isl_basic_map *src, struct isl_dim_map *dim_map)
1003 {
1004         int i;
1005
1006         if (!src || !dst || !dim_map)
1007                 goto error;
1008
1009         for (i = 0; i < src->n_eq; ++i) {
1010                 int i1 = isl_basic_map_alloc_equality(dst);
1011                 if (i1 < 0)
1012                         goto error;
1013                 copy_constraint_dim_map(dst->eq[i1], src->eq[i], dim_map);
1014         }
1015
1016         for (i = 0; i < src->n_ineq; ++i) {
1017                 int i1 = isl_basic_map_alloc_inequality(dst);
1018                 if (i1 < 0)
1019                         goto error;
1020                 copy_constraint_dim_map(dst->ineq[i1], src->ineq[i], dim_map);
1021         }
1022
1023         for (i = 0; i < src->n_div; ++i) {
1024                 int i1 = isl_basic_map_alloc_div(dst);
1025                 if (i1 < 0)
1026                         goto error;
1027                 copy_div_dim_map(dst->div[i1], src->div[i], dim_map);
1028         }
1029
1030         free(dim_map);
1031         isl_basic_map_free(src);
1032
1033         return dst;
1034 error:
1035         free(dim_map);
1036         isl_basic_map_free(src);
1037         isl_basic_map_free(dst);
1038         return NULL;
1039 }
1040
1041 struct isl_basic_set *isl_basic_set_add_constraints(struct isl_basic_set *bset1,
1042                 struct isl_basic_set *bset2, unsigned pos)
1043 {
1044         return (struct isl_basic_set *)
1045                 add_constraints((struct isl_basic_map *)bset1,
1046                                 (struct isl_basic_map *)bset2, 0, pos);
1047 }
1048
1049 struct isl_basic_map *isl_basic_map_extend_dim(struct isl_basic_map *base,
1050                 struct isl_dim *dim, unsigned extra,
1051                 unsigned n_eq, unsigned n_ineq)
1052 {
1053         struct isl_basic_map *ext;
1054         unsigned flags;
1055         int dims_ok;
1056
1057         if (!dim)
1058                 goto error;
1059
1060         if (!base)
1061                 goto error;
1062
1063         dims_ok = isl_dim_equal(base->dim, dim) &&
1064                   base->extra >= base->n_div + extra;
1065
1066         if (dims_ok && room_for_con(base, n_eq + n_ineq) &&
1067                        room_for_ineq(base, n_ineq)) {
1068                 isl_dim_free(dim);
1069                 return base;
1070         }
1071
1072         isl_assert(base->ctx, base->dim->nparam <= dim->nparam, goto error);
1073         isl_assert(base->ctx, base->dim->n_in <= dim->n_in, goto error);
1074         isl_assert(base->ctx, base->dim->n_out <= dim->n_out, goto error);
1075         extra += base->extra;
1076         n_eq += base->n_eq;
1077         n_ineq += base->n_ineq;
1078
1079         ext = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
1080         dim = NULL;
1081         if (!ext)
1082                 goto error;
1083
1084         if (dims_ok)
1085                 ext->sample = isl_vec_copy(base->sample);
1086         flags = base->flags;
1087         ext = add_constraints(ext, base, 0, 0);
1088         if (ext) {
1089                 ext->flags = flags;
1090                 ISL_F_CLR(ext, ISL_BASIC_SET_FINAL);
1091         }
1092
1093         return ext;
1094
1095 error:
1096         isl_dim_free(dim);
1097         isl_basic_map_free(base);
1098         return NULL;
1099 }
1100
1101 struct isl_basic_set *isl_basic_set_extend_dim(struct isl_basic_set *base,
1102                 struct isl_dim *dim, unsigned extra,
1103                 unsigned n_eq, unsigned n_ineq)
1104 {
1105         return (struct isl_basic_set *)
1106                 isl_basic_map_extend_dim((struct isl_basic_map *)base, dim,
1107                                                         extra, n_eq, n_ineq);
1108 }
1109
1110 struct isl_basic_map *isl_basic_map_extend_constraints(
1111                 struct isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
1112 {
1113         if (!base)
1114                 return NULL;
1115         return isl_basic_map_extend_dim(base, isl_dim_copy(base->dim),
1116                                         0, n_eq, n_ineq);
1117 }
1118
1119 struct isl_basic_map *isl_basic_map_extend(struct isl_basic_map *base,
1120                 unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra,
1121                 unsigned n_eq, unsigned n_ineq)
1122 {
1123         struct isl_basic_map *bmap;
1124         struct isl_dim *dim;
1125
1126         if (!base)
1127                 return NULL;
1128         dim = isl_dim_alloc(base->ctx, nparam, n_in, n_out);
1129         if (!dim)
1130                 goto error;
1131
1132         bmap = isl_basic_map_extend_dim(base, dim, extra, n_eq, n_ineq);
1133         return bmap;
1134 error:
1135         isl_basic_map_free(base);
1136         return NULL;
1137 }
1138
1139 struct isl_basic_set *isl_basic_set_extend(struct isl_basic_set *base,
1140                 unsigned nparam, unsigned dim, unsigned extra,
1141                 unsigned n_eq, unsigned n_ineq)
1142 {
1143         return (struct isl_basic_set *)
1144                 isl_basic_map_extend((struct isl_basic_map *)base,
1145                                         nparam, 0, dim, extra, n_eq, n_ineq);
1146 }
1147
1148 struct isl_basic_set *isl_basic_set_extend_constraints(
1149                 struct isl_basic_set *base, unsigned n_eq, unsigned n_ineq)
1150 {
1151         return (struct isl_basic_set *)
1152                 isl_basic_map_extend_constraints((struct isl_basic_map *)base,
1153                                                     n_eq, n_ineq);
1154 }
1155
1156 struct isl_basic_set *isl_basic_set_cow(struct isl_basic_set *bset)
1157 {
1158         return (struct isl_basic_set *)
1159                 isl_basic_map_cow((struct isl_basic_map *)bset);
1160 }
1161
1162 struct isl_basic_map *isl_basic_map_cow(struct isl_basic_map *bmap)
1163 {
1164         if (!bmap)
1165                 return NULL;
1166
1167         if (bmap->ref > 1) {
1168                 bmap->ref--;
1169                 bmap = isl_basic_map_dup(bmap);
1170         }
1171         if (bmap)
1172                 ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL);
1173         return bmap;
1174 }
1175
1176 struct isl_set *isl_set_cow(struct isl_set *set)
1177 {
1178         if (!set)
1179                 return NULL;
1180
1181         if (set->ref == 1)
1182                 return set;
1183         set->ref--;
1184         return isl_set_dup(set);
1185 }
1186
1187 struct isl_map *isl_map_cow(struct isl_map *map)
1188 {
1189         if (!map)
1190                 return NULL;
1191
1192         if (map->ref == 1)
1193                 return map;
1194         map->ref--;
1195         return isl_map_dup(map);
1196 }
1197
1198 static void swap_vars(struct isl_blk blk, isl_int *a,
1199                         unsigned a_len, unsigned b_len)
1200 {
1201         isl_seq_cpy(blk.data, a+a_len, b_len);
1202         isl_seq_cpy(blk.data+b_len, a, a_len);
1203         isl_seq_cpy(a, blk.data, b_len+a_len);
1204 }
1205
1206 struct isl_basic_set *isl_basic_set_swap_vars(
1207                 struct isl_basic_set *bset, unsigned n)
1208 {
1209         int i;
1210         struct isl_blk blk;
1211         unsigned dim;
1212         unsigned nparam;
1213
1214         if (!bset)
1215                 goto error;
1216
1217         nparam = isl_basic_set_n_param(bset);
1218         dim = isl_basic_set_n_dim(bset);
1219         isl_assert(bset->ctx, n <= dim, goto error);
1220
1221         if (n == dim)
1222                 return bset;
1223
1224         bset = isl_basic_set_cow(bset);
1225         if (!bset)
1226                 return NULL;
1227
1228         blk = isl_blk_alloc(bset->ctx, dim);
1229         if (isl_blk_is_error(blk))
1230                 goto error;
1231
1232         for (i = 0; i < bset->n_eq; ++i)
1233                 swap_vars(blk,
1234                           bset->eq[i]+1+nparam, n, dim - n);
1235
1236         for (i = 0; i < bset->n_ineq; ++i)
1237                 swap_vars(blk,
1238                           bset->ineq[i]+1+nparam, n, dim - n);
1239
1240         for (i = 0; i < bset->n_div; ++i)
1241                 swap_vars(blk,
1242                           bset->div[i]+1+1+nparam, n, dim - n);
1243
1244         isl_blk_free(bset->ctx, blk);
1245
1246         ISL_F_CLR(bset, ISL_BASIC_SET_NORMALIZED);
1247         bset = isl_basic_set_gauss(bset, NULL);
1248         return isl_basic_set_finalize(bset);
1249 error:
1250         isl_basic_set_free(bset);
1251         return NULL;
1252 }
1253
1254 struct isl_set *isl_set_swap_vars(struct isl_set *set, unsigned n)
1255 {
1256         int i;
1257         set = isl_set_cow(set);
1258         if (!set)
1259                 return NULL;
1260
1261         for (i = 0; i < set->n; ++i) {
1262                 set->p[i] = isl_basic_set_swap_vars(set->p[i], n);
1263                 if (!set->p[i]) {
1264                         isl_set_free(set);
1265                         return NULL;
1266                 }
1267         }
1268         ISL_F_CLR(set, ISL_SET_NORMALIZED);
1269         return set;
1270 }
1271
1272 struct isl_basic_map *isl_basic_map_set_to_empty(struct isl_basic_map *bmap)
1273 {
1274         int i = 0;
1275         unsigned total;
1276         if (!bmap)
1277                 goto error;
1278         total = isl_basic_map_total_dim(bmap);
1279         isl_basic_map_free_div(bmap, bmap->n_div);
1280         isl_basic_map_free_inequality(bmap, bmap->n_ineq);
1281         if (bmap->n_eq > 0)
1282                 isl_basic_map_free_equality(bmap, bmap->n_eq-1);
1283         else {
1284                 i = isl_basic_map_alloc_equality(bmap);
1285                 if (i < 0)
1286                         goto error;
1287         }
1288         isl_int_set_si(bmap->eq[i][0], 1);
1289         isl_seq_clr(bmap->eq[i]+1, total);
1290         ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
1291         isl_vec_free(bmap->sample);
1292         bmap->sample = NULL;
1293         return isl_basic_map_finalize(bmap);
1294 error:
1295         isl_basic_map_free(bmap);
1296         return NULL;
1297 }
1298
1299 struct isl_basic_set *isl_basic_set_set_to_empty(struct isl_basic_set *bset)
1300 {
1301         return (struct isl_basic_set *)
1302                 isl_basic_map_set_to_empty((struct isl_basic_map *)bset);
1303 }
1304
1305 void isl_basic_map_swap_div(struct isl_basic_map *bmap, int a, int b)
1306 {
1307         int i;
1308         unsigned off = isl_dim_total(bmap->dim);
1309         isl_int *t = bmap->div[a];
1310         bmap->div[a] = bmap->div[b];
1311         bmap->div[b] = t;
1312
1313         for (i = 0; i < bmap->n_eq; ++i)
1314                 isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]);
1315
1316         for (i = 0; i < bmap->n_ineq; ++i)
1317                 isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]);
1318
1319         for (i = 0; i < bmap->n_div; ++i)
1320                 isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]);
1321         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1322 }
1323
1324 /* Eliminate the specified n dimensions starting at first from the
1325  * constraints using Fourier-Motzkin.  The dimensions themselves
1326  * are not removed.
1327  */
1328 __isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
1329         enum isl_dim_type type, unsigned first, unsigned n)
1330 {
1331         int i;
1332
1333         if (!map)
1334                 return NULL;
1335         if (n == 0)
1336                 return map;
1337
1338         map = isl_map_cow(map);
1339         if (!map)
1340                 return NULL;
1341         isl_assert(map->ctx, first + n <= isl_map_dim(map, type), goto error);
1342         first += pos(map->dim, type) - 1;
1343         
1344         for (i = 0; i < map->n; ++i) {
1345                 map->p[i] = isl_basic_map_eliminate_vars(map->p[i], first, n);
1346                 if (!map->p[i])
1347                         goto error;
1348         }
1349         return map;
1350 error:
1351         isl_map_free(map);
1352         return NULL;
1353 }
1354
1355 /* Eliminate the specified n dimensions starting at first from the
1356  * constraints using Fourier-Motzkin.  The dimensions themselves
1357  * are not removed.
1358  */
1359 __isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set,
1360         enum isl_dim_type type, unsigned first, unsigned n)
1361 {
1362         return (isl_set *)isl_map_eliminate((isl_map *)set, type, first, n);
1363 }
1364
1365 /* Eliminate the specified n dimensions starting at first from the
1366  * constraints using Fourier-Motzkin.  The dimensions themselves
1367  * are not removed.
1368  */
1369 __isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set,
1370         unsigned first, unsigned n)
1371 {
1372         return isl_set_eliminate(set, isl_dim_set, first, n);
1373 }
1374
1375 /* Project out n dimensions starting at first using Fourier-Motzkin */
1376 struct isl_set *isl_set_remove_dims(struct isl_set *set,
1377         unsigned first, unsigned n)
1378 {
1379         set = isl_set_eliminate_dims(set, first, n);
1380         set = isl_set_drop_dims(set, first, n);
1381         return set;
1382 }
1383
1384 __isl_give isl_basic_map *isl_basic_map_remove_divs(
1385         __isl_take isl_basic_map *bmap)
1386 {
1387         bmap = isl_basic_map_eliminate_vars(bmap, isl_dim_total(bmap->dim),
1388                                                 bmap->n_div);
1389         if (!bmap)
1390                 return NULL;
1391         bmap->n_div = 0;
1392         return bmap;
1393 }
1394
1395 __isl_give isl_basic_set *isl_basic_set_remove_divs(
1396         __isl_take isl_basic_set *bset)
1397 {
1398         return (struct isl_basic_set *)isl_basic_map_remove_divs(
1399                         (struct isl_basic_map *)bset);
1400 }
1401
1402 struct isl_set *isl_set_remove_divs(struct isl_set *set)
1403 {
1404         int i;
1405
1406         if (!set)
1407                 return NULL;
1408         if (set->n == 0)
1409                 return set;
1410
1411         set = isl_set_cow(set);
1412         if (!set)
1413                 return NULL;
1414         
1415         for (i = 0; i < set->n; ++i) {
1416                 set->p[i] = isl_basic_set_remove_divs(set->p[i]);
1417                 if (!set->p[i])
1418                         goto error;
1419         }
1420         return set;
1421 error:
1422         isl_set_free(set);
1423         return NULL;
1424 }
1425
1426 struct isl_basic_map *isl_basic_map_remove(struct isl_basic_map *bmap,
1427         enum isl_dim_type type, unsigned first, unsigned n)
1428 {
1429         if (!bmap)
1430                 return NULL;
1431         isl_assert(bmap->ctx, first + n <= isl_basic_map_dim(bmap, type),
1432                         goto error);
1433         if (n == 0)
1434                 return bmap;
1435         bmap = isl_basic_map_eliminate_vars(bmap,
1436                         isl_basic_map_offset(bmap, type) - 1 + first, n);
1437         if (!bmap)
1438                 return bmap;
1439         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY) && type == isl_dim_div)
1440                 return bmap;
1441         bmap = isl_basic_map_drop(bmap, type, first, n);
1442         return bmap;
1443 error:
1444         isl_basic_map_free(bmap);
1445         return NULL;
1446 }
1447
1448 __isl_give isl_basic_set *isl_basic_set_remove(__isl_take isl_basic_set *bset,
1449         enum isl_dim_type type, unsigned first, unsigned n)
1450 {
1451         return (isl_basic_set *)
1452                 isl_basic_map_remove((isl_basic_map *)bset, type, first, n);
1453 }
1454
1455 struct isl_map *isl_map_remove(struct isl_map *map,
1456         enum isl_dim_type type, unsigned first, unsigned n)
1457 {
1458         int i;
1459
1460         if (n == 0)
1461                 return map;
1462
1463         map = isl_map_cow(map);
1464         if (!map)
1465                 return NULL;
1466         isl_assert(map->ctx, first + n <= isl_map_dim(map, type), goto error);
1467         
1468         for (i = 0; i < map->n; ++i) {
1469                 map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
1470                         isl_basic_map_offset(map->p[i], type) - 1 + first, n);
1471                 if (!map->p[i])
1472                         goto error;
1473         }
1474         map = isl_map_drop(map, type, first, n);
1475         return map;
1476 error:
1477         isl_map_free(map);
1478         return NULL;
1479 }
1480
1481 __isl_give isl_set *isl_set_remove(__isl_take isl_set *bset,
1482         enum isl_dim_type type, unsigned first, unsigned n)
1483 {
1484         return (isl_set *)isl_map_remove((isl_map *)bset, type, first, n);
1485 }
1486
1487 /* Project out n inputs starting at first using Fourier-Motzkin */
1488 struct isl_map *isl_map_remove_inputs(struct isl_map *map,
1489         unsigned first, unsigned n)
1490 {
1491         return isl_map_remove(map, isl_dim_in, first, n);
1492 }
1493
1494 /* Project out n dimensions starting at first using Fourier-Motzkin */
1495 struct isl_basic_set *isl_basic_set_remove_dims(struct isl_basic_set *bset,
1496         unsigned first, unsigned n)
1497 {
1498         unsigned nparam = isl_basic_set_n_param(bset);
1499         bset = isl_basic_set_eliminate_vars(bset, nparam + first, n);
1500         bset = isl_basic_set_drop_dims(bset, first, n);
1501         return bset;
1502 }
1503
1504 static void dump_term(struct isl_basic_map *bmap,
1505                         isl_int c, int pos, FILE *out)
1506 {
1507         const char *name;
1508         unsigned in = isl_basic_map_n_in(bmap);
1509         unsigned dim = in + isl_basic_map_n_out(bmap);
1510         unsigned nparam = isl_basic_map_n_param(bmap);
1511         if (!pos)
1512                 isl_int_print(out, c, 0);
1513         else {
1514                 if (!isl_int_is_one(c))
1515                         isl_int_print(out, c, 0);
1516                 if (pos < 1 + nparam) {
1517                         name = isl_dim_get_name(bmap->dim,
1518                                                 isl_dim_param, pos - 1);
1519                         if (name)
1520                                 fprintf(out, "%s", name);
1521                         else
1522                                 fprintf(out, "p%d", pos - 1);
1523                 } else if (pos < 1 + nparam + in)
1524                         fprintf(out, "i%d", pos - 1 - nparam);
1525                 else if (pos < 1 + nparam + dim)
1526                         fprintf(out, "o%d", pos - 1 - nparam - in);
1527                 else
1528                         fprintf(out, "e%d", pos - 1 - nparam - dim);
1529         }
1530 }
1531
1532 static void dump_constraint_sign(struct isl_basic_map *bmap, isl_int *c,
1533                                 int sign, FILE *out)
1534 {
1535         int i;
1536         int first;
1537         unsigned len = 1 + isl_basic_map_total_dim(bmap);
1538         isl_int v;
1539
1540         isl_int_init(v);
1541         for (i = 0, first = 1; i < len; ++i) {
1542                 if (isl_int_sgn(c[i]) * sign <= 0)
1543                         continue;
1544                 if (!first)
1545                         fprintf(out, " + ");
1546                 first = 0;
1547                 isl_int_abs(v, c[i]);
1548                 dump_term(bmap, v, i, out);
1549         }
1550         isl_int_clear(v);
1551         if (first)
1552                 fprintf(out, "0");
1553 }
1554
1555 static void dump_constraint(struct isl_basic_map *bmap, isl_int *c,
1556                                 const char *op, FILE *out, int indent)
1557 {
1558         int i;
1559
1560         fprintf(out, "%*s", indent, "");
1561
1562         dump_constraint_sign(bmap, c, 1, out);
1563         fprintf(out, " %s ", op);
1564         dump_constraint_sign(bmap, c, -1, out);
1565
1566         fprintf(out, "\n");
1567
1568         for (i = bmap->n_div; i < bmap->extra; ++i) {
1569                 if (isl_int_is_zero(c[1+isl_dim_total(bmap->dim)+i]))
1570                         continue;
1571                 fprintf(out, "%*s", indent, "");
1572                 fprintf(out, "ERROR: unused div coefficient not zero\n");
1573                 abort();
1574         }
1575 }
1576
1577 static void dump_constraints(struct isl_basic_map *bmap,
1578                                 isl_int **c, unsigned n,
1579                                 const char *op, FILE *out, int indent)
1580 {
1581         int i;
1582
1583         for (i = 0; i < n; ++i)
1584                 dump_constraint(bmap, c[i], op, out, indent);
1585 }
1586
1587 static void dump_affine(struct isl_basic_map *bmap, isl_int *exp, FILE *out)
1588 {
1589         int j;
1590         int first = 1;
1591         unsigned total = isl_basic_map_total_dim(bmap);
1592
1593         for (j = 0; j < 1 + total; ++j) {
1594                 if (isl_int_is_zero(exp[j]))
1595                         continue;
1596                 if (!first && isl_int_is_pos(exp[j]))
1597                         fprintf(out, "+");
1598                 dump_term(bmap, exp[j], j, out);
1599                 first = 0;
1600         }
1601 }
1602
1603 static void dump(struct isl_basic_map *bmap, FILE *out, int indent)
1604 {
1605         int i;
1606
1607         dump_constraints(bmap, bmap->eq, bmap->n_eq, "=", out, indent);
1608         dump_constraints(bmap, bmap->ineq, bmap->n_ineq, ">=", out, indent);
1609
1610         for (i = 0; i < bmap->n_div; ++i) {
1611                 fprintf(out, "%*s", indent, "");
1612                 fprintf(out, "e%d = [(", i);
1613                 dump_affine(bmap, bmap->div[i]+1, out);
1614                 fprintf(out, ")/");
1615                 isl_int_print(out, bmap->div[i][0], 0);
1616                 fprintf(out, "]\n");
1617         }
1618 }
1619
1620 void isl_basic_set_dump(struct isl_basic_set *bset, FILE *out, int indent)
1621 {
1622         if (!bset) {
1623                 fprintf(out, "null basic set\n");
1624                 return;
1625         }
1626
1627         fprintf(out, "%*s", indent, "");
1628         fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
1629                         bset->ref, bset->dim->nparam, bset->dim->n_out,
1630                         bset->extra, bset->flags);
1631         dump((struct isl_basic_map *)bset, out, indent);
1632 }
1633
1634 void isl_basic_map_dump(struct isl_basic_map *bmap, FILE *out, int indent)
1635 {
1636         if (!bmap) {
1637                 fprintf(out, "null basic map\n");
1638                 return;
1639         }
1640
1641         fprintf(out, "%*s", indent, "");
1642         fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
1643                         "flags: %x, n_name: %d\n",
1644                 bmap->ref,
1645                 bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
1646                 bmap->extra, bmap->flags, bmap->dim->n_name);
1647         dump(bmap, out, indent);
1648 }
1649
1650 int isl_inequality_negate(struct isl_basic_map *bmap, unsigned pos)
1651 {
1652         unsigned total;
1653         if (!bmap)
1654                 return -1;
1655         total = isl_basic_map_total_dim(bmap);
1656         isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
1657         isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
1658         isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1);
1659         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1660         return 0;
1661 }
1662
1663 struct isl_set *isl_set_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
1664 {
1665         struct isl_set *set;
1666
1667         if (!dim)
1668                 return NULL;
1669         isl_assert(dim->ctx, dim->n_in == 0, return NULL);
1670         isl_assert(dim->ctx, n >= 0, return NULL);
1671         set = isl_alloc(dim->ctx, struct isl_set,
1672                         sizeof(struct isl_set) +
1673                         (n - 1) * sizeof(struct isl_basic_set *));
1674         if (!set)
1675                 goto error;
1676
1677         set->ctx = dim->ctx;
1678         isl_ctx_ref(set->ctx);
1679         set->ref = 1;
1680         set->size = n;
1681         set->n = 0;
1682         set->dim = dim;
1683         set->flags = flags;
1684         return set;
1685 error:
1686         isl_dim_free(dim);
1687         return NULL;
1688 }
1689
1690 struct isl_set *isl_set_alloc(struct isl_ctx *ctx,
1691                 unsigned nparam, unsigned dim, int n, unsigned flags)
1692 {
1693         struct isl_set *set;
1694         struct isl_dim *dims;
1695
1696         dims = isl_dim_alloc(ctx, nparam, 0, dim);
1697         if (!dims)
1698                 return NULL;
1699
1700         set = isl_set_alloc_dim(dims, n, flags);
1701         return set;
1702 }
1703
1704 /* Make sure "map" has room for at least "n" more basic maps.
1705  */
1706 struct isl_map *isl_map_grow(struct isl_map *map, int n)
1707 {
1708         int i;
1709         struct isl_map *grown = NULL;
1710
1711         if (!map)
1712                 return NULL;
1713         isl_assert(map->ctx, n >= 0, goto error);
1714         if (map->n + n <= map->size)
1715                 return map;
1716         grown = isl_map_alloc_dim(isl_map_get_dim(map), map->n + n, map->flags);
1717         if (!grown)
1718                 goto error;
1719         for (i = 0; i < map->n; ++i) {
1720                 grown->p[i] = isl_basic_map_copy(map->p[i]);
1721                 if (!grown->p[i])
1722                         goto error;
1723                 grown->n++;
1724         }
1725         isl_map_free(map);
1726         return grown;
1727 error:
1728         isl_map_free(grown);
1729         isl_map_free(map);
1730         return NULL;
1731 }
1732
1733 /* Make sure "set" has room for at least "n" more basic sets.
1734  */
1735 struct isl_set *isl_set_grow(struct isl_set *set, int n)
1736 {
1737         return (struct isl_set *)isl_map_grow((struct isl_map *)set, n);
1738 }
1739
1740 struct isl_set *isl_set_dup(struct isl_set *set)
1741 {
1742         int i;
1743         struct isl_set *dup;
1744
1745         if (!set)
1746                 return NULL;
1747
1748         dup = isl_set_alloc_dim(isl_dim_copy(set->dim), set->n, set->flags);
1749         if (!dup)
1750                 return NULL;
1751         for (i = 0; i < set->n; ++i)
1752                 dup = isl_set_add_basic_set(dup, isl_basic_set_copy(set->p[i]));
1753         return dup;
1754 }
1755
1756 struct isl_set *isl_set_from_basic_set(struct isl_basic_set *bset)
1757 {
1758         struct isl_set *set;
1759
1760         if (!bset)
1761                 return NULL;
1762
1763         set = isl_set_alloc_dim(isl_dim_copy(bset->dim), 1, ISL_MAP_DISJOINT);
1764         if (!set) {
1765                 isl_basic_set_free(bset);
1766                 return NULL;
1767         }
1768         return isl_set_add_basic_set(set, bset);
1769 }
1770
1771 struct isl_map *isl_map_from_basic_map(struct isl_basic_map *bmap)
1772 {
1773         struct isl_map *map;
1774
1775         if (!bmap)
1776                 return NULL;
1777
1778         map = isl_map_alloc_dim(isl_dim_copy(bmap->dim), 1, ISL_MAP_DISJOINT);
1779         if (!map) {
1780                 isl_basic_map_free(bmap);
1781                 return NULL;
1782         }
1783         return isl_map_add_basic_map(map, bmap);
1784 }
1785
1786 __isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set,
1787                                                 __isl_take isl_basic_set *bset)
1788 {
1789         return (struct isl_set *)isl_map_add_basic_map((struct isl_map *)set,
1790                                                 (struct isl_basic_map *)bset);
1791 }
1792
1793 void isl_set_free(struct isl_set *set)
1794 {
1795         int i;
1796
1797         if (!set)
1798                 return;
1799
1800         if (--set->ref > 0)
1801                 return;
1802
1803         isl_ctx_deref(set->ctx);
1804         for (i = 0; i < set->n; ++i)
1805                 isl_basic_set_free(set->p[i]);
1806         isl_dim_free(set->dim);
1807         free(set);
1808 }
1809
1810 void isl_set_dump(struct isl_set *set, FILE *out, int indent)
1811 {
1812         int i;
1813
1814         if (!set) {
1815                 fprintf(out, "null set\n");
1816                 return;
1817         }
1818
1819         fprintf(out, "%*s", indent, "");
1820         fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
1821                         set->ref, set->n, set->dim->nparam, set->dim->n_out,
1822                         set->flags);
1823         for (i = 0; i < set->n; ++i) {
1824                 fprintf(out, "%*s", indent, "");
1825                 fprintf(out, "basic set %d:\n", i);
1826                 isl_basic_set_dump(set->p[i], out, indent+4);
1827         }
1828 }
1829
1830 void isl_map_dump(struct isl_map *map, FILE *out, int indent)
1831 {
1832         int i;
1833
1834         if (!map) {
1835                 fprintf(out, "null map\n");
1836                 return;
1837         }
1838
1839         fprintf(out, "%*s", indent, "");
1840         fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
1841                      "flags: %x, n_name: %d\n",
1842                         map->ref, map->n, map->dim->nparam, map->dim->n_in,
1843                         map->dim->n_out, map->flags, map->dim->n_name);
1844         for (i = 0; i < map->n; ++i) {
1845                 fprintf(out, "%*s", indent, "");
1846                 fprintf(out, "basic map %d:\n", i);
1847                 isl_basic_map_dump(map->p[i], out, indent+4);
1848         }
1849 }
1850
1851 struct isl_basic_map *isl_basic_map_intersect_domain(
1852                 struct isl_basic_map *bmap, struct isl_basic_set *bset)
1853 {
1854         struct isl_basic_map *bmap_domain;
1855         struct isl_dim *dim;
1856
1857         if (!bmap || !bset)
1858                 goto error;
1859
1860         isl_assert(bset->ctx, isl_dim_match(bmap->dim, isl_dim_param,
1861                                         bset->dim, isl_dim_param), goto error);
1862
1863         if (isl_dim_size(bset->dim, isl_dim_set) != 0)
1864                 isl_assert(bset->ctx,
1865                     isl_basic_map_compatible_domain(bmap, bset), goto error);
1866
1867         bmap = isl_basic_map_cow(bmap);
1868         if (!bmap)
1869                 goto error;
1870         bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
1871                         bset->n_div, bset->n_eq, bset->n_ineq);
1872         dim = isl_dim_reverse(isl_dim_copy(bset->dim));
1873         bmap_domain = isl_basic_map_from_basic_set(bset, dim);
1874         bmap = add_constraints(bmap, bmap_domain, 0, 0);
1875
1876         bmap = isl_basic_map_simplify(bmap);
1877         return isl_basic_map_finalize(bmap);
1878 error:
1879         isl_basic_map_free(bmap);
1880         isl_basic_set_free(bset);
1881         return NULL;
1882 }
1883
1884 struct isl_basic_map *isl_basic_map_intersect_range(
1885                 struct isl_basic_map *bmap, struct isl_basic_set *bset)
1886 {
1887         struct isl_basic_map *bmap_range;
1888
1889         if (!bmap || !bset)
1890                 goto error;
1891
1892         isl_assert(bset->ctx, isl_dim_match(bmap->dim, isl_dim_param,
1893                                         bset->dim, isl_dim_param), goto error);
1894
1895         if (isl_dim_size(bset->dim, isl_dim_set) != 0)
1896                 isl_assert(bset->ctx,
1897                     isl_basic_map_compatible_range(bmap, bset), goto error);
1898
1899         bmap = isl_basic_map_cow(bmap);
1900         if (!bmap)
1901                 goto error;
1902         bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
1903                         bset->n_div, bset->n_eq, bset->n_ineq);
1904         bmap_range = isl_basic_map_from_basic_set(bset, isl_dim_copy(bset->dim));
1905         bmap = add_constraints(bmap, bmap_range, 0, 0);
1906
1907         bmap = isl_basic_map_simplify(bmap);
1908         return isl_basic_map_finalize(bmap);
1909 error:
1910         isl_basic_map_free(bmap);
1911         isl_basic_set_free(bset);
1912         return NULL;
1913 }
1914
1915 int isl_basic_map_contains(struct isl_basic_map *bmap, struct isl_vec *vec)
1916 {
1917         int i;
1918         unsigned total;
1919         isl_int s;
1920
1921         total = 1 + isl_basic_map_total_dim(bmap);
1922         if (total != vec->size)
1923                 return -1;
1924
1925         isl_int_init(s);
1926
1927         for (i = 0; i < bmap->n_eq; ++i) {
1928                 isl_seq_inner_product(vec->el, bmap->eq[i], total, &s);
1929                 if (!isl_int_is_zero(s)) {
1930                         isl_int_clear(s);
1931                         return 0;
1932                 }
1933         }
1934
1935         for (i = 0; i < bmap->n_ineq; ++i) {
1936                 isl_seq_inner_product(vec->el, bmap->ineq[i], total, &s);
1937                 if (isl_int_is_neg(s)) {
1938                         isl_int_clear(s);
1939                         return 0;
1940                 }
1941         }
1942
1943         isl_int_clear(s);
1944
1945         return 1;
1946 }
1947
1948 int isl_basic_set_contains(struct isl_basic_set *bset, struct isl_vec *vec)
1949 {
1950         return isl_basic_map_contains((struct isl_basic_map *)bset, vec);
1951 }
1952
1953 struct isl_basic_map *isl_basic_map_intersect(
1954                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
1955 {
1956         struct isl_vec *sample = NULL;
1957
1958         if (!bmap1 || !bmap2)
1959                 goto error;
1960
1961         isl_assert(bmap1->ctx, isl_dim_match(bmap1->dim, isl_dim_param,
1962                                      bmap2->dim, isl_dim_param), goto error);
1963         if (isl_dim_total(bmap1->dim) ==
1964                                 isl_dim_size(bmap1->dim, isl_dim_param) &&
1965             isl_dim_total(bmap2->dim) !=
1966                                 isl_dim_size(bmap2->dim, isl_dim_param))
1967                 return isl_basic_map_intersect(bmap2, bmap1);
1968
1969         if (isl_dim_total(bmap2->dim) !=
1970                                         isl_dim_size(bmap2->dim, isl_dim_param))
1971                 isl_assert(bmap1->ctx,
1972                             isl_dim_equal(bmap1->dim, bmap2->dim), goto error);
1973
1974         if (bmap1->sample &&
1975             isl_basic_map_contains(bmap1, bmap1->sample) > 0 &&
1976             isl_basic_map_contains(bmap2, bmap1->sample) > 0)
1977                 sample = isl_vec_copy(bmap1->sample);
1978         else if (bmap2->sample &&
1979             isl_basic_map_contains(bmap1, bmap2->sample) > 0 &&
1980             isl_basic_map_contains(bmap2, bmap2->sample) > 0)
1981                 sample = isl_vec_copy(bmap2->sample);
1982
1983         bmap1 = isl_basic_map_cow(bmap1);
1984         if (!bmap1)
1985                 goto error;
1986         bmap1 = isl_basic_map_extend_dim(bmap1, isl_dim_copy(bmap1->dim),
1987                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
1988         bmap1 = add_constraints(bmap1, bmap2, 0, 0);
1989
1990         if (!bmap1)
1991                 isl_vec_free(sample);
1992         else if (sample) {
1993                 isl_vec_free(bmap1->sample);
1994                 bmap1->sample = sample;
1995         }
1996
1997         bmap1 = isl_basic_map_simplify(bmap1);
1998         return isl_basic_map_finalize(bmap1);
1999 error:
2000         if (sample)
2001                 isl_vec_free(sample);
2002         isl_basic_map_free(bmap1);
2003         isl_basic_map_free(bmap2);
2004         return NULL;
2005 }
2006
2007 struct isl_basic_set *isl_basic_set_intersect(
2008                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
2009 {
2010         return (struct isl_basic_set *)
2011                 isl_basic_map_intersect(
2012                         (struct isl_basic_map *)bset1,
2013                         (struct isl_basic_map *)bset2);
2014 }
2015
2016 /* Special case of isl_map_intersect, where both map1 and map2
2017  * are convex, without any divs and such that either map1 or map2
2018  * contains a single constraint.  This constraint is then simply
2019  * added to the other map.
2020  */
2021 static __isl_give isl_map *map_intersect_add_constraint(
2022         __isl_take isl_map *map1, __isl_take isl_map *map2)
2023 {
2024         struct isl_basic_map *bmap1;
2025         struct isl_basic_map *bmap2;
2026
2027         isl_assert(map1->ctx, map1->n == 1, goto error);
2028         isl_assert(map2->ctx, map1->n == 1, goto error);
2029         isl_assert(map1->ctx, map1->p[0]->n_div == 0, goto error);
2030         isl_assert(map2->ctx, map1->p[0]->n_div == 0, goto error);
2031
2032         if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
2033                 return isl_map_intersect(map2, map1);
2034
2035         isl_assert(map2->ctx,
2036                     map2->p[0]->n_eq + map2->p[0]->n_ineq == 1, goto error);
2037
2038         map1 = isl_map_cow(map1);
2039         if (!map1)
2040                 goto error;
2041         if (isl_map_fast_is_empty(map1)) {
2042                 isl_map_free(map2);
2043                 return map1;
2044         }
2045         map1->p[0] = isl_basic_map_cow(map1->p[0]);
2046         if (map2->p[0]->n_eq == 1)
2047                 map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]);
2048         else
2049                 map1->p[0] = isl_basic_map_add_ineq(map1->p[0],
2050                                                         map2->p[0]->ineq[0]);
2051
2052         map1->p[0] = isl_basic_map_simplify(map1->p[0]);
2053         map1->p[0] = isl_basic_map_finalize(map1->p[0]);
2054         if (!map1->p[0])
2055                 goto error;
2056
2057         if (isl_basic_map_fast_is_empty(map1->p[0])) {
2058                 isl_basic_map_free(map1->p[0]);
2059                 map1->n = 0;
2060         }
2061
2062         isl_map_free(map2);
2063
2064         return map1;
2065 error:
2066         isl_map_free(map1);
2067         isl_map_free(map2);
2068         return NULL;
2069 }
2070
2071 struct isl_map *isl_map_intersect(struct isl_map *map1, struct isl_map *map2)
2072 {
2073         unsigned flags = 0;
2074         struct isl_map *result;
2075         int i, j;
2076
2077         if (!map1 || !map2)
2078                 goto error;
2079
2080         if (isl_map_fast_is_empty(map1)) {
2081                 isl_map_free(map2);
2082                 return map1;
2083         }
2084         if (isl_map_fast_is_empty(map2)) {
2085                 isl_map_free(map1);
2086                 return map2;
2087         }
2088
2089         if (map1->n == 1 && map2->n == 1 &&
2090             map1->p[0]->n_div == 0 && map2->p[0]->n_div == 0 &&
2091             isl_dim_equal(map1->dim, map2->dim) &&
2092             (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
2093              map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
2094                 return map_intersect_add_constraint(map1, map2);
2095         isl_assert(map1->ctx, isl_dim_match(map1->dim, isl_dim_param,
2096                                          map2->dim, isl_dim_param), goto error);
2097         if (isl_dim_total(map1->dim) ==
2098                                 isl_dim_size(map1->dim, isl_dim_param) &&
2099             isl_dim_total(map2->dim) != isl_dim_size(map2->dim, isl_dim_param))
2100                 return isl_map_intersect(map2, map1);
2101
2102         if (isl_dim_total(map2->dim) != isl_dim_size(map2->dim, isl_dim_param))
2103                 isl_assert(map1->ctx,
2104                             isl_dim_equal(map1->dim, map2->dim), goto error);
2105
2106         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
2107             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
2108                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
2109
2110         result = isl_map_alloc_dim(isl_dim_copy(map1->dim),
2111                                 map1->n * map2->n, flags);
2112         if (!result)
2113                 goto error;
2114         for (i = 0; i < map1->n; ++i)
2115                 for (j = 0; j < map2->n; ++j) {
2116                         struct isl_basic_map *part;
2117                         part = isl_basic_map_intersect(
2118                                     isl_basic_map_copy(map1->p[i]),
2119                                     isl_basic_map_copy(map2->p[j]));
2120                         if (isl_basic_map_is_empty(part))
2121                                 isl_basic_map_free(part);
2122                         else
2123                                 result = isl_map_add_basic_map(result, part);
2124                         if (!result)
2125                                 goto error;
2126                 }
2127         isl_map_free(map1);
2128         isl_map_free(map2);
2129         return result;
2130 error:
2131         isl_map_free(map1);
2132         isl_map_free(map2);
2133         return NULL;
2134 }
2135
2136 struct isl_set *isl_set_intersect(struct isl_set *set1, struct isl_set *set2)
2137 {
2138         return (struct isl_set *)
2139                 isl_map_intersect((struct isl_map *)set1,
2140                                   (struct isl_map *)set2);
2141 }
2142
2143 struct isl_basic_map *isl_basic_map_reverse(struct isl_basic_map *bmap)
2144 {
2145         struct isl_dim *dim;
2146         struct isl_basic_set *bset;
2147         unsigned in;
2148
2149         if (!bmap)
2150                 return NULL;
2151         bmap = isl_basic_map_cow(bmap);
2152         if (!bmap)
2153                 return NULL;
2154         dim = isl_dim_reverse(isl_dim_copy(bmap->dim));
2155         in = isl_basic_map_n_in(bmap);
2156         bset = isl_basic_set_from_basic_map(bmap);
2157         bset = isl_basic_set_swap_vars(bset, in);
2158         return isl_basic_map_from_basic_set(bset, dim);
2159 }
2160
2161 __isl_give isl_basic_map *isl_basic_map_insert(__isl_take isl_basic_map *bmap,
2162                 enum isl_dim_type type, unsigned pos, unsigned n)
2163 {
2164         struct isl_dim *res_dim;
2165         struct isl_basic_map *res;
2166         struct isl_dim_map *dim_map;
2167         unsigned total, off;
2168         enum isl_dim_type t;
2169
2170         if (n == 0)
2171                 return bmap;
2172
2173         if (!bmap)
2174                 return NULL;
2175
2176         res_dim = isl_dim_insert(isl_basic_map_get_dim(bmap), type, pos, n);
2177
2178         total = isl_basic_map_total_dim(bmap) + n;
2179         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2180         off = 0;
2181         for (t = isl_dim_param; t <= isl_dim_out; ++t) {
2182                 if (t != type) {
2183                         isl_dim_map_dim(dim_map, bmap->dim, t, off);
2184                 } else {
2185                         unsigned size = isl_basic_map_dim(bmap, t);
2186                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2187                                                 0, pos, off);
2188                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2189                                                 pos, size - pos, off + pos + n);
2190                 }
2191                 off += isl_dim_size(res_dim, t);
2192         }
2193         isl_dim_map_div(dim_map, bmap, off);
2194
2195         res = isl_basic_map_alloc_dim(res_dim,
2196                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
2197         res = add_constraints_dim_map(res, bmap, dim_map);
2198         res = isl_basic_map_simplify(res);
2199         return isl_basic_map_finalize(res);
2200 }
2201
2202 __isl_give isl_basic_map *isl_basic_map_add(__isl_take isl_basic_map *bmap,
2203                 enum isl_dim_type type, unsigned n)
2204 {
2205         if (!bmap)
2206                 return NULL;
2207         return isl_basic_map_insert(bmap, type,
2208                                         isl_basic_map_dim(bmap, type), n);
2209 }
2210
2211 __isl_give isl_basic_set *isl_basic_set_add(__isl_take isl_basic_set *bset,
2212                 enum isl_dim_type type, unsigned n)
2213 {
2214         if (!bset)
2215                 return NULL;
2216         isl_assert(bset->ctx, type != isl_dim_in, goto error);
2217         return (isl_basic_set *)isl_basic_map_add((isl_basic_map *)bset, type, n);
2218 error:
2219         isl_basic_set_free(bset);
2220         return NULL;
2221 }
2222
2223 __isl_give isl_map *isl_map_insert(__isl_take isl_map *map,
2224                 enum isl_dim_type type, unsigned pos, unsigned n)
2225 {
2226         int i;
2227
2228         if (n == 0)
2229                 return map;
2230
2231         map = isl_map_cow(map);
2232         if (!map)
2233                 return NULL;
2234
2235         map->dim = isl_dim_insert(map->dim, type, pos, n);
2236         if (!map->dim)
2237                 goto error;
2238
2239         for (i = 0; i < map->n; ++i) {
2240                 map->p[i] = isl_basic_map_insert(map->p[i], type, pos, n);
2241                 if (!map->p[i])
2242                         goto error;
2243         }
2244
2245         return map;
2246 error:
2247         isl_map_free(map);
2248         return NULL;
2249 }
2250
2251 __isl_give isl_set *isl_set_insert(__isl_take isl_set *set,
2252                 enum isl_dim_type type, unsigned pos, unsigned n)
2253 {
2254         return (isl_set *)isl_map_insert((isl_map *)set, type, pos, n);
2255 }
2256
2257 __isl_give isl_map *isl_map_add(__isl_take isl_map *map,
2258                 enum isl_dim_type type, unsigned n)
2259 {
2260         if (!map)
2261                 return NULL;
2262         return isl_map_insert(map, type, isl_map_dim(map, type), n);
2263 }
2264
2265 __isl_give isl_set *isl_set_add(__isl_take isl_set *set,
2266                 enum isl_dim_type type, unsigned n)
2267 {
2268         if (!set)
2269                 return NULL;
2270         isl_assert(set->ctx, type != isl_dim_in, goto error);
2271         return (isl_set *)isl_map_add((isl_map *)set, type, n);
2272 error:
2273         isl_set_free(set);
2274         return NULL;
2275 }
2276
2277 __isl_give isl_basic_map *isl_basic_map_move_dims(
2278         __isl_take isl_basic_map *bmap,
2279         enum isl_dim_type dst_type, unsigned dst_pos,
2280         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2281 {
2282         int i;
2283         struct isl_dim_map *dim_map;
2284         struct isl_basic_map *res;
2285         enum isl_dim_type t;
2286         unsigned total, off;
2287
2288         if (!bmap)
2289                 return NULL;
2290         if (n == 0)
2291                 return bmap;
2292
2293         isl_assert(bmap->ctx, src_pos + n <= isl_basic_map_dim(bmap, src_type),
2294                 goto error);
2295
2296         if (dst_type == src_type && dst_pos == src_pos)
2297                 return bmap;
2298
2299         isl_assert(bmap->ctx, dst_type != src_type, goto error);
2300
2301         if (pos(bmap->dim, dst_type) + dst_pos ==
2302             pos(bmap->dim, src_type) + src_pos +
2303                                             ((src_type < dst_type) ? n : 0)) {
2304                 bmap = isl_basic_map_cow(bmap);
2305                 if (!bmap)
2306                         return NULL;
2307
2308                 bmap->dim = isl_dim_move(bmap->dim, dst_type, dst_pos,
2309                                                 src_type, src_pos, n);
2310                 if (!bmap->dim)
2311                         goto error;
2312
2313                 bmap = isl_basic_map_finalize(bmap);
2314
2315                 return bmap;
2316         }
2317
2318         total = isl_basic_map_total_dim(bmap);
2319         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2320
2321         off = 0;
2322         for (t = isl_dim_param; t <= isl_dim_out; ++t) {
2323                 unsigned size = isl_dim_size(bmap->dim, t);
2324                 if (t == dst_type) {
2325                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2326                                             0, dst_pos, off);
2327                         off += dst_pos;
2328                         isl_dim_map_dim_range(dim_map, bmap->dim, src_type,
2329                                             src_pos, n, off);
2330                         off += n;
2331                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2332                                             dst_pos, size - dst_pos, off);
2333                         off += size - dst_pos;
2334                 } else if (t == src_type) {
2335                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2336                                             0, src_pos, off);
2337                         off += src_pos;
2338                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2339                                         src_pos + n, size - src_pos - n, off);
2340                         off += size - src_pos - n;
2341                 } else {
2342                         isl_dim_map_dim(dim_map, bmap->dim, t, off);
2343                         off += size;
2344                 }
2345         }
2346         isl_dim_map_div(dim_map, bmap, off);
2347
2348         res = isl_basic_map_alloc_dim(isl_basic_map_get_dim(bmap),
2349                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
2350         bmap = add_constraints_dim_map(res, bmap, dim_map);
2351
2352         bmap->dim = isl_dim_move(bmap->dim, dst_type, dst_pos,
2353                                         src_type, src_pos, n);
2354         if (!bmap->dim)
2355                 goto error;
2356
2357         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
2358         bmap = isl_basic_map_gauss(bmap, NULL);
2359         bmap = isl_basic_map_finalize(bmap);
2360
2361         return bmap;
2362 error:
2363         isl_basic_map_free(bmap);
2364         return NULL;
2365 }
2366
2367 __isl_give isl_basic_set *isl_basic_set_move_dims(__isl_take isl_basic_set *bset,
2368         enum isl_dim_type dst_type, unsigned dst_pos,
2369         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2370 {
2371         return (isl_basic_set *)isl_basic_map_move_dims(
2372                 (isl_basic_map *)bset, dst_type, dst_pos, src_type, src_pos, n);
2373 }
2374
2375 __isl_give isl_set *isl_set_move_dims(__isl_take isl_set *set,
2376         enum isl_dim_type dst_type, unsigned dst_pos,
2377         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2378 {
2379         if (!set)
2380                 return NULL;
2381         isl_assert(set->ctx, dst_type != isl_dim_in, goto error);
2382         return (isl_set *)isl_map_move_dims((isl_map *)set, dst_type, dst_pos,
2383                                         src_type, src_pos, n);
2384 error:
2385         isl_set_free(set);
2386         return NULL;
2387 }
2388
2389 __isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
2390         enum isl_dim_type dst_type, unsigned dst_pos,
2391         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2392 {
2393         int i;
2394
2395         if (!map)
2396                 return NULL;
2397         if (n == 0)
2398                 return map;
2399
2400         isl_assert(map->ctx, src_pos + n <= isl_map_dim(map, src_type),
2401                 goto error);
2402
2403         if (dst_type == src_type && dst_pos == src_pos)
2404                 return map;
2405
2406         isl_assert(map->ctx, dst_type != src_type, goto error);
2407
2408         map = isl_map_cow(map);
2409         if (!map)
2410                 return NULL;
2411
2412         map->dim = isl_dim_move(map->dim, dst_type, dst_pos, src_type, src_pos, n);
2413         if (!map->dim)
2414                 goto error;
2415
2416         for (i = 0; i < map->n; ++i) {
2417                 map->p[i] = isl_basic_map_move_dims(map->p[i],
2418                                                 dst_type, dst_pos,
2419                                                 src_type, src_pos, n);
2420                 if (!map->p[i])
2421                         goto error;
2422         }
2423
2424         return map;
2425 error:
2426         isl_map_free(map);
2427         return NULL;
2428 }
2429
2430 /* Move the specified dimensions to the last columns right before
2431  * the divs.  Don't change the dimension specification of bmap.
2432  * That's the responsibility of the caller.
2433  */
2434 static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
2435         enum isl_dim_type type, unsigned first, unsigned n)
2436 {
2437         struct isl_dim_map *dim_map;
2438         struct isl_basic_map *res;
2439         enum isl_dim_type t;
2440         unsigned total, off;
2441
2442         if (!bmap)
2443                 return NULL;
2444         if (pos(bmap->dim, type) + first + n == 1 + isl_dim_total(bmap->dim))
2445                 return bmap;
2446
2447         total = isl_basic_map_total_dim(bmap);
2448         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2449
2450         off = 0;
2451         for (t = isl_dim_param; t <= isl_dim_out; ++t) {
2452                 unsigned size = isl_dim_size(bmap->dim, t);
2453                 if (t == type) {
2454                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2455                                             0, first, off);
2456                         off += first;
2457                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2458                                             first, n, total - bmap->n_div - n);
2459                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2460                                             first + n, size - (first + n), off);
2461                         off += size - (first + n);
2462                 } else {
2463                         isl_dim_map_dim(dim_map, bmap->dim, t, off);
2464                         off += size;
2465                 }
2466         }
2467         isl_dim_map_div(dim_map, bmap, off + n);
2468
2469         res = isl_basic_map_alloc_dim(isl_basic_map_get_dim(bmap),
2470                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
2471         res = add_constraints_dim_map(res, bmap, dim_map);
2472         return res;
2473 }
2474
2475 /* Turn the n dimensions of type type, starting at first
2476  * into existentially quantified variables.
2477  */
2478 __isl_give isl_basic_map *isl_basic_map_project_out(
2479                 __isl_take isl_basic_map *bmap,
2480                 enum isl_dim_type type, unsigned first, unsigned n)
2481 {
2482         int i;
2483         size_t row_size;
2484         isl_int **new_div;
2485         isl_int *old;
2486
2487         if (n == 0)
2488                 return bmap;
2489
2490         if (!bmap)
2491                 return NULL;
2492
2493         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
2494                 return isl_basic_map_remove(bmap, type, first, n);
2495
2496         isl_assert(bmap->ctx, first + n <= isl_basic_map_dim(bmap, type),
2497                         goto error);
2498
2499         bmap = move_last(bmap, type, first, n);
2500         bmap = isl_basic_map_cow(bmap);
2501         if (!bmap)
2502                 return NULL;
2503
2504         row_size = 1 + isl_dim_total(bmap->dim) + bmap->extra;
2505         old = bmap->block2.data;
2506         bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
2507                                         (bmap->extra + n) * (1 + row_size));
2508         if (!bmap->block2.data)
2509                 goto error;
2510         new_div = isl_alloc_array(bmap->ctx, isl_int *, bmap->extra + n);
2511         if (!new_div)
2512                 goto error;
2513         for (i = 0; i < n; ++i) {
2514                 new_div[i] = bmap->block2.data +
2515                                 (bmap->extra + i) * (1 + row_size);
2516                 isl_seq_clr(new_div[i], 1 + row_size);
2517         }
2518         for (i = 0; i < bmap->extra; ++i)
2519                 new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
2520         free(bmap->div);
2521         bmap->div = new_div;
2522         bmap->n_div += n;
2523         bmap->extra += n;
2524
2525         bmap->dim = isl_dim_drop(bmap->dim, type, first, n);
2526         if (!bmap->dim)
2527                 goto error;
2528         bmap = isl_basic_map_simplify(bmap);
2529         bmap = isl_basic_map_drop_redundant_divs(bmap);
2530         return isl_basic_map_finalize(bmap);
2531 error:
2532         isl_basic_map_free(bmap);
2533         return NULL;
2534 }
2535
2536 /* Turn the n dimensions of type type, starting at first
2537  * into existentially quantified variables.
2538  */
2539 struct isl_basic_set *isl_basic_set_project_out(struct isl_basic_set *bset,
2540                 enum isl_dim_type type, unsigned first, unsigned n)
2541 {
2542         return (isl_basic_set *)isl_basic_map_project_out(
2543                         (isl_basic_map *)bset, type, first, n);
2544 }
2545
2546 /* Turn the n dimensions of type type, starting at first
2547  * into existentially quantified variables.
2548  */
2549 __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
2550                 enum isl_dim_type type, unsigned first, unsigned n)
2551 {
2552         int i;
2553
2554         if (!map)
2555                 return NULL;
2556
2557         if (n == 0)
2558                 return map;
2559
2560         isl_assert(map->ctx, first + n <= isl_map_dim(map, type), goto error);
2561
2562         map = isl_map_cow(map);
2563         if (!map)
2564                 return NULL;
2565
2566         map->dim = isl_dim_drop(map->dim, type, first, n);
2567         if (!map->dim)
2568                 goto error;
2569
2570         for (i = 0; i < map->n; ++i) {
2571                 map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
2572                 if (!map->p[i])
2573                         goto error;
2574         }
2575
2576         return map;
2577 error:
2578         isl_map_free(map);
2579         return NULL;
2580 }
2581
2582 /* Turn the n dimensions of type type, starting at first
2583  * into existentially quantified variables.
2584  */
2585 __isl_give isl_set *isl_set_project_out(__isl_take isl_set *set,
2586                 enum isl_dim_type type, unsigned first, unsigned n)
2587 {
2588         return (isl_set *)isl_map_project_out((isl_map *)set, type, first, n);
2589 }
2590
2591 static struct isl_basic_map *add_divs(struct isl_basic_map *bmap, unsigned n)
2592 {
2593         int i, j;
2594
2595         for (i = 0; i < n; ++i) {
2596                 j = isl_basic_map_alloc_div(bmap);
2597                 if (j < 0)
2598                         goto error;
2599                 isl_seq_clr(bmap->div[j], 1+1+isl_basic_map_total_dim(bmap));
2600         }
2601         return bmap;
2602 error:
2603         isl_basic_map_free(bmap);
2604         return NULL;
2605 }
2606
2607 struct isl_basic_map *isl_basic_map_apply_range(
2608                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
2609 {
2610         struct isl_dim *dim_result = NULL;
2611         struct isl_basic_map *bmap;
2612         unsigned n_in, n_out, n, nparam, total, pos;
2613         struct isl_dim_map *dim_map1, *dim_map2;
2614
2615         if (!bmap1 || !bmap2)
2616                 goto error;
2617
2618         dim_result = isl_dim_join(isl_dim_copy(bmap1->dim),
2619                                   isl_dim_copy(bmap2->dim));
2620
2621         n_in = isl_basic_map_n_in(bmap1);
2622         n_out = isl_basic_map_n_out(bmap2);
2623         n = isl_basic_map_n_out(bmap1);
2624         nparam = isl_basic_map_n_param(bmap1);
2625
2626         total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
2627         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
2628         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
2629         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
2630         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
2631         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
2632         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
2633         isl_dim_map_div(dim_map1, bmap1, pos += n_out);
2634         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
2635         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
2636         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
2637
2638         bmap = isl_basic_map_alloc_dim(dim_result,
2639                         bmap1->n_div + bmap2->n_div + n,
2640                         bmap1->n_eq + bmap2->n_eq,
2641                         bmap1->n_ineq + bmap2->n_ineq);
2642         bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
2643         bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
2644         bmap = add_divs(bmap, n);
2645         bmap = isl_basic_map_simplify(bmap);
2646         bmap = isl_basic_map_drop_redundant_divs(bmap);
2647         return isl_basic_map_finalize(bmap);
2648 error:
2649         isl_basic_map_free(bmap1);
2650         isl_basic_map_free(bmap2);
2651         return NULL;
2652 }
2653
2654 struct isl_basic_set *isl_basic_set_apply(
2655                 struct isl_basic_set *bset, struct isl_basic_map *bmap)
2656 {
2657         if (!bset || !bmap)
2658                 goto error;
2659
2660         isl_assert(bset->ctx, isl_basic_map_compatible_domain(bmap, bset),
2661                     goto error);
2662
2663         return (struct isl_basic_set *)
2664                 isl_basic_map_apply_range((struct isl_basic_map *)bset, bmap);
2665 error:
2666         isl_basic_set_free(bset);
2667         isl_basic_map_free(bmap);
2668         return NULL;
2669 }
2670
2671 struct isl_basic_map *isl_basic_map_apply_domain(
2672                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
2673 {
2674         if (!bmap1 || !bmap2)
2675                 goto error;
2676
2677         isl_assert(bmap1->ctx,
2678             isl_basic_map_n_in(bmap1) == isl_basic_map_n_in(bmap2), goto error);
2679         isl_assert(bmap1->ctx,
2680             isl_basic_map_n_param(bmap1) == isl_basic_map_n_param(bmap2),
2681             goto error);
2682
2683         bmap1 = isl_basic_map_reverse(bmap1);
2684         bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
2685         return isl_basic_map_reverse(bmap1);
2686 error:
2687         isl_basic_map_free(bmap1);
2688         isl_basic_map_free(bmap2);
2689         return NULL;
2690 }
2691
2692 /* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
2693  * A \cap B -> f(A) + f(B)
2694  */
2695 struct isl_basic_map *isl_basic_map_sum(
2696                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
2697 {
2698         unsigned n_in, n_out, nparam, total, pos;
2699         struct isl_basic_map *bmap = NULL;
2700         struct isl_dim_map *dim_map1, *dim_map2;
2701         int i;
2702
2703         if (!bmap1 || !bmap2)
2704                 goto error;
2705
2706         isl_assert(bmap1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim),
2707                 goto error);
2708
2709         nparam = isl_basic_map_n_param(bmap1);
2710         n_in = isl_basic_map_n_in(bmap1);
2711         n_out = isl_basic_map_n_out(bmap1);
2712
2713         total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
2714         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
2715         dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
2716         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
2717         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
2718         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
2719         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
2720         isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
2721         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
2722         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
2723         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
2724
2725         bmap = isl_basic_map_alloc_dim(isl_dim_copy(bmap1->dim),
2726                         bmap1->n_div + bmap2->n_div + 2 * n_out,
2727                         bmap1->n_eq + bmap2->n_eq + n_out,
2728                         bmap1->n_ineq + bmap2->n_ineq);
2729         for (i = 0; i < n_out; ++i) {
2730                 int j = isl_basic_map_alloc_equality(bmap);
2731                 if (j < 0)
2732                         goto error;
2733                 isl_seq_clr(bmap->eq[j], 1+total);
2734                 isl_int_set_si(bmap->eq[j][1+nparam+n_in+i], -1);
2735                 isl_int_set_si(bmap->eq[j][1+pos+i], 1);
2736                 isl_int_set_si(bmap->eq[j][1+pos-n_out+i], 1);
2737         }
2738         bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
2739         bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
2740         bmap = add_divs(bmap, 2 * n_out);
2741
2742         bmap = isl_basic_map_simplify(bmap);
2743         return isl_basic_map_finalize(bmap);
2744 error:
2745         isl_basic_map_free(bmap);
2746         isl_basic_map_free(bmap1);
2747         isl_basic_map_free(bmap2);
2748         return NULL;
2749 }
2750
2751 /* Given two maps A -> f(A) and B -> g(B), construct a map
2752  * A \cap B -> f(A) + f(B)
2753  */
2754 struct isl_map *isl_map_sum(struct isl_map *map1, struct isl_map *map2)
2755 {
2756         struct isl_map *result;
2757         int i, j;
2758
2759         if (!map1 || !map2)
2760                 goto error;
2761
2762         isl_assert(map1->ctx, isl_dim_equal(map1->dim, map2->dim), goto error);
2763
2764         result = isl_map_alloc_dim(isl_dim_copy(map1->dim),
2765                                 map1->n * map2->n, 0);
2766         if (!result)
2767                 goto error;
2768         for (i = 0; i < map1->n; ++i)
2769                 for (j = 0; j < map2->n; ++j) {
2770                         struct isl_basic_map *part;
2771                         part = isl_basic_map_sum(
2772                                     isl_basic_map_copy(map1->p[i]),
2773                                     isl_basic_map_copy(map2->p[j]));
2774                         if (isl_basic_map_is_empty(part))
2775                                 isl_basic_map_free(part);
2776                         else
2777                                 result = isl_map_add_basic_map(result, part);
2778                         if (!result)
2779                                 goto error;
2780                 }
2781         isl_map_free(map1);
2782         isl_map_free(map2);
2783         return result;
2784 error:
2785         isl_map_free(map1);
2786         isl_map_free(map2);
2787         return NULL;
2788 }
2789
2790 __isl_give isl_set *isl_set_sum(__isl_take isl_set *set1,
2791         __isl_take isl_set *set2)
2792 {
2793         return (isl_set *)isl_map_sum((isl_map *)set1, (isl_map *)set2);
2794 }
2795
2796 /* Given a basic map A -> f(A), construct A -> -f(A).
2797  */
2798 struct isl_basic_map *isl_basic_map_neg(struct isl_basic_map *bmap)
2799 {
2800         int i, j;
2801         unsigned off, n;
2802
2803         bmap = isl_basic_map_cow(bmap);
2804         if (!bmap)
2805                 return NULL;
2806
2807         n = isl_basic_map_dim(bmap, isl_dim_out);
2808         off = isl_basic_map_offset(bmap, isl_dim_out);
2809         for (i = 0; i < bmap->n_eq; ++i)
2810                 for (j = 0; j < n; ++j)
2811                         isl_int_neg(bmap->eq[i][off+j], bmap->eq[i][off+j]);
2812         for (i = 0; i < bmap->n_ineq; ++i)
2813                 for (j = 0; j < n; ++j)
2814                         isl_int_neg(bmap->ineq[i][off+j], bmap->ineq[i][off+j]);
2815         for (i = 0; i < bmap->n_div; ++i)
2816                 for (j = 0; j < n; ++j)
2817                         isl_int_neg(bmap->div[i][1+off+j], bmap->div[i][1+off+j]);
2818         return isl_basic_map_finalize(bmap);
2819 }
2820
2821 /* Given a map A -> f(A), construct A -> -f(A).
2822  */
2823 struct isl_map *isl_map_neg(struct isl_map *map)
2824 {
2825         int i;
2826
2827         map = isl_map_cow(map);
2828         if (!map)
2829                 return NULL;
2830
2831         for (i = 0; i < map->n; ++i) {
2832                 map->p[i] = isl_basic_map_neg(map->p[i]);
2833                 if (!map->p[i])
2834                         goto error;
2835         }
2836
2837         return map;
2838 error:
2839         isl_map_free(map);
2840         return NULL;
2841 }
2842
2843 __isl_give isl_set *isl_set_neg(__isl_take isl_set *set)
2844 {
2845         return (isl_set *)isl_map_neg((isl_map *)set);
2846 }
2847
2848 /* Given a basic map A -> f(A) and an integer d, construct a basic map
2849  * A -> floor(f(A)/d).
2850  */
2851 struct isl_basic_map *isl_basic_map_floordiv(struct isl_basic_map *bmap,
2852                 isl_int d)
2853 {
2854         unsigned n_in, n_out, nparam, total, pos;
2855         struct isl_basic_map *result = NULL;
2856         struct isl_dim_map *dim_map;
2857         int i;
2858
2859         if (!bmap)
2860                 return NULL;
2861
2862         nparam = isl_basic_map_n_param(bmap);
2863         n_in = isl_basic_map_n_in(bmap);
2864         n_out = isl_basic_map_n_out(bmap);
2865
2866         total = nparam + n_in + n_out + bmap->n_div + n_out;
2867         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2868         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
2869         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
2870         isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
2871         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
2872
2873         result = isl_basic_map_alloc_dim(isl_dim_copy(bmap->dim),
2874                         bmap->n_div + n_out,
2875                         bmap->n_eq, bmap->n_ineq + 2 * n_out);
2876         result = add_constraints_dim_map(result, bmap, dim_map);
2877         result = add_divs(result, n_out);
2878         for (i = 0; i < n_out; ++i) {
2879                 int j;
2880                 j = isl_basic_map_alloc_inequality(result);
2881                 if (j < 0)
2882                         goto error;
2883                 isl_seq_clr(result->ineq[j], 1+total);
2884                 isl_int_neg(result->ineq[j][1+nparam+n_in+i], d);
2885                 isl_int_set_si(result->ineq[j][1+pos+i], 1);
2886                 j = isl_basic_map_alloc_inequality(result);
2887                 if (j < 0)
2888                         goto error;
2889                 isl_seq_clr(result->ineq[j], 1+total);
2890                 isl_int_set(result->ineq[j][1+nparam+n_in+i], d);
2891                 isl_int_set_si(result->ineq[j][1+pos+i], -1);
2892                 isl_int_sub_ui(result->ineq[j][0], d, 1);
2893         }
2894
2895         result = isl_basic_map_simplify(result);
2896         return isl_basic_map_finalize(result);
2897 error:
2898         isl_basic_map_free(result);
2899         return NULL;
2900 }
2901
2902 /* Given a map A -> f(A) and an integer d, construct a map
2903  * A -> floor(f(A)/d).
2904  */
2905 struct isl_map *isl_map_floordiv(struct isl_map *map, isl_int d)
2906 {
2907         int i;
2908
2909         map = isl_map_cow(map);
2910         if (!map)
2911                 return NULL;
2912
2913         ISL_F_CLR(map, ISL_MAP_DISJOINT);
2914         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
2915         for (i = 0; i < map->n; ++i) {
2916                 map->p[i] = isl_basic_map_floordiv(map->p[i], d);
2917                 if (!map->p[i])
2918                         goto error;
2919         }
2920
2921         return map;
2922 error:
2923         isl_map_free(map);
2924         return NULL;
2925 }
2926
2927 static struct isl_basic_map *var_equal(struct isl_basic_map *bmap, unsigned pos)
2928 {
2929         int i;
2930         unsigned nparam;
2931         unsigned n_in;
2932
2933         i = isl_basic_map_alloc_equality(bmap);
2934         if (i < 0)
2935                 goto error;
2936         nparam = isl_basic_map_n_param(bmap);
2937         n_in = isl_basic_map_n_in(bmap);
2938         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
2939         isl_int_set_si(bmap->eq[i][1+nparam+pos], -1);
2940         isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1);
2941         return isl_basic_map_finalize(bmap);
2942 error:
2943         isl_basic_map_free(bmap);
2944         return NULL;
2945 }
2946
2947 /* Add a constraints to "bmap" expressing i_pos < o_pos
2948  */
2949 static struct isl_basic_map *var_less(struct isl_basic_map *bmap, unsigned pos)
2950 {
2951         int i;
2952         unsigned nparam;
2953         unsigned n_in;
2954
2955         i = isl_basic_map_alloc_inequality(bmap);
2956         if (i < 0)
2957                 goto error;
2958         nparam = isl_basic_map_n_param(bmap);
2959         n_in = isl_basic_map_n_in(bmap);
2960         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
2961         isl_int_set_si(bmap->ineq[i][0], -1);
2962         isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
2963         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
2964         return isl_basic_map_finalize(bmap);
2965 error:
2966         isl_basic_map_free(bmap);
2967         return NULL;
2968 }
2969
2970 /* Add a constraint to "bmap" expressing i_pos <= o_pos
2971  */
2972 static __isl_give isl_basic_map *var_less_or_equal(
2973         __isl_take isl_basic_map *bmap, unsigned pos)
2974 {
2975         int i;
2976         unsigned nparam;
2977         unsigned n_in;
2978
2979         i = isl_basic_map_alloc_inequality(bmap);
2980         if (i < 0)
2981                 goto error;
2982         nparam = isl_basic_map_n_param(bmap);
2983         n_in = isl_basic_map_n_in(bmap);
2984         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
2985         isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
2986         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
2987         return isl_basic_map_finalize(bmap);
2988 error:
2989         isl_basic_map_free(bmap);
2990         return NULL;
2991 }
2992
2993 /* Add a constraints to "bmap" expressing i_pos > o_pos
2994  */
2995 static struct isl_basic_map *var_more(struct isl_basic_map *bmap, unsigned pos)
2996 {
2997         int i;
2998         unsigned nparam;
2999         unsigned n_in;
3000
3001         i = isl_basic_map_alloc_inequality(bmap);
3002         if (i < 0)
3003                 goto error;
3004         nparam = isl_basic_map_n_param(bmap);
3005         n_in = isl_basic_map_n_in(bmap);
3006         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
3007         isl_int_set_si(bmap->ineq[i][0], -1);
3008         isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
3009         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
3010         return isl_basic_map_finalize(bmap);
3011 error:
3012         isl_basic_map_free(bmap);
3013         return NULL;
3014 }
3015
3016 /* Add a constraint to "bmap" expressing i_pos >= o_pos
3017  */
3018 static __isl_give isl_basic_map *var_more_or_equal(
3019         __isl_take isl_basic_map *bmap, unsigned pos)
3020 {
3021         int i;
3022         unsigned nparam;
3023         unsigned n_in;
3024
3025         i = isl_basic_map_alloc_inequality(bmap);
3026         if (i < 0)
3027                 goto error;
3028         nparam = isl_basic_map_n_param(bmap);
3029         n_in = isl_basic_map_n_in(bmap);
3030         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
3031         isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
3032         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
3033         return isl_basic_map_finalize(bmap);
3034 error:
3035         isl_basic_map_free(bmap);
3036         return NULL;
3037 }
3038
3039 struct isl_basic_map *isl_basic_map_equal(struct isl_dim *dim, unsigned n_equal)
3040 {
3041         int i;
3042         struct isl_basic_map *bmap;
3043         bmap = isl_basic_map_alloc_dim(dim, 0, n_equal, 0);
3044         if (!bmap)
3045                 return NULL;
3046         for (i = 0; i < n_equal && bmap; ++i)
3047                 bmap = var_equal(bmap, i);
3048         return isl_basic_map_finalize(bmap);
3049 }
3050
3051 /* Return a relation on of dimension "dim" expressing i_[0..pos] << o_[0..pos]
3052  */
3053 struct isl_basic_map *isl_basic_map_less_at(struct isl_dim *dim, unsigned pos)
3054 {
3055         int i;
3056         struct isl_basic_map *bmap;
3057         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
3058         if (!bmap)
3059                 return NULL;
3060         for (i = 0; i < pos && bmap; ++i)
3061                 bmap = var_equal(bmap, i);
3062         if (bmap)
3063                 bmap = var_less(bmap, pos);
3064         return isl_basic_map_finalize(bmap);
3065 }
3066
3067 /* Return a relation on of dimension "dim" expressing i_[0..pos] <<= o_[0..pos]
3068  */
3069 __isl_give isl_basic_map *isl_basic_map_less_or_equal_at(
3070         __isl_take isl_dim *dim, unsigned pos)
3071 {
3072         int i;
3073         isl_basic_map *bmap;
3074
3075         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
3076         for (i = 0; i < pos; ++i)
3077                 bmap = var_equal(bmap, i);
3078         bmap = var_less_or_equal(bmap, pos);
3079         return isl_basic_map_finalize(bmap);
3080 }
3081
3082 /* Return a relation on pairs of sets of dimension "dim" expressing i_pos > o_pos
3083  */
3084 struct isl_basic_map *isl_basic_map_more_at(struct isl_dim *dim, unsigned pos)
3085 {
3086         int i;
3087         struct isl_basic_map *bmap;
3088         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
3089         if (!bmap)
3090                 return NULL;
3091         for (i = 0; i < pos && bmap; ++i)
3092                 bmap = var_equal(bmap, i);
3093         if (bmap)
3094                 bmap = var_more(bmap, pos);
3095         return isl_basic_map_finalize(bmap);
3096 }
3097
3098 /* Return a relation on of dimension "dim" expressing i_[0..pos] >>= o_[0..pos]
3099  */
3100 __isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
3101         __isl_take isl_dim *dim, unsigned pos)
3102 {
3103         int i;
3104         isl_basic_map *bmap;
3105
3106         bmap = isl_basic_map_alloc_dim(dim, 0, pos, 1);
3107         for (i = 0; i < pos; ++i)
3108                 bmap = var_equal(bmap, i);
3109         bmap = var_more_or_equal(bmap, pos);
3110         return isl_basic_map_finalize(bmap);
3111 }
3112
3113 static __isl_give isl_map *map_lex_lte_first(__isl_take isl_dim *dims,
3114         unsigned n, int equal)
3115 {
3116         struct isl_map *map;
3117         int i;
3118
3119         if (n == 0 && equal)
3120                 return isl_map_universe(dims);
3121
3122         map = isl_map_alloc_dim(isl_dim_copy(dims), n, ISL_MAP_DISJOINT);
3123
3124         for (i = 0; i + 1 < n; ++i)
3125                 map = isl_map_add_basic_map(map,
3126                                   isl_basic_map_less_at(isl_dim_copy(dims), i));
3127         if (n > 0) {
3128                 if (equal)
3129                         map = isl_map_add_basic_map(map,
3130                               isl_basic_map_less_or_equal_at(dims, n - 1));
3131                 else
3132                         map = isl_map_add_basic_map(map,
3133                               isl_basic_map_less_at(dims, n - 1));
3134         } else
3135                 isl_dim_free(dims);
3136
3137         return map;
3138 }
3139
3140 static __isl_give isl_map *map_lex_lte(__isl_take isl_dim *dims, int equal)
3141 {
3142         if (!dims)
3143                 return NULL;
3144         return map_lex_lte_first(dims, dims->n_out, equal);
3145 }
3146
3147 __isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_dim *dim, unsigned n)
3148 {
3149         return map_lex_lte_first(dim, n, 0);
3150 }
3151
3152 __isl_give isl_map *isl_map_lex_le_first(__isl_take isl_dim *dim, unsigned n)
3153 {
3154         return map_lex_lte_first(dim, n, 1);
3155 }
3156
3157 __isl_give isl_map *isl_map_lex_lt(__isl_take isl_dim *set_dim)
3158 {
3159         return map_lex_lte(isl_dim_map(set_dim), 0);
3160 }
3161
3162 __isl_give isl_map *isl_map_lex_le(__isl_take isl_dim *set_dim)
3163 {
3164         return map_lex_lte(isl_dim_map(set_dim), 1);
3165 }
3166
3167 static __isl_give isl_map *map_lex_gte_first(__isl_take isl_dim *dims,
3168         unsigned n, int equal)
3169 {
3170         struct isl_map *map;
3171         int i;
3172
3173         if (n == 0 && equal)
3174                 return isl_map_universe(dims);
3175
3176         map = isl_map_alloc_dim(isl_dim_copy(dims), n, ISL_MAP_DISJOINT);
3177
3178         for (i = 0; i + 1 < n; ++i)
3179                 map = isl_map_add_basic_map(map,
3180                                   isl_basic_map_more_at(isl_dim_copy(dims), i));
3181         if (n > 0) {
3182                 if (equal)
3183                         map = isl_map_add_basic_map(map,
3184                               isl_basic_map_more_or_equal_at(dims, n - 1));
3185                 else
3186                         map = isl_map_add_basic_map(map,
3187                               isl_basic_map_more_at(dims, n - 1));
3188         } else
3189                 isl_dim_free(dims);
3190
3191         return map;
3192 }
3193
3194 static __isl_give isl_map *map_lex_gte(__isl_take isl_dim *dims, int equal)
3195 {
3196         if (!dims)
3197                 return NULL;
3198         return map_lex_gte_first(dims, dims->n_out, equal);
3199 }
3200
3201 __isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_dim *dim, unsigned n)
3202 {
3203         return map_lex_gte_first(dim, n, 0);
3204 }
3205
3206 __isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_dim *dim, unsigned n)
3207 {
3208         return map_lex_gte_first(dim, n, 1);
3209 }
3210
3211 __isl_give isl_map *isl_map_lex_gt(__isl_take isl_dim *set_dim)
3212 {
3213         return map_lex_gte(isl_dim_map(set_dim), 0);
3214 }
3215
3216 __isl_give isl_map *isl_map_lex_ge(__isl_take isl_dim *set_dim)
3217 {
3218         return map_lex_gte(isl_dim_map(set_dim), 1);
3219 }
3220
3221 __isl_give isl_map *isl_set_lex_le_set(__isl_take isl_set *set1,
3222         __isl_take isl_set *set2)
3223 {
3224         isl_map *map;
3225         map = isl_map_lex_le(isl_set_get_dim(set1));
3226         map = isl_map_intersect_domain(map, set1);
3227         map = isl_map_intersect_range(map, set2);
3228         return map;
3229 }
3230
3231 __isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_set *set1,
3232         __isl_take isl_set *set2)
3233 {
3234         isl_map *map;
3235         map = isl_map_lex_lt(isl_set_get_dim(set1));
3236         map = isl_map_intersect_domain(map, set1);
3237         map = isl_map_intersect_range(map, set2);
3238         return map;
3239 }
3240
3241 __isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_set *set1,
3242         __isl_take isl_set *set2)
3243 {
3244         isl_map *map;
3245         map = isl_map_lex_ge(isl_set_get_dim(set1));
3246         map = isl_map_intersect_domain(map, set1);
3247         map = isl_map_intersect_range(map, set2);
3248         return map;
3249 }
3250
3251 __isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_set *set1,
3252         __isl_take isl_set *set2)
3253 {
3254         isl_map *map;
3255         map = isl_map_lex_gt(isl_set_get_dim(set1));
3256         map = isl_map_intersect_domain(map, set1);
3257         map = isl_map_intersect_range(map, set2);
3258         return map;
3259 }
3260
3261 __isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
3262         __isl_take isl_map *map2)
3263 {
3264         isl_map *map;
3265         map = isl_map_lex_le(isl_dim_range(isl_map_get_dim(map1)));
3266         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3267         map = isl_map_apply_range(map, isl_map_reverse(map2));
3268         return map;
3269 }
3270
3271 __isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
3272         __isl_take isl_map *map2)
3273 {
3274         isl_map *map;
3275         map = isl_map_lex_lt(isl_dim_range(isl_map_get_dim(map1)));
3276         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3277         map = isl_map_apply_range(map, isl_map_reverse(map2));
3278         return map;
3279 }
3280
3281 __isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
3282         __isl_take isl_map *map2)
3283 {
3284         isl_map *map;
3285         map = isl_map_lex_ge(isl_dim_range(isl_map_get_dim(map1)));
3286         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3287         map = isl_map_apply_range(map, isl_map_reverse(map2));
3288         return map;
3289 }
3290
3291 __isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
3292         __isl_take isl_map *map2)
3293 {
3294         isl_map *map;
3295         map = isl_map_lex_gt(isl_dim_range(isl_map_get_dim(map1)));
3296         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3297         map = isl_map_apply_range(map, isl_map_reverse(map2));
3298         return map;
3299 }
3300
3301 struct isl_basic_map *isl_basic_map_from_basic_set(
3302                 struct isl_basic_set *bset, struct isl_dim *dim)
3303 {
3304         struct isl_basic_map *bmap;
3305
3306         bset = isl_basic_set_cow(bset);
3307         if (!bset || !dim)
3308                 goto error;
3309
3310         isl_assert(bset->ctx, isl_dim_compatible(bset->dim, dim), goto error);
3311         isl_dim_free(bset->dim);
3312         bmap = (struct isl_basic_map *) bset;
3313         bmap->dim = dim;
3314         return isl_basic_map_finalize(bmap);
3315 error:
3316         isl_basic_set_free(bset);
3317         isl_dim_free(dim);
3318         return NULL;
3319 }
3320
3321 struct isl_basic_set *isl_basic_set_from_basic_map(struct isl_basic_map *bmap)
3322 {
3323         if (!bmap)
3324                 goto error;
3325         if (bmap->dim->n_in == 0)
3326                 return (struct isl_basic_set *)bmap;
3327         bmap = isl_basic_map_cow(bmap);
3328         if (!bmap)
3329                 goto error;
3330         bmap->dim = isl_dim_as_set_dim(bmap->dim);
3331         if (!bmap->dim)
3332                 goto error;
3333         bmap = isl_basic_map_finalize(bmap);
3334         return (struct isl_basic_set *)bmap;
3335 error:
3336         isl_basic_map_free(bmap);
3337         return NULL;
3338 }
3339
3340 /* For a div d = floor(f/m), add the constraints
3341  *
3342  *              f - m d >= 0
3343  *              -(f-(n-1)) + m d >= 0
3344  *
3345  * Note that the second constraint is the negation of
3346  *
3347  *              f - m d >= n
3348  */
3349 int isl_basic_map_add_div_constraints_var(__isl_keep isl_basic_map *bmap,
3350         unsigned pos, isl_int *div)
3351 {
3352         int i, j;
3353         unsigned total = isl_basic_map_total_dim(bmap);
3354
3355         i = isl_basic_map_alloc_inequality(bmap);
3356         if (i < 0)
3357                 return -1;
3358         isl_seq_cpy(bmap->ineq[i], div + 1, 1 + total);
3359         isl_int_neg(bmap->ineq[i][1 + pos], div[0]);
3360
3361         j = isl_basic_map_alloc_inequality(bmap);
3362         if (j < 0)
3363                 return -1;
3364         isl_seq_neg(bmap->ineq[j], bmap->ineq[i], 1 + total);
3365         isl_int_add(bmap->ineq[j][0], bmap->ineq[j][0], bmap->ineq[j][1 + pos]);
3366         isl_int_sub_ui(bmap->ineq[j][0], bmap->ineq[j][0], 1);
3367         return j;
3368 }
3369
3370 int isl_basic_set_add_div_constraints_var(__isl_keep isl_basic_set *bset,
3371         unsigned pos, isl_int *div)
3372 {
3373         return isl_basic_map_add_div_constraints_var((isl_basic_map *)bset,
3374                                                         pos, div);
3375 }
3376
3377 int isl_basic_map_add_div_constraints(struct isl_basic_map *bmap, unsigned div)
3378 {
3379         unsigned total = isl_basic_map_total_dim(bmap);
3380         unsigned div_pos = total - bmap->n_div + div;
3381
3382         return isl_basic_map_add_div_constraints_var(bmap, div_pos,
3383                                                         bmap->div[div]);
3384 }
3385
3386 struct isl_basic_set *isl_basic_map_underlying_set(
3387                 struct isl_basic_map *bmap)
3388 {
3389         if (!bmap)
3390                 goto error;
3391         if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
3392             bmap->n_div == 0 && !isl_dim_get_tuple_name(bmap->dim, isl_dim_out))
3393                 return (struct isl_basic_set *)bmap;
3394         bmap = isl_basic_map_cow(bmap);
3395         if (!bmap)
3396                 goto error;
3397         bmap->dim = isl_dim_underlying(bmap->dim, bmap->n_div);
3398         if (!bmap->dim)
3399                 goto error;
3400         bmap->extra -= bmap->n_div;
3401         bmap->n_div = 0;
3402         bmap = isl_basic_map_finalize(bmap);
3403         return (struct isl_basic_set *)bmap;
3404 error:
3405         return NULL;
3406 }
3407
3408 __isl_give isl_basic_set *isl_basic_set_underlying_set(
3409                 __isl_take isl_basic_set *bset)
3410 {
3411         return isl_basic_map_underlying_set((isl_basic_map *)bset);
3412 }
3413
3414 struct isl_basic_map *isl_basic_map_overlying_set(
3415         struct isl_basic_set *bset, struct isl_basic_map *like)
3416 {
3417         struct isl_basic_map *bmap;
3418         struct isl_ctx *ctx;
3419         unsigned total;
3420         int i;
3421
3422         if (!bset || !like)
3423                 goto error;
3424         ctx = bset->ctx;
3425         isl_assert(ctx, bset->n_div == 0, goto error);
3426         isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error);
3427         isl_assert(ctx, bset->dim->n_out == isl_basic_map_total_dim(like),
3428                         goto error);
3429         if (isl_dim_equal(bset->dim, like->dim) && like->n_div == 0) {
3430                 isl_basic_map_free(like);
3431                 return (struct isl_basic_map *)bset;
3432         }
3433         bset = isl_basic_set_cow(bset);
3434         if (!bset)
3435                 goto error;
3436         total = bset->dim->n_out + bset->extra;
3437         bmap = (struct isl_basic_map *)bset;
3438         isl_dim_free(bmap->dim);
3439         bmap->dim = isl_dim_copy(like->dim);
3440         if (!bmap->dim)
3441                 goto error;
3442         bmap->n_div = like->n_div;
3443         bmap->extra += like->n_div;
3444         if (bmap->extra) {
3445                 unsigned ltotal;
3446                 ltotal = total - bmap->extra + like->extra;
3447                 if (ltotal > total)
3448                         ltotal = total;
3449                 bmap->block2 = isl_blk_extend(ctx, bmap->block2,
3450                                         bmap->extra * (1 + 1 + total));
3451                 if (isl_blk_is_error(bmap->block2))
3452                         goto error;
3453                 bmap->div = isl_realloc_array(ctx, bmap->div, isl_int *,
3454                                                 bmap->extra);
3455                 if (!bmap->div)
3456                         goto error;
3457                 for (i = 0; i < bmap->extra; ++i)
3458                         bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
3459                 for (i = 0; i < like->n_div; ++i) {
3460                         isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
3461                         isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
3462                 }
3463                 bmap = isl_basic_map_extend_constraints(bmap, 
3464                                                         0, 2 * like->n_div);
3465                 for (i = 0; i < like->n_div; ++i) {
3466                         if (isl_int_is_zero(bmap->div[i][0]))
3467                                 continue;
3468                         if (isl_basic_map_add_div_constraints(bmap, i) < 0)
3469                                 goto error;
3470                 }
3471         }
3472         isl_basic_map_free(like);
3473         bmap = isl_basic_map_simplify(bmap);
3474         bmap = isl_basic_map_finalize(bmap);
3475         return bmap;
3476 error:
3477         isl_basic_map_free(like);
3478         isl_basic_set_free(bset);
3479         return NULL;
3480 }
3481
3482 struct isl_basic_set *isl_basic_set_from_underlying_set(
3483         struct isl_basic_set *bset, struct isl_basic_set *like)
3484 {
3485         return (struct isl_basic_set *)
3486                 isl_basic_map_overlying_set(bset, (struct isl_basic_map *)like);
3487 }
3488
3489 struct isl_set *isl_set_from_underlying_set(
3490         struct isl_set *set, struct isl_basic_set *like)
3491 {
3492         int i;
3493
3494         if (!set || !like)
3495                 goto error;
3496         isl_assert(set->ctx, set->dim->n_out == isl_basic_set_total_dim(like),
3497                     goto error);
3498         if (isl_dim_equal(set->dim, like->dim) && like->n_div == 0) {
3499                 isl_basic_set_free(like);
3500                 return set;
3501         }
3502         set = isl_set_cow(set);
3503         if (!set)
3504                 goto error;
3505         for (i = 0; i < set->n; ++i) {
3506                 set->p[i] = isl_basic_set_from_underlying_set(set->p[i],
3507                                                       isl_basic_set_copy(like));
3508                 if (!set->p[i])
3509                         goto error;
3510         }
3511         isl_dim_free(set->dim);
3512         set->dim = isl_dim_copy(like->dim);
3513         if (!set->dim)
3514                 goto error;
3515         isl_basic_set_free(like);
3516         return set;
3517 error:
3518         isl_basic_set_free(like);
3519         isl_set_free(set);
3520         return NULL;
3521 }
3522
3523 struct isl_set *isl_map_underlying_set(struct isl_map *map)
3524 {
3525         int i;
3526
3527         map = isl_map_cow(map);
3528         if (!map)
3529                 return NULL;
3530         map->dim = isl_dim_cow(map->dim);
3531         if (!map->dim)
3532                 goto error;
3533
3534         for (i = 1; i < map->n; ++i)
3535                 isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,
3536                                 goto error);
3537         for (i = 0; i < map->n; ++i) {
3538                 map->p[i] = (struct isl_basic_map *)
3539                                 isl_basic_map_underlying_set(map->p[i]);
3540                 if (!map->p[i])
3541                         goto error;
3542         }
3543         if (map->n == 0)
3544                 map->dim = isl_dim_underlying(map->dim, 0);
3545         else {
3546                 isl_dim_free(map->dim);
3547                 map->dim = isl_dim_copy(map->p[0]->dim);
3548         }
3549         if (!map->dim)
3550                 goto error;
3551         return (struct isl_set *)map;
3552 error:
3553         isl_map_free(map);
3554         return NULL;
3555 }
3556
3557 struct isl_set *isl_set_to_underlying_set(struct isl_set *set)
3558 {
3559         return (struct isl_set *)isl_map_underlying_set((struct isl_map *)set);
3560 }
3561
3562 static __isl_give isl_basic_map *isl_basic_map_reset_dim(
3563         __isl_take isl_basic_map *bmap, __isl_take isl_dim *dim)
3564 {
3565         bmap = isl_basic_map_cow(bmap);
3566         if (!bmap || !dim)
3567                 goto error;
3568
3569         isl_dim_free(bmap->dim);
3570         bmap->dim = dim;
3571
3572         bmap = isl_basic_map_finalize(bmap);
3573
3574         return bmap;
3575 error:
3576         isl_basic_map_free(bmap);
3577         isl_dim_free(dim);
3578         return NULL;
3579 }
3580
3581 static __isl_give isl_basic_set *isl_basic_set_reset_dim(
3582         __isl_take isl_basic_set *bset, __isl_take isl_dim *dim)
3583 {
3584         return (isl_basic_set *)isl_basic_map_reset_dim((isl_basic_map *)bset,
3585                                                         dim);
3586 }
3587
3588 __isl_give isl_map *isl_map_reset_dim(__isl_take isl_map *map,
3589         __isl_take isl_dim *dim)
3590 {
3591         int i;
3592
3593         map = isl_map_cow(map);
3594         if (!map || !dim)
3595                 goto error;
3596
3597         for (i = 0; i < map->n; ++i) {
3598                 map->p[i] = isl_basic_map_reset_dim(map->p[i],
3599                                                     isl_dim_copy(dim));
3600                 if (!map->p[i])
3601                         goto error;
3602         }
3603         isl_dim_free(map->dim);
3604         map->dim = dim;
3605
3606         return map;
3607 error:
3608         isl_map_free(map);
3609         isl_dim_free(dim);
3610         return NULL;
3611 }
3612
3613 __isl_give isl_set *isl_set_reset_dim(__isl_take isl_set *set,
3614         __isl_take isl_dim *dim)
3615 {
3616         return (struct isl_set *) isl_map_reset_dim((struct isl_map *)set, dim);
3617 }
3618
3619 struct isl_basic_set *isl_basic_map_domain(struct isl_basic_map *bmap)
3620 {
3621         isl_dim *dim;
3622         struct isl_basic_set *domain;
3623         unsigned n_in;
3624         unsigned n_out;
3625
3626         if (!bmap)
3627                 return NULL;
3628         dim = isl_dim_domain(isl_basic_map_get_dim(bmap));
3629
3630         n_in = isl_basic_map_n_in(bmap);
3631         n_out = isl_basic_map_n_out(bmap);
3632         domain = isl_basic_set_from_basic_map(bmap);
3633         domain = isl_basic_set_project_out(domain, isl_dim_set, n_in, n_out);
3634
3635         domain = isl_basic_set_reset_dim(domain, dim);
3636
3637         return domain;
3638 }
3639
3640 struct isl_basic_set *isl_basic_map_range(struct isl_basic_map *bmap)
3641 {
3642         return isl_basic_map_domain(isl_basic_map_reverse(bmap));
3643 }
3644
3645 __isl_give isl_basic_map *isl_basic_map_domain_map(
3646         __isl_take isl_basic_map *bmap)
3647 {
3648         int i, k;
3649         isl_dim *dim;
3650         isl_basic_map *domain;
3651         isl_basic_set *bset;
3652         int nparam, n_in, n_out;
3653         unsigned total;
3654
3655         nparam = isl_basic_map_dim(bmap, isl_dim_param);
3656         n_in = isl_basic_map_dim(bmap, isl_dim_in);
3657         n_out = isl_basic_map_dim(bmap, isl_dim_out);
3658
3659         dim = isl_dim_from_range(isl_dim_domain(isl_basic_map_get_dim(bmap)));
3660         domain = isl_basic_map_universe(dim);
3661
3662         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
3663         bmap = isl_basic_map_apply_range(bmap, domain);
3664         bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
3665
3666         total = isl_basic_map_total_dim(bmap);
3667
3668         for (i = 0; i < n_in; ++i) {
3669                 k = isl_basic_map_alloc_equality(bmap);
3670                 if (k < 0)
3671                         goto error;
3672                 isl_seq_clr(bmap->eq[k], 1 + total);
3673                 isl_int_set_si(bmap->eq[k][1 + nparam + i], -1);
3674                 isl_int_set_si(bmap->eq[k][1 + nparam + n_in + n_out + i], 1);
3675         }
3676
3677         bmap = isl_basic_map_gauss(bmap, NULL);
3678         return isl_basic_map_finalize(bmap);
3679 error:
3680         isl_basic_map_free(bmap);
3681         return NULL;
3682 }
3683
3684 __isl_give isl_basic_map *isl_basic_map_range_map(
3685         __isl_take isl_basic_map *bmap)
3686 {
3687         int i, k;
3688         isl_dim *dim;
3689         isl_basic_map *range;
3690         isl_basic_set *bset;
3691         int nparam, n_in, n_out;
3692         unsigned total;
3693
3694         nparam = isl_basic_map_dim(bmap, isl_dim_param);
3695         n_in = isl_basic_map_dim(bmap, isl_dim_in);
3696         n_out = isl_basic_map_dim(bmap, isl_dim_out);
3697
3698         dim = isl_dim_from_range(isl_dim_range(isl_basic_map_get_dim(bmap)));
3699         range = isl_basic_map_universe(dim);
3700
3701         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
3702         bmap = isl_basic_map_apply_range(bmap, range);
3703         bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
3704
3705         total = isl_basic_map_total_dim(bmap);
3706
3707         for (i = 0; i < n_out; ++i) {
3708                 k = isl_basic_map_alloc_equality(bmap);
3709                 if (k < 0)
3710                         goto error;
3711                 isl_seq_clr(bmap->eq[k], 1 + total);
3712                 isl_int_set_si(bmap->eq[k][1 + nparam + n_in + i], -1);
3713                 isl_int_set_si(bmap->eq[k][1 + nparam + n_in + n_out + i], 1);
3714         }
3715
3716         bmap = isl_basic_map_gauss(bmap, NULL);
3717         return isl_basic_map_finalize(bmap);
3718 error:
3719         isl_basic_map_free(bmap);
3720         return NULL;
3721 }
3722
3723 struct isl_set *isl_map_range(struct isl_map *map)
3724 {
3725         int i;
3726         struct isl_set *set;
3727
3728         if (!map)
3729                 goto error;
3730         if (isl_map_dim(map, isl_dim_in) == 0)
3731                 return (isl_set *)map;
3732
3733         map = isl_map_cow(map);
3734         if (!map)
3735                 goto error;
3736
3737         set = (struct isl_set *) map;
3738         set->dim = isl_dim_drop_inputs(set->dim, 0, set->dim->n_in);
3739         if (!set->dim)
3740                 goto error;
3741         for (i = 0; i < map->n; ++i) {
3742                 set->p[i] = isl_basic_map_range(map->p[i]);
3743                 if (!set->p[i])
3744                         goto error;
3745         }
3746         ISL_F_CLR(set, ISL_MAP_DISJOINT);
3747         ISL_F_CLR(set, ISL_SET_NORMALIZED);
3748         return set;
3749 error:
3750         isl_map_free(map);
3751         return NULL;
3752 }
3753
3754 __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
3755 {
3756         int i;
3757         isl_dim *domain_dim;
3758
3759         map = isl_map_cow(map);
3760         if (!map)
3761                 return NULL;
3762
3763         domain_dim = isl_dim_from_range(isl_dim_domain(isl_map_get_dim(map)));
3764         map->dim = isl_dim_from_domain(isl_dim_wrap(map->dim));
3765         map->dim = isl_dim_join(map->dim, domain_dim);
3766         if (!map->dim)
3767                 goto error;
3768         for (i = 0; i < map->n; ++i) {
3769                 map->p[i] = isl_basic_map_domain_map(map->p[i]);
3770                 if (!map->p[i])
3771                         goto error;
3772         }
3773         ISL_F_CLR(map, ISL_MAP_DISJOINT);
3774         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
3775         return map;
3776 error:
3777         isl_map_free(map);
3778         return NULL;
3779 }
3780
3781 __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
3782 {
3783         int i;
3784         isl_dim *range_dim;
3785
3786         map = isl_map_cow(map);
3787         if (!map)
3788                 return NULL;
3789
3790         range_dim = isl_dim_range(isl_map_get_dim(map));
3791         map->dim = isl_dim_from_domain(isl_dim_wrap(map->dim));
3792         map->dim = isl_dim_join(map->dim, range_dim);
3793         if (!map->dim)
3794                 goto error;
3795         for (i = 0; i < map->n; ++i) {
3796                 map->p[i] = isl_basic_map_range_map(map->p[i]);
3797                 if (!map->p[i])
3798                         goto error;
3799         }
3800         ISL_F_CLR(map, ISL_MAP_DISJOINT);
3801         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
3802         return map;
3803 error:
3804         isl_map_free(map);
3805         return NULL;
3806 }
3807
3808 struct isl_map *isl_map_from_set(struct isl_set *set, struct isl_dim *dim)
3809 {
3810         int i;
3811         struct isl_map *map = NULL;
3812
3813         set = isl_set_cow(set);
3814         if (!set || !dim)
3815                 goto error;
3816         isl_assert(set->ctx, isl_dim_compatible(set->dim, dim), goto error);
3817         map = (struct isl_map *)set;
3818         for (i = 0; i < set->n; ++i) {
3819                 map->p[i] = isl_basic_map_from_basic_set(
3820                                 set->p[i], isl_dim_copy(dim));
3821                 if (!map->p[i])
3822                         goto error;
3823         }
3824         isl_dim_free(map->dim);
3825         map->dim = dim;
3826         return map;
3827 error:
3828         isl_dim_free(dim);
3829         isl_set_free(set);
3830         return NULL;
3831 }
3832
3833 __isl_give isl_basic_map *isl_basic_map_from_domain(
3834         __isl_take isl_basic_set *bset)
3835 {
3836         return isl_basic_map_reverse(isl_basic_map_from_range(bset));
3837 }
3838
3839 __isl_give isl_basic_map *isl_basic_map_from_range(
3840         __isl_take isl_basic_set *bset)
3841 {
3842         return (isl_basic_map *)bset;
3843 }
3844
3845 struct isl_map *isl_map_from_range(struct isl_set *set)
3846 {
3847         return (struct isl_map *)set;
3848 }
3849
3850 __isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set)
3851 {
3852         return isl_map_reverse(isl_map_from_range(set));
3853 }
3854
3855 __isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain,
3856         __isl_take isl_set *range)
3857 {
3858         return isl_map_apply_range(isl_map_from_domain(domain),
3859                                    isl_map_from_range(range));
3860 }
3861
3862 struct isl_set *isl_set_from_map(struct isl_map *map)
3863 {
3864         int i;
3865         struct isl_set *set = NULL;
3866
3867         if (!map)
3868                 return NULL;
3869         map = isl_map_cow(map);
3870         if (!map)
3871                 return NULL;
3872         map->dim = isl_dim_as_set_dim(map->dim);
3873         if (!map->dim)
3874                 goto error;
3875         set = (struct isl_set *)map;
3876         for (i = 0; i < map->n; ++i) {
3877                 set->p[i] = isl_basic_set_from_basic_map(map->p[i]);
3878                 if (!set->p[i])
3879                         goto error;
3880         }
3881         return set;
3882 error:
3883         isl_map_free(map);
3884         return NULL;
3885 }
3886
3887 struct isl_map *isl_map_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
3888 {
3889         struct isl_map *map;
3890
3891         if (!dim)
3892                 return NULL;
3893         isl_assert(dim->ctx, n >= 0, return NULL);
3894         map = isl_alloc(dim->ctx, struct isl_map,
3895                         sizeof(struct isl_map) +
3896                         (n - 1) * sizeof(struct isl_basic_map *));
3897         if (!map)
3898                 goto error;
3899
3900         map->ctx = dim->ctx;
3901         isl_ctx_ref(map->ctx);
3902         map->ref = 1;
3903         map->size = n;
3904         map->n = 0;
3905         map->dim = dim;
3906         map->flags = flags;
3907         return map;
3908 error:
3909         isl_dim_free(dim);
3910         return NULL;
3911 }
3912
3913 struct isl_map *isl_map_alloc(struct isl_ctx *ctx,
3914                 unsigned nparam, unsigned in, unsigned out, int n,
3915                 unsigned flags)
3916 {
3917         struct isl_map *map;
3918         struct isl_dim *dims;
3919
3920         dims = isl_dim_alloc(ctx, nparam, in, out);
3921         if (!dims)
3922                 return NULL;
3923
3924         map = isl_map_alloc_dim(dims, n, flags);
3925         return map;
3926 }
3927
3928 struct isl_basic_map *isl_basic_map_empty(struct isl_dim *dim)
3929 {
3930         struct isl_basic_map *bmap;
3931         bmap = isl_basic_map_alloc_dim(dim, 0, 1, 0);
3932         bmap = isl_basic_map_set_to_empty(bmap);
3933         return bmap;
3934 }
3935
3936 struct isl_basic_set *isl_basic_set_empty(struct isl_dim *dim)
3937 {
3938         struct isl_basic_set *bset;
3939         bset = isl_basic_set_alloc_dim(dim, 0, 1, 0);
3940         bset = isl_basic_set_set_to_empty(bset);
3941         return bset;
3942 }
3943
3944 struct isl_basic_map *isl_basic_map_empty_like(struct isl_basic_map *model)
3945 {
3946         struct isl_basic_map *bmap;
3947         if (!model)
3948                 return NULL;
3949         bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
3950         bmap = isl_basic_map_set_to_empty(bmap);
3951         return bmap;
3952 }
3953
3954 struct isl_basic_map *isl_basic_map_empty_like_map(struct isl_map *model)
3955 {
3956         struct isl_basic_map *bmap;
3957         if (!model)
3958                 return NULL;
3959         bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
3960         bmap = isl_basic_map_set_to_empty(bmap);
3961         return bmap;
3962 }
3963
3964 struct isl_basic_set *isl_basic_set_empty_like(struct isl_basic_set *model)
3965 {
3966         struct isl_basic_set *bset;
3967         if (!model)
3968                 return NULL;
3969         bset = isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
3970         bset = isl_basic_set_set_to_empty(bset);
3971         return bset;
3972 }
3973
3974 struct isl_basic_map *isl_basic_map_universe(struct isl_dim *dim)
3975 {
3976         struct isl_basic_map *bmap;
3977         bmap = isl_basic_map_alloc_dim(dim, 0, 0, 0);
3978         return bmap;
3979 }
3980
3981 struct isl_basic_set *isl_basic_set_universe(struct isl_dim *dim)
3982 {
3983         struct isl_basic_set *bset;
3984         bset = isl_basic_set_alloc_dim(dim, 0, 0, 0);
3985         return bset;
3986 }
3987
3988 __isl_give isl_basic_map *isl_basic_map_universe_like(
3989                 __isl_keep isl_basic_map *model)
3990 {
3991         if (!model)
3992                 return NULL;
3993         return isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 0, 0);
3994 }
3995
3996 struct isl_basic_set *isl_basic_set_universe_like(struct isl_basic_set *model)
3997 {
3998         if (!model)
3999                 return NULL;
4000         return isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 0, 0);
4001 }
4002
4003 __isl_give isl_basic_set *isl_basic_set_universe_like_set(
4004         __isl_keep isl_set *model)
4005 {
4006         if (!model)
4007                 return NULL;
4008         return isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 0, 0);
4009 }
4010
4011 struct isl_map *isl_map_empty(struct isl_dim *dim)
4012 {
4013         return isl_map_alloc_dim(dim, 0, ISL_MAP_DISJOINT);
4014 }
4015
4016 struct isl_map *isl_map_empty_like(struct isl_map *model)
4017 {
4018         if (!model)
4019                 return NULL;
4020         return isl_map_alloc_dim(isl_dim_copy(model->dim), 0, ISL_MAP_DISJOINT);
4021 }
4022
4023 struct isl_map *isl_map_empty_like_basic_map(struct isl_basic_map *model)
4024 {
4025         if (!model)
4026                 return NULL;
4027         return isl_map_alloc_dim(isl_dim_copy(model->dim), 0, ISL_MAP_DISJOINT);
4028 }
4029
4030 struct isl_set *isl_set_empty(struct isl_dim *dim)
4031 {
4032         return isl_set_alloc_dim(dim, 0, ISL_MAP_DISJOINT);
4033 }
4034
4035 struct isl_set *isl_set_empty_like(struct isl_set *model)
4036 {
4037         if (!model)
4038                 return NULL;
4039         return isl_set_empty(isl_dim_copy(model->dim));
4040 }
4041
4042 struct isl_map *isl_map_universe(struct isl_dim *dim)
4043 {
4044         struct isl_map *map;
4045         if (!dim)
4046                 return NULL;
4047         map = isl_map_alloc_dim(isl_dim_copy(dim), 1, ISL_MAP_DISJOINT);
4048         map = isl_map_add_basic_map(map, isl_basic_map_universe(dim));
4049         return map;
4050 }
4051
4052 struct isl_set *isl_set_universe(struct isl_dim *dim)
4053 {
4054         struct isl_set *set;
4055         if (!dim)
4056                 return NULL;
4057         set = isl_set_alloc_dim(isl_dim_copy(dim), 1, ISL_MAP_DISJOINT);
4058         set = isl_set_add_basic_set(set, isl_basic_set_universe(dim));
4059         return set;
4060 }
4061
4062 __isl_give isl_set *isl_set_universe_like(__isl_keep isl_set *model)
4063 {
4064         if (!model)
4065                 return NULL;
4066         return isl_set_universe(isl_dim_copy(model->dim));
4067 }
4068
4069 struct isl_map *isl_map_dup(struct isl_map *map)
4070 {
4071         int i;
4072         struct isl_map *dup;
4073
4074         if (!map)
4075                 return NULL;
4076         dup = isl_map_alloc_dim(isl_dim_copy(map->dim), map->n, map->flags);
4077         for (i = 0; i < map->n; ++i)
4078                 dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
4079         return dup;
4080 }
4081
4082 __isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
4083                                                 __isl_take isl_basic_map *bmap)
4084 {
4085         if (!bmap || !map)
4086                 goto error;
4087         if (isl_basic_map_fast_is_empty(bmap)) {
4088                 isl_basic_map_free(bmap);
4089                 return map;
4090         }
4091         isl_assert(map->ctx, isl_dim_equal(map->dim, bmap->dim), goto error);
4092         isl_assert(map->ctx, map->n < map->size, goto error);
4093         map->p[map->n] = bmap;
4094         map->n++;
4095         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4096         return map;
4097 error:
4098         if (map)
4099                 isl_map_free(map);
4100         if (bmap)
4101                 isl_basic_map_free(bmap);
4102         return NULL;
4103 }
4104
4105 void isl_map_free(struct isl_map *map)
4106 {
4107         int i;
4108
4109         if (!map)
4110                 return;
4111
4112         if (--map->ref > 0)
4113                 return;
4114
4115         isl_ctx_deref(map->ctx);
4116         for (i = 0; i < map->n; ++i)
4117                 isl_basic_map_free(map->p[i]);
4118         isl_dim_free(map->dim);
4119         free(map);
4120 }
4121
4122 struct isl_map *isl_map_extend(struct isl_map *base,
4123                 unsigned nparam, unsigned n_in, unsigned n_out)
4124 {
4125         int i;
4126
4127         base = isl_map_cow(base);
4128         if (!base)
4129                 return NULL;
4130
4131         base->dim = isl_dim_extend(base->dim, nparam, n_in, n_out);
4132         if (!base->dim)
4133                 goto error;
4134         for (i = 0; i < base->n; ++i) {
4135                 base->p[i] = isl_basic_map_extend_dim(base->p[i],
4136                                 isl_dim_copy(base->dim), 0, 0, 0);
4137                 if (!base->p[i])
4138                         goto error;
4139         }
4140         return base;
4141 error:
4142         isl_map_free(base);
4143         return NULL;
4144 }
4145
4146 struct isl_set *isl_set_extend(struct isl_set *base,
4147                 unsigned nparam, unsigned dim)
4148 {
4149         return (struct isl_set *)isl_map_extend((struct isl_map *)base,
4150                                                         nparam, 0, dim);
4151 }
4152
4153 static struct isl_basic_map *isl_basic_map_fix_pos_si(
4154         struct isl_basic_map *bmap, unsigned pos, int value)
4155 {
4156         int j;
4157
4158         bmap = isl_basic_map_cow(bmap);
4159         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
4160         j = isl_basic_map_alloc_equality(bmap);
4161         if (j < 0)
4162                 goto error;
4163         isl_seq_clr(bmap->eq[j] + 1, isl_basic_map_total_dim(bmap));
4164         isl_int_set_si(bmap->eq[j][pos], -1);
4165         isl_int_set_si(bmap->eq[j][0], value);
4166         bmap = isl_basic_map_simplify(bmap);
4167         return isl_basic_map_finalize(bmap);
4168 error:
4169         isl_basic_map_free(bmap);
4170         return NULL;
4171 }
4172
4173 static __isl_give isl_basic_map *isl_basic_map_fix_pos(
4174         __isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
4175 {
4176         int j;
4177
4178         bmap = isl_basic_map_cow(bmap);
4179         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
4180         j = isl_basic_map_alloc_equality(bmap);
4181         if (j < 0)
4182                 goto error;
4183         isl_seq_clr(bmap->eq[j] + 1, isl_basic_map_total_dim(bmap));
4184         isl_int_set_si(bmap->eq[j][pos], -1);
4185         isl_int_set(bmap->eq[j][0], value);
4186         bmap = isl_basic_map_simplify(bmap);
4187         return isl_basic_map_finalize(bmap);
4188 error:
4189         isl_basic_map_free(bmap);
4190         return NULL;
4191 }
4192
4193 struct isl_basic_map *isl_basic_map_fix_si(struct isl_basic_map *bmap,
4194                 enum isl_dim_type type, unsigned pos, int value)
4195 {
4196         if (!bmap)
4197                 return NULL;
4198         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
4199         return isl_basic_map_fix_pos_si(bmap,
4200                 isl_basic_map_offset(bmap, type) + pos, value);
4201 error:
4202         isl_basic_map_free(bmap);
4203         return NULL;
4204 }
4205
4206 __isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
4207                 enum isl_dim_type type, unsigned pos, isl_int value)
4208 {
4209         if (!bmap)
4210                 return NULL;
4211         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
4212         return isl_basic_map_fix_pos(bmap,
4213                 isl_basic_map_offset(bmap, type) + pos, value);
4214 error:
4215         isl_basic_map_free(bmap);
4216         return NULL;
4217 }
4218
4219 struct isl_basic_set *isl_basic_set_fix_si(struct isl_basic_set *bset,
4220                 enum isl_dim_type type, unsigned pos, int value)
4221 {
4222         return (struct isl_basic_set *)
4223                 isl_basic_map_fix_si((struct isl_basic_map *)bset,
4224                                         type, pos, value);
4225 }
4226
4227 __isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset,
4228                 enum isl_dim_type type, unsigned pos, isl_int value)
4229 {
4230         return (struct isl_basic_set *)
4231                 isl_basic_map_fix((struct isl_basic_map *)bset,
4232                                         type, pos, value);
4233 }
4234
4235 struct isl_basic_map *isl_basic_map_fix_input_si(struct isl_basic_map *bmap,
4236                 unsigned input, int value)
4237 {
4238         return isl_basic_map_fix_si(bmap, isl_dim_in, input, value);
4239 }
4240
4241 struct isl_basic_set *isl_basic_set_fix_dim_si(struct isl_basic_set *bset,
4242                 unsigned dim, int value)
4243 {
4244         return (struct isl_basic_set *)
4245                 isl_basic_map_fix_si((struct isl_basic_map *)bset,
4246                                         isl_dim_set, dim, value);
4247 }
4248
4249 struct isl_map *isl_map_fix_si(struct isl_map *map,
4250                 enum isl_dim_type type, unsigned pos, int value)
4251 {
4252         int i;
4253
4254         map = isl_map_cow(map);
4255         if (!map)
4256                 return NULL;
4257
4258         isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error);
4259         for (i = 0; i < map->n; ++i) {
4260                 map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
4261                 if (!map->p[i])
4262                         goto error;
4263         }
4264         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4265         return map;
4266 error:
4267         isl_map_free(map);
4268         return NULL;
4269 }
4270
4271 __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set,
4272                 enum isl_dim_type type, unsigned pos, int value)
4273 {
4274         return (struct isl_set *)
4275                 isl_map_fix_si((struct isl_map *)set, type, pos, value);
4276 }
4277
4278 __isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
4279                 enum isl_dim_type type, unsigned pos, isl_int value)
4280 {
4281         int i;
4282
4283         map = isl_map_cow(map);
4284         if (!map)
4285                 return NULL;
4286
4287         isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error);
4288         for (i = 0; i < map->n; ++i) {
4289                 map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
4290                 if (!map->p[i])
4291                         goto error;
4292         }
4293         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4294         return map;
4295 error:
4296         isl_map_free(map);
4297         return NULL;
4298 }
4299
4300 __isl_give isl_set *isl_set_fix(__isl_take isl_set *set,
4301                 enum isl_dim_type type, unsigned pos, isl_int value)
4302 {
4303         return (struct isl_set *)isl_map_fix((isl_map *)set, type, pos, value);
4304 }
4305
4306 struct isl_map *isl_map_fix_input_si(struct isl_map *map,
4307                 unsigned input, int value)
4308 {
4309         return isl_map_fix_si(map, isl_dim_in, input, value);
4310 }
4311
4312 struct isl_set *isl_set_fix_dim_si(struct isl_set *set, unsigned dim, int value)
4313 {
4314         return (struct isl_set *)
4315                 isl_map_fix_si((struct isl_map *)set, isl_dim_set, dim, value);
4316 }
4317
4318 __isl_give isl_basic_map *isl_basic_map_lower_bound_si(
4319                 __isl_take isl_basic_map *bmap,
4320                 enum isl_dim_type type, unsigned pos, int value)
4321 {
4322         int j;
4323
4324         if (!bmap)
4325                 return NULL;
4326         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
4327         pos += isl_basic_map_offset(bmap, type);
4328         bmap = isl_basic_map_cow(bmap);
4329         bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
4330         j = isl_basic_map_alloc_inequality(bmap);
4331         if (j < 0)
4332                 goto error;
4333         isl_seq_clr(bmap->ineq[j], 1 + isl_basic_map_total_dim(bmap));
4334         isl_int_set_si(bmap->ineq[j][pos], 1);
4335         isl_int_set_si(bmap->ineq[j][0], -value);
4336         bmap = isl_basic_map_simplify(bmap);
4337         return isl_basic_map_finalize(bmap);
4338 error:
4339         isl_basic_map_free(bmap);
4340         return NULL;
4341 }
4342
4343 struct isl_basic_set *isl_basic_set_lower_bound_dim(struct isl_basic_set *bset,
4344         unsigned dim, isl_int value)
4345 {
4346         int j;
4347
4348         bset = isl_basic_set_cow(bset);
4349         bset = isl_basic_set_extend_constraints(bset, 0, 1);
4350         j = isl_basic_set_alloc_inequality(bset);
4351         if (j < 0)
4352                 goto error;
4353         isl_seq_clr(bset->ineq[j], 1 + isl_basic_set_total_dim(bset));
4354         isl_int_set_si(bset->ineq[j][1 + isl_basic_set_n_param(bset) + dim], 1);
4355         isl_int_neg(bset->ineq[j][0], value);
4356         bset = isl_basic_set_simplify(bset);
4357         return isl_basic_set_finalize(bset);
4358 error:
4359         isl_basic_set_free(bset);
4360         return NULL;
4361 }
4362
4363 __isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
4364                 enum isl_dim_type type, unsigned pos, int value)
4365 {
4366         int i;
4367
4368         map = isl_map_cow(map);
4369         if (!map)
4370                 return NULL;
4371
4372         isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error);
4373         for (i = 0; i < map->n; ++i) {
4374                 map->p[i] = isl_basic_map_lower_bound_si(map->p[i],
4375                                                          type, pos, value);
4376                 if (!map->p[i])
4377                         goto error;
4378         }
4379         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4380         return map;
4381 error:
4382         isl_map_free(map);
4383         return NULL;
4384 }
4385
4386 __isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set,
4387                 enum isl_dim_type type, unsigned pos, int value)
4388 {
4389         return (struct isl_set *)
4390                 isl_map_lower_bound_si((struct isl_map *)set, type, pos, value);
4391 }
4392
4393 struct isl_set *isl_set_lower_bound_dim(struct isl_set *set, unsigned dim,
4394                                         isl_int value)
4395 {
4396         int i;
4397
4398         set = isl_set_cow(set);
4399         if (!set)
4400                 return NULL;
4401
4402         isl_assert(set->ctx, dim < isl_set_n_dim(set), goto error);
4403         for (i = 0; i < set->n; ++i) {
4404                 set->p[i] = isl_basic_set_lower_bound_dim(set->p[i], dim, value);
4405                 if (!set->p[i])
4406                         goto error;
4407         }
4408         return set;
4409 error:
4410         isl_set_free(set);
4411         return NULL;
4412 }
4413
4414 struct isl_map *isl_map_reverse(struct isl_map *map)
4415 {
4416         int i;
4417
4418         map = isl_map_cow(map);
4419         if (!map)
4420                 return NULL;
4421
4422         map->dim = isl_dim_reverse(map->dim);
4423         if (!map->dim)
4424                 goto error;
4425         for (i = 0; i < map->n; ++i) {
4426                 map->p[i] = isl_basic_map_reverse(map->p[i]);
4427                 if (!map->p[i])
4428                         goto error;
4429         }
4430         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4431         return map;
4432 error:
4433         isl_map_free(map);
4434         return NULL;
4435 }
4436
4437 static struct isl_map *isl_basic_map_partial_lexopt(
4438                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
4439                 struct isl_set **empty, int max)
4440 {
4441         if (!bmap)
4442                 goto error;
4443         if (bmap->ctx->opt->pip == ISL_PIP_PIP)
4444                 return isl_pip_basic_map_lexopt(bmap, dom, empty, max);
4445         else
4446                 return isl_tab_basic_map_partial_lexopt(bmap, dom, empty, max);
4447 error:
4448         isl_basic_map_free(bmap);
4449         isl_basic_set_free(dom);
4450         if (empty)
4451                 *empty = NULL;
4452         return NULL;
4453 }
4454
4455 struct isl_map *isl_basic_map_partial_lexmax(
4456                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
4457                 struct isl_set **empty)
4458 {
4459         return isl_basic_map_partial_lexopt(bmap, dom, empty, 1);
4460 }
4461
4462 struct isl_map *isl_basic_map_partial_lexmin(
4463                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
4464                 struct isl_set **empty)
4465 {
4466         return isl_basic_map_partial_lexopt(bmap, dom, empty, 0);
4467 }
4468
4469 struct isl_set *isl_basic_set_partial_lexmin(
4470                 struct isl_basic_set *bset, struct isl_basic_set *dom,
4471                 struct isl_set **empty)
4472 {
4473         return (struct isl_set *)
4474                 isl_basic_map_partial_lexmin((struct isl_basic_map *)bset,
4475                         dom, empty);
4476 }
4477
4478 struct isl_set *isl_basic_set_partial_lexmax(
4479                 struct isl_basic_set *bset, struct isl_basic_set *dom,
4480                 struct isl_set **empty)
4481 {
4482         return (struct isl_set *)
4483                 isl_basic_map_partial_lexmax((struct isl_basic_map *)bset,
4484                         dom, empty);
4485 }
4486
4487 /* Given a basic map "bmap", compute the lexicograhically minimal
4488  * (or maximal) image element for each domain element in dom.
4489  * Set *empty to those elements in dom that do not have an image element.
4490  *
4491  * We first make sure the basic sets in dom are disjoint and then
4492  * simply collect the results over each of the basic sets separately.
4493  * We could probably improve the efficiency a bit by moving the union
4494  * domain down into the parametric integer programming.
4495  */
4496 static __isl_give isl_map *basic_map_partial_lexopt(
4497                 __isl_take isl_basic_map *bmap, __isl_take isl_set *dom,
4498                 __isl_give isl_set **empty, int max)
4499 {
4500         int i;
4501         struct isl_map *res;
4502
4503         dom = isl_set_make_disjoint(dom);
4504         if (!dom)
4505                 goto error;
4506
4507         if (isl_set_fast_is_empty(dom)) {
4508                 res = isl_map_empty_like_basic_map(bmap);
4509                 *empty = isl_set_empty_like(dom);
4510                 isl_set_free(dom);
4511                 isl_basic_map_free(bmap);
4512                 return res;
4513         }
4514
4515         res = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap),
4516                         isl_basic_set_copy(dom->p[0]), empty, max);
4517                 
4518         for (i = 1; i < dom->n; ++i) {
4519                 struct isl_map *res_i;
4520                 struct isl_set *empty_i;
4521
4522                 res_i = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap),
4523                                 isl_basic_set_copy(dom->p[i]), &empty_i, max);
4524
4525                 res = isl_map_union_disjoint(res, res_i);
4526                 *empty = isl_set_union_disjoint(*empty, empty_i);
4527         }
4528
4529         isl_set_free(dom);
4530         isl_basic_map_free(bmap);
4531         return res;
4532 error:
4533         *empty = NULL;
4534         isl_set_free(dom);
4535         isl_basic_map_free(bmap);
4536         return NULL;
4537 }
4538
4539 /* Given a map "map", compute the lexicograhically minimal
4540  * (or maximal) image element for each domain element in dom.
4541  * Set *empty to those elements in dom that do not have an image element.
4542  *
4543  * We first compute the lexicographically minimal or maximal element
4544  * in the first basic map.  This results in a partial solution "res"
4545  * and a subset "todo" of dom that still need to be handled.
4546  * We then consider each of the remaining maps in "map" and successively
4547  * improve both "res" and "todo".
4548  *
4549  * Let res^k and todo^k be the results after k steps and let i = k + 1.
4550  * Assume we are computing the lexicographical maximum.
4551  * We first intersect basic map i with a relation that maps elements
4552  * to elements that are lexicographically larger than the image elements
4553  * in res^k and the compute the maximum image element of this intersection.
4554  * The result ("better") corresponds to those image elements in basic map i
4555  * that are better than what we had before.  The remainder ("keep") are the
4556  * domain elements for which the image element in res_k was better.
4557  * We also compute the lexicographical maximum of basic map i in todo^k.
4558  * res^i is the result of the operation + better + those elements in
4559  *              res^k that we should keep
4560  * todo^i is the remainder of the maximum operation on todo^k.
4561  */
4562 static __isl_give isl_map *isl_map_partial_lexopt(
4563                 __isl_take isl_map *map, __isl_take isl_set *dom,
4564                 __isl_give isl_set **empty, int max)
4565 {
4566         int i;
4567         struct isl_map *res;
4568         struct isl_set *todo;
4569
4570         if (!map || !dom)
4571                 goto error;
4572
4573         if (isl_map_fast_is_empty(map)) {
4574                 if (empty)
4575                         *empty = dom;
4576                 else
4577                         isl_set_free(dom);
4578                 return map;
4579         }
4580
4581         res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
4582                                         isl_set_copy(dom), &todo, max);
4583
4584         for (i = 1; i < map->n; ++i) {
4585                 struct isl_map *lt;
4586                 struct isl_map *better;
4587                 struct isl_set *keep;
4588                 struct isl_map *res_i;
4589                 struct isl_set *todo_i;
4590                 struct isl_dim *dim = isl_map_get_dim(res);
4591
4592                 dim = isl_dim_range(dim);
4593                 if (max)
4594                         lt = isl_map_lex_lt(dim);
4595                 else
4596                         lt = isl_map_lex_gt(dim);
4597                 lt = isl_map_apply_range(isl_map_copy(res), lt);
4598                 lt = isl_map_intersect(lt,
4599                         isl_map_from_basic_map(isl_basic_map_copy(map->p[i])));
4600                 better = isl_map_partial_lexopt(lt,
4601                         isl_map_domain(isl_map_copy(res)),
4602                         &keep, max);
4603
4604                 res_i = basic_map_partial_lexopt(isl_basic_map_copy(map->p[i]),
4605                                                 todo, &todo_i, max);
4606
4607                 res = isl_map_intersect_domain(res, keep);
4608                 res = isl_map_union_disjoint(res, res_i);
4609                 res = isl_map_union_disjoint(res, better);
4610                 todo = todo_i;
4611         }
4612
4613         isl_set_free(dom);
4614         isl_map_free(map);
4615
4616         if (empty)
4617                 *empty = todo;
4618         else
4619                 isl_set_free(todo);
4620
4621         return res;
4622 error:
4623         if (empty)
4624                 *empty = NULL;
4625         isl_set_free(dom);
4626         isl_map_free(map);
4627         return NULL;
4628 }
4629
4630 __isl_give isl_map *isl_map_partial_lexmax(
4631                 __isl_take isl_map *map, __isl_take isl_set *dom,
4632                 __isl_give isl_set **empty)
4633 {
4634         return isl_map_partial_lexopt(map, dom, empty, 1);
4635 }
4636
4637 __isl_give isl_map *isl_map_partial_lexmin(
4638                 __isl_take isl_map *map, __isl_take isl_set *dom,
4639                 __isl_give isl_set **empty)
4640 {
4641         return isl_map_partial_lexopt(map, dom, empty, 0);
4642 }
4643
4644 __isl_give isl_set *isl_set_partial_lexmin(
4645                 __isl_take isl_set *set, __isl_take isl_set *dom,
4646                 __isl_give isl_set **empty)
4647 {
4648         return (struct isl_set *)
4649                 isl_map_partial_lexmin((struct isl_map *)set,
4650                         dom, empty);
4651 }
4652
4653 __isl_give isl_set *isl_set_partial_lexmax(
4654                 __isl_take isl_set *set, __isl_take isl_set *dom,
4655                 __isl_give isl_set **empty)
4656 {
4657         return (struct isl_set *)
4658                 isl_map_partial_lexmax((struct isl_map *)set,
4659                         dom, empty);
4660 }
4661
4662 __isl_give isl_map *isl_basic_map_lexopt(__isl_take isl_basic_map *bmap, int max)
4663 {
4664         struct isl_basic_set *dom = NULL;
4665         struct isl_dim *dom_dim;
4666
4667         if (!bmap)
4668                 goto error;
4669         dom_dim = isl_dim_domain(isl_dim_copy(bmap->dim));
4670         dom = isl_basic_set_universe(dom_dim);
4671         return isl_basic_map_partial_lexopt(bmap, dom, NULL, max);
4672 error:
4673         isl_basic_map_free(bmap);
4674         return NULL;
4675 }
4676
4677 __isl_give isl_map *isl_basic_map_lexmin(__isl_take isl_basic_map *bmap)
4678 {
4679         return isl_basic_map_lexopt(bmap, 0);
4680 }
4681
4682 __isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
4683 {
4684         return isl_basic_map_lexopt(bmap, 1);
4685 }
4686
4687 __isl_give isl_set *isl_basic_set_lexmin(__isl_take isl_basic_set *bset)
4688 {
4689         return (isl_set *)isl_basic_map_lexmin((isl_basic_map *)bset);
4690 }
4691
4692 __isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset)
4693 {
4694         return (isl_set *)isl_basic_map_lexmax((isl_basic_map *)bset);
4695 }
4696
4697 __isl_give isl_map *isl_map_lexopt(__isl_take isl_map *map, int max)
4698 {
4699         struct isl_set *dom = NULL;
4700         struct isl_dim *dom_dim;
4701
4702         if (!map)
4703                 goto error;
4704         dom_dim = isl_dim_domain(isl_dim_copy(map->dim));
4705         dom = isl_set_universe(dom_dim);
4706         return isl_map_partial_lexopt(map, dom, NULL, max);
4707 error:
4708         isl_map_free(map);
4709         return NULL;
4710 }
4711
4712 __isl_give isl_map *isl_map_lexmin(__isl_take isl_map *map)
4713 {
4714         return isl_map_lexopt(map, 0);
4715 }
4716
4717 __isl_give isl_map *isl_map_lexmax(__isl_take isl_map *map)
4718 {
4719         return isl_map_lexopt(map, 1);
4720 }
4721
4722 __isl_give isl_set *isl_set_lexmin(__isl_take isl_set *set)
4723 {
4724         return (isl_set *)isl_map_lexmin((isl_map *)set);
4725 }
4726
4727 __isl_give isl_set *isl_set_lexmax(__isl_take isl_set *set)
4728 {
4729         return (isl_set *)isl_map_lexmax((isl_map *)set);
4730 }
4731
4732 /* Apply a preimage specified by "mat" on the parameters of "bset".
4733  * bset is assumed to have only parameters and divs.
4734  */
4735 static struct isl_basic_set *basic_set_parameter_preimage(
4736         struct isl_basic_set *bset, struct isl_mat *mat)
4737 {
4738         unsigned nparam;
4739
4740         if (!bset || !mat)
4741                 goto error;
4742
4743         bset->dim = isl_dim_cow(bset->dim);
4744         if (!bset->dim)
4745                 goto error;
4746
4747         nparam = isl_basic_set_dim(bset, isl_dim_param);
4748
4749         isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error);
4750
4751         bset->dim->nparam = 0;
4752         bset->dim->n_out = nparam;
4753         bset = isl_basic_set_preimage(bset, mat);
4754         if (bset) {
4755                 bset->dim->nparam = bset->dim->n_out;
4756                 bset->dim->n_out = 0;
4757         }
4758         return bset;
4759 error:
4760         isl_mat_free(mat);
4761         isl_basic_set_free(bset);
4762         return NULL;
4763 }
4764
4765 /* Apply a preimage specified by "mat" on the parameters of "set".
4766  * set is assumed to have only parameters and divs.
4767  */
4768 static struct isl_set *set_parameter_preimage(
4769         struct isl_set *set, struct isl_mat *mat)
4770 {
4771         struct isl_dim *dim = NULL;
4772         unsigned nparam;
4773
4774         if (!set || !mat)
4775                 goto error;
4776
4777         dim = isl_dim_copy(set->dim);
4778         dim = isl_dim_cow(dim);
4779         if (!dim)
4780                 goto error;
4781
4782         nparam = isl_set_dim(set, isl_dim_param);
4783
4784         isl_assert(set->ctx, mat->n_row == 1 + nparam, goto error);
4785
4786         dim->nparam = 0;
4787         dim->n_out = nparam;
4788         isl_set_reset_dim(set, dim);
4789         set = isl_set_preimage(set, mat);
4790         if (!set)
4791                 goto error2;
4792         dim = isl_dim_copy(set->dim);
4793         dim = isl_dim_cow(dim);
4794         if (!dim)
4795                 goto error2;
4796         dim->nparam = dim->n_out;
4797         dim->n_out = 0;
4798         isl_set_reset_dim(set, dim);
4799         return set;
4800 error:
4801         isl_dim_free(dim);
4802         isl_mat_free(mat);
4803 error2:
4804         isl_set_free(set);
4805         return NULL;
4806 }
4807
4808 /* Intersect the basic set "bset" with the affine space specified by the
4809  * equalities in "eq".
4810  */
4811 static struct isl_basic_set *basic_set_append_equalities(
4812         struct isl_basic_set *bset, struct isl_mat *eq)
4813 {
4814         int i, k;
4815         unsigned len;
4816
4817         if (!bset || !eq)
4818                 goto error;
4819
4820         bset = isl_basic_set_extend_dim(bset, isl_dim_copy(bset->dim), 0,
4821                                         eq->n_row, 0);
4822         if (!bset)
4823                 goto error;
4824
4825         len = 1 + isl_dim_total(bset->dim) + bset->extra;
4826         for (i = 0; i < eq->n_row; ++i) {
4827                 k = isl_basic_set_alloc_equality(bset);
4828                 if (k < 0)
4829                         goto error;
4830                 isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
4831                 isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
4832         }
4833         isl_mat_free(eq);
4834
4835         bset = isl_basic_set_gauss(bset, NULL);
4836         bset = isl_basic_set_finalize(bset);
4837
4838         return bset;
4839 error:
4840         isl_mat_free(eq);
4841         isl_basic_set_free(bset);
4842         return NULL;
4843 }
4844
4845 /* Intersect the set "set" with the affine space specified by the
4846  * equalities in "eq".
4847  */
4848 static struct isl_set *set_append_equalities(struct isl_set *set,
4849         struct isl_mat *eq)
4850 {
4851         int i;
4852
4853         if (!set || !eq)
4854                 goto error;
4855
4856         for (i = 0; i < set->n; ++i) {
4857                 set->p[i] = basic_set_append_equalities(set->p[i],
4858                                         isl_mat_copy(eq));
4859                 if (!set->p[i])
4860                         goto error;
4861         }
4862         isl_mat_free(eq);
4863         return set;
4864 error:
4865         isl_mat_free(eq);
4866         isl_set_free(set);
4867         return NULL;
4868 }
4869
4870 /* Project the given basic set onto its parameter domain, possibly introducing
4871  * new, explicit, existential variables in the constraints.
4872  * The input has parameters and (possibly implicit) existential variables.
4873  * The output has the same parameters, but only
4874  * explicit existentially quantified variables.
4875  *
4876  * The actual projection is performed by pip, but pip doesn't seem
4877  * to like equalities very much, so we first remove the equalities
4878  * among the parameters by performing a variable compression on
4879  * the parameters.  Afterward, an inverse transformation is performed
4880  * and the equalities among the parameters are inserted back in.
4881  */
4882 static struct isl_set *parameter_compute_divs(struct isl_basic_set *bset)
4883 {
4884         int i, j;
4885         struct isl_mat *eq;
4886         struct isl_mat *T, *T2;
4887         struct isl_set *set;
4888         unsigned nparam, n_div;
4889
4890         bset = isl_basic_set_cow(bset);
4891         if (!bset)
4892                 return NULL;
4893
4894         if (bset->n_eq == 0)
4895                 return isl_basic_set_lexmin(bset);
4896
4897         isl_basic_set_gauss(bset, NULL);
4898
4899         nparam = isl_basic_set_dim(bset, isl_dim_param);
4900         n_div = isl_basic_set_dim(bset, isl_dim_div);
4901
4902         for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
4903                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + j]))
4904                         ++i;
4905         }
4906         if (i == bset->n_eq)
4907                 return isl_basic_set_lexmin(bset);
4908
4909         eq = isl_mat_sub_alloc(bset->ctx, bset->eq, i, bset->n_eq - i,
4910                 0, 1 + nparam);
4911         eq = isl_mat_cow(eq);
4912         T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
4913         if (T && T->n_col == 0) {
4914                 isl_mat_free(T);
4915                 isl_mat_free(T2);
4916                 isl_mat_free(eq);
4917                 bset = isl_basic_set_set_to_empty(bset);
4918                 return isl_set_from_basic_set(bset);
4919         }
4920         bset = basic_set_parameter_preimage(bset, T);
4921
4922         set = isl_basic_set_lexmin(bset);
4923         set = set_parameter_preimage(set, T2);
4924         set = set_append_equalities(set, eq);
4925         return set;
4926 }
4927
4928 /* Compute an explicit representation for all the existentially
4929  * quantified variables.
4930  * The input and output dimensions are first turned into parameters.
4931  * compute_divs then returns a map with the same parameters and
4932  * no input or output dimensions and the dimension specification
4933  * is reset to that of the input.
4934  */
4935 static struct isl_map *compute_divs(struct isl_basic_map *bmap)
4936 {
4937         struct isl_basic_set *bset;
4938         struct isl_set *set;
4939         struct isl_map *map;
4940         struct isl_dim *dim, *orig_dim = NULL;
4941         unsigned         nparam;
4942         unsigned         n_in;
4943         unsigned         n_out;
4944
4945         bmap = isl_basic_map_cow(bmap);
4946         if (!bmap)
4947                 return NULL;
4948
4949         nparam = isl_basic_map_dim(bmap, isl_dim_param);
4950         n_in = isl_basic_map_dim(bmap, isl_dim_in);
4951         n_out = isl_basic_map_dim(bmap, isl_dim_out);
4952         dim = isl_dim_set_alloc(bmap->ctx, nparam + n_in + n_out, 0);
4953         if (!dim)
4954                 goto error;
4955
4956         orig_dim = bmap->dim;
4957         bmap->dim = dim;
4958         bset = (struct isl_basic_set *)bmap;
4959
4960         set = parameter_compute_divs(bset);
4961         map = (struct isl_map *)set;
4962         map = isl_map_reset_dim(map, orig_dim);
4963
4964         return map;
4965 error:
4966         isl_basic_map_free(bmap);
4967         return NULL;
4968 }
4969
4970 static int basic_map_divs_known(__isl_keep isl_basic_map *bmap)
4971 {
4972         int i;
4973         unsigned off;
4974
4975         if (!bmap)
4976                 return -1;
4977
4978         off = isl_dim_total(bmap->dim);
4979         for (i = 0; i < bmap->n_div; ++i) {
4980                 if (isl_int_is_zero(bmap->div[i][0]))
4981                         return 0;
4982                 isl_assert(bmap->ctx, isl_int_is_zero(bmap->div[i][1+1+off+i]),
4983                                 return -1);
4984         }
4985         return 1;
4986 }
4987
4988 static int map_divs_known(__isl_keep isl_map *map)
4989 {
4990         int i;
4991
4992         if (!map)
4993                 return -1;
4994
4995         for (i = 0; i < map->n; ++i) {
4996                 int known = basic_map_divs_known(map->p[i]);
4997                 if (known <= 0)
4998                         return known;
4999         }
5000
5001         return 1;
5002 }
5003
5004 /* If bmap contains any unknown divs, then compute explicit
5005  * expressions for them.  However, this computation may be
5006  * quite expensive, so first try to remove divs that aren't
5007  * strictly needed.
5008  */
5009 struct isl_map *isl_basic_map_compute_divs(struct isl_basic_map *bmap)
5010 {
5011         int i;
5012         int known;
5013         struct isl_map *map;
5014
5015         known = basic_map_divs_known(bmap);
5016         if (known < 0)
5017                 goto error;
5018         if (known)
5019                 return isl_map_from_basic_map(bmap);
5020
5021         bmap = isl_basic_map_drop_redundant_divs(bmap);
5022
5023         known = basic_map_divs_known(bmap);
5024         if (known < 0)
5025                 goto error;
5026         if (known)
5027                 return isl_map_from_basic_map(bmap);
5028
5029         map = compute_divs(bmap);
5030         return map;
5031 error:
5032         isl_basic_map_free(bmap);
5033         return NULL;
5034 }
5035
5036 struct isl_map *isl_map_compute_divs(struct isl_map *map)
5037 {
5038         int i;
5039         int known;
5040         struct isl_map *res;
5041
5042         if (!map)
5043                 return NULL;
5044         if (map->n == 0)
5045                 return map;
5046
5047         known = map_divs_known(map);
5048         if (known < 0) {
5049                 isl_map_free(map);
5050                 return NULL;
5051         }
5052         if (known)
5053                 return map;
5054
5055         res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
5056         for (i = 1 ; i < map->n; ++i) {
5057                 struct isl_map *r2;
5058                 r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
5059                 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
5060                         res = isl_map_union_disjoint(res, r2);
5061                 else
5062                         res = isl_map_union(res, r2);
5063         }
5064         isl_map_free(map);
5065
5066         return res;
5067 }
5068
5069 struct isl_set *isl_basic_set_compute_divs(struct isl_basic_set *bset)
5070 {
5071         return (struct isl_set *)
5072                 isl_basic_map_compute_divs((struct isl_basic_map *)bset);
5073 }
5074
5075 struct isl_set *isl_set_compute_divs(struct isl_set *set)
5076 {
5077         return (struct isl_set *)
5078                 isl_map_compute_divs((struct isl_map *)set);
5079 }
5080
5081 struct isl_set *isl_map_domain(struct isl_map *map)
5082 {
5083         int i;
5084         struct isl_set *set;
5085
5086         if (!map)
5087                 goto error;
5088
5089         map = isl_map_cow(map);
5090         if (!map)
5091                 return NULL;
5092
5093         set = (struct isl_set *)map;
5094         set->dim = isl_dim_domain(set->dim);
5095         if (!set->dim)
5096                 goto error;
5097         for (i = 0; i < map->n; ++i) {
5098                 set->p[i] = isl_basic_map_domain(map->p[i]);
5099                 if (!set->p[i])
5100                         goto error;
5101         }
5102         ISL_F_CLR(set, ISL_MAP_DISJOINT);
5103         ISL_F_CLR(set, ISL_SET_NORMALIZED);
5104         return set;
5105 error:
5106         isl_map_free(map);
5107         return NULL;
5108 }
5109
5110 struct isl_map *isl_map_union_disjoint(
5111                         struct isl_map *map1, struct isl_map *map2)
5112 {
5113         int i;
5114         unsigned flags = 0;
5115         struct isl_map *map = NULL;
5116
5117         if (!map1 || !map2)
5118                 goto error;
5119
5120         if (map1->n == 0) {
5121                 isl_map_free(map1);
5122                 return map2;
5123         }
5124         if (map2->n == 0) {
5125                 isl_map_free(map2);
5126                 return map1;
5127         }
5128
5129         isl_assert(map1->ctx, isl_dim_equal(map1->dim, map2->dim), goto error);
5130
5131         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
5132             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
5133                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
5134
5135         map = isl_map_alloc_dim(isl_dim_copy(map1->dim),
5136                                 map1->n + map2->n, flags);
5137         if (!map)
5138                 goto error;
5139         for (i = 0; i < map1->n; ++i) {
5140                 map = isl_map_add_basic_map(map,
5141                                   isl_basic_map_copy(map1->p[i]));
5142                 if (!map)
5143                         goto error;
5144         }
5145         for (i = 0; i < map2->n; ++i) {
5146                 map = isl_map_add_basic_map(map,
5147                                   isl_basic_map_copy(map2->p[i]));
5148                 if (!map)
5149                         goto error;
5150         }
5151         isl_map_free(map1);
5152         isl_map_free(map2);
5153         return map;
5154 error:
5155         isl_map_free(map);
5156         isl_map_free(map1);
5157         isl_map_free(map2);
5158         return NULL;
5159 }
5160
5161 struct isl_map *isl_map_union(struct isl_map *map1, struct isl_map *map2)
5162 {
5163         map1 = isl_map_union_disjoint(map1, map2);
5164         if (!map1)
5165                 return NULL;
5166         if (map1->n > 1)
5167                 ISL_F_CLR(map1, ISL_MAP_DISJOINT);
5168         return map1;
5169 }
5170
5171 struct isl_set *isl_set_union_disjoint(
5172                         struct isl_set *set1, struct isl_set *set2)
5173 {
5174         return (struct isl_set *)
5175                 isl_map_union_disjoint(
5176                         (struct isl_map *)set1, (struct isl_map *)set2);
5177 }
5178
5179 struct isl_set *isl_set_union(struct isl_set *set1, struct isl_set *set2)
5180 {
5181         return (struct isl_set *)
5182                 isl_map_union((struct isl_map *)set1, (struct isl_map *)set2);
5183 }
5184
5185 struct isl_map *isl_map_intersect_range(
5186                 struct isl_map *map, struct isl_set *set)
5187 {
5188         unsigned flags = 0;
5189         struct isl_map *result;
5190         int i, j;
5191
5192         if (!map || !set)
5193                 goto error;
5194
5195         if (ISL_F_ISSET(map, ISL_MAP_DISJOINT) &&
5196             ISL_F_ISSET(set, ISL_MAP_DISJOINT))
5197                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
5198
5199         result = isl_map_alloc_dim(isl_dim_copy(map->dim),
5200                                         map->n * set->n, flags);
5201         if (!result)
5202                 goto error;
5203         for (i = 0; i < map->n; ++i)
5204                 for (j = 0; j < set->n; ++j) {
5205                         result = isl_map_add_basic_map(result,
5206                             isl_basic_map_intersect_range(
5207                                 isl_basic_map_copy(map->p[i]),
5208                                 isl_basic_set_copy(set->p[j])));
5209                         if (!result)
5210                                 goto error;
5211                 }
5212         isl_map_free(map);
5213         isl_set_free(set);
5214         return result;
5215 error:
5216         isl_map_free(map);
5217         isl_set_free(set);
5218         return NULL;
5219 }
5220
5221 struct isl_map *isl_map_intersect_domain(
5222                 struct isl_map *map, struct isl_set *set)
5223 {
5224         return isl_map_reverse(
5225                 isl_map_intersect_range(isl_map_reverse(map), set));
5226 }
5227
5228 struct isl_map *isl_map_apply_domain(
5229                 struct isl_map *map1, struct isl_map *map2)
5230 {
5231         if (!map1 || !map2)
5232                 goto error;
5233         map1 = isl_map_reverse(map1);
5234         map1 = isl_map_apply_range(map1, map2);
5235         return isl_map_reverse(map1);
5236 error:
5237         isl_map_free(map1);
5238         isl_map_free(map2);
5239         return NULL;
5240 }
5241
5242 struct isl_map *isl_map_apply_range(
5243                 struct isl_map *map1, struct isl_map *map2)
5244 {
5245         struct isl_dim *dim_result;
5246         struct isl_map *result;
5247         int i, j;
5248
5249         if (!map1 || !map2)
5250                 goto error;
5251
5252         dim_result = isl_dim_join(isl_dim_copy(map1->dim),
5253                                   isl_dim_copy(map2->dim));
5254
5255         result = isl_map_alloc_dim(dim_result, map1->n * map2->n, 0);
5256         if (!result)
5257                 goto error;
5258         for (i = 0; i < map1->n; ++i)
5259                 for (j = 0; j < map2->n; ++j) {
5260                         result = isl_map_add_basic_map(result,
5261                             isl_basic_map_apply_range(
5262                                 isl_basic_map_copy(map1->p[i]),
5263                                 isl_basic_map_copy(map2->p[j])));
5264                         if (!result)
5265                                 goto error;
5266                 }
5267         isl_map_free(map1);
5268         isl_map_free(map2);
5269         if (result && result->n <= 1)
5270                 ISL_F_SET(result, ISL_MAP_DISJOINT);
5271         return result;
5272 error:
5273         isl_map_free(map1);
5274         isl_map_free(map2);
5275         return NULL;
5276 }
5277
5278 /*
5279  * returns range - domain
5280  */
5281 struct isl_basic_set *isl_basic_map_deltas(struct isl_basic_map *bmap)
5282 {
5283         isl_dim *dims, *target_dim;
5284         struct isl_basic_set *bset;
5285         unsigned dim;
5286         unsigned nparam;
5287         int i;
5288
5289         if (!bmap)
5290                 goto error;
5291         isl_assert(bmap->ctx, isl_dim_tuple_match(bmap->dim, isl_dim_in,
5292                                                   bmap->dim, isl_dim_out),
5293                    goto error);
5294         target_dim = isl_dim_domain(isl_basic_map_get_dim(bmap));
5295         dim = isl_basic_map_n_in(bmap);
5296         nparam = isl_basic_map_n_param(bmap);
5297         bset = isl_basic_set_from_basic_map(bmap);
5298         bset = isl_basic_set_cow(bset);
5299         dims = isl_basic_set_get_dim(bset);
5300         dims = isl_dim_add(dims, isl_dim_set, dim);
5301         bset = isl_basic_set_extend_dim(bset, dims, 0, dim, 0);
5302         bset = isl_basic_set_swap_vars(bset, 2*dim);
5303         for (i = 0; i < dim; ++i) {
5304                 int j = isl_basic_map_alloc_equality(
5305                                             (struct isl_basic_map *)bset);
5306                 if (j < 0)
5307                         goto error;
5308                 isl_seq_clr(bset->eq[j], 1 + isl_basic_set_total_dim(bset));
5309                 isl_int_set_si(bset->eq[j][1+nparam+i], 1);
5310                 isl_int_set_si(bset->eq[j][1+nparam+dim+i], 1);
5311                 isl_int_set_si(bset->eq[j][1+nparam+2*dim+i], -1);
5312         }
5313         bset = isl_basic_set_project_out(bset, isl_dim_set, dim, 2*dim);
5314         bset = isl_basic_set_reset_dim(bset, target_dim);
5315         return bset;
5316 error:
5317         isl_basic_map_free(bmap);
5318         return NULL;
5319 }
5320
5321 /*
5322  * returns range - domain
5323  */
5324 struct isl_set *isl_map_deltas(struct isl_map *map)
5325 {
5326         int i;
5327         isl_dim *dim;
5328         struct isl_set *result;
5329
5330         if (!map)
5331                 return NULL;
5332
5333         isl_assert(map->ctx, isl_dim_tuple_match(map->dim, isl_dim_in,
5334                                                  map->dim, isl_dim_out),
5335                    goto error);
5336         dim = isl_map_get_dim(map);
5337         dim = isl_dim_domain(dim);
5338         result = isl_set_alloc_dim(dim, map->n, map->flags);
5339         if (!result)
5340                 goto error;
5341         for (i = 0; i < map->n; ++i)
5342                 result = isl_set_add_basic_set(result,
5343                           isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
5344         isl_map_free(map);
5345         return result;
5346 error:
5347         isl_map_free(map);
5348         return NULL;
5349 }
5350
5351 static struct isl_basic_map *basic_map_identity(struct isl_dim *dims)
5352 {
5353         struct isl_basic_map *bmap;
5354         unsigned nparam;
5355         unsigned dim;
5356         int i;
5357
5358         if (!dims)
5359                 return NULL;
5360
5361         nparam = dims->nparam;
5362         dim = dims->n_out;
5363         bmap = isl_basic_map_alloc_dim(dims, 0, dim, 0);
5364         if (!bmap)
5365                 goto error;
5366
5367         for (i = 0; i < dim; ++i) {
5368                 int j = isl_basic_map_alloc_equality(bmap);
5369                 if (j < 0)
5370                         goto error;
5371                 isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
5372                 isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
5373                 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], -1);
5374         }
5375         return isl_basic_map_finalize(bmap);
5376 error:
5377         isl_basic_map_free(bmap);
5378         return NULL;
5379 }
5380
5381 struct isl_basic_map *isl_basic_map_identity(struct isl_dim *set_dim)
5382 {
5383         struct isl_dim *dim = isl_dim_map(set_dim);
5384         if (!dim)
5385                 return NULL;
5386         return basic_map_identity(dim);
5387 }
5388
5389 struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model)
5390 {
5391         if (!model || !model->dim)
5392                 return NULL;
5393         isl_assert(model->ctx,
5394                         model->dim->n_in == model->dim->n_out, return NULL);
5395         return basic_map_identity(isl_dim_copy(model->dim));
5396 }
5397
5398 static struct isl_map *map_identity(struct isl_dim *dim)
5399 {
5400         struct isl_map *map = isl_map_alloc_dim(dim, 1, ISL_MAP_DISJOINT);
5401         return isl_map_add_basic_map(map, basic_map_identity(isl_dim_copy(dim)));
5402 }
5403
5404 struct isl_map *isl_map_identity(struct isl_dim *set_dim)
5405 {
5406         struct isl_dim *dim = isl_dim_map(set_dim);
5407         if (!dim)
5408                 return NULL;
5409         return map_identity(dim);
5410 }
5411
5412 struct isl_map *isl_map_identity_like(struct isl_map *model)
5413 {
5414         if (!model || !model->dim)
5415                 return NULL;
5416         isl_assert(model->ctx,
5417                         model->dim->n_in == model->dim->n_out, return NULL);
5418         return map_identity(isl_dim_copy(model->dim));
5419 }
5420
5421 struct isl_map *isl_map_identity_like_basic_map(struct isl_basic_map *model)
5422 {
5423         if (!model || !model->dim)
5424                 return NULL;
5425         isl_assert(model->ctx,
5426                         model->dim->n_in == model->dim->n_out, return NULL);
5427         return map_identity(isl_dim_copy(model->dim));
5428 }
5429
5430 /* Construct a basic set with all set dimensions having only non-negative
5431  * values.
5432  */
5433 struct isl_basic_set *isl_basic_set_positive_orthant(struct isl_dim *dims)
5434 {
5435         int i;
5436         unsigned nparam;
5437         unsigned dim;
5438         struct isl_basic_set *bset;
5439
5440         if (!dims)
5441                 return NULL;
5442         nparam = dims->nparam;
5443         dim = dims->n_out;
5444         bset = isl_basic_set_alloc_dim(dims, 0, 0, dim);
5445         if (!bset)
5446                 return NULL;
5447         for (i = 0; i < dim; ++i) {
5448                 int k = isl_basic_set_alloc_inequality(bset);
5449                 if (k < 0)
5450                         goto error;
5451                 isl_seq_clr(bset->ineq[k], 1 + isl_basic_set_total_dim(bset));
5452                 isl_int_set_si(bset->ineq[k][1 + nparam + i], 1);
5453         }
5454         return bset;
5455 error:
5456         isl_basic_set_free(bset);
5457         return NULL;
5458 }
5459
5460 __isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set,
5461         enum isl_dim_type type, unsigned first, unsigned n)
5462 {
5463         int i;
5464         isl_basic_set *nonneg = NULL;
5465         isl_basic_set *neg = NULL;
5466
5467         if (!set)
5468                 return NULL;
5469         if (n == 0)
5470                 return set;
5471
5472         isl_assert(set->ctx, first + n <= isl_set_dim(set, type), goto error);
5473
5474         for (i = 0; i < n; ++i) {
5475                 int k;
5476
5477                 neg = NULL;
5478                 nonneg = isl_basic_set_alloc_dim(isl_set_get_dim(set), 0, 0, 1);
5479                 k = isl_basic_set_alloc_inequality(nonneg);
5480                 if (k < 0)
5481                         goto error;
5482                 isl_seq_clr(nonneg->ineq[k], 1 + isl_basic_set_total_dim(nonneg));
5483                 isl_int_set_si(nonneg->ineq[k][pos(set->dim, type) + first + i], 1);
5484
5485                 neg = isl_basic_set_alloc_dim(isl_set_get_dim(set), 0, 0, 1);
5486                 k = isl_basic_set_alloc_inequality(neg);
5487                 if (k < 0)
5488                         goto error;
5489                 isl_seq_clr(neg->ineq[k], 1 + isl_basic_set_total_dim(neg));
5490                 isl_int_set_si(neg->ineq[k][0], -1);
5491                 isl_int_set_si(neg->ineq[k][pos(set->dim, type) + first + i], -1);
5492
5493                 set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
5494         }
5495
5496         return set;
5497 error:
5498         isl_basic_set_free(nonneg);
5499         isl_basic_set_free(neg);
5500         isl_set_free(set);
5501         return NULL;
5502 }
5503
5504 int isl_set_is_equal(struct isl_set *set1, struct isl_set *set2)
5505 {
5506         return isl_map_is_equal((struct isl_map *)set1, (struct isl_map *)set2);
5507 }
5508
5509 int isl_basic_map_is_subset(
5510                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
5511 {
5512         int is_subset;
5513         struct isl_map *map1;
5514         struct isl_map *map2;
5515
5516         if (!bmap1 || !bmap2)
5517                 return -1;
5518
5519         map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
5520         map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
5521
5522         is_subset = isl_map_is_subset(map1, map2);
5523
5524         isl_map_free(map1);
5525         isl_map_free(map2);
5526
5527         return is_subset;
5528 }
5529
5530 int isl_basic_map_is_equal(
5531                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
5532 {
5533         int is_subset;
5534
5535         if (!bmap1 || !bmap2)
5536                 return -1;
5537         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
5538         if (is_subset != 1)
5539                 return is_subset;
5540         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
5541         return is_subset;
5542 }
5543
5544 int isl_basic_set_is_equal(
5545                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
5546 {
5547         return isl_basic_map_is_equal(
5548                 (struct isl_basic_map *)bset1, (struct isl_basic_map *)bset2);
5549 }
5550
5551 int isl_map_is_empty(struct isl_map *map)
5552 {
5553         int i;
5554         int is_empty;
5555
5556         if (!map)
5557                 return -1;
5558         for (i = 0; i < map->n; ++i) {
5559                 is_empty = isl_basic_map_is_empty(map->p[i]);
5560                 if (is_empty < 0)
5561                         return -1;
5562                 if (!is_empty)
5563                         return 0;
5564         }
5565         return 1;
5566 }
5567
5568 int isl_map_fast_is_empty(struct isl_map *map)
5569 {
5570         return map ? map->n == 0 : -1;
5571 }
5572
5573 int isl_set_fast_is_empty(struct isl_set *set)
5574 {
5575         return set ? set->n == 0 : -1;
5576 }
5577
5578 int isl_set_is_empty(struct isl_set *set)
5579 {
5580         return isl_map_is_empty((struct isl_map *)set);
5581 }
5582
5583 int isl_map_has_equal_dim(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
5584 {
5585         if (!map1 || !map2)
5586                 return -1;
5587
5588         return isl_dim_equal(map1->dim, map2->dim);
5589 }
5590
5591 int isl_set_has_equal_dim(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
5592 {
5593         if (!set1 || !set2)
5594                 return -1;
5595
5596         return isl_dim_equal(set1->dim, set2->dim);
5597 }
5598
5599 int isl_map_is_equal(struct isl_map *map1, struct isl_map *map2)
5600 {
5601         int is_subset;
5602
5603         if (!map1 || !map2)
5604                 return -1;
5605         is_subset = isl_map_is_subset(map1, map2);
5606         if (is_subset != 1)
5607                 return is_subset;
5608         is_subset = isl_map_is_subset(map2, map1);
5609         return is_subset;
5610 }
5611
5612 int isl_basic_map_is_strict_subset(
5613                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
5614 {
5615         int is_subset;
5616
5617         if (!bmap1 || !bmap2)
5618                 return -1;
5619         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
5620         if (is_subset != 1)
5621                 return is_subset;
5622         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
5623         if (is_subset == -1)
5624                 return is_subset;
5625         return !is_subset;
5626 }
5627
5628 int isl_map_is_strict_subset(struct isl_map *map1, struct isl_map *map2)
5629 {
5630         int is_subset;
5631
5632         if (!map1 || !map2)
5633                 return -1;
5634         is_subset = isl_map_is_subset(map1, map2);
5635         if (is_subset != 1)
5636                 return is_subset;
5637         is_subset = isl_map_is_subset(map2, map1);
5638         if (is_subset == -1)
5639                 return is_subset;
5640         return !is_subset;
5641 }
5642
5643 int isl_set_is_strict_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
5644 {
5645         return isl_map_is_strict_subset((isl_map *)set1, (isl_map *)set2);
5646 }
5647
5648 int isl_basic_map_is_universe(struct isl_basic_map *bmap)
5649 {
5650         if (!bmap)
5651                 return -1;
5652         return bmap->n_eq == 0 && bmap->n_ineq == 0;
5653 }
5654
5655 int isl_basic_set_is_universe(struct isl_basic_set *bset)
5656 {
5657         if (!bset)
5658                 return -1;
5659         return bset->n_eq == 0 && bset->n_ineq == 0;
5660 }
5661
5662 int isl_map_fast_is_universe(__isl_keep isl_map *map)
5663 {
5664         int i;
5665
5666         if (!map)
5667                 return -1;
5668
5669         for (i = 0; i < map->n; ++i) {
5670                 int r = isl_basic_map_is_universe(map->p[i]);
5671                 if (r < 0 || r)
5672                         return r;
5673         }
5674
5675         return 0;
5676 }
5677
5678 int isl_set_fast_is_universe(__isl_keep isl_set *set)
5679 {
5680         return isl_map_fast_is_universe((isl_map *) set);
5681 }
5682
5683 int isl_basic_map_is_empty(struct isl_basic_map *bmap)
5684 {
5685         struct isl_basic_set *bset = NULL;
5686         struct isl_vec *sample = NULL;
5687         int empty;
5688         unsigned total;
5689
5690         if (!bmap)
5691                 return -1;
5692
5693         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
5694                 return 1;
5695
5696         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
5697                 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
5698                 copy = isl_basic_map_remove_redundancies(copy);
5699                 empty = ISL_F_ISSET(copy, ISL_BASIC_MAP_EMPTY);
5700                 isl_basic_map_free(copy);
5701                 return empty;
5702         }
5703
5704         total = 1 + isl_basic_map_total_dim(bmap);
5705         if (bmap->sample && bmap->sample->size == total) {
5706                 int contains = isl_basic_map_contains(bmap, bmap->sample);
5707                 if (contains < 0)
5708                         return -1;
5709                 if (contains)
5710                         return 0;
5711         }
5712         isl_vec_free(bmap->sample);
5713         bmap->sample = NULL;
5714         bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
5715         if (!bset)
5716                 return -1;
5717         sample = isl_basic_set_sample_vec(bset);
5718         if (!sample)
5719                 return -1;
5720         empty = sample->size == 0;
5721         isl_vec_free(bmap->sample);
5722         bmap->sample = sample;
5723         if (empty)
5724                 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
5725
5726         return empty;
5727 }
5728
5729 int isl_basic_map_fast_is_empty(struct isl_basic_map *bmap)
5730 {
5731         if (!bmap)
5732                 return -1;
5733         return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY);
5734 }
5735
5736 int isl_basic_set_fast_is_empty(struct isl_basic_set *bset)
5737 {
5738         if (!bset)
5739                 return -1;
5740         return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY);
5741 }
5742
5743 int isl_basic_set_is_empty(struct isl_basic_set *bset)
5744 {
5745         return isl_basic_map_is_empty((struct isl_basic_map *)bset);
5746 }
5747
5748 struct isl_map *isl_basic_map_union(
5749         struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
5750 {
5751         struct isl_map *map;
5752         if (!bmap1 || !bmap2)
5753                 return NULL;
5754
5755         isl_assert(bmap1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim), goto error);
5756
5757         map = isl_map_alloc_dim(isl_dim_copy(bmap1->dim), 2, 0);
5758         if (!map)
5759                 goto error;
5760         map = isl_map_add_basic_map(map, bmap1);
5761         map = isl_map_add_basic_map(map, bmap2);
5762         return map;
5763 error:
5764         isl_basic_map_free(bmap1);
5765         isl_basic_map_free(bmap2);
5766         return NULL;
5767 }
5768
5769 struct isl_set *isl_basic_set_union(
5770                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
5771 {
5772         return (struct isl_set *)isl_basic_map_union(
5773                                             (struct isl_basic_map *)bset1,
5774                                             (struct isl_basic_map *)bset2);
5775 }
5776
5777 /* Order divs such that any div only depends on previous divs */
5778 struct isl_basic_map *isl_basic_map_order_divs(struct isl_basic_map *bmap)
5779 {
5780         int i;
5781         unsigned off;
5782
5783         if (!bmap)
5784                 return NULL;
5785
5786         off = isl_dim_total(bmap->dim);
5787
5788         for (i = 0; i < bmap->n_div; ++i) {
5789                 int pos;
5790                 if (isl_int_is_zero(bmap->div[i][0]))
5791                         continue;
5792                 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
5793                                                             bmap->n_div-i);
5794                 if (pos == -1)
5795                         continue;
5796                 isl_basic_map_swap_div(bmap, i, i + pos);
5797                 --i;
5798         }
5799         return bmap;
5800 }
5801
5802 struct isl_basic_set *isl_basic_set_order_divs(struct isl_basic_set *bset)
5803 {
5804         return (struct isl_basic_set *)
5805                 isl_basic_map_order_divs((struct isl_basic_map *)bset);
5806 }
5807
5808 __isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
5809 {
5810         int i;
5811
5812         if (!map)
5813                 return 0;
5814
5815         for (i = 0; i < map->n; ++i) {
5816                 map->p[i] = isl_basic_map_order_divs(map->p[i]);
5817                 if (!map->p[i])
5818                         goto error;
5819         }
5820
5821         return map;
5822 error:
5823         isl_map_free(map);
5824         return NULL;
5825 }
5826
5827 /* Look for a div in dst that corresponds to the div "div" in src.
5828  * The divs before "div" in src and dst are assumed to be the same.
5829  * 
5830  * Returns -1 if no corresponding div was found and the position
5831  * of the corresponding div in dst otherwise.
5832  */
5833 static int find_div(struct isl_basic_map *dst,
5834                         struct isl_basic_map *src, unsigned div)
5835 {
5836         int i;
5837
5838         unsigned total = isl_dim_total(src->dim);
5839
5840         isl_assert(dst->ctx, div <= dst->n_div, return -1);
5841         for (i = div; i < dst->n_div; ++i)
5842                 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total+div) &&
5843                     isl_seq_first_non_zero(dst->div[i]+1+1+total+div,
5844                                                 dst->n_div - div) == -1)
5845                         return i;
5846         return -1;
5847 }
5848
5849 struct isl_basic_map *isl_basic_map_align_divs(
5850                 struct isl_basic_map *dst, struct isl_basic_map *src)
5851 {
5852         int i;
5853         unsigned total = isl_dim_total(src->dim);
5854
5855         if (!dst || !src)
5856                 goto error;
5857
5858         if (src->n_div == 0)
5859                 return dst;
5860
5861         for (i = 0; i < src->n_div; ++i)
5862                 isl_assert(src->ctx, !isl_int_is_zero(src->div[i][0]), goto error);
5863
5864         src = isl_basic_map_order_divs(src);
5865         dst = isl_basic_map_cow(dst);
5866         dst = isl_basic_map_extend_dim(dst, isl_dim_copy(dst->dim),
5867                         src->n_div, 0, 2 * src->n_div);
5868         if (!dst)
5869                 return NULL;
5870         for (i = 0; i < src->n_div; ++i) {
5871                 int j = find_div(dst, src, i);
5872                 if (j < 0) {
5873                         j = isl_basic_map_alloc_div(dst);
5874                         if (j < 0)
5875                                 goto error;
5876                         isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i);
5877                         isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i);
5878                         if (isl_basic_map_add_div_constraints(dst, j) < 0)
5879                                 goto error;
5880                 }
5881                 if (j != i)
5882                         isl_basic_map_swap_div(dst, i, j);
5883         }
5884         return dst;
5885 error:
5886         isl_basic_map_free(dst);
5887         return NULL;
5888 }
5889
5890 struct isl_basic_set *isl_basic_set_align_divs(
5891                 struct isl_basic_set *dst, struct isl_basic_set *src)
5892 {
5893         return (struct isl_basic_set *)isl_basic_map_align_divs(
5894                 (struct isl_basic_map *)dst, (struct isl_basic_map *)src);
5895 }
5896
5897 struct isl_map *isl_map_align_divs(struct isl_map *map)
5898 {
5899         int i;
5900
5901         if (!map)
5902                 return NULL;
5903         if (map->n == 0)
5904                 return map;
5905         map = isl_map_compute_divs(map);
5906         map = isl_map_cow(map);
5907         if (!map)
5908                 return NULL;
5909
5910         for (i = 1; i < map->n; ++i)
5911                 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
5912         for (i = 1; i < map->n; ++i)
5913                 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
5914
5915         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
5916         return map;
5917 }
5918
5919 struct isl_set *isl_set_align_divs(struct isl_set *set)
5920 {
5921         return (struct isl_set *)isl_map_align_divs((struct isl_map *)set);
5922 }
5923
5924 struct isl_set *isl_set_apply(struct isl_set *set, struct isl_map *map)
5925 {
5926         if (!set || !map)
5927                 goto error;
5928         isl_assert(set->ctx, isl_map_compatible_domain(map, set), goto error);
5929         map = isl_map_intersect_domain(map, set);
5930         set = isl_map_range(map);
5931         return set;
5932 error:
5933         isl_set_free(set);
5934         isl_map_free(map);
5935         return NULL;
5936 }
5937
5938 /* There is no need to cow as removing empty parts doesn't change
5939  * the meaning of the set.
5940  */
5941 struct isl_map *isl_map_remove_empty_parts(struct isl_map *map)
5942 {
5943         int i;
5944
5945         if (!map)
5946                 return NULL;
5947
5948         for (i = map->n-1; i >= 0; --i) {
5949                 if (!ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_EMPTY))
5950                         continue;
5951                 isl_basic_map_free(map->p[i]);
5952                 if (i != map->n-1) {
5953                         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
5954                         map->p[i] = map->p[map->n-1];
5955                 }
5956                 map->n--;
5957         }
5958
5959         return map;
5960 }
5961
5962 struct isl_set *isl_set_remove_empty_parts(struct isl_set *set)
5963 {
5964         return (struct isl_set *)
5965                 isl_map_remove_empty_parts((struct isl_map *)set);
5966 }
5967
5968 struct isl_basic_map *isl_map_copy_basic_map(struct isl_map *map)
5969 {
5970         struct isl_basic_map *bmap;
5971         if (!map || map->n == 0)
5972                 return NULL;
5973         bmap = map->p[map->n-1];
5974         isl_assert(map->ctx, ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL), return NULL);
5975         return isl_basic_map_copy(bmap);
5976 }
5977
5978 struct isl_basic_set *isl_set_copy_basic_set(struct isl_set *set)
5979 {
5980         return (struct isl_basic_set *)
5981                 isl_map_copy_basic_map((struct isl_map *)set);
5982 }
5983
5984 __isl_give isl_map *isl_map_drop_basic_map(__isl_take isl_map *map,
5985                                                 __isl_keep isl_basic_map *bmap)
5986 {
5987         int i;
5988
5989         if (!map || !bmap)
5990                 goto error;
5991         for (i = map->n-1; i >= 0; --i) {
5992                 if (map->p[i] != bmap)
5993                         continue;
5994                 map = isl_map_cow(map);
5995                 if (!map)
5996                         goto error;
5997                 isl_basic_map_free(map->p[i]);
5998                 if (i != map->n-1) {
5999                         ISL_F_CLR(map, ISL_SET_NORMALIZED);
6000                         map->p[i] = map->p[map->n-1];
6001                 }
6002                 map->n--;
6003                 return map;
6004         }
6005         return map;
6006 error:
6007         isl_map_free(map);
6008         return NULL;
6009 }
6010
6011 struct isl_set *isl_set_drop_basic_set(struct isl_set *set,
6012                                                 struct isl_basic_set *bset)
6013 {
6014         return (struct isl_set *)isl_map_drop_basic_map((struct isl_map *)set,
6015                                                 (struct isl_basic_map *)bset);
6016 }
6017
6018 /* Given two basic sets bset1 and bset2, compute the maximal difference
6019  * between the values of dimension pos in bset1 and those in bset2
6020  * for any common value of the parameters and dimensions preceding pos.
6021  */
6022 static enum isl_lp_result basic_set_maximal_difference_at(
6023         __isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2,
6024         int pos, isl_int *opt)
6025 {
6026         struct isl_dim *dims;
6027         struct isl_basic_map *bmap1 = NULL;
6028         struct isl_basic_map *bmap2 = NULL;
6029         struct isl_ctx *ctx;
6030         struct isl_vec *obj;
6031         unsigned total;
6032         unsigned nparam;
6033         unsigned dim1, dim2;
6034         enum isl_lp_result res;
6035
6036         if (!bset1 || !bset2)
6037                 return isl_lp_error;
6038
6039         nparam = isl_basic_set_n_param(bset1);
6040         dim1 = isl_basic_set_n_dim(bset1);
6041         dim2 = isl_basic_set_n_dim(bset2);
6042         dims = isl_dim_alloc(bset1->ctx, nparam, pos, dim1 - pos);
6043         bmap1 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset1), dims);
6044         dims = isl_dim_alloc(bset2->ctx, nparam, pos, dim2 - pos);
6045         bmap2 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset2), dims);
6046         if (!bmap1 || !bmap2)
6047                 goto error;
6048         bmap1 = isl_basic_map_cow(bmap1);
6049         bmap1 = isl_basic_map_extend(bmap1, nparam,
6050                         pos, (dim1 - pos) + (dim2 - pos),
6051                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
6052         bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos);
6053         if (!bmap1)
6054                 goto error;
6055         total = isl_basic_map_total_dim(bmap1);
6056         ctx = bmap1->ctx;
6057         obj = isl_vec_alloc(ctx, 1 + total);
6058         isl_seq_clr(obj->block.data, 1 + total);
6059         isl_int_set_si(obj->block.data[1+nparam+pos], 1);
6060         isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
6061         if (!obj)
6062                 goto error;
6063         res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
6064                                         opt, NULL, NULL);
6065         isl_basic_map_free(bmap1);
6066         isl_vec_free(obj);
6067         return res;
6068 error:
6069         isl_basic_map_free(bmap1);
6070         isl_basic_map_free(bmap2);
6071         return isl_lp_error;
6072 }
6073
6074 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
6075  * for any common value of the parameters and dimensions preceding pos
6076  * in both basic sets, the values of dimension pos in bset1 are
6077  * smaller or larger than those in bset2.
6078  *
6079  * Returns
6080  *       1 if bset1 follows bset2
6081  *      -1 if bset1 precedes bset2
6082  *       0 if bset1 and bset2 are incomparable
6083  *      -2 if some error occurred.
6084  */
6085 int isl_basic_set_compare_at(struct isl_basic_set *bset1,
6086         struct isl_basic_set *bset2, int pos)
6087 {
6088         isl_int opt;
6089         enum isl_lp_result res;
6090         int cmp;
6091
6092         isl_int_init(opt);
6093
6094         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
6095
6096         if (res == isl_lp_empty)
6097                 cmp = 0;
6098         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
6099                   res == isl_lp_unbounded)
6100                 cmp = 1;
6101         else if (res == isl_lp_ok && isl_int_is_neg(opt))
6102                 cmp = -1;
6103         else
6104                 cmp = -2;
6105
6106         isl_int_clear(opt);
6107         return cmp;
6108 }
6109
6110 /* Given two basic sets bset1 and bset2, check whether
6111  * for any common value of the parameters and dimensions preceding pos
6112  * there is a value of dimension pos in bset1 that is larger
6113  * than a value of the same dimension in bset2.
6114  *
6115  * Return
6116  *       1 if there exists such a pair
6117  *       0 if there is no such pair, but there is a pair of equal values
6118  *      -1 otherwise
6119  *      -2 if some error occurred.
6120  */
6121 int isl_basic_set_follows_at(__isl_keep isl_basic_set *bset1,
6122         __isl_keep isl_basic_set *bset2, int pos)
6123 {
6124         isl_int opt;
6125         enum isl_lp_result res;
6126         int cmp;
6127
6128         isl_int_init(opt);
6129
6130         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
6131
6132         if (res == isl_lp_empty)
6133                 cmp = -1;
6134         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
6135                   res == isl_lp_unbounded)
6136                 cmp = 1;
6137         else if (res == isl_lp_ok && isl_int_is_neg(opt))
6138                 cmp = -1;
6139         else if (res == isl_lp_ok)
6140                 cmp = 0;
6141         else
6142                 cmp = -2;
6143
6144         isl_int_clear(opt);
6145         return cmp;
6146 }
6147
6148 /* Given two sets set1 and set2, check whether
6149  * for any common value of the parameters and dimensions preceding pos
6150  * there is a value of dimension pos in set1 that is larger
6151  * than a value of the same dimension in set2.
6152  *
6153  * Return
6154  *       1 if there exists such a pair
6155  *       0 if there is no such pair, but there is a pair of equal values
6156  *      -1 otherwise
6157  *      -2 if some error occurred.
6158  */
6159 int isl_set_follows_at(__isl_keep isl_set *set1,
6160         __isl_keep isl_set *set2, int pos)
6161 {
6162         int i, j;
6163         int follows = -1;
6164
6165         if (!set1 || !set2)
6166                 return -2;
6167
6168         for (i = 0; i < set1->n; ++i)
6169                 for (j = 0; j < set2->n; ++j) {
6170                         int f;
6171                         f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
6172                         if (f == 1 || f == -2)
6173                                 return f;
6174                         if (f > follows)
6175                                 follows = f;
6176                 }
6177
6178         return follows;
6179 }
6180
6181 static int isl_basic_map_fast_has_fixed_var(struct isl_basic_map *bmap,
6182         unsigned pos, isl_int *val)
6183 {
6184         int i;
6185         int d;
6186         unsigned total;
6187
6188         if (!bmap)
6189                 return -1;
6190         total = isl_basic_map_total_dim(bmap);
6191         for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
6192                 for (; d+1 > pos; --d)
6193                         if (!isl_int_is_zero(bmap->eq[i][1+d]))
6194                                 break;
6195                 if (d != pos)
6196                         continue;
6197                 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
6198                         return 0;
6199                 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
6200                         return 0;
6201                 if (!isl_int_is_one(bmap->eq[i][1+d]))
6202                         return 0;
6203                 if (val)
6204                         isl_int_neg(*val, bmap->eq[i][0]);
6205                 return 1;
6206         }
6207         return 0;
6208 }
6209
6210 static int isl_map_fast_has_fixed_var(struct isl_map *map,
6211         unsigned pos, isl_int *val)
6212 {
6213         int i;
6214         isl_int v;
6215         isl_int tmp;
6216         int fixed;
6217
6218         if (!map)
6219                 return -1;
6220         if (map->n == 0)
6221                 return 0;
6222         if (map->n == 1)
6223                 return isl_basic_map_fast_has_fixed_var(map->p[0], pos, val); 
6224         isl_int_init(v);
6225         isl_int_init(tmp);
6226         fixed = isl_basic_map_fast_has_fixed_var(map->p[0], pos, &v); 
6227         for (i = 1; fixed == 1 && i < map->n; ++i) {
6228                 fixed = isl_basic_map_fast_has_fixed_var(map->p[i], pos, &tmp); 
6229                 if (fixed == 1 && isl_int_ne(tmp, v))
6230                         fixed = 0;
6231         }
6232         if (val)
6233                 isl_int_set(*val, v);
6234         isl_int_clear(tmp);
6235         isl_int_clear(v);
6236         return fixed;
6237 }
6238
6239 static int isl_basic_set_fast_has_fixed_var(struct isl_basic_set *bset,
6240         unsigned pos, isl_int *val)
6241 {
6242         return isl_basic_map_fast_has_fixed_var((struct isl_basic_map *)bset,
6243                                                 pos, val);
6244 }
6245
6246 static int isl_set_fast_has_fixed_var(struct isl_set *set, unsigned pos,
6247         isl_int *val)
6248 {
6249         return isl_map_fast_has_fixed_var((struct isl_map *)set, pos, val);
6250 }
6251
6252 int isl_basic_map_fast_is_fixed(struct isl_basic_map *bmap,
6253         enum isl_dim_type type, unsigned pos, isl_int *val)
6254 {
6255         if (pos >= isl_basic_map_dim(bmap, type))
6256                 return -1;
6257         return isl_basic_map_fast_has_fixed_var(bmap,
6258                 isl_basic_map_offset(bmap, type) - 1 + pos, val);
6259 }
6260
6261 int isl_map_fast_is_fixed(struct isl_map *map,
6262         enum isl_dim_type type, unsigned pos, isl_int *val)
6263 {
6264         if (pos >= isl_map_dim(map, type))
6265                 return -1;
6266         return isl_map_fast_has_fixed_var(map,
6267                 map_offset(map, type) - 1 + pos, val);
6268 }
6269
6270 /* Check if dimension dim has fixed value and if so and if val is not NULL,
6271  * then return this fixed value in *val.
6272  */
6273 int isl_basic_set_fast_dim_is_fixed(struct isl_basic_set *bset, unsigned dim,
6274         isl_int *val)
6275 {
6276         return isl_basic_set_fast_has_fixed_var(bset,
6277                                         isl_basic_set_n_param(bset) + dim, val);
6278 }
6279
6280 /* Check if dimension dim has fixed value and if so and if val is not NULL,
6281  * then return this fixed value in *val.
6282  */
6283 int isl_set_fast_dim_is_fixed(struct isl_set *set, unsigned dim, isl_int *val)
6284 {
6285         return isl_set_fast_has_fixed_var(set, isl_set_n_param(set) + dim, val);
6286 }
6287
6288 /* Check if input variable in has fixed value and if so and if val is not NULL,
6289  * then return this fixed value in *val.
6290  */
6291 int isl_map_fast_input_is_fixed(struct isl_map *map, unsigned in, isl_int *val)
6292 {
6293         return isl_map_fast_has_fixed_var(map, isl_map_n_param(map) + in, val);
6294 }
6295
6296 /* Check if dimension dim has an (obvious) fixed lower bound and if so
6297  * and if val is not NULL, then return this lower bound in *val.
6298  */
6299 int isl_basic_set_fast_dim_has_fixed_lower_bound(struct isl_basic_set *bset,
6300         unsigned dim, isl_int *val)
6301 {
6302         int i, i_eq = -1, i_ineq = -1;
6303         isl_int *c;
6304         unsigned total;
6305         unsigned nparam;
6306
6307         if (!bset)
6308                 return -1;
6309         total = isl_basic_set_total_dim(bset);
6310         nparam = isl_basic_set_n_param(bset);
6311         for (i = 0; i < bset->n_eq; ++i) {
6312                 if (isl_int_is_zero(bset->eq[i][1+nparam+dim]))
6313                         continue;
6314                 if (i_eq != -1)
6315                         return 0;
6316                 i_eq = i;
6317         }
6318         for (i = 0; i < bset->n_ineq; ++i) {
6319                 if (!isl_int_is_pos(bset->ineq[i][1+nparam+dim]))
6320                         continue;
6321                 if (i_eq != -1 || i_ineq != -1)
6322                         return 0;
6323                 i_ineq = i;
6324         }
6325         if (i_eq == -1 && i_ineq == -1)
6326                 return 0;
6327         c = i_eq != -1 ? bset->eq[i_eq] : bset->ineq[i_ineq];
6328         /* The coefficient should always be one due to normalization. */
6329         if (!isl_int_is_one(c[1+nparam+dim]))
6330                 return 0;
6331         if (isl_seq_first_non_zero(c+1, nparam+dim) != -1)
6332                 return 0;
6333         if (isl_seq_first_non_zero(c+1+nparam+dim+1,
6334                                         total - nparam - dim - 1) != -1)
6335                 return 0;
6336         if (val)
6337                 isl_int_neg(*val, c[0]);
6338         return 1;
6339 }
6340
6341 int isl_set_fast_dim_has_fixed_lower_bound(struct isl_set *set,
6342         unsigned dim, isl_int *val)
6343 {
6344         int i;
6345         isl_int v;
6346         isl_int tmp;
6347         int fixed;
6348
6349         if (!set)
6350                 return -1;
6351         if (set->n == 0)
6352                 return 0;
6353         if (set->n == 1)
6354                 return isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
6355                                                                 dim, val);
6356         isl_int_init(v);
6357         isl_int_init(tmp);
6358         fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
6359                                                                 dim, &v);
6360         for (i = 1; fixed == 1 && i < set->n; ++i) {
6361                 fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[i],
6362                                                                 dim, &tmp);
6363                 if (fixed == 1 && isl_int_ne(tmp, v))
6364                         fixed = 0;
6365         }
6366         if (val)
6367                 isl_int_set(*val, v);
6368         isl_int_clear(tmp);
6369         isl_int_clear(v);
6370         return fixed;
6371 }
6372
6373 struct constraint {
6374         unsigned        size;
6375         isl_int         *c;
6376 };
6377
6378 static int qsort_constraint_cmp(const void *p1, const void *p2)
6379 {
6380         const struct constraint *c1 = (const struct constraint *)p1;
6381         const struct constraint *c2 = (const struct constraint *)p2;
6382         unsigned size = isl_min(c1->size, c2->size);
6383         return isl_seq_cmp(c1->c, c2->c, size);
6384 }
6385
6386 static struct isl_basic_map *isl_basic_map_sort_constraints(
6387         struct isl_basic_map *bmap)
6388 {
6389         int i;
6390         struct constraint *c;
6391         unsigned total;
6392
6393         if (!bmap)
6394                 return NULL;
6395         total = isl_basic_map_total_dim(bmap);
6396         c = isl_alloc_array(bmap->ctx, struct constraint, bmap->n_ineq);
6397         if (!c)
6398                 goto error;
6399         for (i = 0; i < bmap->n_ineq; ++i) {
6400                 c[i].size = total;
6401                 c[i].c = bmap->ineq[i];
6402         }
6403         qsort(c, bmap->n_ineq, sizeof(struct constraint), qsort_constraint_cmp);
6404         for (i = 0; i < bmap->n_ineq; ++i)
6405                 bmap->ineq[i] = c[i].c;
6406         free(c);
6407         return bmap;
6408 error:
6409         isl_basic_map_free(bmap);
6410         return NULL;
6411 }
6412
6413 __isl_give isl_basic_set *isl_basic_set_sort_constraints(
6414         __isl_take isl_basic_set *bset)
6415 {
6416         return (struct isl_basic_set *)isl_basic_map_sort_constraints(
6417                                                 (struct isl_basic_map *)bset);
6418 }
6419
6420 struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap)
6421 {
6422         if (!bmap)
6423                 return NULL;
6424         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED))
6425                 return bmap;
6426         bmap = isl_basic_map_remove_redundancies(bmap);
6427         bmap = isl_basic_map_sort_constraints(bmap);
6428         ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
6429         return bmap;
6430 }
6431
6432 struct isl_basic_set *isl_basic_set_normalize(struct isl_basic_set *bset)
6433 {
6434         return (struct isl_basic_set *)isl_basic_map_normalize(
6435                                                 (struct isl_basic_map *)bset);
6436 }
6437
6438 int isl_basic_map_fast_cmp(const __isl_keep isl_basic_map *bmap1,
6439         const __isl_keep isl_basic_map *bmap2)
6440 {
6441         int i, cmp;
6442         unsigned total;
6443
6444         if (bmap1 == bmap2)
6445                 return 0;
6446         if (isl_basic_map_n_param(bmap1) != isl_basic_map_n_param(bmap2))
6447                 return isl_basic_map_n_param(bmap1) - isl_basic_map_n_param(bmap2);
6448         if (isl_basic_map_n_in(bmap1) != isl_basic_map_n_in(bmap2))
6449                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
6450         if (isl_basic_map_n_out(bmap1) != isl_basic_map_n_out(bmap2))
6451                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
6452         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
6453             ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
6454                 return 0;
6455         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
6456                 return 1;
6457         if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
6458                 return -1;
6459         if (bmap1->n_eq != bmap2->n_eq)
6460                 return bmap1->n_eq - bmap2->n_eq;
6461         if (bmap1->n_ineq != bmap2->n_ineq)
6462                 return bmap1->n_ineq - bmap2->n_ineq;
6463         if (bmap1->n_div != bmap2->n_div)
6464                 return bmap1->n_div - bmap2->n_div;
6465         total = isl_basic_map_total_dim(bmap1);
6466         for (i = 0; i < bmap1->n_eq; ++i) {
6467                 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
6468                 if (cmp)
6469                         return cmp;
6470         }
6471         for (i = 0; i < bmap1->n_ineq; ++i) {
6472                 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
6473                 if (cmp)
6474                         return cmp;
6475         }
6476         for (i = 0; i < bmap1->n_div; ++i) {
6477                 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
6478                 if (cmp)
6479                         return cmp;
6480         }
6481         return 0;
6482 }
6483
6484 int isl_basic_map_fast_is_equal(__isl_keep isl_basic_map *bmap1,
6485         __isl_keep isl_basic_map *bmap2)
6486 {
6487         return isl_basic_map_fast_cmp(bmap1, bmap2) == 0;
6488 }
6489
6490 int isl_basic_set_fast_is_equal(__isl_keep isl_basic_set *bset1,
6491         __isl_keep isl_basic_set *bset2)
6492 {
6493         return isl_basic_map_fast_is_equal((isl_basic_map *)bset1,
6494                                             (isl_basic_map *)bset2);
6495 }
6496
6497 static int qsort_bmap_cmp(const void *p1, const void *p2)
6498 {
6499         const struct isl_basic_map *bmap1 = *(const struct isl_basic_map **)p1;
6500         const struct isl_basic_map *bmap2 = *(const struct isl_basic_map **)p2;
6501
6502         return isl_basic_map_fast_cmp(bmap1, bmap2);
6503 }
6504
6505 /* We normalize in place, but if anything goes wrong we need
6506  * to return NULL, so we need to make sure we don't change the
6507  * meaning of any possible other copies of map.
6508  */
6509 struct isl_map *isl_map_normalize(struct isl_map *map)
6510 {
6511         int i, j;
6512         struct isl_basic_map *bmap;
6513
6514         if (!map)
6515                 return NULL;
6516         if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED))
6517                 return map;
6518         for (i = 0; i < map->n; ++i) {
6519                 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
6520                 if (!bmap)
6521                         goto error;
6522                 isl_basic_map_free(map->p[i]);
6523                 map->p[i] = bmap;
6524         }
6525         qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
6526         ISL_F_SET(map, ISL_MAP_NORMALIZED);
6527         map = isl_map_remove_empty_parts(map);
6528         if (!map)
6529                 return NULL;
6530         for (i = map->n - 1; i >= 1; --i) {
6531                 if (!isl_basic_map_fast_is_equal(map->p[i-1], map->p[i]))
6532                         continue;
6533                 isl_basic_map_free(map->p[i-1]);
6534                 for (j = i; j < map->n; ++j)
6535                         map->p[j-1] = map->p[j];
6536                 map->n--;
6537         }
6538         return map;
6539 error:
6540         isl_map_free(map);
6541         return NULL;
6542
6543 }
6544
6545 struct isl_set *isl_set_normalize(struct isl_set *set)
6546 {
6547         return (struct isl_set *)isl_map_normalize((struct isl_map *)set);
6548 }
6549
6550 int isl_map_fast_is_equal(struct isl_map *map1, struct isl_map *map2)
6551 {
6552         int i;
6553         int equal;
6554
6555         if (!map1 || !map2)
6556                 return -1;
6557
6558         if (map1 == map2)
6559                 return 1;
6560         if (!isl_dim_equal(map1->dim, map2->dim))
6561                 return 0;
6562
6563         map1 = isl_map_copy(map1);
6564         map2 = isl_map_copy(map2);
6565         map1 = isl_map_normalize(map1);
6566         map2 = isl_map_normalize(map2);
6567         if (!map1 || !map2)
6568                 goto error;
6569         equal = map1->n == map2->n;
6570         for (i = 0; equal && i < map1->n; ++i) {
6571                 equal = isl_basic_map_fast_is_equal(map1->p[i], map2->p[i]);
6572                 if (equal < 0)
6573                         goto error;
6574         }
6575         isl_map_free(map1);
6576         isl_map_free(map2);
6577         return equal;
6578 error:
6579         isl_map_free(map1);
6580         isl_map_free(map2);
6581         return -1;
6582 }
6583
6584 int isl_set_fast_is_equal(struct isl_set *set1, struct isl_set *set2)
6585 {
6586         return isl_map_fast_is_equal((struct isl_map *)set1,
6587                                                 (struct isl_map *)set2);
6588 }
6589
6590 /* Return an interval that ranges from min to max (inclusive)
6591  */
6592 struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx,
6593         isl_int min, isl_int max)
6594 {
6595         int k;
6596         struct isl_basic_set *bset = NULL;
6597
6598         bset = isl_basic_set_alloc(ctx, 0, 1, 0, 0, 2);
6599         if (!bset)
6600                 goto error;
6601
6602         k = isl_basic_set_alloc_inequality(bset);
6603         if (k < 0)
6604                 goto error;
6605         isl_int_set_si(bset->ineq[k][1], 1);
6606         isl_int_neg(bset->ineq[k][0], min);
6607
6608         k = isl_basic_set_alloc_inequality(bset);
6609         if (k < 0)
6610                 goto error;
6611         isl_int_set_si(bset->ineq[k][1], -1);
6612         isl_int_set(bset->ineq[k][0], max);
6613
6614         return bset;
6615 error:
6616         isl_basic_set_free(bset);
6617         return NULL;
6618 }
6619
6620 /* Return the Cartesian product of the basic sets in list (in the given order).
6621  */
6622 struct isl_basic_set *isl_basic_set_product(struct isl_basic_set_list *list)
6623 {
6624         int i;
6625         unsigned dim;
6626         unsigned nparam;
6627         unsigned extra;
6628         unsigned n_eq;
6629         unsigned n_ineq;
6630         struct isl_basic_set *product = NULL;
6631
6632         if (!list)
6633                 goto error;
6634         isl_assert(list->ctx, list->n > 0, goto error);
6635         isl_assert(list->ctx, list->p[0], goto error);
6636         nparam = isl_basic_set_n_param(list->p[0]);
6637         dim = isl_basic_set_n_dim(list->p[0]);
6638         extra = list->p[0]->n_div;
6639         n_eq = list->p[0]->n_eq;
6640         n_ineq = list->p[0]->n_ineq;
6641         for (i = 1; i < list->n; ++i) {
6642                 isl_assert(list->ctx, list->p[i], goto error);
6643                 isl_assert(list->ctx,
6644                     nparam == isl_basic_set_n_param(list->p[i]), goto error);
6645                 dim += isl_basic_set_n_dim(list->p[i]);
6646                 extra += list->p[i]->n_div;
6647                 n_eq += list->p[i]->n_eq;
6648                 n_ineq += list->p[i]->n_ineq;
6649         }
6650         product = isl_basic_set_alloc(list->ctx, nparam, dim, extra,
6651                                         n_eq, n_ineq);
6652         if (!product)
6653                 goto error;
6654         dim = 0;
6655         for (i = 0; i < list->n; ++i) {
6656                 isl_basic_set_add_constraints(product,
6657                                         isl_basic_set_copy(list->p[i]), dim);
6658                 dim += isl_basic_set_n_dim(list->p[i]);
6659         }
6660         isl_basic_set_list_free(list);
6661         return product;
6662 error:
6663         isl_basic_set_free(product);
6664         isl_basic_set_list_free(list);
6665         return NULL;
6666 }
6667
6668 struct isl_basic_map *isl_basic_map_product(
6669                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
6670 {
6671         struct isl_dim *dim_result = NULL;
6672         struct isl_basic_map *bmap;
6673         unsigned in1, in2, out1, out2, nparam, total, pos;
6674         struct isl_dim_map *dim_map1, *dim_map2;
6675
6676         if (!bmap1 || !bmap2)
6677                 goto error;
6678
6679         isl_assert(bmap1->ctx, isl_dim_match(bmap1->dim, isl_dim_param,
6680                                      bmap2->dim, isl_dim_param), goto error);
6681         dim_result = isl_dim_product(isl_dim_copy(bmap1->dim),
6682                                                    isl_dim_copy(bmap2->dim));
6683
6684         in1 = isl_basic_map_n_in(bmap1);
6685         in2 = isl_basic_map_n_in(bmap2);
6686         out1 = isl_basic_map_n_out(bmap1);
6687         out2 = isl_basic_map_n_out(bmap2);
6688         nparam = isl_basic_map_n_param(bmap1);
6689
6690         total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
6691         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
6692         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
6693         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
6694         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
6695         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
6696         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
6697         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
6698         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
6699         isl_dim_map_div(dim_map1, bmap1, pos += out2);
6700         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
6701
6702         bmap = isl_basic_map_alloc_dim(dim_result,
6703                         bmap1->n_div + bmap2->n_div,
6704                         bmap1->n_eq + bmap2->n_eq,
6705                         bmap1->n_ineq + bmap2->n_ineq);
6706         bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
6707         bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
6708         bmap = isl_basic_map_simplify(bmap);
6709         return isl_basic_map_finalize(bmap);
6710 error:
6711         isl_basic_map_free(bmap1);
6712         isl_basic_map_free(bmap2);
6713         return NULL;
6714 }
6715
6716 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
6717  */
6718 struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2)
6719 {
6720         unsigned flags = 0;
6721         struct isl_map *result;
6722         int i, j;
6723
6724         if (!map1 || !map2)
6725                 goto error;
6726
6727         isl_assert(map1->ctx, isl_dim_match(map1->dim, isl_dim_param,
6728                                          map2->dim, isl_dim_param), goto error);
6729
6730         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
6731             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
6732                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
6733
6734         result = isl_map_alloc_dim(isl_dim_product(isl_dim_copy(map1->dim),
6735                                                    isl_dim_copy(map2->dim)),
6736                                 map1->n * map2->n, flags);
6737         if (!result)
6738                 goto error;
6739         for (i = 0; i < map1->n; ++i)
6740                 for (j = 0; j < map2->n; ++j) {
6741                         struct isl_basic_map *part;
6742                         part = isl_basic_map_product(
6743                                     isl_basic_map_copy(map1->p[i]),
6744                                     isl_basic_map_copy(map2->p[j]));
6745                         if (isl_basic_map_is_empty(part))
6746                                 isl_basic_map_free(part);
6747                         else
6748                                 result = isl_map_add_basic_map(result, part);
6749                         if (!result)
6750                                 goto error;
6751                 }
6752         isl_map_free(map1);
6753         isl_map_free(map2);
6754         return result;
6755 error:
6756         isl_map_free(map1);
6757         isl_map_free(map2);
6758         return NULL;
6759 }
6760
6761 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
6762  */
6763 __isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
6764         __isl_take isl_map *map2)
6765 {
6766         isl_map *prod;
6767
6768         prod = isl_map_product(map1, map2);
6769         prod = isl_map_flatten(prod);
6770         return prod;
6771 }
6772
6773 /* Given two set A and B, construct its Cartesian product A x B.
6774  */
6775 struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2)
6776 {
6777         return (struct isl_set *)isl_map_product((struct isl_map *)set1,
6778                                                  (struct isl_map *)set2);
6779 }
6780
6781 __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
6782         __isl_take isl_set *set2)
6783 {
6784         return (isl_set *)isl_map_flat_product((isl_map *)set1, (isl_map *)set2);
6785 }
6786
6787 uint32_t isl_basic_set_get_hash(struct isl_basic_set *bset)
6788 {
6789         int i;
6790         uint32_t hash = isl_hash_init();
6791         unsigned total;
6792
6793         if (!bset)
6794                 return 0;
6795         bset = isl_basic_set_copy(bset);
6796         bset = isl_basic_set_normalize(bset);
6797         if (!bset)
6798                 return 0;
6799         total = isl_basic_set_total_dim(bset);
6800         isl_hash_byte(hash, bset->n_eq & 0xFF);
6801         for (i = 0; i < bset->n_eq; ++i) {
6802                 uint32_t c_hash;
6803                 c_hash = isl_seq_get_hash(bset->eq[i], 1 + total);
6804                 isl_hash_hash(hash, c_hash);
6805         }
6806         isl_hash_byte(hash, bset->n_ineq & 0xFF);
6807         for (i = 0; i < bset->n_ineq; ++i) {
6808                 uint32_t c_hash;
6809                 c_hash = isl_seq_get_hash(bset->ineq[i], 1 + total);
6810                 isl_hash_hash(hash, c_hash);
6811         }
6812         isl_hash_byte(hash, bset->n_div & 0xFF);
6813         for (i = 0; i < bset->n_div; ++i) {
6814                 uint32_t c_hash;
6815                 if (isl_int_is_zero(bset->div[i][0]))
6816                         continue;
6817                 isl_hash_byte(hash, i & 0xFF);
6818                 c_hash = isl_seq_get_hash(bset->div[i], 1 + 1 + total);
6819                 isl_hash_hash(hash, c_hash);
6820         }
6821         isl_basic_set_free(bset);
6822         return hash;
6823 }
6824
6825 uint32_t isl_set_get_hash(struct isl_set *set)
6826 {
6827         int i;
6828         uint32_t hash;
6829
6830         if (!set)
6831                 return 0;
6832         set = isl_set_copy(set);
6833         set = isl_set_normalize(set);
6834         if (!set)
6835                 return 0;
6836
6837         hash = isl_hash_init();
6838         for (i = 0; i < set->n; ++i) {
6839                 uint32_t bset_hash;
6840                 bset_hash = isl_basic_set_get_hash(set->p[i]);
6841                 isl_hash_hash(hash, bset_hash);
6842         }
6843                 
6844         isl_set_free(set);
6845
6846         return hash;
6847 }
6848
6849 /* Check if the value for dimension dim is completely determined
6850  * by the values of the other parameters and variables.
6851  * That is, check if dimension dim is involved in an equality.
6852  */
6853 int isl_basic_set_dim_is_unique(struct isl_basic_set *bset, unsigned dim)
6854 {
6855         int i;
6856         unsigned nparam;
6857
6858         if (!bset)
6859                 return -1;
6860         nparam = isl_basic_set_n_param(bset);
6861         for (i = 0; i < bset->n_eq; ++i)
6862                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + dim]))
6863                         return 1;
6864         return 0;
6865 }
6866
6867 /* Check if the value for dimension dim is completely determined
6868  * by the values of the other parameters and variables.
6869  * That is, check if dimension dim is involved in an equality
6870  * for each of the subsets.
6871  */
6872 int isl_set_dim_is_unique(struct isl_set *set, unsigned dim)
6873 {
6874         int i;
6875
6876         if (!set)
6877                 return -1;
6878         for (i = 0; i < set->n; ++i) {
6879                 int unique;
6880                 unique = isl_basic_set_dim_is_unique(set->p[i], dim);
6881                 if (unique != 1)
6882                         return unique;
6883         }
6884         return 1;
6885 }
6886
6887 int isl_map_foreach_basic_map(__isl_keep isl_map *map,
6888         int (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
6889 {
6890         int i;
6891
6892         if (!map)
6893                 return -1;
6894
6895         for (i = 0; i < map->n; ++i)
6896                 if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
6897                         return -1;
6898
6899         return 0;
6900 }
6901
6902 int isl_set_foreach_basic_set(__isl_keep isl_set *set,
6903         int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user)
6904 {
6905         int i;
6906
6907         if (!set)
6908                 return -1;
6909
6910         for (i = 0; i < set->n; ++i)
6911                 if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
6912                         return -1;
6913
6914         return 0;
6915 }
6916
6917 __isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset)
6918 {
6919         struct isl_dim *dim;
6920
6921         if (!bset)
6922                 return NULL;
6923
6924         if (bset->n_div == 0)
6925                 return bset;
6926
6927         bset = isl_basic_set_cow(bset);
6928         if (!bset)
6929                 return NULL;
6930
6931         dim = isl_basic_set_get_dim(bset);
6932         dim = isl_dim_add(dim, isl_dim_set, bset->n_div);
6933         if (!dim)
6934                 goto error;
6935         isl_dim_free(bset->dim);
6936         bset->dim = dim;
6937         bset->n_div = 0;
6938
6939         bset = isl_basic_set_finalize(bset);
6940
6941         return bset;
6942 error:
6943         isl_basic_set_free(bset);
6944         return NULL;
6945 }
6946
6947 __isl_give isl_set *isl_set_lift(__isl_take isl_set *set)
6948 {
6949         int i;
6950         struct isl_dim *dim;
6951         unsigned n_div;
6952
6953         set = isl_set_align_divs(set);
6954
6955         if (!set)
6956                 return NULL;
6957         if (set->n == 0 || set->p[0]->n_div == 0)
6958                 return set;
6959
6960         set = isl_set_cow(set);
6961         if (!set)
6962                 return NULL;
6963
6964         n_div = set->p[0]->n_div;
6965         dim = isl_set_get_dim(set);
6966         dim = isl_dim_add(dim, isl_dim_set, n_div);
6967         if (!dim)
6968                 goto error;
6969         isl_dim_free(set->dim);
6970         set->dim = dim;
6971
6972         for (i = 0; i < set->n; ++i) {
6973                 set->p[i] = isl_basic_set_lift(set->p[i]);
6974                 if (!set->p[i])
6975                         goto error;
6976         }
6977
6978         return set;
6979 error:
6980         isl_set_free(set);
6981         return NULL;
6982 }
6983
6984 __isl_give isl_map *isl_set_lifting(__isl_take isl_set *set)
6985 {
6986         struct isl_dim *dim;
6987         struct isl_basic_map *bmap;
6988         unsigned n_set;
6989         unsigned n_div;
6990         unsigned n_param;
6991         unsigned total;
6992         int i, k, l;
6993
6994         set = isl_set_align_divs(set);
6995
6996         if (!set)
6997                 return NULL;
6998
6999         dim = isl_set_get_dim(set);
7000         if (set->n == 0 || set->p[0]->n_div == 0) {
7001                 isl_set_free(set);
7002                 return isl_map_identity(dim);
7003         }
7004
7005         n_div = set->p[0]->n_div;
7006         dim = isl_dim_map(dim);
7007         n_param = isl_dim_size(dim, isl_dim_param);
7008         n_set = isl_dim_size(dim, isl_dim_in);
7009         dim = isl_dim_extend(dim, n_param, n_set, n_set + n_div);
7010         bmap = isl_basic_map_alloc_dim(dim, 0, n_set, 2 * n_div);
7011         for (i = 0; i < n_set; ++i)
7012                 bmap = var_equal(bmap, i);
7013
7014         total = n_param + n_set + n_set + n_div;
7015         for (i = 0; i < n_div; ++i) {
7016                 k = isl_basic_map_alloc_inequality(bmap);
7017                 if (k < 0)
7018                         goto error;
7019                 isl_seq_cpy(bmap->ineq[k], set->p[0]->div[i]+1, 1+n_param);
7020                 isl_seq_clr(bmap->ineq[k]+1+n_param, n_set);
7021                 isl_seq_cpy(bmap->ineq[k]+1+n_param+n_set,
7022                             set->p[0]->div[i]+1+1+n_param, n_set + n_div);
7023                 isl_int_neg(bmap->ineq[k][1+n_param+n_set+n_set+i],
7024                             set->p[0]->div[i][0]);
7025
7026                 l = isl_basic_map_alloc_inequality(bmap);
7027                 if (l < 0)
7028                         goto error;
7029                 isl_seq_neg(bmap->ineq[l], bmap->ineq[k], 1 + total);
7030                 isl_int_add(bmap->ineq[l][0], bmap->ineq[l][0],
7031                             set->p[0]->div[i][0]);
7032                 isl_int_sub_ui(bmap->ineq[l][0], bmap->ineq[l][0], 1);
7033         }
7034
7035         isl_set_free(set);
7036         return isl_map_from_basic_map(bmap);
7037 error:
7038         isl_set_free(set);
7039         isl_basic_map_free(bmap);
7040         return NULL;
7041 }
7042
7043 int isl_basic_set_size(__isl_keep isl_basic_set *bset)
7044 {
7045         unsigned dim;
7046         int size = 0;
7047
7048         if (!bset)
7049                 return -1;
7050
7051         dim = isl_basic_set_total_dim(bset);
7052         size += bset->n_eq * (1 + dim);
7053         size += bset->n_ineq * (1 + dim);
7054         size += bset->n_div * (2 + dim);
7055
7056         return size;
7057 }
7058
7059 int isl_set_size(__isl_keep isl_set *set)
7060 {
7061         int i;
7062         int size = 0;
7063
7064         if (!set)
7065                 return -1;
7066
7067         for (i = 0; i < set->n; ++i)
7068                 size += isl_basic_set_size(set->p[i]);
7069
7070         return size;
7071 }
7072
7073 int isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
7074         enum isl_dim_type type, unsigned pos)
7075 {
7076         int i;
7077         int lower, upper;
7078
7079         if (!bmap)
7080                 return -1;
7081
7082         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), return -1);
7083
7084         pos += isl_basic_map_offset(bmap, type);
7085
7086         for (i = 0; i < bmap->n_eq; ++i)
7087                 if (!isl_int_is_zero(bmap->eq[i][pos]))
7088                         return 1;
7089
7090         lower = upper = 0;
7091         for (i = 0; i < bmap->n_ineq; ++i) {
7092                 int sgn = isl_int_sgn(bmap->ineq[i][pos]);
7093                 if (sgn > 0)
7094                         lower = 1;
7095                 if (sgn < 0)
7096                         upper = 1;
7097         }
7098
7099         return lower && upper;
7100 }
7101
7102 int isl_map_dim_is_bounded(__isl_keep isl_map *map,
7103         enum isl_dim_type type, unsigned pos)
7104 {
7105         int i;
7106
7107         if (!map)
7108                 return -1;
7109
7110         for (i = 0; i < map->n; ++i) {
7111                 int bounded;
7112                 bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
7113                 if (bounded < 0 || !bounded)
7114                         return bounded;
7115         }
7116
7117         return 1;
7118 }
7119
7120 /* Return 1 if the specified dim is involved in both an upper bound
7121  * and a lower bound.
7122  */
7123 int isl_set_dim_is_bounded(__isl_keep isl_set *set,
7124         enum isl_dim_type type, unsigned pos)
7125 {
7126         return isl_map_dim_is_bounded((isl_map *)set, type, pos);
7127 }
7128
7129 /* For each of the "n" variables starting at "first", determine
7130  * the sign of the variable and put the results in the first "n"
7131  * elements of the array "signs".
7132  * Sign
7133  *      1 means that the variable is non-negative
7134  *      -1 means that the variable is non-positive
7135  *      0 means the variable attains both positive and negative values.
7136  */
7137 int isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset,
7138         unsigned first, unsigned n, int *signs)
7139 {
7140         isl_vec *bound = NULL;
7141         struct isl_tab *tab = NULL;
7142         struct isl_tab_undo *snap;
7143         int i;
7144
7145         if (!bset || !signs)
7146                 return -1;
7147
7148         bound = isl_vec_alloc(bset->ctx, 1 + isl_basic_set_total_dim(bset));
7149         tab = isl_tab_from_basic_set(bset);
7150         if (!bound || !tab)
7151                 goto error;
7152
7153         isl_seq_clr(bound->el, bound->size);
7154         isl_int_set_si(bound->el[0], -1);
7155
7156         snap = isl_tab_snap(tab);
7157         for (i = 0; i < n; ++i) {
7158                 int empty;
7159
7160                 isl_int_set_si(bound->el[1 + first + i], -1);
7161                 if (isl_tab_add_ineq(tab, bound->el) < 0)
7162                         goto error;
7163                 empty = tab->empty;
7164                 isl_int_set_si(bound->el[1 + first + i], 0);
7165                 if (isl_tab_rollback(tab, snap) < 0)
7166                         goto error;
7167
7168                 if (empty) {
7169                         signs[i] = 1;
7170                         continue;
7171                 }
7172
7173                 isl_int_set_si(bound->el[1 + first + i], 1);
7174                 if (isl_tab_add_ineq(tab, bound->el) < 0)
7175                         goto error;
7176                 empty = tab->empty;
7177                 isl_int_set_si(bound->el[1 + first + i], 0);
7178                 if (isl_tab_rollback(tab, snap) < 0)
7179                         goto error;
7180
7181                 signs[i] = empty ? -1 : 0;
7182         }
7183
7184         isl_tab_free(tab);
7185         isl_vec_free(bound);
7186         return 0;
7187 error:
7188         isl_tab_free(tab);
7189         isl_vec_free(bound);
7190         return -1;
7191 }
7192
7193 int isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset,
7194         enum isl_dim_type type, unsigned first, unsigned n, int *signs)
7195 {
7196         if (!bset || !signs)
7197                 return -1;
7198         isl_assert(bset->ctx, first + n <= isl_basic_set_dim(bset, type),
7199                 return -1);
7200
7201         first += pos(bset->dim, type) - 1;
7202         return isl_basic_set_vars_get_sign(bset, first, n, signs);
7203 }
7204
7205 /* Check if the given map is single-valued.
7206  * We simply compute
7207  *
7208  *      M \circ M^-1
7209  *
7210  * and check if the result is a subset of the identity mapping.
7211  */
7212 int isl_map_is_single_valued(__isl_keep isl_map *map)
7213 {
7214         isl_map *test;
7215         isl_map *id;
7216         int sv;
7217
7218         test = isl_map_reverse(isl_map_copy(map));
7219         test = isl_map_apply_range(test, isl_map_copy(map));
7220
7221         id = isl_map_identity(isl_dim_range(isl_map_get_dim(map)));
7222
7223         sv = isl_map_is_subset(test, id);
7224
7225         isl_map_free(test);
7226         isl_map_free(id);
7227
7228         return sv;
7229 }
7230
7231 int isl_map_is_bijective(__isl_keep isl_map *map)
7232 {
7233         int sv;
7234
7235         sv = isl_map_is_single_valued(map);
7236         if (sv < 0 || !sv)
7237                 return sv;
7238
7239         map = isl_map_copy(map);
7240         map = isl_map_reverse(map);
7241         sv = isl_map_is_single_valued(map);
7242         isl_map_free(map);
7243
7244         return sv;
7245 }
7246
7247 int isl_set_is_singleton(__isl_keep isl_set *set)
7248 {
7249         return isl_map_is_single_valued((isl_map *)set);
7250 }
7251
7252 int isl_map_is_translation(__isl_keep isl_map *map)
7253 {
7254         int ok;
7255         isl_set *delta;
7256
7257         delta = isl_map_deltas(isl_map_copy(map));
7258         ok = isl_set_is_singleton(delta);
7259         isl_set_free(delta);
7260
7261         return ok;
7262 }
7263
7264 static int unique(isl_int *p, unsigned pos, unsigned len)
7265 {
7266         if (isl_seq_first_non_zero(p, pos) != -1)
7267                 return 0;
7268         if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
7269                 return 0;
7270         return 1;
7271 }
7272
7273 int isl_basic_set_is_box(__isl_keep isl_basic_set *bset)
7274 {
7275         int i, j;
7276         unsigned nvar;
7277         unsigned ovar;
7278
7279         if (!bset)
7280                 return -1;
7281
7282         if (isl_basic_set_dim(bset, isl_dim_div) != 0)
7283                 return 0;
7284
7285         nvar = isl_basic_set_dim(bset, isl_dim_set);
7286         ovar = isl_dim_offset(bset->dim, isl_dim_set);
7287         for (j = 0; j < nvar; ++j) {
7288                 int lower = 0, upper = 0;
7289                 for (i = 0; i < bset->n_eq; ++i) {
7290                         if (isl_int_is_zero(bset->eq[i][1 + ovar + j]))
7291                                 continue;
7292                         if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
7293                                 return 0;
7294                         break;
7295                 }
7296                 if (i < bset->n_eq)
7297                         continue;
7298                 for (i = 0; i < bset->n_ineq; ++i) {
7299                         if (isl_int_is_zero(bset->ineq[i][1 + ovar + j]))
7300                                 continue;
7301                         if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
7302                                 return 0;
7303                         if (isl_int_is_pos(bset->ineq[i][1 + ovar + j]))
7304                                 lower = 1;
7305                         else
7306                                 upper = 1;
7307                 }
7308                 if (!lower || !upper)
7309                         return 0;
7310         }
7311
7312         return 1;
7313 }
7314
7315 int isl_set_is_box(__isl_keep isl_set *set)
7316 {
7317         if (!set)
7318                 return -1;
7319         if (set->n != 1)
7320                 return 0;
7321
7322         return isl_basic_set_is_box(set->p[0]);
7323 }
7324
7325 int isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset)
7326 {
7327         if (!bset)
7328                 return -1;
7329         
7330         return isl_dim_is_wrapping(bset->dim);
7331 }
7332
7333 int isl_set_is_wrapping(__isl_keep isl_set *set)
7334 {
7335         if (!set)
7336                 return -1;
7337         
7338         return isl_dim_is_wrapping(set->dim);
7339 }
7340
7341 __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
7342 {
7343         bmap = isl_basic_map_cow(bmap);
7344         if (!bmap)
7345                 return NULL;
7346
7347         bmap->dim = isl_dim_wrap(bmap->dim);
7348         if (!bmap->dim)
7349                 goto error;
7350
7351         bmap = isl_basic_map_finalize(bmap);
7352
7353         return (isl_basic_set *)bmap;
7354 error:
7355         isl_basic_map_free(bmap);
7356         return NULL;
7357 }
7358
7359 __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map)
7360 {
7361         int i;
7362
7363         map = isl_map_cow(map);
7364         if (!map)
7365                 return NULL;
7366
7367         for (i = 0; i < map->n; ++i) {
7368                 map->p[i] = (isl_basic_map *)isl_basic_map_wrap(map->p[i]);
7369                 if (!map->p[i])
7370                         goto error;
7371         }
7372         map->dim = isl_dim_wrap(map->dim);
7373         if (!map->dim)
7374                 goto error;
7375
7376         return (isl_set *)map;
7377 error:
7378         isl_map_free(map);
7379         return NULL;
7380 }
7381
7382 __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset)
7383 {
7384         bset = isl_basic_set_cow(bset);
7385         if (!bset)
7386                 return NULL;
7387
7388         bset->dim = isl_dim_unwrap(bset->dim);
7389         if (!bset->dim)
7390                 goto error;
7391
7392         bset = isl_basic_set_finalize(bset);
7393
7394         return (isl_basic_map *)bset;
7395 error:
7396         isl_basic_set_free(bset);
7397         return NULL;
7398 }
7399
7400 __isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set)
7401 {
7402         int i;
7403
7404         if (!set)
7405                 return NULL;
7406
7407         if (!isl_set_is_wrapping(set))
7408                 isl_die(set->ctx, isl_error_invalid, "not a wrapping set",
7409                         goto error);
7410
7411         set = isl_set_cow(set);
7412         if (!set)
7413                 return NULL;
7414
7415         for (i = 0; i < set->n; ++i) {
7416                 set->p[i] = (isl_basic_set *)isl_basic_set_unwrap(set->p[i]);
7417                 if (!set->p[i])
7418                         goto error;
7419         }
7420
7421         set->dim = isl_dim_unwrap(set->dim);
7422         if (!set->dim)
7423                 goto error;
7424
7425         return (isl_map *)set;
7426 error:
7427         isl_set_free(set);
7428         return NULL;
7429 }
7430
7431 __isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
7432         enum isl_dim_type type)
7433 {
7434         if (!bmap)
7435                 return NULL;
7436
7437         if (!isl_dim_is_named_or_nested(bmap->dim, type))
7438                 return bmap;
7439
7440         bmap = isl_basic_map_cow(bmap);
7441         if (!bmap)
7442                 return NULL;
7443
7444         bmap->dim = isl_dim_reset(bmap->dim, type);
7445         if (!bmap->dim)
7446                 goto error;
7447
7448         bmap = isl_basic_map_finalize(bmap);
7449
7450         return bmap;
7451 error:
7452         isl_basic_map_free(bmap);
7453         return NULL;
7454 }
7455
7456 __isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
7457         enum isl_dim_type type)
7458 {
7459         int i;
7460
7461         if (!map)
7462                 return NULL;
7463
7464         if (!isl_dim_is_named_or_nested(map->dim, type))
7465                 return map;
7466
7467         map = isl_map_cow(map);
7468         if (!map)
7469                 return NULL;
7470
7471         for (i = 0; i < map->n; ++i) {
7472                 map->p[i] = isl_basic_map_reset(map->p[i], type);
7473                 if (!map->p[i])
7474                         goto error;
7475         }
7476         map->dim = isl_dim_reset(map->dim, type);
7477         if (!map->dim)
7478                 goto error;
7479
7480         return map;
7481 error:
7482         isl_map_free(map);
7483         return NULL;
7484 }
7485
7486 __isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
7487 {
7488         if (!bmap)
7489                 return NULL;
7490
7491         if (!bmap->dim->nested[0] && !bmap->dim->nested[1])
7492                 return bmap;
7493
7494         bmap = isl_basic_map_cow(bmap);
7495         if (!bmap)
7496                 return NULL;
7497
7498         bmap->dim = isl_dim_flatten(bmap->dim);
7499         if (!bmap->dim)
7500                 goto error;
7501
7502         bmap = isl_basic_map_finalize(bmap);
7503
7504         return bmap;
7505 error:
7506         isl_basic_map_free(bmap);
7507         return NULL;
7508 }
7509
7510 __isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
7511 {
7512         int i;
7513
7514         if (!map)
7515                 return NULL;
7516
7517         if (!map->dim->nested[0] && !map->dim->nested[1])
7518                 return map;
7519
7520         map = isl_map_cow(map);
7521         if (!map)
7522                 return NULL;
7523
7524         for (i = 0; i < map->n; ++i) {
7525                 map->p[i] = isl_basic_map_flatten(map->p[i]);
7526                 if (!map->p[i])
7527                         goto error;
7528         }
7529         map->dim = isl_dim_flatten(map->dim);
7530         if (!map->dim)
7531                 goto error;
7532
7533         return map;
7534 error:
7535         isl_map_free(map);
7536         return NULL;
7537 }
7538
7539 /* Extend the given dim_map with mappings for the divs in bmap.
7540  */
7541 static __isl_give struct isl_dim_map *extend_dim_map(
7542         __isl_keep struct isl_dim_map *dim_map,
7543         __isl_keep isl_basic_map *bmap)
7544 {
7545         int i;
7546         struct isl_dim_map *res;
7547         int offset;
7548
7549         offset = isl_basic_map_offset(bmap, isl_dim_div);
7550
7551         res = isl_dim_map_alloc(bmap->ctx, dim_map->len - 1 + bmap->n_div);
7552         if (!res)
7553                 return NULL;
7554
7555         for (i = 0; i < dim_map->len; ++i)
7556                 res->pos[i] = dim_map->pos[i];
7557         for (i = 0; i < bmap->n_div; ++i)
7558                 res->pos[dim_map->len + i] = offset + i;
7559
7560         return res;
7561 }
7562
7563 /* Extract a dim_map from a reordering.
7564  * We essentially need to reverse the mapping, and add an offset
7565  * of 1 for the constant term.
7566  */
7567 __isl_give struct isl_dim_map *isl_dim_map_from_reordering(
7568         __isl_keep isl_reordering *exp)
7569 {
7570         int i;
7571         struct isl_dim_map *dim_map;
7572
7573         if (!exp)
7574                 return NULL;
7575
7576         dim_map = isl_dim_map_alloc(exp->dim->ctx, isl_dim_total(exp->dim));
7577         if (!dim_map)
7578                 return NULL;
7579
7580         for (i = 0; i < exp->len; ++i)
7581                 dim_map->pos[1 + exp->pos[i]] = 1 + i;
7582
7583         return dim_map;
7584 }
7585
7586 /* Reorder the dimensions of "bmap" according to the given dim_map
7587  * and set the dimension specification to "dim".
7588  */
7589 __isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
7590         __isl_take isl_dim *dim, __isl_take struct isl_dim_map *dim_map)
7591 {
7592         isl_basic_map *res;
7593
7594         bmap = isl_basic_map_cow(bmap);
7595         if (!bmap || !dim || !dim_map)
7596                 goto error;
7597
7598         res = isl_basic_map_alloc_dim(dim,
7599                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
7600         res = add_constraints_dim_map(res, bmap, dim_map);
7601         res = isl_basic_map_finalize(res);
7602         return res;
7603 error:
7604         free(dim_map);
7605         isl_basic_map_free(bmap);
7606         isl_dim_free(dim);
7607         return NULL;
7608 }
7609
7610 /* Reorder the dimensions of "map" according to given reordering.
7611  */
7612 __isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
7613         __isl_take isl_reordering *r)
7614 {
7615         int i;
7616         struct isl_dim_map *dim_map;
7617
7618         map = isl_map_cow(map);
7619         dim_map = isl_dim_map_from_reordering(r);
7620         if (!map || !r || !dim_map)
7621                 goto error;
7622
7623         for (i = 0; i < map->n; ++i) {
7624                 struct isl_dim_map *dim_map_i;
7625
7626                 dim_map_i = extend_dim_map(dim_map, map->p[i]);
7627
7628                 map->p[i] = isl_basic_map_realign(map->p[i],
7629                                             isl_dim_copy(r->dim), dim_map_i);
7630
7631                 if (!map->p[i])
7632                         goto error;
7633         }
7634
7635         map = isl_map_reset_dim(map, isl_dim_copy(r->dim));
7636
7637         isl_reordering_free(r);
7638         free(dim_map);
7639         return map;
7640 error:
7641         free(dim_map);
7642         isl_map_free(map);
7643         isl_reordering_free(r);
7644         return NULL;
7645 }
7646
7647 __isl_give isl_set *isl_set_realign(__isl_take isl_set *set,
7648         __isl_take isl_reordering *r)
7649 {
7650         return (isl_set *)isl_map_realign((isl_map *)set, r);
7651 }
7652
7653 __isl_give isl_mat *isl_basic_map_equalities_matrix(
7654                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
7655                 enum isl_dim_type c2, enum isl_dim_type c3,
7656                 enum isl_dim_type c4, enum isl_dim_type c5)
7657 {
7658         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
7659         struct isl_mat *mat;
7660         int i, j, k;
7661         int pos;
7662
7663         if (!bmap)
7664                 return NULL;
7665         mat = isl_mat_alloc(bmap->ctx, bmap->n_eq,
7666                                 isl_basic_map_total_dim(bmap) + 1);
7667         if (!mat)
7668                 return NULL;
7669         for (i = 0; i < bmap->n_eq; ++i)
7670                 for (j = 0, pos = 0; j < 5; ++j) {
7671                         int off = isl_basic_map_offset(bmap, c[j]);
7672                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
7673                                 isl_int_set(mat->row[i][pos],
7674                                             bmap->eq[i][off + k]);
7675                                 ++pos;
7676                         }
7677                 }
7678
7679         return mat;
7680 }
7681
7682 __isl_give isl_mat *isl_basic_map_inequalities_matrix(
7683                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
7684                 enum isl_dim_type c2, enum isl_dim_type c3,
7685                 enum isl_dim_type c4, enum isl_dim_type c5)
7686 {
7687         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
7688         struct isl_mat *mat;
7689         int i, j, k;
7690         int pos;
7691
7692         if (!bmap)
7693                 return NULL;
7694         mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq,
7695                                 isl_basic_map_total_dim(bmap) + 1);
7696         if (!mat)
7697                 return NULL;
7698         for (i = 0; i < bmap->n_ineq; ++i)
7699                 for (j = 0, pos = 0; j < 5; ++j) {
7700                         int off = isl_basic_map_offset(bmap, c[j]);
7701                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
7702                                 isl_int_set(mat->row[i][pos],
7703                                             bmap->ineq[i][off + k]);
7704                                 ++pos;
7705                         }
7706                 }
7707
7708         return mat;
7709 }
7710
7711 __isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
7712         __isl_take isl_dim *dim,
7713         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
7714         enum isl_dim_type c2, enum isl_dim_type c3,
7715         enum isl_dim_type c4, enum isl_dim_type c5)
7716 {
7717         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
7718         isl_basic_map *bmap;
7719         unsigned total;
7720         unsigned extra;
7721         int i, j, k, l;
7722         int pos;
7723
7724         if (!dim || !eq || !ineq)
7725                 goto error;
7726
7727         if (eq->n_col != ineq->n_col)
7728                 isl_die(dim->ctx, isl_error_invalid,
7729                         "equalities and inequalities matrices should have "
7730                         "same number of columns", goto error);
7731
7732         total = 1 + isl_dim_total(dim);
7733
7734         if (eq->n_col < total)
7735                 isl_die(dim->ctx, isl_error_invalid,
7736                         "number of columns too small", goto error);
7737
7738         extra = eq->n_col - total;
7739
7740         bmap = isl_basic_map_alloc_dim(isl_dim_copy(dim), extra,
7741                                        eq->n_row, ineq->n_row);
7742         if (!bmap)
7743                 goto error;
7744         for (i = 0; i < extra; ++i)
7745                 if (isl_basic_map_alloc_div(bmap) < 0)
7746                         goto error;
7747         for (i = 0; i < eq->n_row; ++i) {
7748                 l = isl_basic_map_alloc_equality(bmap);
7749                 if (l < 0)
7750                         goto error;
7751                 for (j = 0, pos = 0; j < 5; ++j) {
7752                         int off = isl_basic_map_offset(bmap, c[j]);
7753                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
7754                                 isl_int_set(bmap->eq[l][off + k], 
7755                                             eq->row[i][pos]);
7756                                 ++pos;
7757                         }
7758                 }
7759         }
7760         for (i = 0; i < ineq->n_row; ++i) {
7761                 l = isl_basic_map_alloc_inequality(bmap);
7762                 if (l < 0)
7763                         goto error;
7764                 for (j = 0, pos = 0; j < 5; ++j) {
7765                         int off = isl_basic_map_offset(bmap, c[j]);
7766                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
7767                                 isl_int_set(bmap->ineq[l][off + k], 
7768                                             ineq->row[i][pos]);
7769                                 ++pos;
7770                         }
7771                 }
7772         }
7773
7774         isl_dim_free(dim);
7775         isl_mat_free(eq);
7776         isl_mat_free(ineq);
7777
7778         return bmap;
7779 error:
7780         isl_dim_free(dim);
7781         isl_mat_free(eq);
7782         isl_mat_free(ineq);
7783         return NULL;
7784 }
7785
7786 __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices(
7787         __isl_take isl_dim *dim,
7788         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
7789         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
7790 {
7791         return (isl_basic_set*)
7792             isl_basic_map_from_constraint_matrices(dim, eq, ineq,
7793                                                    c1, c2, c3, c4, isl_dim_in);
7794 }