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