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