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