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