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