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