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