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