Merge branch 'maint'
[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_map_is_equal(
6717                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
6718 {
6719         int is_subset;
6720
6721         if (!bmap1 || !bmap2)
6722                 return -1;
6723         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
6724         if (is_subset != 1)
6725                 return is_subset;
6726         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
6727         return is_subset;
6728 }
6729
6730 int isl_basic_set_is_equal(
6731                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
6732 {
6733         return isl_basic_map_is_equal(
6734                 (struct isl_basic_map *)bset1, (struct isl_basic_map *)bset2);
6735 }
6736
6737 int isl_map_is_empty(struct isl_map *map)
6738 {
6739         int i;
6740         int is_empty;
6741
6742         if (!map)
6743                 return -1;
6744         for (i = 0; i < map->n; ++i) {
6745                 is_empty = isl_basic_map_is_empty(map->p[i]);
6746                 if (is_empty < 0)
6747                         return -1;
6748                 if (!is_empty)
6749                         return 0;
6750         }
6751         return 1;
6752 }
6753
6754 int isl_map_plain_is_empty(__isl_keep isl_map *map)
6755 {
6756         return map ? map->n == 0 : -1;
6757 }
6758
6759 int isl_map_fast_is_empty(__isl_keep isl_map *map)
6760 {
6761         return isl_map_plain_is_empty(map);
6762 }
6763
6764 int isl_set_plain_is_empty(struct isl_set *set)
6765 {
6766         return set ? set->n == 0 : -1;
6767 }
6768
6769 int isl_set_fast_is_empty(__isl_keep isl_set *set)
6770 {
6771         return isl_set_plain_is_empty(set);
6772 }
6773
6774 int isl_set_is_empty(struct isl_set *set)
6775 {
6776         return isl_map_is_empty((struct isl_map *)set);
6777 }
6778
6779 int isl_map_has_equal_space(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
6780 {
6781         if (!map1 || !map2)
6782                 return -1;
6783
6784         return isl_space_is_equal(map1->dim, map2->dim);
6785 }
6786
6787 int isl_set_has_equal_space(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
6788 {
6789         if (!set1 || !set2)
6790                 return -1;
6791
6792         return isl_space_is_equal(set1->dim, set2->dim);
6793 }
6794
6795 static int map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
6796 {
6797         int is_subset;
6798
6799         if (!map1 || !map2)
6800                 return -1;
6801         is_subset = isl_map_is_subset(map1, map2);
6802         if (is_subset != 1)
6803                 return is_subset;
6804         is_subset = isl_map_is_subset(map2, map1);
6805         return is_subset;
6806 }
6807
6808 int isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
6809 {
6810         return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
6811 }
6812
6813 int isl_basic_map_is_strict_subset(
6814                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
6815 {
6816         int is_subset;
6817
6818         if (!bmap1 || !bmap2)
6819                 return -1;
6820         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
6821         if (is_subset != 1)
6822                 return is_subset;
6823         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
6824         if (is_subset == -1)
6825                 return is_subset;
6826         return !is_subset;
6827 }
6828
6829 int isl_map_is_strict_subset(struct isl_map *map1, struct isl_map *map2)
6830 {
6831         int is_subset;
6832
6833         if (!map1 || !map2)
6834                 return -1;
6835         is_subset = isl_map_is_subset(map1, map2);
6836         if (is_subset != 1)
6837                 return is_subset;
6838         is_subset = isl_map_is_subset(map2, map1);
6839         if (is_subset == -1)
6840                 return is_subset;
6841         return !is_subset;
6842 }
6843
6844 int isl_set_is_strict_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
6845 {
6846         return isl_map_is_strict_subset((isl_map *)set1, (isl_map *)set2);
6847 }
6848
6849 int isl_basic_map_is_universe(struct isl_basic_map *bmap)
6850 {
6851         if (!bmap)
6852                 return -1;
6853         return bmap->n_eq == 0 && bmap->n_ineq == 0;
6854 }
6855
6856 int isl_basic_set_is_universe(struct isl_basic_set *bset)
6857 {
6858         if (!bset)
6859                 return -1;
6860         return bset->n_eq == 0 && bset->n_ineq == 0;
6861 }
6862
6863 int isl_map_plain_is_universe(__isl_keep isl_map *map)
6864 {
6865         int i;
6866
6867         if (!map)
6868                 return -1;
6869
6870         for (i = 0; i < map->n; ++i) {
6871                 int r = isl_basic_map_is_universe(map->p[i]);
6872                 if (r < 0 || r)
6873                         return r;
6874         }
6875
6876         return 0;
6877 }
6878
6879 int isl_set_plain_is_universe(__isl_keep isl_set *set)
6880 {
6881         return isl_map_plain_is_universe((isl_map *) set);
6882 }
6883
6884 int isl_set_fast_is_universe(__isl_keep isl_set *set)
6885 {
6886         return isl_set_plain_is_universe(set);
6887 }
6888
6889 int isl_basic_map_is_empty(struct isl_basic_map *bmap)
6890 {
6891         struct isl_basic_set *bset = NULL;
6892         struct isl_vec *sample = NULL;
6893         int empty;
6894         unsigned total;
6895
6896         if (!bmap)
6897                 return -1;
6898
6899         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
6900                 return 1;
6901
6902         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
6903                 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
6904                 copy = isl_basic_map_remove_redundancies(copy);
6905                 empty = ISL_F_ISSET(copy, ISL_BASIC_MAP_EMPTY);
6906                 isl_basic_map_free(copy);
6907                 return empty;
6908         }
6909
6910         total = 1 + isl_basic_map_total_dim(bmap);
6911         if (bmap->sample && bmap->sample->size == total) {
6912                 int contains = isl_basic_map_contains(bmap, bmap->sample);
6913                 if (contains < 0)
6914                         return -1;
6915                 if (contains)
6916                         return 0;
6917         }
6918         isl_vec_free(bmap->sample);
6919         bmap->sample = NULL;
6920         bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
6921         if (!bset)
6922                 return -1;
6923         sample = isl_basic_set_sample_vec(bset);
6924         if (!sample)
6925                 return -1;
6926         empty = sample->size == 0;
6927         isl_vec_free(bmap->sample);
6928         bmap->sample = sample;
6929         if (empty)
6930                 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
6931
6932         return empty;
6933 }
6934
6935 int isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
6936 {
6937         if (!bmap)
6938                 return -1;
6939         return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY);
6940 }
6941
6942 int isl_basic_map_fast_is_empty(__isl_keep isl_basic_map *bmap)
6943 {
6944         return isl_basic_map_plain_is_empty(bmap);
6945 }
6946
6947 int isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset)
6948 {
6949         if (!bset)
6950                 return -1;
6951         return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY);
6952 }
6953
6954 int isl_basic_set_fast_is_empty(__isl_keep isl_basic_set *bset)
6955 {
6956         return isl_basic_set_plain_is_empty(bset);
6957 }
6958
6959 int isl_basic_set_is_empty(struct isl_basic_set *bset)
6960 {
6961         return isl_basic_map_is_empty((struct isl_basic_map *)bset);
6962 }
6963
6964 struct isl_map *isl_basic_map_union(
6965         struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
6966 {
6967         struct isl_map *map;
6968         if (!bmap1 || !bmap2)
6969                 return NULL;
6970
6971         isl_assert(bmap1->ctx, isl_space_is_equal(bmap1->dim, bmap2->dim), goto error);
6972
6973         map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
6974         if (!map)
6975                 goto error;
6976         map = isl_map_add_basic_map(map, bmap1);
6977         map = isl_map_add_basic_map(map, bmap2);
6978         return map;
6979 error:
6980         isl_basic_map_free(bmap1);
6981         isl_basic_map_free(bmap2);
6982         return NULL;
6983 }
6984
6985 struct isl_set *isl_basic_set_union(
6986                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
6987 {
6988         return (struct isl_set *)isl_basic_map_union(
6989                                             (struct isl_basic_map *)bset1,
6990                                             (struct isl_basic_map *)bset2);
6991 }
6992
6993 /* Order divs such that any div only depends on previous divs */
6994 struct isl_basic_map *isl_basic_map_order_divs(struct isl_basic_map *bmap)
6995 {
6996         int i;
6997         unsigned off;
6998
6999         if (!bmap)
7000                 return NULL;
7001
7002         off = isl_space_dim(bmap->dim, isl_dim_all);
7003
7004         for (i = 0; i < bmap->n_div; ++i) {
7005                 int pos;
7006                 if (isl_int_is_zero(bmap->div[i][0]))
7007                         continue;
7008                 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
7009                                                             bmap->n_div-i);
7010                 if (pos == -1)
7011                         continue;
7012                 isl_basic_map_swap_div(bmap, i, i + pos);
7013                 --i;
7014         }
7015         return bmap;
7016 }
7017
7018 struct isl_basic_set *isl_basic_set_order_divs(struct isl_basic_set *bset)
7019 {
7020         return (struct isl_basic_set *)
7021                 isl_basic_map_order_divs((struct isl_basic_map *)bset);
7022 }
7023
7024 __isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
7025 {
7026         int i;
7027
7028         if (!map)
7029                 return 0;
7030
7031         for (i = 0; i < map->n; ++i) {
7032                 map->p[i] = isl_basic_map_order_divs(map->p[i]);
7033                 if (!map->p[i])
7034                         goto error;
7035         }
7036
7037         return map;
7038 error:
7039         isl_map_free(map);
7040         return NULL;
7041 }
7042
7043 /* Apply the expansion computed by isl_merge_divs.
7044  * The expansion itself is given by "exp" while the resulting
7045  * list of divs is given by "div".
7046  */
7047 __isl_give isl_basic_set *isl_basic_set_expand_divs(
7048         __isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp)
7049 {
7050         int i, j;
7051         int n_div;
7052
7053         bset = isl_basic_set_cow(bset);
7054         if (!bset || !div)
7055                 goto error;
7056
7057         if (div->n_row < bset->n_div)
7058                 isl_die(isl_mat_get_ctx(div), isl_error_invalid,
7059                         "not an expansion", goto error);
7060
7061         bset = isl_basic_map_extend_space(bset, isl_space_copy(bset->dim),
7062                                         div->n_row - bset->n_div, 0,
7063                                         2 * (div->n_row - bset->n_div));
7064
7065         n_div = bset->n_div;
7066         for (i = n_div; i < div->n_row; ++i)
7067                 if (isl_basic_set_alloc_div(bset) < 0)
7068                         goto error;
7069
7070         j = n_div - 1;
7071         for (i = div->n_row - 1; i >= 0; --i) {
7072                 if (j >= 0 && exp[j] == i) {
7073                         if (i != j)
7074                                 isl_basic_map_swap_div(bset, i, j);
7075                         j--;
7076                 } else {
7077                         isl_seq_cpy(bset->div[i], div->row[i], div->n_col);
7078                         if (isl_basic_map_add_div_constraints(bset, i) < 0)
7079                                 goto error;
7080                 }
7081         }
7082
7083         isl_mat_free(div);
7084         return bset;
7085 error:
7086         isl_basic_set_free(bset);
7087         isl_mat_free(div);
7088         return NULL;
7089 }
7090
7091 /* Look for a div in dst that corresponds to the div "div" in src.
7092  * The divs before "div" in src and dst are assumed to be the same.
7093  * 
7094  * Returns -1 if no corresponding div was found and the position
7095  * of the corresponding div in dst otherwise.
7096  */
7097 static int find_div(struct isl_basic_map *dst,
7098                         struct isl_basic_map *src, unsigned div)
7099 {
7100         int i;
7101
7102         unsigned total = isl_space_dim(src->dim, isl_dim_all);
7103
7104         isl_assert(dst->ctx, div <= dst->n_div, return -1);
7105         for (i = div; i < dst->n_div; ++i)
7106                 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total+div) &&
7107                     isl_seq_first_non_zero(dst->div[i]+1+1+total+div,
7108                                                 dst->n_div - div) == -1)
7109                         return i;
7110         return -1;
7111 }
7112
7113 struct isl_basic_map *isl_basic_map_align_divs(
7114                 struct isl_basic_map *dst, struct isl_basic_map *src)
7115 {
7116         int i;
7117         unsigned total = isl_space_dim(src->dim, isl_dim_all);
7118
7119         if (!dst || !src)
7120                 goto error;
7121
7122         if (src->n_div == 0)
7123                 return dst;
7124
7125         for (i = 0; i < src->n_div; ++i)
7126                 isl_assert(src->ctx, !isl_int_is_zero(src->div[i][0]), goto error);
7127
7128         src = isl_basic_map_order_divs(src);
7129         dst = isl_basic_map_cow(dst);
7130         dst = isl_basic_map_extend_space(dst, isl_space_copy(dst->dim),
7131                         src->n_div, 0, 2 * src->n_div);
7132         if (!dst)
7133                 return NULL;
7134         for (i = 0; i < src->n_div; ++i) {
7135                 int j = find_div(dst, src, i);
7136                 if (j < 0) {
7137                         j = isl_basic_map_alloc_div(dst);
7138                         if (j < 0)
7139                                 goto error;
7140                         isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i);
7141                         isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i);
7142                         if (isl_basic_map_add_div_constraints(dst, j) < 0)
7143                                 goto error;
7144                 }
7145                 if (j != i)
7146                         isl_basic_map_swap_div(dst, i, j);
7147         }
7148         return dst;
7149 error:
7150         isl_basic_map_free(dst);
7151         return NULL;
7152 }
7153
7154 struct isl_basic_set *isl_basic_set_align_divs(
7155                 struct isl_basic_set *dst, struct isl_basic_set *src)
7156 {
7157         return (struct isl_basic_set *)isl_basic_map_align_divs(
7158                 (struct isl_basic_map *)dst, (struct isl_basic_map *)src);
7159 }
7160
7161 struct isl_map *isl_map_align_divs(struct isl_map *map)
7162 {
7163         int i;
7164
7165         if (!map)
7166                 return NULL;
7167         if (map->n == 0)
7168                 return map;
7169         map = isl_map_compute_divs(map);
7170         map = isl_map_cow(map);
7171         if (!map)
7172                 return NULL;
7173
7174         for (i = 1; i < map->n; ++i)
7175                 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
7176         for (i = 1; i < map->n; ++i)
7177                 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
7178
7179         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
7180         return map;
7181 }
7182
7183 struct isl_set *isl_set_align_divs(struct isl_set *set)
7184 {
7185         return (struct isl_set *)isl_map_align_divs((struct isl_map *)set);
7186 }
7187
7188 static __isl_give isl_set *set_apply( __isl_take isl_set *set,
7189         __isl_take isl_map *map)
7190 {
7191         if (!set || !map)
7192                 goto error;
7193         isl_assert(set->ctx, isl_map_compatible_domain(map, set), goto error);
7194         map = isl_map_intersect_domain(map, set);
7195         set = isl_map_range(map);
7196         return set;
7197 error:
7198         isl_set_free(set);
7199         isl_map_free(map);
7200         return NULL;
7201 }
7202
7203 __isl_give isl_set *isl_set_apply( __isl_take isl_set *set,
7204         __isl_take isl_map *map)
7205 {
7206         return isl_map_align_params_map_map_and(set, map, &set_apply);
7207 }
7208
7209 /* There is no need to cow as removing empty parts doesn't change
7210  * the meaning of the set.
7211  */
7212 struct isl_map *isl_map_remove_empty_parts(struct isl_map *map)
7213 {
7214         int i;
7215
7216         if (!map)
7217                 return NULL;
7218
7219         for (i = map->n - 1; i >= 0; --i)
7220                 remove_if_empty(map, i);
7221
7222         return map;
7223 }
7224
7225 struct isl_set *isl_set_remove_empty_parts(struct isl_set *set)
7226 {
7227         return (struct isl_set *)
7228                 isl_map_remove_empty_parts((struct isl_map *)set);
7229 }
7230
7231 struct isl_basic_map *isl_map_copy_basic_map(struct isl_map *map)
7232 {
7233         struct isl_basic_map *bmap;
7234         if (!map || map->n == 0)
7235                 return NULL;
7236         bmap = map->p[map->n-1];
7237         isl_assert(map->ctx, ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL), return NULL);
7238         return isl_basic_map_copy(bmap);
7239 }
7240
7241 struct isl_basic_set *isl_set_copy_basic_set(struct isl_set *set)
7242 {
7243         return (struct isl_basic_set *)
7244                 isl_map_copy_basic_map((struct isl_map *)set);
7245 }
7246
7247 __isl_give isl_map *isl_map_drop_basic_map(__isl_take isl_map *map,
7248                                                 __isl_keep isl_basic_map *bmap)
7249 {
7250         int i;
7251
7252         if (!map || !bmap)
7253                 goto error;
7254         for (i = map->n-1; i >= 0; --i) {
7255                 if (map->p[i] != bmap)
7256                         continue;
7257                 map = isl_map_cow(map);
7258                 if (!map)
7259                         goto error;
7260                 isl_basic_map_free(map->p[i]);
7261                 if (i != map->n-1) {
7262                         ISL_F_CLR(map, ISL_SET_NORMALIZED);
7263                         map->p[i] = map->p[map->n-1];
7264                 }
7265                 map->n--;
7266                 return map;
7267         }
7268         return map;
7269 error:
7270         isl_map_free(map);
7271         return NULL;
7272 }
7273
7274 struct isl_set *isl_set_drop_basic_set(struct isl_set *set,
7275                                                 struct isl_basic_set *bset)
7276 {
7277         return (struct isl_set *)isl_map_drop_basic_map((struct isl_map *)set,
7278                                                 (struct isl_basic_map *)bset);
7279 }
7280
7281 /* Given two basic sets bset1 and bset2, compute the maximal difference
7282  * between the values of dimension pos in bset1 and those in bset2
7283  * for any common value of the parameters and dimensions preceding pos.
7284  */
7285 static enum isl_lp_result basic_set_maximal_difference_at(
7286         __isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2,
7287         int pos, isl_int *opt)
7288 {
7289         isl_space *dims;
7290         struct isl_basic_map *bmap1 = NULL;
7291         struct isl_basic_map *bmap2 = NULL;
7292         struct isl_ctx *ctx;
7293         struct isl_vec *obj;
7294         unsigned total;
7295         unsigned nparam;
7296         unsigned dim1, dim2;
7297         enum isl_lp_result res;
7298
7299         if (!bset1 || !bset2)
7300                 return isl_lp_error;
7301
7302         nparam = isl_basic_set_n_param(bset1);
7303         dim1 = isl_basic_set_n_dim(bset1);
7304         dim2 = isl_basic_set_n_dim(bset2);
7305         dims = isl_space_alloc(bset1->ctx, nparam, pos, dim1 - pos);
7306         bmap1 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset1), dims);
7307         dims = isl_space_alloc(bset2->ctx, nparam, pos, dim2 - pos);
7308         bmap2 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset2), dims);
7309         if (!bmap1 || !bmap2)
7310                 goto error;
7311         bmap1 = isl_basic_map_cow(bmap1);
7312         bmap1 = isl_basic_map_extend(bmap1, nparam,
7313                         pos, (dim1 - pos) + (dim2 - pos),
7314                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
7315         bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos);
7316         if (!bmap1)
7317                 goto error;
7318         total = isl_basic_map_total_dim(bmap1);
7319         ctx = bmap1->ctx;
7320         obj = isl_vec_alloc(ctx, 1 + total);
7321         isl_seq_clr(obj->block.data, 1 + total);
7322         isl_int_set_si(obj->block.data[1+nparam+pos], 1);
7323         isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
7324         if (!obj)
7325                 goto error;
7326         res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
7327                                         opt, NULL, NULL);
7328         isl_basic_map_free(bmap1);
7329         isl_vec_free(obj);
7330         return res;
7331 error:
7332         isl_basic_map_free(bmap1);
7333         isl_basic_map_free(bmap2);
7334         return isl_lp_error;
7335 }
7336
7337 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
7338  * for any common value of the parameters and dimensions preceding pos
7339  * in both basic sets, the values of dimension pos in bset1 are
7340  * smaller or larger than those in bset2.
7341  *
7342  * Returns
7343  *       1 if bset1 follows bset2
7344  *      -1 if bset1 precedes bset2
7345  *       0 if bset1 and bset2 are incomparable
7346  *      -2 if some error occurred.
7347  */
7348 int isl_basic_set_compare_at(struct isl_basic_set *bset1,
7349         struct isl_basic_set *bset2, int pos)
7350 {
7351         isl_int opt;
7352         enum isl_lp_result res;
7353         int cmp;
7354
7355         isl_int_init(opt);
7356
7357         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
7358
7359         if (res == isl_lp_empty)
7360                 cmp = 0;
7361         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
7362                   res == isl_lp_unbounded)
7363                 cmp = 1;
7364         else if (res == isl_lp_ok && isl_int_is_neg(opt))
7365                 cmp = -1;
7366         else
7367                 cmp = -2;
7368
7369         isl_int_clear(opt);
7370         return cmp;
7371 }
7372
7373 /* Given two basic sets bset1 and bset2, check whether
7374  * for any common value of the parameters and dimensions preceding pos
7375  * there is a value of dimension pos in bset1 that is larger
7376  * than a value of the same dimension in bset2.
7377  *
7378  * Return
7379  *       1 if there exists such a pair
7380  *       0 if there is no such pair, but there is a pair of equal values
7381  *      -1 otherwise
7382  *      -2 if some error occurred.
7383  */
7384 int isl_basic_set_follows_at(__isl_keep isl_basic_set *bset1,
7385         __isl_keep isl_basic_set *bset2, int pos)
7386 {
7387         isl_int opt;
7388         enum isl_lp_result res;
7389         int cmp;
7390
7391         isl_int_init(opt);
7392
7393         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
7394
7395         if (res == isl_lp_empty)
7396                 cmp = -1;
7397         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
7398                   res == isl_lp_unbounded)
7399                 cmp = 1;
7400         else if (res == isl_lp_ok && isl_int_is_neg(opt))
7401                 cmp = -1;
7402         else if (res == isl_lp_ok)
7403                 cmp = 0;
7404         else
7405                 cmp = -2;
7406
7407         isl_int_clear(opt);
7408         return cmp;
7409 }
7410
7411 /* Given two sets set1 and set2, check whether
7412  * for any common value of the parameters and dimensions preceding pos
7413  * there is a value of dimension pos in set1 that is larger
7414  * than a value of the same dimension in set2.
7415  *
7416  * Return
7417  *       1 if there exists such a pair
7418  *       0 if there is no such pair, but there is a pair of equal values
7419  *      -1 otherwise
7420  *      -2 if some error occurred.
7421  */
7422 int isl_set_follows_at(__isl_keep isl_set *set1,
7423         __isl_keep isl_set *set2, int pos)
7424 {
7425         int i, j;
7426         int follows = -1;
7427
7428         if (!set1 || !set2)
7429                 return -2;
7430
7431         for (i = 0; i < set1->n; ++i)
7432                 for (j = 0; j < set2->n; ++j) {
7433                         int f;
7434                         f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
7435                         if (f == 1 || f == -2)
7436                                 return f;
7437                         if (f > follows)
7438                                 follows = f;
7439                 }
7440
7441         return follows;
7442 }
7443
7444 static int isl_basic_map_plain_has_fixed_var(__isl_keep isl_basic_map *bmap,
7445         unsigned pos, isl_int *val)
7446 {
7447         int i;
7448         int d;
7449         unsigned total;
7450
7451         if (!bmap)
7452                 return -1;
7453         total = isl_basic_map_total_dim(bmap);
7454         for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
7455                 for (; d+1 > pos; --d)
7456                         if (!isl_int_is_zero(bmap->eq[i][1+d]))
7457                                 break;
7458                 if (d != pos)
7459                         continue;
7460                 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
7461                         return 0;
7462                 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
7463                         return 0;
7464                 if (!isl_int_is_one(bmap->eq[i][1+d]))
7465                         return 0;
7466                 if (val)
7467                         isl_int_neg(*val, bmap->eq[i][0]);
7468                 return 1;
7469         }
7470         return 0;
7471 }
7472
7473 static int isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
7474         unsigned pos, isl_int *val)
7475 {
7476         int i;
7477         isl_int v;
7478         isl_int tmp;
7479         int fixed;
7480
7481         if (!map)
7482                 return -1;
7483         if (map->n == 0)
7484                 return 0;
7485         if (map->n == 1)
7486                 return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val); 
7487         isl_int_init(v);
7488         isl_int_init(tmp);
7489         fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v); 
7490         for (i = 1; fixed == 1 && i < map->n; ++i) {
7491                 fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp); 
7492                 if (fixed == 1 && isl_int_ne(tmp, v))
7493                         fixed = 0;
7494         }
7495         if (val)
7496                 isl_int_set(*val, v);
7497         isl_int_clear(tmp);
7498         isl_int_clear(v);
7499         return fixed;
7500 }
7501
7502 static int isl_basic_set_plain_has_fixed_var(__isl_keep isl_basic_set *bset,
7503         unsigned pos, isl_int *val)
7504 {
7505         return isl_basic_map_plain_has_fixed_var((struct isl_basic_map *)bset,
7506                                                 pos, val);
7507 }
7508
7509 static int isl_set_plain_has_fixed_var(__isl_keep isl_set *set, unsigned pos,
7510         isl_int *val)
7511 {
7512         return isl_map_plain_has_fixed_var((struct isl_map *)set, pos, val);
7513 }
7514
7515 int isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
7516         enum isl_dim_type type, unsigned pos, isl_int *val)
7517 {
7518         if (pos >= isl_basic_map_dim(bmap, type))
7519                 return -1;
7520         return isl_basic_map_plain_has_fixed_var(bmap,
7521                 isl_basic_map_offset(bmap, type) - 1 + pos, val);
7522 }
7523
7524 int isl_map_plain_is_fixed(__isl_keep isl_map *map,
7525         enum isl_dim_type type, unsigned pos, isl_int *val)
7526 {
7527         if (pos >= isl_map_dim(map, type))
7528                 return -1;
7529         return isl_map_plain_has_fixed_var(map,
7530                 map_offset(map, type) - 1 + pos, val);
7531 }
7532
7533 int isl_set_plain_is_fixed(__isl_keep isl_set *set,
7534         enum isl_dim_type type, unsigned pos, isl_int *val)
7535 {
7536         return isl_map_plain_is_fixed(set, type, pos, val);
7537 }
7538
7539 int isl_map_fast_is_fixed(__isl_keep isl_map *map,
7540         enum isl_dim_type type, unsigned pos, isl_int *val)
7541 {
7542         return isl_map_plain_is_fixed(map, type, pos, val);
7543 }
7544
7545 /* Check if dimension dim has fixed value and if so and if val is not NULL,
7546  * then return this fixed value in *val.
7547  */
7548 int isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset,
7549         unsigned dim, isl_int *val)
7550 {
7551         return isl_basic_set_plain_has_fixed_var(bset,
7552                                         isl_basic_set_n_param(bset) + dim, val);
7553 }
7554
7555 /* Check if dimension dim has fixed value and if so and if val is not NULL,
7556  * then return this fixed value in *val.
7557  */
7558 int isl_set_plain_dim_is_fixed(__isl_keep isl_set *set,
7559         unsigned dim, isl_int *val)
7560 {
7561         return isl_set_plain_has_fixed_var(set, isl_set_n_param(set) + dim, val);
7562 }
7563
7564 int isl_set_fast_dim_is_fixed(__isl_keep isl_set *set,
7565         unsigned dim, isl_int *val)
7566 {
7567         return isl_set_plain_dim_is_fixed(set, dim, val);
7568 }
7569
7570 /* Check if input variable in has fixed value and if so and if val is not NULL,
7571  * then return this fixed value in *val.
7572  */
7573 int isl_map_plain_input_is_fixed(__isl_keep isl_map *map,
7574         unsigned in, isl_int *val)
7575 {
7576         return isl_map_plain_has_fixed_var(map, isl_map_n_param(map) + in, val);
7577 }
7578
7579 /* Check if dimension dim has an (obvious) fixed lower bound and if so
7580  * and if val is not NULL, then return this lower bound in *val.
7581  */
7582 int isl_basic_set_plain_dim_has_fixed_lower_bound(
7583         __isl_keep isl_basic_set *bset, unsigned dim, isl_int *val)
7584 {
7585         int i, i_eq = -1, i_ineq = -1;
7586         isl_int *c;
7587         unsigned total;
7588         unsigned nparam;
7589
7590         if (!bset)
7591                 return -1;
7592         total = isl_basic_set_total_dim(bset);
7593         nparam = isl_basic_set_n_param(bset);
7594         for (i = 0; i < bset->n_eq; ++i) {
7595                 if (isl_int_is_zero(bset->eq[i][1+nparam+dim]))
7596                         continue;
7597                 if (i_eq != -1)
7598                         return 0;
7599                 i_eq = i;
7600         }
7601         for (i = 0; i < bset->n_ineq; ++i) {
7602                 if (!isl_int_is_pos(bset->ineq[i][1+nparam+dim]))
7603                         continue;
7604                 if (i_eq != -1 || i_ineq != -1)
7605                         return 0;
7606                 i_ineq = i;
7607         }
7608         if (i_eq == -1 && i_ineq == -1)
7609                 return 0;
7610         c = i_eq != -1 ? bset->eq[i_eq] : bset->ineq[i_ineq];
7611         /* The coefficient should always be one due to normalization. */
7612         if (!isl_int_is_one(c[1+nparam+dim]))
7613                 return 0;
7614         if (isl_seq_first_non_zero(c+1, nparam+dim) != -1)
7615                 return 0;
7616         if (isl_seq_first_non_zero(c+1+nparam+dim+1,
7617                                         total - nparam - dim - 1) != -1)
7618                 return 0;
7619         if (val)
7620                 isl_int_neg(*val, c[0]);
7621         return 1;
7622 }
7623
7624 int isl_set_plain_dim_has_fixed_lower_bound(__isl_keep isl_set *set,
7625         unsigned dim, isl_int *val)
7626 {
7627         int i;
7628         isl_int v;
7629         isl_int tmp;
7630         int fixed;
7631
7632         if (!set)
7633                 return -1;
7634         if (set->n == 0)
7635                 return 0;
7636         if (set->n == 1)
7637                 return isl_basic_set_plain_dim_has_fixed_lower_bound(set->p[0],
7638                                                                 dim, val);
7639         isl_int_init(v);
7640         isl_int_init(tmp);
7641         fixed = isl_basic_set_plain_dim_has_fixed_lower_bound(set->p[0],
7642                                                                 dim, &v);
7643         for (i = 1; fixed == 1 && i < set->n; ++i) {
7644                 fixed = isl_basic_set_plain_dim_has_fixed_lower_bound(set->p[i],
7645                                                                 dim, &tmp);
7646                 if (fixed == 1 && isl_int_ne(tmp, v))
7647                         fixed = 0;
7648         }
7649         if (val)
7650                 isl_int_set(*val, v);
7651         isl_int_clear(tmp);
7652         isl_int_clear(v);
7653         return fixed;
7654 }
7655
7656 struct constraint {
7657         unsigned        size;
7658         isl_int         *c;
7659 };
7660
7661 /* uset_gist depends on constraints without existentially quantified
7662  * variables sorting first.
7663  */
7664 static int qsort_constraint_cmp(const void *p1, const void *p2)
7665 {
7666         const struct constraint *c1 = (const struct constraint *)p1;
7667         const struct constraint *c2 = (const struct constraint *)p2;
7668         int l1, l2;
7669         unsigned size = isl_min(c1->size, c2->size);
7670
7671         l1 = isl_seq_last_non_zero(c1->c, size);
7672         l2 = isl_seq_last_non_zero(c2->c, size);
7673
7674         if (l1 != l2)
7675                 return l1 - l2;
7676
7677         return isl_seq_cmp(c1->c, c2->c, size);
7678 }
7679
7680 static struct isl_basic_map *isl_basic_map_sort_constraints(
7681         struct isl_basic_map *bmap)
7682 {
7683         int i;
7684         struct constraint *c;
7685         unsigned total;
7686
7687         if (!bmap)
7688                 return NULL;
7689         total = isl_basic_map_total_dim(bmap);
7690         c = isl_alloc_array(bmap->ctx, struct constraint, bmap->n_ineq);
7691         if (!c)
7692                 goto error;
7693         for (i = 0; i < bmap->n_ineq; ++i) {
7694                 c[i].size = total;
7695                 c[i].c = bmap->ineq[i];
7696         }
7697         qsort(c, bmap->n_ineq, sizeof(struct constraint), qsort_constraint_cmp);
7698         for (i = 0; i < bmap->n_ineq; ++i)
7699                 bmap->ineq[i] = c[i].c;
7700         free(c);
7701         return bmap;
7702 error:
7703         isl_basic_map_free(bmap);
7704         return NULL;
7705 }
7706
7707 __isl_give isl_basic_set *isl_basic_set_sort_constraints(
7708         __isl_take isl_basic_set *bset)
7709 {
7710         return (struct isl_basic_set *)isl_basic_map_sort_constraints(
7711                                                 (struct isl_basic_map *)bset);
7712 }
7713
7714 struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap)
7715 {
7716         if (!bmap)
7717                 return NULL;
7718         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED))
7719                 return bmap;
7720         bmap = isl_basic_map_remove_redundancies(bmap);
7721         bmap = isl_basic_map_sort_constraints(bmap);
7722         ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
7723         return bmap;
7724 }
7725
7726 struct isl_basic_set *isl_basic_set_normalize(struct isl_basic_set *bset)
7727 {
7728         return (struct isl_basic_set *)isl_basic_map_normalize(
7729                                                 (struct isl_basic_map *)bset);
7730 }
7731
7732 int isl_basic_map_plain_cmp(const __isl_keep isl_basic_map *bmap1,
7733         const __isl_keep isl_basic_map *bmap2)
7734 {
7735         int i, cmp;
7736         unsigned total;
7737
7738         if (bmap1 == bmap2)
7739                 return 0;
7740         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) !=
7741             ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL))
7742                 return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) ? -1 : 1;
7743         if (isl_basic_map_n_param(bmap1) != isl_basic_map_n_param(bmap2))
7744                 return isl_basic_map_n_param(bmap1) - isl_basic_map_n_param(bmap2);
7745         if (isl_basic_map_n_in(bmap1) != isl_basic_map_n_in(bmap2))
7746                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
7747         if (isl_basic_map_n_out(bmap1) != isl_basic_map_n_out(bmap2))
7748                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
7749         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
7750             ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
7751                 return 0;
7752         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
7753                 return 1;
7754         if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
7755                 return -1;
7756         if (bmap1->n_eq != bmap2->n_eq)
7757                 return bmap1->n_eq - bmap2->n_eq;
7758         if (bmap1->n_ineq != bmap2->n_ineq)
7759                 return bmap1->n_ineq - bmap2->n_ineq;
7760         if (bmap1->n_div != bmap2->n_div)
7761                 return bmap1->n_div - bmap2->n_div;
7762         total = isl_basic_map_total_dim(bmap1);
7763         for (i = 0; i < bmap1->n_eq; ++i) {
7764                 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
7765                 if (cmp)
7766                         return cmp;
7767         }
7768         for (i = 0; i < bmap1->n_ineq; ++i) {
7769                 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
7770                 if (cmp)
7771                         return cmp;
7772         }
7773         for (i = 0; i < bmap1->n_div; ++i) {
7774                 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
7775                 if (cmp)
7776                         return cmp;
7777         }
7778         return 0;
7779 }
7780
7781 int isl_basic_set_plain_cmp(const __isl_keep isl_basic_set *bset1,
7782         const __isl_keep isl_basic_set *bset2)
7783 {
7784         return isl_basic_map_plain_cmp(bset1, bset2);
7785 }
7786
7787 int isl_set_plain_cmp(const __isl_keep isl_set *set1,
7788         const __isl_keep isl_set *set2)
7789 {
7790         int i, cmp;
7791
7792         if (set1 == set2)
7793                 return 0;
7794         if (set1->n != set2->n)
7795                 return set1->n - set2->n;
7796
7797         for (i = 0; i < set1->n; ++i) {
7798                 cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
7799                 if (cmp)
7800                         return cmp;
7801         }
7802
7803         return 0;
7804 }
7805
7806 int isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
7807         __isl_keep isl_basic_map *bmap2)
7808 {
7809         return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
7810 }
7811
7812 int isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1,
7813         __isl_keep isl_basic_set *bset2)
7814 {
7815         return isl_basic_map_plain_is_equal((isl_basic_map *)bset1,
7816                                             (isl_basic_map *)bset2);
7817 }
7818
7819 static int qsort_bmap_cmp(const void *p1, const void *p2)
7820 {
7821         const struct isl_basic_map *bmap1 = *(const struct isl_basic_map **)p1;
7822         const struct isl_basic_map *bmap2 = *(const struct isl_basic_map **)p2;
7823
7824         return isl_basic_map_plain_cmp(bmap1, bmap2);
7825 }
7826
7827 /* We normalize in place, but if anything goes wrong we need
7828  * to return NULL, so we need to make sure we don't change the
7829  * meaning of any possible other copies of map.
7830  */
7831 struct isl_map *isl_map_normalize(struct isl_map *map)
7832 {
7833         int i, j;
7834         struct isl_basic_map *bmap;
7835
7836         if (!map)
7837                 return NULL;
7838         if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED))
7839                 return map;
7840         for (i = 0; i < map->n; ++i) {
7841                 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
7842                 if (!bmap)
7843                         goto error;
7844                 isl_basic_map_free(map->p[i]);
7845                 map->p[i] = bmap;
7846         }
7847         qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
7848         ISL_F_SET(map, ISL_MAP_NORMALIZED);
7849         map = isl_map_remove_empty_parts(map);
7850         if (!map)
7851                 return NULL;
7852         for (i = map->n - 1; i >= 1; --i) {
7853                 if (!isl_basic_map_plain_is_equal(map->p[i-1], map->p[i]))
7854                         continue;
7855                 isl_basic_map_free(map->p[i-1]);
7856                 for (j = i; j < map->n; ++j)
7857                         map->p[j-1] = map->p[j];
7858                 map->n--;
7859         }
7860         return map;
7861 error:
7862         isl_map_free(map);
7863         return NULL;
7864
7865 }
7866
7867 struct isl_set *isl_set_normalize(struct isl_set *set)
7868 {
7869         return (struct isl_set *)isl_map_normalize((struct isl_map *)set);
7870 }
7871
7872 int isl_map_plain_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
7873 {
7874         int i;
7875         int equal;
7876
7877         if (!map1 || !map2)
7878                 return -1;
7879
7880         if (map1 == map2)
7881                 return 1;
7882         if (!isl_space_is_equal(map1->dim, map2->dim))
7883                 return 0;
7884
7885         map1 = isl_map_copy(map1);
7886         map2 = isl_map_copy(map2);
7887         map1 = isl_map_normalize(map1);
7888         map2 = isl_map_normalize(map2);
7889         if (!map1 || !map2)
7890                 goto error;
7891         equal = map1->n == map2->n;
7892         for (i = 0; equal && i < map1->n; ++i) {
7893                 equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
7894                 if (equal < 0)
7895                         goto error;
7896         }
7897         isl_map_free(map1);
7898         isl_map_free(map2);
7899         return equal;
7900 error:
7901         isl_map_free(map1);
7902         isl_map_free(map2);
7903         return -1;
7904 }
7905
7906 int isl_map_fast_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
7907 {
7908         return isl_map_plain_is_equal(map1, map2);
7909 }
7910
7911 int isl_set_plain_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
7912 {
7913         return isl_map_plain_is_equal((struct isl_map *)set1,
7914                                                 (struct isl_map *)set2);
7915 }
7916
7917 int isl_set_fast_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
7918 {
7919         return isl_set_plain_is_equal(set1, set2);
7920 }
7921
7922 /* Return an interval that ranges from min to max (inclusive)
7923  */
7924 struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx,
7925         isl_int min, isl_int max)
7926 {
7927         int k;
7928         struct isl_basic_set *bset = NULL;
7929
7930         bset = isl_basic_set_alloc(ctx, 0, 1, 0, 0, 2);
7931         if (!bset)
7932                 goto error;
7933
7934         k = isl_basic_set_alloc_inequality(bset);
7935         if (k < 0)
7936                 goto error;
7937         isl_int_set_si(bset->ineq[k][1], 1);
7938         isl_int_neg(bset->ineq[k][0], min);
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_set(bset->ineq[k][0], max);
7945
7946         return bset;
7947 error:
7948         isl_basic_set_free(bset);
7949         return NULL;
7950 }
7951
7952 /* Return the Cartesian product of the basic sets in list (in the given order).
7953  */
7954 __isl_give isl_basic_set *isl_basic_set_list_product(
7955         __isl_take struct isl_basic_set_list *list)
7956 {
7957         int i;
7958         unsigned dim;
7959         unsigned nparam;
7960         unsigned extra;
7961         unsigned n_eq;
7962         unsigned n_ineq;
7963         struct isl_basic_set *product = NULL;
7964
7965         if (!list)
7966                 goto error;
7967         isl_assert(list->ctx, list->n > 0, goto error);
7968         isl_assert(list->ctx, list->p[0], goto error);
7969         nparam = isl_basic_set_n_param(list->p[0]);
7970         dim = isl_basic_set_n_dim(list->p[0]);
7971         extra = list->p[0]->n_div;
7972         n_eq = list->p[0]->n_eq;
7973         n_ineq = list->p[0]->n_ineq;
7974         for (i = 1; i < list->n; ++i) {
7975                 isl_assert(list->ctx, list->p[i], goto error);
7976                 isl_assert(list->ctx,
7977                     nparam == isl_basic_set_n_param(list->p[i]), goto error);
7978                 dim += isl_basic_set_n_dim(list->p[i]);
7979                 extra += list->p[i]->n_div;
7980                 n_eq += list->p[i]->n_eq;
7981                 n_ineq += list->p[i]->n_ineq;
7982         }
7983         product = isl_basic_set_alloc(list->ctx, nparam, dim, extra,
7984                                         n_eq, n_ineq);
7985         if (!product)
7986                 goto error;
7987         dim = 0;
7988         for (i = 0; i < list->n; ++i) {
7989                 isl_basic_set_add_constraints(product,
7990                                         isl_basic_set_copy(list->p[i]), dim);
7991                 dim += isl_basic_set_n_dim(list->p[i]);
7992         }
7993         isl_basic_set_list_free(list);
7994         return product;
7995 error:
7996         isl_basic_set_free(product);
7997         isl_basic_set_list_free(list);
7998         return NULL;
7999 }
8000
8001 struct isl_basic_map *isl_basic_map_product(
8002                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
8003 {
8004         isl_space *dim_result = NULL;
8005         struct isl_basic_map *bmap;
8006         unsigned in1, in2, out1, out2, nparam, total, pos;
8007         struct isl_dim_map *dim_map1, *dim_map2;
8008
8009         if (!bmap1 || !bmap2)
8010                 goto error;
8011
8012         isl_assert(bmap1->ctx, isl_space_match(bmap1->dim, isl_dim_param,
8013                                      bmap2->dim, isl_dim_param), goto error);
8014         dim_result = isl_space_product(isl_space_copy(bmap1->dim),
8015                                                    isl_space_copy(bmap2->dim));
8016
8017         in1 = isl_basic_map_n_in(bmap1);
8018         in2 = isl_basic_map_n_in(bmap2);
8019         out1 = isl_basic_map_n_out(bmap1);
8020         out2 = isl_basic_map_n_out(bmap2);
8021         nparam = isl_basic_map_n_param(bmap1);
8022
8023         total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
8024         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
8025         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
8026         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
8027         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
8028         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
8029         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
8030         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
8031         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
8032         isl_dim_map_div(dim_map1, bmap1, pos += out2);
8033         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
8034
8035         bmap = isl_basic_map_alloc_space(dim_result,
8036                         bmap1->n_div + bmap2->n_div,
8037                         bmap1->n_eq + bmap2->n_eq,
8038                         bmap1->n_ineq + bmap2->n_ineq);
8039         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
8040         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
8041         bmap = isl_basic_map_simplify(bmap);
8042         return isl_basic_map_finalize(bmap);
8043 error:
8044         isl_basic_map_free(bmap1);
8045         isl_basic_map_free(bmap2);
8046         return NULL;
8047 }
8048
8049 __isl_give isl_basic_map *isl_basic_map_flat_product(
8050         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8051 {
8052         isl_basic_map *prod;
8053
8054         prod = isl_basic_map_product(bmap1, bmap2);
8055         prod = isl_basic_map_flatten(prod);
8056         return prod;
8057 }
8058
8059 __isl_give isl_basic_set *isl_basic_set_flat_product(
8060         __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
8061 {
8062         return isl_basic_map_flat_range_product(bset1, bset2);
8063 }
8064
8065 __isl_give isl_basic_map *isl_basic_map_domain_product(
8066         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8067 {
8068         isl_space *space_result = NULL;
8069         isl_basic_map *bmap;
8070         unsigned in1, in2, out, nparam, total, pos;
8071         struct isl_dim_map *dim_map1, *dim_map2;
8072
8073         if (!bmap1 || !bmap2)
8074                 goto error;
8075
8076         space_result = isl_space_domain_product(isl_space_copy(bmap1->dim),
8077                                                 isl_space_copy(bmap2->dim));
8078
8079         in1 = isl_basic_map_dim(bmap1, isl_dim_in);
8080         in2 = isl_basic_map_dim(bmap2, isl_dim_in);
8081         out = isl_basic_map_dim(bmap1, isl_dim_out);
8082         nparam = isl_basic_map_dim(bmap1, isl_dim_param);
8083
8084         total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
8085         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
8086         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
8087         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
8088         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
8089         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
8090         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
8091         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
8092         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
8093         isl_dim_map_div(dim_map1, bmap1, pos += out);
8094         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
8095
8096         bmap = isl_basic_map_alloc_space(space_result,
8097                         bmap1->n_div + bmap2->n_div,
8098                         bmap1->n_eq + bmap2->n_eq,
8099                         bmap1->n_ineq + bmap2->n_ineq);
8100         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
8101         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
8102         bmap = isl_basic_map_simplify(bmap);
8103         return isl_basic_map_finalize(bmap);
8104 error:
8105         isl_basic_map_free(bmap1);
8106         isl_basic_map_free(bmap2);
8107         return NULL;
8108 }
8109
8110 __isl_give isl_basic_map *isl_basic_map_range_product(
8111         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8112 {
8113         isl_space *dim_result = NULL;
8114         isl_basic_map *bmap;
8115         unsigned in, out1, out2, nparam, total, pos;
8116         struct isl_dim_map *dim_map1, *dim_map2;
8117
8118         if (!bmap1 || !bmap2)
8119                 goto error;
8120
8121         dim_result = isl_space_range_product(isl_space_copy(bmap1->dim),
8122                                            isl_space_copy(bmap2->dim));
8123
8124         in = isl_basic_map_dim(bmap1, isl_dim_in);
8125         out1 = isl_basic_map_n_out(bmap1);
8126         out2 = isl_basic_map_n_out(bmap2);
8127         nparam = isl_basic_map_n_param(bmap1);
8128
8129         total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
8130         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
8131         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
8132         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
8133         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
8134         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
8135         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
8136         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
8137         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
8138         isl_dim_map_div(dim_map1, bmap1, pos += out2);
8139         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
8140
8141         bmap = isl_basic_map_alloc_space(dim_result,
8142                         bmap1->n_div + bmap2->n_div,
8143                         bmap1->n_eq + bmap2->n_eq,
8144                         bmap1->n_ineq + bmap2->n_ineq);
8145         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
8146         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
8147         bmap = isl_basic_map_simplify(bmap);
8148         return isl_basic_map_finalize(bmap);
8149 error:
8150         isl_basic_map_free(bmap1);
8151         isl_basic_map_free(bmap2);
8152         return NULL;
8153 }
8154
8155 __isl_give isl_basic_map *isl_basic_map_flat_range_product(
8156         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8157 {
8158         isl_basic_map *prod;
8159
8160         prod = isl_basic_map_range_product(bmap1, bmap2);
8161         prod = isl_basic_map_flatten_range(prod);
8162         return prod;
8163 }
8164
8165 static __isl_give isl_map *map_product(__isl_take isl_map *map1,
8166         __isl_take isl_map *map2,
8167         __isl_give isl_space *(*dim_product)(__isl_take isl_space *left,
8168                                            __isl_take isl_space *right),
8169         __isl_give isl_basic_map *(*basic_map_product)(
8170                 __isl_take isl_basic_map *left, __isl_take isl_basic_map *right))
8171 {
8172         unsigned flags = 0;
8173         struct isl_map *result;
8174         int i, j;
8175
8176         if (!map1 || !map2)
8177                 goto error;
8178
8179         isl_assert(map1->ctx, isl_space_match(map1->dim, isl_dim_param,
8180                                          map2->dim, isl_dim_param), goto error);
8181
8182         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
8183             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
8184                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
8185
8186         result = isl_map_alloc_space(dim_product(isl_space_copy(map1->dim),
8187                                                isl_space_copy(map2->dim)),
8188                                 map1->n * map2->n, flags);
8189         if (!result)
8190                 goto error;
8191         for (i = 0; i < map1->n; ++i)
8192                 for (j = 0; j < map2->n; ++j) {
8193                         struct isl_basic_map *part;
8194                         part = basic_map_product(isl_basic_map_copy(map1->p[i]),
8195                                                  isl_basic_map_copy(map2->p[j]));
8196                         if (isl_basic_map_is_empty(part))
8197                                 isl_basic_map_free(part);
8198                         else
8199                                 result = isl_map_add_basic_map(result, part);
8200                         if (!result)
8201                                 goto error;
8202                 }
8203         isl_map_free(map1);
8204         isl_map_free(map2);
8205         return result;
8206 error:
8207         isl_map_free(map1);
8208         isl_map_free(map2);
8209         return NULL;
8210 }
8211
8212 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
8213  */
8214 static __isl_give isl_map *map_product_aligned(__isl_take isl_map *map1,
8215         __isl_take isl_map *map2)
8216 {
8217         return map_product(map1, map2, &isl_space_product, &isl_basic_map_product);
8218 }
8219
8220 __isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
8221         __isl_take isl_map *map2)
8222 {
8223         return isl_map_align_params_map_map_and(map1, map2, &map_product_aligned);
8224 }
8225
8226 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
8227  */
8228 __isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
8229         __isl_take isl_map *map2)
8230 {
8231         isl_map *prod;
8232
8233         prod = isl_map_product(map1, map2);
8234         prod = isl_map_flatten(prod);
8235         return prod;
8236 }
8237
8238 /* Given two set A and B, construct its Cartesian product A x B.
8239  */
8240 struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2)
8241 {
8242         return isl_map_range_product(set1, set2);
8243 }
8244
8245 __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
8246         __isl_take isl_set *set2)
8247 {
8248         return isl_map_flat_range_product(set1, set2);
8249 }
8250
8251 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
8252  */
8253 static __isl_give isl_map *map_domain_product_aligned(__isl_take isl_map *map1,
8254         __isl_take isl_map *map2)
8255 {
8256         return map_product(map1, map2, &isl_space_domain_product,
8257                                 &isl_basic_map_domain_product);
8258 }
8259
8260 /* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
8261  */
8262 static __isl_give isl_map *map_range_product_aligned(__isl_take isl_map *map1,
8263         __isl_take isl_map *map2)
8264 {
8265         return map_product(map1, map2, &isl_space_range_product,
8266                                 &isl_basic_map_range_product);
8267 }
8268
8269 __isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
8270         __isl_take isl_map *map2)
8271 {
8272         return isl_map_align_params_map_map_and(map1, map2,
8273                                                 &map_domain_product_aligned);
8274 }
8275
8276 __isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
8277         __isl_take isl_map *map2)
8278 {
8279         return isl_map_align_params_map_map_and(map1, map2,
8280                                                 &map_range_product_aligned);
8281 }
8282
8283 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
8284  */
8285 __isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
8286         __isl_take isl_map *map2)
8287 {
8288         isl_map *prod;
8289
8290         prod = isl_map_domain_product(map1, map2);
8291         prod = isl_map_flatten_domain(prod);
8292         return prod;
8293 }
8294
8295 /* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
8296  */
8297 __isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
8298         __isl_take isl_map *map2)
8299 {
8300         isl_map *prod;
8301
8302         prod = isl_map_range_product(map1, map2);
8303         prod = isl_map_flatten_range(prod);
8304         return prod;
8305 }
8306
8307 uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
8308 {
8309         int i;
8310         uint32_t hash = isl_hash_init();
8311         unsigned total;
8312
8313         if (!bmap)
8314                 return 0;
8315         bmap = isl_basic_map_copy(bmap);
8316         bmap = isl_basic_map_normalize(bmap);
8317         if (!bmap)
8318                 return 0;
8319         total = isl_basic_map_total_dim(bmap);
8320         isl_hash_byte(hash, bmap->n_eq & 0xFF);
8321         for (i = 0; i < bmap->n_eq; ++i) {
8322                 uint32_t c_hash;
8323                 c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
8324                 isl_hash_hash(hash, c_hash);
8325         }
8326         isl_hash_byte(hash, bmap->n_ineq & 0xFF);
8327         for (i = 0; i < bmap->n_ineq; ++i) {
8328                 uint32_t c_hash;
8329                 c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
8330                 isl_hash_hash(hash, c_hash);
8331         }
8332         isl_hash_byte(hash, bmap->n_div & 0xFF);
8333         for (i = 0; i < bmap->n_div; ++i) {
8334                 uint32_t c_hash;
8335                 if (isl_int_is_zero(bmap->div[i][0]))
8336                         continue;
8337                 isl_hash_byte(hash, i & 0xFF);
8338                 c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
8339                 isl_hash_hash(hash, c_hash);
8340         }
8341         isl_basic_map_free(bmap);
8342         return hash;
8343 }
8344
8345 uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_set *bset)
8346 {
8347         return isl_basic_map_get_hash((isl_basic_map *)bset);
8348 }
8349
8350 uint32_t isl_map_get_hash(__isl_keep isl_map *map)
8351 {
8352         int i;
8353         uint32_t hash;
8354
8355         if (!map)
8356                 return 0;
8357         map = isl_map_copy(map);
8358         map = isl_map_normalize(map);
8359         if (!map)
8360                 return 0;
8361
8362         hash = isl_hash_init();
8363         for (i = 0; i < map->n; ++i) {
8364                 uint32_t bmap_hash;
8365                 bmap_hash = isl_basic_map_get_hash(map->p[i]);
8366                 isl_hash_hash(hash, bmap_hash);
8367         }
8368                 
8369         isl_map_free(map);
8370
8371         return hash;
8372 }
8373
8374 uint32_t isl_set_get_hash(__isl_keep isl_set *set)
8375 {
8376         return isl_map_get_hash((isl_map *)set);
8377 }
8378
8379 /* Check if the value for dimension dim is completely determined
8380  * by the values of the other parameters and variables.
8381  * That is, check if dimension dim is involved in an equality.
8382  */
8383 int isl_basic_set_dim_is_unique(struct isl_basic_set *bset, unsigned dim)
8384 {
8385         int i;
8386         unsigned nparam;
8387
8388         if (!bset)
8389                 return -1;
8390         nparam = isl_basic_set_n_param(bset);
8391         for (i = 0; i < bset->n_eq; ++i)
8392                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + dim]))
8393                         return 1;
8394         return 0;
8395 }
8396
8397 /* Check if the value for dimension dim is completely determined
8398  * by the values of the other parameters and variables.
8399  * That is, check if dimension dim is involved in an equality
8400  * for each of the subsets.
8401  */
8402 int isl_set_dim_is_unique(struct isl_set *set, unsigned dim)
8403 {
8404         int i;
8405
8406         if (!set)
8407                 return -1;
8408         for (i = 0; i < set->n; ++i) {
8409                 int unique;
8410                 unique = isl_basic_set_dim_is_unique(set->p[i], dim);
8411                 if (unique != 1)
8412                         return unique;
8413         }
8414         return 1;
8415 }
8416
8417 int isl_set_n_basic_set(__isl_keep isl_set *set)
8418 {
8419         return set ? set->n : 0;
8420 }
8421
8422 int isl_map_foreach_basic_map(__isl_keep isl_map *map,
8423         int (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
8424 {
8425         int i;
8426
8427         if (!map)
8428                 return -1;
8429
8430         for (i = 0; i < map->n; ++i)
8431                 if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
8432                         return -1;
8433
8434         return 0;
8435 }
8436
8437 int isl_set_foreach_basic_set(__isl_keep isl_set *set,
8438         int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user)
8439 {
8440         int i;
8441
8442         if (!set)
8443                 return -1;
8444
8445         for (i = 0; i < set->n; ++i)
8446                 if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
8447                         return -1;
8448
8449         return 0;
8450 }
8451
8452 __isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset)
8453 {
8454         isl_space *dim;
8455
8456         if (!bset)
8457                 return NULL;
8458
8459         bset = isl_basic_set_cow(bset);
8460         if (!bset)
8461                 return NULL;
8462
8463         dim = isl_basic_set_get_space(bset);
8464         dim = isl_space_lift(dim, bset->n_div);
8465         if (!dim)
8466                 goto error;
8467         isl_space_free(bset->dim);
8468         bset->dim = dim;
8469         bset->extra -= bset->n_div;
8470         bset->n_div = 0;
8471
8472         bset = isl_basic_set_finalize(bset);
8473
8474         return bset;
8475 error:
8476         isl_basic_set_free(bset);
8477         return NULL;
8478 }
8479
8480 __isl_give isl_set *isl_set_lift(__isl_take isl_set *set)
8481 {
8482         int i;
8483         isl_space *dim;
8484         unsigned n_div;
8485
8486         set = isl_set_align_divs(set);
8487
8488         if (!set)
8489                 return NULL;
8490
8491         set = isl_set_cow(set);
8492         if (!set)
8493                 return NULL;
8494
8495         n_div = set->p[0]->n_div;
8496         dim = isl_set_get_space(set);
8497         dim = isl_space_lift(dim, n_div);
8498         if (!dim)
8499                 goto error;
8500         isl_space_free(set->dim);
8501         set->dim = dim;
8502
8503         for (i = 0; i < set->n; ++i) {
8504                 set->p[i] = isl_basic_set_lift(set->p[i]);
8505                 if (!set->p[i])
8506                         goto error;
8507         }
8508
8509         return set;
8510 error:
8511         isl_set_free(set);
8512         return NULL;
8513 }
8514
8515 __isl_give isl_map *isl_set_lifting(__isl_take isl_set *set)
8516 {
8517         isl_space *dim;
8518         struct isl_basic_map *bmap;
8519         unsigned n_set;
8520         unsigned n_div;
8521         unsigned n_param;
8522         unsigned total;
8523         int i, k, l;
8524
8525         set = isl_set_align_divs(set);
8526
8527         if (!set)
8528                 return NULL;
8529
8530         dim = isl_set_get_space(set);
8531         if (set->n == 0 || set->p[0]->n_div == 0) {
8532                 isl_set_free(set);
8533                 return isl_map_identity(isl_space_map_from_set(dim));
8534         }
8535
8536         n_div = set->p[0]->n_div;
8537         dim = isl_space_map_from_set(dim);
8538         n_param = isl_space_dim(dim, isl_dim_param);
8539         n_set = isl_space_dim(dim, isl_dim_in);
8540         dim = isl_space_extend(dim, n_param, n_set, n_set + n_div);
8541         bmap = isl_basic_map_alloc_space(dim, 0, n_set, 2 * n_div);
8542         for (i = 0; i < n_set; ++i)
8543                 bmap = var_equal(bmap, i);
8544
8545         total = n_param + n_set + n_set + n_div;
8546         for (i = 0; i < n_div; ++i) {
8547                 k = isl_basic_map_alloc_inequality(bmap);
8548                 if (k < 0)
8549                         goto error;
8550                 isl_seq_cpy(bmap->ineq[k], set->p[0]->div[i]+1, 1+n_param);
8551                 isl_seq_clr(bmap->ineq[k]+1+n_param, n_set);
8552                 isl_seq_cpy(bmap->ineq[k]+1+n_param+n_set,
8553                             set->p[0]->div[i]+1+1+n_param, n_set + n_div);
8554                 isl_int_neg(bmap->ineq[k][1+n_param+n_set+n_set+i],
8555                             set->p[0]->div[i][0]);
8556
8557                 l = isl_basic_map_alloc_inequality(bmap);
8558                 if (l < 0)
8559                         goto error;
8560                 isl_seq_neg(bmap->ineq[l], bmap->ineq[k], 1 + total);
8561                 isl_int_add(bmap->ineq[l][0], bmap->ineq[l][0],
8562                             set->p[0]->div[i][0]);
8563                 isl_int_sub_ui(bmap->ineq[l][0], bmap->ineq[l][0], 1);
8564         }
8565
8566         isl_set_free(set);
8567         bmap = isl_basic_map_simplify(bmap);
8568         bmap = isl_basic_map_finalize(bmap);
8569         return isl_map_from_basic_map(bmap);
8570 error:
8571         isl_set_free(set);
8572         isl_basic_map_free(bmap);
8573         return NULL;
8574 }
8575
8576 int isl_basic_set_size(__isl_keep isl_basic_set *bset)
8577 {
8578         unsigned dim;
8579         int size = 0;
8580
8581         if (!bset)
8582                 return -1;
8583
8584         dim = isl_basic_set_total_dim(bset);
8585         size += bset->n_eq * (1 + dim);
8586         size += bset->n_ineq * (1 + dim);
8587         size += bset->n_div * (2 + dim);
8588
8589         return size;
8590 }
8591
8592 int isl_set_size(__isl_keep isl_set *set)
8593 {
8594         int i;
8595         int size = 0;
8596
8597         if (!set)
8598                 return -1;
8599
8600         for (i = 0; i < set->n; ++i)
8601                 size += isl_basic_set_size(set->p[i]);
8602
8603         return size;
8604 }
8605
8606 /* Check if there is any lower bound (if lower == 0) and/or upper
8607  * bound (if upper == 0) on the specified dim.
8608  */
8609 static int basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
8610         enum isl_dim_type type, unsigned pos, int lower, int upper)
8611 {
8612         int i;
8613
8614         if (!bmap)
8615                 return -1;
8616
8617         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), return -1);
8618
8619         pos += isl_basic_map_offset(bmap, type);
8620
8621         for (i = 0; i < bmap->n_div; ++i) {
8622                 if (isl_int_is_zero(bmap->div[i][0]))
8623                         continue;
8624                 if (!isl_int_is_zero(bmap->div[i][1 + pos]))
8625                         return 1;
8626         }
8627
8628         for (i = 0; i < bmap->n_eq; ++i)
8629                 if (!isl_int_is_zero(bmap->eq[i][pos]))
8630                         return 1;
8631
8632         for (i = 0; i < bmap->n_ineq; ++i) {
8633                 int sgn = isl_int_sgn(bmap->ineq[i][pos]);
8634                 if (sgn > 0)
8635                         lower = 1;
8636                 if (sgn < 0)
8637                         upper = 1;
8638         }
8639
8640         return lower && upper;
8641 }
8642
8643 int isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
8644         enum isl_dim_type type, unsigned pos)
8645 {
8646         return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
8647 }
8648
8649 int isl_basic_map_dim_has_lower_bound(__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, 1);
8653 }
8654
8655 int isl_basic_map_dim_has_upper_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, 1, 0);
8659 }
8660
8661 int isl_map_dim_is_bounded(__isl_keep isl_map *map,
8662         enum isl_dim_type type, unsigned pos)
8663 {
8664         int i;
8665
8666         if (!map)
8667                 return -1;
8668
8669         for (i = 0; i < map->n; ++i) {
8670                 int bounded;
8671                 bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
8672                 if (bounded < 0 || !bounded)
8673                         return bounded;
8674         }
8675
8676         return 1;
8677 }
8678
8679 /* Return 1 if the specified dim is involved in both an upper bound
8680  * and a lower bound.
8681  */
8682 int isl_set_dim_is_bounded(__isl_keep isl_set *set,
8683         enum isl_dim_type type, unsigned pos)
8684 {
8685         return isl_map_dim_is_bounded((isl_map *)set, type, pos);
8686 }
8687
8688 static int has_bound(__isl_keep isl_map *map,
8689         enum isl_dim_type type, unsigned pos,
8690         int (*fn)(__isl_keep isl_basic_map *bmap,
8691                   enum isl_dim_type type, unsigned pos))
8692 {
8693         int i;
8694
8695         if (!map)
8696                 return -1;
8697
8698         for (i = 0; i < map->n; ++i) {
8699                 int bounded;
8700                 bounded = fn(map->p[i], type, pos);
8701                 if (bounded < 0 || bounded)
8702                         return bounded;
8703         }
8704
8705         return 0;
8706 }
8707
8708 /* Return 1 if the specified dim is involved in any lower bound.
8709  */
8710 int isl_set_dim_has_lower_bound(__isl_keep isl_set *set,
8711         enum isl_dim_type type, unsigned pos)
8712 {
8713         return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound);
8714 }
8715
8716 /* Return 1 if the specified dim is involved in any upper bound.
8717  */
8718 int isl_set_dim_has_upper_bound(__isl_keep isl_set *set,
8719         enum isl_dim_type type, unsigned pos)
8720 {
8721         return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound);
8722 }
8723
8724 /* For each of the "n" variables starting at "first", determine
8725  * the sign of the variable and put the results in the first "n"
8726  * elements of the array "signs".
8727  * Sign
8728  *      1 means that the variable is non-negative
8729  *      -1 means that the variable is non-positive
8730  *      0 means the variable attains both positive and negative values.
8731  */
8732 int isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset,
8733         unsigned first, unsigned n, int *signs)
8734 {
8735         isl_vec *bound = NULL;
8736         struct isl_tab *tab = NULL;
8737         struct isl_tab_undo *snap;
8738         int i;
8739
8740         if (!bset || !signs)
8741                 return -1;
8742
8743         bound = isl_vec_alloc(bset->ctx, 1 + isl_basic_set_total_dim(bset));
8744         tab = isl_tab_from_basic_set(bset, 0);
8745         if (!bound || !tab)
8746                 goto error;
8747
8748         isl_seq_clr(bound->el, bound->size);
8749         isl_int_set_si(bound->el[0], -1);
8750
8751         snap = isl_tab_snap(tab);
8752         for (i = 0; i < n; ++i) {
8753                 int empty;
8754
8755                 isl_int_set_si(bound->el[1 + first + i], -1);
8756                 if (isl_tab_add_ineq(tab, bound->el) < 0)
8757                         goto error;
8758                 empty = tab->empty;
8759                 isl_int_set_si(bound->el[1 + first + i], 0);
8760                 if (isl_tab_rollback(tab, snap) < 0)
8761                         goto error;
8762
8763                 if (empty) {
8764                         signs[i] = 1;
8765                         continue;
8766                 }
8767
8768                 isl_int_set_si(bound->el[1 + first + i], 1);
8769                 if (isl_tab_add_ineq(tab, bound->el) < 0)
8770                         goto error;
8771                 empty = tab->empty;
8772                 isl_int_set_si(bound->el[1 + first + i], 0);
8773                 if (isl_tab_rollback(tab, snap) < 0)
8774                         goto error;
8775
8776                 signs[i] = empty ? -1 : 0;
8777         }
8778
8779         isl_tab_free(tab);
8780         isl_vec_free(bound);
8781         return 0;
8782 error:
8783         isl_tab_free(tab);
8784         isl_vec_free(bound);
8785         return -1;
8786 }
8787
8788 int isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset,
8789         enum isl_dim_type type, unsigned first, unsigned n, int *signs)
8790 {
8791         if (!bset || !signs)
8792                 return -1;
8793         isl_assert(bset->ctx, first + n <= isl_basic_set_dim(bset, type),
8794                 return -1);
8795
8796         first += pos(bset->dim, type) - 1;
8797         return isl_basic_set_vars_get_sign(bset, first, n, signs);
8798 }
8799
8800 /* Check if the given basic map is obviously single-valued.
8801  * In particular, for each output dimension, check that there is
8802  * an equality that defines the output dimension in terms of
8803  * earlier dimensions.
8804  */
8805 int isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
8806 {
8807         int i, j;
8808         unsigned total;
8809         unsigned n_out;
8810         unsigned o_out;
8811
8812         if (!bmap)
8813                 return -1;
8814
8815         total = 1 + isl_basic_map_total_dim(bmap);
8816         n_out = isl_basic_map_dim(bmap, isl_dim_out);
8817         o_out = isl_basic_map_offset(bmap, isl_dim_out);
8818
8819         for (i = 0; i < n_out; ++i) {
8820                 for (j = 0; j < bmap->n_eq; ++j) {
8821                         if (isl_int_is_zero(bmap->eq[j][o_out + i]))
8822                                 continue;
8823                         if (isl_seq_first_non_zero(bmap->eq[j] + o_out + i + 1,
8824                                                 total - (o_out + i + 1)) == -1)
8825                                 break;
8826                 }
8827                 if (j >= bmap->n_eq)
8828                         return 0;
8829         }
8830
8831         return 1;
8832 }
8833
8834 /* Check if the given map is obviously single-valued.
8835  */
8836 int isl_map_plain_is_single_valued(__isl_keep isl_map *map)
8837 {
8838         if (!map)
8839                 return -1;
8840         if (map->n == 0)
8841                 return 1;
8842         if (map->n >= 2)
8843                 return 0;
8844
8845         return isl_basic_map_plain_is_single_valued(map->p[0]);
8846 }
8847
8848 /* Check if the given map is single-valued.
8849  * We simply compute
8850  *
8851  *      M \circ M^-1
8852  *
8853  * and check if the result is a subset of the identity mapping.
8854  */
8855 int isl_map_is_single_valued(__isl_keep isl_map *map)
8856 {
8857         isl_space *dim;
8858         isl_map *test;
8859         isl_map *id;
8860         int sv;
8861
8862         sv = isl_map_plain_is_single_valued(map);
8863         if (sv < 0 || sv)
8864                 return sv;
8865
8866         test = isl_map_reverse(isl_map_copy(map));
8867         test = isl_map_apply_range(test, isl_map_copy(map));
8868
8869         dim = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
8870         id = isl_map_identity(dim);
8871
8872         sv = isl_map_is_subset(test, id);
8873
8874         isl_map_free(test);
8875         isl_map_free(id);
8876
8877         return sv;
8878 }
8879
8880 int isl_map_is_injective(__isl_keep isl_map *map)
8881 {
8882         int in;
8883
8884         map = isl_map_copy(map);
8885         map = isl_map_reverse(map);
8886         in = isl_map_is_single_valued(map);
8887         isl_map_free(map);
8888
8889         return in;
8890 }
8891
8892 /* Check if the given map is obviously injective.
8893  */
8894 int isl_map_plain_is_injective(__isl_keep isl_map *map)
8895 {
8896         int in;
8897
8898         map = isl_map_copy(map);
8899         map = isl_map_reverse(map);
8900         in = isl_map_plain_is_single_valued(map);
8901         isl_map_free(map);
8902
8903         return in;
8904 }
8905
8906 int isl_map_is_bijective(__isl_keep isl_map *map)
8907 {
8908         int sv;
8909
8910         sv = isl_map_is_single_valued(map);
8911         if (sv < 0 || !sv)
8912                 return sv;
8913
8914         return isl_map_is_injective(map);
8915 }
8916
8917 int isl_set_is_singleton(__isl_keep isl_set *set)
8918 {
8919         return isl_map_is_single_valued((isl_map *)set);
8920 }
8921
8922 int isl_map_is_translation(__isl_keep isl_map *map)
8923 {
8924         int ok;
8925         isl_set *delta;
8926
8927         delta = isl_map_deltas(isl_map_copy(map));
8928         ok = isl_set_is_singleton(delta);
8929         isl_set_free(delta);
8930
8931         return ok;
8932 }
8933
8934 static int unique(isl_int *p, unsigned pos, unsigned len)
8935 {
8936         if (isl_seq_first_non_zero(p, pos) != -1)
8937                 return 0;
8938         if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
8939                 return 0;
8940         return 1;
8941 }
8942
8943 int isl_basic_set_is_box(__isl_keep isl_basic_set *bset)
8944 {
8945         int i, j;
8946         unsigned nvar;
8947         unsigned ovar;
8948
8949         if (!bset)
8950                 return -1;
8951
8952         if (isl_basic_set_dim(bset, isl_dim_div) != 0)
8953                 return 0;
8954
8955         nvar = isl_basic_set_dim(bset, isl_dim_set);
8956         ovar = isl_space_offset(bset->dim, isl_dim_set);
8957         for (j = 0; j < nvar; ++j) {
8958                 int lower = 0, upper = 0;
8959                 for (i = 0; i < bset->n_eq; ++i) {
8960                         if (isl_int_is_zero(bset->eq[i][1 + ovar + j]))
8961                                 continue;
8962                         if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
8963                                 return 0;
8964                         break;
8965                 }
8966                 if (i < bset->n_eq)
8967                         continue;
8968                 for (i = 0; i < bset->n_ineq; ++i) {
8969                         if (isl_int_is_zero(bset->ineq[i][1 + ovar + j]))
8970                                 continue;
8971                         if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
8972                                 return 0;
8973                         if (isl_int_is_pos(bset->ineq[i][1 + ovar + j]))
8974                                 lower = 1;
8975                         else
8976                                 upper = 1;
8977                 }
8978                 if (!lower || !upper)
8979                         return 0;
8980         }
8981
8982         return 1;
8983 }
8984
8985 int isl_set_is_box(__isl_keep isl_set *set)
8986 {
8987         if (!set)
8988                 return -1;
8989         if (set->n != 1)
8990                 return 0;
8991
8992         return isl_basic_set_is_box(set->p[0]);
8993 }
8994
8995 int isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset)
8996 {
8997         if (!bset)
8998                 return -1;
8999         
9000         return isl_space_is_wrapping(bset->dim);
9001 }
9002
9003 int isl_set_is_wrapping(__isl_keep isl_set *set)
9004 {
9005         if (!set)
9006                 return -1;
9007         
9008         return isl_space_is_wrapping(set->dim);
9009 }
9010
9011 __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
9012 {
9013         bmap = isl_basic_map_cow(bmap);
9014         if (!bmap)
9015                 return NULL;
9016
9017         bmap->dim = isl_space_wrap(bmap->dim);
9018         if (!bmap->dim)
9019                 goto error;
9020
9021         bmap = isl_basic_map_finalize(bmap);
9022
9023         return (isl_basic_set *)bmap;
9024 error:
9025         isl_basic_map_free(bmap);
9026         return NULL;
9027 }
9028
9029 __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map)
9030 {
9031         int i;
9032
9033         map = isl_map_cow(map);
9034         if (!map)
9035                 return NULL;
9036
9037         for (i = 0; i < map->n; ++i) {
9038                 map->p[i] = (isl_basic_map *)isl_basic_map_wrap(map->p[i]);
9039                 if (!map->p[i])
9040                         goto error;
9041         }
9042         map->dim = isl_space_wrap(map->dim);
9043         if (!map->dim)
9044                 goto error;
9045
9046         return (isl_set *)map;
9047 error:
9048         isl_map_free(map);
9049         return NULL;
9050 }
9051
9052 __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset)
9053 {
9054         bset = isl_basic_set_cow(bset);
9055         if (!bset)
9056                 return NULL;
9057
9058         bset->dim = isl_space_unwrap(bset->dim);
9059         if (!bset->dim)
9060                 goto error;
9061
9062         bset = isl_basic_set_finalize(bset);
9063
9064         return (isl_basic_map *)bset;
9065 error:
9066         isl_basic_set_free(bset);
9067         return NULL;
9068 }
9069
9070 __isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set)
9071 {
9072         int i;
9073
9074         if (!set)
9075                 return NULL;
9076
9077         if (!isl_set_is_wrapping(set))
9078                 isl_die(set->ctx, isl_error_invalid, "not a wrapping set",
9079                         goto error);
9080
9081         set = isl_set_cow(set);
9082         if (!set)
9083                 return NULL;
9084
9085         for (i = 0; i < set->n; ++i) {
9086                 set->p[i] = (isl_basic_set *)isl_basic_set_unwrap(set->p[i]);
9087                 if (!set->p[i])
9088                         goto error;
9089         }
9090
9091         set->dim = isl_space_unwrap(set->dim);
9092         if (!set->dim)
9093                 goto error;
9094
9095         return (isl_map *)set;
9096 error:
9097         isl_set_free(set);
9098         return NULL;
9099 }
9100
9101 __isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
9102         enum isl_dim_type type)
9103 {
9104         if (!bmap)
9105                 return NULL;
9106
9107         if (!isl_space_is_named_or_nested(bmap->dim, type))
9108                 return bmap;
9109
9110         bmap = isl_basic_map_cow(bmap);
9111         if (!bmap)
9112                 return NULL;
9113
9114         bmap->dim = isl_space_reset(bmap->dim, type);
9115         if (!bmap->dim)
9116                 goto error;
9117
9118         bmap = isl_basic_map_finalize(bmap);
9119
9120         return bmap;
9121 error:
9122         isl_basic_map_free(bmap);
9123         return NULL;
9124 }
9125
9126 __isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
9127         enum isl_dim_type type)
9128 {
9129         int i;
9130
9131         if (!map)
9132                 return NULL;
9133
9134         if (!isl_space_is_named_or_nested(map->dim, type))
9135                 return map;
9136
9137         map = isl_map_cow(map);
9138         if (!map)
9139                 return NULL;
9140
9141         for (i = 0; i < map->n; ++i) {
9142                 map->p[i] = isl_basic_map_reset(map->p[i], type);
9143                 if (!map->p[i])
9144                         goto error;
9145         }
9146         map->dim = isl_space_reset(map->dim, type);
9147         if (!map->dim)
9148                 goto error;
9149
9150         return map;
9151 error:
9152         isl_map_free(map);
9153         return NULL;
9154 }
9155
9156 __isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
9157 {
9158         if (!bmap)
9159                 return NULL;
9160
9161         if (!bmap->dim->nested[0] && !bmap->dim->nested[1])
9162                 return bmap;
9163
9164         bmap = isl_basic_map_cow(bmap);
9165         if (!bmap)
9166                 return NULL;
9167
9168         bmap->dim = isl_space_flatten(bmap->dim);
9169         if (!bmap->dim)
9170                 goto error;
9171
9172         bmap = isl_basic_map_finalize(bmap);
9173
9174         return bmap;
9175 error:
9176         isl_basic_map_free(bmap);
9177         return NULL;
9178 }
9179
9180 __isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset)
9181 {
9182         return (isl_basic_set *)isl_basic_map_flatten((isl_basic_map *)bset);
9183 }
9184
9185 __isl_give isl_basic_map *isl_basic_map_flatten_domain(
9186         __isl_take isl_basic_map *bmap)
9187 {
9188         if (!bmap)
9189                 return NULL;
9190
9191         if (!bmap->dim->nested[0])
9192                 return bmap;
9193
9194         bmap = isl_basic_map_cow(bmap);
9195         if (!bmap)
9196                 return NULL;
9197
9198         bmap->dim = isl_space_flatten_domain(bmap->dim);
9199         if (!bmap->dim)
9200                 goto error;
9201
9202         bmap = isl_basic_map_finalize(bmap);
9203
9204         return bmap;
9205 error:
9206         isl_basic_map_free(bmap);
9207         return NULL;
9208 }
9209
9210 __isl_give isl_basic_map *isl_basic_map_flatten_range(
9211         __isl_take isl_basic_map *bmap)
9212 {
9213         if (!bmap)
9214                 return NULL;
9215
9216         if (!bmap->dim->nested[1])
9217                 return bmap;
9218
9219         bmap = isl_basic_map_cow(bmap);
9220         if (!bmap)
9221                 return NULL;
9222
9223         bmap->dim = isl_space_flatten_range(bmap->dim);
9224         if (!bmap->dim)
9225                 goto error;
9226
9227         bmap = isl_basic_map_finalize(bmap);
9228
9229         return bmap;
9230 error:
9231         isl_basic_map_free(bmap);
9232         return NULL;
9233 }
9234
9235 __isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
9236 {
9237         int i;
9238
9239         if (!map)
9240                 return NULL;
9241
9242         if (!map->dim->nested[0] && !map->dim->nested[1])
9243                 return map;
9244
9245         map = isl_map_cow(map);
9246         if (!map)
9247                 return NULL;
9248
9249         for (i = 0; i < map->n; ++i) {
9250                 map->p[i] = isl_basic_map_flatten(map->p[i]);
9251                 if (!map->p[i])
9252                         goto error;
9253         }
9254         map->dim = isl_space_flatten(map->dim);
9255         if (!map->dim)
9256                 goto error;
9257
9258         return map;
9259 error:
9260         isl_map_free(map);
9261         return NULL;
9262 }
9263
9264 __isl_give isl_set *isl_set_flatten(__isl_take isl_set *set)
9265 {
9266         return (isl_set *)isl_map_flatten((isl_map *)set);
9267 }
9268
9269 __isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set)
9270 {
9271         isl_space *dim, *flat_dim;
9272         isl_map *map;
9273
9274         dim = isl_set_get_space(set);
9275         flat_dim = isl_space_flatten(isl_space_copy(dim));
9276         map = isl_map_identity(isl_space_join(isl_space_reverse(dim), flat_dim));
9277         map = isl_map_intersect_domain(map, set);
9278
9279         return map;
9280 }
9281
9282 __isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
9283 {
9284         int i;
9285
9286         if (!map)
9287                 return NULL;
9288
9289         if (!map->dim->nested[0])
9290                 return map;
9291
9292         map = isl_map_cow(map);
9293         if (!map)
9294                 return NULL;
9295
9296         for (i = 0; i < map->n; ++i) {
9297                 map->p[i] = isl_basic_map_flatten_domain(map->p[i]);
9298                 if (!map->p[i])
9299                         goto error;
9300         }
9301         map->dim = isl_space_flatten_domain(map->dim);
9302         if (!map->dim)
9303                 goto error;
9304
9305         return map;
9306 error:
9307         isl_map_free(map);
9308         return NULL;
9309 }
9310
9311 __isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
9312 {
9313         int i;
9314
9315         if (!map)
9316                 return NULL;
9317
9318         if (!map->dim->nested[1])
9319                 return map;
9320
9321         map = isl_map_cow(map);
9322         if (!map)
9323                 return NULL;
9324
9325         for (i = 0; i < map->n; ++i) {
9326                 map->p[i] = isl_basic_map_flatten_range(map->p[i]);
9327                 if (!map->p[i])
9328                         goto error;
9329         }
9330         map->dim = isl_space_flatten_range(map->dim);
9331         if (!map->dim)
9332                 goto error;
9333
9334         return map;
9335 error:
9336         isl_map_free(map);
9337         return NULL;
9338 }
9339
9340 /* Reorder the dimensions of "bmap" according to the given dim_map
9341  * and set the dimension specification to "dim".
9342  */
9343 __isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
9344         __isl_take isl_space *dim, __isl_take struct isl_dim_map *dim_map)
9345 {
9346         isl_basic_map *res;
9347         unsigned flags;
9348
9349         bmap = isl_basic_map_cow(bmap);
9350         if (!bmap || !dim || !dim_map)
9351                 goto error;
9352
9353         flags = bmap->flags;
9354         ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL);
9355         ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED);
9356         ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS);
9357         res = isl_basic_map_alloc_space(dim,
9358                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
9359         res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
9360         if (res)
9361                 res->flags = flags;
9362         res = isl_basic_map_finalize(res);
9363         return res;
9364 error:
9365         free(dim_map);
9366         isl_basic_map_free(bmap);
9367         isl_space_free(dim);
9368         return NULL;
9369 }
9370
9371 /* Reorder the dimensions of "map" according to given reordering.
9372  */
9373 __isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
9374         __isl_take isl_reordering *r)
9375 {
9376         int i;
9377         struct isl_dim_map *dim_map;
9378
9379         map = isl_map_cow(map);
9380         dim_map = isl_dim_map_from_reordering(r);
9381         if (!map || !r || !dim_map)
9382                 goto error;
9383
9384         for (i = 0; i < map->n; ++i) {
9385                 struct isl_dim_map *dim_map_i;
9386
9387                 dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
9388
9389                 map->p[i] = isl_basic_map_realign(map->p[i],
9390                                             isl_space_copy(r->dim), dim_map_i);
9391
9392                 if (!map->p[i])
9393                         goto error;
9394         }
9395
9396         map = isl_map_reset_space(map, isl_space_copy(r->dim));
9397
9398         isl_reordering_free(r);
9399         free(dim_map);
9400         return map;
9401 error:
9402         free(dim_map);
9403         isl_map_free(map);
9404         isl_reordering_free(r);
9405         return NULL;
9406 }
9407
9408 __isl_give isl_set *isl_set_realign(__isl_take isl_set *set,
9409         __isl_take isl_reordering *r)
9410 {
9411         return (isl_set *)isl_map_realign((isl_map *)set, r);
9412 }
9413
9414 __isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
9415         __isl_take isl_space *model)
9416 {
9417         isl_ctx *ctx;
9418
9419         if (!map || !model)
9420                 goto error;
9421
9422         ctx = isl_space_get_ctx(model);
9423         if (!isl_space_has_named_params(model))
9424                 isl_die(ctx, isl_error_invalid,
9425                         "model has unnamed parameters", goto error);
9426         if (!isl_space_has_named_params(map->dim))
9427                 isl_die(ctx, isl_error_invalid,
9428                         "relation has unnamed parameters", goto error);
9429         if (!isl_space_match(map->dim, isl_dim_param, model, isl_dim_param)) {
9430                 isl_reordering *exp;
9431
9432                 model = isl_space_drop_dims(model, isl_dim_in,
9433                                         0, isl_space_dim(model, isl_dim_in));
9434                 model = isl_space_drop_dims(model, isl_dim_out,
9435                                         0, isl_space_dim(model, isl_dim_out));
9436                 exp = isl_parameter_alignment_reordering(map->dim, model);
9437                 exp = isl_reordering_extend_space(exp, isl_map_get_space(map));
9438                 map = isl_map_realign(map, exp);
9439         }
9440
9441         isl_space_free(model);
9442         return map;
9443 error:
9444         isl_space_free(model);
9445         isl_map_free(map);
9446         return NULL;
9447 }
9448
9449 __isl_give isl_set *isl_set_align_params(__isl_take isl_set *set,
9450         __isl_take isl_space *model)
9451 {
9452         return isl_map_align_params(set, model);
9453 }
9454
9455 __isl_give isl_mat *isl_basic_map_equalities_matrix(
9456                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
9457                 enum isl_dim_type c2, enum isl_dim_type c3,
9458                 enum isl_dim_type c4, enum isl_dim_type c5)
9459 {
9460         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
9461         struct isl_mat *mat;
9462         int i, j, k;
9463         int pos;
9464
9465         if (!bmap)
9466                 return NULL;
9467         mat = isl_mat_alloc(bmap->ctx, bmap->n_eq,
9468                                 isl_basic_map_total_dim(bmap) + 1);
9469         if (!mat)
9470                 return NULL;
9471         for (i = 0; i < bmap->n_eq; ++i)
9472                 for (j = 0, pos = 0; j < 5; ++j) {
9473                         int off = isl_basic_map_offset(bmap, c[j]);
9474                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9475                                 isl_int_set(mat->row[i][pos],
9476                                             bmap->eq[i][off + k]);
9477                                 ++pos;
9478                         }
9479                 }
9480
9481         return mat;
9482 }
9483
9484 __isl_give isl_mat *isl_basic_map_inequalities_matrix(
9485                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
9486                 enum isl_dim_type c2, enum isl_dim_type c3,
9487                 enum isl_dim_type c4, enum isl_dim_type c5)
9488 {
9489         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
9490         struct isl_mat *mat;
9491         int i, j, k;
9492         int pos;
9493
9494         if (!bmap)
9495                 return NULL;
9496         mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq,
9497                                 isl_basic_map_total_dim(bmap) + 1);
9498         if (!mat)
9499                 return NULL;
9500         for (i = 0; i < bmap->n_ineq; ++i)
9501                 for (j = 0, pos = 0; j < 5; ++j) {
9502                         int off = isl_basic_map_offset(bmap, c[j]);
9503                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9504                                 isl_int_set(mat->row[i][pos],
9505                                             bmap->ineq[i][off + k]);
9506                                 ++pos;
9507                         }
9508                 }
9509
9510         return mat;
9511 }
9512
9513 __isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
9514         __isl_take isl_space *dim,
9515         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
9516         enum isl_dim_type c2, enum isl_dim_type c3,
9517         enum isl_dim_type c4, enum isl_dim_type c5)
9518 {
9519         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
9520         isl_basic_map *bmap;
9521         unsigned total;
9522         unsigned extra;
9523         int i, j, k, l;
9524         int pos;
9525
9526         if (!dim || !eq || !ineq)
9527                 goto error;
9528
9529         if (eq->n_col != ineq->n_col)
9530                 isl_die(dim->ctx, isl_error_invalid,
9531                         "equalities and inequalities matrices should have "
9532                         "same number of columns", goto error);
9533
9534         total = 1 + isl_space_dim(dim, isl_dim_all);
9535
9536         if (eq->n_col < total)
9537                 isl_die(dim->ctx, isl_error_invalid,
9538                         "number of columns too small", goto error);
9539
9540         extra = eq->n_col - total;
9541
9542         bmap = isl_basic_map_alloc_space(isl_space_copy(dim), extra,
9543                                        eq->n_row, ineq->n_row);
9544         if (!bmap)
9545                 goto error;
9546         for (i = 0; i < extra; ++i) {
9547                 k = isl_basic_map_alloc_div(bmap);
9548                 if (k < 0)
9549                         goto error;
9550                 isl_int_set_si(bmap->div[k][0], 0);
9551         }
9552         for (i = 0; i < eq->n_row; ++i) {
9553                 l = isl_basic_map_alloc_equality(bmap);
9554                 if (l < 0)
9555                         goto error;
9556                 for (j = 0, pos = 0; j < 5; ++j) {
9557                         int off = isl_basic_map_offset(bmap, c[j]);
9558                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9559                                 isl_int_set(bmap->eq[l][off + k], 
9560                                             eq->row[i][pos]);
9561                                 ++pos;
9562                         }
9563                 }
9564         }
9565         for (i = 0; i < ineq->n_row; ++i) {
9566                 l = isl_basic_map_alloc_inequality(bmap);
9567                 if (l < 0)
9568                         goto error;
9569                 for (j = 0, pos = 0; j < 5; ++j) {
9570                         int off = isl_basic_map_offset(bmap, c[j]);
9571                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9572                                 isl_int_set(bmap->ineq[l][off + k], 
9573                                             ineq->row[i][pos]);
9574                                 ++pos;
9575                         }
9576                 }
9577         }
9578
9579         isl_space_free(dim);
9580         isl_mat_free(eq);
9581         isl_mat_free(ineq);
9582
9583         return bmap;
9584 error:
9585         isl_space_free(dim);
9586         isl_mat_free(eq);
9587         isl_mat_free(ineq);
9588         return NULL;
9589 }
9590
9591 __isl_give isl_mat *isl_basic_set_equalities_matrix(
9592         __isl_keep isl_basic_set *bset, enum isl_dim_type c1,
9593         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
9594 {
9595         return isl_basic_map_equalities_matrix((isl_basic_map *)bset,
9596                                                 c1, c2, c3, c4, isl_dim_in);
9597 }
9598
9599 __isl_give isl_mat *isl_basic_set_inequalities_matrix(
9600         __isl_keep isl_basic_set *bset, enum isl_dim_type c1,
9601         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
9602 {
9603         return isl_basic_map_inequalities_matrix((isl_basic_map *)bset,
9604                                                  c1, c2, c3, c4, isl_dim_in);
9605 }
9606
9607 __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices(
9608         __isl_take isl_space *dim,
9609         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
9610         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
9611 {
9612         return (isl_basic_set*)
9613             isl_basic_map_from_constraint_matrices(dim, eq, ineq,
9614                                                    c1, c2, c3, c4, isl_dim_in);
9615 }
9616
9617 int isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
9618 {
9619         if (!bmap)
9620                 return -1;
9621         
9622         return isl_space_can_zip(bmap->dim);
9623 }
9624
9625 int isl_map_can_zip(__isl_keep isl_map *map)
9626 {
9627         if (!map)
9628                 return -1;
9629         
9630         return isl_space_can_zip(map->dim);
9631 }
9632
9633 /* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
9634  * (A -> C) -> (B -> D).
9635  */
9636 __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
9637 {
9638         unsigned pos;
9639         unsigned n1;
9640         unsigned n2;
9641
9642         if (!bmap)
9643                 return NULL;
9644
9645         if (!isl_basic_map_can_zip(bmap))
9646                 isl_die(bmap->ctx, isl_error_invalid,
9647                         "basic map cannot be zipped", goto error);
9648         pos = isl_basic_map_offset(bmap, isl_dim_in) +
9649                 isl_space_dim(bmap->dim->nested[0], isl_dim_in);
9650         n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
9651         n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
9652         bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
9653         if (!bmap)
9654                 return NULL;
9655         bmap->dim = isl_space_zip(bmap->dim);
9656         if (!bmap->dim)
9657                 goto error;
9658         return bmap;
9659 error:
9660         isl_basic_map_free(bmap);
9661         return NULL;
9662 }
9663
9664 /* Given a map (A -> B) -> (C -> D), return the corresponding map
9665  * (A -> C) -> (B -> D).
9666  */
9667 __isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
9668 {
9669         int i;
9670
9671         if (!map)
9672                 return NULL;
9673
9674         if (!isl_map_can_zip(map))
9675                 isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",
9676                         goto error);
9677
9678         map = isl_map_cow(map);
9679         if (!map)
9680                 return NULL;
9681
9682         for (i = 0; i < map->n; ++i) {
9683                 map->p[i] = isl_basic_map_zip(map->p[i]);
9684                 if (!map->p[i])
9685                         goto error;
9686         }
9687
9688         map->dim = isl_space_zip(map->dim);
9689         if (!map->dim)
9690                 goto error;
9691
9692         return map;
9693 error:
9694         isl_map_free(map);
9695         return NULL;
9696 }
9697
9698 /* Construct a basic map mapping the domain of the affine expression
9699  * to a one-dimensional range prescribed by the affine expression.
9700  */
9701 __isl_give isl_basic_map *isl_basic_map_from_aff(__isl_take isl_aff *aff)
9702 {
9703         int k;
9704         int pos;
9705         isl_local_space *ls;
9706         isl_basic_map *bmap;
9707
9708         if (!aff)
9709                 return NULL;
9710
9711         ls = isl_aff_get_local_space(aff);
9712         bmap = isl_basic_map_from_local_space(ls);
9713         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
9714         k = isl_basic_map_alloc_equality(bmap);
9715         if (k < 0)
9716                 goto error;
9717
9718         pos = isl_basic_map_offset(bmap, isl_dim_out);
9719         isl_seq_cpy(bmap->eq[k], aff->v->el + 1, pos);
9720         isl_int_neg(bmap->eq[k][pos], aff->v->el[0]);
9721         isl_seq_cpy(bmap->eq[k] + pos + 1, aff->v->el + 1 + pos,
9722                     aff->v->size - (pos + 1));
9723
9724         isl_aff_free(aff);
9725         bmap = isl_basic_map_finalize(bmap);
9726         return bmap;
9727 error:
9728         isl_aff_free(aff);
9729         isl_basic_map_free(bmap);
9730         return NULL;
9731 }
9732
9733 /* Construct a basic map mapping the domain the multi-affine expression
9734  * to its range, with each dimension in the range equated to the
9735  * corresponding affine expression.
9736  */
9737 __isl_give isl_basic_map *isl_basic_map_from_multi_aff(
9738         __isl_take isl_multi_aff *maff)
9739 {
9740         int i;
9741         isl_space *space;
9742         isl_basic_map *bmap;
9743
9744         if (!maff)
9745                 return NULL;
9746
9747         if (isl_space_dim(maff->space, isl_dim_out) != maff->n)
9748                 isl_die(isl_multi_aff_get_ctx(maff), isl_error_internal,
9749                         "invalid space", return isl_multi_aff_free(maff));
9750
9751         space = isl_space_domain(isl_multi_aff_get_space(maff));
9752         bmap = isl_basic_map_universe(isl_space_from_domain(space));
9753
9754         for (i = 0; i < maff->n; ++i) {
9755                 isl_aff *aff;
9756                 isl_basic_map *bmap_i;
9757
9758                 aff = isl_aff_copy(maff->p[i]);
9759                 bmap_i = isl_basic_map_from_aff(aff);
9760
9761                 bmap = isl_basic_map_flat_range_product(bmap, bmap_i);
9762         }
9763
9764         bmap = isl_basic_map_reset_space(bmap, isl_multi_aff_get_space(maff));
9765
9766         isl_multi_aff_free(maff);
9767         return bmap;
9768 }
9769
9770 /* Construct a basic map mapping a domain in the given space to
9771  * to an n-dimensional range, with n the number of elements in the list,
9772  * where each coordinate in the range is prescribed by the
9773  * corresponding affine expression.
9774  * The domains of all affine expressions in the list are assumed to match
9775  * domain_dim.
9776  */
9777 __isl_give isl_basic_map *isl_basic_map_from_aff_list(
9778         __isl_take isl_space *domain_dim, __isl_take isl_aff_list *list)
9779 {
9780         int i;
9781         isl_space *dim;
9782         isl_basic_map *bmap;
9783
9784         if (!list)
9785                 return NULL;
9786
9787         dim = isl_space_from_domain(domain_dim);
9788         bmap = isl_basic_map_universe(dim);
9789
9790         for (i = 0; i < list->n; ++i) {
9791                 isl_aff *aff;
9792                 isl_basic_map *bmap_i;
9793
9794                 aff = isl_aff_copy(list->p[i]);
9795                 bmap_i = isl_basic_map_from_aff(aff);
9796
9797                 bmap = isl_basic_map_flat_range_product(bmap, bmap_i);
9798         }
9799
9800         isl_aff_list_free(list);
9801         return bmap;
9802 }
9803
9804 __isl_give isl_set *isl_set_equate(__isl_take isl_set *set,
9805         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
9806 {
9807         return isl_map_equate(set, type1, pos1, type2, pos2);
9808 }
9809
9810 /* Add a constraint imposing that the given two dimensions are equal.
9811  */
9812 __isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
9813         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
9814 {
9815         isl_basic_map *bmap = NULL;
9816         int i;
9817
9818         if (!map)
9819                 return NULL;
9820
9821         if (pos1 >= isl_map_dim(map, type1))
9822                 isl_die(map->ctx, isl_error_invalid,
9823                         "index out of bounds", goto error);
9824         if (pos2 >= isl_map_dim(map, type2))
9825                 isl_die(map->ctx, isl_error_invalid,
9826                         "index out of bounds", goto error);
9827
9828         bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
9829         i = isl_basic_map_alloc_equality(bmap);
9830         if (i < 0)
9831                 goto error;
9832         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
9833         pos1 += isl_basic_map_offset(bmap, type1);
9834         pos2 += isl_basic_map_offset(bmap, type2);
9835         isl_int_set_si(bmap->eq[i][pos1], -1);
9836         isl_int_set_si(bmap->eq[i][pos2], 1);
9837         bmap = isl_basic_map_finalize(bmap);
9838
9839         map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
9840
9841         return map;
9842 error:
9843         isl_basic_map_free(bmap);
9844         isl_map_free(map);
9845         return NULL;
9846 }
9847
9848 /* Add a constraint imposing that the given two dimensions have opposite values.
9849  */
9850 __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
9851         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
9852 {
9853         isl_basic_map *bmap = NULL;
9854         int i;
9855
9856         if (!map)
9857                 return NULL;
9858
9859         if (pos1 >= isl_map_dim(map, type1))
9860                 isl_die(map->ctx, isl_error_invalid,
9861                         "index out of bounds", goto error);
9862         if (pos2 >= isl_map_dim(map, type2))
9863                 isl_die(map->ctx, isl_error_invalid,
9864                         "index out of bounds", goto error);
9865
9866         bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
9867         i = isl_basic_map_alloc_equality(bmap);
9868         if (i < 0)
9869                 goto error;
9870         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
9871         pos1 += isl_basic_map_offset(bmap, type1);
9872         pos2 += isl_basic_map_offset(bmap, type2);
9873         isl_int_set_si(bmap->eq[i][pos1], 1);
9874         isl_int_set_si(bmap->eq[i][pos2], 1);
9875         bmap = isl_basic_map_finalize(bmap);
9876
9877         map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
9878
9879         return map;
9880 error:
9881         isl_basic_map_free(bmap);
9882         isl_map_free(map);
9883         return NULL;
9884 }
9885
9886 __isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
9887         int pos)
9888 {
9889         isl_aff *div;
9890         isl_local_space *ls;
9891
9892         if (!bmap)
9893                 return NULL;
9894
9895         if (!isl_basic_map_divs_known(bmap))
9896                 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
9897                         "some divs are unknown", return NULL);
9898
9899         ls = isl_basic_map_get_local_space(bmap);
9900         div = isl_local_space_get_div(ls, pos);
9901         isl_local_space_free(ls);
9902
9903         return div;
9904 }
9905
9906 __isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset,
9907         int pos)
9908 {
9909         return isl_basic_map_get_div(bset, pos);
9910 }
9911
9912 /* Plug in "subs" for dimension "type", "pos" of "bset".
9913  *
9914  * Let i be the dimension to replace and let "subs" be of the form
9915  *
9916  *      f/d
9917  *
9918  * Any integer division with a non-zero coefficient for i,
9919  *
9920  *      floor((a i + g)/m)
9921  *
9922  * is replaced by
9923  *
9924  *      floor((a f + d g)/(m d))
9925  *
9926  * Constraints of the form
9927  *
9928  *      a i + g
9929  *
9930  * are replaced by
9931  *
9932  *      a f + d g
9933  */
9934 __isl_give isl_basic_set *isl_basic_set_substitute(
9935         __isl_take isl_basic_set *bset,
9936         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
9937 {
9938         int i;
9939         isl_int v;
9940         isl_ctx *ctx;
9941
9942         if (bset && isl_basic_set_plain_is_empty(bset))
9943                 return bset;
9944
9945         bset = isl_basic_set_cow(bset);
9946         if (!bset || !subs)
9947                 goto error;
9948
9949         ctx = isl_basic_set_get_ctx(bset);
9950         if (!isl_space_is_equal(bset->dim, subs->ls->dim))
9951                 isl_die(ctx, isl_error_invalid,
9952                         "spaces don't match", goto error);
9953         if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
9954                 isl_die(ctx, isl_error_unsupported,
9955                         "cannot handle divs yet", goto error);
9956
9957         pos += isl_basic_set_offset(bset, type);
9958
9959         isl_int_init(v);
9960
9961         for (i = 0; i < bset->n_eq; ++i) {
9962                 if (isl_int_is_zero(bset->eq[i][pos]))
9963                         continue;
9964                 isl_int_set(v, bset->eq[i][pos]);
9965                 isl_int_set_si(bset->eq[i][pos], 0);
9966                 isl_seq_combine(bset->eq[i], subs->v->el[0], bset->eq[i],
9967                                 v, subs->v->el + 1, subs->v->size - 1);
9968         }
9969
9970         for (i = 0; i < bset->n_ineq; ++i) {
9971                 if (isl_int_is_zero(bset->ineq[i][pos]))
9972                         continue;
9973                 isl_int_set(v, bset->ineq[i][pos]);
9974                 isl_int_set_si(bset->ineq[i][pos], 0);
9975                 isl_seq_combine(bset->ineq[i], subs->v->el[0], bset->ineq[i],
9976                                 v, subs->v->el + 1, subs->v->size - 1);
9977         }
9978
9979         for (i = 0; i < bset->n_div; ++i) {
9980                 if (isl_int_is_zero(bset->div[i][1 + pos]))
9981                         continue;
9982                 isl_int_set(v, bset->div[i][1 + pos]);
9983                 isl_int_set_si(bset->div[i][1 + pos], 0);
9984                 isl_seq_combine(bset->div[i] + 1,
9985                                 subs->v->el[0], bset->div[i] + 1,
9986                                 v, subs->v->el + 1, subs->v->size - 1);
9987                 isl_int_mul(bset->div[i][0], bset->div[i][0], subs->v->el[0]);
9988         }
9989
9990         isl_int_clear(v);
9991
9992         bset = isl_basic_set_simplify(bset);
9993         return isl_basic_set_finalize(bset);
9994 error:
9995         isl_basic_set_free(bset);
9996         return NULL;
9997 }
9998
9999 /* Plug in "subs" for dimension "type", "pos" of "set".
10000  */
10001 __isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
10002         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
10003 {
10004         int i;
10005
10006         if (set && isl_set_plain_is_empty(set))
10007                 return set;
10008
10009         set = isl_set_cow(set);
10010         if (!set || !subs)
10011                 goto error;
10012
10013         for (i = set->n - 1; i >= 0; --i) {
10014                 set->p[i] = isl_basic_set_substitute(set->p[i], type, pos, subs);
10015                 if (remove_if_empty(set, i) < 0)
10016                         goto error;
10017         }
10018
10019         return set;
10020 error:
10021         isl_set_free(set);
10022         return NULL;
10023 }