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