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