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