add isl_basic_set_remove_unknown_divs
[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 static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
6450         __isl_take isl_map *map2)
6451 {
6452         int i;
6453         unsigned flags = 0;
6454         struct isl_map *map = NULL;
6455
6456         if (!map1 || !map2)
6457                 goto error;
6458
6459         if (map1->n == 0) {
6460                 isl_map_free(map1);
6461                 return map2;
6462         }
6463         if (map2->n == 0) {
6464                 isl_map_free(map2);
6465                 return map1;
6466         }
6467
6468         isl_assert(map1->ctx, isl_space_is_equal(map1->dim, map2->dim), goto error);
6469
6470         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
6471             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
6472                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
6473
6474         map = isl_map_alloc_space(isl_space_copy(map1->dim),
6475                                 map1->n + map2->n, flags);
6476         if (!map)
6477                 goto error;
6478         for (i = 0; i < map1->n; ++i) {
6479                 map = isl_map_add_basic_map(map,
6480                                   isl_basic_map_copy(map1->p[i]));
6481                 if (!map)
6482                         goto error;
6483         }
6484         for (i = 0; i < map2->n; ++i) {
6485                 map = isl_map_add_basic_map(map,
6486                                   isl_basic_map_copy(map2->p[i]));
6487                 if (!map)
6488                         goto error;
6489         }
6490         isl_map_free(map1);
6491         isl_map_free(map2);
6492         return map;
6493 error:
6494         isl_map_free(map);
6495         isl_map_free(map1);
6496         isl_map_free(map2);
6497         return NULL;
6498 }
6499
6500 __isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1,
6501         __isl_take isl_map *map2)
6502 {
6503         return isl_map_align_params_map_map_and(map1, map2, &map_union_disjoint);
6504 }
6505
6506 struct isl_map *isl_map_union(struct isl_map *map1, struct isl_map *map2)
6507 {
6508         map1 = isl_map_union_disjoint(map1, map2);
6509         if (!map1)
6510                 return NULL;
6511         if (map1->n > 1)
6512                 ISL_F_CLR(map1, ISL_MAP_DISJOINT);
6513         return map1;
6514 }
6515
6516 struct isl_set *isl_set_union_disjoint(
6517                         struct isl_set *set1, struct isl_set *set2)
6518 {
6519         return (struct isl_set *)
6520                 isl_map_union_disjoint(
6521                         (struct isl_map *)set1, (struct isl_map *)set2);
6522 }
6523
6524 struct isl_set *isl_set_union(struct isl_set *set1, struct isl_set *set2)
6525 {
6526         return (struct isl_set *)
6527                 isl_map_union((struct isl_map *)set1, (struct isl_map *)set2);
6528 }
6529
6530 /* Apply "fn" to pairs of elements from "map" and "set" and collect
6531  * the results.
6532  *
6533  * "map" and "set" are assumed to be compatible and non-NULL.
6534  */
6535 static __isl_give isl_map *map_intersect_set(__isl_take isl_map *map,
6536         __isl_take isl_set *set,
6537         __isl_give isl_basic_map *fn(__isl_take isl_basic_map *bmap,
6538                 __isl_take isl_basic_set *bset))
6539 {
6540         unsigned flags = 0;
6541         struct isl_map *result;
6542         int i, j;
6543
6544         if (isl_set_plain_is_universe(set)) {
6545                 isl_set_free(set);
6546                 return map;
6547         }
6548
6549         if (ISL_F_ISSET(map, ISL_MAP_DISJOINT) &&
6550             ISL_F_ISSET(set, ISL_MAP_DISJOINT))
6551                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
6552
6553         result = isl_map_alloc_space(isl_space_copy(map->dim),
6554                                         map->n * set->n, flags);
6555         for (i = 0; result && i < map->n; ++i)
6556                 for (j = 0; j < set->n; ++j) {
6557                         result = isl_map_add_basic_map(result,
6558                                         fn(isl_basic_map_copy(map->p[i]),
6559                                             isl_basic_set_copy(set->p[j])));
6560                         if (!result)
6561                                 break;
6562                 }
6563
6564         isl_map_free(map);
6565         isl_set_free(set);
6566         return result;
6567 }
6568
6569 static __isl_give isl_map *map_intersect_range(__isl_take isl_map *map,
6570         __isl_take isl_set *set)
6571 {
6572         if (!map || !set)
6573                 goto error;
6574
6575         if (!isl_map_compatible_range(map, set))
6576                 isl_die(set->ctx, isl_error_invalid,
6577                         "incompatible spaces", goto error);
6578
6579         return map_intersect_set(map, set, &isl_basic_map_intersect_range);
6580 error:
6581         isl_map_free(map);
6582         isl_set_free(set);
6583         return NULL;
6584 }
6585
6586 __isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map,
6587         __isl_take isl_set *set)
6588 {
6589         return isl_map_align_params_map_map_and(map, set, &map_intersect_range);
6590 }
6591
6592 static __isl_give isl_map *map_intersect_domain(__isl_take isl_map *map,
6593         __isl_take isl_set *set)
6594 {
6595         if (!map || !set)
6596                 goto error;
6597
6598         if (!isl_map_compatible_domain(map, set))
6599                 isl_die(set->ctx, isl_error_invalid,
6600                         "incompatible spaces", goto error);
6601
6602         return map_intersect_set(map, set, &isl_basic_map_intersect_domain);
6603 error:
6604         isl_map_free(map);
6605         isl_set_free(set);
6606         return NULL;
6607 }
6608
6609 __isl_give isl_map *isl_map_intersect_domain(__isl_take isl_map *map,
6610         __isl_take isl_set *set)
6611 {
6612         return isl_map_align_params_map_map_and(map, set,
6613                                                 &map_intersect_domain);
6614 }
6615
6616 static __isl_give isl_map *map_apply_domain(__isl_take isl_map *map1,
6617         __isl_take isl_map *map2)
6618 {
6619         if (!map1 || !map2)
6620                 goto error;
6621         map1 = isl_map_reverse(map1);
6622         map1 = isl_map_apply_range(map1, map2);
6623         return isl_map_reverse(map1);
6624 error:
6625         isl_map_free(map1);
6626         isl_map_free(map2);
6627         return NULL;
6628 }
6629
6630 __isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1,
6631         __isl_take isl_map *map2)
6632 {
6633         return isl_map_align_params_map_map_and(map1, map2, &map_apply_domain);
6634 }
6635
6636 static __isl_give isl_map *map_apply_range(__isl_take isl_map *map1,
6637         __isl_take isl_map *map2)
6638 {
6639         isl_space *dim_result;
6640         struct isl_map *result;
6641         int i, j;
6642
6643         if (!map1 || !map2)
6644                 goto error;
6645
6646         dim_result = isl_space_join(isl_space_copy(map1->dim),
6647                                   isl_space_copy(map2->dim));
6648
6649         result = isl_map_alloc_space(dim_result, map1->n * map2->n, 0);
6650         if (!result)
6651                 goto error;
6652         for (i = 0; i < map1->n; ++i)
6653                 for (j = 0; j < map2->n; ++j) {
6654                         result = isl_map_add_basic_map(result,
6655                             isl_basic_map_apply_range(
6656                                 isl_basic_map_copy(map1->p[i]),
6657                                 isl_basic_map_copy(map2->p[j])));
6658                         if (!result)
6659                                 goto error;
6660                 }
6661         isl_map_free(map1);
6662         isl_map_free(map2);
6663         if (result && result->n <= 1)
6664                 ISL_F_SET(result, ISL_MAP_DISJOINT);
6665         return result;
6666 error:
6667         isl_map_free(map1);
6668         isl_map_free(map2);
6669         return NULL;
6670 }
6671
6672 __isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1,
6673         __isl_take isl_map *map2)
6674 {
6675         return isl_map_align_params_map_map_and(map1, map2, &map_apply_range);
6676 }
6677
6678 /*
6679  * returns range - domain
6680  */
6681 struct isl_basic_set *isl_basic_map_deltas(struct isl_basic_map *bmap)
6682 {
6683         isl_space *dims, *target_dim;
6684         struct isl_basic_set *bset;
6685         unsigned dim;
6686         unsigned nparam;
6687         int i;
6688
6689         if (!bmap)
6690                 goto error;
6691         isl_assert(bmap->ctx, isl_space_tuple_match(bmap->dim, isl_dim_in,
6692                                                   bmap->dim, isl_dim_out),
6693                    goto error);
6694         target_dim = isl_space_domain(isl_basic_map_get_space(bmap));
6695         dim = isl_basic_map_n_in(bmap);
6696         nparam = isl_basic_map_n_param(bmap);
6697         bset = isl_basic_set_from_basic_map(bmap);
6698         bset = isl_basic_set_cow(bset);
6699         dims = isl_basic_set_get_space(bset);
6700         dims = isl_space_add_dims(dims, isl_dim_set, dim);
6701         bset = isl_basic_set_extend_space(bset, dims, 0, dim, 0);
6702         bset = isl_basic_set_swap_vars(bset, 2*dim);
6703         for (i = 0; i < dim; ++i) {
6704                 int j = isl_basic_map_alloc_equality(
6705                                             (struct isl_basic_map *)bset);
6706                 if (j < 0)
6707                         goto error;
6708                 isl_seq_clr(bset->eq[j], 1 + isl_basic_set_total_dim(bset));
6709                 isl_int_set_si(bset->eq[j][1+nparam+i], 1);
6710                 isl_int_set_si(bset->eq[j][1+nparam+dim+i], 1);
6711                 isl_int_set_si(bset->eq[j][1+nparam+2*dim+i], -1);
6712         }
6713         bset = isl_basic_set_project_out(bset, isl_dim_set, dim, 2*dim);
6714         bset = isl_basic_set_reset_space(bset, target_dim);
6715         return bset;
6716 error:
6717         isl_basic_map_free(bmap);
6718         return NULL;
6719 }
6720
6721 /*
6722  * returns range - domain
6723  */
6724 __isl_give isl_set *isl_map_deltas(__isl_take isl_map *map)
6725 {
6726         int i;
6727         isl_space *dim;
6728         struct isl_set *result;
6729
6730         if (!map)
6731                 return NULL;
6732
6733         isl_assert(map->ctx, isl_space_tuple_match(map->dim, isl_dim_in,
6734                                                  map->dim, isl_dim_out),
6735                    goto error);
6736         dim = isl_map_get_space(map);
6737         dim = isl_space_domain(dim);
6738         result = isl_set_alloc_space(dim, map->n, 0);
6739         if (!result)
6740                 goto error;
6741         for (i = 0; i < map->n; ++i)
6742                 result = isl_set_add_basic_set(result,
6743                           isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
6744         isl_map_free(map);
6745         return result;
6746 error:
6747         isl_map_free(map);
6748         return NULL;
6749 }
6750
6751 /*
6752  * returns [domain -> range] -> range - domain
6753  */
6754 __isl_give isl_basic_map *isl_basic_map_deltas_map(
6755         __isl_take isl_basic_map *bmap)
6756 {
6757         int i, k;
6758         isl_space *dim;
6759         isl_basic_map *domain;
6760         int nparam, n;
6761         unsigned total;
6762
6763         if (!isl_space_tuple_match(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out))
6764                 isl_die(bmap->ctx, isl_error_invalid,
6765                         "domain and range don't match", goto error);
6766
6767         nparam = isl_basic_map_dim(bmap, isl_dim_param);
6768         n = isl_basic_map_dim(bmap, isl_dim_in);
6769
6770         dim = isl_space_from_range(isl_space_domain(isl_basic_map_get_space(bmap)));
6771         domain = isl_basic_map_universe(dim);
6772
6773         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
6774         bmap = isl_basic_map_apply_range(bmap, domain);
6775         bmap = isl_basic_map_extend_constraints(bmap, n, 0);
6776
6777         total = isl_basic_map_total_dim(bmap);
6778
6779         for (i = 0; i < n; ++i) {
6780                 k = isl_basic_map_alloc_equality(bmap);
6781                 if (k < 0)
6782                         goto error;
6783                 isl_seq_clr(bmap->eq[k], 1 + total);
6784                 isl_int_set_si(bmap->eq[k][1 + nparam + i], 1);
6785                 isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1);
6786                 isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1);
6787         }
6788
6789         bmap = isl_basic_map_gauss(bmap, NULL);
6790         return isl_basic_map_finalize(bmap);
6791 error:
6792         isl_basic_map_free(bmap);
6793         return NULL;
6794 }
6795
6796 /*
6797  * returns [domain -> range] -> range - domain
6798  */
6799 __isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
6800 {
6801         int i;
6802         isl_space *domain_dim;
6803
6804         if (!map)
6805                 return NULL;
6806
6807         if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
6808                 isl_die(map->ctx, isl_error_invalid,
6809                         "domain and range don't match", goto error);
6810
6811         map = isl_map_cow(map);
6812         if (!map)
6813                 return NULL;
6814
6815         domain_dim = isl_space_from_range(isl_space_domain(isl_map_get_space(map)));
6816         map->dim = isl_space_from_domain(isl_space_wrap(map->dim));
6817         map->dim = isl_space_join(map->dim, domain_dim);
6818         if (!map->dim)
6819                 goto error;
6820         for (i = 0; i < map->n; ++i) {
6821                 map->p[i] = isl_basic_map_deltas_map(map->p[i]);
6822                 if (!map->p[i])
6823                         goto error;
6824         }
6825         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
6826         return map;
6827 error:
6828         isl_map_free(map);
6829         return NULL;
6830 }
6831
6832 static __isl_give isl_basic_map *basic_map_identity(__isl_take isl_space *dims)
6833 {
6834         struct isl_basic_map *bmap;
6835         unsigned nparam;
6836         unsigned dim;
6837         int i;
6838
6839         if (!dims)
6840                 return NULL;
6841
6842         nparam = dims->nparam;
6843         dim = dims->n_out;
6844         bmap = isl_basic_map_alloc_space(dims, 0, dim, 0);
6845         if (!bmap)
6846                 goto error;
6847
6848         for (i = 0; i < dim; ++i) {
6849                 int j = isl_basic_map_alloc_equality(bmap);
6850                 if (j < 0)
6851                         goto error;
6852                 isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
6853                 isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
6854                 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], -1);
6855         }
6856         return isl_basic_map_finalize(bmap);
6857 error:
6858         isl_basic_map_free(bmap);
6859         return NULL;
6860 }
6861
6862 __isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *dim)
6863 {
6864         if (!dim)
6865                 return NULL;
6866         if (dim->n_in != dim->n_out)
6867                 isl_die(dim->ctx, isl_error_invalid,
6868                         "number of input and output dimensions needs to be "
6869                         "the same", goto error);
6870         return basic_map_identity(dim);
6871 error:
6872         isl_space_free(dim);
6873         return NULL;
6874 }
6875
6876 struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model)
6877 {
6878         if (!model || !model->dim)
6879                 return NULL;
6880         return isl_basic_map_identity(isl_space_copy(model->dim));
6881 }
6882
6883 __isl_give isl_map *isl_map_identity(__isl_take isl_space *dim)
6884 {
6885         return isl_map_from_basic_map(isl_basic_map_identity(dim));
6886 }
6887
6888 struct isl_map *isl_map_identity_like(struct isl_map *model)
6889 {
6890         if (!model || !model->dim)
6891                 return NULL;
6892         return isl_map_identity(isl_space_copy(model->dim));
6893 }
6894
6895 struct isl_map *isl_map_identity_like_basic_map(struct isl_basic_map *model)
6896 {
6897         if (!model || !model->dim)
6898                 return NULL;
6899         return isl_map_identity(isl_space_copy(model->dim));
6900 }
6901
6902 __isl_give isl_map *isl_set_identity(__isl_take isl_set *set)
6903 {
6904         isl_space *dim = isl_set_get_space(set);
6905         isl_map *id;
6906         id = isl_map_identity(isl_space_map_from_set(dim));
6907         return isl_map_intersect_range(id, set);
6908 }
6909
6910 /* Construct a basic set with all set dimensions having only non-negative
6911  * values.
6912  */
6913 __isl_give isl_basic_set *isl_basic_set_positive_orthant(
6914         __isl_take isl_space *space)
6915 {
6916         int i;
6917         unsigned nparam;
6918         unsigned dim;
6919         struct isl_basic_set *bset;
6920
6921         if (!space)
6922                 return NULL;
6923         nparam = space->nparam;
6924         dim = space->n_out;
6925         bset = isl_basic_set_alloc_space(space, 0, 0, dim);
6926         if (!bset)
6927                 return NULL;
6928         for (i = 0; i < dim; ++i) {
6929                 int k = isl_basic_set_alloc_inequality(bset);
6930                 if (k < 0)
6931                         goto error;
6932                 isl_seq_clr(bset->ineq[k], 1 + isl_basic_set_total_dim(bset));
6933                 isl_int_set_si(bset->ineq[k][1 + nparam + i], 1);
6934         }
6935         return bset;
6936 error:
6937         isl_basic_set_free(bset);
6938         return NULL;
6939 }
6940
6941 /* Construct the half-space x_pos >= 0.
6942  */
6943 static __isl_give isl_basic_set *nonneg_halfspace(__isl_take isl_space *dim,
6944         int pos)
6945 {
6946         int k;
6947         isl_basic_set *nonneg;
6948
6949         nonneg = isl_basic_set_alloc_space(dim, 0, 0, 1);
6950         k = isl_basic_set_alloc_inequality(nonneg);
6951         if (k < 0)
6952                 goto error;
6953         isl_seq_clr(nonneg->ineq[k], 1 + isl_basic_set_total_dim(nonneg));
6954         isl_int_set_si(nonneg->ineq[k][pos], 1);
6955
6956         return isl_basic_set_finalize(nonneg);
6957 error:
6958         isl_basic_set_free(nonneg);
6959         return NULL;
6960 }
6961
6962 /* Construct the half-space x_pos <= -1.
6963  */
6964 static __isl_give isl_basic_set *neg_halfspace(__isl_take isl_space *dim, int pos)
6965 {
6966         int k;
6967         isl_basic_set *neg;
6968
6969         neg = isl_basic_set_alloc_space(dim, 0, 0, 1);
6970         k = isl_basic_set_alloc_inequality(neg);
6971         if (k < 0)
6972                 goto error;
6973         isl_seq_clr(neg->ineq[k], 1 + isl_basic_set_total_dim(neg));
6974         isl_int_set_si(neg->ineq[k][0], -1);
6975         isl_int_set_si(neg->ineq[k][pos], -1);
6976
6977         return isl_basic_set_finalize(neg);
6978 error:
6979         isl_basic_set_free(neg);
6980         return NULL;
6981 }
6982
6983 __isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set,
6984         enum isl_dim_type type, unsigned first, unsigned n)
6985 {
6986         int i;
6987         isl_basic_set *nonneg;
6988         isl_basic_set *neg;
6989
6990         if (!set)
6991                 return NULL;
6992         if (n == 0)
6993                 return set;
6994
6995         isl_assert(set->ctx, first + n <= isl_set_dim(set, type), goto error);
6996
6997         for (i = 0; i < n; ++i) {
6998                 nonneg = nonneg_halfspace(isl_set_get_space(set),
6999                                           pos(set->dim, type) + first + i);
7000                 neg = neg_halfspace(isl_set_get_space(set),
7001                                           pos(set->dim, type) + first + i);
7002
7003                 set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
7004         }
7005
7006         return set;
7007 error:
7008         isl_set_free(set);
7009         return NULL;
7010 }
7011
7012 static int foreach_orthant(__isl_take isl_set *set, int *signs, int first,
7013         int len, int (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
7014         void *user)
7015 {
7016         isl_set *half;
7017
7018         if (!set)
7019                 return -1;
7020         if (isl_set_plain_is_empty(set)) {
7021                 isl_set_free(set);
7022                 return 0;
7023         }
7024         if (first == len)
7025                 return fn(set, signs, user);
7026
7027         signs[first] = 1;
7028         half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set),
7029                                                         1 + first));
7030         half = isl_set_intersect(half, isl_set_copy(set));
7031         if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0)
7032                 goto error;
7033
7034         signs[first] = -1;
7035         half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set),
7036                                                         1 + first));
7037         half = isl_set_intersect(half, set);
7038         return foreach_orthant(half, signs, first + 1, len, fn, user);
7039 error:
7040         isl_set_free(set);
7041         return -1;
7042 }
7043
7044 /* Call "fn" on the intersections of "set" with each of the orthants
7045  * (except for obviously empty intersections).  The orthant is identified
7046  * by the signs array, with each entry having value 1 or -1 according
7047  * to the sign of the corresponding variable.
7048  */
7049 int isl_set_foreach_orthant(__isl_keep isl_set *set,
7050         int (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
7051         void *user)
7052 {
7053         unsigned nparam;
7054         unsigned nvar;
7055         int *signs;
7056         int r;
7057
7058         if (!set)
7059                 return -1;
7060         if (isl_set_plain_is_empty(set))
7061                 return 0;
7062
7063         nparam = isl_set_dim(set, isl_dim_param);
7064         nvar = isl_set_dim(set, isl_dim_set);
7065
7066         signs = isl_alloc_array(set->ctx, int, nparam + nvar);
7067
7068         r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar,
7069                             fn, user);
7070
7071         free(signs);
7072
7073         return r;
7074 }
7075
7076 int isl_set_is_equal(struct isl_set *set1, struct isl_set *set2)
7077 {
7078         return isl_map_is_equal((struct isl_map *)set1, (struct isl_map *)set2);
7079 }
7080
7081 int isl_basic_map_is_subset(
7082                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
7083 {
7084         int is_subset;
7085         struct isl_map *map1;
7086         struct isl_map *map2;
7087
7088         if (!bmap1 || !bmap2)
7089                 return -1;
7090
7091         map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
7092         map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
7093
7094         is_subset = isl_map_is_subset(map1, map2);
7095
7096         isl_map_free(map1);
7097         isl_map_free(map2);
7098
7099         return is_subset;
7100 }
7101
7102 int isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1,
7103         __isl_keep isl_basic_set *bset2)
7104 {
7105         return isl_basic_map_is_subset(bset1, bset2);
7106 }
7107
7108 int isl_basic_map_is_equal(
7109                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
7110 {
7111         int is_subset;
7112
7113         if (!bmap1 || !bmap2)
7114                 return -1;
7115         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
7116         if (is_subset != 1)
7117                 return is_subset;
7118         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
7119         return is_subset;
7120 }
7121
7122 int isl_basic_set_is_equal(
7123                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
7124 {
7125         return isl_basic_map_is_equal(
7126                 (struct isl_basic_map *)bset1, (struct isl_basic_map *)bset2);
7127 }
7128
7129 int isl_map_is_empty(struct isl_map *map)
7130 {
7131         int i;
7132         int is_empty;
7133
7134         if (!map)
7135                 return -1;
7136         for (i = 0; i < map->n; ++i) {
7137                 is_empty = isl_basic_map_is_empty(map->p[i]);
7138                 if (is_empty < 0)
7139                         return -1;
7140                 if (!is_empty)
7141                         return 0;
7142         }
7143         return 1;
7144 }
7145
7146 int isl_map_plain_is_empty(__isl_keep isl_map *map)
7147 {
7148         return map ? map->n == 0 : -1;
7149 }
7150
7151 int isl_map_fast_is_empty(__isl_keep isl_map *map)
7152 {
7153         return isl_map_plain_is_empty(map);
7154 }
7155
7156 int isl_set_plain_is_empty(struct isl_set *set)
7157 {
7158         return set ? set->n == 0 : -1;
7159 }
7160
7161 int isl_set_fast_is_empty(__isl_keep isl_set *set)
7162 {
7163         return isl_set_plain_is_empty(set);
7164 }
7165
7166 int isl_set_is_empty(struct isl_set *set)
7167 {
7168         return isl_map_is_empty((struct isl_map *)set);
7169 }
7170
7171 int isl_map_has_equal_space(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
7172 {
7173         if (!map1 || !map2)
7174                 return -1;
7175
7176         return isl_space_is_equal(map1->dim, map2->dim);
7177 }
7178
7179 int isl_set_has_equal_space(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
7180 {
7181         if (!set1 || !set2)
7182                 return -1;
7183
7184         return isl_space_is_equal(set1->dim, set2->dim);
7185 }
7186
7187 static int map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
7188 {
7189         int is_subset;
7190
7191         if (!map1 || !map2)
7192                 return -1;
7193         is_subset = isl_map_is_subset(map1, map2);
7194         if (is_subset != 1)
7195                 return is_subset;
7196         is_subset = isl_map_is_subset(map2, map1);
7197         return is_subset;
7198 }
7199
7200 int isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
7201 {
7202         return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
7203 }
7204
7205 int isl_basic_map_is_strict_subset(
7206                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
7207 {
7208         int is_subset;
7209
7210         if (!bmap1 || !bmap2)
7211                 return -1;
7212         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
7213         if (is_subset != 1)
7214                 return is_subset;
7215         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
7216         if (is_subset == -1)
7217                 return is_subset;
7218         return !is_subset;
7219 }
7220
7221 int isl_map_is_strict_subset(struct isl_map *map1, struct isl_map *map2)
7222 {
7223         int is_subset;
7224
7225         if (!map1 || !map2)
7226                 return -1;
7227         is_subset = isl_map_is_subset(map1, map2);
7228         if (is_subset != 1)
7229                 return is_subset;
7230         is_subset = isl_map_is_subset(map2, map1);
7231         if (is_subset == -1)
7232                 return is_subset;
7233         return !is_subset;
7234 }
7235
7236 int isl_set_is_strict_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
7237 {
7238         return isl_map_is_strict_subset((isl_map *)set1, (isl_map *)set2);
7239 }
7240
7241 int isl_basic_map_is_universe(struct isl_basic_map *bmap)
7242 {
7243         if (!bmap)
7244                 return -1;
7245         return bmap->n_eq == 0 && bmap->n_ineq == 0;
7246 }
7247
7248 int isl_basic_set_is_universe(struct isl_basic_set *bset)
7249 {
7250         if (!bset)
7251                 return -1;
7252         return bset->n_eq == 0 && bset->n_ineq == 0;
7253 }
7254
7255 int isl_map_plain_is_universe(__isl_keep isl_map *map)
7256 {
7257         int i;
7258
7259         if (!map)
7260                 return -1;
7261
7262         for (i = 0; i < map->n; ++i) {
7263                 int r = isl_basic_map_is_universe(map->p[i]);
7264                 if (r < 0 || r)
7265                         return r;
7266         }
7267
7268         return 0;
7269 }
7270
7271 int isl_set_plain_is_universe(__isl_keep isl_set *set)
7272 {
7273         return isl_map_plain_is_universe((isl_map *) set);
7274 }
7275
7276 int isl_set_fast_is_universe(__isl_keep isl_set *set)
7277 {
7278         return isl_set_plain_is_universe(set);
7279 }
7280
7281 int isl_basic_map_is_empty(struct isl_basic_map *bmap)
7282 {
7283         struct isl_basic_set *bset = NULL;
7284         struct isl_vec *sample = NULL;
7285         int empty;
7286         unsigned total;
7287
7288         if (!bmap)
7289                 return -1;
7290
7291         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
7292                 return 1;
7293
7294         if (isl_basic_map_is_universe(bmap))
7295                 return 0;
7296
7297         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
7298                 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
7299                 copy = isl_basic_map_remove_redundancies(copy);
7300                 empty = ISL_F_ISSET(copy, ISL_BASIC_MAP_EMPTY);
7301                 isl_basic_map_free(copy);
7302                 return empty;
7303         }
7304
7305         total = 1 + isl_basic_map_total_dim(bmap);
7306         if (bmap->sample && bmap->sample->size == total) {
7307                 int contains = isl_basic_map_contains(bmap, bmap->sample);
7308                 if (contains < 0)
7309                         return -1;
7310                 if (contains)
7311                         return 0;
7312         }
7313         isl_vec_free(bmap->sample);
7314         bmap->sample = NULL;
7315         bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
7316         if (!bset)
7317                 return -1;
7318         sample = isl_basic_set_sample_vec(bset);
7319         if (!sample)
7320                 return -1;
7321         empty = sample->size == 0;
7322         isl_vec_free(bmap->sample);
7323         bmap->sample = sample;
7324         if (empty)
7325                 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
7326
7327         return empty;
7328 }
7329
7330 int isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
7331 {
7332         if (!bmap)
7333                 return -1;
7334         return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY);
7335 }
7336
7337 int isl_basic_map_fast_is_empty(__isl_keep isl_basic_map *bmap)
7338 {
7339         return isl_basic_map_plain_is_empty(bmap);
7340 }
7341
7342 int isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset)
7343 {
7344         if (!bset)
7345                 return -1;
7346         return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY);
7347 }
7348
7349 int isl_basic_set_fast_is_empty(__isl_keep isl_basic_set *bset)
7350 {
7351         return isl_basic_set_plain_is_empty(bset);
7352 }
7353
7354 int isl_basic_set_is_empty(struct isl_basic_set *bset)
7355 {
7356         return isl_basic_map_is_empty((struct isl_basic_map *)bset);
7357 }
7358
7359 struct isl_map *isl_basic_map_union(
7360         struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
7361 {
7362         struct isl_map *map;
7363         if (!bmap1 || !bmap2)
7364                 goto error;
7365
7366         isl_assert(bmap1->ctx, isl_space_is_equal(bmap1->dim, bmap2->dim), goto error);
7367
7368         map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
7369         if (!map)
7370                 goto error;
7371         map = isl_map_add_basic_map(map, bmap1);
7372         map = isl_map_add_basic_map(map, bmap2);
7373         return map;
7374 error:
7375         isl_basic_map_free(bmap1);
7376         isl_basic_map_free(bmap2);
7377         return NULL;
7378 }
7379
7380 struct isl_set *isl_basic_set_union(
7381                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
7382 {
7383         return (struct isl_set *)isl_basic_map_union(
7384                                             (struct isl_basic_map *)bset1,
7385                                             (struct isl_basic_map *)bset2);
7386 }
7387
7388 /* Order divs such that any div only depends on previous divs */
7389 struct isl_basic_map *isl_basic_map_order_divs(struct isl_basic_map *bmap)
7390 {
7391         int i;
7392         unsigned off;
7393
7394         if (!bmap)
7395                 return NULL;
7396
7397         off = isl_space_dim(bmap->dim, isl_dim_all);
7398
7399         for (i = 0; i < bmap->n_div; ++i) {
7400                 int pos;
7401                 if (isl_int_is_zero(bmap->div[i][0]))
7402                         continue;
7403                 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
7404                                                             bmap->n_div-i);
7405                 if (pos == -1)
7406                         continue;
7407                 isl_basic_map_swap_div(bmap, i, i + pos);
7408                 --i;
7409         }
7410         return bmap;
7411 }
7412
7413 struct isl_basic_set *isl_basic_set_order_divs(struct isl_basic_set *bset)
7414 {
7415         return (struct isl_basic_set *)
7416                 isl_basic_map_order_divs((struct isl_basic_map *)bset);
7417 }
7418
7419 __isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
7420 {
7421         int i;
7422
7423         if (!map)
7424                 return 0;
7425
7426         for (i = 0; i < map->n; ++i) {
7427                 map->p[i] = isl_basic_map_order_divs(map->p[i]);
7428                 if (!map->p[i])
7429                         goto error;
7430         }
7431
7432         return map;
7433 error:
7434         isl_map_free(map);
7435         return NULL;
7436 }
7437
7438 /* Apply the expansion computed by isl_merge_divs.
7439  * The expansion itself is given by "exp" while the resulting
7440  * list of divs is given by "div".
7441  */
7442 __isl_give isl_basic_set *isl_basic_set_expand_divs(
7443         __isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp)
7444 {
7445         int i, j;
7446         int n_div;
7447
7448         bset = isl_basic_set_cow(bset);
7449         if (!bset || !div)
7450                 goto error;
7451
7452         if (div->n_row < bset->n_div)
7453                 isl_die(isl_mat_get_ctx(div), isl_error_invalid,
7454                         "not an expansion", goto error);
7455
7456         bset = isl_basic_map_extend_space(bset, isl_space_copy(bset->dim),
7457                                         div->n_row - bset->n_div, 0,
7458                                         2 * (div->n_row - bset->n_div));
7459
7460         n_div = bset->n_div;
7461         for (i = n_div; i < div->n_row; ++i)
7462                 if (isl_basic_set_alloc_div(bset) < 0)
7463                         goto error;
7464
7465         j = n_div - 1;
7466         for (i = div->n_row - 1; i >= 0; --i) {
7467                 if (j >= 0 && exp[j] == i) {
7468                         if (i != j)
7469                                 isl_basic_map_swap_div(bset, i, j);
7470                         j--;
7471                 } else {
7472                         isl_seq_cpy(bset->div[i], div->row[i], div->n_col);
7473                         if (isl_basic_map_add_div_constraints(bset, i) < 0)
7474                                 goto error;
7475                 }
7476         }
7477
7478         isl_mat_free(div);
7479         return bset;
7480 error:
7481         isl_basic_set_free(bset);
7482         isl_mat_free(div);
7483         return NULL;
7484 }
7485
7486 /* Look for a div in dst that corresponds to the div "div" in src.
7487  * The divs before "div" in src and dst are assumed to be the same.
7488  * 
7489  * Returns -1 if no corresponding div was found and the position
7490  * of the corresponding div in dst otherwise.
7491  */
7492 static int find_div(struct isl_basic_map *dst,
7493                         struct isl_basic_map *src, unsigned div)
7494 {
7495         int i;
7496
7497         unsigned total = isl_space_dim(src->dim, isl_dim_all);
7498
7499         isl_assert(dst->ctx, div <= dst->n_div, return -1);
7500         for (i = div; i < dst->n_div; ++i)
7501                 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total+div) &&
7502                     isl_seq_first_non_zero(dst->div[i]+1+1+total+div,
7503                                                 dst->n_div - div) == -1)
7504                         return i;
7505         return -1;
7506 }
7507
7508 struct isl_basic_map *isl_basic_map_align_divs(
7509                 struct isl_basic_map *dst, struct isl_basic_map *src)
7510 {
7511         int i;
7512         unsigned total = isl_space_dim(src->dim, isl_dim_all);
7513
7514         if (!dst || !src)
7515                 goto error;
7516
7517         if (src->n_div == 0)
7518                 return dst;
7519
7520         for (i = 0; i < src->n_div; ++i)
7521                 isl_assert(src->ctx, !isl_int_is_zero(src->div[i][0]), goto error);
7522
7523         src = isl_basic_map_order_divs(src);
7524         dst = isl_basic_map_cow(dst);
7525         dst = isl_basic_map_extend_space(dst, isl_space_copy(dst->dim),
7526                         src->n_div, 0, 2 * src->n_div);
7527         if (!dst)
7528                 return NULL;
7529         for (i = 0; i < src->n_div; ++i) {
7530                 int j = find_div(dst, src, i);
7531                 if (j < 0) {
7532                         j = isl_basic_map_alloc_div(dst);
7533                         if (j < 0)
7534                                 goto error;
7535                         isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i);
7536                         isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i);
7537                         if (isl_basic_map_add_div_constraints(dst, j) < 0)
7538                                 goto error;
7539                 }
7540                 if (j != i)
7541                         isl_basic_map_swap_div(dst, i, j);
7542         }
7543         return dst;
7544 error:
7545         isl_basic_map_free(dst);
7546         return NULL;
7547 }
7548
7549 struct isl_basic_set *isl_basic_set_align_divs(
7550                 struct isl_basic_set *dst, struct isl_basic_set *src)
7551 {
7552         return (struct isl_basic_set *)isl_basic_map_align_divs(
7553                 (struct isl_basic_map *)dst, (struct isl_basic_map *)src);
7554 }
7555
7556 struct isl_map *isl_map_align_divs(struct isl_map *map)
7557 {
7558         int i;
7559
7560         if (!map)
7561                 return NULL;
7562         if (map->n == 0)
7563                 return map;
7564         map = isl_map_compute_divs(map);
7565         map = isl_map_cow(map);
7566         if (!map)
7567                 return NULL;
7568
7569         for (i = 1; i < map->n; ++i)
7570                 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
7571         for (i = 1; i < map->n; ++i)
7572                 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
7573
7574         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
7575         return map;
7576 }
7577
7578 struct isl_set *isl_set_align_divs(struct isl_set *set)
7579 {
7580         return (struct isl_set *)isl_map_align_divs((struct isl_map *)set);
7581 }
7582
7583 static __isl_give isl_set *set_apply( __isl_take isl_set *set,
7584         __isl_take isl_map *map)
7585 {
7586         if (!set || !map)
7587                 goto error;
7588         isl_assert(set->ctx, isl_map_compatible_domain(map, set), goto error);
7589         map = isl_map_intersect_domain(map, set);
7590         set = isl_map_range(map);
7591         return set;
7592 error:
7593         isl_set_free(set);
7594         isl_map_free(map);
7595         return NULL;
7596 }
7597
7598 __isl_give isl_set *isl_set_apply( __isl_take isl_set *set,
7599         __isl_take isl_map *map)
7600 {
7601         return isl_map_align_params_map_map_and(set, map, &set_apply);
7602 }
7603
7604 /* There is no need to cow as removing empty parts doesn't change
7605  * the meaning of the set.
7606  */
7607 struct isl_map *isl_map_remove_empty_parts(struct isl_map *map)
7608 {
7609         int i;
7610
7611         if (!map)
7612                 return NULL;
7613
7614         for (i = map->n - 1; i >= 0; --i)
7615                 remove_if_empty(map, i);
7616
7617         return map;
7618 }
7619
7620 struct isl_set *isl_set_remove_empty_parts(struct isl_set *set)
7621 {
7622         return (struct isl_set *)
7623                 isl_map_remove_empty_parts((struct isl_map *)set);
7624 }
7625
7626 struct isl_basic_map *isl_map_copy_basic_map(struct isl_map *map)
7627 {
7628         struct isl_basic_map *bmap;
7629         if (!map || map->n == 0)
7630                 return NULL;
7631         bmap = map->p[map->n-1];
7632         isl_assert(map->ctx, ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL), return NULL);
7633         return isl_basic_map_copy(bmap);
7634 }
7635
7636 struct isl_basic_set *isl_set_copy_basic_set(struct isl_set *set)
7637 {
7638         return (struct isl_basic_set *)
7639                 isl_map_copy_basic_map((struct isl_map *)set);
7640 }
7641
7642 __isl_give isl_map *isl_map_drop_basic_map(__isl_take isl_map *map,
7643                                                 __isl_keep isl_basic_map *bmap)
7644 {
7645         int i;
7646
7647         if (!map || !bmap)
7648                 goto error;
7649         for (i = map->n-1; i >= 0; --i) {
7650                 if (map->p[i] != bmap)
7651                         continue;
7652                 map = isl_map_cow(map);
7653                 if (!map)
7654                         goto error;
7655                 isl_basic_map_free(map->p[i]);
7656                 if (i != map->n-1) {
7657                         ISL_F_CLR(map, ISL_SET_NORMALIZED);
7658                         map->p[i] = map->p[map->n-1];
7659                 }
7660                 map->n--;
7661                 return map;
7662         }
7663         return map;
7664 error:
7665         isl_map_free(map);
7666         return NULL;
7667 }
7668
7669 struct isl_set *isl_set_drop_basic_set(struct isl_set *set,
7670                                                 struct isl_basic_set *bset)
7671 {
7672         return (struct isl_set *)isl_map_drop_basic_map((struct isl_map *)set,
7673                                                 (struct isl_basic_map *)bset);
7674 }
7675
7676 /* Given two basic sets bset1 and bset2, compute the maximal difference
7677  * between the values of dimension pos in bset1 and those in bset2
7678  * for any common value of the parameters and dimensions preceding pos.
7679  */
7680 static enum isl_lp_result basic_set_maximal_difference_at(
7681         __isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2,
7682         int pos, isl_int *opt)
7683 {
7684         isl_space *dims;
7685         struct isl_basic_map *bmap1 = NULL;
7686         struct isl_basic_map *bmap2 = NULL;
7687         struct isl_ctx *ctx;
7688         struct isl_vec *obj;
7689         unsigned total;
7690         unsigned nparam;
7691         unsigned dim1, dim2;
7692         enum isl_lp_result res;
7693
7694         if (!bset1 || !bset2)
7695                 return isl_lp_error;
7696
7697         nparam = isl_basic_set_n_param(bset1);
7698         dim1 = isl_basic_set_n_dim(bset1);
7699         dim2 = isl_basic_set_n_dim(bset2);
7700         dims = isl_space_alloc(bset1->ctx, nparam, pos, dim1 - pos);
7701         bmap1 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset1), dims);
7702         dims = isl_space_alloc(bset2->ctx, nparam, pos, dim2 - pos);
7703         bmap2 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset2), dims);
7704         if (!bmap1 || !bmap2)
7705                 goto error;
7706         bmap1 = isl_basic_map_cow(bmap1);
7707         bmap1 = isl_basic_map_extend(bmap1, nparam,
7708                         pos, (dim1 - pos) + (dim2 - pos),
7709                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
7710         bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos);
7711         if (!bmap1)
7712                 goto error;
7713         total = isl_basic_map_total_dim(bmap1);
7714         ctx = bmap1->ctx;
7715         obj = isl_vec_alloc(ctx, 1 + total);
7716         isl_seq_clr(obj->block.data, 1 + total);
7717         isl_int_set_si(obj->block.data[1+nparam+pos], 1);
7718         isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
7719         if (!obj)
7720                 goto error;
7721         res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
7722                                         opt, NULL, NULL);
7723         isl_basic_map_free(bmap1);
7724         isl_vec_free(obj);
7725         return res;
7726 error:
7727         isl_basic_map_free(bmap1);
7728         isl_basic_map_free(bmap2);
7729         return isl_lp_error;
7730 }
7731
7732 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
7733  * for any common value of the parameters and dimensions preceding pos
7734  * in both basic sets, the values of dimension pos in bset1 are
7735  * smaller or larger than those in bset2.
7736  *
7737  * Returns
7738  *       1 if bset1 follows bset2
7739  *      -1 if bset1 precedes bset2
7740  *       0 if bset1 and bset2 are incomparable
7741  *      -2 if some error occurred.
7742  */
7743 int isl_basic_set_compare_at(struct isl_basic_set *bset1,
7744         struct isl_basic_set *bset2, int pos)
7745 {
7746         isl_int opt;
7747         enum isl_lp_result res;
7748         int cmp;
7749
7750         isl_int_init(opt);
7751
7752         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
7753
7754         if (res == isl_lp_empty)
7755                 cmp = 0;
7756         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
7757                   res == isl_lp_unbounded)
7758                 cmp = 1;
7759         else if (res == isl_lp_ok && isl_int_is_neg(opt))
7760                 cmp = -1;
7761         else
7762                 cmp = -2;
7763
7764         isl_int_clear(opt);
7765         return cmp;
7766 }
7767
7768 /* Given two basic sets bset1 and bset2, check whether
7769  * for any common value of the parameters and dimensions preceding pos
7770  * there is a value of dimension pos in bset1 that is larger
7771  * than a value of the same dimension in bset2.
7772  *
7773  * Return
7774  *       1 if there exists such a pair
7775  *       0 if there is no such pair, but there is a pair of equal values
7776  *      -1 otherwise
7777  *      -2 if some error occurred.
7778  */
7779 int isl_basic_set_follows_at(__isl_keep isl_basic_set *bset1,
7780         __isl_keep isl_basic_set *bset2, int pos)
7781 {
7782         isl_int opt;
7783         enum isl_lp_result res;
7784         int cmp;
7785
7786         isl_int_init(opt);
7787
7788         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
7789
7790         if (res == isl_lp_empty)
7791                 cmp = -1;
7792         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
7793                   res == isl_lp_unbounded)
7794                 cmp = 1;
7795         else if (res == isl_lp_ok && isl_int_is_neg(opt))
7796                 cmp = -1;
7797         else if (res == isl_lp_ok)
7798                 cmp = 0;
7799         else
7800                 cmp = -2;
7801
7802         isl_int_clear(opt);
7803         return cmp;
7804 }
7805
7806 /* Given two sets set1 and set2, check whether
7807  * for any common value of the parameters and dimensions preceding pos
7808  * there is a value of dimension pos in set1 that is larger
7809  * than a value of the same dimension in set2.
7810  *
7811  * Return
7812  *       1 if there exists such a pair
7813  *       0 if there is no such pair, but there is a pair of equal values
7814  *      -1 otherwise
7815  *      -2 if some error occurred.
7816  */
7817 int isl_set_follows_at(__isl_keep isl_set *set1,
7818         __isl_keep isl_set *set2, int pos)
7819 {
7820         int i, j;
7821         int follows = -1;
7822
7823         if (!set1 || !set2)
7824                 return -2;
7825
7826         for (i = 0; i < set1->n; ++i)
7827                 for (j = 0; j < set2->n; ++j) {
7828                         int f;
7829                         f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
7830                         if (f == 1 || f == -2)
7831                                 return f;
7832                         if (f > follows)
7833                                 follows = f;
7834                 }
7835
7836         return follows;
7837 }
7838
7839 static int isl_basic_map_plain_has_fixed_var(__isl_keep isl_basic_map *bmap,
7840         unsigned pos, isl_int *val)
7841 {
7842         int i;
7843         int d;
7844         unsigned total;
7845
7846         if (!bmap)
7847                 return -1;
7848         total = isl_basic_map_total_dim(bmap);
7849         for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
7850                 for (; d+1 > pos; --d)
7851                         if (!isl_int_is_zero(bmap->eq[i][1+d]))
7852                                 break;
7853                 if (d != pos)
7854                         continue;
7855                 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
7856                         return 0;
7857                 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
7858                         return 0;
7859                 if (!isl_int_is_one(bmap->eq[i][1+d]))
7860                         return 0;
7861                 if (val)
7862                         isl_int_neg(*val, bmap->eq[i][0]);
7863                 return 1;
7864         }
7865         return 0;
7866 }
7867
7868 static int isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
7869         unsigned pos, isl_int *val)
7870 {
7871         int i;
7872         isl_int v;
7873         isl_int tmp;
7874         int fixed;
7875
7876         if (!map)
7877                 return -1;
7878         if (map->n == 0)
7879                 return 0;
7880         if (map->n == 1)
7881                 return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val); 
7882         isl_int_init(v);
7883         isl_int_init(tmp);
7884         fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v); 
7885         for (i = 1; fixed == 1 && i < map->n; ++i) {
7886                 fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp); 
7887                 if (fixed == 1 && isl_int_ne(tmp, v))
7888                         fixed = 0;
7889         }
7890         if (val)
7891                 isl_int_set(*val, v);
7892         isl_int_clear(tmp);
7893         isl_int_clear(v);
7894         return fixed;
7895 }
7896
7897 static int isl_basic_set_plain_has_fixed_var(__isl_keep isl_basic_set *bset,
7898         unsigned pos, isl_int *val)
7899 {
7900         return isl_basic_map_plain_has_fixed_var((struct isl_basic_map *)bset,
7901                                                 pos, val);
7902 }
7903
7904 static int isl_set_plain_has_fixed_var(__isl_keep isl_set *set, unsigned pos,
7905         isl_int *val)
7906 {
7907         return isl_map_plain_has_fixed_var((struct isl_map *)set, pos, val);
7908 }
7909
7910 int isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
7911         enum isl_dim_type type, unsigned pos, isl_int *val)
7912 {
7913         if (pos >= isl_basic_map_dim(bmap, type))
7914                 return -1;
7915         return isl_basic_map_plain_has_fixed_var(bmap,
7916                 isl_basic_map_offset(bmap, type) - 1 + pos, val);
7917 }
7918
7919 int isl_map_plain_is_fixed(__isl_keep isl_map *map,
7920         enum isl_dim_type type, unsigned pos, isl_int *val)
7921 {
7922         if (pos >= isl_map_dim(map, type))
7923                 return -1;
7924         return isl_map_plain_has_fixed_var(map,
7925                 map_offset(map, type) - 1 + pos, val);
7926 }
7927
7928 int isl_set_plain_is_fixed(__isl_keep isl_set *set,
7929         enum isl_dim_type type, unsigned pos, isl_int *val)
7930 {
7931         return isl_map_plain_is_fixed(set, type, pos, val);
7932 }
7933
7934 int isl_map_fast_is_fixed(__isl_keep isl_map *map,
7935         enum isl_dim_type type, unsigned pos, isl_int *val)
7936 {
7937         return isl_map_plain_is_fixed(map, type, pos, val);
7938 }
7939
7940 /* Check if dimension dim has fixed value and if so and if val is not NULL,
7941  * then return this fixed value in *val.
7942  */
7943 int isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset,
7944         unsigned dim, isl_int *val)
7945 {
7946         return isl_basic_set_plain_has_fixed_var(bset,
7947                                         isl_basic_set_n_param(bset) + dim, val);
7948 }
7949
7950 /* Check if dimension dim has fixed value and if so and if val is not NULL,
7951  * then return this fixed value in *val.
7952  */
7953 int isl_set_plain_dim_is_fixed(__isl_keep isl_set *set,
7954         unsigned dim, isl_int *val)
7955 {
7956         return isl_set_plain_has_fixed_var(set, isl_set_n_param(set) + dim, val);
7957 }
7958
7959 int isl_set_fast_dim_is_fixed(__isl_keep isl_set *set,
7960         unsigned dim, isl_int *val)
7961 {
7962         return isl_set_plain_dim_is_fixed(set, dim, val);
7963 }
7964
7965 /* Check if input variable in has fixed value and if so and if val is not NULL,
7966  * then return this fixed value in *val.
7967  */
7968 int isl_map_plain_input_is_fixed(__isl_keep isl_map *map,
7969         unsigned in, isl_int *val)
7970 {
7971         return isl_map_plain_has_fixed_var(map, isl_map_n_param(map) + in, val);
7972 }
7973
7974 /* Check if dimension dim has an (obvious) fixed lower bound and if so
7975  * and if val is not NULL, then return this lower bound in *val.
7976  */
7977 int isl_basic_set_plain_dim_has_fixed_lower_bound(
7978         __isl_keep isl_basic_set *bset, unsigned dim, isl_int *val)
7979 {
7980         int i, i_eq = -1, i_ineq = -1;
7981         isl_int *c;
7982         unsigned total;
7983         unsigned nparam;
7984
7985         if (!bset)
7986                 return -1;
7987         total = isl_basic_set_total_dim(bset);
7988         nparam = isl_basic_set_n_param(bset);
7989         for (i = 0; i < bset->n_eq; ++i) {
7990                 if (isl_int_is_zero(bset->eq[i][1+nparam+dim]))
7991                         continue;
7992                 if (i_eq != -1)
7993                         return 0;
7994                 i_eq = i;
7995         }
7996         for (i = 0; i < bset->n_ineq; ++i) {
7997                 if (!isl_int_is_pos(bset->ineq[i][1+nparam+dim]))
7998                         continue;
7999                 if (i_eq != -1 || i_ineq != -1)
8000                         return 0;
8001                 i_ineq = i;
8002         }
8003         if (i_eq == -1 && i_ineq == -1)
8004                 return 0;
8005         c = i_eq != -1 ? bset->eq[i_eq] : bset->ineq[i_ineq];
8006         /* The coefficient should always be one due to normalization. */
8007         if (!isl_int_is_one(c[1+nparam+dim]))
8008                 return 0;
8009         if (isl_seq_first_non_zero(c+1, nparam+dim) != -1)
8010                 return 0;
8011         if (isl_seq_first_non_zero(c+1+nparam+dim+1,
8012                                         total - nparam - dim - 1) != -1)
8013                 return 0;
8014         if (val)
8015                 isl_int_neg(*val, c[0]);
8016         return 1;
8017 }
8018
8019 int isl_set_plain_dim_has_fixed_lower_bound(__isl_keep isl_set *set,
8020         unsigned dim, isl_int *val)
8021 {
8022         int i;
8023         isl_int v;
8024         isl_int tmp;
8025         int fixed;
8026
8027         if (!set)
8028                 return -1;
8029         if (set->n == 0)
8030                 return 0;
8031         if (set->n == 1)
8032                 return isl_basic_set_plain_dim_has_fixed_lower_bound(set->p[0],
8033                                                                 dim, val);
8034         isl_int_init(v);
8035         isl_int_init(tmp);
8036         fixed = isl_basic_set_plain_dim_has_fixed_lower_bound(set->p[0],
8037                                                                 dim, &v);
8038         for (i = 1; fixed == 1 && i < set->n; ++i) {
8039                 fixed = isl_basic_set_plain_dim_has_fixed_lower_bound(set->p[i],
8040                                                                 dim, &tmp);
8041                 if (fixed == 1 && isl_int_ne(tmp, v))
8042                         fixed = 0;
8043         }
8044         if (val)
8045                 isl_int_set(*val, v);
8046         isl_int_clear(tmp);
8047         isl_int_clear(v);
8048         return fixed;
8049 }
8050
8051 struct constraint {
8052         unsigned        size;
8053         isl_int         *c;
8054 };
8055
8056 /* uset_gist depends on constraints without existentially quantified
8057  * variables sorting first.
8058  */
8059 static int qsort_constraint_cmp(const void *p1, const void *p2)
8060 {
8061         const struct constraint *c1 = (const struct constraint *)p1;
8062         const struct constraint *c2 = (const struct constraint *)p2;
8063         int l1, l2;
8064         unsigned size = isl_min(c1->size, c2->size);
8065
8066         l1 = isl_seq_last_non_zero(c1->c, size);
8067         l2 = isl_seq_last_non_zero(c2->c, size);
8068
8069         if (l1 != l2)
8070                 return l1 - l2;
8071
8072         return isl_seq_cmp(c1->c, c2->c, size);
8073 }
8074
8075 static struct isl_basic_map *isl_basic_map_sort_constraints(
8076         struct isl_basic_map *bmap)
8077 {
8078         int i;
8079         struct constraint *c;
8080         unsigned total;
8081
8082         if (!bmap)
8083                 return NULL;
8084         total = isl_basic_map_total_dim(bmap);
8085         c = isl_alloc_array(bmap->ctx, struct constraint, bmap->n_ineq);
8086         if (!c)
8087                 goto error;
8088         for (i = 0; i < bmap->n_ineq; ++i) {
8089                 c[i].size = total;
8090                 c[i].c = bmap->ineq[i];
8091         }
8092         qsort(c, bmap->n_ineq, sizeof(struct constraint), qsort_constraint_cmp);
8093         for (i = 0; i < bmap->n_ineq; ++i)
8094                 bmap->ineq[i] = c[i].c;
8095         free(c);
8096         return bmap;
8097 error:
8098         isl_basic_map_free(bmap);
8099         return NULL;
8100 }
8101
8102 __isl_give isl_basic_set *isl_basic_set_sort_constraints(
8103         __isl_take isl_basic_set *bset)
8104 {
8105         return (struct isl_basic_set *)isl_basic_map_sort_constraints(
8106                                                 (struct isl_basic_map *)bset);
8107 }
8108
8109 struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap)
8110 {
8111         if (!bmap)
8112                 return NULL;
8113         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED))
8114                 return bmap;
8115         bmap = isl_basic_map_remove_redundancies(bmap);
8116         bmap = isl_basic_map_sort_constraints(bmap);
8117         ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
8118         return bmap;
8119 }
8120
8121 struct isl_basic_set *isl_basic_set_normalize(struct isl_basic_set *bset)
8122 {
8123         return (struct isl_basic_set *)isl_basic_map_normalize(
8124                                                 (struct isl_basic_map *)bset);
8125 }
8126
8127 int isl_basic_map_plain_cmp(const __isl_keep isl_basic_map *bmap1,
8128         const __isl_keep isl_basic_map *bmap2)
8129 {
8130         int i, cmp;
8131         unsigned total;
8132
8133         if (bmap1 == bmap2)
8134                 return 0;
8135         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) !=
8136             ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL))
8137                 return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) ? -1 : 1;
8138         if (isl_basic_map_n_param(bmap1) != isl_basic_map_n_param(bmap2))
8139                 return isl_basic_map_n_param(bmap1) - isl_basic_map_n_param(bmap2);
8140         if (isl_basic_map_n_in(bmap1) != isl_basic_map_n_in(bmap2))
8141                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
8142         if (isl_basic_map_n_out(bmap1) != isl_basic_map_n_out(bmap2))
8143                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
8144         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
8145             ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
8146                 return 0;
8147         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
8148                 return 1;
8149         if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
8150                 return -1;
8151         if (bmap1->n_eq != bmap2->n_eq)
8152                 return bmap1->n_eq - bmap2->n_eq;
8153         if (bmap1->n_ineq != bmap2->n_ineq)
8154                 return bmap1->n_ineq - bmap2->n_ineq;
8155         if (bmap1->n_div != bmap2->n_div)
8156                 return bmap1->n_div - bmap2->n_div;
8157         total = isl_basic_map_total_dim(bmap1);
8158         for (i = 0; i < bmap1->n_eq; ++i) {
8159                 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
8160                 if (cmp)
8161                         return cmp;
8162         }
8163         for (i = 0; i < bmap1->n_ineq; ++i) {
8164                 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
8165                 if (cmp)
8166                         return cmp;
8167         }
8168         for (i = 0; i < bmap1->n_div; ++i) {
8169                 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
8170                 if (cmp)
8171                         return cmp;
8172         }
8173         return 0;
8174 }
8175
8176 int isl_basic_set_plain_cmp(const __isl_keep isl_basic_set *bset1,
8177         const __isl_keep isl_basic_set *bset2)
8178 {
8179         return isl_basic_map_plain_cmp(bset1, bset2);
8180 }
8181
8182 int isl_set_plain_cmp(const __isl_keep isl_set *set1,
8183         const __isl_keep isl_set *set2)
8184 {
8185         int i, cmp;
8186
8187         if (set1 == set2)
8188                 return 0;
8189         if (set1->n != set2->n)
8190                 return set1->n - set2->n;
8191
8192         for (i = 0; i < set1->n; ++i) {
8193                 cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
8194                 if (cmp)
8195                         return cmp;
8196         }
8197
8198         return 0;
8199 }
8200
8201 int isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
8202         __isl_keep isl_basic_map *bmap2)
8203 {
8204         return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
8205 }
8206
8207 int isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1,
8208         __isl_keep isl_basic_set *bset2)
8209 {
8210         return isl_basic_map_plain_is_equal((isl_basic_map *)bset1,
8211                                             (isl_basic_map *)bset2);
8212 }
8213
8214 static int qsort_bmap_cmp(const void *p1, const void *p2)
8215 {
8216         const struct isl_basic_map *bmap1 = *(const struct isl_basic_map **)p1;
8217         const struct isl_basic_map *bmap2 = *(const struct isl_basic_map **)p2;
8218
8219         return isl_basic_map_plain_cmp(bmap1, bmap2);
8220 }
8221
8222 /* We normalize in place, but if anything goes wrong we need
8223  * to return NULL, so we need to make sure we don't change the
8224  * meaning of any possible other copies of map.
8225  */
8226 struct isl_map *isl_map_normalize(struct isl_map *map)
8227 {
8228         int i, j;
8229         struct isl_basic_map *bmap;
8230
8231         if (!map)
8232                 return NULL;
8233         if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED))
8234                 return map;
8235         for (i = 0; i < map->n; ++i) {
8236                 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
8237                 if (!bmap)
8238                         goto error;
8239                 isl_basic_map_free(map->p[i]);
8240                 map->p[i] = bmap;
8241         }
8242         qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
8243         ISL_F_SET(map, ISL_MAP_NORMALIZED);
8244         map = isl_map_remove_empty_parts(map);
8245         if (!map)
8246                 return NULL;
8247         for (i = map->n - 1; i >= 1; --i) {
8248                 if (!isl_basic_map_plain_is_equal(map->p[i-1], map->p[i]))
8249                         continue;
8250                 isl_basic_map_free(map->p[i-1]);
8251                 for (j = i; j < map->n; ++j)
8252                         map->p[j-1] = map->p[j];
8253                 map->n--;
8254         }
8255         return map;
8256 error:
8257         isl_map_free(map);
8258         return NULL;
8259
8260 }
8261
8262 struct isl_set *isl_set_normalize(struct isl_set *set)
8263 {
8264         return (struct isl_set *)isl_map_normalize((struct isl_map *)set);
8265 }
8266
8267 int isl_map_plain_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
8268 {
8269         int i;
8270         int equal;
8271
8272         if (!map1 || !map2)
8273                 return -1;
8274
8275         if (map1 == map2)
8276                 return 1;
8277         if (!isl_space_is_equal(map1->dim, map2->dim))
8278                 return 0;
8279
8280         map1 = isl_map_copy(map1);
8281         map2 = isl_map_copy(map2);
8282         map1 = isl_map_normalize(map1);
8283         map2 = isl_map_normalize(map2);
8284         if (!map1 || !map2)
8285                 goto error;
8286         equal = map1->n == map2->n;
8287         for (i = 0; equal && i < map1->n; ++i) {
8288                 equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
8289                 if (equal < 0)
8290                         goto error;
8291         }
8292         isl_map_free(map1);
8293         isl_map_free(map2);
8294         return equal;
8295 error:
8296         isl_map_free(map1);
8297         isl_map_free(map2);
8298         return -1;
8299 }
8300
8301 int isl_map_fast_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
8302 {
8303         return isl_map_plain_is_equal(map1, map2);
8304 }
8305
8306 int isl_set_plain_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
8307 {
8308         return isl_map_plain_is_equal((struct isl_map *)set1,
8309                                                 (struct isl_map *)set2);
8310 }
8311
8312 int isl_set_fast_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
8313 {
8314         return isl_set_plain_is_equal(set1, set2);
8315 }
8316
8317 /* Return an interval that ranges from min to max (inclusive)
8318  */
8319 struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx,
8320         isl_int min, isl_int max)
8321 {
8322         int k;
8323         struct isl_basic_set *bset = NULL;
8324
8325         bset = isl_basic_set_alloc(ctx, 0, 1, 0, 0, 2);
8326         if (!bset)
8327                 goto error;
8328
8329         k = isl_basic_set_alloc_inequality(bset);
8330         if (k < 0)
8331                 goto error;
8332         isl_int_set_si(bset->ineq[k][1], 1);
8333         isl_int_neg(bset->ineq[k][0], min);
8334
8335         k = isl_basic_set_alloc_inequality(bset);
8336         if (k < 0)
8337                 goto error;
8338         isl_int_set_si(bset->ineq[k][1], -1);
8339         isl_int_set(bset->ineq[k][0], max);
8340
8341         return bset;
8342 error:
8343         isl_basic_set_free(bset);
8344         return NULL;
8345 }
8346
8347 /* Return the Cartesian product of the basic sets in list (in the given order).
8348  */
8349 __isl_give isl_basic_set *isl_basic_set_list_product(
8350         __isl_take struct isl_basic_set_list *list)
8351 {
8352         int i;
8353         unsigned dim;
8354         unsigned nparam;
8355         unsigned extra;
8356         unsigned n_eq;
8357         unsigned n_ineq;
8358         struct isl_basic_set *product = NULL;
8359
8360         if (!list)
8361                 goto error;
8362         isl_assert(list->ctx, list->n > 0, goto error);
8363         isl_assert(list->ctx, list->p[0], goto error);
8364         nparam = isl_basic_set_n_param(list->p[0]);
8365         dim = isl_basic_set_n_dim(list->p[0]);
8366         extra = list->p[0]->n_div;
8367         n_eq = list->p[0]->n_eq;
8368         n_ineq = list->p[0]->n_ineq;
8369         for (i = 1; i < list->n; ++i) {
8370                 isl_assert(list->ctx, list->p[i], goto error);
8371                 isl_assert(list->ctx,
8372                     nparam == isl_basic_set_n_param(list->p[i]), goto error);
8373                 dim += isl_basic_set_n_dim(list->p[i]);
8374                 extra += list->p[i]->n_div;
8375                 n_eq += list->p[i]->n_eq;
8376                 n_ineq += list->p[i]->n_ineq;
8377         }
8378         product = isl_basic_set_alloc(list->ctx, nparam, dim, extra,
8379                                         n_eq, n_ineq);
8380         if (!product)
8381                 goto error;
8382         dim = 0;
8383         for (i = 0; i < list->n; ++i) {
8384                 isl_basic_set_add_constraints(product,
8385                                         isl_basic_set_copy(list->p[i]), dim);
8386                 dim += isl_basic_set_n_dim(list->p[i]);
8387         }
8388         isl_basic_set_list_free(list);
8389         return product;
8390 error:
8391         isl_basic_set_free(product);
8392         isl_basic_set_list_free(list);
8393         return NULL;
8394 }
8395
8396 struct isl_basic_map *isl_basic_map_product(
8397                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
8398 {
8399         isl_space *dim_result = NULL;
8400         struct isl_basic_map *bmap;
8401         unsigned in1, in2, out1, out2, nparam, total, pos;
8402         struct isl_dim_map *dim_map1, *dim_map2;
8403
8404         if (!bmap1 || !bmap2)
8405                 goto error;
8406
8407         isl_assert(bmap1->ctx, isl_space_match(bmap1->dim, isl_dim_param,
8408                                      bmap2->dim, isl_dim_param), goto error);
8409         dim_result = isl_space_product(isl_space_copy(bmap1->dim),
8410                                                    isl_space_copy(bmap2->dim));
8411
8412         in1 = isl_basic_map_n_in(bmap1);
8413         in2 = isl_basic_map_n_in(bmap2);
8414         out1 = isl_basic_map_n_out(bmap1);
8415         out2 = isl_basic_map_n_out(bmap2);
8416         nparam = isl_basic_map_n_param(bmap1);
8417
8418         total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
8419         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
8420         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
8421         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
8422         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
8423         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
8424         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
8425         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
8426         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
8427         isl_dim_map_div(dim_map1, bmap1, pos += out2);
8428         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
8429
8430         bmap = isl_basic_map_alloc_space(dim_result,
8431                         bmap1->n_div + bmap2->n_div,
8432                         bmap1->n_eq + bmap2->n_eq,
8433                         bmap1->n_ineq + bmap2->n_ineq);
8434         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
8435         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
8436         bmap = isl_basic_map_simplify(bmap);
8437         return isl_basic_map_finalize(bmap);
8438 error:
8439         isl_basic_map_free(bmap1);
8440         isl_basic_map_free(bmap2);
8441         return NULL;
8442 }
8443
8444 __isl_give isl_basic_map *isl_basic_map_flat_product(
8445         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8446 {
8447         isl_basic_map *prod;
8448
8449         prod = isl_basic_map_product(bmap1, bmap2);
8450         prod = isl_basic_map_flatten(prod);
8451         return prod;
8452 }
8453
8454 __isl_give isl_basic_set *isl_basic_set_flat_product(
8455         __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
8456 {
8457         return isl_basic_map_flat_range_product(bset1, bset2);
8458 }
8459
8460 __isl_give isl_basic_map *isl_basic_map_domain_product(
8461         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8462 {
8463         isl_space *space_result = NULL;
8464         isl_basic_map *bmap;
8465         unsigned in1, in2, out, nparam, total, pos;
8466         struct isl_dim_map *dim_map1, *dim_map2;
8467
8468         if (!bmap1 || !bmap2)
8469                 goto error;
8470
8471         space_result = isl_space_domain_product(isl_space_copy(bmap1->dim),
8472                                                 isl_space_copy(bmap2->dim));
8473
8474         in1 = isl_basic_map_dim(bmap1, isl_dim_in);
8475         in2 = isl_basic_map_dim(bmap2, isl_dim_in);
8476         out = isl_basic_map_dim(bmap1, isl_dim_out);
8477         nparam = isl_basic_map_dim(bmap1, isl_dim_param);
8478
8479         total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
8480         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
8481         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
8482         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
8483         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
8484         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
8485         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
8486         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
8487         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
8488         isl_dim_map_div(dim_map1, bmap1, pos += out);
8489         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
8490
8491         bmap = isl_basic_map_alloc_space(space_result,
8492                         bmap1->n_div + bmap2->n_div,
8493                         bmap1->n_eq + bmap2->n_eq,
8494                         bmap1->n_ineq + bmap2->n_ineq);
8495         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
8496         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
8497         bmap = isl_basic_map_simplify(bmap);
8498         return isl_basic_map_finalize(bmap);
8499 error:
8500         isl_basic_map_free(bmap1);
8501         isl_basic_map_free(bmap2);
8502         return NULL;
8503 }
8504
8505 __isl_give isl_basic_map *isl_basic_map_range_product(
8506         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8507 {
8508         isl_space *dim_result = NULL;
8509         isl_basic_map *bmap;
8510         unsigned in, out1, out2, nparam, total, pos;
8511         struct isl_dim_map *dim_map1, *dim_map2;
8512
8513         if (!bmap1 || !bmap2)
8514                 goto error;
8515
8516         if (!isl_space_match(bmap1->dim, isl_dim_param,
8517                             bmap2->dim, isl_dim_param))
8518                 isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
8519                         "parameters don't match", goto error);
8520
8521         dim_result = isl_space_range_product(isl_space_copy(bmap1->dim),
8522                                            isl_space_copy(bmap2->dim));
8523
8524         in = isl_basic_map_dim(bmap1, isl_dim_in);
8525         out1 = isl_basic_map_n_out(bmap1);
8526         out2 = isl_basic_map_n_out(bmap2);
8527         nparam = isl_basic_map_n_param(bmap1);
8528
8529         total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
8530         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
8531         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
8532         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
8533         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
8534         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
8535         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
8536         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
8537         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
8538         isl_dim_map_div(dim_map1, bmap1, pos += out2);
8539         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
8540
8541         bmap = isl_basic_map_alloc_space(dim_result,
8542                         bmap1->n_div + bmap2->n_div,
8543                         bmap1->n_eq + bmap2->n_eq,
8544                         bmap1->n_ineq + bmap2->n_ineq);
8545         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
8546         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
8547         bmap = isl_basic_map_simplify(bmap);
8548         return isl_basic_map_finalize(bmap);
8549 error:
8550         isl_basic_map_free(bmap1);
8551         isl_basic_map_free(bmap2);
8552         return NULL;
8553 }
8554
8555 __isl_give isl_basic_map *isl_basic_map_flat_range_product(
8556         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8557 {
8558         isl_basic_map *prod;
8559
8560         prod = isl_basic_map_range_product(bmap1, bmap2);
8561         prod = isl_basic_map_flatten_range(prod);
8562         return prod;
8563 }
8564
8565 static __isl_give isl_map *map_product(__isl_take isl_map *map1,
8566         __isl_take isl_map *map2,
8567         __isl_give isl_space *(*dim_product)(__isl_take isl_space *left,
8568                                            __isl_take isl_space *right),
8569         __isl_give isl_basic_map *(*basic_map_product)(
8570                 __isl_take isl_basic_map *left, __isl_take isl_basic_map *right))
8571 {
8572         unsigned flags = 0;
8573         struct isl_map *result;
8574         int i, j;
8575
8576         if (!map1 || !map2)
8577                 goto error;
8578
8579         isl_assert(map1->ctx, isl_space_match(map1->dim, isl_dim_param,
8580                                          map2->dim, isl_dim_param), goto error);
8581
8582         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
8583             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
8584                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
8585
8586         result = isl_map_alloc_space(dim_product(isl_space_copy(map1->dim),
8587                                                isl_space_copy(map2->dim)),
8588                                 map1->n * map2->n, flags);
8589         if (!result)
8590                 goto error;
8591         for (i = 0; i < map1->n; ++i)
8592                 for (j = 0; j < map2->n; ++j) {
8593                         struct isl_basic_map *part;
8594                         part = basic_map_product(isl_basic_map_copy(map1->p[i]),
8595                                                  isl_basic_map_copy(map2->p[j]));
8596                         if (isl_basic_map_is_empty(part))
8597                                 isl_basic_map_free(part);
8598                         else
8599                                 result = isl_map_add_basic_map(result, part);
8600                         if (!result)
8601                                 goto error;
8602                 }
8603         isl_map_free(map1);
8604         isl_map_free(map2);
8605         return result;
8606 error:
8607         isl_map_free(map1);
8608         isl_map_free(map2);
8609         return NULL;
8610 }
8611
8612 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
8613  */
8614 static __isl_give isl_map *map_product_aligned(__isl_take isl_map *map1,
8615         __isl_take isl_map *map2)
8616 {
8617         return map_product(map1, map2, &isl_space_product, &isl_basic_map_product);
8618 }
8619
8620 __isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
8621         __isl_take isl_map *map2)
8622 {
8623         return isl_map_align_params_map_map_and(map1, map2, &map_product_aligned);
8624 }
8625
8626 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
8627  */
8628 __isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
8629         __isl_take isl_map *map2)
8630 {
8631         isl_map *prod;
8632
8633         prod = isl_map_product(map1, map2);
8634         prod = isl_map_flatten(prod);
8635         return prod;
8636 }
8637
8638 /* Given two set A and B, construct its Cartesian product A x B.
8639  */
8640 struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2)
8641 {
8642         return isl_map_range_product(set1, set2);
8643 }
8644
8645 __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
8646         __isl_take isl_set *set2)
8647 {
8648         return isl_map_flat_range_product(set1, set2);
8649 }
8650
8651 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
8652  */
8653 static __isl_give isl_map *map_domain_product_aligned(__isl_take isl_map *map1,
8654         __isl_take isl_map *map2)
8655 {
8656         return map_product(map1, map2, &isl_space_domain_product,
8657                                 &isl_basic_map_domain_product);
8658 }
8659
8660 /* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
8661  */
8662 static __isl_give isl_map *map_range_product_aligned(__isl_take isl_map *map1,
8663         __isl_take isl_map *map2)
8664 {
8665         return map_product(map1, map2, &isl_space_range_product,
8666                                 &isl_basic_map_range_product);
8667 }
8668
8669 __isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
8670         __isl_take isl_map *map2)
8671 {
8672         return isl_map_align_params_map_map_and(map1, map2,
8673                                                 &map_domain_product_aligned);
8674 }
8675
8676 __isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
8677         __isl_take isl_map *map2)
8678 {
8679         return isl_map_align_params_map_map_and(map1, map2,
8680                                                 &map_range_product_aligned);
8681 }
8682
8683 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
8684  */
8685 __isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
8686         __isl_take isl_map *map2)
8687 {
8688         isl_map *prod;
8689
8690         prod = isl_map_domain_product(map1, map2);
8691         prod = isl_map_flatten_domain(prod);
8692         return prod;
8693 }
8694
8695 /* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
8696  */
8697 __isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
8698         __isl_take isl_map *map2)
8699 {
8700         isl_map *prod;
8701
8702         prod = isl_map_range_product(map1, map2);
8703         prod = isl_map_flatten_range(prod);
8704         return prod;
8705 }
8706
8707 uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
8708 {
8709         int i;
8710         uint32_t hash = isl_hash_init();
8711         unsigned total;
8712
8713         if (!bmap)
8714                 return 0;
8715         bmap = isl_basic_map_copy(bmap);
8716         bmap = isl_basic_map_normalize(bmap);
8717         if (!bmap)
8718                 return 0;
8719         total = isl_basic_map_total_dim(bmap);
8720         isl_hash_byte(hash, bmap->n_eq & 0xFF);
8721         for (i = 0; i < bmap->n_eq; ++i) {
8722                 uint32_t c_hash;
8723                 c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
8724                 isl_hash_hash(hash, c_hash);
8725         }
8726         isl_hash_byte(hash, bmap->n_ineq & 0xFF);
8727         for (i = 0; i < bmap->n_ineq; ++i) {
8728                 uint32_t c_hash;
8729                 c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
8730                 isl_hash_hash(hash, c_hash);
8731         }
8732         isl_hash_byte(hash, bmap->n_div & 0xFF);
8733         for (i = 0; i < bmap->n_div; ++i) {
8734                 uint32_t c_hash;
8735                 if (isl_int_is_zero(bmap->div[i][0]))
8736                         continue;
8737                 isl_hash_byte(hash, i & 0xFF);
8738                 c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
8739                 isl_hash_hash(hash, c_hash);
8740         }
8741         isl_basic_map_free(bmap);
8742         return hash;
8743 }
8744
8745 uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_set *bset)
8746 {
8747         return isl_basic_map_get_hash((isl_basic_map *)bset);
8748 }
8749
8750 uint32_t isl_map_get_hash(__isl_keep isl_map *map)
8751 {
8752         int i;
8753         uint32_t hash;
8754
8755         if (!map)
8756                 return 0;
8757         map = isl_map_copy(map);
8758         map = isl_map_normalize(map);
8759         if (!map)
8760                 return 0;
8761
8762         hash = isl_hash_init();
8763         for (i = 0; i < map->n; ++i) {
8764                 uint32_t bmap_hash;
8765                 bmap_hash = isl_basic_map_get_hash(map->p[i]);
8766                 isl_hash_hash(hash, bmap_hash);
8767         }
8768                 
8769         isl_map_free(map);
8770
8771         return hash;
8772 }
8773
8774 uint32_t isl_set_get_hash(__isl_keep isl_set *set)
8775 {
8776         return isl_map_get_hash((isl_map *)set);
8777 }
8778
8779 /* Check if the value for dimension dim is completely determined
8780  * by the values of the other parameters and variables.
8781  * That is, check if dimension dim is involved in an equality.
8782  */
8783 int isl_basic_set_dim_is_unique(struct isl_basic_set *bset, unsigned dim)
8784 {
8785         int i;
8786         unsigned nparam;
8787
8788         if (!bset)
8789                 return -1;
8790         nparam = isl_basic_set_n_param(bset);
8791         for (i = 0; i < bset->n_eq; ++i)
8792                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + dim]))
8793                         return 1;
8794         return 0;
8795 }
8796
8797 /* Check if the value for dimension dim is completely determined
8798  * by the values of the other parameters and variables.
8799  * That is, check if dimension dim is involved in an equality
8800  * for each of the subsets.
8801  */
8802 int isl_set_dim_is_unique(struct isl_set *set, unsigned dim)
8803 {
8804         int i;
8805
8806         if (!set)
8807                 return -1;
8808         for (i = 0; i < set->n; ++i) {
8809                 int unique;
8810                 unique = isl_basic_set_dim_is_unique(set->p[i], dim);
8811                 if (unique != 1)
8812                         return unique;
8813         }
8814         return 1;
8815 }
8816
8817 int isl_set_n_basic_set(__isl_keep isl_set *set)
8818 {
8819         return set ? set->n : 0;
8820 }
8821
8822 int isl_map_foreach_basic_map(__isl_keep isl_map *map,
8823         int (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
8824 {
8825         int i;
8826
8827         if (!map)
8828                 return -1;
8829
8830         for (i = 0; i < map->n; ++i)
8831                 if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
8832                         return -1;
8833
8834         return 0;
8835 }
8836
8837 int isl_set_foreach_basic_set(__isl_keep isl_set *set,
8838         int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user)
8839 {
8840         int i;
8841
8842         if (!set)
8843                 return -1;
8844
8845         for (i = 0; i < set->n; ++i)
8846                 if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
8847                         return -1;
8848
8849         return 0;
8850 }
8851
8852 __isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset)
8853 {
8854         isl_space *dim;
8855
8856         if (!bset)
8857                 return NULL;
8858
8859         bset = isl_basic_set_cow(bset);
8860         if (!bset)
8861                 return NULL;
8862
8863         dim = isl_basic_set_get_space(bset);
8864         dim = isl_space_lift(dim, bset->n_div);
8865         if (!dim)
8866                 goto error;
8867         isl_space_free(bset->dim);
8868         bset->dim = dim;
8869         bset->extra -= bset->n_div;
8870         bset->n_div = 0;
8871
8872         bset = isl_basic_set_finalize(bset);
8873
8874         return bset;
8875 error:
8876         isl_basic_set_free(bset);
8877         return NULL;
8878 }
8879
8880 __isl_give isl_set *isl_set_lift(__isl_take isl_set *set)
8881 {
8882         int i;
8883         isl_space *dim;
8884         unsigned n_div;
8885
8886         set = isl_set_align_divs(set);
8887
8888         if (!set)
8889                 return NULL;
8890
8891         set = isl_set_cow(set);
8892         if (!set)
8893                 return NULL;
8894
8895         n_div = set->p[0]->n_div;
8896         dim = isl_set_get_space(set);
8897         dim = isl_space_lift(dim, n_div);
8898         if (!dim)
8899                 goto error;
8900         isl_space_free(set->dim);
8901         set->dim = dim;
8902
8903         for (i = 0; i < set->n; ++i) {
8904                 set->p[i] = isl_basic_set_lift(set->p[i]);
8905                 if (!set->p[i])
8906                         goto error;
8907         }
8908
8909         return set;
8910 error:
8911         isl_set_free(set);
8912         return NULL;
8913 }
8914
8915 __isl_give isl_map *isl_set_lifting(__isl_take isl_set *set)
8916 {
8917         isl_space *dim;
8918         struct isl_basic_map *bmap;
8919         unsigned n_set;
8920         unsigned n_div;
8921         unsigned n_param;
8922         unsigned total;
8923         int i, k, l;
8924
8925         set = isl_set_align_divs(set);
8926
8927         if (!set)
8928                 return NULL;
8929
8930         dim = isl_set_get_space(set);
8931         if (set->n == 0 || set->p[0]->n_div == 0) {
8932                 isl_set_free(set);
8933                 return isl_map_identity(isl_space_map_from_set(dim));
8934         }
8935
8936         n_div = set->p[0]->n_div;
8937         dim = isl_space_map_from_set(dim);
8938         n_param = isl_space_dim(dim, isl_dim_param);
8939         n_set = isl_space_dim(dim, isl_dim_in);
8940         dim = isl_space_extend(dim, n_param, n_set, n_set + n_div);
8941         bmap = isl_basic_map_alloc_space(dim, 0, n_set, 2 * n_div);
8942         for (i = 0; i < n_set; ++i)
8943                 bmap = var_equal(bmap, i);
8944
8945         total = n_param + n_set + n_set + n_div;
8946         for (i = 0; i < n_div; ++i) {
8947                 k = isl_basic_map_alloc_inequality(bmap);
8948                 if (k < 0)
8949                         goto error;
8950                 isl_seq_cpy(bmap->ineq[k], set->p[0]->div[i]+1, 1+n_param);
8951                 isl_seq_clr(bmap->ineq[k]+1+n_param, n_set);
8952                 isl_seq_cpy(bmap->ineq[k]+1+n_param+n_set,
8953                             set->p[0]->div[i]+1+1+n_param, n_set + n_div);
8954                 isl_int_neg(bmap->ineq[k][1+n_param+n_set+n_set+i],
8955                             set->p[0]->div[i][0]);
8956
8957                 l = isl_basic_map_alloc_inequality(bmap);
8958                 if (l < 0)
8959                         goto error;
8960                 isl_seq_neg(bmap->ineq[l], bmap->ineq[k], 1 + total);
8961                 isl_int_add(bmap->ineq[l][0], bmap->ineq[l][0],
8962                             set->p[0]->div[i][0]);
8963                 isl_int_sub_ui(bmap->ineq[l][0], bmap->ineq[l][0], 1);
8964         }
8965
8966         isl_set_free(set);
8967         bmap = isl_basic_map_simplify(bmap);
8968         bmap = isl_basic_map_finalize(bmap);
8969         return isl_map_from_basic_map(bmap);
8970 error:
8971         isl_set_free(set);
8972         isl_basic_map_free(bmap);
8973         return NULL;
8974 }
8975
8976 int isl_basic_set_size(__isl_keep isl_basic_set *bset)
8977 {
8978         unsigned dim;
8979         int size = 0;
8980
8981         if (!bset)
8982                 return -1;
8983
8984         dim = isl_basic_set_total_dim(bset);
8985         size += bset->n_eq * (1 + dim);
8986         size += bset->n_ineq * (1 + dim);
8987         size += bset->n_div * (2 + dim);
8988
8989         return size;
8990 }
8991
8992 int isl_set_size(__isl_keep isl_set *set)
8993 {
8994         int i;
8995         int size = 0;
8996
8997         if (!set)
8998                 return -1;
8999
9000         for (i = 0; i < set->n; ++i)
9001                 size += isl_basic_set_size(set->p[i]);
9002
9003         return size;
9004 }
9005
9006 /* Check if there is any lower bound (if lower == 0) and/or upper
9007  * bound (if upper == 0) on the specified dim.
9008  */
9009 static int basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
9010         enum isl_dim_type type, unsigned pos, int lower, int upper)
9011 {
9012         int i;
9013
9014         if (!bmap)
9015                 return -1;
9016
9017         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), return -1);
9018
9019         pos += isl_basic_map_offset(bmap, type);
9020
9021         for (i = 0; i < bmap->n_div; ++i) {
9022                 if (isl_int_is_zero(bmap->div[i][0]))
9023                         continue;
9024                 if (!isl_int_is_zero(bmap->div[i][1 + pos]))
9025                         return 1;
9026         }
9027
9028         for (i = 0; i < bmap->n_eq; ++i)
9029                 if (!isl_int_is_zero(bmap->eq[i][pos]))
9030                         return 1;
9031
9032         for (i = 0; i < bmap->n_ineq; ++i) {
9033                 int sgn = isl_int_sgn(bmap->ineq[i][pos]);
9034                 if (sgn > 0)
9035                         lower = 1;
9036                 if (sgn < 0)
9037                         upper = 1;
9038         }
9039
9040         return lower && upper;
9041 }
9042
9043 int isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
9044         enum isl_dim_type type, unsigned pos)
9045 {
9046         return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
9047 }
9048
9049 int isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap,
9050         enum isl_dim_type type, unsigned pos)
9051 {
9052         return basic_map_dim_is_bounded(bmap, type, pos, 0, 1);
9053 }
9054
9055 int isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap,
9056         enum isl_dim_type type, unsigned pos)
9057 {
9058         return basic_map_dim_is_bounded(bmap, type, pos, 1, 0);
9059 }
9060
9061 int isl_map_dim_is_bounded(__isl_keep isl_map *map,
9062         enum isl_dim_type type, unsigned pos)
9063 {
9064         int i;
9065
9066         if (!map)
9067                 return -1;
9068
9069         for (i = 0; i < map->n; ++i) {
9070                 int bounded;
9071                 bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
9072                 if (bounded < 0 || !bounded)
9073                         return bounded;
9074         }
9075
9076         return 1;
9077 }
9078
9079 /* Return 1 if the specified dim is involved in both an upper bound
9080  * and a lower bound.
9081  */
9082 int isl_set_dim_is_bounded(__isl_keep isl_set *set,
9083         enum isl_dim_type type, unsigned pos)
9084 {
9085         return isl_map_dim_is_bounded((isl_map *)set, type, pos);
9086 }
9087
9088 static int has_any_bound(__isl_keep isl_map *map,
9089         enum isl_dim_type type, unsigned pos,
9090         int (*fn)(__isl_keep isl_basic_map *bmap,
9091                   enum isl_dim_type type, unsigned pos))
9092 {
9093         int i;
9094
9095         if (!map)
9096                 return -1;
9097
9098         for (i = 0; i < map->n; ++i) {
9099                 int bounded;
9100                 bounded = fn(map->p[i], type, pos);
9101                 if (bounded < 0 || bounded)
9102                         return bounded;
9103         }
9104
9105         return 0;
9106 }
9107
9108 /* Return 1 if the specified dim is involved in any lower bound.
9109  */
9110 int isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set,
9111         enum isl_dim_type type, unsigned pos)
9112 {
9113         return has_any_bound(set, type, pos,
9114                                 &isl_basic_map_dim_has_lower_bound);
9115 }
9116
9117 /* Return 1 if the specified dim is involved in any upper bound.
9118  */
9119 int isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set,
9120         enum isl_dim_type type, unsigned pos)
9121 {
9122         return has_any_bound(set, type, pos,
9123                                 &isl_basic_map_dim_has_upper_bound);
9124 }
9125
9126 /* For each of the "n" variables starting at "first", determine
9127  * the sign of the variable and put the results in the first "n"
9128  * elements of the array "signs".
9129  * Sign
9130  *      1 means that the variable is non-negative
9131  *      -1 means that the variable is non-positive
9132  *      0 means the variable attains both positive and negative values.
9133  */
9134 int isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset,
9135         unsigned first, unsigned n, int *signs)
9136 {
9137         isl_vec *bound = NULL;
9138         struct isl_tab *tab = NULL;
9139         struct isl_tab_undo *snap;
9140         int i;
9141
9142         if (!bset || !signs)
9143                 return -1;
9144
9145         bound = isl_vec_alloc(bset->ctx, 1 + isl_basic_set_total_dim(bset));
9146         tab = isl_tab_from_basic_set(bset, 0);
9147         if (!bound || !tab)
9148                 goto error;
9149
9150         isl_seq_clr(bound->el, bound->size);
9151         isl_int_set_si(bound->el[0], -1);
9152
9153         snap = isl_tab_snap(tab);
9154         for (i = 0; i < n; ++i) {
9155                 int empty;
9156
9157                 isl_int_set_si(bound->el[1 + first + i], -1);
9158                 if (isl_tab_add_ineq(tab, bound->el) < 0)
9159                         goto error;
9160                 empty = tab->empty;
9161                 isl_int_set_si(bound->el[1 + first + i], 0);
9162                 if (isl_tab_rollback(tab, snap) < 0)
9163                         goto error;
9164
9165                 if (empty) {
9166                         signs[i] = 1;
9167                         continue;
9168                 }
9169
9170                 isl_int_set_si(bound->el[1 + first + i], 1);
9171                 if (isl_tab_add_ineq(tab, bound->el) < 0)
9172                         goto error;
9173                 empty = tab->empty;
9174                 isl_int_set_si(bound->el[1 + first + i], 0);
9175                 if (isl_tab_rollback(tab, snap) < 0)
9176                         goto error;
9177
9178                 signs[i] = empty ? -1 : 0;
9179         }
9180
9181         isl_tab_free(tab);
9182         isl_vec_free(bound);
9183         return 0;
9184 error:
9185         isl_tab_free(tab);
9186         isl_vec_free(bound);
9187         return -1;
9188 }
9189
9190 int isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset,
9191         enum isl_dim_type type, unsigned first, unsigned n, int *signs)
9192 {
9193         if (!bset || !signs)
9194                 return -1;
9195         isl_assert(bset->ctx, first + n <= isl_basic_set_dim(bset, type),
9196                 return -1);
9197
9198         first += pos(bset->dim, type) - 1;
9199         return isl_basic_set_vars_get_sign(bset, first, n, signs);
9200 }
9201
9202 /* Check if the given basic map is obviously single-valued.
9203  * In particular, for each output dimension, check that there is
9204  * an equality that defines the output dimension in terms of
9205  * earlier dimensions.
9206  */
9207 int isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
9208 {
9209         int i, j;
9210         unsigned total;
9211         unsigned n_out;
9212         unsigned o_out;
9213
9214         if (!bmap)
9215                 return -1;
9216
9217         total = 1 + isl_basic_map_total_dim(bmap);
9218         n_out = isl_basic_map_dim(bmap, isl_dim_out);
9219         o_out = isl_basic_map_offset(bmap, isl_dim_out);
9220
9221         for (i = 0; i < n_out; ++i) {
9222                 for (j = 0; j < bmap->n_eq; ++j) {
9223                         if (isl_int_is_zero(bmap->eq[j][o_out + i]))
9224                                 continue;
9225                         if (isl_seq_first_non_zero(bmap->eq[j] + o_out + i + 1,
9226                                                 total - (o_out + i + 1)) == -1)
9227                                 break;
9228                 }
9229                 if (j >= bmap->n_eq)
9230                         return 0;
9231         }
9232
9233         return 1;
9234 }
9235
9236 /* Check if the given basic map is single-valued.
9237  * We simply compute
9238  *
9239  *      M \circ M^-1
9240  *
9241  * and check if the result is a subset of the identity mapping.
9242  */
9243 int isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
9244 {
9245         isl_space *space;
9246         isl_basic_map *test;
9247         isl_basic_map *id;
9248         int sv;
9249
9250         sv = isl_basic_map_plain_is_single_valued(bmap);
9251         if (sv < 0 || sv)
9252                 return sv;
9253
9254         test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
9255         test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
9256
9257         space = isl_basic_map_get_space(bmap);
9258         space = isl_space_map_from_set(isl_space_range(space));
9259         id = isl_basic_map_identity(space);
9260
9261         sv = isl_basic_map_is_subset(test, id);
9262
9263         isl_basic_map_free(test);
9264         isl_basic_map_free(id);
9265
9266         return sv;
9267 }
9268
9269 /* Check if the given map is obviously single-valued.
9270  */
9271 int isl_map_plain_is_single_valued(__isl_keep isl_map *map)
9272 {
9273         if (!map)
9274                 return -1;
9275         if (map->n == 0)
9276                 return 1;
9277         if (map->n >= 2)
9278                 return 0;
9279
9280         return isl_basic_map_plain_is_single_valued(map->p[0]);
9281 }
9282
9283 /* Check if the given map is single-valued.
9284  * We simply compute
9285  *
9286  *      M \circ M^-1
9287  *
9288  * and check if the result is a subset of the identity mapping.
9289  */
9290 int isl_map_is_single_valued(__isl_keep isl_map *map)
9291 {
9292         isl_space *dim;
9293         isl_map *test;
9294         isl_map *id;
9295         int sv;
9296
9297         sv = isl_map_plain_is_single_valued(map);
9298         if (sv < 0 || sv)
9299                 return sv;
9300
9301         test = isl_map_reverse(isl_map_copy(map));
9302         test = isl_map_apply_range(test, isl_map_copy(map));
9303
9304         dim = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
9305         id = isl_map_identity(dim);
9306
9307         sv = isl_map_is_subset(test, id);
9308
9309         isl_map_free(test);
9310         isl_map_free(id);
9311
9312         return sv;
9313 }
9314
9315 int isl_map_is_injective(__isl_keep isl_map *map)
9316 {
9317         int in;
9318
9319         map = isl_map_copy(map);
9320         map = isl_map_reverse(map);
9321         in = isl_map_is_single_valued(map);
9322         isl_map_free(map);
9323
9324         return in;
9325 }
9326
9327 /* Check if the given map is obviously injective.
9328  */
9329 int isl_map_plain_is_injective(__isl_keep isl_map *map)
9330 {
9331         int in;
9332
9333         map = isl_map_copy(map);
9334         map = isl_map_reverse(map);
9335         in = isl_map_plain_is_single_valued(map);
9336         isl_map_free(map);
9337
9338         return in;
9339 }
9340
9341 int isl_map_is_bijective(__isl_keep isl_map *map)
9342 {
9343         int sv;
9344
9345         sv = isl_map_is_single_valued(map);
9346         if (sv < 0 || !sv)
9347                 return sv;
9348
9349         return isl_map_is_injective(map);
9350 }
9351
9352 int isl_set_is_singleton(__isl_keep isl_set *set)
9353 {
9354         return isl_map_is_single_valued((isl_map *)set);
9355 }
9356
9357 int isl_map_is_translation(__isl_keep isl_map *map)
9358 {
9359         int ok;
9360         isl_set *delta;
9361
9362         delta = isl_map_deltas(isl_map_copy(map));
9363         ok = isl_set_is_singleton(delta);
9364         isl_set_free(delta);
9365
9366         return ok;
9367 }
9368
9369 static int unique(isl_int *p, unsigned pos, unsigned len)
9370 {
9371         if (isl_seq_first_non_zero(p, pos) != -1)
9372                 return 0;
9373         if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
9374                 return 0;
9375         return 1;
9376 }
9377
9378 int isl_basic_set_is_box(__isl_keep isl_basic_set *bset)
9379 {
9380         int i, j;
9381         unsigned nvar;
9382         unsigned ovar;
9383
9384         if (!bset)
9385                 return -1;
9386
9387         if (isl_basic_set_dim(bset, isl_dim_div) != 0)
9388                 return 0;
9389
9390         nvar = isl_basic_set_dim(bset, isl_dim_set);
9391         ovar = isl_space_offset(bset->dim, isl_dim_set);
9392         for (j = 0; j < nvar; ++j) {
9393                 int lower = 0, upper = 0;
9394                 for (i = 0; i < bset->n_eq; ++i) {
9395                         if (isl_int_is_zero(bset->eq[i][1 + ovar + j]))
9396                                 continue;
9397                         if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
9398                                 return 0;
9399                         break;
9400                 }
9401                 if (i < bset->n_eq)
9402                         continue;
9403                 for (i = 0; i < bset->n_ineq; ++i) {
9404                         if (isl_int_is_zero(bset->ineq[i][1 + ovar + j]))
9405                                 continue;
9406                         if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
9407                                 return 0;
9408                         if (isl_int_is_pos(bset->ineq[i][1 + ovar + j]))
9409                                 lower = 1;
9410                         else
9411                                 upper = 1;
9412                 }
9413                 if (!lower || !upper)
9414                         return 0;
9415         }
9416
9417         return 1;
9418 }
9419
9420 int isl_set_is_box(__isl_keep isl_set *set)
9421 {
9422         if (!set)
9423                 return -1;
9424         if (set->n != 1)
9425                 return 0;
9426
9427         return isl_basic_set_is_box(set->p[0]);
9428 }
9429
9430 int isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset)
9431 {
9432         if (!bset)
9433                 return -1;
9434         
9435         return isl_space_is_wrapping(bset->dim);
9436 }
9437
9438 int isl_set_is_wrapping(__isl_keep isl_set *set)
9439 {
9440         if (!set)
9441                 return -1;
9442         
9443         return isl_space_is_wrapping(set->dim);
9444 }
9445
9446 __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
9447 {
9448         bmap = isl_basic_map_cow(bmap);
9449         if (!bmap)
9450                 return NULL;
9451
9452         bmap->dim = isl_space_wrap(bmap->dim);
9453         if (!bmap->dim)
9454                 goto error;
9455
9456         bmap = isl_basic_map_finalize(bmap);
9457
9458         return (isl_basic_set *)bmap;
9459 error:
9460         isl_basic_map_free(bmap);
9461         return NULL;
9462 }
9463
9464 __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map)
9465 {
9466         int i;
9467
9468         map = isl_map_cow(map);
9469         if (!map)
9470                 return NULL;
9471
9472         for (i = 0; i < map->n; ++i) {
9473                 map->p[i] = (isl_basic_map *)isl_basic_map_wrap(map->p[i]);
9474                 if (!map->p[i])
9475                         goto error;
9476         }
9477         map->dim = isl_space_wrap(map->dim);
9478         if (!map->dim)
9479                 goto error;
9480
9481         return (isl_set *)map;
9482 error:
9483         isl_map_free(map);
9484         return NULL;
9485 }
9486
9487 __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset)
9488 {
9489         bset = isl_basic_set_cow(bset);
9490         if (!bset)
9491                 return NULL;
9492
9493         bset->dim = isl_space_unwrap(bset->dim);
9494         if (!bset->dim)
9495                 goto error;
9496
9497         bset = isl_basic_set_finalize(bset);
9498
9499         return (isl_basic_map *)bset;
9500 error:
9501         isl_basic_set_free(bset);
9502         return NULL;
9503 }
9504
9505 __isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set)
9506 {
9507         int i;
9508
9509         if (!set)
9510                 return NULL;
9511
9512         if (!isl_set_is_wrapping(set))
9513                 isl_die(set->ctx, isl_error_invalid, "not a wrapping set",
9514                         goto error);
9515
9516         set = isl_set_cow(set);
9517         if (!set)
9518                 return NULL;
9519
9520         for (i = 0; i < set->n; ++i) {
9521                 set->p[i] = (isl_basic_set *)isl_basic_set_unwrap(set->p[i]);
9522                 if (!set->p[i])
9523                         goto error;
9524         }
9525
9526         set->dim = isl_space_unwrap(set->dim);
9527         if (!set->dim)
9528                 goto error;
9529
9530         return (isl_map *)set;
9531 error:
9532         isl_set_free(set);
9533         return NULL;
9534 }
9535
9536 __isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
9537         enum isl_dim_type type)
9538 {
9539         if (!bmap)
9540                 return NULL;
9541
9542         if (!isl_space_is_named_or_nested(bmap->dim, type))
9543                 return bmap;
9544
9545         bmap = isl_basic_map_cow(bmap);
9546         if (!bmap)
9547                 return NULL;
9548
9549         bmap->dim = isl_space_reset(bmap->dim, type);
9550         if (!bmap->dim)
9551                 goto error;
9552
9553         bmap = isl_basic_map_finalize(bmap);
9554
9555         return bmap;
9556 error:
9557         isl_basic_map_free(bmap);
9558         return NULL;
9559 }
9560
9561 __isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
9562         enum isl_dim_type type)
9563 {
9564         int i;
9565
9566         if (!map)
9567                 return NULL;
9568
9569         if (!isl_space_is_named_or_nested(map->dim, type))
9570                 return map;
9571
9572         map = isl_map_cow(map);
9573         if (!map)
9574                 return NULL;
9575
9576         for (i = 0; i < map->n; ++i) {
9577                 map->p[i] = isl_basic_map_reset(map->p[i], type);
9578                 if (!map->p[i])
9579                         goto error;
9580         }
9581         map->dim = isl_space_reset(map->dim, type);
9582         if (!map->dim)
9583                 goto error;
9584
9585         return map;
9586 error:
9587         isl_map_free(map);
9588         return NULL;
9589 }
9590
9591 __isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
9592 {
9593         if (!bmap)
9594                 return NULL;
9595
9596         if (!bmap->dim->nested[0] && !bmap->dim->nested[1])
9597                 return bmap;
9598
9599         bmap = isl_basic_map_cow(bmap);
9600         if (!bmap)
9601                 return NULL;
9602
9603         bmap->dim = isl_space_flatten(bmap->dim);
9604         if (!bmap->dim)
9605                 goto error;
9606
9607         bmap = isl_basic_map_finalize(bmap);
9608
9609         return bmap;
9610 error:
9611         isl_basic_map_free(bmap);
9612         return NULL;
9613 }
9614
9615 __isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset)
9616 {
9617         return (isl_basic_set *)isl_basic_map_flatten((isl_basic_map *)bset);
9618 }
9619
9620 __isl_give isl_basic_map *isl_basic_map_flatten_domain(
9621         __isl_take isl_basic_map *bmap)
9622 {
9623         if (!bmap)
9624                 return NULL;
9625
9626         if (!bmap->dim->nested[0])
9627                 return bmap;
9628
9629         bmap = isl_basic_map_cow(bmap);
9630         if (!bmap)
9631                 return NULL;
9632
9633         bmap->dim = isl_space_flatten_domain(bmap->dim);
9634         if (!bmap->dim)
9635                 goto error;
9636
9637         bmap = isl_basic_map_finalize(bmap);
9638
9639         return bmap;
9640 error:
9641         isl_basic_map_free(bmap);
9642         return NULL;
9643 }
9644
9645 __isl_give isl_basic_map *isl_basic_map_flatten_range(
9646         __isl_take isl_basic_map *bmap)
9647 {
9648         if (!bmap)
9649                 return NULL;
9650
9651         if (!bmap->dim->nested[1])
9652                 return bmap;
9653
9654         bmap = isl_basic_map_cow(bmap);
9655         if (!bmap)
9656                 return NULL;
9657
9658         bmap->dim = isl_space_flatten_range(bmap->dim);
9659         if (!bmap->dim)
9660                 goto error;
9661
9662         bmap = isl_basic_map_finalize(bmap);
9663
9664         return bmap;
9665 error:
9666         isl_basic_map_free(bmap);
9667         return NULL;
9668 }
9669
9670 __isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
9671 {
9672         int i;
9673
9674         if (!map)
9675                 return NULL;
9676
9677         if (!map->dim->nested[0] && !map->dim->nested[1])
9678                 return map;
9679
9680         map = isl_map_cow(map);
9681         if (!map)
9682                 return NULL;
9683
9684         for (i = 0; i < map->n; ++i) {
9685                 map->p[i] = isl_basic_map_flatten(map->p[i]);
9686                 if (!map->p[i])
9687                         goto error;
9688         }
9689         map->dim = isl_space_flatten(map->dim);
9690         if (!map->dim)
9691                 goto error;
9692
9693         return map;
9694 error:
9695         isl_map_free(map);
9696         return NULL;
9697 }
9698
9699 __isl_give isl_set *isl_set_flatten(__isl_take isl_set *set)
9700 {
9701         return (isl_set *)isl_map_flatten((isl_map *)set);
9702 }
9703
9704 __isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set)
9705 {
9706         isl_space *dim, *flat_dim;
9707         isl_map *map;
9708
9709         dim = isl_set_get_space(set);
9710         flat_dim = isl_space_flatten(isl_space_copy(dim));
9711         map = isl_map_identity(isl_space_join(isl_space_reverse(dim), flat_dim));
9712         map = isl_map_intersect_domain(map, set);
9713
9714         return map;
9715 }
9716
9717 __isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
9718 {
9719         int i;
9720
9721         if (!map)
9722                 return NULL;
9723
9724         if (!map->dim->nested[0])
9725                 return map;
9726
9727         map = isl_map_cow(map);
9728         if (!map)
9729                 return NULL;
9730
9731         for (i = 0; i < map->n; ++i) {
9732                 map->p[i] = isl_basic_map_flatten_domain(map->p[i]);
9733                 if (!map->p[i])
9734                         goto error;
9735         }
9736         map->dim = isl_space_flatten_domain(map->dim);
9737         if (!map->dim)
9738                 goto error;
9739
9740         return map;
9741 error:
9742         isl_map_free(map);
9743         return NULL;
9744 }
9745
9746 __isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
9747 {
9748         int i;
9749
9750         if (!map)
9751                 return NULL;
9752
9753         if (!map->dim->nested[1])
9754                 return map;
9755
9756         map = isl_map_cow(map);
9757         if (!map)
9758                 return NULL;
9759
9760         for (i = 0; i < map->n; ++i) {
9761                 map->p[i] = isl_basic_map_flatten_range(map->p[i]);
9762                 if (!map->p[i])
9763                         goto error;
9764         }
9765         map->dim = isl_space_flatten_range(map->dim);
9766         if (!map->dim)
9767                 goto error;
9768
9769         return map;
9770 error:
9771         isl_map_free(map);
9772         return NULL;
9773 }
9774
9775 /* Reorder the dimensions of "bmap" according to the given dim_map
9776  * and set the dimension specification to "dim".
9777  */
9778 __isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
9779         __isl_take isl_space *dim, __isl_take struct isl_dim_map *dim_map)
9780 {
9781         isl_basic_map *res;
9782         unsigned flags;
9783
9784         bmap = isl_basic_map_cow(bmap);
9785         if (!bmap || !dim || !dim_map)
9786                 goto error;
9787
9788         flags = bmap->flags;
9789         ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL);
9790         ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED);
9791         ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS);
9792         res = isl_basic_map_alloc_space(dim,
9793                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
9794         res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
9795         if (res)
9796                 res->flags = flags;
9797         res = isl_basic_map_finalize(res);
9798         return res;
9799 error:
9800         free(dim_map);
9801         isl_basic_map_free(bmap);
9802         isl_space_free(dim);
9803         return NULL;
9804 }
9805
9806 /* Reorder the dimensions of "map" according to given reordering.
9807  */
9808 __isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
9809         __isl_take isl_reordering *r)
9810 {
9811         int i;
9812         struct isl_dim_map *dim_map;
9813
9814         map = isl_map_cow(map);
9815         dim_map = isl_dim_map_from_reordering(r);
9816         if (!map || !r || !dim_map)
9817                 goto error;
9818
9819         for (i = 0; i < map->n; ++i) {
9820                 struct isl_dim_map *dim_map_i;
9821
9822                 dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
9823
9824                 map->p[i] = isl_basic_map_realign(map->p[i],
9825                                             isl_space_copy(r->dim), dim_map_i);
9826
9827                 if (!map->p[i])
9828                         goto error;
9829         }
9830
9831         map = isl_map_reset_space(map, isl_space_copy(r->dim));
9832
9833         isl_reordering_free(r);
9834         free(dim_map);
9835         return map;
9836 error:
9837         free(dim_map);
9838         isl_map_free(map);
9839         isl_reordering_free(r);
9840         return NULL;
9841 }
9842
9843 __isl_give isl_set *isl_set_realign(__isl_take isl_set *set,
9844         __isl_take isl_reordering *r)
9845 {
9846         return (isl_set *)isl_map_realign((isl_map *)set, r);
9847 }
9848
9849 __isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
9850         __isl_take isl_space *model)
9851 {
9852         isl_ctx *ctx;
9853
9854         if (!map || !model)
9855                 goto error;
9856
9857         ctx = isl_space_get_ctx(model);
9858         if (!isl_space_has_named_params(model))
9859                 isl_die(ctx, isl_error_invalid,
9860                         "model has unnamed parameters", goto error);
9861         if (!isl_space_has_named_params(map->dim))
9862                 isl_die(ctx, isl_error_invalid,
9863                         "relation has unnamed parameters", goto error);
9864         if (!isl_space_match(map->dim, isl_dim_param, model, isl_dim_param)) {
9865                 isl_reordering *exp;
9866
9867                 model = isl_space_drop_dims(model, isl_dim_in,
9868                                         0, isl_space_dim(model, isl_dim_in));
9869                 model = isl_space_drop_dims(model, isl_dim_out,
9870                                         0, isl_space_dim(model, isl_dim_out));
9871                 exp = isl_parameter_alignment_reordering(map->dim, model);
9872                 exp = isl_reordering_extend_space(exp, isl_map_get_space(map));
9873                 map = isl_map_realign(map, exp);
9874         }
9875
9876         isl_space_free(model);
9877         return map;
9878 error:
9879         isl_space_free(model);
9880         isl_map_free(map);
9881         return NULL;
9882 }
9883
9884 __isl_give isl_set *isl_set_align_params(__isl_take isl_set *set,
9885         __isl_take isl_space *model)
9886 {
9887         return isl_map_align_params(set, model);
9888 }
9889
9890 /* Align the parameters of "bmap" to those of "model", introducing
9891  * additional parameters if needed.
9892  */
9893 __isl_give isl_basic_map *isl_basic_map_align_params(
9894         __isl_take isl_basic_map *bmap, __isl_take isl_space *model)
9895 {
9896         isl_ctx *ctx;
9897
9898         if (!bmap || !model)
9899                 goto error;
9900
9901         ctx = isl_space_get_ctx(model);
9902         if (!isl_space_has_named_params(model))
9903                 isl_die(ctx, isl_error_invalid,
9904                         "model has unnamed parameters", goto error);
9905         if (!isl_space_has_named_params(bmap->dim))
9906                 isl_die(ctx, isl_error_invalid,
9907                         "relation has unnamed parameters", goto error);
9908         if (!isl_space_match(bmap->dim, isl_dim_param, model, isl_dim_param)) {
9909                 isl_reordering *exp;
9910                 struct isl_dim_map *dim_map;
9911
9912                 model = isl_space_drop_dims(model, isl_dim_in,
9913                                         0, isl_space_dim(model, isl_dim_in));
9914                 model = isl_space_drop_dims(model, isl_dim_out,
9915                                         0, isl_space_dim(model, isl_dim_out));
9916                 exp = isl_parameter_alignment_reordering(bmap->dim, model);
9917                 exp = isl_reordering_extend_space(exp,
9918                                         isl_basic_map_get_space(bmap));
9919                 dim_map = isl_dim_map_from_reordering(exp);
9920                 bmap = isl_basic_map_realign(bmap,
9921                                     exp ? isl_space_copy(exp->dim) : NULL,
9922                                     isl_dim_map_extend(dim_map, bmap));
9923                 isl_reordering_free(exp);
9924                 free(dim_map);
9925         }
9926
9927         isl_space_free(model);
9928         return bmap;
9929 error:
9930         isl_space_free(model);
9931         isl_basic_map_free(bmap);
9932         return NULL;
9933 }
9934
9935 /* Align the parameters of "bset" to those of "model", introducing
9936  * additional parameters if needed.
9937  */
9938 __isl_give isl_basic_set *isl_basic_set_align_params(
9939         __isl_take isl_basic_set *bset, __isl_take isl_space *model)
9940 {
9941         return isl_basic_map_align_params(bset, model);
9942 }
9943
9944 __isl_give isl_mat *isl_basic_map_equalities_matrix(
9945                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
9946                 enum isl_dim_type c2, enum isl_dim_type c3,
9947                 enum isl_dim_type c4, enum isl_dim_type c5)
9948 {
9949         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
9950         struct isl_mat *mat;
9951         int i, j, k;
9952         int pos;
9953
9954         if (!bmap)
9955                 return NULL;
9956         mat = isl_mat_alloc(bmap->ctx, bmap->n_eq,
9957                                 isl_basic_map_total_dim(bmap) + 1);
9958         if (!mat)
9959                 return NULL;
9960         for (i = 0; i < bmap->n_eq; ++i)
9961                 for (j = 0, pos = 0; j < 5; ++j) {
9962                         int off = isl_basic_map_offset(bmap, c[j]);
9963                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9964                                 isl_int_set(mat->row[i][pos],
9965                                             bmap->eq[i][off + k]);
9966                                 ++pos;
9967                         }
9968                 }
9969
9970         return mat;
9971 }
9972
9973 __isl_give isl_mat *isl_basic_map_inequalities_matrix(
9974                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
9975                 enum isl_dim_type c2, enum isl_dim_type c3,
9976                 enum isl_dim_type c4, enum isl_dim_type c5)
9977 {
9978         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
9979         struct isl_mat *mat;
9980         int i, j, k;
9981         int pos;
9982
9983         if (!bmap)
9984                 return NULL;
9985         mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq,
9986                                 isl_basic_map_total_dim(bmap) + 1);
9987         if (!mat)
9988                 return NULL;
9989         for (i = 0; i < bmap->n_ineq; ++i)
9990                 for (j = 0, pos = 0; j < 5; ++j) {
9991                         int off = isl_basic_map_offset(bmap, c[j]);
9992                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9993                                 isl_int_set(mat->row[i][pos],
9994                                             bmap->ineq[i][off + k]);
9995                                 ++pos;
9996                         }
9997                 }
9998
9999         return mat;
10000 }
10001
10002 __isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
10003         __isl_take isl_space *dim,
10004         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
10005         enum isl_dim_type c2, enum isl_dim_type c3,
10006         enum isl_dim_type c4, enum isl_dim_type c5)
10007 {
10008         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
10009         isl_basic_map *bmap;
10010         unsigned total;
10011         unsigned extra;
10012         int i, j, k, l;
10013         int pos;
10014
10015         if (!dim || !eq || !ineq)
10016                 goto error;
10017
10018         if (eq->n_col != ineq->n_col)
10019                 isl_die(dim->ctx, isl_error_invalid,
10020                         "equalities and inequalities matrices should have "
10021                         "same number of columns", goto error);
10022
10023         total = 1 + isl_space_dim(dim, isl_dim_all);
10024
10025         if (eq->n_col < total)
10026                 isl_die(dim->ctx, isl_error_invalid,
10027                         "number of columns too small", goto error);
10028
10029         extra = eq->n_col - total;
10030
10031         bmap = isl_basic_map_alloc_space(isl_space_copy(dim), extra,
10032                                        eq->n_row, ineq->n_row);
10033         if (!bmap)
10034                 goto error;
10035         for (i = 0; i < extra; ++i) {
10036                 k = isl_basic_map_alloc_div(bmap);
10037                 if (k < 0)
10038                         goto error;
10039                 isl_int_set_si(bmap->div[k][0], 0);
10040         }
10041         for (i = 0; i < eq->n_row; ++i) {
10042                 l = isl_basic_map_alloc_equality(bmap);
10043                 if (l < 0)
10044                         goto error;
10045                 for (j = 0, pos = 0; j < 5; ++j) {
10046                         int off = isl_basic_map_offset(bmap, c[j]);
10047                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
10048                                 isl_int_set(bmap->eq[l][off + k], 
10049                                             eq->row[i][pos]);
10050                                 ++pos;
10051                         }
10052                 }
10053         }
10054         for (i = 0; i < ineq->n_row; ++i) {
10055                 l = isl_basic_map_alloc_inequality(bmap);
10056                 if (l < 0)
10057                         goto error;
10058                 for (j = 0, pos = 0; j < 5; ++j) {
10059                         int off = isl_basic_map_offset(bmap, c[j]);
10060                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
10061                                 isl_int_set(bmap->ineq[l][off + k], 
10062                                             ineq->row[i][pos]);
10063                                 ++pos;
10064                         }
10065                 }
10066         }
10067
10068         isl_space_free(dim);
10069         isl_mat_free(eq);
10070         isl_mat_free(ineq);
10071
10072         return bmap;
10073 error:
10074         isl_space_free(dim);
10075         isl_mat_free(eq);
10076         isl_mat_free(ineq);
10077         return NULL;
10078 }
10079
10080 __isl_give isl_mat *isl_basic_set_equalities_matrix(
10081         __isl_keep isl_basic_set *bset, enum isl_dim_type c1,
10082         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
10083 {
10084         return isl_basic_map_equalities_matrix((isl_basic_map *)bset,
10085                                                 c1, c2, c3, c4, isl_dim_in);
10086 }
10087
10088 __isl_give isl_mat *isl_basic_set_inequalities_matrix(
10089         __isl_keep isl_basic_set *bset, enum isl_dim_type c1,
10090         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
10091 {
10092         return isl_basic_map_inequalities_matrix((isl_basic_map *)bset,
10093                                                  c1, c2, c3, c4, isl_dim_in);
10094 }
10095
10096 __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices(
10097         __isl_take isl_space *dim,
10098         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
10099         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
10100 {
10101         return (isl_basic_set*)
10102             isl_basic_map_from_constraint_matrices(dim, eq, ineq,
10103                                                    c1, c2, c3, c4, isl_dim_in);
10104 }
10105
10106 int isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
10107 {
10108         if (!bmap)
10109                 return -1;
10110         
10111         return isl_space_can_zip(bmap->dim);
10112 }
10113
10114 int isl_map_can_zip(__isl_keep isl_map *map)
10115 {
10116         if (!map)
10117                 return -1;
10118         
10119         return isl_space_can_zip(map->dim);
10120 }
10121
10122 /* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
10123  * (A -> C) -> (B -> D).
10124  */
10125 __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
10126 {
10127         unsigned pos;
10128         unsigned n1;
10129         unsigned n2;
10130
10131         if (!bmap)
10132                 return NULL;
10133
10134         if (!isl_basic_map_can_zip(bmap))
10135                 isl_die(bmap->ctx, isl_error_invalid,
10136                         "basic map cannot be zipped", goto error);
10137         pos = isl_basic_map_offset(bmap, isl_dim_in) +
10138                 isl_space_dim(bmap->dim->nested[0], isl_dim_in);
10139         n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
10140         n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
10141         bmap = isl_basic_map_cow(bmap);
10142         bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
10143         if (!bmap)
10144                 return NULL;
10145         bmap->dim = isl_space_zip(bmap->dim);
10146         if (!bmap->dim)
10147                 goto error;
10148         return bmap;
10149 error:
10150         isl_basic_map_free(bmap);
10151         return NULL;
10152 }
10153
10154 /* Given a map (A -> B) -> (C -> D), return the corresponding map
10155  * (A -> C) -> (B -> D).
10156  */
10157 __isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
10158 {
10159         int i;
10160
10161         if (!map)
10162                 return NULL;
10163
10164         if (!isl_map_can_zip(map))
10165                 isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",
10166                         goto error);
10167
10168         map = isl_map_cow(map);
10169         if (!map)
10170                 return NULL;
10171
10172         for (i = 0; i < map->n; ++i) {
10173                 map->p[i] = isl_basic_map_zip(map->p[i]);
10174                 if (!map->p[i])
10175                         goto error;
10176         }
10177
10178         map->dim = isl_space_zip(map->dim);
10179         if (!map->dim)
10180                 goto error;
10181
10182         return map;
10183 error:
10184         isl_map_free(map);
10185         return NULL;
10186 }
10187
10188 /* Can we apply isl_basic_map_curry to "bmap"?
10189  * That is, does it have a nested relation in its domain?
10190  */
10191 int isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
10192 {
10193         if (!bmap)
10194                 return -1;
10195
10196         return isl_space_can_curry(bmap->dim);
10197 }
10198
10199 /* Can we apply isl_map_curry to "map"?
10200  * That is, does it have a nested relation in its domain?
10201  */
10202 int isl_map_can_curry(__isl_keep isl_map *map)
10203 {
10204         if (!map)
10205                 return -1;
10206
10207         return isl_space_can_curry(map->dim);
10208 }
10209
10210 /* Given a basic map (A -> B) -> C, return the corresponding basic map
10211  * A -> (B -> C).
10212  */
10213 __isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
10214 {
10215
10216         if (!bmap)
10217                 return NULL;
10218
10219         if (!isl_basic_map_can_curry(bmap))
10220                 isl_die(bmap->ctx, isl_error_invalid,
10221                         "basic map cannot be curried", goto error);
10222         bmap->dim = isl_space_curry(bmap->dim);
10223         if (!bmap->dim)
10224                 goto error;
10225         return bmap;
10226 error:
10227         isl_basic_map_free(bmap);
10228         return NULL;
10229 }
10230
10231 /* Given a map (A -> B) -> C, return the corresponding map
10232  * A -> (B -> C).
10233  */
10234 __isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
10235 {
10236         int i;
10237
10238         if (!map)
10239                 return NULL;
10240
10241         if (!isl_map_can_curry(map))
10242                 isl_die(map->ctx, isl_error_invalid, "map cannot be curried",
10243                         goto error);
10244
10245         map = isl_map_cow(map);
10246         if (!map)
10247                 return NULL;
10248
10249         for (i = 0; i < map->n; ++i) {
10250                 map->p[i] = isl_basic_map_curry(map->p[i]);
10251                 if (!map->p[i])
10252                         goto error;
10253         }
10254
10255         map->dim = isl_space_curry(map->dim);
10256         if (!map->dim)
10257                 goto error;
10258
10259         return map;
10260 error:
10261         isl_map_free(map);
10262         return NULL;
10263 }
10264
10265 /* Can we apply isl_basic_map_uncurry to "bmap"?
10266  * That is, does it have a nested relation in its domain?
10267  */
10268 int isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
10269 {
10270         if (!bmap)
10271                 return -1;
10272
10273         return isl_space_can_uncurry(bmap->dim);
10274 }
10275
10276 /* Can we apply isl_map_uncurry to "map"?
10277  * That is, does it have a nested relation in its domain?
10278  */
10279 int isl_map_can_uncurry(__isl_keep isl_map *map)
10280 {
10281         if (!map)
10282                 return -1;
10283
10284         return isl_space_can_uncurry(map->dim);
10285 }
10286
10287 /* Given a basic map A -> (B -> C), return the corresponding basic map
10288  * (A -> B) -> C.
10289  */
10290 __isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
10291 {
10292
10293         if (!bmap)
10294                 return NULL;
10295
10296         if (!isl_basic_map_can_uncurry(bmap))
10297                 isl_die(bmap->ctx, isl_error_invalid,
10298                         "basic map cannot be uncurried",
10299                         return isl_basic_map_free(bmap));
10300         bmap->dim = isl_space_uncurry(bmap->dim);
10301         if (!bmap->dim)
10302                 return isl_basic_map_free(bmap);
10303         return bmap;
10304 }
10305
10306 /* Given a map A -> (B -> C), return the corresponding map
10307  * (A -> B) -> C.
10308  */
10309 __isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
10310 {
10311         int i;
10312
10313         if (!map)
10314                 return NULL;
10315
10316         if (!isl_map_can_uncurry(map))
10317                 isl_die(map->ctx, isl_error_invalid, "map cannot be uncurried",
10318                         return isl_map_free(map));
10319
10320         map = isl_map_cow(map);
10321         if (!map)
10322                 return NULL;
10323
10324         for (i = 0; i < map->n; ++i) {
10325                 map->p[i] = isl_basic_map_uncurry(map->p[i]);
10326                 if (!map->p[i])
10327                         return isl_map_free(map);
10328         }
10329
10330         map->dim = isl_space_uncurry(map->dim);
10331         if (!map->dim)
10332                 return isl_map_free(map);
10333
10334         return map;
10335 }
10336
10337 /* Construct a basic map mapping the domain of the affine expression
10338  * to a one-dimensional range prescribed by the affine expression.
10339  */
10340 __isl_give isl_basic_map *isl_basic_map_from_aff(__isl_take isl_aff *aff)
10341 {
10342         int k;
10343         int pos;
10344         isl_local_space *ls;
10345         isl_basic_map *bmap;
10346
10347         if (!aff)
10348                 return NULL;
10349
10350         ls = isl_aff_get_local_space(aff);
10351         bmap = isl_basic_map_from_local_space(ls);
10352         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
10353         k = isl_basic_map_alloc_equality(bmap);
10354         if (k < 0)
10355                 goto error;
10356
10357         pos = isl_basic_map_offset(bmap, isl_dim_out);
10358         isl_seq_cpy(bmap->eq[k], aff->v->el + 1, pos);
10359         isl_int_neg(bmap->eq[k][pos], aff->v->el[0]);
10360         isl_seq_cpy(bmap->eq[k] + pos + 1, aff->v->el + 1 + pos,
10361                     aff->v->size - (pos + 1));
10362
10363         isl_aff_free(aff);
10364         bmap = isl_basic_map_finalize(bmap);
10365         return bmap;
10366 error:
10367         isl_aff_free(aff);
10368         isl_basic_map_free(bmap);
10369         return NULL;
10370 }
10371
10372 /* Construct a map mapping the domain of the affine expression
10373  * to a one-dimensional range prescribed by the affine expression.
10374  */
10375 __isl_give isl_map *isl_map_from_aff(__isl_take isl_aff *aff)
10376 {
10377         isl_basic_map *bmap;
10378
10379         bmap = isl_basic_map_from_aff(aff);
10380         return isl_map_from_basic_map(bmap);
10381 }
10382
10383 /* Construct a basic map mapping the domain the multi-affine expression
10384  * to its range, with each dimension in the range equated to the
10385  * corresponding affine expression.
10386  */
10387 __isl_give isl_basic_map *isl_basic_map_from_multi_aff(
10388         __isl_take isl_multi_aff *maff)
10389 {
10390         int i;
10391         isl_space *space;
10392         isl_basic_map *bmap;
10393
10394         if (!maff)
10395                 return NULL;
10396
10397         if (isl_space_dim(maff->space, isl_dim_out) != maff->n)
10398                 isl_die(isl_multi_aff_get_ctx(maff), isl_error_internal,
10399                         "invalid space", return isl_multi_aff_free(maff));
10400
10401         space = isl_space_domain(isl_multi_aff_get_space(maff));
10402         bmap = isl_basic_map_universe(isl_space_from_domain(space));
10403
10404         for (i = 0; i < maff->n; ++i) {
10405                 isl_aff *aff;
10406                 isl_basic_map *bmap_i;
10407
10408                 aff = isl_aff_copy(maff->p[i]);
10409                 bmap_i = isl_basic_map_from_aff(aff);
10410
10411                 bmap = isl_basic_map_flat_range_product(bmap, bmap_i);
10412         }
10413
10414         bmap = isl_basic_map_reset_space(bmap, isl_multi_aff_get_space(maff));
10415
10416         isl_multi_aff_free(maff);
10417         return bmap;
10418 }
10419
10420 /* Construct a map mapping the domain the multi-affine expression
10421  * to its range, with each dimension in the range equated to the
10422  * corresponding affine expression.
10423  */
10424 __isl_give isl_map *isl_map_from_multi_aff(__isl_take isl_multi_aff *maff)
10425 {
10426         isl_basic_map *bmap;
10427
10428         bmap = isl_basic_map_from_multi_aff(maff);
10429         return isl_map_from_basic_map(bmap);
10430 }
10431
10432 /* Construct a basic map mapping a domain in the given space to
10433  * to an n-dimensional range, with n the number of elements in the list,
10434  * where each coordinate in the range is prescribed by the
10435  * corresponding affine expression.
10436  * The domains of all affine expressions in the list are assumed to match
10437  * domain_dim.
10438  */
10439 __isl_give isl_basic_map *isl_basic_map_from_aff_list(
10440         __isl_take isl_space *domain_dim, __isl_take isl_aff_list *list)
10441 {
10442         int i;
10443         isl_space *dim;
10444         isl_basic_map *bmap;
10445
10446         if (!list)
10447                 return NULL;
10448
10449         dim = isl_space_from_domain(domain_dim);
10450         bmap = isl_basic_map_universe(dim);
10451
10452         for (i = 0; i < list->n; ++i) {
10453                 isl_aff *aff;
10454                 isl_basic_map *bmap_i;
10455
10456                 aff = isl_aff_copy(list->p[i]);
10457                 bmap_i = isl_basic_map_from_aff(aff);
10458
10459                 bmap = isl_basic_map_flat_range_product(bmap, bmap_i);
10460         }
10461
10462         isl_aff_list_free(list);
10463         return bmap;
10464 }
10465
10466 __isl_give isl_set *isl_set_equate(__isl_take isl_set *set,
10467         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
10468 {
10469         return isl_map_equate(set, type1, pos1, type2, pos2);
10470 }
10471
10472 /* Construct a basic map where the given dimensions are equal to each other.
10473  */
10474 static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
10475         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
10476 {
10477         isl_basic_map *bmap = NULL;
10478         int i;
10479
10480         if (!space)
10481                 return NULL;
10482
10483         if (pos1 >= isl_space_dim(space, type1))
10484                 isl_die(isl_space_get_ctx(space), isl_error_invalid,
10485                         "index out of bounds", goto error);
10486         if (pos2 >= isl_space_dim(space, type2))
10487                 isl_die(isl_space_get_ctx(space), isl_error_invalid,
10488                         "index out of bounds", goto error);
10489
10490         if (type1 == type2 && pos1 == pos2)
10491                 return isl_basic_map_universe(space);
10492
10493         bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
10494         i = isl_basic_map_alloc_equality(bmap);
10495         if (i < 0)
10496                 goto error;
10497         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
10498         pos1 += isl_basic_map_offset(bmap, type1);
10499         pos2 += isl_basic_map_offset(bmap, type2);
10500         isl_int_set_si(bmap->eq[i][pos1], -1);
10501         isl_int_set_si(bmap->eq[i][pos2], 1);
10502         bmap = isl_basic_map_finalize(bmap);
10503         isl_space_free(space);
10504         return bmap;
10505 error:
10506         isl_space_free(space);
10507         isl_basic_map_free(bmap);
10508         return NULL;
10509 }
10510
10511 /* Add a constraint imposing that the given two dimensions are equal.
10512  */
10513 __isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
10514         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
10515 {
10516         isl_basic_map *eq;
10517
10518         eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
10519
10520         bmap = isl_basic_map_intersect(bmap, eq);
10521
10522         return bmap;
10523 }
10524
10525 /* Add a constraint imposing that the given two dimensions are equal.
10526  */
10527 __isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
10528         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
10529 {
10530         isl_basic_map *bmap;
10531
10532         bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
10533
10534         map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
10535
10536         return map;
10537 }
10538
10539 /* Add a constraint imposing that the given two dimensions have opposite values.
10540  */
10541 __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
10542         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
10543 {
10544         isl_basic_map *bmap = NULL;
10545         int i;
10546
10547         if (!map)
10548                 return NULL;
10549
10550         if (pos1 >= isl_map_dim(map, type1))
10551                 isl_die(map->ctx, isl_error_invalid,
10552                         "index out of bounds", goto error);
10553         if (pos2 >= isl_map_dim(map, type2))
10554                 isl_die(map->ctx, isl_error_invalid,
10555                         "index out of bounds", goto error);
10556
10557         bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
10558         i = isl_basic_map_alloc_equality(bmap);
10559         if (i < 0)
10560                 goto error;
10561         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
10562         pos1 += isl_basic_map_offset(bmap, type1);
10563         pos2 += isl_basic_map_offset(bmap, type2);
10564         isl_int_set_si(bmap->eq[i][pos1], 1);
10565         isl_int_set_si(bmap->eq[i][pos2], 1);
10566         bmap = isl_basic_map_finalize(bmap);
10567
10568         map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
10569
10570         return map;
10571 error:
10572         isl_basic_map_free(bmap);
10573         isl_map_free(map);
10574         return NULL;
10575 }
10576
10577 /* Add a constraint imposing that the value of the first dimension is
10578  * greater than or equal to that of the second.
10579  */
10580 __isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap,
10581         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
10582 {
10583         isl_constraint *c;
10584         isl_local_space *ls;
10585
10586         if (!bmap)
10587                 return NULL;
10588
10589         if (pos1 >= isl_basic_map_dim(bmap, type1))
10590                 isl_die(bmap->ctx, isl_error_invalid,
10591                         "index out of bounds", return isl_basic_map_free(bmap));
10592         if (pos2 >= isl_basic_map_dim(bmap, type2))
10593                 isl_die(bmap->ctx, isl_error_invalid,
10594                         "index out of bounds", return isl_basic_map_free(bmap));
10595
10596         if (type1 == type2 && pos1 == pos2)
10597                 return bmap;
10598
10599         ls = isl_local_space_from_space(isl_basic_map_get_space(bmap));
10600         c = isl_inequality_alloc(ls);
10601         c = isl_constraint_set_coefficient_si(c, type1, pos1, 1);
10602         c = isl_constraint_set_coefficient_si(c, type2, pos2, -1);
10603         bmap = isl_basic_map_add_constraint(bmap, c);
10604
10605         return bmap;
10606 }
10607
10608 /* Add a constraint imposing that the value of the first dimension is
10609  * greater than that of the second.
10610  */
10611 __isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map,
10612         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
10613 {
10614         isl_basic_map *bmap = NULL;
10615         int i;
10616
10617         if (!map)
10618                 return NULL;
10619
10620         if (pos1 >= isl_map_dim(map, type1))
10621                 isl_die(map->ctx, isl_error_invalid,
10622                         "index out of bounds", goto error);
10623         if (pos2 >= isl_map_dim(map, type2))
10624                 isl_die(map->ctx, isl_error_invalid,
10625                         "index out of bounds", goto error);
10626
10627         if (type1 == type2 && pos1 == pos2) {
10628                 isl_space *space = isl_map_get_space(map);
10629                 isl_map_free(map);
10630                 return isl_map_empty(space);
10631         }
10632
10633         bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 0, 1);
10634         i = isl_basic_map_alloc_inequality(bmap);
10635         if (i < 0)
10636                 goto error;
10637         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
10638         pos1 += isl_basic_map_offset(bmap, type1);
10639         pos2 += isl_basic_map_offset(bmap, type2);
10640         isl_int_set_si(bmap->ineq[i][pos1], 1);
10641         isl_int_set_si(bmap->ineq[i][pos2], -1);
10642         isl_int_set_si(bmap->ineq[i][0], -1);
10643         bmap = isl_basic_map_finalize(bmap);
10644
10645         map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
10646
10647         return map;
10648 error:
10649         isl_basic_map_free(bmap);
10650         isl_map_free(map);
10651         return NULL;
10652 }
10653
10654 /* Add a constraint imposing that the value of the first dimension is
10655  * smaller than that of the second.
10656  */
10657 __isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map,
10658         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
10659 {
10660         return isl_map_order_gt(map, type2, pos2, type1, pos1);
10661 }
10662
10663 __isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
10664         int pos)
10665 {
10666         isl_aff *div;
10667         isl_local_space *ls;
10668
10669         if (!bmap)
10670                 return NULL;
10671
10672         if (!isl_basic_map_divs_known(bmap))
10673                 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
10674                         "some divs are unknown", return NULL);
10675
10676         ls = isl_basic_map_get_local_space(bmap);
10677         div = isl_local_space_get_div(ls, pos);
10678         isl_local_space_free(ls);
10679
10680         return div;
10681 }
10682
10683 __isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset,
10684         int pos)
10685 {
10686         return isl_basic_map_get_div(bset, pos);
10687 }
10688
10689 /* Plug in "subs" for dimension "type", "pos" of "bset".
10690  *
10691  * Let i be the dimension to replace and let "subs" be of the form
10692  *
10693  *      f/d
10694  *
10695  * Any integer division with a non-zero coefficient for i,
10696  *
10697  *      floor((a i + g)/m)
10698  *
10699  * is replaced by
10700  *
10701  *      floor((a f + d g)/(m d))
10702  *
10703  * Constraints of the form
10704  *
10705  *      a i + g
10706  *
10707  * are replaced by
10708  *
10709  *      a f + d g
10710  */
10711 __isl_give isl_basic_set *isl_basic_set_substitute(
10712         __isl_take isl_basic_set *bset,
10713         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
10714 {
10715         int i;
10716         isl_int v;
10717         isl_ctx *ctx;
10718
10719         if (bset && isl_basic_set_plain_is_empty(bset))
10720                 return bset;
10721
10722         bset = isl_basic_set_cow(bset);
10723         if (!bset || !subs)
10724                 goto error;
10725
10726         ctx = isl_basic_set_get_ctx(bset);
10727         if (!isl_space_is_equal(bset->dim, subs->ls->dim))
10728                 isl_die(ctx, isl_error_invalid,
10729                         "spaces don't match", goto error);
10730         if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
10731                 isl_die(ctx, isl_error_unsupported,
10732                         "cannot handle divs yet", goto error);
10733
10734         pos += isl_basic_set_offset(bset, type);
10735
10736         isl_int_init(v);
10737
10738         for (i = 0; i < bset->n_eq; ++i) {
10739                 if (isl_int_is_zero(bset->eq[i][pos]))
10740                         continue;
10741                 isl_int_set(v, bset->eq[i][pos]);
10742                 isl_int_set_si(bset->eq[i][pos], 0);
10743                 isl_seq_combine(bset->eq[i], subs->v->el[0], bset->eq[i],
10744                                 v, subs->v->el + 1, subs->v->size - 1);
10745         }
10746
10747         for (i = 0; i < bset->n_ineq; ++i) {
10748                 if (isl_int_is_zero(bset->ineq[i][pos]))
10749                         continue;
10750                 isl_int_set(v, bset->ineq[i][pos]);
10751                 isl_int_set_si(bset->ineq[i][pos], 0);
10752                 isl_seq_combine(bset->ineq[i], subs->v->el[0], bset->ineq[i],
10753                                 v, subs->v->el + 1, subs->v->size - 1);
10754         }
10755
10756         for (i = 0; i < bset->n_div; ++i) {
10757                 if (isl_int_is_zero(bset->div[i][1 + pos]))
10758                         continue;
10759                 isl_int_set(v, bset->div[i][1 + pos]);
10760                 isl_int_set_si(bset->div[i][1 + pos], 0);
10761                 isl_seq_combine(bset->div[i] + 1,
10762                                 subs->v->el[0], bset->div[i] + 1,
10763                                 v, subs->v->el + 1, subs->v->size - 1);
10764                 isl_int_mul(bset->div[i][0], bset->div[i][0], subs->v->el[0]);
10765         }
10766
10767         isl_int_clear(v);
10768
10769         bset = isl_basic_set_simplify(bset);
10770         return isl_basic_set_finalize(bset);
10771 error:
10772         isl_basic_set_free(bset);
10773         return NULL;
10774 }
10775
10776 /* Plug in "subs" for dimension "type", "pos" of "set".
10777  */
10778 __isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
10779         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
10780 {
10781         int i;
10782
10783         if (set && isl_set_plain_is_empty(set))
10784                 return set;
10785
10786         set = isl_set_cow(set);
10787         if (!set || !subs)
10788                 goto error;
10789
10790         for (i = set->n - 1; i >= 0; --i) {
10791                 set->p[i] = isl_basic_set_substitute(set->p[i], type, pos, subs);
10792                 if (remove_if_empty(set, i) < 0)
10793                         goto error;
10794         }
10795
10796         return set;
10797 error:
10798         isl_set_free(set);
10799         return NULL;
10800 }