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