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