isl_basic_set_total_dim: handle NULL input
[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 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         res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
2700         return isl_basic_map_finalize(res);
2701 }
2702
2703 __isl_give isl_basic_map *isl_basic_map_add(__isl_take isl_basic_map *bmap,
2704                 enum isl_dim_type type, unsigned n)
2705 {
2706         if (!bmap)
2707                 return NULL;
2708         return isl_basic_map_insert(bmap, type,
2709                                         isl_basic_map_dim(bmap, type), n);
2710 }
2711
2712 __isl_give isl_basic_set *isl_basic_set_add(__isl_take isl_basic_set *bset,
2713                 enum isl_dim_type type, unsigned n)
2714 {
2715         if (!bset)
2716                 return NULL;
2717         isl_assert(bset->ctx, type != isl_dim_in, goto error);
2718         return (isl_basic_set *)isl_basic_map_add((isl_basic_map *)bset, type, n);
2719 error:
2720         isl_basic_set_free(bset);
2721         return NULL;
2722 }
2723
2724 static __isl_give isl_map *map_space_reset(__isl_take isl_map *map,
2725         enum isl_dim_type type)
2726 {
2727         isl_space *space;
2728
2729         if (!map || !isl_space_is_named_or_nested(map->dim, type))
2730                 return map;
2731
2732         space = isl_map_get_space(map);
2733         space = isl_space_reset(space, type);
2734         map = isl_map_reset_space(map, space);
2735         return map;
2736 }
2737
2738 __isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map,
2739                 enum isl_dim_type type, unsigned pos, unsigned n)
2740 {
2741         int i;
2742
2743         if (n == 0)
2744                 return map_space_reset(map, type);
2745
2746         map = isl_map_cow(map);
2747         if (!map)
2748                 return NULL;
2749
2750         map->dim = isl_space_insert_dims(map->dim, type, pos, n);
2751         if (!map->dim)
2752                 goto error;
2753
2754         for (i = 0; i < map->n; ++i) {
2755                 map->p[i] = isl_basic_map_insert(map->p[i], type, pos, n);
2756                 if (!map->p[i])
2757                         goto error;
2758         }
2759
2760         return map;
2761 error:
2762         isl_map_free(map);
2763         return NULL;
2764 }
2765
2766 __isl_give isl_set *isl_set_insert_dims(__isl_take isl_set *set,
2767                 enum isl_dim_type type, unsigned pos, unsigned n)
2768 {
2769         return isl_map_insert_dims(set, type, pos, n);
2770 }
2771
2772 __isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map,
2773                 enum isl_dim_type type, unsigned n)
2774 {
2775         if (!map)
2776                 return NULL;
2777         return isl_map_insert_dims(map, type, isl_map_dim(map, type), n);
2778 }
2779
2780 __isl_give isl_set *isl_set_add_dims(__isl_take isl_set *set,
2781                 enum isl_dim_type type, unsigned n)
2782 {
2783         if (!set)
2784                 return NULL;
2785         isl_assert(set->ctx, type != isl_dim_in, goto error);
2786         return (isl_set *)isl_map_add_dims((isl_map *)set, type, n);
2787 error:
2788         isl_set_free(set);
2789         return NULL;
2790 }
2791
2792 __isl_give isl_basic_map *isl_basic_map_move_dims(
2793         __isl_take isl_basic_map *bmap,
2794         enum isl_dim_type dst_type, unsigned dst_pos,
2795         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2796 {
2797         struct isl_dim_map *dim_map;
2798         struct isl_basic_map *res;
2799         enum isl_dim_type t;
2800         unsigned total, off;
2801
2802         if (!bmap)
2803                 return NULL;
2804         if (n == 0)
2805                 return bmap;
2806
2807         isl_assert(bmap->ctx, src_pos + n <= isl_basic_map_dim(bmap, src_type),
2808                 goto error);
2809
2810         if (dst_type == src_type && dst_pos == src_pos)
2811                 return bmap;
2812
2813         isl_assert(bmap->ctx, dst_type != src_type, goto error);
2814
2815         if (pos(bmap->dim, dst_type) + dst_pos ==
2816             pos(bmap->dim, src_type) + src_pos +
2817                                             ((src_type < dst_type) ? n : 0)) {
2818                 bmap = isl_basic_map_cow(bmap);
2819                 if (!bmap)
2820                         return NULL;
2821
2822                 bmap->dim = isl_space_move_dims(bmap->dim, dst_type, dst_pos,
2823                                                 src_type, src_pos, n);
2824                 if (!bmap->dim)
2825                         goto error;
2826
2827                 bmap = isl_basic_map_finalize(bmap);
2828
2829                 return bmap;
2830         }
2831
2832         total = isl_basic_map_total_dim(bmap);
2833         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2834
2835         off = 0;
2836         for (t = isl_dim_param; t <= isl_dim_out; ++t) {
2837                 unsigned size = isl_space_dim(bmap->dim, t);
2838                 if (t == dst_type) {
2839                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2840                                             0, dst_pos, off);
2841                         off += dst_pos;
2842                         isl_dim_map_dim_range(dim_map, bmap->dim, src_type,
2843                                             src_pos, n, off);
2844                         off += n;
2845                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2846                                             dst_pos, size - dst_pos, off);
2847                         off += size - dst_pos;
2848                 } else if (t == src_type) {
2849                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2850                                             0, src_pos, off);
2851                         off += src_pos;
2852                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2853                                         src_pos + n, size - src_pos - n, off);
2854                         off += size - src_pos - n;
2855                 } else {
2856                         isl_dim_map_dim(dim_map, bmap->dim, t, off);
2857                         off += size;
2858                 }
2859         }
2860         isl_dim_map_div(dim_map, bmap, off);
2861
2862         res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
2863                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
2864         bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
2865
2866         bmap->dim = isl_space_move_dims(bmap->dim, dst_type, dst_pos,
2867                                         src_type, src_pos, n);
2868         if (!bmap->dim)
2869                 goto error;
2870
2871         ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
2872         bmap = isl_basic_map_gauss(bmap, NULL);
2873         bmap = isl_basic_map_finalize(bmap);
2874
2875         return bmap;
2876 error:
2877         isl_basic_map_free(bmap);
2878         return NULL;
2879 }
2880
2881 __isl_give isl_basic_set *isl_basic_set_move_dims(__isl_take isl_basic_set *bset,
2882         enum isl_dim_type dst_type, unsigned dst_pos,
2883         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2884 {
2885         return (isl_basic_set *)isl_basic_map_move_dims(
2886                 (isl_basic_map *)bset, dst_type, dst_pos, src_type, src_pos, n);
2887 }
2888
2889 __isl_give isl_set *isl_set_move_dims(__isl_take isl_set *set,
2890         enum isl_dim_type dst_type, unsigned dst_pos,
2891         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2892 {
2893         if (!set)
2894                 return NULL;
2895         isl_assert(set->ctx, dst_type != isl_dim_in, goto error);
2896         return (isl_set *)isl_map_move_dims((isl_map *)set, dst_type, dst_pos,
2897                                         src_type, src_pos, n);
2898 error:
2899         isl_set_free(set);
2900         return NULL;
2901 }
2902
2903 __isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
2904         enum isl_dim_type dst_type, unsigned dst_pos,
2905         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2906 {
2907         int i;
2908
2909         if (!map)
2910                 return NULL;
2911         if (n == 0)
2912                 return map;
2913
2914         isl_assert(map->ctx, src_pos + n <= isl_map_dim(map, src_type),
2915                 goto error);
2916
2917         if (dst_type == src_type && dst_pos == src_pos)
2918                 return map;
2919
2920         isl_assert(map->ctx, dst_type != src_type, goto error);
2921
2922         map = isl_map_cow(map);
2923         if (!map)
2924                 return NULL;
2925
2926         map->dim = isl_space_move_dims(map->dim, dst_type, dst_pos, src_type, src_pos, n);
2927         if (!map->dim)
2928                 goto error;
2929
2930         for (i = 0; i < map->n; ++i) {
2931                 map->p[i] = isl_basic_map_move_dims(map->p[i],
2932                                                 dst_type, dst_pos,
2933                                                 src_type, src_pos, n);
2934                 if (!map->p[i])
2935                         goto error;
2936         }
2937
2938         return map;
2939 error:
2940         isl_map_free(map);
2941         return NULL;
2942 }
2943
2944 /* Move the specified dimensions to the last columns right before
2945  * the divs.  Don't change the dimension specification of bmap.
2946  * That's the responsibility of the caller.
2947  */
2948 static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
2949         enum isl_dim_type type, unsigned first, unsigned n)
2950 {
2951         struct isl_dim_map *dim_map;
2952         struct isl_basic_map *res;
2953         enum isl_dim_type t;
2954         unsigned total, off;
2955
2956         if (!bmap)
2957                 return NULL;
2958         if (pos(bmap->dim, type) + first + n ==
2959                                 1 + isl_space_dim(bmap->dim, isl_dim_all))
2960                 return bmap;
2961
2962         total = isl_basic_map_total_dim(bmap);
2963         dim_map = isl_dim_map_alloc(bmap->ctx, total);
2964
2965         off = 0;
2966         for (t = isl_dim_param; t <= isl_dim_out; ++t) {
2967                 unsigned size = isl_space_dim(bmap->dim, t);
2968                 if (t == type) {
2969                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2970                                             0, first, off);
2971                         off += first;
2972                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2973                                             first, n, total - bmap->n_div - n);
2974                         isl_dim_map_dim_range(dim_map, bmap->dim, t,
2975                                             first + n, size - (first + n), off);
2976                         off += size - (first + n);
2977                 } else {
2978                         isl_dim_map_dim(dim_map, bmap->dim, t, off);
2979                         off += size;
2980                 }
2981         }
2982         isl_dim_map_div(dim_map, bmap, off + n);
2983
2984         res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
2985                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
2986         res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
2987         return res;
2988 }
2989
2990 /* Turn the n dimensions of type type, starting at first
2991  * into existentially quantified variables.
2992  */
2993 __isl_give isl_basic_map *isl_basic_map_project_out(
2994                 __isl_take isl_basic_map *bmap,
2995                 enum isl_dim_type type, unsigned first, unsigned n)
2996 {
2997         int i;
2998         size_t row_size;
2999         isl_int **new_div;
3000         isl_int *old;
3001
3002         if (n == 0)
3003                 return basic_map_space_reset(bmap, type);
3004
3005         if (!bmap)
3006                 return NULL;
3007
3008         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
3009                 return isl_basic_map_remove_dims(bmap, type, first, n);
3010
3011         isl_assert(bmap->ctx, first + n <= isl_basic_map_dim(bmap, type),
3012                         goto error);
3013
3014         bmap = move_last(bmap, type, first, n);
3015         bmap = isl_basic_map_cow(bmap);
3016         if (!bmap)
3017                 return NULL;
3018
3019         row_size = 1 + isl_space_dim(bmap->dim, isl_dim_all) + bmap->extra;
3020         old = bmap->block2.data;
3021         bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
3022                                         (bmap->extra + n) * (1 + row_size));
3023         if (!bmap->block2.data)
3024                 goto error;
3025         new_div = isl_alloc_array(bmap->ctx, isl_int *, bmap->extra + n);
3026         if (!new_div)
3027                 goto error;
3028         for (i = 0; i < n; ++i) {
3029                 new_div[i] = bmap->block2.data +
3030                                 (bmap->extra + i) * (1 + row_size);
3031                 isl_seq_clr(new_div[i], 1 + row_size);
3032         }
3033         for (i = 0; i < bmap->extra; ++i)
3034                 new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
3035         free(bmap->div);
3036         bmap->div = new_div;
3037         bmap->n_div += n;
3038         bmap->extra += n;
3039
3040         bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n);
3041         if (!bmap->dim)
3042                 goto error;
3043         bmap = isl_basic_map_simplify(bmap);
3044         bmap = isl_basic_map_drop_redundant_divs(bmap);
3045         return isl_basic_map_finalize(bmap);
3046 error:
3047         isl_basic_map_free(bmap);
3048         return NULL;
3049 }
3050
3051 /* Turn the n dimensions of type type, starting at first
3052  * into existentially quantified variables.
3053  */
3054 struct isl_basic_set *isl_basic_set_project_out(struct isl_basic_set *bset,
3055                 enum isl_dim_type type, unsigned first, unsigned n)
3056 {
3057         return (isl_basic_set *)isl_basic_map_project_out(
3058                         (isl_basic_map *)bset, type, first, n);
3059 }
3060
3061 /* Turn the n dimensions of type type, starting at first
3062  * into existentially quantified variables.
3063  */
3064 __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
3065                 enum isl_dim_type type, unsigned first, unsigned n)
3066 {
3067         int i;
3068
3069         if (!map)
3070                 return NULL;
3071
3072         if (n == 0)
3073                 return map_space_reset(map, type);
3074
3075         isl_assert(map->ctx, first + n <= isl_map_dim(map, type), goto error);
3076
3077         map = isl_map_cow(map);
3078         if (!map)
3079                 return NULL;
3080
3081         map->dim = isl_space_drop_dims(map->dim, type, first, n);
3082         if (!map->dim)
3083                 goto error;
3084
3085         for (i = 0; i < map->n; ++i) {
3086                 map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
3087                 if (!map->p[i])
3088                         goto error;
3089         }
3090
3091         return map;
3092 error:
3093         isl_map_free(map);
3094         return NULL;
3095 }
3096
3097 /* Turn the n dimensions of type type, starting at first
3098  * into existentially quantified variables.
3099  */
3100 __isl_give isl_set *isl_set_project_out(__isl_take isl_set *set,
3101                 enum isl_dim_type type, unsigned first, unsigned n)
3102 {
3103         return (isl_set *)isl_map_project_out((isl_map *)set, type, first, n);
3104 }
3105
3106 static struct isl_basic_map *add_divs(struct isl_basic_map *bmap, unsigned n)
3107 {
3108         int i, j;
3109
3110         for (i = 0; i < n; ++i) {
3111                 j = isl_basic_map_alloc_div(bmap);
3112                 if (j < 0)
3113                         goto error;
3114                 isl_seq_clr(bmap->div[j], 1+1+isl_basic_map_total_dim(bmap));
3115         }
3116         return bmap;
3117 error:
3118         isl_basic_map_free(bmap);
3119         return NULL;
3120 }
3121
3122 struct isl_basic_map *isl_basic_map_apply_range(
3123                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
3124 {
3125         isl_space *dim_result = NULL;
3126         struct isl_basic_map *bmap;
3127         unsigned n_in, n_out, n, nparam, total, pos;
3128         struct isl_dim_map *dim_map1, *dim_map2;
3129
3130         if (!bmap1 || !bmap2)
3131                 goto error;
3132
3133         dim_result = isl_space_join(isl_space_copy(bmap1->dim),
3134                                   isl_space_copy(bmap2->dim));
3135
3136         n_in = isl_basic_map_n_in(bmap1);
3137         n_out = isl_basic_map_n_out(bmap2);
3138         n = isl_basic_map_n_out(bmap1);
3139         nparam = isl_basic_map_n_param(bmap1);
3140
3141         total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
3142         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
3143         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
3144         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
3145         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
3146         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
3147         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
3148         isl_dim_map_div(dim_map1, bmap1, pos += n_out);
3149         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
3150         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
3151         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
3152
3153         bmap = isl_basic_map_alloc_space(dim_result,
3154                         bmap1->n_div + bmap2->n_div + n,
3155                         bmap1->n_eq + bmap2->n_eq,
3156                         bmap1->n_ineq + bmap2->n_ineq);
3157         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
3158         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
3159         bmap = add_divs(bmap, n);
3160         bmap = isl_basic_map_simplify(bmap);
3161         bmap = isl_basic_map_drop_redundant_divs(bmap);
3162         return isl_basic_map_finalize(bmap);
3163 error:
3164         isl_basic_map_free(bmap1);
3165         isl_basic_map_free(bmap2);
3166         return NULL;
3167 }
3168
3169 struct isl_basic_set *isl_basic_set_apply(
3170                 struct isl_basic_set *bset, struct isl_basic_map *bmap)
3171 {
3172         if (!bset || !bmap)
3173                 goto error;
3174
3175         isl_assert(bset->ctx, isl_basic_map_compatible_domain(bmap, bset),
3176                     goto error);
3177
3178         return (struct isl_basic_set *)
3179                 isl_basic_map_apply_range((struct isl_basic_map *)bset, bmap);
3180 error:
3181         isl_basic_set_free(bset);
3182         isl_basic_map_free(bmap);
3183         return NULL;
3184 }
3185
3186 struct isl_basic_map *isl_basic_map_apply_domain(
3187                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
3188 {
3189         if (!bmap1 || !bmap2)
3190                 goto error;
3191
3192         isl_assert(bmap1->ctx,
3193             isl_basic_map_n_in(bmap1) == isl_basic_map_n_in(bmap2), goto error);
3194         isl_assert(bmap1->ctx,
3195             isl_basic_map_n_param(bmap1) == isl_basic_map_n_param(bmap2),
3196             goto error);
3197
3198         bmap1 = isl_basic_map_reverse(bmap1);
3199         bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
3200         return isl_basic_map_reverse(bmap1);
3201 error:
3202         isl_basic_map_free(bmap1);
3203         isl_basic_map_free(bmap2);
3204         return NULL;
3205 }
3206
3207 /* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
3208  * A \cap B -> f(A) + f(B)
3209  */
3210 struct isl_basic_map *isl_basic_map_sum(
3211                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
3212 {
3213         unsigned n_in, n_out, nparam, total, pos;
3214         struct isl_basic_map *bmap = NULL;
3215         struct isl_dim_map *dim_map1, *dim_map2;
3216         int i;
3217
3218         if (!bmap1 || !bmap2)
3219                 goto error;
3220
3221         isl_assert(bmap1->ctx, isl_space_is_equal(bmap1->dim, bmap2->dim),
3222                 goto error);
3223
3224         nparam = isl_basic_map_n_param(bmap1);
3225         n_in = isl_basic_map_n_in(bmap1);
3226         n_out = isl_basic_map_n_out(bmap1);
3227
3228         total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
3229         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
3230         dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
3231         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
3232         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
3233         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
3234         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
3235         isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
3236         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
3237         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
3238         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
3239
3240         bmap = isl_basic_map_alloc_space(isl_space_copy(bmap1->dim),
3241                         bmap1->n_div + bmap2->n_div + 2 * n_out,
3242                         bmap1->n_eq + bmap2->n_eq + n_out,
3243                         bmap1->n_ineq + bmap2->n_ineq);
3244         for (i = 0; i < n_out; ++i) {
3245                 int j = isl_basic_map_alloc_equality(bmap);
3246                 if (j < 0)
3247                         goto error;
3248                 isl_seq_clr(bmap->eq[j], 1+total);
3249                 isl_int_set_si(bmap->eq[j][1+nparam+n_in+i], -1);
3250                 isl_int_set_si(bmap->eq[j][1+pos+i], 1);
3251                 isl_int_set_si(bmap->eq[j][1+pos-n_out+i], 1);
3252         }
3253         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
3254         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
3255         bmap = add_divs(bmap, 2 * n_out);
3256
3257         bmap = isl_basic_map_simplify(bmap);
3258         return isl_basic_map_finalize(bmap);
3259 error:
3260         isl_basic_map_free(bmap);
3261         isl_basic_map_free(bmap1);
3262         isl_basic_map_free(bmap2);
3263         return NULL;
3264 }
3265
3266 /* Given two maps A -> f(A) and B -> g(B), construct a map
3267  * A \cap B -> f(A) + f(B)
3268  */
3269 struct isl_map *isl_map_sum(struct isl_map *map1, struct isl_map *map2)
3270 {
3271         struct isl_map *result;
3272         int i, j;
3273
3274         if (!map1 || !map2)
3275                 goto error;
3276
3277         isl_assert(map1->ctx, isl_space_is_equal(map1->dim, map2->dim), goto error);
3278
3279         result = isl_map_alloc_space(isl_space_copy(map1->dim),
3280                                 map1->n * map2->n, 0);
3281         if (!result)
3282                 goto error;
3283         for (i = 0; i < map1->n; ++i)
3284                 for (j = 0; j < map2->n; ++j) {
3285                         struct isl_basic_map *part;
3286                         part = isl_basic_map_sum(
3287                                     isl_basic_map_copy(map1->p[i]),
3288                                     isl_basic_map_copy(map2->p[j]));
3289                         if (isl_basic_map_is_empty(part))
3290                                 isl_basic_map_free(part);
3291                         else
3292                                 result = isl_map_add_basic_map(result, part);
3293                         if (!result)
3294                                 goto error;
3295                 }
3296         isl_map_free(map1);
3297         isl_map_free(map2);
3298         return result;
3299 error:
3300         isl_map_free(map1);
3301         isl_map_free(map2);
3302         return NULL;
3303 }
3304
3305 __isl_give isl_set *isl_set_sum(__isl_take isl_set *set1,
3306         __isl_take isl_set *set2)
3307 {
3308         return (isl_set *)isl_map_sum((isl_map *)set1, (isl_map *)set2);
3309 }
3310
3311 /* Given a basic map A -> f(A), construct A -> -f(A).
3312  */
3313 struct isl_basic_map *isl_basic_map_neg(struct isl_basic_map *bmap)
3314 {
3315         int i, j;
3316         unsigned off, n;
3317
3318         bmap = isl_basic_map_cow(bmap);
3319         if (!bmap)
3320                 return NULL;
3321
3322         n = isl_basic_map_dim(bmap, isl_dim_out);
3323         off = isl_basic_map_offset(bmap, isl_dim_out);
3324         for (i = 0; i < bmap->n_eq; ++i)
3325                 for (j = 0; j < n; ++j)
3326                         isl_int_neg(bmap->eq[i][off+j], bmap->eq[i][off+j]);
3327         for (i = 0; i < bmap->n_ineq; ++i)
3328                 for (j = 0; j < n; ++j)
3329                         isl_int_neg(bmap->ineq[i][off+j], bmap->ineq[i][off+j]);
3330         for (i = 0; i < bmap->n_div; ++i)
3331                 for (j = 0; j < n; ++j)
3332                         isl_int_neg(bmap->div[i][1+off+j], bmap->div[i][1+off+j]);
3333         bmap = isl_basic_map_gauss(bmap, NULL);
3334         return isl_basic_map_finalize(bmap);
3335 }
3336
3337 __isl_give isl_basic_set *isl_basic_set_neg(__isl_take isl_basic_set *bset)
3338 {
3339         return isl_basic_map_neg(bset);
3340 }
3341
3342 /* Given a map A -> f(A), construct A -> -f(A).
3343  */
3344 struct isl_map *isl_map_neg(struct isl_map *map)
3345 {
3346         int i;
3347
3348         map = isl_map_cow(map);
3349         if (!map)
3350                 return NULL;
3351
3352         for (i = 0; i < map->n; ++i) {
3353                 map->p[i] = isl_basic_map_neg(map->p[i]);
3354                 if (!map->p[i])
3355                         goto error;
3356         }
3357
3358         return map;
3359 error:
3360         isl_map_free(map);
3361         return NULL;
3362 }
3363
3364 __isl_give isl_set *isl_set_neg(__isl_take isl_set *set)
3365 {
3366         return (isl_set *)isl_map_neg((isl_map *)set);
3367 }
3368
3369 /* Given a basic map A -> f(A) and an integer d, construct a basic map
3370  * A -> floor(f(A)/d).
3371  */
3372 struct isl_basic_map *isl_basic_map_floordiv(struct isl_basic_map *bmap,
3373                 isl_int d)
3374 {
3375         unsigned n_in, n_out, nparam, total, pos;
3376         struct isl_basic_map *result = NULL;
3377         struct isl_dim_map *dim_map;
3378         int i;
3379
3380         if (!bmap)
3381                 return NULL;
3382
3383         nparam = isl_basic_map_n_param(bmap);
3384         n_in = isl_basic_map_n_in(bmap);
3385         n_out = isl_basic_map_n_out(bmap);
3386
3387         total = nparam + n_in + n_out + bmap->n_div + n_out;
3388         dim_map = isl_dim_map_alloc(bmap->ctx, total);
3389         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
3390         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
3391         isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
3392         isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
3393
3394         result = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
3395                         bmap->n_div + n_out,
3396                         bmap->n_eq, bmap->n_ineq + 2 * n_out);
3397         result = isl_basic_map_add_constraints_dim_map(result, bmap, dim_map);
3398         result = add_divs(result, n_out);
3399         for (i = 0; i < n_out; ++i) {
3400                 int j;
3401                 j = isl_basic_map_alloc_inequality(result);
3402                 if (j < 0)
3403                         goto error;
3404                 isl_seq_clr(result->ineq[j], 1+total);
3405                 isl_int_neg(result->ineq[j][1+nparam+n_in+i], d);
3406                 isl_int_set_si(result->ineq[j][1+pos+i], 1);
3407                 j = isl_basic_map_alloc_inequality(result);
3408                 if (j < 0)
3409                         goto error;
3410                 isl_seq_clr(result->ineq[j], 1+total);
3411                 isl_int_set(result->ineq[j][1+nparam+n_in+i], d);
3412                 isl_int_set_si(result->ineq[j][1+pos+i], -1);
3413                 isl_int_sub_ui(result->ineq[j][0], d, 1);
3414         }
3415
3416         result = isl_basic_map_simplify(result);
3417         return isl_basic_map_finalize(result);
3418 error:
3419         isl_basic_map_free(result);
3420         return NULL;
3421 }
3422
3423 /* Given a map A -> f(A) and an integer d, construct a map
3424  * A -> floor(f(A)/d).
3425  */
3426 struct isl_map *isl_map_floordiv(struct isl_map *map, isl_int d)
3427 {
3428         int i;
3429
3430         map = isl_map_cow(map);
3431         if (!map)
3432                 return NULL;
3433
3434         ISL_F_CLR(map, ISL_MAP_DISJOINT);
3435         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
3436         for (i = 0; i < map->n; ++i) {
3437                 map->p[i] = isl_basic_map_floordiv(map->p[i], d);
3438                 if (!map->p[i])
3439                         goto error;
3440         }
3441
3442         return map;
3443 error:
3444         isl_map_free(map);
3445         return NULL;
3446 }
3447
3448 static struct isl_basic_map *var_equal(struct isl_basic_map *bmap, unsigned pos)
3449 {
3450         int i;
3451         unsigned nparam;
3452         unsigned n_in;
3453
3454         i = isl_basic_map_alloc_equality(bmap);
3455         if (i < 0)
3456                 goto error;
3457         nparam = isl_basic_map_n_param(bmap);
3458         n_in = isl_basic_map_n_in(bmap);
3459         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
3460         isl_int_set_si(bmap->eq[i][1+nparam+pos], -1);
3461         isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1);
3462         return isl_basic_map_finalize(bmap);
3463 error:
3464         isl_basic_map_free(bmap);
3465         return NULL;
3466 }
3467
3468 /* Add a constraints to "bmap" expressing i_pos < o_pos
3469  */
3470 static struct isl_basic_map *var_less(struct isl_basic_map *bmap, unsigned pos)
3471 {
3472         int i;
3473         unsigned nparam;
3474         unsigned n_in;
3475
3476         i = isl_basic_map_alloc_inequality(bmap);
3477         if (i < 0)
3478                 goto error;
3479         nparam = isl_basic_map_n_param(bmap);
3480         n_in = isl_basic_map_n_in(bmap);
3481         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
3482         isl_int_set_si(bmap->ineq[i][0], -1);
3483         isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
3484         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
3485         return isl_basic_map_finalize(bmap);
3486 error:
3487         isl_basic_map_free(bmap);
3488         return NULL;
3489 }
3490
3491 /* Add a constraint to "bmap" expressing i_pos <= o_pos
3492  */
3493 static __isl_give isl_basic_map *var_less_or_equal(
3494         __isl_take isl_basic_map *bmap, unsigned pos)
3495 {
3496         int i;
3497         unsigned nparam;
3498         unsigned n_in;
3499
3500         i = isl_basic_map_alloc_inequality(bmap);
3501         if (i < 0)
3502                 goto error;
3503         nparam = isl_basic_map_n_param(bmap);
3504         n_in = isl_basic_map_n_in(bmap);
3505         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
3506         isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
3507         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
3508         return isl_basic_map_finalize(bmap);
3509 error:
3510         isl_basic_map_free(bmap);
3511         return NULL;
3512 }
3513
3514 /* Add a constraints to "bmap" expressing i_pos > o_pos
3515  */
3516 static struct isl_basic_map *var_more(struct isl_basic_map *bmap, unsigned pos)
3517 {
3518         int i;
3519         unsigned nparam;
3520         unsigned n_in;
3521
3522         i = isl_basic_map_alloc_inequality(bmap);
3523         if (i < 0)
3524                 goto error;
3525         nparam = isl_basic_map_n_param(bmap);
3526         n_in = isl_basic_map_n_in(bmap);
3527         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
3528         isl_int_set_si(bmap->ineq[i][0], -1);
3529         isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
3530         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
3531         return isl_basic_map_finalize(bmap);
3532 error:
3533         isl_basic_map_free(bmap);
3534         return NULL;
3535 }
3536
3537 /* Add a constraint to "bmap" expressing i_pos >= o_pos
3538  */
3539 static __isl_give isl_basic_map *var_more_or_equal(
3540         __isl_take isl_basic_map *bmap, unsigned pos)
3541 {
3542         int i;
3543         unsigned nparam;
3544         unsigned n_in;
3545
3546         i = isl_basic_map_alloc_inequality(bmap);
3547         if (i < 0)
3548                 goto error;
3549         nparam = isl_basic_map_n_param(bmap);
3550         n_in = isl_basic_map_n_in(bmap);
3551         isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
3552         isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
3553         isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
3554         return isl_basic_map_finalize(bmap);
3555 error:
3556         isl_basic_map_free(bmap);
3557         return NULL;
3558 }
3559
3560 __isl_give isl_basic_map *isl_basic_map_equal(
3561         __isl_take isl_space *dim, unsigned n_equal)
3562 {
3563         int i;
3564         struct isl_basic_map *bmap;
3565         bmap = isl_basic_map_alloc_space(dim, 0, n_equal, 0);
3566         if (!bmap)
3567                 return NULL;
3568         for (i = 0; i < n_equal && bmap; ++i)
3569                 bmap = var_equal(bmap, i);
3570         return isl_basic_map_finalize(bmap);
3571 }
3572
3573 /* Return a relation on of dimension "dim" expressing i_[0..pos] << o_[0..pos]
3574  */
3575 __isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *dim,
3576         unsigned pos)
3577 {
3578         int i;
3579         struct isl_basic_map *bmap;
3580         bmap = isl_basic_map_alloc_space(dim, 0, pos, 1);
3581         if (!bmap)
3582                 return NULL;
3583         for (i = 0; i < pos && bmap; ++i)
3584                 bmap = var_equal(bmap, i);
3585         if (bmap)
3586                 bmap = var_less(bmap, pos);
3587         return isl_basic_map_finalize(bmap);
3588 }
3589
3590 /* Return a relation on of dimension "dim" expressing i_[0..pos] <<= o_[0..pos]
3591  */
3592 __isl_give isl_basic_map *isl_basic_map_less_or_equal_at(
3593         __isl_take isl_space *dim, unsigned pos)
3594 {
3595         int i;
3596         isl_basic_map *bmap;
3597
3598         bmap = isl_basic_map_alloc_space(dim, 0, pos, 1);
3599         for (i = 0; i < pos; ++i)
3600                 bmap = var_equal(bmap, i);
3601         bmap = var_less_or_equal(bmap, pos);
3602         return isl_basic_map_finalize(bmap);
3603 }
3604
3605 /* Return a relation on pairs of sets of dimension "dim" expressing i_pos > o_pos
3606  */
3607 __isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *dim,
3608         unsigned pos)
3609 {
3610         int i;
3611         struct isl_basic_map *bmap;
3612         bmap = isl_basic_map_alloc_space(dim, 0, pos, 1);
3613         if (!bmap)
3614                 return NULL;
3615         for (i = 0; i < pos && bmap; ++i)
3616                 bmap = var_equal(bmap, i);
3617         if (bmap)
3618                 bmap = var_more(bmap, pos);
3619         return isl_basic_map_finalize(bmap);
3620 }
3621
3622 /* Return a relation on of dimension "dim" expressing i_[0..pos] >>= o_[0..pos]
3623  */
3624 __isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
3625         __isl_take isl_space *dim, unsigned pos)
3626 {
3627         int i;
3628         isl_basic_map *bmap;
3629
3630         bmap = isl_basic_map_alloc_space(dim, 0, pos, 1);
3631         for (i = 0; i < pos; ++i)
3632                 bmap = var_equal(bmap, i);
3633         bmap = var_more_or_equal(bmap, pos);
3634         return isl_basic_map_finalize(bmap);
3635 }
3636
3637 static __isl_give isl_map *map_lex_lte_first(__isl_take isl_space *dims,
3638         unsigned n, int equal)
3639 {
3640         struct isl_map *map;
3641         int i;
3642
3643         if (n == 0 && equal)
3644                 return isl_map_universe(dims);
3645
3646         map = isl_map_alloc_space(isl_space_copy(dims), n, ISL_MAP_DISJOINT);
3647
3648         for (i = 0; i + 1 < n; ++i)
3649                 map = isl_map_add_basic_map(map,
3650                                   isl_basic_map_less_at(isl_space_copy(dims), i));
3651         if (n > 0) {
3652                 if (equal)
3653                         map = isl_map_add_basic_map(map,
3654                               isl_basic_map_less_or_equal_at(dims, n - 1));
3655                 else
3656                         map = isl_map_add_basic_map(map,
3657                               isl_basic_map_less_at(dims, n - 1));
3658         } else
3659                 isl_space_free(dims);
3660
3661         return map;
3662 }
3663
3664 static __isl_give isl_map *map_lex_lte(__isl_take isl_space *dims, int equal)
3665 {
3666         if (!dims)
3667                 return NULL;
3668         return map_lex_lte_first(dims, dims->n_out, equal);
3669 }
3670
3671 __isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *dim, unsigned n)
3672 {
3673         return map_lex_lte_first(dim, n, 0);
3674 }
3675
3676 __isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *dim, unsigned n)
3677 {
3678         return map_lex_lte_first(dim, n, 1);
3679 }
3680
3681 __isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_dim)
3682 {
3683         return map_lex_lte(isl_space_map_from_set(set_dim), 0);
3684 }
3685
3686 __isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_dim)
3687 {
3688         return map_lex_lte(isl_space_map_from_set(set_dim), 1);
3689 }
3690
3691 static __isl_give isl_map *map_lex_gte_first(__isl_take isl_space *dims,
3692         unsigned n, int equal)
3693 {
3694         struct isl_map *map;
3695         int i;
3696
3697         if (n == 0 && equal)
3698                 return isl_map_universe(dims);
3699
3700         map = isl_map_alloc_space(isl_space_copy(dims), n, ISL_MAP_DISJOINT);
3701
3702         for (i = 0; i + 1 < n; ++i)
3703                 map = isl_map_add_basic_map(map,
3704                                   isl_basic_map_more_at(isl_space_copy(dims), i));
3705         if (n > 0) {
3706                 if (equal)
3707                         map = isl_map_add_basic_map(map,
3708                               isl_basic_map_more_or_equal_at(dims, n - 1));
3709                 else
3710                         map = isl_map_add_basic_map(map,
3711                               isl_basic_map_more_at(dims, n - 1));
3712         } else
3713                 isl_space_free(dims);
3714
3715         return map;
3716 }
3717
3718 static __isl_give isl_map *map_lex_gte(__isl_take isl_space *dims, int equal)
3719 {
3720         if (!dims)
3721                 return NULL;
3722         return map_lex_gte_first(dims, dims->n_out, equal);
3723 }
3724
3725 __isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *dim, unsigned n)
3726 {
3727         return map_lex_gte_first(dim, n, 0);
3728 }
3729
3730 __isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *dim, unsigned n)
3731 {
3732         return map_lex_gte_first(dim, n, 1);
3733 }
3734
3735 __isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_dim)
3736 {
3737         return map_lex_gte(isl_space_map_from_set(set_dim), 0);
3738 }
3739
3740 __isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_dim)
3741 {
3742         return map_lex_gte(isl_space_map_from_set(set_dim), 1);
3743 }
3744
3745 __isl_give isl_map *isl_set_lex_le_set(__isl_take isl_set *set1,
3746         __isl_take isl_set *set2)
3747 {
3748         isl_map *map;
3749         map = isl_map_lex_le(isl_set_get_space(set1));
3750         map = isl_map_intersect_domain(map, set1);
3751         map = isl_map_intersect_range(map, set2);
3752         return map;
3753 }
3754
3755 __isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_set *set1,
3756         __isl_take isl_set *set2)
3757 {
3758         isl_map *map;
3759         map = isl_map_lex_lt(isl_set_get_space(set1));
3760         map = isl_map_intersect_domain(map, set1);
3761         map = isl_map_intersect_range(map, set2);
3762         return map;
3763 }
3764
3765 __isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_set *set1,
3766         __isl_take isl_set *set2)
3767 {
3768         isl_map *map;
3769         map = isl_map_lex_ge(isl_set_get_space(set1));
3770         map = isl_map_intersect_domain(map, set1);
3771         map = isl_map_intersect_range(map, set2);
3772         return map;
3773 }
3774
3775 __isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_set *set1,
3776         __isl_take isl_set *set2)
3777 {
3778         isl_map *map;
3779         map = isl_map_lex_gt(isl_set_get_space(set1));
3780         map = isl_map_intersect_domain(map, set1);
3781         map = isl_map_intersect_range(map, set2);
3782         return map;
3783 }
3784
3785 __isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
3786         __isl_take isl_map *map2)
3787 {
3788         isl_map *map;
3789         map = isl_map_lex_le(isl_space_range(isl_map_get_space(map1)));
3790         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3791         map = isl_map_apply_range(map, isl_map_reverse(map2));
3792         return map;
3793 }
3794
3795 __isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
3796         __isl_take isl_map *map2)
3797 {
3798         isl_map *map;
3799         map = isl_map_lex_lt(isl_space_range(isl_map_get_space(map1)));
3800         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3801         map = isl_map_apply_range(map, isl_map_reverse(map2));
3802         return map;
3803 }
3804
3805 __isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
3806         __isl_take isl_map *map2)
3807 {
3808         isl_map *map;
3809         map = isl_map_lex_ge(isl_space_range(isl_map_get_space(map1)));
3810         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3811         map = isl_map_apply_range(map, isl_map_reverse(map2));
3812         return map;
3813 }
3814
3815 __isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
3816         __isl_take isl_map *map2)
3817 {
3818         isl_map *map;
3819         map = isl_map_lex_gt(isl_space_range(isl_map_get_space(map1)));
3820         map = isl_map_apply_domain(map, isl_map_reverse(map1));
3821         map = isl_map_apply_range(map, isl_map_reverse(map2));
3822         return map;
3823 }
3824
3825 __isl_give isl_basic_map *isl_basic_map_from_basic_set(
3826         __isl_take isl_basic_set *bset, __isl_take isl_space *dim)
3827 {
3828         struct isl_basic_map *bmap;
3829
3830         bset = isl_basic_set_cow(bset);
3831         if (!bset || !dim)
3832                 goto error;
3833
3834         isl_assert(bset->ctx, isl_space_compatible(bset->dim, dim), goto error);
3835         isl_space_free(bset->dim);
3836         bmap = (struct isl_basic_map *) bset;
3837         bmap->dim = dim;
3838         return isl_basic_map_finalize(bmap);
3839 error:
3840         isl_basic_set_free(bset);
3841         isl_space_free(dim);
3842         return NULL;
3843 }
3844
3845 struct isl_basic_set *isl_basic_set_from_basic_map(struct isl_basic_map *bmap)
3846 {
3847         if (!bmap)
3848                 goto error;
3849         if (bmap->dim->n_in == 0)
3850                 return (struct isl_basic_set *)bmap;
3851         bmap = isl_basic_map_cow(bmap);
3852         if (!bmap)
3853                 goto error;
3854         bmap->dim = isl_space_as_set_space(bmap->dim);
3855         if (!bmap->dim)
3856                 goto error;
3857         bmap = isl_basic_map_finalize(bmap);
3858         return (struct isl_basic_set *)bmap;
3859 error:
3860         isl_basic_map_free(bmap);
3861         return NULL;
3862 }
3863
3864 /* For a div d = floor(f/m), add the constraints
3865  *
3866  *              f - m d >= 0
3867  *              -(f-(n-1)) + m d >= 0
3868  *
3869  * Note that the second constraint is the negation of
3870  *
3871  *              f - m d >= n
3872  */
3873 int isl_basic_map_add_div_constraints_var(__isl_keep isl_basic_map *bmap,
3874         unsigned pos, isl_int *div)
3875 {
3876         int i, j;
3877         unsigned total = isl_basic_map_total_dim(bmap);
3878
3879         i = isl_basic_map_alloc_inequality(bmap);
3880         if (i < 0)
3881                 return -1;
3882         isl_seq_cpy(bmap->ineq[i], div + 1, 1 + total);
3883         isl_int_neg(bmap->ineq[i][1 + pos], div[0]);
3884
3885         j = isl_basic_map_alloc_inequality(bmap);
3886         if (j < 0)
3887                 return -1;
3888         isl_seq_neg(bmap->ineq[j], bmap->ineq[i], 1 + total);
3889         isl_int_add(bmap->ineq[j][0], bmap->ineq[j][0], bmap->ineq[j][1 + pos]);
3890         isl_int_sub_ui(bmap->ineq[j][0], bmap->ineq[j][0], 1);
3891         return j;
3892 }
3893
3894 int isl_basic_set_add_div_constraints_var(__isl_keep isl_basic_set *bset,
3895         unsigned pos, isl_int *div)
3896 {
3897         return isl_basic_map_add_div_constraints_var((isl_basic_map *)bset,
3898                                                         pos, div);
3899 }
3900
3901 int isl_basic_map_add_div_constraints(struct isl_basic_map *bmap, unsigned div)
3902 {
3903         unsigned total = isl_basic_map_total_dim(bmap);
3904         unsigned div_pos = total - bmap->n_div + div;
3905
3906         return isl_basic_map_add_div_constraints_var(bmap, div_pos,
3907                                                         bmap->div[div]);
3908 }
3909
3910 struct isl_basic_set *isl_basic_map_underlying_set(
3911                 struct isl_basic_map *bmap)
3912 {
3913         if (!bmap)
3914                 goto error;
3915         if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
3916             bmap->n_div == 0 &&
3917             !isl_space_is_named_or_nested(bmap->dim, isl_dim_in) &&
3918             !isl_space_is_named_or_nested(bmap->dim, isl_dim_out))
3919                 return (struct isl_basic_set *)bmap;
3920         bmap = isl_basic_map_cow(bmap);
3921         if (!bmap)
3922                 goto error;
3923         bmap->dim = isl_space_underlying(bmap->dim, bmap->n_div);
3924         if (!bmap->dim)
3925                 goto error;
3926         bmap->extra -= bmap->n_div;
3927         bmap->n_div = 0;
3928         bmap = isl_basic_map_finalize(bmap);
3929         return (struct isl_basic_set *)bmap;
3930 error:
3931         return NULL;
3932 }
3933
3934 __isl_give isl_basic_set *isl_basic_set_underlying_set(
3935                 __isl_take isl_basic_set *bset)
3936 {
3937         return isl_basic_map_underlying_set((isl_basic_map *)bset);
3938 }
3939
3940 struct isl_basic_map *isl_basic_map_overlying_set(
3941         struct isl_basic_set *bset, struct isl_basic_map *like)
3942 {
3943         struct isl_basic_map *bmap;
3944         struct isl_ctx *ctx;
3945         unsigned total;
3946         int i;
3947
3948         if (!bset || !like)
3949                 goto error;
3950         ctx = bset->ctx;
3951         isl_assert(ctx, bset->n_div == 0, goto error);
3952         isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error);
3953         isl_assert(ctx, bset->dim->n_out == isl_basic_map_total_dim(like),
3954                         goto error);
3955         if (isl_space_is_equal(bset->dim, like->dim) && like->n_div == 0) {
3956                 isl_basic_map_free(like);
3957                 return (struct isl_basic_map *)bset;
3958         }
3959         bset = isl_basic_set_cow(bset);
3960         if (!bset)
3961                 goto error;
3962         total = bset->dim->n_out + bset->extra;
3963         bmap = (struct isl_basic_map *)bset;
3964         isl_space_free(bmap->dim);
3965         bmap->dim = isl_space_copy(like->dim);
3966         if (!bmap->dim)
3967                 goto error;
3968         bmap->n_div = like->n_div;
3969         bmap->extra += like->n_div;
3970         if (bmap->extra) {
3971                 unsigned ltotal;
3972                 isl_int **div;
3973                 ltotal = total - bmap->extra + like->extra;
3974                 if (ltotal > total)
3975                         ltotal = total;
3976                 bmap->block2 = isl_blk_extend(ctx, bmap->block2,
3977                                         bmap->extra * (1 + 1 + total));
3978                 if (isl_blk_is_error(bmap->block2))
3979                         goto error;
3980                 div = isl_realloc_array(ctx, bmap->div, isl_int *, bmap->extra);
3981                 if (!div)
3982                         goto error;
3983                 bmap->div = div;
3984                 for (i = 0; i < bmap->extra; ++i)
3985                         bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
3986                 for (i = 0; i < like->n_div; ++i) {
3987                         isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
3988                         isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
3989                 }
3990                 bmap = isl_basic_map_extend_constraints(bmap, 
3991                                                         0, 2 * like->n_div);
3992                 for (i = 0; i < like->n_div; ++i) {
3993                         if (isl_int_is_zero(bmap->div[i][0]))
3994                                 continue;
3995                         if (isl_basic_map_add_div_constraints(bmap, i) < 0)
3996                                 goto error;
3997                 }
3998         }
3999         isl_basic_map_free(like);
4000         bmap = isl_basic_map_simplify(bmap);
4001         bmap = isl_basic_map_finalize(bmap);
4002         return bmap;
4003 error:
4004         isl_basic_map_free(like);
4005         isl_basic_set_free(bset);
4006         return NULL;
4007 }
4008
4009 struct isl_basic_set *isl_basic_set_from_underlying_set(
4010         struct isl_basic_set *bset, struct isl_basic_set *like)
4011 {
4012         return (struct isl_basic_set *)
4013                 isl_basic_map_overlying_set(bset, (struct isl_basic_map *)like);
4014 }
4015
4016 struct isl_set *isl_set_from_underlying_set(
4017         struct isl_set *set, struct isl_basic_set *like)
4018 {
4019         int i;
4020
4021         if (!set || !like)
4022                 goto error;
4023         isl_assert(set->ctx, set->dim->n_out == isl_basic_set_total_dim(like),
4024                     goto error);
4025         if (isl_space_is_equal(set->dim, like->dim) && like->n_div == 0) {
4026                 isl_basic_set_free(like);
4027                 return set;
4028         }
4029         set = isl_set_cow(set);
4030         if (!set)
4031                 goto error;
4032         for (i = 0; i < set->n; ++i) {
4033                 set->p[i] = isl_basic_set_from_underlying_set(set->p[i],
4034                                                       isl_basic_set_copy(like));
4035                 if (!set->p[i])
4036                         goto error;
4037         }
4038         isl_space_free(set->dim);
4039         set->dim = isl_space_copy(like->dim);
4040         if (!set->dim)
4041                 goto error;
4042         isl_basic_set_free(like);
4043         return set;
4044 error:
4045         isl_basic_set_free(like);
4046         isl_set_free(set);
4047         return NULL;
4048 }
4049
4050 struct isl_set *isl_map_underlying_set(struct isl_map *map)
4051 {
4052         int i;
4053
4054         map = isl_map_cow(map);
4055         if (!map)
4056                 return NULL;
4057         map->dim = isl_space_cow(map->dim);
4058         if (!map->dim)
4059                 goto error;
4060
4061         for (i = 1; i < map->n; ++i)
4062                 isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,
4063                                 goto error);
4064         for (i = 0; i < map->n; ++i) {
4065                 map->p[i] = (struct isl_basic_map *)
4066                                 isl_basic_map_underlying_set(map->p[i]);
4067                 if (!map->p[i])
4068                         goto error;
4069         }
4070         if (map->n == 0)
4071                 map->dim = isl_space_underlying(map->dim, 0);
4072         else {
4073                 isl_space_free(map->dim);
4074                 map->dim = isl_space_copy(map->p[0]->dim);
4075         }
4076         if (!map->dim)
4077                 goto error;
4078         return (struct isl_set *)map;
4079 error:
4080         isl_map_free(map);
4081         return NULL;
4082 }
4083
4084 struct isl_set *isl_set_to_underlying_set(struct isl_set *set)
4085 {
4086         return (struct isl_set *)isl_map_underlying_set((struct isl_map *)set);
4087 }
4088
4089 __isl_give isl_basic_map *isl_basic_map_reset_space(
4090         __isl_take isl_basic_map *bmap, __isl_take isl_space *dim)
4091 {
4092         bmap = isl_basic_map_cow(bmap);
4093         if (!bmap || !dim)
4094                 goto error;
4095
4096         isl_space_free(bmap->dim);
4097         bmap->dim = dim;
4098
4099         bmap = isl_basic_map_finalize(bmap);
4100
4101         return bmap;
4102 error:
4103         isl_basic_map_free(bmap);
4104         isl_space_free(dim);
4105         return NULL;
4106 }
4107
4108 __isl_give isl_basic_set *isl_basic_set_reset_space(
4109         __isl_take isl_basic_set *bset, __isl_take isl_space *dim)
4110 {
4111         return (isl_basic_set *)isl_basic_map_reset_space((isl_basic_map *)bset,
4112                                                         dim);
4113 }
4114
4115 __isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map,
4116         __isl_take isl_space *dim)
4117 {
4118         int i;
4119
4120         map = isl_map_cow(map);
4121         if (!map || !dim)
4122                 goto error;
4123
4124         for (i = 0; i < map->n; ++i) {
4125                 map->p[i] = isl_basic_map_reset_space(map->p[i],
4126                                                     isl_space_copy(dim));
4127                 if (!map->p[i])
4128                         goto error;
4129         }
4130         isl_space_free(map->dim);
4131         map->dim = dim;
4132
4133         return map;
4134 error:
4135         isl_map_free(map);
4136         isl_space_free(dim);
4137         return NULL;
4138 }
4139
4140 __isl_give isl_set *isl_set_reset_space(__isl_take isl_set *set,
4141         __isl_take isl_space *dim)
4142 {
4143         return (struct isl_set *) isl_map_reset_space((struct isl_map *)set, dim);
4144 }
4145
4146 /* Compute the parameter domain of the given basic set.
4147  */
4148 __isl_give isl_basic_set *isl_basic_set_params(__isl_take isl_basic_set *bset)
4149 {
4150         isl_space *space;
4151         unsigned n;
4152
4153         if (isl_basic_set_is_params(bset))
4154                 return bset;
4155
4156         n = isl_basic_set_dim(bset, isl_dim_set);
4157         bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
4158         space = isl_basic_set_get_space(bset);
4159         space = isl_space_params(space);
4160         bset = isl_basic_set_reset_space(bset, space);
4161         return bset;
4162 }
4163
4164 /* Compute the parameter domain of the given set.
4165  */
4166 __isl_give isl_set *isl_set_params(__isl_take isl_set *set)
4167 {
4168         isl_space *space;
4169         unsigned n;
4170
4171         if (isl_set_is_params(set))
4172                 return set;
4173
4174         n = isl_set_dim(set, isl_dim_set);
4175         set = isl_set_project_out(set, isl_dim_set, 0, n);
4176         space = isl_set_get_space(set);
4177         space = isl_space_params(space);
4178         set = isl_set_reset_space(set, space);
4179         return set;
4180 }
4181
4182 /* Construct a zero-dimensional set with the given parameter domain.
4183  */
4184 __isl_give isl_set *isl_set_from_params(__isl_take isl_set *set)
4185 {
4186         isl_space *space;
4187         space = isl_set_get_space(set);
4188         space = isl_space_set_from_params(space);
4189         set = isl_set_reset_space(set, space);
4190         return set;
4191 }
4192
4193 /* Compute the parameter domain of the given map.
4194  */
4195 __isl_give isl_set *isl_map_params(__isl_take isl_map *map)
4196 {
4197         isl_space *space;
4198         unsigned n;
4199
4200         n = isl_map_dim(map, isl_dim_in);
4201         map = isl_map_project_out(map, isl_dim_in, 0, n);
4202         n = isl_map_dim(map, isl_dim_out);
4203         map = isl_map_project_out(map, isl_dim_out, 0, n);
4204         space = isl_map_get_space(map);
4205         space = isl_space_params(space);
4206         map = isl_map_reset_space(map, space);
4207         return map;
4208 }
4209
4210 struct isl_basic_set *isl_basic_map_domain(struct isl_basic_map *bmap)
4211 {
4212         isl_space *dim;
4213         struct isl_basic_set *domain;
4214         unsigned n_in;
4215         unsigned n_out;
4216
4217         if (!bmap)
4218                 return NULL;
4219         dim = isl_space_domain(isl_basic_map_get_space(bmap));
4220
4221         n_in = isl_basic_map_n_in(bmap);
4222         n_out = isl_basic_map_n_out(bmap);
4223         domain = isl_basic_set_from_basic_map(bmap);
4224         domain = isl_basic_set_project_out(domain, isl_dim_set, n_in, n_out);
4225
4226         domain = isl_basic_set_reset_space(domain, dim);
4227
4228         return domain;
4229 }
4230
4231 int isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap)
4232 {
4233         if (!bmap)
4234                 return -1;
4235         return isl_space_may_be_set(bmap->dim);
4236 }
4237
4238 /* Is this basic map actually a set?
4239  * Users should never call this function.  Outside of isl,
4240  * the type should indicate whether something is a set or a map.
4241  */
4242 int isl_basic_map_is_set(__isl_keep isl_basic_map *bmap)
4243 {
4244         if (!bmap)
4245                 return -1;
4246         return isl_space_is_set(bmap->dim);
4247 }
4248
4249 struct isl_basic_set *isl_basic_map_range(struct isl_basic_map *bmap)
4250 {
4251         if (!bmap)
4252                 return NULL;
4253         if (isl_basic_map_is_set(bmap))
4254                 return bmap;
4255         return isl_basic_map_domain(isl_basic_map_reverse(bmap));
4256 }
4257
4258 __isl_give isl_basic_map *isl_basic_map_domain_map(
4259         __isl_take isl_basic_map *bmap)
4260 {
4261         int i, k;
4262         isl_space *dim;
4263         isl_basic_map *domain;
4264         int nparam, n_in, n_out;
4265         unsigned total;
4266
4267         nparam = isl_basic_map_dim(bmap, isl_dim_param);
4268         n_in = isl_basic_map_dim(bmap, isl_dim_in);
4269         n_out = isl_basic_map_dim(bmap, isl_dim_out);
4270
4271         dim = isl_space_from_range(isl_space_domain(isl_basic_map_get_space(bmap)));
4272         domain = isl_basic_map_universe(dim);
4273
4274         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
4275         bmap = isl_basic_map_apply_range(bmap, domain);
4276         bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
4277
4278         total = isl_basic_map_total_dim(bmap);
4279
4280         for (i = 0; i < n_in; ++i) {
4281                 k = isl_basic_map_alloc_equality(bmap);
4282                 if (k < 0)
4283                         goto error;
4284                 isl_seq_clr(bmap->eq[k], 1 + total);
4285                 isl_int_set_si(bmap->eq[k][1 + nparam + i], -1);
4286                 isl_int_set_si(bmap->eq[k][1 + nparam + n_in + n_out + i], 1);
4287         }
4288
4289         bmap = isl_basic_map_gauss(bmap, NULL);
4290         return isl_basic_map_finalize(bmap);
4291 error:
4292         isl_basic_map_free(bmap);
4293         return NULL;
4294 }
4295
4296 __isl_give isl_basic_map *isl_basic_map_range_map(
4297         __isl_take isl_basic_map *bmap)
4298 {
4299         int i, k;
4300         isl_space *dim;
4301         isl_basic_map *range;
4302         int nparam, n_in, n_out;
4303         unsigned total;
4304
4305         nparam = isl_basic_map_dim(bmap, isl_dim_param);
4306         n_in = isl_basic_map_dim(bmap, isl_dim_in);
4307         n_out = isl_basic_map_dim(bmap, isl_dim_out);
4308
4309         dim = isl_space_from_range(isl_space_range(isl_basic_map_get_space(bmap)));
4310         range = isl_basic_map_universe(dim);
4311
4312         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
4313         bmap = isl_basic_map_apply_range(bmap, range);
4314         bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
4315
4316         total = isl_basic_map_total_dim(bmap);
4317
4318         for (i = 0; i < n_out; ++i) {
4319                 k = isl_basic_map_alloc_equality(bmap);
4320                 if (k < 0)
4321                         goto error;
4322                 isl_seq_clr(bmap->eq[k], 1 + total);
4323                 isl_int_set_si(bmap->eq[k][1 + nparam + n_in + i], -1);
4324                 isl_int_set_si(bmap->eq[k][1 + nparam + n_in + n_out + i], 1);
4325         }
4326
4327         bmap = isl_basic_map_gauss(bmap, NULL);
4328         return isl_basic_map_finalize(bmap);
4329 error:
4330         isl_basic_map_free(bmap);
4331         return NULL;
4332 }
4333
4334 int isl_map_may_be_set(__isl_keep isl_map *map)
4335 {
4336         if (!map)
4337                 return -1;
4338         return isl_space_may_be_set(map->dim);
4339 }
4340
4341 /* Is this map actually a set?
4342  * Users should never call this function.  Outside of isl,
4343  * the type should indicate whether something is a set or a map.
4344  */
4345 int isl_map_is_set(__isl_keep isl_map *map)
4346 {
4347         if (!map)
4348                 return -1;
4349         return isl_space_is_set(map->dim);
4350 }
4351
4352 struct isl_set *isl_map_range(struct isl_map *map)
4353 {
4354         int i;
4355         struct isl_set *set;
4356
4357         if (!map)
4358                 goto error;
4359         if (isl_map_is_set(map))
4360                 return (isl_set *)map;
4361
4362         map = isl_map_cow(map);
4363         if (!map)
4364                 goto error;
4365
4366         set = (struct isl_set *) map;
4367         set->dim = isl_space_range(set->dim);
4368         if (!set->dim)
4369                 goto error;
4370         for (i = 0; i < map->n; ++i) {
4371                 set->p[i] = isl_basic_map_range(map->p[i]);
4372                 if (!set->p[i])
4373                         goto error;
4374         }
4375         ISL_F_CLR(set, ISL_MAP_DISJOINT);
4376         ISL_F_CLR(set, ISL_SET_NORMALIZED);
4377         return set;
4378 error:
4379         isl_map_free(map);
4380         return NULL;
4381 }
4382
4383 __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
4384 {
4385         int i;
4386         isl_space *domain_dim;
4387
4388         map = isl_map_cow(map);
4389         if (!map)
4390                 return NULL;
4391
4392         domain_dim = isl_space_from_range(isl_space_domain(isl_map_get_space(map)));
4393         map->dim = isl_space_from_domain(isl_space_wrap(map->dim));
4394         map->dim = isl_space_join(map->dim, domain_dim);
4395         if (!map->dim)
4396                 goto error;
4397         for (i = 0; i < map->n; ++i) {
4398                 map->p[i] = isl_basic_map_domain_map(map->p[i]);
4399                 if (!map->p[i])
4400                         goto error;
4401         }
4402         ISL_F_CLR(map, ISL_MAP_DISJOINT);
4403         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4404         return map;
4405 error:
4406         isl_map_free(map);
4407         return NULL;
4408 }
4409
4410 __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
4411 {
4412         int i;
4413         isl_space *range_dim;
4414
4415         map = isl_map_cow(map);
4416         if (!map)
4417                 return NULL;
4418
4419         range_dim = isl_space_range(isl_map_get_space(map));
4420         range_dim = isl_space_from_range(range_dim);
4421         map->dim = isl_space_from_domain(isl_space_wrap(map->dim));
4422         map->dim = isl_space_join(map->dim, range_dim);
4423         if (!map->dim)
4424                 goto error;
4425         for (i = 0; i < map->n; ++i) {
4426                 map->p[i] = isl_basic_map_range_map(map->p[i]);
4427                 if (!map->p[i])
4428                         goto error;
4429         }
4430         ISL_F_CLR(map, ISL_MAP_DISJOINT);
4431         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4432         return map;
4433 error:
4434         isl_map_free(map);
4435         return NULL;
4436 }
4437
4438 __isl_give isl_map *isl_map_from_set(__isl_take isl_set *set,
4439         __isl_take isl_space *dim)
4440 {
4441         int i;
4442         struct isl_map *map = NULL;
4443
4444         set = isl_set_cow(set);
4445         if (!set || !dim)
4446                 goto error;
4447         isl_assert(set->ctx, isl_space_compatible(set->dim, dim), goto error);
4448         map = (struct isl_map *)set;
4449         for (i = 0; i < set->n; ++i) {
4450                 map->p[i] = isl_basic_map_from_basic_set(
4451                                 set->p[i], isl_space_copy(dim));
4452                 if (!map->p[i])
4453                         goto error;
4454         }
4455         isl_space_free(map->dim);
4456         map->dim = dim;
4457         return map;
4458 error:
4459         isl_space_free(dim);
4460         isl_set_free(set);
4461         return NULL;
4462 }
4463
4464 __isl_give isl_basic_map *isl_basic_map_from_domain(
4465         __isl_take isl_basic_set *bset)
4466 {
4467         return isl_basic_map_reverse(isl_basic_map_from_range(bset));
4468 }
4469
4470 __isl_give isl_basic_map *isl_basic_map_from_range(
4471         __isl_take isl_basic_set *bset)
4472 {
4473         isl_space *space;
4474         space = isl_basic_set_get_space(bset);
4475         space = isl_space_from_range(space);
4476         bset = isl_basic_set_reset_space(bset, space);
4477         return (isl_basic_map *)bset;
4478 }
4479
4480 struct isl_map *isl_map_from_range(struct isl_set *set)
4481 {
4482         isl_space *space;
4483         space = isl_set_get_space(set);
4484         space = isl_space_from_range(space);
4485         set = isl_set_reset_space(set, space);
4486         return (struct isl_map *)set;
4487 }
4488
4489 __isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set)
4490 {
4491         return isl_map_reverse(isl_map_from_range(set));
4492 }
4493
4494 __isl_give isl_basic_map *isl_basic_map_from_domain_and_range(
4495         __isl_take isl_basic_set *domain, __isl_take isl_basic_set *range)
4496 {
4497         return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range);
4498 }
4499
4500 __isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain,
4501         __isl_take isl_set *range)
4502 {
4503         return isl_map_apply_range(isl_map_reverse(domain), range);
4504 }
4505
4506 struct isl_set *isl_set_from_map(struct isl_map *map)
4507 {
4508         int i;
4509         struct isl_set *set = NULL;
4510
4511         if (!map)
4512                 return NULL;
4513         map = isl_map_cow(map);
4514         if (!map)
4515                 return NULL;
4516         map->dim = isl_space_as_set_space(map->dim);
4517         if (!map->dim)
4518                 goto error;
4519         set = (struct isl_set *)map;
4520         for (i = 0; i < map->n; ++i) {
4521                 set->p[i] = isl_basic_set_from_basic_map(map->p[i]);
4522                 if (!set->p[i])
4523                         goto error;
4524         }
4525         return set;
4526 error:
4527         isl_map_free(map);
4528         return NULL;
4529 }
4530
4531 __isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *dim, int n,
4532         unsigned flags)
4533 {
4534         struct isl_map *map;
4535
4536         if (!dim)
4537                 return NULL;
4538         if (n < 0)
4539                 isl_die(dim->ctx, isl_error_internal,
4540                         "negative number of basic maps", goto error);
4541         map = isl_alloc(dim->ctx, struct isl_map,
4542                         sizeof(struct isl_map) +
4543                         (n - 1) * sizeof(struct isl_basic_map *));
4544         if (!map)
4545                 goto error;
4546
4547         map->ctx = dim->ctx;
4548         isl_ctx_ref(map->ctx);
4549         map->ref = 1;
4550         map->size = n;
4551         map->n = 0;
4552         map->dim = dim;
4553         map->flags = flags;
4554         return map;
4555 error:
4556         isl_space_free(dim);
4557         return NULL;
4558 }
4559
4560 struct isl_map *isl_map_alloc(struct isl_ctx *ctx,
4561                 unsigned nparam, unsigned in, unsigned out, int n,
4562                 unsigned flags)
4563 {
4564         struct isl_map *map;
4565         isl_space *dims;
4566
4567         dims = isl_space_alloc(ctx, nparam, in, out);
4568         if (!dims)
4569                 return NULL;
4570
4571         map = isl_map_alloc_space(dims, n, flags);
4572         return map;
4573 }
4574
4575 __isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *dim)
4576 {
4577         struct isl_basic_map *bmap;
4578         bmap = isl_basic_map_alloc_space(dim, 0, 1, 0);
4579         bmap = isl_basic_map_set_to_empty(bmap);
4580         return bmap;
4581 }
4582
4583 __isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *dim)
4584 {
4585         struct isl_basic_set *bset;
4586         bset = isl_basic_set_alloc_space(dim, 0, 1, 0);
4587         bset = isl_basic_set_set_to_empty(bset);
4588         return bset;
4589 }
4590
4591 struct isl_basic_map *isl_basic_map_empty_like(struct isl_basic_map *model)
4592 {
4593         struct isl_basic_map *bmap;
4594         if (!model)
4595                 return NULL;
4596         bmap = isl_basic_map_alloc_space(isl_space_copy(model->dim), 0, 1, 0);
4597         bmap = isl_basic_map_set_to_empty(bmap);
4598         return bmap;
4599 }
4600
4601 struct isl_basic_map *isl_basic_map_empty_like_map(struct isl_map *model)
4602 {
4603         struct isl_basic_map *bmap;
4604         if (!model)
4605                 return NULL;
4606         bmap = isl_basic_map_alloc_space(isl_space_copy(model->dim), 0, 1, 0);
4607         bmap = isl_basic_map_set_to_empty(bmap);
4608         return bmap;
4609 }
4610
4611 struct isl_basic_set *isl_basic_set_empty_like(struct isl_basic_set *model)
4612 {
4613         struct isl_basic_set *bset;
4614         if (!model)
4615                 return NULL;
4616         bset = isl_basic_set_alloc_space(isl_space_copy(model->dim), 0, 1, 0);
4617         bset = isl_basic_set_set_to_empty(bset);
4618         return bset;
4619 }
4620
4621 __isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *dim)
4622 {
4623         struct isl_basic_map *bmap;
4624         bmap = isl_basic_map_alloc_space(dim, 0, 0, 0);
4625         bmap = isl_basic_map_finalize(bmap);
4626         return bmap;
4627 }
4628
4629 __isl_give isl_basic_set *isl_basic_set_universe(__isl_take isl_space *dim)
4630 {
4631         struct isl_basic_set *bset;
4632         bset = isl_basic_set_alloc_space(dim, 0, 0, 0);
4633         bset = isl_basic_set_finalize(bset);
4634         return bset;
4635 }
4636
4637 __isl_give isl_basic_map *isl_basic_map_nat_universe(__isl_take isl_space *dim)
4638 {
4639         int i;
4640         unsigned total = isl_space_dim(dim, isl_dim_all);
4641         isl_basic_map *bmap;
4642
4643         bmap= isl_basic_map_alloc_space(dim, 0, 0, total);
4644         for (i = 0; i < total; ++i) {
4645                 int k = isl_basic_map_alloc_inequality(bmap);
4646                 if (k < 0)
4647                         goto error;
4648                 isl_seq_clr(bmap->ineq[k], 1 + total);
4649                 isl_int_set_si(bmap->ineq[k][1 + i], 1);
4650         }
4651         return bmap;
4652 error:
4653         isl_basic_map_free(bmap);
4654         return NULL;
4655 }
4656
4657 __isl_give isl_basic_set *isl_basic_set_nat_universe(__isl_take isl_space *dim)
4658 {
4659         return isl_basic_map_nat_universe(dim);
4660 }
4661
4662 __isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *dim)
4663 {
4664         return isl_map_from_basic_map(isl_basic_map_nat_universe(dim));
4665 }
4666
4667 __isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *dim)
4668 {
4669         return isl_map_nat_universe(dim);
4670 }
4671
4672 __isl_give isl_basic_map *isl_basic_map_universe_like(
4673                 __isl_keep isl_basic_map *model)
4674 {
4675         if (!model)
4676                 return NULL;
4677         return isl_basic_map_alloc_space(isl_space_copy(model->dim), 0, 0, 0);
4678 }
4679
4680 struct isl_basic_set *isl_basic_set_universe_like(struct isl_basic_set *model)
4681 {
4682         if (!model)
4683                 return NULL;
4684         return isl_basic_set_alloc_space(isl_space_copy(model->dim), 0, 0, 0);
4685 }
4686
4687 __isl_give isl_basic_set *isl_basic_set_universe_like_set(
4688         __isl_keep isl_set *model)
4689 {
4690         if (!model)
4691                 return NULL;
4692         return isl_basic_set_alloc_space(isl_space_copy(model->dim), 0, 0, 0);
4693 }
4694
4695 __isl_give isl_map *isl_map_empty(__isl_take isl_space *dim)
4696 {
4697         return isl_map_alloc_space(dim, 0, ISL_MAP_DISJOINT);
4698 }
4699
4700 struct isl_map *isl_map_empty_like(struct isl_map *model)
4701 {
4702         if (!model)
4703                 return NULL;
4704         return isl_map_alloc_space(isl_space_copy(model->dim), 0, ISL_MAP_DISJOINT);
4705 }
4706
4707 struct isl_map *isl_map_empty_like_basic_map(struct isl_basic_map *model)
4708 {
4709         if (!model)
4710                 return NULL;
4711         return isl_map_alloc_space(isl_space_copy(model->dim), 0, ISL_MAP_DISJOINT);
4712 }
4713
4714 __isl_give isl_set *isl_set_empty(__isl_take isl_space *dim)
4715 {
4716         return isl_set_alloc_space(dim, 0, ISL_MAP_DISJOINT);
4717 }
4718
4719 struct isl_set *isl_set_empty_like(struct isl_set *model)
4720 {
4721         if (!model)
4722                 return NULL;
4723         return isl_set_empty(isl_space_copy(model->dim));
4724 }
4725
4726 __isl_give isl_map *isl_map_universe(__isl_take isl_space *dim)
4727 {
4728         struct isl_map *map;
4729         if (!dim)
4730                 return NULL;
4731         map = isl_map_alloc_space(isl_space_copy(dim), 1, ISL_MAP_DISJOINT);
4732         map = isl_map_add_basic_map(map, isl_basic_map_universe(dim));
4733         return map;
4734 }
4735
4736 __isl_give isl_set *isl_set_universe(__isl_take isl_space *dim)
4737 {
4738         struct isl_set *set;
4739         if (!dim)
4740                 return NULL;
4741         set = isl_set_alloc_space(isl_space_copy(dim), 1, ISL_MAP_DISJOINT);
4742         set = isl_set_add_basic_set(set, isl_basic_set_universe(dim));
4743         return set;
4744 }
4745
4746 __isl_give isl_set *isl_set_universe_like(__isl_keep isl_set *model)
4747 {
4748         if (!model)
4749                 return NULL;
4750         return isl_set_universe(isl_space_copy(model->dim));
4751 }
4752
4753 struct isl_map *isl_map_dup(struct isl_map *map)
4754 {
4755         int i;
4756         struct isl_map *dup;
4757
4758         if (!map)
4759                 return NULL;
4760         dup = isl_map_alloc_space(isl_space_copy(map->dim), map->n, map->flags);
4761         for (i = 0; i < map->n; ++i)
4762                 dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
4763         return dup;
4764 }
4765
4766 __isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
4767                                                 __isl_take isl_basic_map *bmap)
4768 {
4769         if (!bmap || !map)
4770                 goto error;
4771         if (isl_basic_map_plain_is_empty(bmap)) {
4772                 isl_basic_map_free(bmap);
4773                 return map;
4774         }
4775         isl_assert(map->ctx, isl_space_is_equal(map->dim, bmap->dim), goto error);
4776         isl_assert(map->ctx, map->n < map->size, goto error);
4777         map->p[map->n] = bmap;
4778         map->n++;
4779         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4780         return map;
4781 error:
4782         if (map)
4783                 isl_map_free(map);
4784         if (bmap)
4785                 isl_basic_map_free(bmap);
4786         return NULL;
4787 }
4788
4789 void isl_map_free(struct isl_map *map)
4790 {
4791         int i;
4792
4793         if (!map)
4794                 return;
4795
4796         if (--map->ref > 0)
4797                 return;
4798
4799         isl_ctx_deref(map->ctx);
4800         for (i = 0; i < map->n; ++i)
4801                 isl_basic_map_free(map->p[i]);
4802         isl_space_free(map->dim);
4803         free(map);
4804 }
4805
4806 struct isl_map *isl_map_extend(struct isl_map *base,
4807                 unsigned nparam, unsigned n_in, unsigned n_out)
4808 {
4809         int i;
4810
4811         base = isl_map_cow(base);
4812         if (!base)
4813                 return NULL;
4814
4815         base->dim = isl_space_extend(base->dim, nparam, n_in, n_out);
4816         if (!base->dim)
4817                 goto error;
4818         for (i = 0; i < base->n; ++i) {
4819                 base->p[i] = isl_basic_map_extend_space(base->p[i],
4820                                 isl_space_copy(base->dim), 0, 0, 0);
4821                 if (!base->p[i])
4822                         goto error;
4823         }
4824         return base;
4825 error:
4826         isl_map_free(base);
4827         return NULL;
4828 }
4829
4830 struct isl_set *isl_set_extend(struct isl_set *base,
4831                 unsigned nparam, unsigned dim)
4832 {
4833         return (struct isl_set *)isl_map_extend((struct isl_map *)base,
4834                                                         nparam, 0, dim);
4835 }
4836
4837 static struct isl_basic_map *isl_basic_map_fix_pos_si(
4838         struct isl_basic_map *bmap, unsigned pos, int value)
4839 {
4840         int j;
4841
4842         bmap = isl_basic_map_cow(bmap);
4843         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
4844         j = isl_basic_map_alloc_equality(bmap);
4845         if (j < 0)
4846                 goto error;
4847         isl_seq_clr(bmap->eq[j] + 1, isl_basic_map_total_dim(bmap));
4848         isl_int_set_si(bmap->eq[j][pos], -1);
4849         isl_int_set_si(bmap->eq[j][0], value);
4850         bmap = isl_basic_map_simplify(bmap);
4851         return isl_basic_map_finalize(bmap);
4852 error:
4853         isl_basic_map_free(bmap);
4854         return NULL;
4855 }
4856
4857 static __isl_give isl_basic_map *isl_basic_map_fix_pos(
4858         __isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
4859 {
4860         int j;
4861
4862         bmap = isl_basic_map_cow(bmap);
4863         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
4864         j = isl_basic_map_alloc_equality(bmap);
4865         if (j < 0)
4866                 goto error;
4867         isl_seq_clr(bmap->eq[j] + 1, isl_basic_map_total_dim(bmap));
4868         isl_int_set_si(bmap->eq[j][pos], -1);
4869         isl_int_set(bmap->eq[j][0], value);
4870         bmap = isl_basic_map_simplify(bmap);
4871         return isl_basic_map_finalize(bmap);
4872 error:
4873         isl_basic_map_free(bmap);
4874         return NULL;
4875 }
4876
4877 struct isl_basic_map *isl_basic_map_fix_si(struct isl_basic_map *bmap,
4878                 enum isl_dim_type type, unsigned pos, int value)
4879 {
4880         if (!bmap)
4881                 return NULL;
4882         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
4883         return isl_basic_map_fix_pos_si(bmap,
4884                 isl_basic_map_offset(bmap, type) + pos, value);
4885 error:
4886         isl_basic_map_free(bmap);
4887         return NULL;
4888 }
4889
4890 __isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
4891                 enum isl_dim_type type, unsigned pos, isl_int value)
4892 {
4893         if (!bmap)
4894                 return NULL;
4895         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
4896         return isl_basic_map_fix_pos(bmap,
4897                 isl_basic_map_offset(bmap, type) + pos, value);
4898 error:
4899         isl_basic_map_free(bmap);
4900         return NULL;
4901 }
4902
4903 struct isl_basic_set *isl_basic_set_fix_si(struct isl_basic_set *bset,
4904                 enum isl_dim_type type, unsigned pos, int value)
4905 {
4906         return (struct isl_basic_set *)
4907                 isl_basic_map_fix_si((struct isl_basic_map *)bset,
4908                                         type, pos, value);
4909 }
4910
4911 __isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset,
4912                 enum isl_dim_type type, unsigned pos, isl_int value)
4913 {
4914         return (struct isl_basic_set *)
4915                 isl_basic_map_fix((struct isl_basic_map *)bset,
4916                                         type, pos, value);
4917 }
4918
4919 struct isl_basic_map *isl_basic_map_fix_input_si(struct isl_basic_map *bmap,
4920                 unsigned input, int value)
4921 {
4922         return isl_basic_map_fix_si(bmap, isl_dim_in, input, value);
4923 }
4924
4925 struct isl_basic_set *isl_basic_set_fix_dim_si(struct isl_basic_set *bset,
4926                 unsigned dim, int value)
4927 {
4928         return (struct isl_basic_set *)
4929                 isl_basic_map_fix_si((struct isl_basic_map *)bset,
4930                                         isl_dim_set, dim, value);
4931 }
4932
4933 struct isl_map *isl_map_fix_si(struct isl_map *map,
4934                 enum isl_dim_type type, unsigned pos, int value)
4935 {
4936         int i;
4937
4938         map = isl_map_cow(map);
4939         if (!map)
4940                 return NULL;
4941
4942         isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error);
4943         for (i = 0; i < map->n; ++i) {
4944                 map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
4945                 if (!map->p[i])
4946                         goto error;
4947         }
4948         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4949         return map;
4950 error:
4951         isl_map_free(map);
4952         return NULL;
4953 }
4954
4955 __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set,
4956                 enum isl_dim_type type, unsigned pos, int value)
4957 {
4958         return (struct isl_set *)
4959                 isl_map_fix_si((struct isl_map *)set, type, pos, value);
4960 }
4961
4962 __isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
4963                 enum isl_dim_type type, unsigned pos, isl_int value)
4964 {
4965         int i;
4966
4967         map = isl_map_cow(map);
4968         if (!map)
4969                 return NULL;
4970
4971         isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error);
4972         for (i = 0; i < map->n; ++i) {
4973                 map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
4974                 if (!map->p[i])
4975                         goto error;
4976         }
4977         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
4978         return map;
4979 error:
4980         isl_map_free(map);
4981         return NULL;
4982 }
4983
4984 __isl_give isl_set *isl_set_fix(__isl_take isl_set *set,
4985                 enum isl_dim_type type, unsigned pos, isl_int value)
4986 {
4987         return (struct isl_set *)isl_map_fix((isl_map *)set, type, pos, value);
4988 }
4989
4990 struct isl_map *isl_map_fix_input_si(struct isl_map *map,
4991                 unsigned input, int value)
4992 {
4993         return isl_map_fix_si(map, isl_dim_in, input, value);
4994 }
4995
4996 struct isl_set *isl_set_fix_dim_si(struct isl_set *set, unsigned dim, int value)
4997 {
4998         return (struct isl_set *)
4999                 isl_map_fix_si((struct isl_map *)set, isl_dim_set, dim, value);
5000 }
5001
5002 static __isl_give isl_basic_map *basic_map_bound_si(
5003         __isl_take isl_basic_map *bmap,
5004         enum isl_dim_type type, unsigned pos, int value, int upper)
5005 {
5006         int j;
5007
5008         if (!bmap)
5009                 return NULL;
5010         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), goto error);
5011         pos += isl_basic_map_offset(bmap, type);
5012         bmap = isl_basic_map_cow(bmap);
5013         bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
5014         j = isl_basic_map_alloc_inequality(bmap);
5015         if (j < 0)
5016                 goto error;
5017         isl_seq_clr(bmap->ineq[j], 1 + isl_basic_map_total_dim(bmap));
5018         if (upper) {
5019                 isl_int_set_si(bmap->ineq[j][pos], -1);
5020                 isl_int_set_si(bmap->ineq[j][0], value);
5021         } else {
5022                 isl_int_set_si(bmap->ineq[j][pos], 1);
5023                 isl_int_set_si(bmap->ineq[j][0], -value);
5024         }
5025         bmap = isl_basic_map_simplify(bmap);
5026         return isl_basic_map_finalize(bmap);
5027 error:
5028         isl_basic_map_free(bmap);
5029         return NULL;
5030 }
5031
5032 __isl_give isl_basic_map *isl_basic_map_lower_bound_si(
5033         __isl_take isl_basic_map *bmap,
5034         enum isl_dim_type type, unsigned pos, int value)
5035 {
5036         return basic_map_bound_si(bmap, type, pos, value, 0);
5037 }
5038
5039 struct isl_basic_set *isl_basic_set_lower_bound_dim(struct isl_basic_set *bset,
5040         unsigned dim, isl_int value)
5041 {
5042         int j;
5043
5044         bset = isl_basic_set_cow(bset);
5045         bset = isl_basic_set_extend_constraints(bset, 0, 1);
5046         j = isl_basic_set_alloc_inequality(bset);
5047         if (j < 0)
5048                 goto error;
5049         isl_seq_clr(bset->ineq[j], 1 + isl_basic_set_total_dim(bset));
5050         isl_int_set_si(bset->ineq[j][1 + isl_basic_set_n_param(bset) + dim], 1);
5051         isl_int_neg(bset->ineq[j][0], value);
5052         bset = isl_basic_set_simplify(bset);
5053         return isl_basic_set_finalize(bset);
5054 error:
5055         isl_basic_set_free(bset);
5056         return NULL;
5057 }
5058
5059 static __isl_give isl_map *map_bound_si(__isl_take isl_map *map,
5060         enum isl_dim_type type, unsigned pos, int value, int upper)
5061 {
5062         int i;
5063
5064         map = isl_map_cow(map);
5065         if (!map)
5066                 return NULL;
5067
5068         isl_assert(map->ctx, pos < isl_map_dim(map, type), goto error);
5069         for (i = 0; i < map->n; ++i) {
5070                 map->p[i] = basic_map_bound_si(map->p[i],
5071                                                  type, pos, value, upper);
5072                 if (!map->p[i])
5073                         goto error;
5074         }
5075         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
5076         return map;
5077 error:
5078         isl_map_free(map);
5079         return NULL;
5080 }
5081
5082 __isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
5083         enum isl_dim_type type, unsigned pos, int value)
5084 {
5085         return map_bound_si(map, type, pos, value, 0);
5086 }
5087
5088 __isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map,
5089         enum isl_dim_type type, unsigned pos, int value)
5090 {
5091         return map_bound_si(map, type, pos, value, 1);
5092 }
5093
5094 __isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set,
5095                 enum isl_dim_type type, unsigned pos, int value)
5096 {
5097         return (struct isl_set *)
5098                 isl_map_lower_bound_si((struct isl_map *)set, type, pos, value);
5099 }
5100
5101 __isl_give isl_set *isl_set_upper_bound_si(__isl_take isl_set *set,
5102         enum isl_dim_type type, unsigned pos, int value)
5103 {
5104         return isl_map_upper_bound_si(set, type, pos, value);
5105 }
5106
5107 struct isl_set *isl_set_lower_bound_dim(struct isl_set *set, unsigned dim,
5108                                         isl_int value)
5109 {
5110         int i;
5111
5112         set = isl_set_cow(set);
5113         if (!set)
5114                 return NULL;
5115
5116         isl_assert(set->ctx, dim < isl_set_n_dim(set), goto error);
5117         for (i = 0; i < set->n; ++i) {
5118                 set->p[i] = isl_basic_set_lower_bound_dim(set->p[i], dim, value);
5119                 if (!set->p[i])
5120                         goto error;
5121         }
5122         return set;
5123 error:
5124         isl_set_free(set);
5125         return NULL;
5126 }
5127
5128 struct isl_map *isl_map_reverse(struct isl_map *map)
5129 {
5130         int i;
5131
5132         map = isl_map_cow(map);
5133         if (!map)
5134                 return NULL;
5135
5136         map->dim = isl_space_reverse(map->dim);
5137         if (!map->dim)
5138                 goto error;
5139         for (i = 0; i < map->n; ++i) {
5140                 map->p[i] = isl_basic_map_reverse(map->p[i]);
5141                 if (!map->p[i])
5142                         goto error;
5143         }
5144         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
5145         return map;
5146 error:
5147         isl_map_free(map);
5148         return NULL;
5149 }
5150
5151 static struct isl_map *isl_basic_map_partial_lexopt(
5152                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
5153                 struct isl_set **empty, int max)
5154 {
5155         if (!bmap)
5156                 goto error;
5157         if (bmap->ctx->opt->pip == ISL_PIP_PIP)
5158                 return isl_pip_basic_map_lexopt(bmap, dom, empty, max);
5159         else
5160                 return isl_tab_basic_map_partial_lexopt(bmap, dom, empty, max);
5161 error:
5162         isl_basic_map_free(bmap);
5163         isl_basic_set_free(dom);
5164         if (empty)
5165                 *empty = NULL;
5166         return NULL;
5167 }
5168
5169 struct isl_map *isl_basic_map_partial_lexmax(
5170                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
5171                 struct isl_set **empty)
5172 {
5173         return isl_basic_map_partial_lexopt(bmap, dom, empty, 1);
5174 }
5175
5176 struct isl_map *isl_basic_map_partial_lexmin(
5177                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
5178                 struct isl_set **empty)
5179 {
5180         return isl_basic_map_partial_lexopt(bmap, dom, empty, 0);
5181 }
5182
5183 struct isl_set *isl_basic_set_partial_lexmin(
5184                 struct isl_basic_set *bset, struct isl_basic_set *dom,
5185                 struct isl_set **empty)
5186 {
5187         return (struct isl_set *)
5188                 isl_basic_map_partial_lexmin((struct isl_basic_map *)bset,
5189                         dom, empty);
5190 }
5191
5192 struct isl_set *isl_basic_set_partial_lexmax(
5193                 struct isl_basic_set *bset, struct isl_basic_set *dom,
5194                 struct isl_set **empty)
5195 {
5196         return (struct isl_set *)
5197                 isl_basic_map_partial_lexmax((struct isl_basic_map *)bset,
5198                         dom, empty);
5199 }
5200
5201 __isl_give isl_pw_multi_aff *isl_basic_map_partial_lexmin_pw_multi_aff(
5202         __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom,
5203         __isl_give isl_set **empty)
5204 {
5205         return isl_basic_map_partial_lexopt_pw_multi_aff(bmap, dom, empty, 0);
5206 }
5207
5208 __isl_give isl_pw_multi_aff *isl_basic_map_partial_lexmax_pw_multi_aff(
5209         __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom,
5210         __isl_give isl_set **empty)
5211 {
5212         return isl_basic_map_partial_lexopt_pw_multi_aff(bmap, dom, empty, 1);
5213 }
5214
5215 __isl_give isl_pw_multi_aff *isl_basic_set_partial_lexmin_pw_multi_aff(
5216         __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom,
5217         __isl_give isl_set **empty)
5218 {
5219         return isl_basic_map_partial_lexmin_pw_multi_aff(bset, dom, empty);
5220 }
5221
5222 __isl_give isl_pw_multi_aff *isl_basic_set_partial_lexmax_pw_multi_aff(
5223         __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom,
5224         __isl_give isl_set **empty)
5225 {
5226         return isl_basic_map_partial_lexmax_pw_multi_aff(bset, dom, empty);
5227 }
5228
5229 __isl_give isl_pw_multi_aff *isl_basic_map_lexopt_pw_multi_aff(
5230         __isl_take isl_basic_map *bmap, int max)
5231 {
5232         isl_basic_set *dom = NULL;
5233         isl_space *dom_space;
5234
5235         if (!bmap)
5236                 goto error;
5237         dom_space = isl_space_domain(isl_space_copy(bmap->dim));
5238         dom = isl_basic_set_universe(dom_space);
5239         return isl_basic_map_partial_lexopt_pw_multi_aff(bmap, dom, NULL, max);
5240 error:
5241         isl_basic_map_free(bmap);
5242         return NULL;
5243 }
5244
5245 __isl_give isl_pw_multi_aff *isl_basic_map_lexmin_pw_multi_aff(
5246         __isl_take isl_basic_map *bmap)
5247 {
5248         return isl_basic_map_lexopt_pw_multi_aff(bmap, 0);
5249 }
5250
5251 /* Given a basic map "bmap", compute the lexicographically minimal
5252  * (or maximal) image element for each domain element in dom.
5253  * Set *empty to those elements in dom that do not have an image element.
5254  *
5255  * We first make sure the basic sets in dom are disjoint and then
5256  * simply collect the results over each of the basic sets separately.
5257  * We could probably improve the efficiency a bit by moving the union
5258  * domain down into the parametric integer programming.
5259  */
5260 static __isl_give isl_map *basic_map_partial_lexopt(
5261                 __isl_take isl_basic_map *bmap, __isl_take isl_set *dom,
5262                 __isl_give isl_set **empty, int max)
5263 {
5264         int i;
5265         struct isl_map *res;
5266
5267         dom = isl_set_make_disjoint(dom);
5268         if (!dom)
5269                 goto error;
5270
5271         if (isl_set_plain_is_empty(dom)) {
5272                 res = isl_map_empty_like_basic_map(bmap);
5273                 *empty = isl_set_empty_like(dom);
5274                 isl_set_free(dom);
5275                 isl_basic_map_free(bmap);
5276                 return res;
5277         }
5278
5279         res = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap),
5280                         isl_basic_set_copy(dom->p[0]), empty, max);
5281                 
5282         for (i = 1; i < dom->n; ++i) {
5283                 struct isl_map *res_i;
5284                 struct isl_set *empty_i;
5285
5286                 res_i = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap),
5287                                 isl_basic_set_copy(dom->p[i]), &empty_i, max);
5288
5289                 res = isl_map_union_disjoint(res, res_i);
5290                 *empty = isl_set_union_disjoint(*empty, empty_i);
5291         }
5292
5293         isl_set_free(dom);
5294         isl_basic_map_free(bmap);
5295         return res;
5296 error:
5297         *empty = NULL;
5298         isl_set_free(dom);
5299         isl_basic_map_free(bmap);
5300         return NULL;
5301 }
5302
5303 /* Given a map "map", compute the lexicographically minimal
5304  * (or maximal) image element for each domain element in dom.
5305  * Set *empty to those elements in dom that do not have an image element.
5306  *
5307  * We first compute the lexicographically minimal or maximal element
5308  * in the first basic map.  This results in a partial solution "res"
5309  * and a subset "todo" of dom that still need to be handled.
5310  * We then consider each of the remaining maps in "map" and successively
5311  * improve both "res" and "todo".
5312  *
5313  * Let res^k and todo^k be the results after k steps and let i = k + 1.
5314  * Assume we are computing the lexicographical maximum.
5315  * We first compute the lexicographically maximal element in basic map i.
5316  * This results in a partial solution res_i and a subset todo_i.
5317  * Then we combine these results with those obtain for the first k basic maps
5318  * to obtain a result that is valid for the first k+1 basic maps.
5319  * In particular, the set where there is no solution is the set where
5320  * there is no solution for the first k basic maps and also no solution
5321  * for the ith basic map, i.e.,
5322  *
5323  *      todo^i = todo^k * todo_i
5324  *
5325  * On dom(res^k) * dom(res_i), we need to pick the larger of the two
5326  * solutions, arbitrarily breaking ties in favor of res^k.
5327  * That is, when res^k(a) >= res_i(a), we pick res^k and
5328  * when res^k(a) < res_i(a), we pick res_i.  (Here, ">=" and "<" denote
5329  * the lexicographic order.)
5330  * In practice, we compute
5331  *
5332  *      res^k * (res_i . "<=")
5333  *
5334  * and
5335  *
5336  *      res_i * (res^k . "<")
5337  *
5338  * Finally, we consider the symmetric difference of dom(res^k) and dom(res_i),
5339  * where only one of res^k and res_i provides a solution and we simply pick
5340  * that one, i.e.,
5341  *
5342  *      res^k * todo_i
5343  * and
5344  *      res_i * todo^k
5345  *
5346  * Note that we only compute these intersections when dom(res^k) intersects
5347  * dom(res_i).  Otherwise, the only effect of these intersections is to
5348  * potentially break up res^k and res_i into smaller pieces.
5349  * We want to avoid such splintering as much as possible.
5350  * In fact, an earlier implementation of this function would look for
5351  * better results in the domain of res^k and for extra results in todo^k,
5352  * but this would always result in a splintering according to todo^k,
5353  * even when the domain of basic map i is disjoint from the domains of
5354  * the previous basic maps.
5355  */
5356 static __isl_give isl_map *isl_map_partial_lexopt_aligned(
5357                 __isl_take isl_map *map, __isl_take isl_set *dom,
5358                 __isl_give isl_set **empty, int max)
5359 {
5360         int i;
5361         struct isl_map *res;
5362         struct isl_set *todo;
5363
5364         if (!map || !dom)
5365                 goto error;
5366
5367         if (isl_map_plain_is_empty(map)) {
5368                 if (empty)
5369                         *empty = dom;
5370                 else
5371                         isl_set_free(dom);
5372                 return map;
5373         }
5374
5375         res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
5376                                         isl_set_copy(dom), &todo, max);
5377
5378         for (i = 1; i < map->n; ++i) {
5379                 isl_map *lt, *le;
5380                 isl_map *res_i;
5381                 isl_set *todo_i;
5382                 isl_space *dim = isl_space_range(isl_map_get_space(res));
5383
5384                 res_i = basic_map_partial_lexopt(isl_basic_map_copy(map->p[i]),
5385                                         isl_set_copy(dom), &todo_i, max);
5386
5387                 if (max) {
5388                         lt = isl_map_lex_lt(isl_space_copy(dim));
5389                         le = isl_map_lex_le(dim);
5390                 } else {
5391                         lt = isl_map_lex_gt(isl_space_copy(dim));
5392                         le = isl_map_lex_ge(dim);
5393                 }
5394                 lt = isl_map_apply_range(isl_map_copy(res), lt);
5395                 lt = isl_map_intersect(lt, isl_map_copy(res_i));
5396                 le = isl_map_apply_range(isl_map_copy(res_i), le);
5397                 le = isl_map_intersect(le, isl_map_copy(res));
5398
5399                 if (!isl_map_is_empty(lt) || !isl_map_is_empty(le)) {
5400                         res = isl_map_intersect_domain(res,
5401                                                         isl_set_copy(todo_i));
5402                         res_i = isl_map_intersect_domain(res_i,
5403                                                         isl_set_copy(todo));
5404                 }
5405
5406                 res = isl_map_union_disjoint(res, res_i);
5407                 res = isl_map_union_disjoint(res, lt);
5408                 res = isl_map_union_disjoint(res, le);
5409
5410                 todo = isl_set_intersect(todo, todo_i);
5411         }
5412
5413         isl_set_free(dom);
5414         isl_map_free(map);
5415
5416         if (empty)
5417                 *empty = todo;
5418         else
5419                 isl_set_free(todo);
5420
5421         return res;
5422 error:
5423         if (empty)
5424                 *empty = NULL;
5425         isl_set_free(dom);
5426         isl_map_free(map);
5427         return NULL;
5428 }
5429
5430 /* Given a map "map", compute the lexicographically minimal
5431  * (or maximal) image element for each domain element in dom.
5432  * Set *empty to those elements in dom that do not have an image element.
5433  *
5434  * Align parameters if needed and then call isl_map_partial_lexopt_aligned.
5435  */
5436 static __isl_give isl_map *isl_map_partial_lexopt(
5437                 __isl_take isl_map *map, __isl_take isl_set *dom,
5438                 __isl_give isl_set **empty, int max)
5439 {
5440         if (!map || !dom)
5441                 goto error;
5442         if (isl_space_match(map->dim, isl_dim_param, dom->dim, isl_dim_param))
5443                 return isl_map_partial_lexopt_aligned(map, dom, empty, max);
5444         if (!isl_space_has_named_params(map->dim) ||
5445             !isl_space_has_named_params(dom->dim))
5446                 isl_die(map->ctx, isl_error_invalid,
5447                         "unaligned unnamed parameters", goto error);
5448         map = isl_map_align_params(map, isl_map_get_space(dom));
5449         dom = isl_map_align_params(dom, isl_map_get_space(map));
5450         return isl_map_partial_lexopt_aligned(map, dom, empty, max);
5451 error:
5452         if (empty)
5453                 *empty = NULL;
5454         isl_set_free(dom);
5455         isl_map_free(map);
5456         return NULL;
5457 }
5458
5459 __isl_give isl_map *isl_map_partial_lexmax(
5460                 __isl_take isl_map *map, __isl_take isl_set *dom,
5461                 __isl_give isl_set **empty)
5462 {
5463         return isl_map_partial_lexopt(map, dom, empty, 1);
5464 }
5465
5466 __isl_give isl_map *isl_map_partial_lexmin(
5467                 __isl_take isl_map *map, __isl_take isl_set *dom,
5468                 __isl_give isl_set **empty)
5469 {
5470         return isl_map_partial_lexopt(map, dom, empty, 0);
5471 }
5472
5473 __isl_give isl_set *isl_set_partial_lexmin(
5474                 __isl_take isl_set *set, __isl_take isl_set *dom,
5475                 __isl_give isl_set **empty)
5476 {
5477         return (struct isl_set *)
5478                 isl_map_partial_lexmin((struct isl_map *)set,
5479                         dom, empty);
5480 }
5481
5482 __isl_give isl_set *isl_set_partial_lexmax(
5483                 __isl_take isl_set *set, __isl_take isl_set *dom,
5484                 __isl_give isl_set **empty)
5485 {
5486         return (struct isl_set *)
5487                 isl_map_partial_lexmax((struct isl_map *)set,
5488                         dom, empty);
5489 }
5490
5491 __isl_give isl_map *isl_basic_map_lexopt(__isl_take isl_basic_map *bmap, int max)
5492 {
5493         struct isl_basic_set *dom = NULL;
5494         isl_space *dom_dim;
5495
5496         if (!bmap)
5497                 goto error;
5498         dom_dim = isl_space_domain(isl_space_copy(bmap->dim));
5499         dom = isl_basic_set_universe(dom_dim);
5500         return isl_basic_map_partial_lexopt(bmap, dom, NULL, max);
5501 error:
5502         isl_basic_map_free(bmap);
5503         return NULL;
5504 }
5505
5506 __isl_give isl_map *isl_basic_map_lexmin(__isl_take isl_basic_map *bmap)
5507 {
5508         return isl_basic_map_lexopt(bmap, 0);
5509 }
5510
5511 __isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
5512 {
5513         return isl_basic_map_lexopt(bmap, 1);
5514 }
5515
5516 __isl_give isl_set *isl_basic_set_lexmin(__isl_take isl_basic_set *bset)
5517 {
5518         return (isl_set *)isl_basic_map_lexmin((isl_basic_map *)bset);
5519 }
5520
5521 __isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset)
5522 {
5523         return (isl_set *)isl_basic_map_lexmax((isl_basic_map *)bset);
5524 }
5525
5526 __isl_give isl_map *isl_map_lexopt(__isl_take isl_map *map, int max)
5527 {
5528         struct isl_set *dom = NULL;
5529         isl_space *dom_dim;
5530
5531         if (!map)
5532                 goto error;
5533         dom_dim = isl_space_domain(isl_space_copy(map->dim));
5534         dom = isl_set_universe(dom_dim);
5535         return isl_map_partial_lexopt(map, dom, NULL, max);
5536 error:
5537         isl_map_free(map);
5538         return NULL;
5539 }
5540
5541 __isl_give isl_map *isl_map_lexmin(__isl_take isl_map *map)
5542 {
5543         return isl_map_lexopt(map, 0);
5544 }
5545
5546 __isl_give isl_map *isl_map_lexmax(__isl_take isl_map *map)
5547 {
5548         return isl_map_lexopt(map, 1);
5549 }
5550
5551 __isl_give isl_set *isl_set_lexmin(__isl_take isl_set *set)
5552 {
5553         return (isl_set *)isl_map_lexmin((isl_map *)set);
5554 }
5555
5556 __isl_give isl_set *isl_set_lexmax(__isl_take isl_set *set)
5557 {
5558         return (isl_set *)isl_map_lexmax((isl_map *)set);
5559 }
5560
5561 /* Extract the first and only affine expression from list
5562  * and then add it to *pwaff with the given dom.
5563  * This domain is known to be disjoint from other domains
5564  * because of the way isl_basic_map_foreach_lexmax works.
5565  */
5566 static int update_dim_opt(__isl_take isl_basic_set *dom,
5567         __isl_take isl_aff_list *list, void *user)
5568 {
5569         isl_ctx *ctx = isl_basic_set_get_ctx(dom);
5570         isl_aff *aff;
5571         isl_pw_aff **pwaff = user;
5572         isl_pw_aff *pwaff_i;
5573
5574         if (isl_aff_list_n_aff(list) != 1)
5575                 isl_die(ctx, isl_error_internal,
5576                         "expecting single element list", goto error);
5577
5578         aff = isl_aff_list_get_aff(list, 0);
5579         pwaff_i = isl_pw_aff_alloc(isl_set_from_basic_set(dom), aff);
5580
5581         *pwaff = isl_pw_aff_add_disjoint(*pwaff, pwaff_i);
5582
5583         isl_aff_list_free(list);
5584
5585         return 0;
5586 error:
5587         isl_basic_set_free(dom);
5588         isl_aff_list_free(list);
5589         return -1;
5590 }
5591
5592 /* Given a basic map with one output dimension, compute the minimum or
5593  * maximum of that dimension as an isl_pw_aff.
5594  *
5595  * The isl_pw_aff is constructed by having isl_basic_map_foreach_lexopt
5596  * call update_dim_opt on each leaf of the result.
5597  */
5598 static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
5599         int max)
5600 {
5601         isl_space *dim = isl_basic_map_get_space(bmap);
5602         isl_pw_aff *pwaff;
5603         int r;
5604
5605         dim = isl_space_from_domain(isl_space_domain(dim));
5606         dim = isl_space_add_dims(dim, isl_dim_out, 1);
5607         pwaff = isl_pw_aff_empty(dim);
5608
5609         r = isl_basic_map_foreach_lexopt(bmap, max, &update_dim_opt, &pwaff);
5610         if (r < 0)
5611                 return isl_pw_aff_free(pwaff);
5612
5613         return pwaff;
5614 }
5615
5616 /* Compute the minimum or maximum of the given output dimension
5617  * as a function of the parameters and the input dimensions,
5618  * but independently of the other output dimensions.
5619  *
5620  * We first project out the other output dimension and then compute
5621  * the "lexicographic" maximum in each basic map, combining the results
5622  * using isl_pw_aff_union_max.
5623  */
5624 static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos,
5625         int max)
5626 {
5627         int i;
5628         isl_pw_aff *pwaff;
5629         unsigned n_out;
5630
5631         n_out = isl_map_dim(map, isl_dim_out);
5632         map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1));
5633         map = isl_map_project_out(map, isl_dim_out, 0, pos);
5634         if (!map)
5635                 return NULL;
5636
5637         if (map->n == 0) {
5638                 isl_space *dim = isl_map_get_space(map);
5639                 dim = isl_space_domain(isl_space_from_range(dim));
5640                 isl_map_free(map);
5641                 return isl_pw_aff_empty(dim);
5642         }
5643
5644         pwaff = basic_map_dim_opt(map->p[0], max);
5645         for (i = 1; i < map->n; ++i) {
5646                 isl_pw_aff *pwaff_i;
5647
5648                 pwaff_i = basic_map_dim_opt(map->p[i], max);
5649                 pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max);
5650         }
5651
5652         isl_map_free(map);
5653
5654         return pwaff;
5655 }
5656
5657 /* Compute the maximum of the given output dimension as a function of the
5658  * parameters and input dimensions, but independently of
5659  * the other output dimensions.
5660  */
5661 __isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos)
5662 {
5663         return map_dim_opt(map, pos, 1);
5664 }
5665
5666 /* Compute the minimum or maximum of the given set dimension
5667  * as a function of the parameters,
5668  * but independently of the other set dimensions.
5669  */
5670 static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_set *set, int pos,
5671         int max)
5672 {
5673         return map_dim_opt(set, pos, max);
5674 }
5675
5676 /* Compute the maximum of the given set dimension as a function of the
5677  * parameters, but independently of the other set dimensions.
5678  */
5679 __isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_set *set, int pos)
5680 {
5681         return set_dim_opt(set, pos, 1);
5682 }
5683
5684 /* Compute the minimum of the given set dimension as a function of the
5685  * parameters, but independently of the other set dimensions.
5686  */
5687 __isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_set *set, int pos)
5688 {
5689         return set_dim_opt(set, pos, 0);
5690 }
5691
5692 /* Apply a preimage specified by "mat" on the parameters of "bset".
5693  * bset is assumed to have only parameters and divs.
5694  */
5695 static struct isl_basic_set *basic_set_parameter_preimage(
5696         struct isl_basic_set *bset, struct isl_mat *mat)
5697 {
5698         unsigned nparam;
5699
5700         if (!bset || !mat)
5701                 goto error;
5702
5703         bset->dim = isl_space_cow(bset->dim);
5704         if (!bset->dim)
5705                 goto error;
5706
5707         nparam = isl_basic_set_dim(bset, isl_dim_param);
5708
5709         isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error);
5710
5711         bset->dim->nparam = 0;
5712         bset->dim->n_out = nparam;
5713         bset = isl_basic_set_preimage(bset, mat);
5714         if (bset) {
5715                 bset->dim->nparam = bset->dim->n_out;
5716                 bset->dim->n_out = 0;
5717         }
5718         return bset;
5719 error:
5720         isl_mat_free(mat);
5721         isl_basic_set_free(bset);
5722         return NULL;
5723 }
5724
5725 /* Apply a preimage specified by "mat" on the parameters of "set".
5726  * set is assumed to have only parameters and divs.
5727  */
5728 static struct isl_set *set_parameter_preimage(
5729         struct isl_set *set, struct isl_mat *mat)
5730 {
5731         isl_space *dim = NULL;
5732         unsigned nparam;
5733
5734         if (!set || !mat)
5735                 goto error;
5736
5737         dim = isl_space_copy(set->dim);
5738         dim = isl_space_cow(dim);
5739         if (!dim)
5740                 goto error;
5741
5742         nparam = isl_set_dim(set, isl_dim_param);
5743
5744         isl_assert(set->ctx, mat->n_row == 1 + nparam, goto error);
5745
5746         dim->nparam = 0;
5747         dim->n_out = nparam;
5748         isl_set_reset_space(set, dim);
5749         set = isl_set_preimage(set, mat);
5750         if (!set)
5751                 goto error2;
5752         dim = isl_space_copy(set->dim);
5753         dim = isl_space_cow(dim);
5754         if (!dim)
5755                 goto error2;
5756         dim->nparam = dim->n_out;
5757         dim->n_out = 0;
5758         isl_set_reset_space(set, dim);
5759         return set;
5760 error:
5761         isl_space_free(dim);
5762         isl_mat_free(mat);
5763 error2:
5764         isl_set_free(set);
5765         return NULL;
5766 }
5767
5768 /* Intersect the basic set "bset" with the affine space specified by the
5769  * equalities in "eq".
5770  */
5771 static struct isl_basic_set *basic_set_append_equalities(
5772         struct isl_basic_set *bset, struct isl_mat *eq)
5773 {
5774         int i, k;
5775         unsigned len;
5776
5777         if (!bset || !eq)
5778                 goto error;
5779
5780         bset = isl_basic_set_extend_space(bset, isl_space_copy(bset->dim), 0,
5781                                         eq->n_row, 0);
5782         if (!bset)
5783                 goto error;
5784
5785         len = 1 + isl_space_dim(bset->dim, isl_dim_all) + bset->extra;
5786         for (i = 0; i < eq->n_row; ++i) {
5787                 k = isl_basic_set_alloc_equality(bset);
5788                 if (k < 0)
5789                         goto error;
5790                 isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
5791                 isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
5792         }
5793         isl_mat_free(eq);
5794
5795         bset = isl_basic_set_gauss(bset, NULL);
5796         bset = isl_basic_set_finalize(bset);
5797
5798         return bset;
5799 error:
5800         isl_mat_free(eq);
5801         isl_basic_set_free(bset);
5802         return NULL;
5803 }
5804
5805 /* Intersect the set "set" with the affine space specified by the
5806  * equalities in "eq".
5807  */
5808 static struct isl_set *set_append_equalities(struct isl_set *set,
5809         struct isl_mat *eq)
5810 {
5811         int i;
5812
5813         if (!set || !eq)
5814                 goto error;
5815
5816         for (i = 0; i < set->n; ++i) {
5817                 set->p[i] = basic_set_append_equalities(set->p[i],
5818                                         isl_mat_copy(eq));
5819                 if (!set->p[i])
5820                         goto error;
5821         }
5822         isl_mat_free(eq);
5823         return set;
5824 error:
5825         isl_mat_free(eq);
5826         isl_set_free(set);
5827         return NULL;
5828 }
5829
5830 /* Project the given basic set onto its parameter domain, possibly introducing
5831  * new, explicit, existential variables in the constraints.
5832  * The input has parameters and (possibly implicit) existential variables.
5833  * The output has the same parameters, but only
5834  * explicit existentially quantified variables.
5835  *
5836  * The actual projection is performed by pip, but pip doesn't seem
5837  * to like equalities very much, so we first remove the equalities
5838  * among the parameters by performing a variable compression on
5839  * the parameters.  Afterward, an inverse transformation is performed
5840  * and the equalities among the parameters are inserted back in.
5841  */
5842 static struct isl_set *parameter_compute_divs(struct isl_basic_set *bset)
5843 {
5844         int i, j;
5845         struct isl_mat *eq;
5846         struct isl_mat *T, *T2;
5847         struct isl_set *set;
5848         unsigned nparam, n_div;
5849
5850         bset = isl_basic_set_cow(bset);
5851         if (!bset)
5852                 return NULL;
5853
5854         if (bset->n_eq == 0)
5855                 return isl_basic_set_lexmin(bset);
5856
5857         isl_basic_set_gauss(bset, NULL);
5858
5859         nparam = isl_basic_set_dim(bset, isl_dim_param);
5860         n_div = isl_basic_set_dim(bset, isl_dim_div);
5861
5862         for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
5863                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + j]))
5864                         ++i;
5865         }
5866         if (i == bset->n_eq)
5867                 return isl_basic_set_lexmin(bset);
5868
5869         eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i,
5870                 0, 1 + nparam);
5871         eq = isl_mat_cow(eq);
5872         T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
5873         if (T && T->n_col == 0) {
5874                 isl_mat_free(T);
5875                 isl_mat_free(T2);
5876                 isl_mat_free(eq);
5877                 bset = isl_basic_set_set_to_empty(bset);
5878                 return isl_set_from_basic_set(bset);
5879         }
5880         bset = basic_set_parameter_preimage(bset, T);
5881
5882         set = isl_basic_set_lexmin(bset);
5883         set = set_parameter_preimage(set, T2);
5884         set = set_append_equalities(set, eq);
5885         return set;
5886 }
5887
5888 /* Compute an explicit representation for all the existentially
5889  * quantified variables.
5890  * The input and output dimensions are first turned into parameters.
5891  * compute_divs then returns a map with the same parameters and
5892  * no input or output dimensions and the dimension specification
5893  * is reset to that of the input.
5894  */
5895 static struct isl_map *compute_divs(struct isl_basic_map *bmap)
5896 {
5897         struct isl_basic_set *bset;
5898         struct isl_set *set;
5899         struct isl_map *map;
5900         isl_space *dim, *orig_dim = NULL;
5901         unsigned         nparam;
5902         unsigned         n_in;
5903         unsigned         n_out;
5904
5905         bmap = isl_basic_map_cow(bmap);
5906         if (!bmap)
5907                 return NULL;
5908
5909         nparam = isl_basic_map_dim(bmap, isl_dim_param);
5910         n_in = isl_basic_map_dim(bmap, isl_dim_in);
5911         n_out = isl_basic_map_dim(bmap, isl_dim_out);
5912         dim = isl_space_set_alloc(bmap->ctx, nparam + n_in + n_out, 0);
5913         if (!dim)
5914                 goto error;
5915
5916         orig_dim = bmap->dim;
5917         bmap->dim = dim;
5918         bset = (struct isl_basic_set *)bmap;
5919
5920         set = parameter_compute_divs(bset);
5921         map = (struct isl_map *)set;
5922         map = isl_map_reset_space(map, orig_dim);
5923
5924         return map;
5925 error:
5926         isl_basic_map_free(bmap);
5927         return NULL;
5928 }
5929
5930 int isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
5931 {
5932         int i;
5933         unsigned off;
5934
5935         if (!bmap)
5936                 return -1;
5937
5938         off = isl_space_dim(bmap->dim, isl_dim_all);
5939         for (i = 0; i < bmap->n_div; ++i) {
5940                 if (isl_int_is_zero(bmap->div[i][0]))
5941                         return 0;
5942                 isl_assert(bmap->ctx, isl_int_is_zero(bmap->div[i][1+1+off+i]),
5943                                 return -1);
5944         }
5945         return 1;
5946 }
5947
5948 static int map_divs_known(__isl_keep isl_map *map)
5949 {
5950         int i;
5951
5952         if (!map)
5953                 return -1;
5954
5955         for (i = 0; i < map->n; ++i) {
5956                 int known = isl_basic_map_divs_known(map->p[i]);
5957                 if (known <= 0)
5958                         return known;
5959         }
5960
5961         return 1;
5962 }
5963
5964 /* If bmap contains any unknown divs, then compute explicit
5965  * expressions for them.  However, this computation may be
5966  * quite expensive, so first try to remove divs that aren't
5967  * strictly needed.
5968  */
5969 struct isl_map *isl_basic_map_compute_divs(struct isl_basic_map *bmap)
5970 {
5971         int known;
5972         struct isl_map *map;
5973
5974         known = isl_basic_map_divs_known(bmap);
5975         if (known < 0)
5976                 goto error;
5977         if (known)
5978                 return isl_map_from_basic_map(bmap);
5979
5980         bmap = isl_basic_map_drop_redundant_divs(bmap);
5981
5982         known = isl_basic_map_divs_known(bmap);
5983         if (known < 0)
5984                 goto error;
5985         if (known)
5986                 return isl_map_from_basic_map(bmap);
5987
5988         map = compute_divs(bmap);
5989         return map;
5990 error:
5991         isl_basic_map_free(bmap);
5992         return NULL;
5993 }
5994
5995 struct isl_map *isl_map_compute_divs(struct isl_map *map)
5996 {
5997         int i;
5998         int known;
5999         struct isl_map *res;
6000
6001         if (!map)
6002                 return NULL;
6003         if (map->n == 0)
6004                 return map;
6005
6006         known = map_divs_known(map);
6007         if (known < 0) {
6008                 isl_map_free(map);
6009                 return NULL;
6010         }
6011         if (known)
6012                 return map;
6013
6014         res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
6015         for (i = 1 ; i < map->n; ++i) {
6016                 struct isl_map *r2;
6017                 r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
6018                 if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
6019                         res = isl_map_union_disjoint(res, r2);
6020                 else
6021                         res = isl_map_union(res, r2);
6022         }
6023         isl_map_free(map);
6024
6025         return res;
6026 }
6027
6028 struct isl_set *isl_basic_set_compute_divs(struct isl_basic_set *bset)
6029 {
6030         return (struct isl_set *)
6031                 isl_basic_map_compute_divs((struct isl_basic_map *)bset);
6032 }
6033
6034 struct isl_set *isl_set_compute_divs(struct isl_set *set)
6035 {
6036         return (struct isl_set *)
6037                 isl_map_compute_divs((struct isl_map *)set);
6038 }
6039
6040 struct isl_set *isl_map_domain(struct isl_map *map)
6041 {
6042         int i;
6043         struct isl_set *set;
6044
6045         if (!map)
6046                 goto error;
6047
6048         map = isl_map_cow(map);
6049         if (!map)
6050                 return NULL;
6051
6052         set = (struct isl_set *)map;
6053         set->dim = isl_space_domain(set->dim);
6054         if (!set->dim)
6055                 goto error;
6056         for (i = 0; i < map->n; ++i) {
6057                 set->p[i] = isl_basic_map_domain(map->p[i]);
6058                 if (!set->p[i])
6059                         goto error;
6060         }
6061         ISL_F_CLR(set, ISL_MAP_DISJOINT);
6062         ISL_F_CLR(set, ISL_SET_NORMALIZED);
6063         return set;
6064 error:
6065         isl_map_free(map);
6066         return NULL;
6067 }
6068
6069 static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
6070         __isl_take isl_map *map2)
6071 {
6072         int i;
6073         unsigned flags = 0;
6074         struct isl_map *map = NULL;
6075
6076         if (!map1 || !map2)
6077                 goto error;
6078
6079         if (map1->n == 0) {
6080                 isl_map_free(map1);
6081                 return map2;
6082         }
6083         if (map2->n == 0) {
6084                 isl_map_free(map2);
6085                 return map1;
6086         }
6087
6088         isl_assert(map1->ctx, isl_space_is_equal(map1->dim, map2->dim), goto error);
6089
6090         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
6091             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
6092                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
6093
6094         map = isl_map_alloc_space(isl_space_copy(map1->dim),
6095                                 map1->n + map2->n, flags);
6096         if (!map)
6097                 goto error;
6098         for (i = 0; i < map1->n; ++i) {
6099                 map = isl_map_add_basic_map(map,
6100                                   isl_basic_map_copy(map1->p[i]));
6101                 if (!map)
6102                         goto error;
6103         }
6104         for (i = 0; i < map2->n; ++i) {
6105                 map = isl_map_add_basic_map(map,
6106                                   isl_basic_map_copy(map2->p[i]));
6107                 if (!map)
6108                         goto error;
6109         }
6110         isl_map_free(map1);
6111         isl_map_free(map2);
6112         return map;
6113 error:
6114         isl_map_free(map);
6115         isl_map_free(map1);
6116         isl_map_free(map2);
6117         return NULL;
6118 }
6119
6120 __isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1,
6121         __isl_take isl_map *map2)
6122 {
6123         return isl_map_align_params_map_map_and(map1, map2, &map_union_disjoint);
6124 }
6125
6126 struct isl_map *isl_map_union(struct isl_map *map1, struct isl_map *map2)
6127 {
6128         map1 = isl_map_union_disjoint(map1, map2);
6129         if (!map1)
6130                 return NULL;
6131         if (map1->n > 1)
6132                 ISL_F_CLR(map1, ISL_MAP_DISJOINT);
6133         return map1;
6134 }
6135
6136 struct isl_set *isl_set_union_disjoint(
6137                         struct isl_set *set1, struct isl_set *set2)
6138 {
6139         return (struct isl_set *)
6140                 isl_map_union_disjoint(
6141                         (struct isl_map *)set1, (struct isl_map *)set2);
6142 }
6143
6144 struct isl_set *isl_set_union(struct isl_set *set1, struct isl_set *set2)
6145 {
6146         return (struct isl_set *)
6147                 isl_map_union((struct isl_map *)set1, (struct isl_map *)set2);
6148 }
6149
6150 static __isl_give isl_map *map_intersect_range(__isl_take isl_map *map,
6151         __isl_take isl_set *set)
6152 {
6153         unsigned flags = 0;
6154         struct isl_map *result;
6155         int i, j;
6156
6157         if (!map || !set)
6158                 goto error;
6159
6160         if (!isl_space_match(map->dim, isl_dim_param, set->dim, isl_dim_param))
6161                 isl_die(set->ctx, isl_error_invalid,
6162                         "parameters don't match", goto error);
6163
6164         if (isl_space_dim(set->dim, isl_dim_set) != 0 &&
6165             !isl_map_compatible_range(map, set))
6166                 isl_die(set->ctx, isl_error_invalid,
6167                         "incompatible spaces", goto error);
6168
6169         if (isl_set_plain_is_universe(set)) {
6170                 isl_set_free(set);
6171                 return map;
6172         }
6173
6174         if (ISL_F_ISSET(map, ISL_MAP_DISJOINT) &&
6175             ISL_F_ISSET(set, ISL_MAP_DISJOINT))
6176                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
6177
6178         result = isl_map_alloc_space(isl_space_copy(map->dim),
6179                                         map->n * set->n, flags);
6180         if (!result)
6181                 goto error;
6182         for (i = 0; i < map->n; ++i)
6183                 for (j = 0; j < set->n; ++j) {
6184                         result = isl_map_add_basic_map(result,
6185                             isl_basic_map_intersect_range(
6186                                 isl_basic_map_copy(map->p[i]),
6187                                 isl_basic_set_copy(set->p[j])));
6188                         if (!result)
6189                                 goto error;
6190                 }
6191         isl_map_free(map);
6192         isl_set_free(set);
6193         return result;
6194 error:
6195         isl_map_free(map);
6196         isl_set_free(set);
6197         return NULL;
6198 }
6199
6200 __isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map,
6201         __isl_take isl_set *set)
6202 {
6203         return isl_map_align_params_map_map_and(map, set, &map_intersect_range);
6204 }
6205
6206 struct isl_map *isl_map_intersect_domain(
6207                 struct isl_map *map, struct isl_set *set)
6208 {
6209         return isl_map_reverse(
6210                 isl_map_intersect_range(isl_map_reverse(map), set));
6211 }
6212
6213 static __isl_give isl_map *map_apply_domain(__isl_take isl_map *map1,
6214         __isl_take isl_map *map2)
6215 {
6216         if (!map1 || !map2)
6217                 goto error;
6218         map1 = isl_map_reverse(map1);
6219         map1 = isl_map_apply_range(map1, map2);
6220         return isl_map_reverse(map1);
6221 error:
6222         isl_map_free(map1);
6223         isl_map_free(map2);
6224         return NULL;
6225 }
6226
6227 __isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1,
6228         __isl_take isl_map *map2)
6229 {
6230         return isl_map_align_params_map_map_and(map1, map2, &map_apply_domain);
6231 }
6232
6233 static __isl_give isl_map *map_apply_range(__isl_take isl_map *map1,
6234         __isl_take isl_map *map2)
6235 {
6236         isl_space *dim_result;
6237         struct isl_map *result;
6238         int i, j;
6239
6240         if (!map1 || !map2)
6241                 goto error;
6242
6243         dim_result = isl_space_join(isl_space_copy(map1->dim),
6244                                   isl_space_copy(map2->dim));
6245
6246         result = isl_map_alloc_space(dim_result, map1->n * map2->n, 0);
6247         if (!result)
6248                 goto error;
6249         for (i = 0; i < map1->n; ++i)
6250                 for (j = 0; j < map2->n; ++j) {
6251                         result = isl_map_add_basic_map(result,
6252                             isl_basic_map_apply_range(
6253                                 isl_basic_map_copy(map1->p[i]),
6254                                 isl_basic_map_copy(map2->p[j])));
6255                         if (!result)
6256                                 goto error;
6257                 }
6258         isl_map_free(map1);
6259         isl_map_free(map2);
6260         if (result && result->n <= 1)
6261                 ISL_F_SET(result, ISL_MAP_DISJOINT);
6262         return result;
6263 error:
6264         isl_map_free(map1);
6265         isl_map_free(map2);
6266         return NULL;
6267 }
6268
6269 __isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1,
6270         __isl_take isl_map *map2)
6271 {
6272         return isl_map_align_params_map_map_and(map1, map2, &map_apply_range);
6273 }
6274
6275 /*
6276  * returns range - domain
6277  */
6278 struct isl_basic_set *isl_basic_map_deltas(struct isl_basic_map *bmap)
6279 {
6280         isl_space *dims, *target_dim;
6281         struct isl_basic_set *bset;
6282         unsigned dim;
6283         unsigned nparam;
6284         int i;
6285
6286         if (!bmap)
6287                 goto error;
6288         isl_assert(bmap->ctx, isl_space_tuple_match(bmap->dim, isl_dim_in,
6289                                                   bmap->dim, isl_dim_out),
6290                    goto error);
6291         target_dim = isl_space_domain(isl_basic_map_get_space(bmap));
6292         dim = isl_basic_map_n_in(bmap);
6293         nparam = isl_basic_map_n_param(bmap);
6294         bset = isl_basic_set_from_basic_map(bmap);
6295         bset = isl_basic_set_cow(bset);
6296         dims = isl_basic_set_get_space(bset);
6297         dims = isl_space_add_dims(dims, isl_dim_set, dim);
6298         bset = isl_basic_set_extend_space(bset, dims, 0, dim, 0);
6299         bset = isl_basic_set_swap_vars(bset, 2*dim);
6300         for (i = 0; i < dim; ++i) {
6301                 int j = isl_basic_map_alloc_equality(
6302                                             (struct isl_basic_map *)bset);
6303                 if (j < 0)
6304                         goto error;
6305                 isl_seq_clr(bset->eq[j], 1 + isl_basic_set_total_dim(bset));
6306                 isl_int_set_si(bset->eq[j][1+nparam+i], 1);
6307                 isl_int_set_si(bset->eq[j][1+nparam+dim+i], 1);
6308                 isl_int_set_si(bset->eq[j][1+nparam+2*dim+i], -1);
6309         }
6310         bset = isl_basic_set_project_out(bset, isl_dim_set, dim, 2*dim);
6311         bset = isl_basic_set_reset_space(bset, target_dim);
6312         return bset;
6313 error:
6314         isl_basic_map_free(bmap);
6315         return NULL;
6316 }
6317
6318 /*
6319  * returns range - domain
6320  */
6321 struct isl_set *isl_map_deltas(struct isl_map *map)
6322 {
6323         int i;
6324         isl_space *dim;
6325         struct isl_set *result;
6326
6327         if (!map)
6328                 return NULL;
6329
6330         isl_assert(map->ctx, isl_space_tuple_match(map->dim, isl_dim_in,
6331                                                  map->dim, isl_dim_out),
6332                    goto error);
6333         dim = isl_map_get_space(map);
6334         dim = isl_space_domain(dim);
6335         result = isl_set_alloc_space(dim, map->n, 0);
6336         if (!result)
6337                 goto error;
6338         for (i = 0; i < map->n; ++i)
6339                 result = isl_set_add_basic_set(result,
6340                           isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
6341         isl_map_free(map);
6342         return result;
6343 error:
6344         isl_map_free(map);
6345         return NULL;
6346 }
6347
6348 /*
6349  * returns [domain -> range] -> range - domain
6350  */
6351 __isl_give isl_basic_map *isl_basic_map_deltas_map(
6352         __isl_take isl_basic_map *bmap)
6353 {
6354         int i, k;
6355         isl_space *dim;
6356         isl_basic_map *domain;
6357         int nparam, n;
6358         unsigned total;
6359
6360         if (!isl_space_tuple_match(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out))
6361                 isl_die(bmap->ctx, isl_error_invalid,
6362                         "domain and range don't match", goto error);
6363
6364         nparam = isl_basic_map_dim(bmap, isl_dim_param);
6365         n = isl_basic_map_dim(bmap, isl_dim_in);
6366
6367         dim = isl_space_from_range(isl_space_domain(isl_basic_map_get_space(bmap)));
6368         domain = isl_basic_map_universe(dim);
6369
6370         bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
6371         bmap = isl_basic_map_apply_range(bmap, domain);
6372         bmap = isl_basic_map_extend_constraints(bmap, n, 0);
6373
6374         total = isl_basic_map_total_dim(bmap);
6375
6376         for (i = 0; i < n; ++i) {
6377                 k = isl_basic_map_alloc_equality(bmap);
6378                 if (k < 0)
6379                         goto error;
6380                 isl_seq_clr(bmap->eq[k], 1 + total);
6381                 isl_int_set_si(bmap->eq[k][1 + nparam + i], 1);
6382                 isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1);
6383                 isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1);
6384         }
6385
6386         bmap = isl_basic_map_gauss(bmap, NULL);
6387         return isl_basic_map_finalize(bmap);
6388 error:
6389         isl_basic_map_free(bmap);
6390         return NULL;
6391 }
6392
6393 /*
6394  * returns [domain -> range] -> range - domain
6395  */
6396 __isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
6397 {
6398         int i;
6399         isl_space *domain_dim;
6400
6401         if (!map)
6402                 return NULL;
6403
6404         if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
6405                 isl_die(map->ctx, isl_error_invalid,
6406                         "domain and range don't match", goto error);
6407
6408         map = isl_map_cow(map);
6409         if (!map)
6410                 return NULL;
6411
6412         domain_dim = isl_space_from_range(isl_space_domain(isl_map_get_space(map)));
6413         map->dim = isl_space_from_domain(isl_space_wrap(map->dim));
6414         map->dim = isl_space_join(map->dim, domain_dim);
6415         if (!map->dim)
6416                 goto error;
6417         for (i = 0; i < map->n; ++i) {
6418                 map->p[i] = isl_basic_map_deltas_map(map->p[i]);
6419                 if (!map->p[i])
6420                         goto error;
6421         }
6422         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
6423         return map;
6424 error:
6425         isl_map_free(map);
6426         return NULL;
6427 }
6428
6429 __isl_give struct isl_basic_map *basic_map_identity(__isl_take isl_space *dims)
6430 {
6431         struct isl_basic_map *bmap;
6432         unsigned nparam;
6433         unsigned dim;
6434         int i;
6435
6436         if (!dims)
6437                 return NULL;
6438
6439         nparam = dims->nparam;
6440         dim = dims->n_out;
6441         bmap = isl_basic_map_alloc_space(dims, 0, dim, 0);
6442         if (!bmap)
6443                 goto error;
6444
6445         for (i = 0; i < dim; ++i) {
6446                 int j = isl_basic_map_alloc_equality(bmap);
6447                 if (j < 0)
6448                         goto error;
6449                 isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
6450                 isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
6451                 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], -1);
6452         }
6453         return isl_basic_map_finalize(bmap);
6454 error:
6455         isl_basic_map_free(bmap);
6456         return NULL;
6457 }
6458
6459 __isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *dim)
6460 {
6461         if (!dim)
6462                 return NULL;
6463         if (dim->n_in != dim->n_out)
6464                 isl_die(dim->ctx, isl_error_invalid,
6465                         "number of input and output dimensions needs to be "
6466                         "the same", goto error);
6467         return basic_map_identity(dim);
6468 error:
6469         isl_space_free(dim);
6470         return NULL;
6471 }
6472
6473 struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model)
6474 {
6475         if (!model || !model->dim)
6476                 return NULL;
6477         return isl_basic_map_identity(isl_space_copy(model->dim));
6478 }
6479
6480 __isl_give isl_map *isl_map_identity(__isl_take isl_space *dim)
6481 {
6482         return isl_map_from_basic_map(isl_basic_map_identity(dim));
6483 }
6484
6485 struct isl_map *isl_map_identity_like(struct isl_map *model)
6486 {
6487         if (!model || !model->dim)
6488                 return NULL;
6489         return isl_map_identity(isl_space_copy(model->dim));
6490 }
6491
6492 struct isl_map *isl_map_identity_like_basic_map(struct isl_basic_map *model)
6493 {
6494         if (!model || !model->dim)
6495                 return NULL;
6496         return isl_map_identity(isl_space_copy(model->dim));
6497 }
6498
6499 __isl_give isl_map *isl_set_identity(__isl_take isl_set *set)
6500 {
6501         isl_space *dim = isl_set_get_space(set);
6502         isl_map *id;
6503         id = isl_map_identity(isl_space_map_from_set(dim));
6504         return isl_map_intersect_range(id, set);
6505 }
6506
6507 /* Construct a basic set with all set dimensions having only non-negative
6508  * values.
6509  */
6510 __isl_give isl_basic_set *isl_basic_set_positive_orthant(
6511         __isl_take isl_space *space)
6512 {
6513         int i;
6514         unsigned nparam;
6515         unsigned dim;
6516         struct isl_basic_set *bset;
6517
6518         if (!space)
6519                 return NULL;
6520         nparam = space->nparam;
6521         dim = space->n_out;
6522         bset = isl_basic_set_alloc_space(space, 0, 0, dim);
6523         if (!bset)
6524                 return NULL;
6525         for (i = 0; i < dim; ++i) {
6526                 int k = isl_basic_set_alloc_inequality(bset);
6527                 if (k < 0)
6528                         goto error;
6529                 isl_seq_clr(bset->ineq[k], 1 + isl_basic_set_total_dim(bset));
6530                 isl_int_set_si(bset->ineq[k][1 + nparam + i], 1);
6531         }
6532         return bset;
6533 error:
6534         isl_basic_set_free(bset);
6535         return NULL;
6536 }
6537
6538 /* Construct the half-space x_pos >= 0.
6539  */
6540 static __isl_give isl_basic_set *nonneg_halfspace(__isl_take isl_space *dim,
6541         int pos)
6542 {
6543         int k;
6544         isl_basic_set *nonneg;
6545
6546         nonneg = isl_basic_set_alloc_space(dim, 0, 0, 1);
6547         k = isl_basic_set_alloc_inequality(nonneg);
6548         if (k < 0)
6549                 goto error;
6550         isl_seq_clr(nonneg->ineq[k], 1 + isl_basic_set_total_dim(nonneg));
6551         isl_int_set_si(nonneg->ineq[k][pos], 1);
6552
6553         return isl_basic_set_finalize(nonneg);
6554 error:
6555         isl_basic_set_free(nonneg);
6556         return NULL;
6557 }
6558
6559 /* Construct the half-space x_pos <= -1.
6560  */
6561 static __isl_give isl_basic_set *neg_halfspace(__isl_take isl_space *dim, int pos)
6562 {
6563         int k;
6564         isl_basic_set *neg;
6565
6566         neg = isl_basic_set_alloc_space(dim, 0, 0, 1);
6567         k = isl_basic_set_alloc_inequality(neg);
6568         if (k < 0)
6569                 goto error;
6570         isl_seq_clr(neg->ineq[k], 1 + isl_basic_set_total_dim(neg));
6571         isl_int_set_si(neg->ineq[k][0], -1);
6572         isl_int_set_si(neg->ineq[k][pos], -1);
6573
6574         return isl_basic_set_finalize(neg);
6575 error:
6576         isl_basic_set_free(neg);
6577         return NULL;
6578 }
6579
6580 __isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set,
6581         enum isl_dim_type type, unsigned first, unsigned n)
6582 {
6583         int i;
6584         isl_basic_set *nonneg;
6585         isl_basic_set *neg;
6586
6587         if (!set)
6588                 return NULL;
6589         if (n == 0)
6590                 return set;
6591
6592         isl_assert(set->ctx, first + n <= isl_set_dim(set, type), goto error);
6593
6594         for (i = 0; i < n; ++i) {
6595                 nonneg = nonneg_halfspace(isl_set_get_space(set),
6596                                           pos(set->dim, type) + first + i);
6597                 neg = neg_halfspace(isl_set_get_space(set),
6598                                           pos(set->dim, type) + first + i);
6599
6600                 set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
6601         }
6602
6603         return set;
6604 error:
6605         isl_set_free(set);
6606         return NULL;
6607 }
6608
6609 static int foreach_orthant(__isl_take isl_set *set, int *signs, int first,
6610         int len, int (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
6611         void *user)
6612 {
6613         isl_set *half;
6614
6615         if (!set)
6616                 return -1;
6617         if (isl_set_plain_is_empty(set)) {
6618                 isl_set_free(set);
6619                 return 0;
6620         }
6621         if (first == len)
6622                 return fn(set, signs, user);
6623
6624         signs[first] = 1;
6625         half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set),
6626                                                         1 + first));
6627         half = isl_set_intersect(half, isl_set_copy(set));
6628         if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0)
6629                 goto error;
6630
6631         signs[first] = -1;
6632         half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set),
6633                                                         1 + first));
6634         half = isl_set_intersect(half, set);
6635         return foreach_orthant(half, signs, first + 1, len, fn, user);
6636 error:
6637         isl_set_free(set);
6638         return -1;
6639 }
6640
6641 /* Call "fn" on the intersections of "set" with each of the orthants
6642  * (except for obviously empty intersections).  The orthant is identified
6643  * by the signs array, with each entry having value 1 or -1 according
6644  * to the sign of the corresponding variable.
6645  */
6646 int isl_set_foreach_orthant(__isl_keep isl_set *set,
6647         int (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
6648         void *user)
6649 {
6650         unsigned nparam;
6651         unsigned nvar;
6652         int *signs;
6653         int r;
6654
6655         if (!set)
6656                 return -1;
6657         if (isl_set_plain_is_empty(set))
6658                 return 0;
6659
6660         nparam = isl_set_dim(set, isl_dim_param);
6661         nvar = isl_set_dim(set, isl_dim_set);
6662
6663         signs = isl_alloc_array(set->ctx, int, nparam + nvar);
6664
6665         r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar,
6666                             fn, user);
6667
6668         free(signs);
6669
6670         return r;
6671 }
6672
6673 int isl_set_is_equal(struct isl_set *set1, struct isl_set *set2)
6674 {
6675         return isl_map_is_equal((struct isl_map *)set1, (struct isl_map *)set2);
6676 }
6677
6678 int isl_basic_map_is_subset(
6679                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
6680 {
6681         int is_subset;
6682         struct isl_map *map1;
6683         struct isl_map *map2;
6684
6685         if (!bmap1 || !bmap2)
6686                 return -1;
6687
6688         map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
6689         map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
6690
6691         is_subset = isl_map_is_subset(map1, map2);
6692
6693         isl_map_free(map1);
6694         isl_map_free(map2);
6695
6696         return is_subset;
6697 }
6698
6699 int isl_basic_map_is_equal(
6700                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
6701 {
6702         int is_subset;
6703
6704         if (!bmap1 || !bmap2)
6705                 return -1;
6706         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
6707         if (is_subset != 1)
6708                 return is_subset;
6709         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
6710         return is_subset;
6711 }
6712
6713 int isl_basic_set_is_equal(
6714                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
6715 {
6716         return isl_basic_map_is_equal(
6717                 (struct isl_basic_map *)bset1, (struct isl_basic_map *)bset2);
6718 }
6719
6720 int isl_map_is_empty(struct isl_map *map)
6721 {
6722         int i;
6723         int is_empty;
6724
6725         if (!map)
6726                 return -1;
6727         for (i = 0; i < map->n; ++i) {
6728                 is_empty = isl_basic_map_is_empty(map->p[i]);
6729                 if (is_empty < 0)
6730                         return -1;
6731                 if (!is_empty)
6732                         return 0;
6733         }
6734         return 1;
6735 }
6736
6737 int isl_map_plain_is_empty(__isl_keep isl_map *map)
6738 {
6739         return map ? map->n == 0 : -1;
6740 }
6741
6742 int isl_map_fast_is_empty(__isl_keep isl_map *map)
6743 {
6744         return isl_map_plain_is_empty(map);
6745 }
6746
6747 int isl_set_plain_is_empty(struct isl_set *set)
6748 {
6749         return set ? set->n == 0 : -1;
6750 }
6751
6752 int isl_set_fast_is_empty(__isl_keep isl_set *set)
6753 {
6754         return isl_set_plain_is_empty(set);
6755 }
6756
6757 int isl_set_is_empty(struct isl_set *set)
6758 {
6759         return isl_map_is_empty((struct isl_map *)set);
6760 }
6761
6762 int isl_map_has_equal_space(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
6763 {
6764         if (!map1 || !map2)
6765                 return -1;
6766
6767         return isl_space_is_equal(map1->dim, map2->dim);
6768 }
6769
6770 int isl_set_has_equal_space(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
6771 {
6772         if (!set1 || !set2)
6773                 return -1;
6774
6775         return isl_space_is_equal(set1->dim, set2->dim);
6776 }
6777
6778 static int map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
6779 {
6780         int is_subset;
6781
6782         if (!map1 || !map2)
6783                 return -1;
6784         is_subset = isl_map_is_subset(map1, map2);
6785         if (is_subset != 1)
6786                 return is_subset;
6787         is_subset = isl_map_is_subset(map2, map1);
6788         return is_subset;
6789 }
6790
6791 int isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
6792 {
6793         return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
6794 }
6795
6796 int isl_basic_map_is_strict_subset(
6797                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
6798 {
6799         int is_subset;
6800
6801         if (!bmap1 || !bmap2)
6802                 return -1;
6803         is_subset = isl_basic_map_is_subset(bmap1, bmap2);
6804         if (is_subset != 1)
6805                 return is_subset;
6806         is_subset = isl_basic_map_is_subset(bmap2, bmap1);
6807         if (is_subset == -1)
6808                 return is_subset;
6809         return !is_subset;
6810 }
6811
6812 int isl_map_is_strict_subset(struct isl_map *map1, struct isl_map *map2)
6813 {
6814         int is_subset;
6815
6816         if (!map1 || !map2)
6817                 return -1;
6818         is_subset = isl_map_is_subset(map1, map2);
6819         if (is_subset != 1)
6820                 return is_subset;
6821         is_subset = isl_map_is_subset(map2, map1);
6822         if (is_subset == -1)
6823                 return is_subset;
6824         return !is_subset;
6825 }
6826
6827 int isl_set_is_strict_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
6828 {
6829         return isl_map_is_strict_subset((isl_map *)set1, (isl_map *)set2);
6830 }
6831
6832 int isl_basic_map_is_universe(struct isl_basic_map *bmap)
6833 {
6834         if (!bmap)
6835                 return -1;
6836         return bmap->n_eq == 0 && bmap->n_ineq == 0;
6837 }
6838
6839 int isl_basic_set_is_universe(struct isl_basic_set *bset)
6840 {
6841         if (!bset)
6842                 return -1;
6843         return bset->n_eq == 0 && bset->n_ineq == 0;
6844 }
6845
6846 int isl_map_plain_is_universe(__isl_keep isl_map *map)
6847 {
6848         int i;
6849
6850         if (!map)
6851                 return -1;
6852
6853         for (i = 0; i < map->n; ++i) {
6854                 int r = isl_basic_map_is_universe(map->p[i]);
6855                 if (r < 0 || r)
6856                         return r;
6857         }
6858
6859         return 0;
6860 }
6861
6862 int isl_set_plain_is_universe(__isl_keep isl_set *set)
6863 {
6864         return isl_map_plain_is_universe((isl_map *) set);
6865 }
6866
6867 int isl_set_fast_is_universe(__isl_keep isl_set *set)
6868 {
6869         return isl_set_plain_is_universe(set);
6870 }
6871
6872 int isl_basic_map_is_empty(struct isl_basic_map *bmap)
6873 {
6874         struct isl_basic_set *bset = NULL;
6875         struct isl_vec *sample = NULL;
6876         int empty;
6877         unsigned total;
6878
6879         if (!bmap)
6880                 return -1;
6881
6882         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
6883                 return 1;
6884
6885         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
6886                 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
6887                 copy = isl_basic_map_remove_redundancies(copy);
6888                 empty = ISL_F_ISSET(copy, ISL_BASIC_MAP_EMPTY);
6889                 isl_basic_map_free(copy);
6890                 return empty;
6891         }
6892
6893         total = 1 + isl_basic_map_total_dim(bmap);
6894         if (bmap->sample && bmap->sample->size == total) {
6895                 int contains = isl_basic_map_contains(bmap, bmap->sample);
6896                 if (contains < 0)
6897                         return -1;
6898                 if (contains)
6899                         return 0;
6900         }
6901         isl_vec_free(bmap->sample);
6902         bmap->sample = NULL;
6903         bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
6904         if (!bset)
6905                 return -1;
6906         sample = isl_basic_set_sample_vec(bset);
6907         if (!sample)
6908                 return -1;
6909         empty = sample->size == 0;
6910         isl_vec_free(bmap->sample);
6911         bmap->sample = sample;
6912         if (empty)
6913                 ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
6914
6915         return empty;
6916 }
6917
6918 int isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
6919 {
6920         if (!bmap)
6921                 return -1;
6922         return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY);
6923 }
6924
6925 int isl_basic_map_fast_is_empty(__isl_keep isl_basic_map *bmap)
6926 {
6927         return isl_basic_map_plain_is_empty(bmap);
6928 }
6929
6930 int isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset)
6931 {
6932         if (!bset)
6933                 return -1;
6934         return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY);
6935 }
6936
6937 int isl_basic_set_fast_is_empty(__isl_keep isl_basic_set *bset)
6938 {
6939         return isl_basic_set_plain_is_empty(bset);
6940 }
6941
6942 int isl_basic_set_is_empty(struct isl_basic_set *bset)
6943 {
6944         return isl_basic_map_is_empty((struct isl_basic_map *)bset);
6945 }
6946
6947 struct isl_map *isl_basic_map_union(
6948         struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
6949 {
6950         struct isl_map *map;
6951         if (!bmap1 || !bmap2)
6952                 goto error;
6953
6954         isl_assert(bmap1->ctx, isl_space_is_equal(bmap1->dim, bmap2->dim), goto error);
6955
6956         map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
6957         if (!map)
6958                 goto error;
6959         map = isl_map_add_basic_map(map, bmap1);
6960         map = isl_map_add_basic_map(map, bmap2);
6961         return map;
6962 error:
6963         isl_basic_map_free(bmap1);
6964         isl_basic_map_free(bmap2);
6965         return NULL;
6966 }
6967
6968 struct isl_set *isl_basic_set_union(
6969                 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
6970 {
6971         return (struct isl_set *)isl_basic_map_union(
6972                                             (struct isl_basic_map *)bset1,
6973                                             (struct isl_basic_map *)bset2);
6974 }
6975
6976 /* Order divs such that any div only depends on previous divs */
6977 struct isl_basic_map *isl_basic_map_order_divs(struct isl_basic_map *bmap)
6978 {
6979         int i;
6980         unsigned off;
6981
6982         if (!bmap)
6983                 return NULL;
6984
6985         off = isl_space_dim(bmap->dim, isl_dim_all);
6986
6987         for (i = 0; i < bmap->n_div; ++i) {
6988                 int pos;
6989                 if (isl_int_is_zero(bmap->div[i][0]))
6990                         continue;
6991                 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
6992                                                             bmap->n_div-i);
6993                 if (pos == -1)
6994                         continue;
6995                 isl_basic_map_swap_div(bmap, i, i + pos);
6996                 --i;
6997         }
6998         return bmap;
6999 }
7000
7001 struct isl_basic_set *isl_basic_set_order_divs(struct isl_basic_set *bset)
7002 {
7003         return (struct isl_basic_set *)
7004                 isl_basic_map_order_divs((struct isl_basic_map *)bset);
7005 }
7006
7007 __isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
7008 {
7009         int i;
7010
7011         if (!map)
7012                 return 0;
7013
7014         for (i = 0; i < map->n; ++i) {
7015                 map->p[i] = isl_basic_map_order_divs(map->p[i]);
7016                 if (!map->p[i])
7017                         goto error;
7018         }
7019
7020         return map;
7021 error:
7022         isl_map_free(map);
7023         return NULL;
7024 }
7025
7026 /* Apply the expansion computed by isl_merge_divs.
7027  * The expansion itself is given by "exp" while the resulting
7028  * list of divs is given by "div".
7029  */
7030 __isl_give isl_basic_set *isl_basic_set_expand_divs(
7031         __isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp)
7032 {
7033         int i, j;
7034         int n_div;
7035
7036         bset = isl_basic_set_cow(bset);
7037         if (!bset || !div)
7038                 goto error;
7039
7040         if (div->n_row < bset->n_div)
7041                 isl_die(isl_mat_get_ctx(div), isl_error_invalid,
7042                         "not an expansion", goto error);
7043
7044         bset = isl_basic_map_extend_space(bset, isl_space_copy(bset->dim),
7045                                         div->n_row - bset->n_div, 0,
7046                                         2 * (div->n_row - bset->n_div));
7047
7048         n_div = bset->n_div;
7049         for (i = n_div; i < div->n_row; ++i)
7050                 if (isl_basic_set_alloc_div(bset) < 0)
7051                         goto error;
7052
7053         j = n_div - 1;
7054         for (i = div->n_row - 1; i >= 0; --i) {
7055                 if (j >= 0 && exp[j] == i) {
7056                         if (i != j)
7057                                 isl_basic_map_swap_div(bset, i, j);
7058                         j--;
7059                 } else {
7060                         isl_seq_cpy(bset->div[i], div->row[i], div->n_col);
7061                         if (isl_basic_map_add_div_constraints(bset, i) < 0)
7062                                 goto error;
7063                 }
7064         }
7065
7066         isl_mat_free(div);
7067         return bset;
7068 error:
7069         isl_basic_set_free(bset);
7070         isl_mat_free(div);
7071         return NULL;
7072 }
7073
7074 /* Look for a div in dst that corresponds to the div "div" in src.
7075  * The divs before "div" in src and dst are assumed to be the same.
7076  * 
7077  * Returns -1 if no corresponding div was found and the position
7078  * of the corresponding div in dst otherwise.
7079  */
7080 static int find_div(struct isl_basic_map *dst,
7081                         struct isl_basic_map *src, unsigned div)
7082 {
7083         int i;
7084
7085         unsigned total = isl_space_dim(src->dim, isl_dim_all);
7086
7087         isl_assert(dst->ctx, div <= dst->n_div, return -1);
7088         for (i = div; i < dst->n_div; ++i)
7089                 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total+div) &&
7090                     isl_seq_first_non_zero(dst->div[i]+1+1+total+div,
7091                                                 dst->n_div - div) == -1)
7092                         return i;
7093         return -1;
7094 }
7095
7096 struct isl_basic_map *isl_basic_map_align_divs(
7097                 struct isl_basic_map *dst, struct isl_basic_map *src)
7098 {
7099         int i;
7100         unsigned total = isl_space_dim(src->dim, isl_dim_all);
7101
7102         if (!dst || !src)
7103                 goto error;
7104
7105         if (src->n_div == 0)
7106                 return dst;
7107
7108         for (i = 0; i < src->n_div; ++i)
7109                 isl_assert(src->ctx, !isl_int_is_zero(src->div[i][0]), goto error);
7110
7111         src = isl_basic_map_order_divs(src);
7112         dst = isl_basic_map_cow(dst);
7113         dst = isl_basic_map_extend_space(dst, isl_space_copy(dst->dim),
7114                         src->n_div, 0, 2 * src->n_div);
7115         if (!dst)
7116                 return NULL;
7117         for (i = 0; i < src->n_div; ++i) {
7118                 int j = find_div(dst, src, i);
7119                 if (j < 0) {
7120                         j = isl_basic_map_alloc_div(dst);
7121                         if (j < 0)
7122                                 goto error;
7123                         isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i);
7124                         isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i);
7125                         if (isl_basic_map_add_div_constraints(dst, j) < 0)
7126                                 goto error;
7127                 }
7128                 if (j != i)
7129                         isl_basic_map_swap_div(dst, i, j);
7130         }
7131         return dst;
7132 error:
7133         isl_basic_map_free(dst);
7134         return NULL;
7135 }
7136
7137 struct isl_basic_set *isl_basic_set_align_divs(
7138                 struct isl_basic_set *dst, struct isl_basic_set *src)
7139 {
7140         return (struct isl_basic_set *)isl_basic_map_align_divs(
7141                 (struct isl_basic_map *)dst, (struct isl_basic_map *)src);
7142 }
7143
7144 struct isl_map *isl_map_align_divs(struct isl_map *map)
7145 {
7146         int i;
7147
7148         if (!map)
7149                 return NULL;
7150         if (map->n == 0)
7151                 return map;
7152         map = isl_map_compute_divs(map);
7153         map = isl_map_cow(map);
7154         if (!map)
7155                 return NULL;
7156
7157         for (i = 1; i < map->n; ++i)
7158                 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
7159         for (i = 1; i < map->n; ++i)
7160                 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
7161
7162         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
7163         return map;
7164 }
7165
7166 struct isl_set *isl_set_align_divs(struct isl_set *set)
7167 {
7168         return (struct isl_set *)isl_map_align_divs((struct isl_map *)set);
7169 }
7170
7171 static __isl_give isl_set *set_apply( __isl_take isl_set *set,
7172         __isl_take isl_map *map)
7173 {
7174         if (!set || !map)
7175                 goto error;
7176         isl_assert(set->ctx, isl_map_compatible_domain(map, set), goto error);
7177         map = isl_map_intersect_domain(map, set);
7178         set = isl_map_range(map);
7179         return set;
7180 error:
7181         isl_set_free(set);
7182         isl_map_free(map);
7183         return NULL;
7184 }
7185
7186 __isl_give isl_set *isl_set_apply( __isl_take isl_set *set,
7187         __isl_take isl_map *map)
7188 {
7189         return isl_map_align_params_map_map_and(set, map, &set_apply);
7190 }
7191
7192 /* There is no need to cow as removing empty parts doesn't change
7193  * the meaning of the set.
7194  */
7195 struct isl_map *isl_map_remove_empty_parts(struct isl_map *map)
7196 {
7197         int i;
7198
7199         if (!map)
7200                 return NULL;
7201
7202         for (i = map->n-1; i >= 0; --i) {
7203                 if (!ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_EMPTY))
7204                         continue;
7205                 isl_basic_map_free(map->p[i]);
7206                 if (i != map->n-1) {
7207                         ISL_F_CLR(map, ISL_MAP_NORMALIZED);
7208                         map->p[i] = map->p[map->n-1];
7209                 }
7210                 map->n--;
7211         }
7212
7213         return map;
7214 }
7215
7216 struct isl_set *isl_set_remove_empty_parts(struct isl_set *set)
7217 {
7218         return (struct isl_set *)
7219                 isl_map_remove_empty_parts((struct isl_map *)set);
7220 }
7221
7222 struct isl_basic_map *isl_map_copy_basic_map(struct isl_map *map)
7223 {
7224         struct isl_basic_map *bmap;
7225         if (!map || map->n == 0)
7226                 return NULL;
7227         bmap = map->p[map->n-1];
7228         isl_assert(map->ctx, ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL), return NULL);
7229         return isl_basic_map_copy(bmap);
7230 }
7231
7232 struct isl_basic_set *isl_set_copy_basic_set(struct isl_set *set)
7233 {
7234         return (struct isl_basic_set *)
7235                 isl_map_copy_basic_map((struct isl_map *)set);
7236 }
7237
7238 __isl_give isl_map *isl_map_drop_basic_map(__isl_take isl_map *map,
7239                                                 __isl_keep isl_basic_map *bmap)
7240 {
7241         int i;
7242
7243         if (!map || !bmap)
7244                 goto error;
7245         for (i = map->n-1; i >= 0; --i) {
7246                 if (map->p[i] != bmap)
7247                         continue;
7248                 map = isl_map_cow(map);
7249                 if (!map)
7250                         goto error;
7251                 isl_basic_map_free(map->p[i]);
7252                 if (i != map->n-1) {
7253                         ISL_F_CLR(map, ISL_SET_NORMALIZED);
7254                         map->p[i] = map->p[map->n-1];
7255                 }
7256                 map->n--;
7257                 return map;
7258         }
7259         return map;
7260 error:
7261         isl_map_free(map);
7262         return NULL;
7263 }
7264
7265 struct isl_set *isl_set_drop_basic_set(struct isl_set *set,
7266                                                 struct isl_basic_set *bset)
7267 {
7268         return (struct isl_set *)isl_map_drop_basic_map((struct isl_map *)set,
7269                                                 (struct isl_basic_map *)bset);
7270 }
7271
7272 /* Given two basic sets bset1 and bset2, compute the maximal difference
7273  * between the values of dimension pos in bset1 and those in bset2
7274  * for any common value of the parameters and dimensions preceding pos.
7275  */
7276 static enum isl_lp_result basic_set_maximal_difference_at(
7277         __isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2,
7278         int pos, isl_int *opt)
7279 {
7280         isl_space *dims;
7281         struct isl_basic_map *bmap1 = NULL;
7282         struct isl_basic_map *bmap2 = NULL;
7283         struct isl_ctx *ctx;
7284         struct isl_vec *obj;
7285         unsigned total;
7286         unsigned nparam;
7287         unsigned dim1, dim2;
7288         enum isl_lp_result res;
7289
7290         if (!bset1 || !bset2)
7291                 return isl_lp_error;
7292
7293         nparam = isl_basic_set_n_param(bset1);
7294         dim1 = isl_basic_set_n_dim(bset1);
7295         dim2 = isl_basic_set_n_dim(bset2);
7296         dims = isl_space_alloc(bset1->ctx, nparam, pos, dim1 - pos);
7297         bmap1 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset1), dims);
7298         dims = isl_space_alloc(bset2->ctx, nparam, pos, dim2 - pos);
7299         bmap2 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset2), dims);
7300         if (!bmap1 || !bmap2)
7301                 goto error;
7302         bmap1 = isl_basic_map_cow(bmap1);
7303         bmap1 = isl_basic_map_extend(bmap1, nparam,
7304                         pos, (dim1 - pos) + (dim2 - pos),
7305                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
7306         bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos);
7307         if (!bmap1)
7308                 goto error;
7309         total = isl_basic_map_total_dim(bmap1);
7310         ctx = bmap1->ctx;
7311         obj = isl_vec_alloc(ctx, 1 + total);
7312         isl_seq_clr(obj->block.data, 1 + total);
7313         isl_int_set_si(obj->block.data[1+nparam+pos], 1);
7314         isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
7315         if (!obj)
7316                 goto error;
7317         res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
7318                                         opt, NULL, NULL);
7319         isl_basic_map_free(bmap1);
7320         isl_vec_free(obj);
7321         return res;
7322 error:
7323         isl_basic_map_free(bmap1);
7324         isl_basic_map_free(bmap2);
7325         return isl_lp_error;
7326 }
7327
7328 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
7329  * for any common value of the parameters and dimensions preceding pos
7330  * in both basic sets, the values of dimension pos in bset1 are
7331  * smaller or larger than those in bset2.
7332  *
7333  * Returns
7334  *       1 if bset1 follows bset2
7335  *      -1 if bset1 precedes bset2
7336  *       0 if bset1 and bset2 are incomparable
7337  *      -2 if some error occurred.
7338  */
7339 int isl_basic_set_compare_at(struct isl_basic_set *bset1,
7340         struct isl_basic_set *bset2, int pos)
7341 {
7342         isl_int opt;
7343         enum isl_lp_result res;
7344         int cmp;
7345
7346         isl_int_init(opt);
7347
7348         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
7349
7350         if (res == isl_lp_empty)
7351                 cmp = 0;
7352         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
7353                   res == isl_lp_unbounded)
7354                 cmp = 1;
7355         else if (res == isl_lp_ok && isl_int_is_neg(opt))
7356                 cmp = -1;
7357         else
7358                 cmp = -2;
7359
7360         isl_int_clear(opt);
7361         return cmp;
7362 }
7363
7364 /* Given two basic sets bset1 and bset2, check whether
7365  * for any common value of the parameters and dimensions preceding pos
7366  * there is a value of dimension pos in bset1 that is larger
7367  * than a value of the same dimension in bset2.
7368  *
7369  * Return
7370  *       1 if there exists such a pair
7371  *       0 if there is no such pair, but there is a pair of equal values
7372  *      -1 otherwise
7373  *      -2 if some error occurred.
7374  */
7375 int isl_basic_set_follows_at(__isl_keep isl_basic_set *bset1,
7376         __isl_keep isl_basic_set *bset2, int pos)
7377 {
7378         isl_int opt;
7379         enum isl_lp_result res;
7380         int cmp;
7381
7382         isl_int_init(opt);
7383
7384         res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
7385
7386         if (res == isl_lp_empty)
7387                 cmp = -1;
7388         else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
7389                   res == isl_lp_unbounded)
7390                 cmp = 1;
7391         else if (res == isl_lp_ok && isl_int_is_neg(opt))
7392                 cmp = -1;
7393         else if (res == isl_lp_ok)
7394                 cmp = 0;
7395         else
7396                 cmp = -2;
7397
7398         isl_int_clear(opt);
7399         return cmp;
7400 }
7401
7402 /* Given two sets set1 and set2, check whether
7403  * for any common value of the parameters and dimensions preceding pos
7404  * there is a value of dimension pos in set1 that is larger
7405  * than a value of the same dimension in set2.
7406  *
7407  * Return
7408  *       1 if there exists such a pair
7409  *       0 if there is no such pair, but there is a pair of equal values
7410  *      -1 otherwise
7411  *      -2 if some error occurred.
7412  */
7413 int isl_set_follows_at(__isl_keep isl_set *set1,
7414         __isl_keep isl_set *set2, int pos)
7415 {
7416         int i, j;
7417         int follows = -1;
7418
7419         if (!set1 || !set2)
7420                 return -2;
7421
7422         for (i = 0; i < set1->n; ++i)
7423                 for (j = 0; j < set2->n; ++j) {
7424                         int f;
7425                         f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
7426                         if (f == 1 || f == -2)
7427                                 return f;
7428                         if (f > follows)
7429                                 follows = f;
7430                 }
7431
7432         return follows;
7433 }
7434
7435 static int isl_basic_map_plain_has_fixed_var(__isl_keep isl_basic_map *bmap,
7436         unsigned pos, isl_int *val)
7437 {
7438         int i;
7439         int d;
7440         unsigned total;
7441
7442         if (!bmap)
7443                 return -1;
7444         total = isl_basic_map_total_dim(bmap);
7445         for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
7446                 for (; d+1 > pos; --d)
7447                         if (!isl_int_is_zero(bmap->eq[i][1+d]))
7448                                 break;
7449                 if (d != pos)
7450                         continue;
7451                 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
7452                         return 0;
7453                 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
7454                         return 0;
7455                 if (!isl_int_is_one(bmap->eq[i][1+d]))
7456                         return 0;
7457                 if (val)
7458                         isl_int_neg(*val, bmap->eq[i][0]);
7459                 return 1;
7460         }
7461         return 0;
7462 }
7463
7464 static int isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
7465         unsigned pos, isl_int *val)
7466 {
7467         int i;
7468         isl_int v;
7469         isl_int tmp;
7470         int fixed;
7471
7472         if (!map)
7473                 return -1;
7474         if (map->n == 0)
7475                 return 0;
7476         if (map->n == 1)
7477                 return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val); 
7478         isl_int_init(v);
7479         isl_int_init(tmp);
7480         fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v); 
7481         for (i = 1; fixed == 1 && i < map->n; ++i) {
7482                 fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp); 
7483                 if (fixed == 1 && isl_int_ne(tmp, v))
7484                         fixed = 0;
7485         }
7486         if (val)
7487                 isl_int_set(*val, v);
7488         isl_int_clear(tmp);
7489         isl_int_clear(v);
7490         return fixed;
7491 }
7492
7493 static int isl_basic_set_plain_has_fixed_var(__isl_keep isl_basic_set *bset,
7494         unsigned pos, isl_int *val)
7495 {
7496         return isl_basic_map_plain_has_fixed_var((struct isl_basic_map *)bset,
7497                                                 pos, val);
7498 }
7499
7500 static int isl_set_plain_has_fixed_var(__isl_keep isl_set *set, unsigned pos,
7501         isl_int *val)
7502 {
7503         return isl_map_plain_has_fixed_var((struct isl_map *)set, pos, val);
7504 }
7505
7506 int isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
7507         enum isl_dim_type type, unsigned pos, isl_int *val)
7508 {
7509         if (pos >= isl_basic_map_dim(bmap, type))
7510                 return -1;
7511         return isl_basic_map_plain_has_fixed_var(bmap,
7512                 isl_basic_map_offset(bmap, type) - 1 + pos, val);
7513 }
7514
7515 int isl_map_plain_is_fixed(__isl_keep isl_map *map,
7516         enum isl_dim_type type, unsigned pos, isl_int *val)
7517 {
7518         if (pos >= isl_map_dim(map, type))
7519                 return -1;
7520         return isl_map_plain_has_fixed_var(map,
7521                 map_offset(map, type) - 1 + pos, val);
7522 }
7523
7524 int isl_set_plain_is_fixed(__isl_keep isl_set *set,
7525         enum isl_dim_type type, unsigned pos, isl_int *val)
7526 {
7527         return isl_map_plain_is_fixed(set, type, pos, val);
7528 }
7529
7530 int isl_map_fast_is_fixed(__isl_keep isl_map *map,
7531         enum isl_dim_type type, unsigned pos, isl_int *val)
7532 {
7533         return isl_map_plain_is_fixed(map, type, pos, val);
7534 }
7535
7536 /* Check if dimension dim has fixed value and if so and if val is not NULL,
7537  * then return this fixed value in *val.
7538  */
7539 int isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset,
7540         unsigned dim, isl_int *val)
7541 {
7542         return isl_basic_set_plain_has_fixed_var(bset,
7543                                         isl_basic_set_n_param(bset) + dim, val);
7544 }
7545
7546 /* Check if dimension dim has fixed value and if so and if val is not NULL,
7547  * then return this fixed value in *val.
7548  */
7549 int isl_set_plain_dim_is_fixed(__isl_keep isl_set *set,
7550         unsigned dim, isl_int *val)
7551 {
7552         return isl_set_plain_has_fixed_var(set, isl_set_n_param(set) + dim, val);
7553 }
7554
7555 int isl_set_fast_dim_is_fixed(__isl_keep isl_set *set,
7556         unsigned dim, isl_int *val)
7557 {
7558         return isl_set_plain_dim_is_fixed(set, dim, val);
7559 }
7560
7561 /* Check if input variable in has fixed value and if so and if val is not NULL,
7562  * then return this fixed value in *val.
7563  */
7564 int isl_map_plain_input_is_fixed(__isl_keep isl_map *map,
7565         unsigned in, isl_int *val)
7566 {
7567         return isl_map_plain_has_fixed_var(map, isl_map_n_param(map) + in, val);
7568 }
7569
7570 /* Check if dimension dim has an (obvious) fixed lower bound and if so
7571  * and if val is not NULL, then return this lower bound in *val.
7572  */
7573 int isl_basic_set_plain_dim_has_fixed_lower_bound(
7574         __isl_keep isl_basic_set *bset, unsigned dim, isl_int *val)
7575 {
7576         int i, i_eq = -1, i_ineq = -1;
7577         isl_int *c;
7578         unsigned total;
7579         unsigned nparam;
7580
7581         if (!bset)
7582                 return -1;
7583         total = isl_basic_set_total_dim(bset);
7584         nparam = isl_basic_set_n_param(bset);
7585         for (i = 0; i < bset->n_eq; ++i) {
7586                 if (isl_int_is_zero(bset->eq[i][1+nparam+dim]))
7587                         continue;
7588                 if (i_eq != -1)
7589                         return 0;
7590                 i_eq = i;
7591         }
7592         for (i = 0; i < bset->n_ineq; ++i) {
7593                 if (!isl_int_is_pos(bset->ineq[i][1+nparam+dim]))
7594                         continue;
7595                 if (i_eq != -1 || i_ineq != -1)
7596                         return 0;
7597                 i_ineq = i;
7598         }
7599         if (i_eq == -1 && i_ineq == -1)
7600                 return 0;
7601         c = i_eq != -1 ? bset->eq[i_eq] : bset->ineq[i_ineq];
7602         /* The coefficient should always be one due to normalization. */
7603         if (!isl_int_is_one(c[1+nparam+dim]))
7604                 return 0;
7605         if (isl_seq_first_non_zero(c+1, nparam+dim) != -1)
7606                 return 0;
7607         if (isl_seq_first_non_zero(c+1+nparam+dim+1,
7608                                         total - nparam - dim - 1) != -1)
7609                 return 0;
7610         if (val)
7611                 isl_int_neg(*val, c[0]);
7612         return 1;
7613 }
7614
7615 int isl_set_plain_dim_has_fixed_lower_bound(__isl_keep isl_set *set,
7616         unsigned dim, isl_int *val)
7617 {
7618         int i;
7619         isl_int v;
7620         isl_int tmp;
7621         int fixed;
7622
7623         if (!set)
7624                 return -1;
7625         if (set->n == 0)
7626                 return 0;
7627         if (set->n == 1)
7628                 return isl_basic_set_plain_dim_has_fixed_lower_bound(set->p[0],
7629                                                                 dim, val);
7630         isl_int_init(v);
7631         isl_int_init(tmp);
7632         fixed = isl_basic_set_plain_dim_has_fixed_lower_bound(set->p[0],
7633                                                                 dim, &v);
7634         for (i = 1; fixed == 1 && i < set->n; ++i) {
7635                 fixed = isl_basic_set_plain_dim_has_fixed_lower_bound(set->p[i],
7636                                                                 dim, &tmp);
7637                 if (fixed == 1 && isl_int_ne(tmp, v))
7638                         fixed = 0;
7639         }
7640         if (val)
7641                 isl_int_set(*val, v);
7642         isl_int_clear(tmp);
7643         isl_int_clear(v);
7644         return fixed;
7645 }
7646
7647 struct constraint {
7648         unsigned        size;
7649         isl_int         *c;
7650 };
7651
7652 /* uset_gist depends on constraints without existentially quantified
7653  * variables sorting first.
7654  */
7655 static int qsort_constraint_cmp(const void *p1, const void *p2)
7656 {
7657         const struct constraint *c1 = (const struct constraint *)p1;
7658         const struct constraint *c2 = (const struct constraint *)p2;
7659         int l1, l2;
7660         unsigned size = isl_min(c1->size, c2->size);
7661
7662         l1 = isl_seq_last_non_zero(c1->c, size);
7663         l2 = isl_seq_last_non_zero(c2->c, size);
7664
7665         if (l1 != l2)
7666                 return l1 - l2;
7667
7668         return isl_seq_cmp(c1->c, c2->c, size);
7669 }
7670
7671 static struct isl_basic_map *isl_basic_map_sort_constraints(
7672         struct isl_basic_map *bmap)
7673 {
7674         int i;
7675         struct constraint *c;
7676         unsigned total;
7677
7678         if (!bmap)
7679                 return NULL;
7680         total = isl_basic_map_total_dim(bmap);
7681         c = isl_alloc_array(bmap->ctx, struct constraint, bmap->n_ineq);
7682         if (!c)
7683                 goto error;
7684         for (i = 0; i < bmap->n_ineq; ++i) {
7685                 c[i].size = total;
7686                 c[i].c = bmap->ineq[i];
7687         }
7688         qsort(c, bmap->n_ineq, sizeof(struct constraint), qsort_constraint_cmp);
7689         for (i = 0; i < bmap->n_ineq; ++i)
7690                 bmap->ineq[i] = c[i].c;
7691         free(c);
7692         return bmap;
7693 error:
7694         isl_basic_map_free(bmap);
7695         return NULL;
7696 }
7697
7698 __isl_give isl_basic_set *isl_basic_set_sort_constraints(
7699         __isl_take isl_basic_set *bset)
7700 {
7701         return (struct isl_basic_set *)isl_basic_map_sort_constraints(
7702                                                 (struct isl_basic_map *)bset);
7703 }
7704
7705 struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap)
7706 {
7707         if (!bmap)
7708                 return NULL;
7709         if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED))
7710                 return bmap;
7711         bmap = isl_basic_map_remove_redundancies(bmap);
7712         bmap = isl_basic_map_sort_constraints(bmap);
7713         ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
7714         return bmap;
7715 }
7716
7717 struct isl_basic_set *isl_basic_set_normalize(struct isl_basic_set *bset)
7718 {
7719         return (struct isl_basic_set *)isl_basic_map_normalize(
7720                                                 (struct isl_basic_map *)bset);
7721 }
7722
7723 int isl_basic_map_plain_cmp(const __isl_keep isl_basic_map *bmap1,
7724         const __isl_keep isl_basic_map *bmap2)
7725 {
7726         int i, cmp;
7727         unsigned total;
7728
7729         if (bmap1 == bmap2)
7730                 return 0;
7731         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) !=
7732             ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL))
7733                 return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) ? -1 : 1;
7734         if (isl_basic_map_n_param(bmap1) != isl_basic_map_n_param(bmap2))
7735                 return isl_basic_map_n_param(bmap1) - isl_basic_map_n_param(bmap2);
7736         if (isl_basic_map_n_in(bmap1) != isl_basic_map_n_in(bmap2))
7737                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
7738         if (isl_basic_map_n_out(bmap1) != isl_basic_map_n_out(bmap2))
7739                 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
7740         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
7741             ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
7742                 return 0;
7743         if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
7744                 return 1;
7745         if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
7746                 return -1;
7747         if (bmap1->n_eq != bmap2->n_eq)
7748                 return bmap1->n_eq - bmap2->n_eq;
7749         if (bmap1->n_ineq != bmap2->n_ineq)
7750                 return bmap1->n_ineq - bmap2->n_ineq;
7751         if (bmap1->n_div != bmap2->n_div)
7752                 return bmap1->n_div - bmap2->n_div;
7753         total = isl_basic_map_total_dim(bmap1);
7754         for (i = 0; i < bmap1->n_eq; ++i) {
7755                 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
7756                 if (cmp)
7757                         return cmp;
7758         }
7759         for (i = 0; i < bmap1->n_ineq; ++i) {
7760                 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
7761                 if (cmp)
7762                         return cmp;
7763         }
7764         for (i = 0; i < bmap1->n_div; ++i) {
7765                 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
7766                 if (cmp)
7767                         return cmp;
7768         }
7769         return 0;
7770 }
7771
7772 int isl_basic_set_plain_cmp(const __isl_keep isl_basic_set *bset1,
7773         const __isl_keep isl_basic_set *bset2)
7774 {
7775         return isl_basic_map_plain_cmp(bset1, bset2);
7776 }
7777
7778 int isl_set_plain_cmp(const __isl_keep isl_set *set1,
7779         const __isl_keep isl_set *set2)
7780 {
7781         int i, cmp;
7782
7783         if (set1 == set2)
7784                 return 0;
7785         if (set1->n != set2->n)
7786                 return set1->n - set2->n;
7787
7788         for (i = 0; i < set1->n; ++i) {
7789                 cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
7790                 if (cmp)
7791                         return cmp;
7792         }
7793
7794         return 0;
7795 }
7796
7797 int isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
7798         __isl_keep isl_basic_map *bmap2)
7799 {
7800         return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
7801 }
7802
7803 int isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1,
7804         __isl_keep isl_basic_set *bset2)
7805 {
7806         return isl_basic_map_plain_is_equal((isl_basic_map *)bset1,
7807                                             (isl_basic_map *)bset2);
7808 }
7809
7810 static int qsort_bmap_cmp(const void *p1, const void *p2)
7811 {
7812         const struct isl_basic_map *bmap1 = *(const struct isl_basic_map **)p1;
7813         const struct isl_basic_map *bmap2 = *(const struct isl_basic_map **)p2;
7814
7815         return isl_basic_map_plain_cmp(bmap1, bmap2);
7816 }
7817
7818 /* We normalize in place, but if anything goes wrong we need
7819  * to return NULL, so we need to make sure we don't change the
7820  * meaning of any possible other copies of map.
7821  */
7822 struct isl_map *isl_map_normalize(struct isl_map *map)
7823 {
7824         int i, j;
7825         struct isl_basic_map *bmap;
7826
7827         if (!map)
7828                 return NULL;
7829         if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED))
7830                 return map;
7831         for (i = 0; i < map->n; ++i) {
7832                 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
7833                 if (!bmap)
7834                         goto error;
7835                 isl_basic_map_free(map->p[i]);
7836                 map->p[i] = bmap;
7837         }
7838         qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
7839         ISL_F_SET(map, ISL_MAP_NORMALIZED);
7840         map = isl_map_remove_empty_parts(map);
7841         if (!map)
7842                 return NULL;
7843         for (i = map->n - 1; i >= 1; --i) {
7844                 if (!isl_basic_map_plain_is_equal(map->p[i-1], map->p[i]))
7845                         continue;
7846                 isl_basic_map_free(map->p[i-1]);
7847                 for (j = i; j < map->n; ++j)
7848                         map->p[j-1] = map->p[j];
7849                 map->n--;
7850         }
7851         return map;
7852 error:
7853         isl_map_free(map);
7854         return NULL;
7855
7856 }
7857
7858 struct isl_set *isl_set_normalize(struct isl_set *set)
7859 {
7860         return (struct isl_set *)isl_map_normalize((struct isl_map *)set);
7861 }
7862
7863 int isl_map_plain_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
7864 {
7865         int i;
7866         int equal;
7867
7868         if (!map1 || !map2)
7869                 return -1;
7870
7871         if (map1 == map2)
7872                 return 1;
7873         if (!isl_space_is_equal(map1->dim, map2->dim))
7874                 return 0;
7875
7876         map1 = isl_map_copy(map1);
7877         map2 = isl_map_copy(map2);
7878         map1 = isl_map_normalize(map1);
7879         map2 = isl_map_normalize(map2);
7880         if (!map1 || !map2)
7881                 goto error;
7882         equal = map1->n == map2->n;
7883         for (i = 0; equal && i < map1->n; ++i) {
7884                 equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
7885                 if (equal < 0)
7886                         goto error;
7887         }
7888         isl_map_free(map1);
7889         isl_map_free(map2);
7890         return equal;
7891 error:
7892         isl_map_free(map1);
7893         isl_map_free(map2);
7894         return -1;
7895 }
7896
7897 int isl_map_fast_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
7898 {
7899         return isl_map_plain_is_equal(map1, map2);
7900 }
7901
7902 int isl_set_plain_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
7903 {
7904         return isl_map_plain_is_equal((struct isl_map *)set1,
7905                                                 (struct isl_map *)set2);
7906 }
7907
7908 int isl_set_fast_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
7909 {
7910         return isl_set_plain_is_equal(set1, set2);
7911 }
7912
7913 /* Return an interval that ranges from min to max (inclusive)
7914  */
7915 struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx,
7916         isl_int min, isl_int max)
7917 {
7918         int k;
7919         struct isl_basic_set *bset = NULL;
7920
7921         bset = isl_basic_set_alloc(ctx, 0, 1, 0, 0, 2);
7922         if (!bset)
7923                 goto error;
7924
7925         k = isl_basic_set_alloc_inequality(bset);
7926         if (k < 0)
7927                 goto error;
7928         isl_int_set_si(bset->ineq[k][1], 1);
7929         isl_int_neg(bset->ineq[k][0], min);
7930
7931         k = isl_basic_set_alloc_inequality(bset);
7932         if (k < 0)
7933                 goto error;
7934         isl_int_set_si(bset->ineq[k][1], -1);
7935         isl_int_set(bset->ineq[k][0], max);
7936
7937         return bset;
7938 error:
7939         isl_basic_set_free(bset);
7940         return NULL;
7941 }
7942
7943 /* Return the Cartesian product of the basic sets in list (in the given order).
7944  */
7945 __isl_give isl_basic_set *isl_basic_set_list_product(
7946         __isl_take struct isl_basic_set_list *list)
7947 {
7948         int i;
7949         unsigned dim;
7950         unsigned nparam;
7951         unsigned extra;
7952         unsigned n_eq;
7953         unsigned n_ineq;
7954         struct isl_basic_set *product = NULL;
7955
7956         if (!list)
7957                 goto error;
7958         isl_assert(list->ctx, list->n > 0, goto error);
7959         isl_assert(list->ctx, list->p[0], goto error);
7960         nparam = isl_basic_set_n_param(list->p[0]);
7961         dim = isl_basic_set_n_dim(list->p[0]);
7962         extra = list->p[0]->n_div;
7963         n_eq = list->p[0]->n_eq;
7964         n_ineq = list->p[0]->n_ineq;
7965         for (i = 1; i < list->n; ++i) {
7966                 isl_assert(list->ctx, list->p[i], goto error);
7967                 isl_assert(list->ctx,
7968                     nparam == isl_basic_set_n_param(list->p[i]), goto error);
7969                 dim += isl_basic_set_n_dim(list->p[i]);
7970                 extra += list->p[i]->n_div;
7971                 n_eq += list->p[i]->n_eq;
7972                 n_ineq += list->p[i]->n_ineq;
7973         }
7974         product = isl_basic_set_alloc(list->ctx, nparam, dim, extra,
7975                                         n_eq, n_ineq);
7976         if (!product)
7977                 goto error;
7978         dim = 0;
7979         for (i = 0; i < list->n; ++i) {
7980                 isl_basic_set_add_constraints(product,
7981                                         isl_basic_set_copy(list->p[i]), dim);
7982                 dim += isl_basic_set_n_dim(list->p[i]);
7983         }
7984         isl_basic_set_list_free(list);
7985         return product;
7986 error:
7987         isl_basic_set_free(product);
7988         isl_basic_set_list_free(list);
7989         return NULL;
7990 }
7991
7992 struct isl_basic_map *isl_basic_map_product(
7993                 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
7994 {
7995         isl_space *dim_result = NULL;
7996         struct isl_basic_map *bmap;
7997         unsigned in1, in2, out1, out2, nparam, total, pos;
7998         struct isl_dim_map *dim_map1, *dim_map2;
7999
8000         if (!bmap1 || !bmap2)
8001                 goto error;
8002
8003         isl_assert(bmap1->ctx, isl_space_match(bmap1->dim, isl_dim_param,
8004                                      bmap2->dim, isl_dim_param), goto error);
8005         dim_result = isl_space_product(isl_space_copy(bmap1->dim),
8006                                                    isl_space_copy(bmap2->dim));
8007
8008         in1 = isl_basic_map_n_in(bmap1);
8009         in2 = isl_basic_map_n_in(bmap2);
8010         out1 = isl_basic_map_n_out(bmap1);
8011         out2 = isl_basic_map_n_out(bmap2);
8012         nparam = isl_basic_map_n_param(bmap1);
8013
8014         total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
8015         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
8016         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
8017         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
8018         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
8019         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
8020         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
8021         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
8022         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
8023         isl_dim_map_div(dim_map1, bmap1, pos += out2);
8024         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
8025
8026         bmap = isl_basic_map_alloc_space(dim_result,
8027                         bmap1->n_div + bmap2->n_div,
8028                         bmap1->n_eq + bmap2->n_eq,
8029                         bmap1->n_ineq + bmap2->n_ineq);
8030         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
8031         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
8032         bmap = isl_basic_map_simplify(bmap);
8033         return isl_basic_map_finalize(bmap);
8034 error:
8035         isl_basic_map_free(bmap1);
8036         isl_basic_map_free(bmap2);
8037         return NULL;
8038 }
8039
8040 __isl_give isl_basic_map *isl_basic_map_flat_product(
8041         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8042 {
8043         isl_basic_map *prod;
8044
8045         prod = isl_basic_map_product(bmap1, bmap2);
8046         prod = isl_basic_map_flatten(prod);
8047         return prod;
8048 }
8049
8050 __isl_give isl_basic_set *isl_basic_set_flat_product(
8051         __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
8052 {
8053         return isl_basic_map_flat_range_product(bset1, bset2);
8054 }
8055
8056 __isl_give isl_basic_map *isl_basic_map_domain_product(
8057         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8058 {
8059         isl_space *space_result = NULL;
8060         isl_basic_map *bmap;
8061         unsigned in1, in2, out, nparam, total, pos;
8062         struct isl_dim_map *dim_map1, *dim_map2;
8063
8064         if (!bmap1 || !bmap2)
8065                 goto error;
8066
8067         space_result = isl_space_domain_product(isl_space_copy(bmap1->dim),
8068                                                 isl_space_copy(bmap2->dim));
8069
8070         in1 = isl_basic_map_dim(bmap1, isl_dim_in);
8071         in2 = isl_basic_map_dim(bmap2, isl_dim_in);
8072         out = isl_basic_map_dim(bmap1, isl_dim_out);
8073         nparam = isl_basic_map_dim(bmap1, isl_dim_param);
8074
8075         total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
8076         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
8077         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
8078         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
8079         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
8080         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
8081         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
8082         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
8083         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
8084         isl_dim_map_div(dim_map1, bmap1, pos += out);
8085         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
8086
8087         bmap = isl_basic_map_alloc_space(space_result,
8088                         bmap1->n_div + bmap2->n_div,
8089                         bmap1->n_eq + bmap2->n_eq,
8090                         bmap1->n_ineq + bmap2->n_ineq);
8091         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
8092         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
8093         bmap = isl_basic_map_simplify(bmap);
8094         return isl_basic_map_finalize(bmap);
8095 error:
8096         isl_basic_map_free(bmap1);
8097         isl_basic_map_free(bmap2);
8098         return NULL;
8099 }
8100
8101 __isl_give isl_basic_map *isl_basic_map_range_product(
8102         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8103 {
8104         isl_space *dim_result = NULL;
8105         isl_basic_map *bmap;
8106         unsigned in, out1, out2, nparam, total, pos;
8107         struct isl_dim_map *dim_map1, *dim_map2;
8108
8109         if (!bmap1 || !bmap2)
8110                 goto error;
8111
8112         dim_result = isl_space_range_product(isl_space_copy(bmap1->dim),
8113                                            isl_space_copy(bmap2->dim));
8114
8115         in = isl_basic_map_dim(bmap1, isl_dim_in);
8116         out1 = isl_basic_map_n_out(bmap1);
8117         out2 = isl_basic_map_n_out(bmap2);
8118         nparam = isl_basic_map_n_param(bmap1);
8119
8120         total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
8121         dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
8122         dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
8123         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
8124         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
8125         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
8126         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
8127         isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
8128         isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
8129         isl_dim_map_div(dim_map1, bmap1, pos += out2);
8130         isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
8131
8132         bmap = isl_basic_map_alloc_space(dim_result,
8133                         bmap1->n_div + bmap2->n_div,
8134                         bmap1->n_eq + bmap2->n_eq,
8135                         bmap1->n_ineq + bmap2->n_ineq);
8136         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
8137         bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
8138         bmap = isl_basic_map_simplify(bmap);
8139         return isl_basic_map_finalize(bmap);
8140 error:
8141         isl_basic_map_free(bmap1);
8142         isl_basic_map_free(bmap2);
8143         return NULL;
8144 }
8145
8146 __isl_give isl_basic_map *isl_basic_map_flat_range_product(
8147         __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
8148 {
8149         isl_basic_map *prod;
8150
8151         prod = isl_basic_map_range_product(bmap1, bmap2);
8152         prod = isl_basic_map_flatten_range(prod);
8153         return prod;
8154 }
8155
8156 static __isl_give isl_map *map_product(__isl_take isl_map *map1,
8157         __isl_take isl_map *map2,
8158         __isl_give isl_space *(*dim_product)(__isl_take isl_space *left,
8159                                            __isl_take isl_space *right),
8160         __isl_give isl_basic_map *(*basic_map_product)(
8161                 __isl_take isl_basic_map *left, __isl_take isl_basic_map *right))
8162 {
8163         unsigned flags = 0;
8164         struct isl_map *result;
8165         int i, j;
8166
8167         if (!map1 || !map2)
8168                 goto error;
8169
8170         isl_assert(map1->ctx, isl_space_match(map1->dim, isl_dim_param,
8171                                          map2->dim, isl_dim_param), goto error);
8172
8173         if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
8174             ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
8175                 ISL_FL_SET(flags, ISL_MAP_DISJOINT);
8176
8177         result = isl_map_alloc_space(dim_product(isl_space_copy(map1->dim),
8178                                                isl_space_copy(map2->dim)),
8179                                 map1->n * map2->n, flags);
8180         if (!result)
8181                 goto error;
8182         for (i = 0; i < map1->n; ++i)
8183                 for (j = 0; j < map2->n; ++j) {
8184                         struct isl_basic_map *part;
8185                         part = basic_map_product(isl_basic_map_copy(map1->p[i]),
8186                                                  isl_basic_map_copy(map2->p[j]));
8187                         if (isl_basic_map_is_empty(part))
8188                                 isl_basic_map_free(part);
8189                         else
8190                                 result = isl_map_add_basic_map(result, part);
8191                         if (!result)
8192                                 goto error;
8193                 }
8194         isl_map_free(map1);
8195         isl_map_free(map2);
8196         return result;
8197 error:
8198         isl_map_free(map1);
8199         isl_map_free(map2);
8200         return NULL;
8201 }
8202
8203 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
8204  */
8205 static __isl_give isl_map *map_product_aligned(__isl_take isl_map *map1,
8206         __isl_take isl_map *map2)
8207 {
8208         return map_product(map1, map2, &isl_space_product, &isl_basic_map_product);
8209 }
8210
8211 __isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
8212         __isl_take isl_map *map2)
8213 {
8214         return isl_map_align_params_map_map_and(map1, map2, &map_product_aligned);
8215 }
8216
8217 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
8218  */
8219 __isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
8220         __isl_take isl_map *map2)
8221 {
8222         isl_map *prod;
8223
8224         prod = isl_map_product(map1, map2);
8225         prod = isl_map_flatten(prod);
8226         return prod;
8227 }
8228
8229 /* Given two set A and B, construct its Cartesian product A x B.
8230  */
8231 struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2)
8232 {
8233         return isl_map_range_product(set1, set2);
8234 }
8235
8236 __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
8237         __isl_take isl_set *set2)
8238 {
8239         return isl_map_flat_range_product(set1, set2);
8240 }
8241
8242 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
8243  */
8244 static __isl_give isl_map *map_domain_product_aligned(__isl_take isl_map *map1,
8245         __isl_take isl_map *map2)
8246 {
8247         return map_product(map1, map2, &isl_space_domain_product,
8248                                 &isl_basic_map_domain_product);
8249 }
8250
8251 /* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
8252  */
8253 static __isl_give isl_map *map_range_product_aligned(__isl_take isl_map *map1,
8254         __isl_take isl_map *map2)
8255 {
8256         return map_product(map1, map2, &isl_space_range_product,
8257                                 &isl_basic_map_range_product);
8258 }
8259
8260 __isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
8261         __isl_take isl_map *map2)
8262 {
8263         return isl_map_align_params_map_map_and(map1, map2,
8264                                                 &map_domain_product_aligned);
8265 }
8266
8267 __isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
8268         __isl_take isl_map *map2)
8269 {
8270         return isl_map_align_params_map_map_and(map1, map2,
8271                                                 &map_range_product_aligned);
8272 }
8273
8274 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
8275  */
8276 __isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
8277         __isl_take isl_map *map2)
8278 {
8279         isl_map *prod;
8280
8281         prod = isl_map_domain_product(map1, map2);
8282         prod = isl_map_flatten_domain(prod);
8283         return prod;
8284 }
8285
8286 /* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
8287  */
8288 __isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
8289         __isl_take isl_map *map2)
8290 {
8291         isl_map *prod;
8292
8293         prod = isl_map_range_product(map1, map2);
8294         prod = isl_map_flatten_range(prod);
8295         return prod;
8296 }
8297
8298 uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
8299 {
8300         int i;
8301         uint32_t hash = isl_hash_init();
8302         unsigned total;
8303
8304         if (!bmap)
8305                 return 0;
8306         bmap = isl_basic_map_copy(bmap);
8307         bmap = isl_basic_map_normalize(bmap);
8308         if (!bmap)
8309                 return 0;
8310         total = isl_basic_map_total_dim(bmap);
8311         isl_hash_byte(hash, bmap->n_eq & 0xFF);
8312         for (i = 0; i < bmap->n_eq; ++i) {
8313                 uint32_t c_hash;
8314                 c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
8315                 isl_hash_hash(hash, c_hash);
8316         }
8317         isl_hash_byte(hash, bmap->n_ineq & 0xFF);
8318         for (i = 0; i < bmap->n_ineq; ++i) {
8319                 uint32_t c_hash;
8320                 c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
8321                 isl_hash_hash(hash, c_hash);
8322         }
8323         isl_hash_byte(hash, bmap->n_div & 0xFF);
8324         for (i = 0; i < bmap->n_div; ++i) {
8325                 uint32_t c_hash;
8326                 if (isl_int_is_zero(bmap->div[i][0]))
8327                         continue;
8328                 isl_hash_byte(hash, i & 0xFF);
8329                 c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
8330                 isl_hash_hash(hash, c_hash);
8331         }
8332         isl_basic_map_free(bmap);
8333         return hash;
8334 }
8335
8336 uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_set *bset)
8337 {
8338         return isl_basic_map_get_hash((isl_basic_map *)bset);
8339 }
8340
8341 uint32_t isl_map_get_hash(__isl_keep isl_map *map)
8342 {
8343         int i;
8344         uint32_t hash;
8345
8346         if (!map)
8347                 return 0;
8348         map = isl_map_copy(map);
8349         map = isl_map_normalize(map);
8350         if (!map)
8351                 return 0;
8352
8353         hash = isl_hash_init();
8354         for (i = 0; i < map->n; ++i) {
8355                 uint32_t bmap_hash;
8356                 bmap_hash = isl_basic_map_get_hash(map->p[i]);
8357                 isl_hash_hash(hash, bmap_hash);
8358         }
8359                 
8360         isl_map_free(map);
8361
8362         return hash;
8363 }
8364
8365 uint32_t isl_set_get_hash(__isl_keep isl_set *set)
8366 {
8367         return isl_map_get_hash((isl_map *)set);
8368 }
8369
8370 /* Check if the value for dimension dim is completely determined
8371  * by the values of the other parameters and variables.
8372  * That is, check if dimension dim is involved in an equality.
8373  */
8374 int isl_basic_set_dim_is_unique(struct isl_basic_set *bset, unsigned dim)
8375 {
8376         int i;
8377         unsigned nparam;
8378
8379         if (!bset)
8380                 return -1;
8381         nparam = isl_basic_set_n_param(bset);
8382         for (i = 0; i < bset->n_eq; ++i)
8383                 if (!isl_int_is_zero(bset->eq[i][1 + nparam + dim]))
8384                         return 1;
8385         return 0;
8386 }
8387
8388 /* Check if the value for dimension dim is completely determined
8389  * by the values of the other parameters and variables.
8390  * That is, check if dimension dim is involved in an equality
8391  * for each of the subsets.
8392  */
8393 int isl_set_dim_is_unique(struct isl_set *set, unsigned dim)
8394 {
8395         int i;
8396
8397         if (!set)
8398                 return -1;
8399         for (i = 0; i < set->n; ++i) {
8400                 int unique;
8401                 unique = isl_basic_set_dim_is_unique(set->p[i], dim);
8402                 if (unique != 1)
8403                         return unique;
8404         }
8405         return 1;
8406 }
8407
8408 int isl_set_n_basic_set(__isl_keep isl_set *set)
8409 {
8410         return set ? set->n : 0;
8411 }
8412
8413 int isl_map_foreach_basic_map(__isl_keep isl_map *map,
8414         int (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
8415 {
8416         int i;
8417
8418         if (!map)
8419                 return -1;
8420
8421         for (i = 0; i < map->n; ++i)
8422                 if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
8423                         return -1;
8424
8425         return 0;
8426 }
8427
8428 int isl_set_foreach_basic_set(__isl_keep isl_set *set,
8429         int (*fn)(__isl_take isl_basic_set *bset, void *user), void *user)
8430 {
8431         int i;
8432
8433         if (!set)
8434                 return -1;
8435
8436         for (i = 0; i < set->n; ++i)
8437                 if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
8438                         return -1;
8439
8440         return 0;
8441 }
8442
8443 __isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset)
8444 {
8445         isl_space *dim;
8446
8447         if (!bset)
8448                 return NULL;
8449
8450         bset = isl_basic_set_cow(bset);
8451         if (!bset)
8452                 return NULL;
8453
8454         dim = isl_basic_set_get_space(bset);
8455         dim = isl_space_lift(dim, bset->n_div);
8456         if (!dim)
8457                 goto error;
8458         isl_space_free(bset->dim);
8459         bset->dim = dim;
8460         bset->extra -= bset->n_div;
8461         bset->n_div = 0;
8462
8463         bset = isl_basic_set_finalize(bset);
8464
8465         return bset;
8466 error:
8467         isl_basic_set_free(bset);
8468         return NULL;
8469 }
8470
8471 __isl_give isl_set *isl_set_lift(__isl_take isl_set *set)
8472 {
8473         int i;
8474         isl_space *dim;
8475         unsigned n_div;
8476
8477         set = isl_set_align_divs(set);
8478
8479         if (!set)
8480                 return NULL;
8481
8482         set = isl_set_cow(set);
8483         if (!set)
8484                 return NULL;
8485
8486         n_div = set->p[0]->n_div;
8487         dim = isl_set_get_space(set);
8488         dim = isl_space_lift(dim, n_div);
8489         if (!dim)
8490                 goto error;
8491         isl_space_free(set->dim);
8492         set->dim = dim;
8493
8494         for (i = 0; i < set->n; ++i) {
8495                 set->p[i] = isl_basic_set_lift(set->p[i]);
8496                 if (!set->p[i])
8497                         goto error;
8498         }
8499
8500         return set;
8501 error:
8502         isl_set_free(set);
8503         return NULL;
8504 }
8505
8506 __isl_give isl_map *isl_set_lifting(__isl_take isl_set *set)
8507 {
8508         isl_space *dim;
8509         struct isl_basic_map *bmap;
8510         unsigned n_set;
8511         unsigned n_div;
8512         unsigned n_param;
8513         unsigned total;
8514         int i, k, l;
8515
8516         set = isl_set_align_divs(set);
8517
8518         if (!set)
8519                 return NULL;
8520
8521         dim = isl_set_get_space(set);
8522         if (set->n == 0 || set->p[0]->n_div == 0) {
8523                 isl_set_free(set);
8524                 return isl_map_identity(isl_space_map_from_set(dim));
8525         }
8526
8527         n_div = set->p[0]->n_div;
8528         dim = isl_space_map_from_set(dim);
8529         n_param = isl_space_dim(dim, isl_dim_param);
8530         n_set = isl_space_dim(dim, isl_dim_in);
8531         dim = isl_space_extend(dim, n_param, n_set, n_set + n_div);
8532         bmap = isl_basic_map_alloc_space(dim, 0, n_set, 2 * n_div);
8533         for (i = 0; i < n_set; ++i)
8534                 bmap = var_equal(bmap, i);
8535
8536         total = n_param + n_set + n_set + n_div;
8537         for (i = 0; i < n_div; ++i) {
8538                 k = isl_basic_map_alloc_inequality(bmap);
8539                 if (k < 0)
8540                         goto error;
8541                 isl_seq_cpy(bmap->ineq[k], set->p[0]->div[i]+1, 1+n_param);
8542                 isl_seq_clr(bmap->ineq[k]+1+n_param, n_set);
8543                 isl_seq_cpy(bmap->ineq[k]+1+n_param+n_set,
8544                             set->p[0]->div[i]+1+1+n_param, n_set + n_div);
8545                 isl_int_neg(bmap->ineq[k][1+n_param+n_set+n_set+i],
8546                             set->p[0]->div[i][0]);
8547
8548                 l = isl_basic_map_alloc_inequality(bmap);
8549                 if (l < 0)
8550                         goto error;
8551                 isl_seq_neg(bmap->ineq[l], bmap->ineq[k], 1 + total);
8552                 isl_int_add(bmap->ineq[l][0], bmap->ineq[l][0],
8553                             set->p[0]->div[i][0]);
8554                 isl_int_sub_ui(bmap->ineq[l][0], bmap->ineq[l][0], 1);
8555         }
8556
8557         isl_set_free(set);
8558         bmap = isl_basic_map_simplify(bmap);
8559         bmap = isl_basic_map_finalize(bmap);
8560         return isl_map_from_basic_map(bmap);
8561 error:
8562         isl_set_free(set);
8563         isl_basic_map_free(bmap);
8564         return NULL;
8565 }
8566
8567 int isl_basic_set_size(__isl_keep isl_basic_set *bset)
8568 {
8569         unsigned dim;
8570         int size = 0;
8571
8572         if (!bset)
8573                 return -1;
8574
8575         dim = isl_basic_set_total_dim(bset);
8576         size += bset->n_eq * (1 + dim);
8577         size += bset->n_ineq * (1 + dim);
8578         size += bset->n_div * (2 + dim);
8579
8580         return size;
8581 }
8582
8583 int isl_set_size(__isl_keep isl_set *set)
8584 {
8585         int i;
8586         int size = 0;
8587
8588         if (!set)
8589                 return -1;
8590
8591         for (i = 0; i < set->n; ++i)
8592                 size += isl_basic_set_size(set->p[i]);
8593
8594         return size;
8595 }
8596
8597 /* Check if there is any lower bound (if lower == 0) and/or upper
8598  * bound (if upper == 0) on the specified dim.
8599  */
8600 static int basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
8601         enum isl_dim_type type, unsigned pos, int lower, int upper)
8602 {
8603         int i;
8604
8605         if (!bmap)
8606                 return -1;
8607
8608         isl_assert(bmap->ctx, pos < isl_basic_map_dim(bmap, type), return -1);
8609
8610         pos += isl_basic_map_offset(bmap, type);
8611
8612         for (i = 0; i < bmap->n_div; ++i) {
8613                 if (isl_int_is_zero(bmap->div[i][0]))
8614                         continue;
8615                 if (!isl_int_is_zero(bmap->div[i][1 + pos]))
8616                         return 1;
8617         }
8618
8619         for (i = 0; i < bmap->n_eq; ++i)
8620                 if (!isl_int_is_zero(bmap->eq[i][pos]))
8621                         return 1;
8622
8623         for (i = 0; i < bmap->n_ineq; ++i) {
8624                 int sgn = isl_int_sgn(bmap->ineq[i][pos]);
8625                 if (sgn > 0)
8626                         lower = 1;
8627                 if (sgn < 0)
8628                         upper = 1;
8629         }
8630
8631         return lower && upper;
8632 }
8633
8634 int isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
8635         enum isl_dim_type type, unsigned pos)
8636 {
8637         return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
8638 }
8639
8640 int isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap,
8641         enum isl_dim_type type, unsigned pos)
8642 {
8643         return basic_map_dim_is_bounded(bmap, type, pos, 0, 1);
8644 }
8645
8646 int isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap,
8647         enum isl_dim_type type, unsigned pos)
8648 {
8649         return basic_map_dim_is_bounded(bmap, type, pos, 1, 0);
8650 }
8651
8652 int isl_map_dim_is_bounded(__isl_keep isl_map *map,
8653         enum isl_dim_type type, unsigned pos)
8654 {
8655         int i;
8656
8657         if (!map)
8658                 return -1;
8659
8660         for (i = 0; i < map->n; ++i) {
8661                 int bounded;
8662                 bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
8663                 if (bounded < 0 || !bounded)
8664                         return bounded;
8665         }
8666
8667         return 1;
8668 }
8669
8670 /* Return 1 if the specified dim is involved in both an upper bound
8671  * and a lower bound.
8672  */
8673 int isl_set_dim_is_bounded(__isl_keep isl_set *set,
8674         enum isl_dim_type type, unsigned pos)
8675 {
8676         return isl_map_dim_is_bounded((isl_map *)set, type, pos);
8677 }
8678
8679 static int has_bound(__isl_keep isl_map *map,
8680         enum isl_dim_type type, unsigned pos,
8681         int (*fn)(__isl_keep isl_basic_map *bmap,
8682                   enum isl_dim_type type, unsigned pos))
8683 {
8684         int i;
8685
8686         if (!map)
8687                 return -1;
8688
8689         for (i = 0; i < map->n; ++i) {
8690                 int bounded;
8691                 bounded = fn(map->p[i], type, pos);
8692                 if (bounded < 0 || bounded)
8693                         return bounded;
8694         }
8695
8696         return 0;
8697 }
8698
8699 /* Return 1 if the specified dim is involved in any lower bound.
8700  */
8701 int isl_set_dim_has_lower_bound(__isl_keep isl_set *set,
8702         enum isl_dim_type type, unsigned pos)
8703 {
8704         return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound);
8705 }
8706
8707 /* Return 1 if the specified dim is involved in any upper bound.
8708  */
8709 int isl_set_dim_has_upper_bound(__isl_keep isl_set *set,
8710         enum isl_dim_type type, unsigned pos)
8711 {
8712         return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound);
8713 }
8714
8715 /* For each of the "n" variables starting at "first", determine
8716  * the sign of the variable and put the results in the first "n"
8717  * elements of the array "signs".
8718  * Sign
8719  *      1 means that the variable is non-negative
8720  *      -1 means that the variable is non-positive
8721  *      0 means the variable attains both positive and negative values.
8722  */
8723 int isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset,
8724         unsigned first, unsigned n, int *signs)
8725 {
8726         isl_vec *bound = NULL;
8727         struct isl_tab *tab = NULL;
8728         struct isl_tab_undo *snap;
8729         int i;
8730
8731         if (!bset || !signs)
8732                 return -1;
8733
8734         bound = isl_vec_alloc(bset->ctx, 1 + isl_basic_set_total_dim(bset));
8735         tab = isl_tab_from_basic_set(bset, 0);
8736         if (!bound || !tab)
8737                 goto error;
8738
8739         isl_seq_clr(bound->el, bound->size);
8740         isl_int_set_si(bound->el[0], -1);
8741
8742         snap = isl_tab_snap(tab);
8743         for (i = 0; i < n; ++i) {
8744                 int empty;
8745
8746                 isl_int_set_si(bound->el[1 + first + i], -1);
8747                 if (isl_tab_add_ineq(tab, bound->el) < 0)
8748                         goto error;
8749                 empty = tab->empty;
8750                 isl_int_set_si(bound->el[1 + first + i], 0);
8751                 if (isl_tab_rollback(tab, snap) < 0)
8752                         goto error;
8753
8754                 if (empty) {
8755                         signs[i] = 1;
8756                         continue;
8757                 }
8758
8759                 isl_int_set_si(bound->el[1 + first + i], 1);
8760                 if (isl_tab_add_ineq(tab, bound->el) < 0)
8761                         goto error;
8762                 empty = tab->empty;
8763                 isl_int_set_si(bound->el[1 + first + i], 0);
8764                 if (isl_tab_rollback(tab, snap) < 0)
8765                         goto error;
8766
8767                 signs[i] = empty ? -1 : 0;
8768         }
8769
8770         isl_tab_free(tab);
8771         isl_vec_free(bound);
8772         return 0;
8773 error:
8774         isl_tab_free(tab);
8775         isl_vec_free(bound);
8776         return -1;
8777 }
8778
8779 int isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset,
8780         enum isl_dim_type type, unsigned first, unsigned n, int *signs)
8781 {
8782         if (!bset || !signs)
8783                 return -1;
8784         isl_assert(bset->ctx, first + n <= isl_basic_set_dim(bset, type),
8785                 return -1);
8786
8787         first += pos(bset->dim, type) - 1;
8788         return isl_basic_set_vars_get_sign(bset, first, n, signs);
8789 }
8790
8791 /* Check if the given basic map is obviously single-valued.
8792  * In particular, for each output dimension, check that there is
8793  * an equality that defines the output dimension in terms of
8794  * earlier dimensions.
8795  */
8796 int isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
8797 {
8798         int i, j;
8799         unsigned total;
8800         unsigned n_out;
8801         unsigned o_out;
8802
8803         if (!bmap)
8804                 return -1;
8805
8806         total = 1 + isl_basic_map_total_dim(bmap);
8807         n_out = isl_basic_map_dim(bmap, isl_dim_out);
8808         o_out = isl_basic_map_offset(bmap, isl_dim_out);
8809
8810         for (i = 0; i < n_out; ++i) {
8811                 for (j = 0; j < bmap->n_eq; ++j) {
8812                         if (isl_int_is_zero(bmap->eq[j][o_out + i]))
8813                                 continue;
8814                         if (isl_seq_first_non_zero(bmap->eq[j] + o_out + i + 1,
8815                                                 total - (o_out + i + 1)) == -1)
8816                                 break;
8817                 }
8818                 if (j >= bmap->n_eq)
8819                         return 0;
8820         }
8821
8822         return 1;
8823 }
8824
8825 /* Check if the given map is obviously single-valued.
8826  */
8827 int isl_map_plain_is_single_valued(__isl_keep isl_map *map)
8828 {
8829         if (!map)
8830                 return -1;
8831         if (map->n == 0)
8832                 return 1;
8833         if (map->n >= 2)
8834                 return 0;
8835
8836         return isl_basic_map_plain_is_single_valued(map->p[0]);
8837 }
8838
8839 /* Check if the given map is single-valued.
8840  * We simply compute
8841  *
8842  *      M \circ M^-1
8843  *
8844  * and check if the result is a subset of the identity mapping.
8845  */
8846 int isl_map_is_single_valued(__isl_keep isl_map *map)
8847 {
8848         isl_space *dim;
8849         isl_map *test;
8850         isl_map *id;
8851         int sv;
8852
8853         sv = isl_map_plain_is_single_valued(map);
8854         if (sv < 0 || sv)
8855                 return sv;
8856
8857         test = isl_map_reverse(isl_map_copy(map));
8858         test = isl_map_apply_range(test, isl_map_copy(map));
8859
8860         dim = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
8861         id = isl_map_identity(dim);
8862
8863         sv = isl_map_is_subset(test, id);
8864
8865         isl_map_free(test);
8866         isl_map_free(id);
8867
8868         return sv;
8869 }
8870
8871 int isl_map_is_injective(__isl_keep isl_map *map)
8872 {
8873         int in;
8874
8875         map = isl_map_copy(map);
8876         map = isl_map_reverse(map);
8877         in = isl_map_is_single_valued(map);
8878         isl_map_free(map);
8879
8880         return in;
8881 }
8882
8883 /* Check if the given map is obviously injective.
8884  */
8885 int isl_map_plain_is_injective(__isl_keep isl_map *map)
8886 {
8887         int in;
8888
8889         map = isl_map_copy(map);
8890         map = isl_map_reverse(map);
8891         in = isl_map_plain_is_single_valued(map);
8892         isl_map_free(map);
8893
8894         return in;
8895 }
8896
8897 int isl_map_is_bijective(__isl_keep isl_map *map)
8898 {
8899         int sv;
8900
8901         sv = isl_map_is_single_valued(map);
8902         if (sv < 0 || !sv)
8903                 return sv;
8904
8905         return isl_map_is_injective(map);
8906 }
8907
8908 int isl_set_is_singleton(__isl_keep isl_set *set)
8909 {
8910         return isl_map_is_single_valued((isl_map *)set);
8911 }
8912
8913 int isl_map_is_translation(__isl_keep isl_map *map)
8914 {
8915         int ok;
8916         isl_set *delta;
8917
8918         delta = isl_map_deltas(isl_map_copy(map));
8919         ok = isl_set_is_singleton(delta);
8920         isl_set_free(delta);
8921
8922         return ok;
8923 }
8924
8925 static int unique(isl_int *p, unsigned pos, unsigned len)
8926 {
8927         if (isl_seq_first_non_zero(p, pos) != -1)
8928                 return 0;
8929         if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
8930                 return 0;
8931         return 1;
8932 }
8933
8934 int isl_basic_set_is_box(__isl_keep isl_basic_set *bset)
8935 {
8936         int i, j;
8937         unsigned nvar;
8938         unsigned ovar;
8939
8940         if (!bset)
8941                 return -1;
8942
8943         if (isl_basic_set_dim(bset, isl_dim_div) != 0)
8944                 return 0;
8945
8946         nvar = isl_basic_set_dim(bset, isl_dim_set);
8947         ovar = isl_space_offset(bset->dim, isl_dim_set);
8948         for (j = 0; j < nvar; ++j) {
8949                 int lower = 0, upper = 0;
8950                 for (i = 0; i < bset->n_eq; ++i) {
8951                         if (isl_int_is_zero(bset->eq[i][1 + ovar + j]))
8952                                 continue;
8953                         if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
8954                                 return 0;
8955                         break;
8956                 }
8957                 if (i < bset->n_eq)
8958                         continue;
8959                 for (i = 0; i < bset->n_ineq; ++i) {
8960                         if (isl_int_is_zero(bset->ineq[i][1 + ovar + j]))
8961                                 continue;
8962                         if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
8963                                 return 0;
8964                         if (isl_int_is_pos(bset->ineq[i][1 + ovar + j]))
8965                                 lower = 1;
8966                         else
8967                                 upper = 1;
8968                 }
8969                 if (!lower || !upper)
8970                         return 0;
8971         }
8972
8973         return 1;
8974 }
8975
8976 int isl_set_is_box(__isl_keep isl_set *set)
8977 {
8978         if (!set)
8979                 return -1;
8980         if (set->n != 1)
8981                 return 0;
8982
8983         return isl_basic_set_is_box(set->p[0]);
8984 }
8985
8986 int isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset)
8987 {
8988         if (!bset)
8989                 return -1;
8990         
8991         return isl_space_is_wrapping(bset->dim);
8992 }
8993
8994 int isl_set_is_wrapping(__isl_keep isl_set *set)
8995 {
8996         if (!set)
8997                 return -1;
8998         
8999         return isl_space_is_wrapping(set->dim);
9000 }
9001
9002 __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
9003 {
9004         bmap = isl_basic_map_cow(bmap);
9005         if (!bmap)
9006                 return NULL;
9007
9008         bmap->dim = isl_space_wrap(bmap->dim);
9009         if (!bmap->dim)
9010                 goto error;
9011
9012         bmap = isl_basic_map_finalize(bmap);
9013
9014         return (isl_basic_set *)bmap;
9015 error:
9016         isl_basic_map_free(bmap);
9017         return NULL;
9018 }
9019
9020 __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map)
9021 {
9022         int i;
9023
9024         map = isl_map_cow(map);
9025         if (!map)
9026                 return NULL;
9027
9028         for (i = 0; i < map->n; ++i) {
9029                 map->p[i] = (isl_basic_map *)isl_basic_map_wrap(map->p[i]);
9030                 if (!map->p[i])
9031                         goto error;
9032         }
9033         map->dim = isl_space_wrap(map->dim);
9034         if (!map->dim)
9035                 goto error;
9036
9037         return (isl_set *)map;
9038 error:
9039         isl_map_free(map);
9040         return NULL;
9041 }
9042
9043 __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset)
9044 {
9045         bset = isl_basic_set_cow(bset);
9046         if (!bset)
9047                 return NULL;
9048
9049         bset->dim = isl_space_unwrap(bset->dim);
9050         if (!bset->dim)
9051                 goto error;
9052
9053         bset = isl_basic_set_finalize(bset);
9054
9055         return (isl_basic_map *)bset;
9056 error:
9057         isl_basic_set_free(bset);
9058         return NULL;
9059 }
9060
9061 __isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set)
9062 {
9063         int i;
9064
9065         if (!set)
9066                 return NULL;
9067
9068         if (!isl_set_is_wrapping(set))
9069                 isl_die(set->ctx, isl_error_invalid, "not a wrapping set",
9070                         goto error);
9071
9072         set = isl_set_cow(set);
9073         if (!set)
9074                 return NULL;
9075
9076         for (i = 0; i < set->n; ++i) {
9077                 set->p[i] = (isl_basic_set *)isl_basic_set_unwrap(set->p[i]);
9078                 if (!set->p[i])
9079                         goto error;
9080         }
9081
9082         set->dim = isl_space_unwrap(set->dim);
9083         if (!set->dim)
9084                 goto error;
9085
9086         return (isl_map *)set;
9087 error:
9088         isl_set_free(set);
9089         return NULL;
9090 }
9091
9092 __isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
9093         enum isl_dim_type type)
9094 {
9095         if (!bmap)
9096                 return NULL;
9097
9098         if (!isl_space_is_named_or_nested(bmap->dim, type))
9099                 return bmap;
9100
9101         bmap = isl_basic_map_cow(bmap);
9102         if (!bmap)
9103                 return NULL;
9104
9105         bmap->dim = isl_space_reset(bmap->dim, type);
9106         if (!bmap->dim)
9107                 goto error;
9108
9109         bmap = isl_basic_map_finalize(bmap);
9110
9111         return bmap;
9112 error:
9113         isl_basic_map_free(bmap);
9114         return NULL;
9115 }
9116
9117 __isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
9118         enum isl_dim_type type)
9119 {
9120         int i;
9121
9122         if (!map)
9123                 return NULL;
9124
9125         if (!isl_space_is_named_or_nested(map->dim, type))
9126                 return map;
9127
9128         map = isl_map_cow(map);
9129         if (!map)
9130                 return NULL;
9131
9132         for (i = 0; i < map->n; ++i) {
9133                 map->p[i] = isl_basic_map_reset(map->p[i], type);
9134                 if (!map->p[i])
9135                         goto error;
9136         }
9137         map->dim = isl_space_reset(map->dim, type);
9138         if (!map->dim)
9139                 goto error;
9140
9141         return map;
9142 error:
9143         isl_map_free(map);
9144         return NULL;
9145 }
9146
9147 __isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
9148 {
9149         if (!bmap)
9150                 return NULL;
9151
9152         if (!bmap->dim->nested[0] && !bmap->dim->nested[1])
9153                 return bmap;
9154
9155         bmap = isl_basic_map_cow(bmap);
9156         if (!bmap)
9157                 return NULL;
9158
9159         bmap->dim = isl_space_flatten(bmap->dim);
9160         if (!bmap->dim)
9161                 goto error;
9162
9163         bmap = isl_basic_map_finalize(bmap);
9164
9165         return bmap;
9166 error:
9167         isl_basic_map_free(bmap);
9168         return NULL;
9169 }
9170
9171 __isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset)
9172 {
9173         return (isl_basic_set *)isl_basic_map_flatten((isl_basic_map *)bset);
9174 }
9175
9176 __isl_give isl_basic_map *isl_basic_map_flatten_domain(
9177         __isl_take isl_basic_map *bmap)
9178 {
9179         if (!bmap)
9180                 return NULL;
9181
9182         if (!bmap->dim->nested[0])
9183                 return bmap;
9184
9185         bmap = isl_basic_map_cow(bmap);
9186         if (!bmap)
9187                 return NULL;
9188
9189         bmap->dim = isl_space_flatten_domain(bmap->dim);
9190         if (!bmap->dim)
9191                 goto error;
9192
9193         bmap = isl_basic_map_finalize(bmap);
9194
9195         return bmap;
9196 error:
9197         isl_basic_map_free(bmap);
9198         return NULL;
9199 }
9200
9201 __isl_give isl_basic_map *isl_basic_map_flatten_range(
9202         __isl_take isl_basic_map *bmap)
9203 {
9204         if (!bmap)
9205                 return NULL;
9206
9207         if (!bmap->dim->nested[1])
9208                 return bmap;
9209
9210         bmap = isl_basic_map_cow(bmap);
9211         if (!bmap)
9212                 return NULL;
9213
9214         bmap->dim = isl_space_flatten_range(bmap->dim);
9215         if (!bmap->dim)
9216                 goto error;
9217
9218         bmap = isl_basic_map_finalize(bmap);
9219
9220         return bmap;
9221 error:
9222         isl_basic_map_free(bmap);
9223         return NULL;
9224 }
9225
9226 __isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
9227 {
9228         int i;
9229
9230         if (!map)
9231                 return NULL;
9232
9233         if (!map->dim->nested[0] && !map->dim->nested[1])
9234                 return map;
9235
9236         map = isl_map_cow(map);
9237         if (!map)
9238                 return NULL;
9239
9240         for (i = 0; i < map->n; ++i) {
9241                 map->p[i] = isl_basic_map_flatten(map->p[i]);
9242                 if (!map->p[i])
9243                         goto error;
9244         }
9245         map->dim = isl_space_flatten(map->dim);
9246         if (!map->dim)
9247                 goto error;
9248
9249         return map;
9250 error:
9251         isl_map_free(map);
9252         return NULL;
9253 }
9254
9255 __isl_give isl_set *isl_set_flatten(__isl_take isl_set *set)
9256 {
9257         return (isl_set *)isl_map_flatten((isl_map *)set);
9258 }
9259
9260 __isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set)
9261 {
9262         isl_space *dim, *flat_dim;
9263         isl_map *map;
9264
9265         dim = isl_set_get_space(set);
9266         flat_dim = isl_space_flatten(isl_space_copy(dim));
9267         map = isl_map_identity(isl_space_join(isl_space_reverse(dim), flat_dim));
9268         map = isl_map_intersect_domain(map, set);
9269
9270         return map;
9271 }
9272
9273 __isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
9274 {
9275         int i;
9276
9277         if (!map)
9278                 return NULL;
9279
9280         if (!map->dim->nested[0])
9281                 return map;
9282
9283         map = isl_map_cow(map);
9284         if (!map)
9285                 return NULL;
9286
9287         for (i = 0; i < map->n; ++i) {
9288                 map->p[i] = isl_basic_map_flatten_domain(map->p[i]);
9289                 if (!map->p[i])
9290                         goto error;
9291         }
9292         map->dim = isl_space_flatten_domain(map->dim);
9293         if (!map->dim)
9294                 goto error;
9295
9296         return map;
9297 error:
9298         isl_map_free(map);
9299         return NULL;
9300 }
9301
9302 __isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
9303 {
9304         int i;
9305
9306         if (!map)
9307                 return NULL;
9308
9309         if (!map->dim->nested[1])
9310                 return map;
9311
9312         map = isl_map_cow(map);
9313         if (!map)
9314                 return NULL;
9315
9316         for (i = 0; i < map->n; ++i) {
9317                 map->p[i] = isl_basic_map_flatten_range(map->p[i]);
9318                 if (!map->p[i])
9319                         goto error;
9320         }
9321         map->dim = isl_space_flatten_range(map->dim);
9322         if (!map->dim)
9323                 goto error;
9324
9325         return map;
9326 error:
9327         isl_map_free(map);
9328         return NULL;
9329 }
9330
9331 /* Reorder the dimensions of "bmap" according to the given dim_map
9332  * and set the dimension specification to "dim".
9333  */
9334 __isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
9335         __isl_take isl_space *dim, __isl_take struct isl_dim_map *dim_map)
9336 {
9337         isl_basic_map *res;
9338         unsigned flags;
9339
9340         bmap = isl_basic_map_cow(bmap);
9341         if (!bmap || !dim || !dim_map)
9342                 goto error;
9343
9344         flags = bmap->flags;
9345         ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL);
9346         ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED);
9347         ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS);
9348         res = isl_basic_map_alloc_space(dim,
9349                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
9350         res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
9351         if (res)
9352                 res->flags = flags;
9353         res = isl_basic_map_finalize(res);
9354         return res;
9355 error:
9356         free(dim_map);
9357         isl_basic_map_free(bmap);
9358         isl_space_free(dim);
9359         return NULL;
9360 }
9361
9362 /* Reorder the dimensions of "map" according to given reordering.
9363  */
9364 __isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
9365         __isl_take isl_reordering *r)
9366 {
9367         int i;
9368         struct isl_dim_map *dim_map;
9369
9370         map = isl_map_cow(map);
9371         dim_map = isl_dim_map_from_reordering(r);
9372         if (!map || !r || !dim_map)
9373                 goto error;
9374
9375         for (i = 0; i < map->n; ++i) {
9376                 struct isl_dim_map *dim_map_i;
9377
9378                 dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
9379
9380                 map->p[i] = isl_basic_map_realign(map->p[i],
9381                                             isl_space_copy(r->dim), dim_map_i);
9382
9383                 if (!map->p[i])
9384                         goto error;
9385         }
9386
9387         map = isl_map_reset_space(map, isl_space_copy(r->dim));
9388
9389         isl_reordering_free(r);
9390         free(dim_map);
9391         return map;
9392 error:
9393         free(dim_map);
9394         isl_map_free(map);
9395         isl_reordering_free(r);
9396         return NULL;
9397 }
9398
9399 __isl_give isl_set *isl_set_realign(__isl_take isl_set *set,
9400         __isl_take isl_reordering *r)
9401 {
9402         return (isl_set *)isl_map_realign((isl_map *)set, r);
9403 }
9404
9405 __isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
9406         __isl_take isl_space *model)
9407 {
9408         isl_ctx *ctx;
9409
9410         if (!map || !model)
9411                 goto error;
9412
9413         ctx = isl_space_get_ctx(model);
9414         if (!isl_space_has_named_params(model))
9415                 isl_die(ctx, isl_error_invalid,
9416                         "model has unnamed parameters", goto error);
9417         if (!isl_space_has_named_params(map->dim))
9418                 isl_die(ctx, isl_error_invalid,
9419                         "relation has unnamed parameters", goto error);
9420         if (!isl_space_match(map->dim, isl_dim_param, model, isl_dim_param)) {
9421                 isl_reordering *exp;
9422
9423                 model = isl_space_drop_dims(model, isl_dim_in,
9424                                         0, isl_space_dim(model, isl_dim_in));
9425                 model = isl_space_drop_dims(model, isl_dim_out,
9426                                         0, isl_space_dim(model, isl_dim_out));
9427                 exp = isl_parameter_alignment_reordering(map->dim, model);
9428                 exp = isl_reordering_extend_space(exp, isl_map_get_space(map));
9429                 map = isl_map_realign(map, exp);
9430         }
9431
9432         isl_space_free(model);
9433         return map;
9434 error:
9435         isl_space_free(model);
9436         isl_map_free(map);
9437         return NULL;
9438 }
9439
9440 __isl_give isl_set *isl_set_align_params(__isl_take isl_set *set,
9441         __isl_take isl_space *model)
9442 {
9443         return isl_map_align_params(set, model);
9444 }
9445
9446 __isl_give isl_mat *isl_basic_map_equalities_matrix(
9447                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
9448                 enum isl_dim_type c2, enum isl_dim_type c3,
9449                 enum isl_dim_type c4, enum isl_dim_type c5)
9450 {
9451         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
9452         struct isl_mat *mat;
9453         int i, j, k;
9454         int pos;
9455
9456         if (!bmap)
9457                 return NULL;
9458         mat = isl_mat_alloc(bmap->ctx, bmap->n_eq,
9459                                 isl_basic_map_total_dim(bmap) + 1);
9460         if (!mat)
9461                 return NULL;
9462         for (i = 0; i < bmap->n_eq; ++i)
9463                 for (j = 0, pos = 0; j < 5; ++j) {
9464                         int off = isl_basic_map_offset(bmap, c[j]);
9465                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9466                                 isl_int_set(mat->row[i][pos],
9467                                             bmap->eq[i][off + k]);
9468                                 ++pos;
9469                         }
9470                 }
9471
9472         return mat;
9473 }
9474
9475 __isl_give isl_mat *isl_basic_map_inequalities_matrix(
9476                 __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
9477                 enum isl_dim_type c2, enum isl_dim_type c3,
9478                 enum isl_dim_type c4, enum isl_dim_type c5)
9479 {
9480         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
9481         struct isl_mat *mat;
9482         int i, j, k;
9483         int pos;
9484
9485         if (!bmap)
9486                 return NULL;
9487         mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq,
9488                                 isl_basic_map_total_dim(bmap) + 1);
9489         if (!mat)
9490                 return NULL;
9491         for (i = 0; i < bmap->n_ineq; ++i)
9492                 for (j = 0, pos = 0; j < 5; ++j) {
9493                         int off = isl_basic_map_offset(bmap, c[j]);
9494                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9495                                 isl_int_set(mat->row[i][pos],
9496                                             bmap->ineq[i][off + k]);
9497                                 ++pos;
9498                         }
9499                 }
9500
9501         return mat;
9502 }
9503
9504 __isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
9505         __isl_take isl_space *dim,
9506         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
9507         enum isl_dim_type c2, enum isl_dim_type c3,
9508         enum isl_dim_type c4, enum isl_dim_type c5)
9509 {
9510         enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
9511         isl_basic_map *bmap;
9512         unsigned total;
9513         unsigned extra;
9514         int i, j, k, l;
9515         int pos;
9516
9517         if (!dim || !eq || !ineq)
9518                 goto error;
9519
9520         if (eq->n_col != ineq->n_col)
9521                 isl_die(dim->ctx, isl_error_invalid,
9522                         "equalities and inequalities matrices should have "
9523                         "same number of columns", goto error);
9524
9525         total = 1 + isl_space_dim(dim, isl_dim_all);
9526
9527         if (eq->n_col < total)
9528                 isl_die(dim->ctx, isl_error_invalid,
9529                         "number of columns too small", goto error);
9530
9531         extra = eq->n_col - total;
9532
9533         bmap = isl_basic_map_alloc_space(isl_space_copy(dim), extra,
9534                                        eq->n_row, ineq->n_row);
9535         if (!bmap)
9536                 goto error;
9537         for (i = 0; i < extra; ++i) {
9538                 k = isl_basic_map_alloc_div(bmap);
9539                 if (k < 0)
9540                         goto error;
9541                 isl_int_set_si(bmap->div[k][0], 0);
9542         }
9543         for (i = 0; i < eq->n_row; ++i) {
9544                 l = isl_basic_map_alloc_equality(bmap);
9545                 if (l < 0)
9546                         goto error;
9547                 for (j = 0, pos = 0; j < 5; ++j) {
9548                         int off = isl_basic_map_offset(bmap, c[j]);
9549                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9550                                 isl_int_set(bmap->eq[l][off + k], 
9551                                             eq->row[i][pos]);
9552                                 ++pos;
9553                         }
9554                 }
9555         }
9556         for (i = 0; i < ineq->n_row; ++i) {
9557                 l = isl_basic_map_alloc_inequality(bmap);
9558                 if (l < 0)
9559                         goto error;
9560                 for (j = 0, pos = 0; j < 5; ++j) {
9561                         int off = isl_basic_map_offset(bmap, c[j]);
9562                         for (k = 0; k < isl_basic_map_dim(bmap, c[j]); ++k) {
9563                                 isl_int_set(bmap->ineq[l][off + k], 
9564                                             ineq->row[i][pos]);
9565                                 ++pos;
9566                         }
9567                 }
9568         }
9569
9570         isl_space_free(dim);
9571         isl_mat_free(eq);
9572         isl_mat_free(ineq);
9573
9574         return bmap;
9575 error:
9576         isl_space_free(dim);
9577         isl_mat_free(eq);
9578         isl_mat_free(ineq);
9579         return NULL;
9580 }
9581
9582 __isl_give isl_mat *isl_basic_set_equalities_matrix(
9583         __isl_keep isl_basic_set *bset, enum isl_dim_type c1,
9584         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
9585 {
9586         return isl_basic_map_equalities_matrix((isl_basic_map *)bset,
9587                                                 c1, c2, c3, c4, isl_dim_in);
9588 }
9589
9590 __isl_give isl_mat *isl_basic_set_inequalities_matrix(
9591         __isl_keep isl_basic_set *bset, enum isl_dim_type c1,
9592         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
9593 {
9594         return isl_basic_map_inequalities_matrix((isl_basic_map *)bset,
9595                                                  c1, c2, c3, c4, isl_dim_in);
9596 }
9597
9598 __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices(
9599         __isl_take isl_space *dim,
9600         __isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
9601         enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
9602 {
9603         return (isl_basic_set*)
9604             isl_basic_map_from_constraint_matrices(dim, eq, ineq,
9605                                                    c1, c2, c3, c4, isl_dim_in);
9606 }
9607
9608 int isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
9609 {
9610         if (!bmap)
9611                 return -1;
9612         
9613         return isl_space_can_zip(bmap->dim);
9614 }
9615
9616 int isl_map_can_zip(__isl_keep isl_map *map)
9617 {
9618         if (!map)
9619                 return -1;
9620         
9621         return isl_space_can_zip(map->dim);
9622 }
9623
9624 /* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
9625  * (A -> C) -> (B -> D).
9626  */
9627 __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
9628 {
9629         unsigned pos;
9630         unsigned n1;
9631         unsigned n2;
9632
9633         if (!bmap)
9634                 return NULL;
9635
9636         if (!isl_basic_map_can_zip(bmap))
9637                 isl_die(bmap->ctx, isl_error_invalid,
9638                         "basic map cannot be zipped", goto error);
9639         pos = isl_basic_map_offset(bmap, isl_dim_in) +
9640                 isl_space_dim(bmap->dim->nested[0], isl_dim_in);
9641         n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
9642         n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
9643         bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
9644         if (!bmap)
9645                 return NULL;
9646         bmap->dim = isl_space_zip(bmap->dim);
9647         if (!bmap->dim)
9648                 goto error;
9649         return bmap;
9650 error:
9651         isl_basic_map_free(bmap);
9652         return NULL;
9653 }
9654
9655 /* Given a map (A -> B) -> (C -> D), return the corresponding map
9656  * (A -> C) -> (B -> D).
9657  */
9658 __isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
9659 {
9660         int i;
9661
9662         if (!map)
9663                 return NULL;
9664
9665         if (!isl_map_can_zip(map))
9666                 isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",
9667                         goto error);
9668
9669         map = isl_map_cow(map);
9670         if (!map)
9671                 return NULL;
9672
9673         for (i = 0; i < map->n; ++i) {
9674                 map->p[i] = isl_basic_map_zip(map->p[i]);
9675                 if (!map->p[i])
9676                         goto error;
9677         }
9678
9679         map->dim = isl_space_zip(map->dim);
9680         if (!map->dim)
9681                 goto error;
9682
9683         return map;
9684 error:
9685         isl_map_free(map);
9686         return NULL;
9687 }
9688
9689 /* Construct a basic map mapping the domain of the affine expression
9690  * to a one-dimensional range prescribed by the affine expression.
9691  */
9692 __isl_give isl_basic_map *isl_basic_map_from_aff(__isl_take isl_aff *aff)
9693 {
9694         int k;
9695         int pos;
9696         isl_local_space *ls;
9697         isl_basic_map *bmap;
9698
9699         if (!aff)
9700                 return NULL;
9701
9702         ls = isl_aff_get_local_space(aff);
9703         bmap = isl_basic_map_from_local_space(ls);
9704         bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
9705         k = isl_basic_map_alloc_equality(bmap);
9706         if (k < 0)
9707                 goto error;
9708
9709         pos = isl_basic_map_offset(bmap, isl_dim_out);
9710         isl_seq_cpy(bmap->eq[k], aff->v->el + 1, pos);
9711         isl_int_neg(bmap->eq[k][pos], aff->v->el[0]);
9712         isl_seq_cpy(bmap->eq[k] + pos + 1, aff->v->el + 1 + pos,
9713                     aff->v->size - (pos + 1));
9714
9715         isl_aff_free(aff);
9716         bmap = isl_basic_map_finalize(bmap);
9717         return bmap;
9718 error:
9719         isl_aff_free(aff);
9720         isl_basic_map_free(bmap);
9721         return NULL;
9722 }
9723
9724 /* Construct a basic map mapping the domain the multi-affine expression
9725  * to its range, with each dimension in the range equated to the
9726  * corresponding affine expression.
9727  */
9728 __isl_give isl_basic_map *isl_basic_map_from_multi_aff(
9729         __isl_take isl_multi_aff *maff)
9730 {
9731         int i;
9732         isl_space *space;
9733         isl_basic_map *bmap;
9734
9735         if (!maff)
9736                 return NULL;
9737
9738         if (isl_space_dim(maff->space, isl_dim_out) != maff->n)
9739                 isl_die(isl_multi_aff_get_ctx(maff), isl_error_internal,
9740                         "invalid space", return isl_multi_aff_free(maff));
9741
9742         space = isl_space_domain(isl_multi_aff_get_space(maff));
9743         bmap = isl_basic_map_universe(isl_space_from_domain(space));
9744
9745         for (i = 0; i < maff->n; ++i) {
9746                 isl_aff *aff;
9747                 isl_basic_map *bmap_i;
9748
9749                 aff = isl_aff_copy(maff->p[i]);
9750                 bmap_i = isl_basic_map_from_aff(aff);
9751
9752                 bmap = isl_basic_map_flat_range_product(bmap, bmap_i);
9753         }
9754
9755         bmap = isl_basic_map_reset_space(bmap, isl_multi_aff_get_space(maff));
9756
9757         isl_multi_aff_free(maff);
9758         return bmap;
9759 }
9760
9761 /* Construct a basic map mapping a domain in the given space to
9762  * to an n-dimensional range, with n the number of elements in the list,
9763  * where each coordinate in the range is prescribed by the
9764  * corresponding affine expression.
9765  * The domains of all affine expressions in the list are assumed to match
9766  * domain_dim.
9767  */
9768 __isl_give isl_basic_map *isl_basic_map_from_aff_list(
9769         __isl_take isl_space *domain_dim, __isl_take isl_aff_list *list)
9770 {
9771         int i;
9772         isl_space *dim;
9773         isl_basic_map *bmap;
9774
9775         if (!list)
9776                 return NULL;
9777
9778         dim = isl_space_from_domain(domain_dim);
9779         bmap = isl_basic_map_universe(dim);
9780
9781         for (i = 0; i < list->n; ++i) {
9782                 isl_aff *aff;
9783                 isl_basic_map *bmap_i;
9784
9785                 aff = isl_aff_copy(list->p[i]);
9786                 bmap_i = isl_basic_map_from_aff(aff);
9787
9788                 bmap = isl_basic_map_flat_range_product(bmap, bmap_i);
9789         }
9790
9791         isl_aff_list_free(list);
9792         return bmap;
9793 }
9794
9795 __isl_give isl_set *isl_set_equate(__isl_take isl_set *set,
9796         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
9797 {
9798         return isl_map_equate(set, type1, pos1, type2, pos2);
9799 }
9800
9801 /* Add a constraint imposing that the given two dimensions are equal.
9802  */
9803 __isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
9804         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
9805 {
9806         isl_basic_map *bmap = NULL;
9807         int i;
9808
9809         if (!map)
9810                 return NULL;
9811
9812         if (pos1 >= isl_map_dim(map, type1))
9813                 isl_die(map->ctx, isl_error_invalid,
9814                         "index out of bounds", goto error);
9815         if (pos2 >= isl_map_dim(map, type2))
9816                 isl_die(map->ctx, isl_error_invalid,
9817                         "index out of bounds", goto error);
9818
9819         bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
9820         i = isl_basic_map_alloc_equality(bmap);
9821         if (i < 0)
9822                 goto error;
9823         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
9824         pos1 += isl_basic_map_offset(bmap, type1);
9825         pos2 += isl_basic_map_offset(bmap, type2);
9826         isl_int_set_si(bmap->eq[i][pos1], -1);
9827         isl_int_set_si(bmap->eq[i][pos2], 1);
9828         bmap = isl_basic_map_finalize(bmap);
9829
9830         map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
9831
9832         return map;
9833 error:
9834         isl_basic_map_free(bmap);
9835         isl_map_free(map);
9836         return NULL;
9837 }
9838
9839 /* Add a constraint imposing that the given two dimensions have opposite values.
9840  */
9841 __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
9842         enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
9843 {
9844         isl_basic_map *bmap = NULL;
9845         int i;
9846
9847         if (!map)
9848                 return NULL;
9849
9850         if (pos1 >= isl_map_dim(map, type1))
9851                 isl_die(map->ctx, isl_error_invalid,
9852                         "index out of bounds", goto error);
9853         if (pos2 >= isl_map_dim(map, type2))
9854                 isl_die(map->ctx, isl_error_invalid,
9855                         "index out of bounds", goto error);
9856
9857         bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
9858         i = isl_basic_map_alloc_equality(bmap);
9859         if (i < 0)
9860                 goto error;
9861         isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
9862         pos1 += isl_basic_map_offset(bmap, type1);
9863         pos2 += isl_basic_map_offset(bmap, type2);
9864         isl_int_set_si(bmap->eq[i][pos1], 1);
9865         isl_int_set_si(bmap->eq[i][pos2], 1);
9866         bmap = isl_basic_map_finalize(bmap);
9867
9868         map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
9869
9870         return map;
9871 error:
9872         isl_basic_map_free(bmap);
9873         isl_map_free(map);
9874         return NULL;
9875 }
9876
9877 __isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
9878         int pos)
9879 {
9880         isl_aff *div;
9881         isl_local_space *ls;
9882
9883         if (!bmap)
9884                 return NULL;
9885
9886         if (!isl_basic_map_divs_known(bmap))
9887                 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
9888                         "some divs are unknown", return NULL);
9889
9890         ls = isl_basic_map_get_local_space(bmap);
9891         div = isl_local_space_get_div(ls, pos);
9892         isl_local_space_free(ls);
9893
9894         return div;
9895 }
9896
9897 __isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset,
9898         int pos)
9899 {
9900         return isl_basic_map_get_div(bset, pos);
9901 }
9902
9903 /* Plug in "subs" for dimension "type", "pos" of "bset".
9904  *
9905  * Let i be the dimension to replace and let "subs" be of the form
9906  *
9907  *      f/d
9908  *
9909  * Any integer division with a non-zero coefficient for i,
9910  *
9911  *      floor((a i + g)/m)
9912  *
9913  * is replaced by
9914  *
9915  *      floor((a f + d g)/(m d))
9916  *
9917  * Constraints of the form
9918  *
9919  *      a i + g
9920  *
9921  * are replaced by
9922  *
9923  *      a f + d g
9924  */
9925 __isl_give isl_basic_set *isl_basic_set_substitute(
9926         __isl_take isl_basic_set *bset,
9927         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
9928 {
9929         int i;
9930         isl_int v;
9931         isl_ctx *ctx;
9932
9933         if (bset && isl_basic_set_plain_is_empty(bset))
9934                 return bset;
9935
9936         bset = isl_basic_set_cow(bset);
9937         if (!bset || !subs)
9938                 goto error;
9939
9940         ctx = isl_basic_set_get_ctx(bset);
9941         if (!isl_space_is_equal(bset->dim, subs->ls->dim))
9942                 isl_die(ctx, isl_error_invalid,
9943                         "spaces don't match", goto error);
9944         if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
9945                 isl_die(ctx, isl_error_unsupported,
9946                         "cannot handle divs yet", goto error);
9947
9948         pos += isl_basic_set_offset(bset, type);
9949
9950         isl_int_init(v);
9951
9952         for (i = 0; i < bset->n_eq; ++i) {
9953                 if (isl_int_is_zero(bset->eq[i][pos]))
9954                         continue;
9955                 isl_int_set(v, bset->eq[i][pos]);
9956                 isl_int_set_si(bset->eq[i][pos], 0);
9957                 isl_seq_combine(bset->eq[i], subs->v->el[0], bset->eq[i],
9958                                 v, subs->v->el + 1, subs->v->size - 1);
9959         }
9960
9961         for (i = 0; i < bset->n_ineq; ++i) {
9962                 if (isl_int_is_zero(bset->ineq[i][pos]))
9963                         continue;
9964                 isl_int_set(v, bset->ineq[i][pos]);
9965                 isl_int_set_si(bset->ineq[i][pos], 0);
9966                 isl_seq_combine(bset->ineq[i], subs->v->el[0], bset->ineq[i],
9967                                 v, subs->v->el + 1, subs->v->size - 1);
9968         }
9969
9970         for (i = 0; i < bset->n_div; ++i) {
9971                 if (isl_int_is_zero(bset->div[i][1 + pos]))
9972                         continue;
9973                 isl_int_set(v, bset->div[i][1 + pos]);
9974                 isl_int_set_si(bset->div[i][1 + pos], 0);
9975                 isl_seq_combine(bset->div[i] + 1,
9976                                 subs->v->el[0], bset->div[i] + 1,
9977                                 v, subs->v->el + 1, subs->v->size - 1);
9978                 isl_int_mul(bset->div[i][0], bset->div[i][0], subs->v->el[0]);
9979         }
9980
9981         isl_int_clear(v);
9982
9983         bset = isl_basic_set_simplify(bset);
9984         return isl_basic_set_finalize(bset);
9985 error:
9986         isl_basic_set_free(bset);
9987         return NULL;
9988 }
9989
9990 /* Plug in "subs" for dimension "type", "pos" of "set".
9991  */
9992 __isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
9993         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
9994 {
9995         int i;
9996
9997         if (set && isl_set_plain_is_empty(set))
9998                 return set;
9999
10000         set = isl_set_cow(set);
10001         if (!set || !subs)
10002                 goto error;
10003
10004         for (i = set->n - 1; i >= 0; --i) {
10005                 set->p[i] = isl_basic_set_substitute(set->p[i], type, pos, subs);
10006                 if (!set->p[i])
10007                         goto error;
10008                 if (isl_basic_set_plain_is_empty(set->p[i])) {
10009                         isl_basic_set_free(set->p[i]);
10010                         if (i != set->n - 1)
10011                                 set->p[i] = set->p[set->n - 1];
10012                         set->n--;
10013                 }
10014         }
10015
10016         return set;
10017 error:
10018         isl_set_free(set);
10019         return NULL;
10020 }