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