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