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