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