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