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