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