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