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