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