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