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