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