isl_basic_set_sample: remove equalities first
[platform/upstream/isl.git] / isl_map.c
1 #include <string.h>
2 #include <strings.h>
3 #include "isl_ctx.h"
4 #include "isl_blk.h"
5 #include "isl_seq.h"
6 #include "isl_set.h"
7 #include "isl_map.h"
8 #include "isl_map_private.h"
9 #include "isl_map_piplib.h"
10 #include "isl_sample.h"
11 #include "isl_vec.h"
12
13 static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx,
14                 struct isl_basic_map *bmap,
15                 unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra,
16                 unsigned n_eq, unsigned n_ineq)
17 {
18         int i;
19         size_t row_size = 1 + nparam + n_in + n_out + extra;
20
21         bmap->block = isl_blk_alloc(ctx, (n_eq + n_ineq) * row_size);
22         if (!bmap->block.data) {
23                 free(bmap);
24                 return NULL;
25         }
26
27         bmap->eq = isl_alloc_array(ctx, isl_int *, n_eq + n_ineq);
28         if (!bmap->eq) {
29                 isl_blk_free(ctx, bmap->block);
30                 free(bmap);
31                 return NULL;
32         }
33
34         if (extra == 0) {
35                 bmap->block2.size = 0;
36                 bmap->block2.data = NULL;
37                 bmap->div = NULL;
38         } else {
39                 bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
40                 if (!bmap->block2.data) {
41                         free(bmap->eq);
42                         isl_blk_free(ctx, bmap->block);
43                         free(bmap);
44                         return NULL;
45                 }
46
47                 bmap->div = isl_alloc_array(ctx, isl_int *, extra);
48                 if (!bmap->div) {
49                         isl_blk_free(ctx, bmap->block2);
50                         free(bmap->eq);
51                         isl_blk_free(ctx, bmap->block);
52                         free(bmap);
53                         return NULL;
54                 }
55         }
56
57         for (i = 0; i < n_eq + n_ineq; ++i)
58                 bmap->eq[i] = bmap->block.data + i * row_size;
59
60         for (i = 0; i < extra; ++i)
61                 bmap->div[i] = bmap->block2.data + i * (1 + row_size);
62
63         bmap->ref = 1;
64         bmap->flags = 0;
65         bmap->c_size = n_eq + n_ineq;
66         bmap->ineq = bmap->eq + n_eq;
67         bmap->nparam = nparam;
68         bmap->n_in = n_in;
69         bmap->n_out = n_out;
70         bmap->extra = extra;
71         bmap->n_eq = 0;
72         bmap->n_ineq = 0;
73         bmap->n_div = 0;
74
75         return bmap;
76 }
77
78 struct isl_basic_set *isl_basic_set_alloc(struct isl_ctx *ctx,
79                 unsigned nparam, unsigned dim, unsigned extra,
80                 unsigned n_eq, unsigned n_ineq)
81 {
82         struct isl_basic_map *bmap;
83         bmap = isl_basic_map_alloc(ctx, nparam, 0, dim, extra, n_eq, n_ineq);
84         return (struct isl_basic_set *)bmap;
85 }
86
87 struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx,
88                 unsigned nparam, unsigned in, unsigned out, unsigned extra,
89                 unsigned n_eq, unsigned n_ineq)
90 {
91         struct isl_basic_map *bmap;
92
93         bmap = isl_alloc_type(ctx, struct isl_basic_map);
94         if (!bmap)
95                 return NULL;
96
97         return basic_map_init(ctx, bmap,
98                                nparam, in, out, extra, n_eq, n_ineq);
99 }
100
101 static void dup_constraints(struct isl_ctx *ctx,
102                 struct isl_basic_map *dst, struct isl_basic_map *src)
103 {
104         int i;
105         unsigned total = src->nparam + src->n_in + src->n_out + src->n_div;
106
107         for (i = 0; i < src->n_eq; ++i) {
108                 int j = isl_basic_map_alloc_equality(ctx, dst);
109                 isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
110         }
111
112         for (i = 0; i < src->n_ineq; ++i) {
113                 int j = isl_basic_map_alloc_inequality(ctx, dst);
114                 isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
115         }
116
117         for (i = 0; i < src->n_div; ++i) {
118                 int j = isl_basic_map_alloc_div(ctx, dst);
119                 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
120         }
121         F_SET(dst, ISL_BASIC_SET_FINAL);
122 }
123
124 struct isl_basic_map *isl_basic_map_dup(struct isl_ctx *ctx,
125                                         struct isl_basic_map *bmap)
126 {
127         struct isl_basic_map *dup;
128
129         dup = isl_basic_map_alloc(ctx, bmap->nparam,
130                         bmap->n_in, bmap->n_out,
131                         bmap->n_div, bmap->n_eq, bmap->n_ineq);
132         if (!dup)
133                 return NULL;
134         dup_constraints(ctx, dup, bmap);
135         return dup;
136 }
137
138 struct isl_basic_set *isl_basic_set_dup(struct isl_ctx *ctx,
139                                         struct isl_basic_set *bset)
140 {
141         struct isl_basic_map *dup;
142
143         dup = isl_basic_map_dup(ctx, (struct isl_basic_map *)bset);
144         return (struct isl_basic_set *)dup;
145 }
146
147 struct isl_basic_set *isl_basic_set_copy(struct isl_ctx *ctx,
148                                         struct isl_basic_set *bset)
149 {
150         if (!bset)
151                 return NULL;
152
153         if (F_ISSET(bset, ISL_BASIC_SET_FINAL)) {
154                 bset->ref++;
155                 return bset;
156         }
157         return isl_basic_set_dup(ctx, bset);
158 }
159
160 struct isl_set *isl_set_copy(struct isl_ctx *ctx, struct isl_set *set)
161 {
162         if (!set)
163                 return NULL;
164
165         set->ref++;
166         return set;
167 }
168
169 struct isl_basic_map *isl_basic_map_copy(struct isl_ctx *ctx,
170                                         struct isl_basic_map *bmap)
171 {
172         if (!bmap)
173                 return NULL;
174
175         if (F_ISSET(bmap, ISL_BASIC_SET_FINAL)) {
176                 bmap->ref++;
177                 return bmap;
178         }
179         return isl_basic_map_dup(ctx, bmap);
180 }
181
182 struct isl_map *isl_map_copy(struct isl_ctx *ctx, struct isl_map *map)
183 {
184         if (!map)
185                 return NULL;
186
187         map->ref++;
188         return map;
189 }
190
191 void isl_basic_map_free(struct isl_ctx *ctx, struct isl_basic_map *bmap)
192 {
193         if (!bmap)
194                 return;
195
196         if (--bmap->ref > 0)
197                 return;
198
199         free(bmap->div);
200         isl_blk_free(ctx, bmap->block2);
201         free(bmap->eq);
202         isl_blk_free(ctx, bmap->block);
203         free(bmap);
204 }
205
206 void isl_basic_set_free(struct isl_ctx *ctx, struct isl_basic_set *bset)
207 {
208         isl_basic_map_free(ctx, (struct isl_basic_map *)bset);
209 }
210
211 int isl_basic_map_alloc_equality(struct isl_ctx *ctx,
212                 struct isl_basic_map *bmap)
213 {
214         if (!bmap)
215                 return -1;
216         isl_assert(ctx, bmap->n_eq + bmap->n_ineq < bmap->c_size, return -1);
217         isl_assert(ctx, bmap->eq + bmap->n_eq <= bmap->ineq, return -1);
218         if (bmap->eq + bmap->n_eq == bmap->ineq) {
219                 isl_int *t;
220                 int j = isl_basic_map_alloc_inequality(ctx, bmap);
221                 if (j < 0)
222                         return -1;
223                 t = bmap->ineq[0];
224                 bmap->ineq[0] = bmap->ineq[j];
225                 bmap->ineq[j] = t;
226                 bmap->n_ineq--;
227                 bmap->ineq++;
228         }
229         return bmap->n_eq++;
230 }
231
232 int isl_basic_map_free_equality(struct isl_ctx *ctx,
233                 struct isl_basic_map *bmap, unsigned n)
234 {
235         isl_assert(ctx, n <= bmap->n_eq, return -1);
236         bmap->n_eq -= n;
237         return 0;
238 }
239
240 int isl_basic_map_drop_equality(struct isl_ctx *ctx,
241                 struct isl_basic_map *bmap, unsigned pos)
242 {
243         isl_int *t;
244         isl_assert(ctx, pos < bmap->n_eq, return -1);
245
246         if (pos != bmap->n_eq - 1) {
247                 t = bmap->eq[pos];
248                 bmap->eq[pos] = bmap->eq[bmap->n_eq - 1];
249                 bmap->eq[bmap->n_eq - 1] = t;
250         }
251         bmap->n_eq--;
252         return 0;
253 }
254
255 int isl_basic_map_alloc_inequality(struct isl_ctx *ctx,
256                 struct isl_basic_map *bmap)
257 {
258         isl_assert(ctx, (bmap->ineq - bmap->eq) + bmap->n_ineq < bmap->c_size,
259                         return -1);
260         return bmap->n_ineq++;
261 }
262
263 int isl_basic_map_free_inequality(struct isl_ctx *ctx,
264                 struct isl_basic_map *bmap, unsigned n)
265 {
266         isl_assert(ctx, n <= bmap->n_ineq, return -1);
267         bmap->n_ineq -= n;
268         return 0;
269 }
270
271 int isl_basic_map_drop_inequality(struct isl_ctx *ctx,
272                 struct isl_basic_map *bmap, unsigned pos)
273 {
274         isl_int *t;
275         isl_assert(ctx, pos < bmap->n_ineq, return -1);
276
277         if (pos != bmap->n_ineq - 1) {
278                 t = bmap->ineq[pos];
279                 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
280                 bmap->ineq[bmap->n_ineq - 1] = t;
281         }
282         bmap->n_ineq--;
283         return 0;
284 }
285
286 int isl_basic_map_alloc_div(struct isl_ctx *ctx,
287                 struct isl_basic_map *bmap)
288 {
289         isl_assert(ctx, bmap->n_div < bmap->extra, return -1);
290         return bmap->n_div++;
291 }
292
293 int isl_basic_map_free_div(struct isl_ctx *ctx,
294                 struct isl_basic_map *bmap, unsigned n)
295 {
296         isl_assert(ctx, n <= bmap->n_div, return -1);
297         bmap->n_div -= n;
298         return 0;
299 }
300
301 /* Copy constraint from src to dst, putting the vars of src at offset
302  * dim_off in dst and the divs of src at offset div_off in dst.
303  * If both sets are actually map, then dim_off applies to the input
304  * variables.
305  */
306 static void copy_constraint(struct isl_basic_map *dst_map, isl_int *dst,
307                             struct isl_basic_map *src_map, isl_int *src,
308                             unsigned in_off, unsigned out_off, unsigned div_off)
309 {
310         isl_int_set(dst[0], src[0]);
311         isl_seq_cpy(dst+1, src+1, isl_min(dst_map->nparam, src_map->nparam));
312         isl_seq_cpy(dst+1+dst_map->nparam+in_off,
313                     src+1+src_map->nparam,
314                     isl_min(dst_map->n_in-in_off, src_map->n_in));
315         isl_seq_cpy(dst+1+dst_map->nparam+dst_map->n_in+out_off,
316                     src+1+src_map->nparam+src_map->n_in,
317                     isl_min(dst_map->n_out-out_off, src_map->n_out));
318         isl_seq_cpy(dst+1+dst_map->nparam+dst_map->n_in+dst_map->n_out+div_off,
319                     src+1+src_map->nparam+src_map->n_in+src_map->n_out,
320                     isl_min(dst_map->extra-div_off, src_map->extra));
321 }
322
323 static void copy_div(struct isl_basic_map *dst_map, isl_int *dst,
324                      struct isl_basic_map *src_map, isl_int *src,
325                      unsigned in_off, unsigned out_off, unsigned div_off)
326 {
327         isl_int_set(dst[0], src[0]);
328         copy_constraint(dst_map, dst+1, src_map, src+1, in_off, out_off, div_off);
329 }
330
331 static struct isl_basic_map *add_constraints(struct isl_ctx *ctx,
332                 struct isl_basic_map *bmap1,
333                 struct isl_basic_map *bmap2, unsigned i_pos, unsigned o_pos)
334 {
335         int i;
336         unsigned div_off = bmap1->n_div;
337
338         for (i = 0; i < bmap2->n_eq; ++i) {
339                 int i1 = isl_basic_map_alloc_equality(ctx, bmap1);
340                 if (i1 < 0)
341                         goto error;
342                 copy_constraint(bmap1, bmap1->eq[i1], bmap2, bmap2->eq[i],
343                                 i_pos, o_pos, div_off);
344         }
345
346         for (i = 0; i < bmap2->n_ineq; ++i) {
347                 int i1 = isl_basic_map_alloc_inequality(ctx, bmap1);
348                 if (i1 < 0)
349                         goto error;
350                 copy_constraint(bmap1, bmap1->ineq[i1], bmap2, bmap2->ineq[i],
351                                 i_pos, o_pos, div_off);
352         }
353
354         for (i = 0; i < bmap2->n_div; ++i) {
355                 int i1 = isl_basic_map_alloc_div(ctx, bmap1);
356                 if (i1 < 0)
357                         goto error;
358                 copy_div(bmap1, bmap1->div[i1], bmap2, bmap2->div[i],
359                          i_pos, o_pos, div_off);
360         }
361
362         isl_basic_map_free(ctx, bmap2);
363
364         return bmap1;
365
366 error:
367         isl_basic_map_free(ctx, bmap1);
368         isl_basic_map_free(ctx, bmap2);
369         return NULL;
370 }
371
372 struct isl_basic_map *isl_basic_map_extend(struct isl_ctx *ctx,
373                 struct isl_basic_map *base,
374                 unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra,
375                 unsigned n_eq, unsigned n_ineq)
376 {
377         struct isl_basic_map *ext;
378         int dims_ok;
379
380         base = isl_basic_map_cow(ctx, base);
381         if (!base)
382                 goto error;
383
384         dims_ok = base && base->nparam == nparam &&
385                   base->n_in == n_in && base->n_out == n_out &&
386                   base->extra >= base->n_div + extra;
387
388         if (dims_ok && n_eq == 0 && n_ineq == 0)
389                 return base;
390
391         if (base) {
392                 isl_assert(ctx, base->nparam <= nparam, goto error);
393                 isl_assert(ctx, base->n_in <= n_in, goto error);
394                 isl_assert(ctx, base->n_out <= n_out, goto error);
395                 extra += base->extra;
396                 n_eq += base->n_eq;
397                 n_ineq += base->n_ineq;
398         }
399
400         ext = isl_basic_map_alloc(ctx, nparam, n_in, n_out,
401                                         extra, n_eq, n_ineq);
402         if (!base)
403                 return ext;
404         if (!ext)
405                 goto error;
406
407         ext = add_constraints(ctx, ext, base, 0, 0);
408
409         return ext;
410
411 error:
412         isl_basic_map_free(ctx, base);
413         return NULL;
414 }
415
416 struct isl_basic_set *isl_basic_set_extend(struct isl_ctx *ctx,
417                 struct isl_basic_set *base,
418                 unsigned nparam, unsigned dim, unsigned extra,
419                 unsigned n_eq, unsigned n_ineq)
420 {
421         return (struct isl_basic_set *)
422                 isl_basic_map_extend(ctx, (struct isl_basic_map *)base,
423                                         nparam, 0, dim, extra, n_eq, n_ineq);
424 }
425
426 struct isl_basic_set *isl_basic_set_cow(struct isl_ctx *ctx,
427                 struct isl_basic_set *bset)
428 {
429         return (struct isl_basic_set *)
430                 isl_basic_map_cow(ctx, (struct isl_basic_map *)bset);
431 }
432
433 struct isl_basic_map *isl_basic_map_cow(struct isl_ctx *ctx,
434                 struct isl_basic_map *bmap)
435 {
436         if (!bmap)
437                 return NULL;
438
439         if (bmap->ref > 1) {
440                 bmap->ref--;
441                 bmap = isl_basic_map_dup(ctx, bmap);
442         }
443         F_CLR(bmap, ISL_BASIC_SET_FINAL);
444         return bmap;
445 }
446
447 static struct isl_set *isl_set_cow(struct isl_ctx *ctx, struct isl_set *set)
448 {
449         if (set->ref == 1)
450                 return set;
451         set->ref--;
452         return isl_set_dup(ctx, set);
453 }
454
455 struct isl_map *isl_map_cow(struct isl_ctx *ctx, struct isl_map *map)
456 {
457         if (map->ref == 1)
458                 return map;
459         map->ref--;
460         return isl_map_dup(ctx, map);
461 }
462
463 static void swap_vars(struct isl_blk blk, isl_int *a,
464                         unsigned a_len, unsigned b_len)
465 {
466         isl_seq_cpy(blk.data, a+a_len, b_len);
467         isl_seq_cpy(blk.data+b_len, a, a_len);
468         isl_seq_cpy(a, blk.data, b_len+a_len);
469 }
470
471 struct isl_basic_set *isl_basic_set_swap_vars(struct isl_ctx *ctx,
472                 struct isl_basic_set *bset, unsigned n)
473 {
474         int i;
475         struct isl_blk blk;
476
477         if (!bset)
478                 goto error;
479
480         isl_assert(ctx, n <= bset->dim, goto error);
481
482         if (n == bset->dim)
483                 return bset;
484
485         bset = isl_basic_set_cow(ctx, bset);
486         if (!bset)
487                 return NULL;
488
489         blk = isl_blk_alloc(ctx, bset->dim);
490         if (!blk.data)
491                 goto error;
492
493         for (i = 0; i < bset->n_eq; ++i)
494                 swap_vars(blk,
495                           bset->eq[i]+1+bset->nparam, n, bset->dim - n);
496
497         for (i = 0; i < bset->n_ineq; ++i)
498                 swap_vars(blk,
499                           bset->ineq[i]+1+bset->nparam, n, bset->dim - n);
500
501         for (i = 0; i < bset->n_div; ++i)
502                 swap_vars(blk,
503                           bset->div[i]+1+1+bset->nparam, n, bset->dim - n);
504
505         isl_blk_free(ctx, blk);
506
507         return bset;
508
509 error:
510         isl_basic_set_free(ctx, bset);
511         return NULL;
512 }
513
514 struct isl_set *isl_set_swap_vars(struct isl_ctx *ctx,
515                 struct isl_set *set, unsigned n)
516 {
517         int i;
518         set = isl_set_cow(ctx, set);
519         if (!set)
520                 return NULL;
521
522         for (i = 0; i < set->n; ++i) {
523                 set->p[i] = isl_basic_set_swap_vars(ctx, set->p[i], n);
524                 if (!set->p[i]) {
525                         isl_set_free(ctx, set);
526                         return NULL;
527                 }
528         }
529         return set;
530 }
531
532 static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
533 {
534         isl_seq_cpy(c, c + n, rem);
535         isl_seq_clr(c + rem, n);
536 }
537
538 struct isl_basic_set *isl_basic_set_drop_vars(struct isl_ctx *ctx,
539                 struct isl_basic_set *bset, unsigned first, unsigned n)
540 {
541         int i;
542
543         if (!bset)
544                 goto error;
545
546         isl_assert(ctx, first + n <= bset->dim, goto error);
547
548         if (n == 0)
549                 return bset;
550
551         bset = isl_basic_set_cow(ctx, bset);
552         if (!bset)
553                 return NULL;
554
555         for (i = 0; i < bset->n_eq; ++i)
556                 constraint_drop_vars(bset->eq[i]+1+bset->nparam+first, n,
557                                      (bset->dim-first-n)+bset->extra);
558
559         for (i = 0; i < bset->n_ineq; ++i)
560                 constraint_drop_vars(bset->ineq[i]+1+bset->nparam+first, n,
561                                      (bset->dim-first-n)+bset->extra);
562
563         for (i = 0; i < bset->n_div; ++i)
564                 constraint_drop_vars(bset->div[i]+1+1+bset->nparam+first, n,
565                                      (bset->dim-first-n)+bset->extra);
566
567         bset->dim -= n;
568         bset->extra += n;
569
570         return isl_basic_set_finalize(ctx, bset);
571 error:
572         isl_basic_set_free(ctx, bset);
573         return NULL;
574 }
575
576 /*
577  * We don't cow, as the div is assumed to be redundant.
578  */
579 static struct isl_basic_map *isl_basic_map_drop_div(struct isl_ctx *ctx,
580                 struct isl_basic_map *bmap, unsigned div)
581 {
582         int i;
583         unsigned pos;
584
585         if (!bmap)
586                 goto error;
587
588         pos = 1 + bmap->nparam + bmap->n_in + bmap->n_out + div;
589
590         isl_assert(ctx, div < bmap->n_div, goto error);
591
592         for (i = 0; i < bmap->n_eq; ++i)
593                 constraint_drop_vars(bmap->eq[i]+pos, 1, bmap->extra-div-1);
594
595         for (i = 0; i < bmap->n_ineq; ++i) {
596                 if (!isl_int_is_zero(bmap->ineq[i][pos])) {
597                         isl_basic_map_drop_inequality(ctx, bmap, i);
598                         --i;
599                         continue;
600                 }
601                 constraint_drop_vars(bmap->ineq[i]+pos, 1, bmap->extra-div-1);
602         }
603
604         for (i = 0; i < bmap->n_div; ++i)
605                 constraint_drop_vars(bmap->div[i]+1+pos, 1, bmap->extra-div-1);
606
607         if (div != bmap->n_div - 1) {
608                 int j;
609                 isl_int *t = bmap->div[div];
610
611                 for (j = div; j < bmap->n_div - 1; ++j)
612                         bmap->div[j] = bmap->div[j+1];
613
614                 bmap->div[bmap->n_div - 1] = t;
615         }
616         isl_basic_map_free_div(ctx, bmap, 1);
617
618         return bmap;
619 error:
620         isl_basic_map_free(ctx, bmap);
621         return NULL;
622 }
623
624 static void eliminate_div(struct isl_ctx *ctx, struct isl_basic_map *bmap,
625                                 isl_int *eq, unsigned div)
626 {
627         int i;
628         unsigned pos = 1 + bmap->nparam + bmap->n_in + bmap->n_out + div;
629         unsigned len;
630         len = 1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
631
632         for (i = 0; i < bmap->n_eq; ++i)
633                 if (bmap->eq[i] != eq)
634                         isl_seq_elim(bmap->eq[i], eq, pos, len, NULL);
635
636         for (i = 0; i < bmap->n_ineq; ++i)
637                 isl_seq_elim(bmap->ineq[i], eq, pos, len, NULL);
638
639         /* We need to be careful about circular definitions,
640          * so for now we just remove the definitions of other divs that
641          * depend on this div and (possibly) recompute them later.
642          */
643         for (i = 0; i < bmap->n_div; ++i)
644                 if (!isl_int_is_zero(bmap->div[i][0]) &&
645                     !isl_int_is_zero(bmap->div[i][1 + pos]))
646                         isl_seq_clr(bmap->div[i], 1 + len);
647
648         isl_basic_map_drop_div(ctx, bmap, div);
649 }
650
651 struct isl_basic_map *isl_basic_map_set_to_empty(
652                 struct isl_ctx *ctx, struct isl_basic_map *bmap)
653 {
654         int i = 0;
655         unsigned total;
656         if (!bmap)
657                 goto error;
658         total = bmap->nparam + bmap->n_in + bmap->n_out;
659         isl_basic_map_free_div(ctx, bmap, bmap->n_div);
660         isl_basic_map_free_inequality(ctx, bmap, bmap->n_ineq);
661         if (bmap->n_eq > 0)
662                 isl_basic_map_free_equality(ctx, bmap, bmap->n_eq-1);
663         else {
664                 isl_basic_map_alloc_equality(ctx, bmap);
665                 if (i < 0)
666                         goto error;
667         }
668         isl_int_set_si(bmap->eq[i][0], 1);
669         isl_seq_clr(bmap->eq[i]+1, total);
670         F_SET(bmap, ISL_BASIC_MAP_EMPTY);
671         return isl_basic_map_finalize(ctx, bmap);
672 error:
673         isl_basic_map_free(ctx, bmap);
674         return NULL;
675 }
676
677 struct isl_basic_set *isl_basic_set_set_to_empty(
678                 struct isl_ctx *ctx, struct isl_basic_set *bset)
679 {
680         return (struct isl_basic_set *)
681                 isl_basic_map_set_to_empty(ctx, (struct isl_basic_map *)bset);
682 }
683
684 static void swap_equality(struct isl_basic_map *bmap, int a, int b)
685 {
686         isl_int *t = bmap->eq[a];
687         bmap->eq[a] = bmap->eq[b];
688         bmap->eq[b] = t;
689 }
690
691 static void swap_inequality(struct isl_basic_map *bmap, int a, int b)
692 {
693         isl_int *t = bmap->ineq[a];
694         bmap->ineq[a] = bmap->ineq[b];
695         bmap->ineq[b] = t;
696 }
697
698 static void swap_div(struct isl_basic_map *bmap, int a, int b)
699 {
700         int i;
701         unsigned off = bmap->nparam + bmap->n_in + bmap->n_out;
702         isl_int *t = bmap->div[a];
703         bmap->div[a] = bmap->div[b];
704         bmap->div[b] = t;
705
706         for (i = 0; i < bmap->n_eq; ++i)
707                 isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]);
708
709         for (i = 0; i < bmap->n_ineq; ++i)
710                 isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]);
711
712         for (i = 0; i < bmap->n_div; ++i)
713                 isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]);
714 }
715
716 struct isl_basic_map *isl_basic_map_gauss(struct isl_ctx *ctx,
717         struct isl_basic_map *bmap, int *progress)
718 {
719         int k;
720         int done;
721         int last_var;
722         unsigned total_var;
723         unsigned total;
724
725         if (!bmap)
726                 return NULL;
727
728         total_var = bmap->nparam + bmap->n_in + bmap->n_out;
729         total = total_var + bmap->n_div;
730
731         last_var = total - 1;
732         for (done = 0; done < bmap->n_eq; ++done) {
733                 for (; last_var >= 0; --last_var) {
734                         for (k = done; k < bmap->n_eq; ++k)
735                                 if (!isl_int_is_zero(bmap->eq[k][1+last_var]))
736                                         break;
737                         if (k < bmap->n_eq)
738                                 break;
739                 }
740                 if (last_var < 0)
741                         break;
742                 if (k != done)
743                         swap_equality(bmap, k, done);
744                 if (isl_int_is_neg(bmap->eq[done][1+last_var]))
745                         isl_seq_neg(bmap->eq[done], bmap->eq[done], 1+total);
746
747                 for (k = 0; k < bmap->n_eq; ++k) {
748                         if (k == done)
749                                 continue;
750                         if (isl_int_is_zero(bmap->eq[k][1+last_var]))
751                                 continue;
752                         if (progress)
753                                 *progress = 1;
754                         isl_seq_elim(bmap->eq[k], bmap->eq[done],
755                                         1+last_var, 1+total, NULL);
756                 }
757
758                 for (k = 0; k < bmap->n_ineq; ++k) {
759                         if (isl_int_is_zero(bmap->ineq[k][1+last_var]))
760                                 continue;
761                         if (progress)
762                                 *progress = 1;
763                         isl_seq_elim(bmap->ineq[k], bmap->eq[done],
764                                         1+last_var, 1+total, NULL);
765                 }
766
767                 for (k = 0; k < bmap->n_div; ++k) {
768                         if (isl_int_is_zero(bmap->div[k][0]))
769                                 continue;
770                         if (isl_int_is_zero(bmap->div[k][1+1+last_var]))
771                                 continue;
772                         if (progress)
773                                 *progress = 1;
774                         isl_seq_elim(bmap->div[k]+1, bmap->eq[done],
775                                         1+last_var, 1+total, &bmap->div[k][0]);
776                 }
777
778                 if (last_var >= total_var &&
779                     isl_int_is_zero(bmap->div[last_var - total_var][0])) {
780                         unsigned div = last_var - total_var;
781                         isl_seq_neg(bmap->div[div]+1, bmap->eq[done], 1+total);
782                         isl_int_set_si(bmap->div[div][1+1+last_var], 0);
783                         isl_int_set(bmap->div[div][0],
784                                     bmap->eq[done][1+last_var]);
785                 }
786         }
787         if (done == bmap->n_eq)
788                 return bmap;
789         for (k = done; k < bmap->n_eq; ++k) {
790                 if (isl_int_is_zero(bmap->eq[k][0]))
791                         continue;
792                 return isl_basic_map_set_to_empty(ctx, bmap);
793         }
794         isl_basic_map_free_equality(ctx, bmap, bmap->n_eq-done);
795         return bmap;
796 }
797
798 struct isl_basic_set *isl_basic_set_gauss(struct isl_ctx *ctx,
799         struct isl_basic_set *bset, int *progress)
800 {
801         return (struct isl_basic_set*)isl_basic_map_gauss(ctx,
802                         (struct isl_basic_map *)bset, progress);
803 }
804
805 static unsigned int round_up(unsigned int v)
806 {
807         int old_v = v;
808
809         while (v) {
810                 old_v = v;
811                 v ^= v & -v;
812         }
813         return old_v << 1;
814 }
815
816 static struct isl_basic_map *remove_duplicate_constraints(
817         struct isl_ctx *ctx,
818         struct isl_basic_map *bmap, int *progress)
819 {
820         unsigned int size;
821         int *index;
822         int k, l, h;
823         int bits;
824         unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
825
826         if (bmap->n_ineq <= 1)
827                 return bmap;
828
829         size = round_up(4 * bmap->n_ineq / 3 - 1);
830         bits = ffs(size) - 1;
831         index = isl_alloc_array(ctx, int, size);
832         memset(index, 0, size * sizeof(int));
833         if (!index)
834                 return bmap;
835
836         index[isl_seq_hash(bmap->ineq[0]+1, total, bits)] = 1;
837         for (k = 1; k < bmap->n_ineq; ++k) {
838                 u_int32_t hash = isl_seq_hash(bmap->ineq[k]+1, total, bits);
839                 for (h = hash; index[h]; h = (h+1) % size)
840                         if (isl_seq_eq(bmap->ineq[k]+1,
841                                        bmap->ineq[index[h]-1]+1, total))
842                                 break;
843                 if (!index[h]) {
844                         index[h] = k+1;
845                         continue;
846                 }
847                 *progress = 1;
848                 l = index[h] - 1;
849                 if (isl_int_lt(bmap->ineq[k][0], bmap->ineq[l][0]))
850                         swap_inequality(bmap, k, l);
851                 isl_basic_map_drop_inequality(ctx, bmap, k);
852                 --k;
853         }
854
855         free(index);
856         return bmap;
857 }
858
859 static struct isl_basic_map *remove_duplicate_divs(struct isl_ctx *ctx,
860         struct isl_basic_map *bmap, int *progress)
861 {
862         unsigned int size;
863         int *index;
864         int k, l, h;
865         int bits;
866         struct isl_blk eq;
867         unsigned total_var = bmap->nparam + bmap->n_in + bmap->n_out;
868         unsigned total = total_var + bmap->n_div;
869
870         if (bmap->n_div <= 1)
871                 return bmap;
872
873         for (k = bmap->n_div - 1; k >= 0; --k)
874                 if (!isl_int_is_zero(bmap->div[k][0]))
875                         break;
876         if (k <= 0)
877                 return bmap;
878
879         size = round_up(4 * bmap->n_div / 3 - 1);
880         bits = ffs(size) - 1;
881         index = isl_alloc_array(ctx, int, size);
882         memset(index, 0, size * sizeof(int));
883         if (!index)
884                 return bmap;
885         eq = isl_blk_alloc(ctx, 1+total);
886         if (!eq.data)
887                 goto out;
888
889         isl_seq_clr(eq.data, 1+total);
890         index[isl_seq_hash(bmap->div[k], 2+total, bits)] = k + 1;
891         for (--k; k >= 0; --k) {
892                 u_int32_t hash;
893
894                 if (isl_int_is_zero(bmap->div[k][0]))
895                         continue;
896
897                 hash = isl_seq_hash(bmap->div[k], 2+total, bits);
898                 for (h = hash; index[h]; h = (h+1) % size)
899                         if (isl_seq_eq(bmap->div[k],
900                                        bmap->div[index[h]-1], 2+total))
901                                 break;
902                 if (index[h]) {
903                         *progress = 1;
904                         l = index[h] - 1;
905                         isl_int_set_si(eq.data[1+total_var+k], -1);
906                         isl_int_set_si(eq.data[1+total_var+l], 1);
907                         eliminate_div(ctx, bmap, eq.data, l);
908                         isl_int_set_si(eq.data[1+total_var+k], 0);
909                         isl_int_set_si(eq.data[1+total_var+l], 0);
910                 }
911                 index[h] = k+1;
912         }
913
914         isl_blk_free(ctx, eq);
915 out:
916         free(index);
917         return bmap;
918 }
919
920 static struct isl_basic_map *eliminate_divs(
921                 struct isl_ctx *ctx, struct isl_basic_map *bmap,
922                 int *progress)
923 {
924         int d;
925         int i;
926         int modified = 0;
927         unsigned off;
928
929         if (!bmap)
930                 return NULL;
931
932         off = 1 + bmap->nparam + bmap->n_in + bmap->n_out;
933
934         for (d = bmap->n_div - 1; d >= 0 ; --d) {
935                 for (i = 0; i < bmap->n_eq; ++i) {
936                         if (!isl_int_is_one(bmap->eq[i][off + d]) &&
937                             !isl_int_is_negone(bmap->eq[i][off + d]))
938                                 continue;
939                         modified = 1;
940                         *progress = 1;
941                         eliminate_div(ctx, bmap, bmap->eq[i], d);
942                         isl_basic_map_drop_equality(ctx, bmap, i);
943                 }
944         }
945         if (modified)
946                 return eliminate_divs(ctx, bmap, progress);
947         return bmap;
948 }
949
950 static struct isl_basic_map *normalize_constraints(
951                 struct isl_ctx *ctx, struct isl_basic_map *bmap)
952 {
953         int i;
954         isl_int gcd;
955         unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
956
957         isl_int_init(gcd);
958         for (i = bmap->n_eq - 1; i >= 0; --i) {
959                 isl_seq_gcd(bmap->eq[i]+1, total, &gcd);
960                 if (isl_int_is_zero(gcd)) {
961                         if (!isl_int_is_zero(bmap->eq[i][0])) {
962                                 bmap = isl_basic_map_set_to_empty(ctx, bmap);
963                                 break;
964                         }
965                         isl_basic_map_drop_equality(ctx, bmap, i);
966                         continue;
967                 }
968                 if (isl_int_is_one(gcd))
969                         continue;
970                 if (!isl_int_is_divisible_by(bmap->eq[i][0], gcd)) {
971                         bmap = isl_basic_map_set_to_empty(ctx, bmap);
972                         break;
973                 }
974                 isl_seq_scale_down(bmap->eq[i], bmap->eq[i], gcd, 1+total);
975         }
976
977         for (i = bmap->n_ineq - 1; i >= 0; --i) {
978                 isl_seq_gcd(bmap->ineq[i]+1, total, &gcd);
979                 if (isl_int_is_zero(gcd)) {
980                         if (isl_int_is_neg(bmap->ineq[i][0])) {
981                                 bmap = isl_basic_map_set_to_empty(ctx, bmap);
982                                 break;
983                         }
984                         isl_basic_map_drop_inequality(ctx, bmap, i);
985                         continue;
986                 }
987                 if (isl_int_is_one(gcd))
988                         continue;
989                 isl_int_fdiv_q(bmap->ineq[i][0], bmap->ineq[i][0], gcd);
990                 isl_seq_scale_down(bmap->ineq[i]+1, bmap->ineq[i]+1, gcd, total);
991         }
992         isl_int_clear(gcd);
993
994         return bmap;
995 }
996
997 struct isl_basic_map *isl_basic_map_simplify(
998                 struct isl_ctx *ctx, struct isl_basic_map *bmap)
999 {
1000         int progress = 1;
1001         if (!bmap)
1002                 return NULL;
1003         while (progress) {
1004                 progress = 0;
1005                 bmap = normalize_constraints(ctx, bmap);
1006                 bmap = eliminate_divs(ctx, bmap, &progress);
1007                 bmap = isl_basic_map_gauss(ctx, bmap, &progress);
1008                 bmap = remove_duplicate_divs(ctx, bmap, &progress);
1009                 bmap = remove_duplicate_constraints(ctx, bmap, &progress);
1010         }
1011         return bmap;
1012 }
1013
1014 struct isl_basic_set *isl_basic_set_simplify(
1015                 struct isl_ctx *ctx, struct isl_basic_set *bset)
1016 {
1017         return (struct isl_basic_set *)
1018                 isl_basic_map_simplify(ctx,
1019                         (struct isl_basic_map *)bset);
1020 }
1021
1022 static void dump_term(struct isl_basic_map *bmap,
1023                         isl_int c, int pos, FILE *out)
1024 {
1025         unsigned in = bmap->n_in;
1026         unsigned dim = bmap->n_in + bmap->n_out;
1027         if (!pos)
1028                 isl_int_print(out, c);
1029         else {
1030                 if (!isl_int_is_one(c))
1031                         isl_int_print(out, c);
1032                 if (pos < 1 + bmap->nparam)
1033                         fprintf(out, "p%d", pos - 1);
1034                 else if (pos < 1 + bmap->nparam + in)
1035                         fprintf(out, "i%d", pos - 1 - bmap->nparam);
1036                 else if (pos < 1 + bmap->nparam + dim)
1037                         fprintf(out, "o%d", pos - 1 - bmap->nparam - in);
1038                 else
1039                         fprintf(out, "e%d", pos - 1 - bmap->nparam - dim);
1040         }
1041 }
1042
1043 static void dump_constraint_sign(struct isl_basic_map *bmap, isl_int *c,
1044                                 int sign, FILE *out)
1045 {
1046         int i;
1047         int first;
1048         unsigned len = 1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
1049         isl_int v;
1050
1051         isl_int_init(v);
1052         for (i = 0, first = 1; i < len; ++i) {
1053                 if (isl_int_sgn(c[i]) * sign <= 0)
1054                         continue;
1055                 if (!first)
1056                         fprintf(out, " + ");
1057                 first = 0;
1058                 isl_int_abs(v, c[i]);
1059                 dump_term(bmap, v, i, out);
1060         }
1061         isl_int_clear(v);
1062         if (first)
1063                 fprintf(out, "0");
1064 }
1065
1066 static void dump_constraint(struct isl_basic_map *bmap, isl_int *c,
1067                                 const char *op, FILE *out, int indent)
1068 {
1069         fprintf(out, "%*s", indent, "");
1070
1071         dump_constraint_sign(bmap, c, 1, out);
1072         fprintf(out, " %s ", op);
1073         dump_constraint_sign(bmap, c, -1, out);
1074
1075         fprintf(out, "\n");
1076 }
1077
1078 static void dump_constraints(struct isl_basic_map *bmap,
1079                                 isl_int **c, unsigned n,
1080                                 const char *op, FILE *out, int indent)
1081 {
1082         int i;
1083
1084         for (i = 0; i < n; ++i)
1085                 dump_constraint(bmap, c[i], op, out, indent);
1086 }
1087
1088 static void dump_affine(struct isl_basic_map *bmap, isl_int *exp, FILE *out)
1089 {
1090         int j;
1091         int first = 1;
1092         unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
1093
1094         for (j = 0; j < 1 + total; ++j) {
1095                 if (isl_int_is_zero(exp[j]))
1096                         continue;
1097                 if (!first && isl_int_is_pos(exp[j]))
1098                         fprintf(out, "+");
1099                 dump_term(bmap, exp[j], j, out);
1100                 first = 0;
1101         }
1102 }
1103
1104 static void dump(struct isl_basic_map *bmap, FILE *out, int indent)
1105 {
1106         int i;
1107
1108         dump_constraints(bmap, bmap->eq, bmap->n_eq, "=", out, indent);
1109         dump_constraints(bmap, bmap->ineq, bmap->n_ineq, ">=", out, indent);
1110
1111         for (i = 0; i < bmap->n_div; ++i) {
1112                 fprintf(out, "%*s", indent, "");
1113                 fprintf(out, "e%d = [(", i);
1114                 dump_affine(bmap, bmap->div[i]+1, out);
1115                 fprintf(out, ")/");
1116                 isl_int_print(out, bmap->div[i][0]);
1117                 fprintf(out, "]\n");
1118         }
1119 }
1120
1121 void isl_basic_set_dump(struct isl_ctx *ctx, struct isl_basic_set *bset,
1122                                 FILE *out, int indent)
1123 {
1124         fprintf(out, "%*s", indent, "");
1125         fprintf(out, "nparam: %d, dim: %d, extra: %d\n",
1126                         bset->nparam, bset->dim, bset->extra);
1127         dump((struct isl_basic_map *)bset, out, indent);
1128 }
1129
1130 void isl_basic_map_dump(struct isl_ctx *ctx, struct isl_basic_map *bmap,
1131                                 FILE *out, int indent)
1132 {
1133         fprintf(out, "%*s", indent, "");
1134         fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d\n",
1135                 bmap->ref,
1136                 bmap->nparam, bmap->n_in, bmap->n_out, bmap->extra);
1137         dump(bmap, out, indent);
1138 }
1139
1140 int isl_inequality_negate(struct isl_ctx *ctx,
1141                 struct isl_basic_map *bmap, unsigned pos)
1142 {
1143         unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
1144         isl_assert(ctx, pos < bmap->n_ineq, return -1);
1145         isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
1146         isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1);
1147         return 0;
1148 }
1149
1150 struct isl_set *isl_set_alloc(struct isl_ctx *ctx,
1151                 unsigned nparam, unsigned dim, int n, unsigned flags)
1152 {
1153         struct isl_set *set;
1154
1155         set = isl_alloc(ctx, struct isl_set,
1156                         sizeof(struct isl_set) +
1157                         n * sizeof(struct isl_basic_set *));
1158         if (!set)
1159                 return NULL;
1160
1161         set->ref = 1;
1162         set->size = n;
1163         set->n = 0;
1164         set->nparam = nparam;
1165         set->zero = 0;
1166         set->dim = dim;
1167         set->flags = flags;
1168         return set;
1169 }
1170
1171 struct isl_set *isl_set_dup(struct isl_ctx *ctx, struct isl_set *set)
1172 {
1173         int i;
1174         struct isl_set *dup;
1175
1176         dup = isl_set_alloc(ctx, set->nparam, set->dim, set->n, set->flags);
1177         if (!dup)
1178                 return NULL;
1179         for (i = 0; i < set->n; ++i)
1180                 dup = isl_set_add(ctx, dup,
1181                                   isl_basic_set_dup(ctx, set->p[i]));
1182         return dup;
1183 }
1184
1185 struct isl_set *isl_set_from_basic_set(struct isl_ctx *ctx,
1186                                 struct isl_basic_set *bset)
1187 {
1188         struct isl_set *set;
1189
1190         set = isl_set_alloc(ctx, bset->nparam, bset->dim, 1, ISL_MAP_DISJOINT);
1191         if (!set) {
1192                 isl_basic_set_free(ctx, bset);
1193                 return NULL;
1194         }
1195         return isl_set_add(ctx, set, bset);
1196 }
1197
1198 struct isl_map *isl_map_from_basic_map(struct isl_ctx *ctx,
1199                                 struct isl_basic_map *bmap)
1200 {
1201         struct isl_map *map;
1202
1203         map = isl_map_alloc(ctx, bmap->nparam, bmap->n_in, bmap->n_out, 1,
1204                                 ISL_MAP_DISJOINT);
1205         if (!map) {
1206                 isl_basic_map_free(ctx, bmap);
1207                 return NULL;
1208         }
1209         return isl_map_add(ctx, map, bmap);
1210 }
1211
1212 struct isl_set *isl_set_add(struct isl_ctx *ctx, struct isl_set *set,
1213                                 struct isl_basic_set *bset)
1214 {
1215         if (!bset || !set)
1216                 goto error;
1217         isl_assert(ctx, set->nparam == bset->nparam, goto error);
1218         isl_assert(ctx, set->dim == bset->dim, goto error);
1219         isl_assert(ctx, set->n < set->size, goto error);
1220         set->p[set->n] = bset;
1221         set->n++;
1222         return set;
1223 error:
1224         if (set)
1225                 isl_set_free(ctx, set);
1226         if (bset)
1227                 isl_basic_set_free(ctx, bset);
1228         return NULL;
1229 }
1230
1231 void isl_set_free(struct isl_ctx *ctx, struct isl_set *set)
1232 {
1233         int i;
1234
1235         if (!set)
1236                 return;
1237
1238         if (--set->ref > 0)
1239                 return;
1240
1241         for (i = 0; i < set->n; ++i)
1242                 isl_basic_set_free(ctx, set->p[i]);
1243         free(set);
1244 }
1245
1246 void isl_set_dump(struct isl_ctx *ctx, struct isl_set *set, FILE *out,
1247                   int indent)
1248 {
1249         int i;
1250
1251         if (!set) {
1252                 fprintf(out, "null set\n");
1253                 return;
1254         }
1255
1256         fprintf(out, "%*s", indent, "");
1257         fprintf(out, "ref: %d, n: %d\n", set->ref, set->n);
1258         for (i = 0; i < set->n; ++i) {
1259                 fprintf(out, "%*s", indent, "");
1260                 fprintf(out, "basic set %d:\n", i);
1261                 isl_basic_set_dump(ctx, set->p[i], out, indent+4);
1262         }
1263 }
1264
1265 void isl_map_dump(struct isl_ctx *ctx, struct isl_map *map, FILE *out,
1266                   int indent)
1267 {
1268         int i;
1269
1270         fprintf(out, "%*s", indent, "");
1271         fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d\n",
1272                         map->ref, map->n, map->nparam, map->n_in, map->n_out);
1273         for (i = 0; i < map->n; ++i) {
1274                 fprintf(out, "%*s", indent, "");
1275                 fprintf(out, "basic map %d:\n", i);
1276                 isl_basic_map_dump(ctx, map->p[i], out, indent+4);
1277         }
1278 }
1279
1280 struct isl_basic_map *isl_basic_map_intersect_domain(
1281                 struct isl_ctx *ctx, struct isl_basic_map *bmap,
1282                 struct isl_basic_set *bset)
1283 {
1284         struct isl_basic_map *bmap_domain;
1285
1286         if (!bmap || !bset)
1287                 goto error;
1288
1289         isl_assert(ctx, bset->dim == bmap->n_in, goto error);
1290         isl_assert(ctx, bset->nparam == bmap->nparam, goto error);
1291
1292         bmap = isl_basic_map_extend(ctx, bmap,
1293                         bset->nparam, bmap->n_in, bmap->n_out,
1294                         bset->n_div, bset->n_eq, bset->n_ineq);
1295         if (!bmap)
1296                 goto error;
1297         bmap_domain = isl_basic_map_from_basic_set(ctx, bset,
1298                                                 bset->dim, 0);
1299         bmap = add_constraints(ctx, bmap, bmap_domain, 0, 0);
1300
1301         bmap = isl_basic_map_simplify(ctx, bmap);
1302         return isl_basic_map_finalize(ctx, bmap);
1303 error:
1304         isl_basic_map_free(ctx, bmap);
1305         isl_basic_set_free(ctx, bset);
1306         return NULL;
1307 }
1308
1309 struct isl_basic_map *isl_basic_map_intersect_range(
1310                 struct isl_ctx *ctx, struct isl_basic_map *bmap,
1311                 struct isl_basic_set *bset)
1312 {
1313         struct isl_basic_map *bmap_range;
1314
1315         if (!bmap || !bset)
1316                 goto error;
1317
1318         isl_assert(ctx, bset->dim == bmap->n_out, goto error);
1319         isl_assert(ctx, bset->nparam == bmap->nparam, goto error);
1320
1321         bmap = isl_basic_map_extend(ctx, bmap,
1322                         bset->nparam, bmap->n_in, bmap->n_out,
1323                         bset->n_div, bset->n_eq, bset->n_ineq);
1324         if (!bmap)
1325                 goto error;
1326         bmap_range = isl_basic_map_from_basic_set(ctx, bset,
1327                                                 0, bset->dim);
1328         bmap = add_constraints(ctx, bmap, bmap_range, 0, 0);
1329
1330         bmap = isl_basic_map_simplify(ctx, bmap);
1331         return isl_basic_map_finalize(ctx, bmap);
1332 error:
1333         isl_basic_map_free(ctx, bmap);
1334         isl_basic_set_free(ctx, bset);
1335         return NULL;
1336 }
1337
1338 struct isl_basic_map *isl_basic_map_intersect(
1339                 struct isl_ctx *ctx, struct isl_basic_map *bmap1,
1340                 struct isl_basic_map *bmap2)
1341 {
1342         isl_assert(ctx, bmap1->nparam == bmap2->nparam, goto error);
1343         isl_assert(ctx, bmap1->n_in == bmap2->n_in, goto error);
1344         isl_assert(ctx, bmap1->n_out == bmap2->n_out, goto error);
1345
1346         bmap1 = isl_basic_map_extend(ctx, bmap1,
1347                         bmap1->nparam, bmap1->n_in, bmap1->n_out,
1348                         bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
1349         if (!bmap1)
1350                 goto error;
1351         bmap1 = add_constraints(ctx, bmap1, bmap2, 0, 0);
1352
1353         bmap1 = isl_basic_map_simplify(ctx, bmap1);
1354         return isl_basic_map_finalize(ctx, bmap1);
1355 error:
1356         isl_basic_map_free(ctx, bmap1);
1357         isl_basic_map_free(ctx, bmap2);
1358         return NULL;
1359 }
1360
1361 struct isl_basic_set *isl_basic_set_intersect(
1362                 struct isl_ctx *ctx, struct isl_basic_set *bset1,
1363                 struct isl_basic_set *bset2)
1364 {
1365         return (struct isl_basic_set *)
1366                 isl_basic_map_intersect(ctx,
1367                         (struct isl_basic_map *)bset1,
1368                         (struct isl_basic_map *)bset2);
1369 }
1370
1371 struct isl_map *isl_map_intersect(struct isl_ctx *ctx, struct isl_map *map1,
1372                 struct isl_map *map2)
1373 {
1374         unsigned flags = 0;
1375         struct isl_map *result;
1376         int i, j;
1377
1378         if (!map1 || !map2)
1379                 goto error;
1380
1381         if (F_ISSET(map1, ISL_MAP_DISJOINT) &&
1382             F_ISSET(map2, ISL_MAP_DISJOINT))
1383                 FL_SET(flags, ISL_MAP_DISJOINT);
1384
1385         result = isl_map_alloc(ctx, map1->nparam, map1->n_in, map1->n_out,
1386                                 map1->n * map2->n, flags);
1387         if (!result)
1388                 goto error;
1389         for (i = 0; i < map1->n; ++i)
1390                 for (j = 0; j < map2->n; ++j) {
1391                         struct isl_basic_map *part;
1392                         part = isl_basic_map_intersect(ctx,
1393                                     isl_basic_map_copy(ctx, map1->p[i]),
1394                                     isl_basic_map_copy(ctx, map2->p[j]));
1395                         if (isl_basic_map_is_empty(ctx, part))
1396                                 isl_basic_map_free(ctx, part);
1397                         else
1398                                 result = isl_map_add(ctx, result, part);
1399                         if (!result)
1400                                 goto error;
1401                 }
1402         isl_map_free(ctx, map1);
1403         isl_map_free(ctx, map2);
1404         return result;
1405 error:
1406         isl_map_free(ctx, map1);
1407         isl_map_free(ctx, map2);
1408         return NULL;
1409 }
1410
1411 struct isl_basic_map *isl_basic_map_reverse(struct isl_ctx *ctx,
1412                 struct isl_basic_map *bmap)
1413 {
1414         struct isl_basic_set *bset;
1415         unsigned in;
1416
1417         if (!bmap)
1418                 return NULL;
1419         bmap = isl_basic_map_cow(ctx, bmap);
1420         if (!bmap)
1421                 return NULL;
1422         in = bmap->n_in;
1423         bset = isl_basic_set_from_basic_map(ctx, bmap);
1424         bset = isl_basic_set_swap_vars(ctx, bset, in);
1425         return isl_basic_map_from_basic_set(ctx, bset, bset->dim-in, in);
1426 }
1427
1428 /* Turn final n dimensions into existentially quantified variables.
1429  */
1430 struct isl_basic_set *isl_basic_set_project_out(
1431                 struct isl_ctx *ctx, struct isl_basic_set *bset,
1432                 unsigned n, unsigned flags)
1433 {
1434         int i;
1435         size_t row_size;
1436         isl_int **new_div;
1437         isl_int *old;
1438
1439         if (!bset)
1440                 return NULL;
1441
1442         isl_assert(ctx, n <= bset->dim, goto error);
1443
1444         if (n == 0)
1445                 return bset;
1446
1447         bset = isl_basic_set_cow(ctx, bset);
1448
1449         row_size = 1 + bset->nparam + bset->dim + bset->extra;
1450         old = bset->block2.data;
1451         bset->block2 = isl_blk_extend(ctx, bset->block2,
1452                                         (bset->extra + n) * (1 + row_size));
1453         if (!bset->block2.data)
1454                 goto error;
1455         new_div = isl_alloc_array(ctx, isl_int *, bset->extra + n);
1456         if (!new_div)
1457                 goto error;
1458         for (i = 0; i < n; ++i) {
1459                 new_div[i] = bset->block2.data +
1460                                 (bset->extra + i) * (1 + row_size);
1461                 isl_seq_clr(new_div[i], 1 + row_size);
1462         }
1463         for (i = 0; i < bset->extra; ++i)
1464                 new_div[n + i] = bset->block2.data + (bset->div[i] - old);
1465         free(bset->div);
1466         bset->div = new_div;
1467         bset->n_div += n;
1468         bset->extra += n;
1469         bset->dim -= n;
1470         bset = isl_basic_set_simplify(ctx, bset);
1471         return isl_basic_set_finalize(ctx, bset);
1472 error:
1473         isl_basic_set_free(ctx, bset);
1474         return NULL;
1475 }
1476
1477 struct isl_basic_map *isl_basic_map_apply_range(
1478                 struct isl_ctx *ctx, struct isl_basic_map *bmap1,
1479                 struct isl_basic_map *bmap2)
1480 {
1481         struct isl_basic_set *bset;
1482         unsigned n_in, n_out;
1483
1484         if (!bmap1 || !bmap2)
1485                 goto error;
1486
1487         isl_assert(ctx, bmap1->n_out == bmap2->n_in, goto error);
1488         isl_assert(ctx, bmap1->nparam == bmap2->nparam, goto error);
1489
1490         n_in = bmap1->n_in;
1491         n_out = bmap2->n_out;
1492
1493         bmap2 = isl_basic_map_reverse(ctx, bmap2);
1494         if (!bmap2)
1495                 goto error;
1496         bmap1 = isl_basic_map_extend(ctx, bmap1, bmap1->nparam,
1497                         bmap1->n_in + bmap2->n_in, bmap1->n_out,
1498                         bmap2->extra, bmap2->n_eq, bmap2->n_ineq);
1499         if (!bmap1)
1500                 goto error;
1501         bmap1 = add_constraints(ctx, bmap1, bmap2, bmap1->n_in - bmap2->n_in, 0);
1502         bmap1 = isl_basic_map_simplify(ctx, bmap1);
1503         bset = isl_basic_set_from_basic_map(ctx, bmap1);
1504         bset = isl_basic_set_project_out(ctx, bset,
1505                                                 bset->dim - (n_in + n_out), 0);
1506         return isl_basic_map_from_basic_set(ctx, bset, n_in, n_out);
1507 error:
1508         isl_basic_map_free(ctx, bmap1);
1509         isl_basic_map_free(ctx, bmap2);
1510         return NULL;
1511 }
1512
1513 struct isl_basic_map *isl_basic_map_apply_domain(
1514                 struct isl_ctx *ctx, struct isl_basic_map *bmap1,
1515                 struct isl_basic_map *bmap2)
1516 {
1517         if (!bmap1 || !bmap2)
1518                 goto error;
1519
1520         isl_assert(ctx, bmap1->n_in == bmap2->n_in, goto error);
1521         isl_assert(ctx, bmap1->nparam == bmap2->nparam, goto error);
1522
1523         bmap1 = isl_basic_map_reverse(ctx, bmap1);
1524         bmap1 = isl_basic_map_apply_range(ctx, bmap1, bmap2);
1525         return isl_basic_map_reverse(ctx, bmap1);
1526 error:
1527         isl_basic_map_free(ctx, bmap1);
1528         isl_basic_map_free(ctx, bmap2);
1529         return NULL;
1530 }
1531
1532 static struct isl_basic_map *var_equal(struct isl_ctx *ctx,
1533                 struct isl_basic_map *bmap, unsigned pos)
1534 {
1535         int i;
1536         i = isl_basic_map_alloc_equality(ctx, bmap);
1537         if (i < 0)
1538                 goto error;
1539         isl_seq_clr(bmap->eq[i],
1540                     1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->extra);
1541         isl_int_set_si(bmap->eq[i][1+bmap->nparam+pos], -1);
1542         isl_int_set_si(bmap->eq[i][1+bmap->nparam+bmap->n_in+pos], 1);
1543         return isl_basic_map_finalize(ctx, bmap);
1544 error:
1545         isl_basic_map_free(ctx, bmap);
1546         return NULL;
1547 }
1548
1549 static struct isl_basic_map *var_more(struct isl_ctx *ctx,
1550                 struct isl_basic_map *bmap, unsigned pos)
1551 {
1552         int i;
1553         i = isl_basic_map_alloc_inequality(ctx, bmap);
1554         if (i < 0)
1555                 goto error;
1556         isl_seq_clr(bmap->ineq[i],
1557                     1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->extra);
1558         isl_int_set_si(bmap->ineq[i][0], -1);
1559         isl_int_set_si(bmap->ineq[i][1+bmap->nparam+pos], -1);
1560         isl_int_set_si(bmap->ineq[i][1+bmap->nparam+bmap->n_in+pos], 1);
1561         return isl_basic_map_finalize(ctx, bmap);
1562 error:
1563         isl_basic_map_free(ctx, bmap);
1564         return NULL;
1565 }
1566
1567 static struct isl_basic_map *var_less(struct isl_ctx *ctx,
1568                 struct isl_basic_map *bmap, unsigned pos)
1569 {
1570         int i;
1571         i = isl_basic_map_alloc_inequality(ctx, bmap);
1572         if (i < 0)
1573                 goto error;
1574         isl_seq_clr(bmap->ineq[i],
1575                     1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->extra);
1576         isl_int_set_si(bmap->ineq[i][0], -1);
1577         isl_int_set_si(bmap->ineq[i][1+bmap->nparam+pos], 1);
1578         isl_int_set_si(bmap->ineq[i][1+bmap->nparam+bmap->n_in+pos], -1);
1579         return isl_basic_map_finalize(ctx, bmap);
1580 error:
1581         isl_basic_map_free(ctx, bmap);
1582         return NULL;
1583 }
1584
1585 struct isl_basic_map *isl_basic_map_equal(struct isl_ctx *ctx,
1586                 unsigned nparam, unsigned in, unsigned out, unsigned n_equal)
1587 {
1588         int i;
1589         struct isl_basic_map *bmap;
1590         bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, n_equal, 0);
1591         if (!bmap)
1592                 return NULL;
1593         for (i = 0; i < n_equal && bmap; ++i)
1594                 bmap = var_equal(ctx, bmap, i);
1595         return isl_basic_map_finalize(ctx, bmap);
1596 }
1597
1598 struct isl_basic_map *isl_basic_map_less_at(struct isl_ctx *ctx,
1599                 unsigned nparam, unsigned in, unsigned out, unsigned pos)
1600 {
1601         int i;
1602         struct isl_basic_map *bmap;
1603         bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, pos, 1);
1604         if (!bmap)
1605                 return NULL;
1606         for (i = 0; i < pos && bmap; ++i)
1607                 bmap = var_equal(ctx, bmap, i);
1608         if (bmap)
1609                 bmap = var_less(ctx, bmap, pos);
1610         return isl_basic_map_finalize(ctx, bmap);
1611 }
1612
1613 struct isl_basic_map *isl_basic_map_more_at(struct isl_ctx *ctx,
1614                 unsigned nparam, unsigned in, unsigned out, unsigned pos)
1615 {
1616         int i;
1617         struct isl_basic_map *bmap;
1618         bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, pos, 1);
1619         if (!bmap)
1620                 return NULL;
1621         for (i = 0; i < pos && bmap; ++i)
1622                 bmap = var_equal(ctx, bmap, i);
1623         if (bmap)
1624                 bmap = var_more(ctx, bmap, pos);
1625         return isl_basic_map_finalize(ctx, bmap);
1626 }
1627
1628 struct isl_basic_map *isl_basic_map_from_basic_set(
1629                 struct isl_ctx *ctx, struct isl_basic_set *bset,
1630                 unsigned n_in, unsigned n_out)
1631 {
1632         struct isl_basic_map *bmap;
1633
1634         bset = isl_basic_set_cow(ctx, bset);
1635         if (!bset)
1636                 return NULL;
1637
1638         isl_assert(ctx, bset->dim == n_in + n_out, goto error);
1639         bmap = (struct isl_basic_map *) bset;
1640         bmap->n_in = n_in;
1641         bmap->n_out = n_out;
1642         return isl_basic_map_finalize(ctx, bmap);
1643 error:
1644         isl_basic_set_free(ctx, bset);
1645         return NULL;
1646 }
1647
1648 struct isl_basic_set *isl_basic_set_from_basic_map(
1649                 struct isl_ctx *ctx, struct isl_basic_map *bmap)
1650 {
1651         if (!bmap)
1652                 goto error;
1653         if (bmap->n_in == 0)
1654                 return (struct isl_basic_set *)bmap;
1655         bmap = isl_basic_map_cow(ctx, bmap);
1656         if (!bmap)
1657                 goto error;
1658         bmap->n_out += bmap->n_in;
1659         bmap->n_in = 0;
1660         bmap = isl_basic_map_finalize(ctx, bmap);
1661         return (struct isl_basic_set *)bmap;
1662 error:
1663         return NULL;
1664 }
1665
1666 static struct isl_basic_set *isl_basic_map_underlying_set(
1667                 struct isl_ctx *ctx, struct isl_basic_map *bmap)
1668 {
1669         if (!bmap)
1670                 goto error;
1671         if (bmap->nparam == 0 && bmap->n_in == 0 && bmap->n_div == 0)
1672                 return (struct isl_basic_set *)bmap;
1673         bmap = isl_basic_map_cow(ctx, bmap);
1674         if (!bmap)
1675                 goto error;
1676         bmap->n_out += bmap->nparam + bmap->n_in + bmap->n_div;
1677         bmap->nparam = 0;
1678         bmap->n_in = 0;
1679         bmap->n_div = 0;
1680         bmap = isl_basic_map_finalize(ctx, bmap);
1681         return (struct isl_basic_set *)bmap;
1682 error:
1683         return NULL;
1684 }
1685
1686 struct isl_basic_set *isl_basic_map_domain(struct isl_ctx *ctx,
1687                 struct isl_basic_map *bmap)
1688 {
1689         struct isl_basic_set *domain;
1690         unsigned n_out;
1691         if (!bmap)
1692                 return NULL;
1693         n_out = bmap->n_out;
1694         domain = isl_basic_set_from_basic_map(ctx, bmap);
1695         return isl_basic_set_project_out(ctx, domain, n_out, 0);
1696 }
1697
1698 struct isl_basic_set *isl_basic_map_range(struct isl_ctx *ctx,
1699                 struct isl_basic_map *bmap)
1700 {
1701         return isl_basic_map_domain(ctx,
1702                         isl_basic_map_reverse(ctx, bmap));
1703 }
1704
1705 struct isl_set *isl_map_range(struct isl_ctx *ctx, struct isl_map *map)
1706 {
1707         int i;
1708         struct isl_set *set;
1709
1710         if (!map)
1711                 goto error;
1712         map = isl_map_cow(ctx, map);
1713         if (!map)
1714                 goto error;
1715
1716         set = (struct isl_set *) map;
1717         set->zero = 0;
1718         for (i = 0; i < map->n; ++i) {
1719                 set->p[i] = isl_basic_map_range(ctx, map->p[i]);
1720                 if (!set->p[i])
1721                         goto error;
1722         }
1723         F_CLR(set, ISL_MAP_DISJOINT);
1724         return set;
1725 error:
1726         isl_map_free(ctx, map);
1727         return NULL;
1728 }
1729
1730 struct isl_map *isl_map_from_set(
1731                 struct isl_ctx *ctx, struct isl_set *set,
1732                 unsigned n_in, unsigned n_out)
1733 {
1734         int i;
1735         struct isl_map *map = NULL;
1736
1737         if (!set)
1738                 return NULL;
1739         isl_assert(ctx, set->dim == n_in + n_out, goto error);
1740         set = isl_set_cow(ctx, set);
1741         if (!set)
1742                 return NULL;
1743         map = (struct isl_map *)set;
1744         for (i = 0; i < set->n; ++i) {
1745                 map->p[i] = isl_basic_map_from_basic_set(ctx,
1746                                 set->p[i], n_in, n_out);
1747                 if (!map->p[i])
1748                         goto error;
1749         }
1750         map->n_in = n_in;
1751         map->n_out = n_out;
1752         return map;
1753 error:
1754         isl_set_free(ctx, set);
1755         return NULL;
1756 }
1757
1758 struct isl_map *isl_map_alloc(struct isl_ctx *ctx,
1759                 unsigned nparam, unsigned in, unsigned out, int n,
1760                 unsigned flags)
1761 {
1762         struct isl_map *map;
1763
1764         map = isl_alloc(ctx, struct isl_map,
1765                         sizeof(struct isl_map) +
1766                         n * sizeof(struct isl_basic_map *));
1767         if (!map)
1768                 return NULL;
1769
1770         map->ref = 1;
1771         map->size = n;
1772         map->n = 0;
1773         map->nparam = nparam;
1774         map->n_in = in;
1775         map->n_out = out;
1776         map->flags = flags;
1777         return map;
1778 }
1779
1780 struct isl_basic_map *isl_basic_map_empty(struct isl_ctx *ctx,
1781                 unsigned nparam, unsigned in, unsigned out)
1782 {
1783         struct isl_basic_map *bmap;
1784         bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, 1, 0);
1785         bmap = isl_basic_map_set_to_empty(ctx, bmap);
1786         return bmap;
1787 }
1788
1789 struct isl_map *isl_map_empty(struct isl_ctx *ctx,
1790                 unsigned nparam, unsigned in, unsigned out)
1791 {
1792         return isl_map_alloc(ctx, nparam, in, out, 0, ISL_MAP_DISJOINT);
1793 }
1794
1795 struct isl_set *isl_set_empty(struct isl_ctx *ctx,
1796                 unsigned nparam, unsigned dim)
1797 {
1798         return isl_set_alloc(ctx, nparam, dim, 0, ISL_MAP_DISJOINT);
1799 }
1800
1801 struct isl_map *isl_map_dup(struct isl_ctx *ctx, struct isl_map *map)
1802 {
1803         int i;
1804         struct isl_map *dup;
1805
1806         dup = isl_map_alloc(ctx, map->nparam, map->n_in, map->n_out, map->n,
1807                                 map->flags);
1808         for (i = 0; i < map->n; ++i)
1809                 dup = isl_map_add(ctx, dup,
1810                                   isl_basic_map_dup(ctx, map->p[i]));
1811         return dup;
1812 }
1813
1814 struct isl_map *isl_map_add(struct isl_ctx *ctx, struct isl_map *map,
1815                                 struct isl_basic_map *bmap)
1816 {
1817         if (!bmap || !map)
1818                 goto error;
1819         isl_assert(ctx, map->nparam == bmap->nparam, goto error);
1820         isl_assert(ctx, map->n_in == bmap->n_in, goto error);
1821         isl_assert(ctx, map->n_out == bmap->n_out, goto error);
1822         isl_assert(ctx, map->n < map->size, goto error);
1823         map->p[map->n] = bmap;
1824         map->n++;
1825         return map;
1826 error:
1827         if (map)
1828                 isl_map_free(ctx, map);
1829         if (bmap)
1830                 isl_basic_map_free(ctx, bmap);
1831         return NULL;
1832 }
1833
1834 void isl_map_free(struct isl_ctx *ctx, struct isl_map *map)
1835 {
1836         int i;
1837
1838         if (!map)
1839                 return;
1840
1841         if (--map->ref > 0)
1842                 return;
1843
1844         for (i = 0; i < map->n; ++i)
1845                 isl_basic_map_free(ctx, map->p[i]);
1846         free(map);
1847 }
1848
1849 struct isl_map *isl_map_extend(struct isl_ctx *ctx, struct isl_map *base,
1850                 unsigned nparam, unsigned n_in, unsigned n_out)
1851 {
1852         int i;
1853
1854         base = isl_map_cow(ctx, base);
1855         if (!base)
1856                 return NULL;
1857
1858         isl_assert(ctx, base->nparam <= nparam, goto error);
1859         isl_assert(ctx, base->n_in <= n_in, goto error);
1860         isl_assert(ctx, base->n_out <= n_out, goto error);
1861         base->nparam = nparam;
1862         base->n_in = n_in;
1863         base->n_out = n_out;
1864         for (i = 0; i < base->n; ++i) {
1865                 base->p[i] = isl_basic_map_extend(ctx, base->p[i],
1866                                 nparam, n_in, n_out, 0, 0, 0);
1867                 if (!base->p[i])
1868                         goto error;
1869         }
1870         return base;
1871 error:
1872         isl_map_free(ctx, base);
1873         return NULL;
1874 }
1875
1876 struct isl_basic_map *isl_basic_map_fix_input_si(struct isl_ctx *ctx,
1877                 struct isl_basic_map *bmap,
1878                 unsigned input, int value)
1879 {
1880         int j;
1881
1882         bmap = isl_basic_map_cow(ctx, bmap);
1883         if (!bmap)
1884                 return NULL;
1885         isl_assert(ctx, input < bmap->n_in, goto error);
1886
1887         bmap = isl_basic_map_extend(ctx, bmap,
1888                         bmap->nparam, bmap->n_in, bmap->n_out, 0, 1, 0);
1889         j = isl_basic_map_alloc_equality(ctx, bmap);
1890         if (j < 0)
1891                 goto error;
1892         isl_int_set_si(bmap->eq[j][1+bmap->nparam+input], -1);
1893         isl_int_set_si(bmap->eq[j][0], value);
1894         bmap = isl_basic_map_simplify(ctx, bmap);
1895         return isl_basic_map_finalize(ctx, bmap);
1896 error:
1897         isl_basic_map_free(ctx, bmap);
1898         return NULL;
1899 }
1900
1901 struct isl_map *isl_map_fix_input_si(struct isl_ctx *ctx, struct isl_map *map,
1902                 unsigned input, int value)
1903 {
1904         int i;
1905
1906         map = isl_map_cow(ctx, map);
1907         if (!map)
1908                 return NULL;
1909
1910         isl_assert(ctx, input < map->n_in, goto error);
1911         for (i = 0; i < map->n; ++i) {
1912                 map->p[i] = isl_basic_map_fix_input_si(ctx, map->p[i],
1913                                                                 input, value);
1914                 if (!map->p[i])
1915                         goto error;
1916         }
1917         return map;
1918 error:
1919         isl_map_free(ctx, map);
1920         return NULL;
1921 }
1922
1923 struct isl_map *isl_map_reverse(struct isl_ctx *ctx, struct isl_map *map)
1924 {
1925         int i;
1926         unsigned t;
1927
1928         map = isl_map_cow(ctx, map);
1929         if (!map)
1930                 return NULL;
1931
1932         t = map->n_in;
1933         map->n_in = map->n_out;
1934         map->n_out = t;
1935         for (i = 0; i < map->n; ++i) {
1936                 map->p[i] = isl_basic_map_reverse(ctx, map->p[i]);
1937                 if (!map->p[i])
1938                         goto error;
1939         }
1940         return map;
1941 error:
1942         isl_map_free(ctx, map);
1943         return NULL;
1944 }
1945
1946 struct isl_map *isl_basic_map_lexmax(struct isl_ctx *ctx,
1947                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
1948                 struct isl_set **empty)
1949 {
1950         return isl_pip_basic_map_lexmax(ctx, bmap, dom, empty);
1951 }
1952
1953 struct isl_map *isl_basic_map_lexmin(struct isl_ctx *ctx,
1954                 struct isl_basic_map *bmap, struct isl_basic_set *dom,
1955                 struct isl_set **empty)
1956 {
1957         return isl_pip_basic_map_lexmin(ctx, bmap, dom, empty);
1958 }
1959
1960 struct isl_set *isl_basic_set_lexmin(struct isl_ctx *ctx,
1961                 struct isl_basic_set *bset)
1962 {
1963         struct isl_basic_map *bmap = NULL;
1964         struct isl_basic_set *dom = NULL;
1965         struct isl_map *min;
1966
1967         if (!bset)
1968                 goto error;
1969         bmap = isl_basic_map_from_basic_set(ctx, bset, 0, bset->dim);
1970         if (!bmap)
1971                 goto error;
1972         dom = isl_basic_set_alloc(ctx, bmap->nparam, 0, 0, 0, 0);
1973         if (!dom)
1974                 goto error;
1975         min = isl_basic_map_lexmin(ctx, bmap, dom, NULL);
1976         return isl_map_range(ctx, min);
1977 error:
1978         isl_basic_map_free(ctx, bmap);
1979         return NULL;
1980 }
1981
1982 struct isl_map *isl_basic_map_compute_divs(struct isl_ctx *ctx,
1983                 struct isl_basic_map *bmap)
1984 {
1985         if (bmap->n_div == 0)
1986                 return isl_map_from_basic_map(ctx, bmap);
1987         return isl_pip_basic_map_compute_divs(ctx, bmap);
1988 }
1989
1990 struct isl_map *isl_map_compute_divs(struct isl_ctx *ctx, struct isl_map *map)
1991 {
1992         int i;
1993         struct isl_map *res;
1994
1995         if (!map)
1996                 return NULL;
1997         if (map->n == 0)
1998                 return map;
1999         res = isl_basic_map_compute_divs(ctx,
2000                 isl_basic_map_copy(ctx, map->p[0]));
2001         for (i = 1 ; i < map->n; ++i) {
2002                 struct isl_map *r2;
2003                 r2 = isl_basic_map_compute_divs(ctx,
2004                         isl_basic_map_copy(ctx, map->p[i]));
2005                 if (F_ISSET(map, ISL_MAP_DISJOINT))
2006                         res = isl_map_union_disjoint(ctx, res, r2);
2007                 else
2008                         res = isl_map_union(ctx, res, r2);
2009         }
2010         isl_map_free(ctx, map);
2011
2012         return res;
2013 }
2014
2015 struct isl_set *isl_basic_set_compute_divs(struct isl_ctx *ctx,
2016                 struct isl_basic_set *bset)
2017 {
2018         return (struct isl_set *)
2019                 isl_basic_map_compute_divs(ctx,
2020                         (struct isl_basic_map *)bset);
2021 }
2022
2023 struct isl_set *isl_map_domain(struct isl_ctx *ctx, struct isl_map *map)
2024 {
2025         int i;
2026         struct isl_set *set;
2027
2028         if (!map)
2029                 goto error;
2030
2031         map = isl_map_cow(ctx, map);
2032         if (!map)
2033                 return NULL;
2034
2035         set = (struct isl_set *)map;
2036         set->dim = map->n_in;
2037         set->zero = 0;
2038         for (i = 0; i < map->n; ++i) {
2039                 set->p[i] = isl_basic_map_domain(ctx, map->p[i]);
2040                 if (!set->p[i])
2041                         goto error;
2042         }
2043         F_CLR(set, ISL_MAP_DISJOINT);
2044         return set;
2045 error:
2046         isl_map_free(ctx, map);
2047         return NULL;
2048 }
2049
2050 struct isl_map *isl_map_union_disjoint(struct isl_ctx *ctx,
2051                         struct isl_map *map1, struct isl_map *map2)
2052 {
2053         int i;
2054         unsigned flags = 0;
2055         struct isl_map *map = NULL;
2056
2057         if (!map1 || !map2)
2058                 goto error;
2059
2060         if (map1->n == 0) {
2061                 isl_map_free(ctx, map1);
2062                 return map2;
2063         }
2064         if (map2->n == 0) {
2065                 isl_map_free(ctx, map2);
2066                 return map1;
2067         }
2068
2069         isl_assert(ctx, map1->nparam == map2->nparam, goto error);
2070         isl_assert(ctx, map1->n_in == map2->n_in, goto error);
2071         isl_assert(ctx, map1->n_out == map2->n_out, goto error);
2072
2073         if (F_ISSET(map1, ISL_MAP_DISJOINT) &&
2074             F_ISSET(map2, ISL_MAP_DISJOINT))
2075                 FL_SET(flags, ISL_MAP_DISJOINT);
2076
2077         map = isl_map_alloc(ctx, map1->nparam, map1->n_in, map1->n_out,
2078                                 map1->n + map2->n, flags);
2079         if (!map)
2080                 goto error;
2081         for (i = 0; i < map1->n; ++i) {
2082                 map = isl_map_add(ctx, map,
2083                                   isl_basic_map_copy(ctx, map1->p[i]));
2084                 if (!map)
2085                         goto error;
2086         }
2087         for (i = 0; i < map2->n; ++i) {
2088                 map = isl_map_add(ctx, map,
2089                                   isl_basic_map_copy(ctx, map2->p[i]));
2090                 if (!map)
2091                         goto error;
2092         }
2093         isl_map_free(ctx, map1);
2094         isl_map_free(ctx, map2);
2095         return map;
2096 error:
2097         isl_map_free(ctx, map);
2098         isl_map_free(ctx, map1);
2099         isl_map_free(ctx, map2);
2100         return NULL;
2101 }
2102
2103 struct isl_map *isl_map_union(struct isl_ctx *ctx,
2104                         struct isl_map *map1, struct isl_map *map2)
2105 {
2106         map1 = isl_map_union_disjoint(ctx, map1, map2);
2107         if (!map1)
2108                 return NULL;
2109         if (map1->n > 1)
2110                 F_CLR(map1, ISL_MAP_DISJOINT);
2111         return map1;
2112 }
2113
2114 struct isl_set *isl_set_union_disjoint(struct isl_ctx *ctx,
2115                         struct isl_set *set1, struct isl_set *set2)
2116 {
2117         return (struct isl_set *)
2118                 isl_map_union_disjoint(ctx,
2119                         (struct isl_map *)set1, (struct isl_map *)set2);
2120 }
2121
2122 struct isl_set *isl_set_union(struct isl_ctx *ctx,
2123                         struct isl_set *set1, struct isl_set *set2)
2124 {
2125         return (struct isl_set *)
2126                 isl_map_union(ctx,
2127                         (struct isl_map *)set1, (struct isl_map *)set2);
2128 }
2129
2130 struct isl_map *isl_map_intersect_range(
2131                 struct isl_ctx *ctx, struct isl_map *map,
2132                 struct isl_set *set)
2133 {
2134         unsigned flags = 0;
2135         struct isl_map *result;
2136         int i, j;
2137
2138         if (!map || !set)
2139                 goto error;
2140
2141         if (F_ISSET(map, ISL_MAP_DISJOINT) &&
2142             F_ISSET(set, ISL_MAP_DISJOINT))
2143                 FL_SET(flags, ISL_MAP_DISJOINT);
2144
2145         result = isl_map_alloc(ctx, map->nparam, map->n_in, map->n_out,
2146                                 map->n * set->n, flags);
2147         if (!result)
2148                 goto error;
2149         for (i = 0; i < map->n; ++i)
2150                 for (j = 0; j < set->n; ++j) {
2151                         result = isl_map_add(ctx, result,
2152                             isl_basic_map_intersect_range(ctx,
2153                                 isl_basic_map_copy(ctx, map->p[i]),
2154                                 isl_basic_set_copy(ctx, set->p[j])));
2155                         if (!result)
2156                                 goto error;
2157                 }
2158         isl_map_free(ctx, map);
2159         isl_set_free(ctx, set);
2160         return result;
2161 error:
2162         isl_map_free(ctx, map);
2163         isl_set_free(ctx, set);
2164         return NULL;
2165 }
2166
2167 struct isl_map *isl_map_intersect_domain(
2168                 struct isl_ctx *ctx, struct isl_map *map,
2169                 struct isl_set *set)
2170 {
2171         return isl_map_reverse(ctx,
2172                 isl_map_intersect_range(ctx, isl_map_reverse(ctx, map), set));
2173 }
2174
2175 struct isl_map *isl_map_apply_domain(
2176                 struct isl_ctx *ctx, struct isl_map *map1,
2177                 struct isl_map *map2)
2178 {
2179         if (!map1 || !map2)
2180                 goto error;
2181         map1 = isl_map_reverse(ctx, map1);
2182         map1 = isl_map_apply_range(ctx, map1, map2);
2183         return isl_map_reverse(ctx, map1);
2184 error:
2185         isl_map_free(ctx, map1);
2186         isl_map_free(ctx, map2);
2187         return NULL;
2188 }
2189
2190 struct isl_map *isl_map_apply_range(
2191                 struct isl_ctx *ctx, struct isl_map *map1,
2192                 struct isl_map *map2)
2193 {
2194         struct isl_map *result;
2195         int i, j;
2196
2197         if (!map1 || !map2)
2198                 goto error;
2199
2200         isl_assert(ctx, map1->nparam == map2->nparam, goto error);
2201         isl_assert(ctx, map1->n_out == map2->n_in, goto error);
2202
2203         result = isl_map_alloc(ctx, map1->nparam, map1->n_in, map2->n_out,
2204                                 map1->n * map2->n, 0);
2205         if (!result)
2206                 goto error;
2207         for (i = 0; i < map1->n; ++i)
2208                 for (j = 0; j < map2->n; ++j) {
2209                         result = isl_map_add(ctx, result,
2210                             isl_basic_map_apply_range(ctx,
2211                                 isl_basic_map_copy(ctx, map1->p[i]),
2212                                 isl_basic_map_copy(ctx, map2->p[j])));
2213                         if (!result)
2214                                 goto error;
2215                 }
2216         isl_map_free(ctx, map1);
2217         isl_map_free(ctx, map2);
2218         return result;
2219 error:
2220         isl_map_free(ctx, map1);
2221         isl_map_free(ctx, map2);
2222         return NULL;
2223 }
2224
2225 /*
2226  * returns range - domain
2227  */
2228 struct isl_basic_set *isl_basic_map_deltas(struct isl_ctx *ctx,
2229                                 struct isl_basic_map *bmap)
2230 {
2231         struct isl_basic_set *bset;
2232         unsigned dim;
2233         int i;
2234
2235         if (!bmap)
2236                 goto error;
2237         isl_assert(ctx, bmap->n_in == bmap->n_out, goto error);
2238         dim = bmap->n_in;
2239         bset = isl_basic_set_from_basic_map(ctx, bmap);
2240         bset = isl_basic_set_extend(ctx, bset, bset->nparam, 3*dim, 0,
2241                                         dim, 0);
2242         bset = isl_basic_set_swap_vars(ctx, bset, 2*dim);
2243         for (i = 0; i < dim; ++i) {
2244                 int j = isl_basic_map_alloc_equality(ctx,
2245                                             (struct isl_basic_map *)bset);
2246                 if (j < 0)
2247                         goto error;
2248                 isl_int_set_si(bset->eq[j][1+bset->nparam+i], 1);
2249                 isl_int_set_si(bset->eq[j][1+bset->nparam+dim+i], 1);
2250                 isl_int_set_si(bset->eq[j][1+bset->nparam+2*dim+i], -1);
2251         }
2252         return isl_basic_set_project_out(ctx, bset, 2*dim, 0);
2253 error:
2254         isl_basic_map_free(ctx, bmap);
2255         return NULL;
2256 }
2257
2258 /* If the only constraints a div d=floor(f/m)
2259  * appears in are its two defining constraints
2260  *
2261  *      f - m d >=0
2262  *      -(f - (m - 1)) + m d >= 0
2263  *
2264  * then it can safely be removed.
2265  */
2266 static int div_is_redundant(struct isl_ctx *ctx, struct isl_basic_map *bmap,
2267                                 int div)
2268 {
2269         int i;
2270         unsigned pos = 1 + bmap->nparam + bmap->n_in + bmap->n_out + div;
2271
2272         for (i = 0; i < bmap->n_eq; ++i)
2273                 if (!isl_int_is_zero(bmap->eq[i][pos]))
2274                         return 0;
2275
2276         for (i = 0; i < bmap->n_ineq; ++i) {
2277                 if (isl_int_is_zero(bmap->ineq[i][pos]))
2278                         continue;
2279                 if (isl_int_eq(bmap->ineq[i][pos], bmap->div[div][0])) {
2280                         int neg;
2281                         isl_int_sub(bmap->div[div][1],
2282                                         bmap->div[div][1], bmap->div[div][0]);
2283                         isl_int_add_ui(bmap->div[div][1], bmap->div[div][1], 1);
2284                         neg = isl_seq_is_neg(bmap->ineq[i], bmap->div[div]+1, pos);
2285                         isl_int_sub_ui(bmap->div[div][1], bmap->div[div][1], 1);
2286                         isl_int_add(bmap->div[div][1],
2287                                         bmap->div[div][1], bmap->div[div][0]);
2288                         if (!neg)
2289                                 return 0;
2290                         if (isl_seq_first_non_zero(bmap->ineq[i]+pos+1,
2291                                                     bmap->n_div-div-1) != -1)
2292                                 return 0;
2293                 } else if (isl_int_abs_eq(bmap->ineq[i][pos], bmap->div[div][0])) {
2294                         if (!isl_seq_eq(bmap->ineq[i], bmap->div[div]+1, pos))
2295                                 return 0;
2296                         if (isl_seq_first_non_zero(bmap->ineq[i]+pos+1,
2297                                                     bmap->n_div-div-1) != -1)
2298                                 return 0;
2299                 } else
2300                         return 0;
2301         }
2302
2303         for (i = 0; i < bmap->n_div; ++i)
2304                 if (!isl_int_is_zero(bmap->div[i][1+pos]))
2305                         return 0;
2306
2307         return 1;
2308 }
2309
2310 /*
2311  * Remove divs that don't occur in any of the constraints or other divs.
2312  * These can arise when dropping some of the variables in a quast
2313  * returned by piplib.
2314  */
2315 static struct isl_basic_map *remove_redundant_divs(struct isl_ctx *ctx,
2316                 struct isl_basic_map *bmap)
2317 {
2318         int i;
2319
2320         for (i = bmap->n_div-1; i >= 0; --i) {
2321                 if (!div_is_redundant(ctx, bmap, i))
2322                         continue;
2323                 bmap = isl_basic_map_drop_div(ctx, bmap, i);
2324         }
2325         return bmap;
2326 }
2327
2328 struct isl_basic_map *isl_basic_map_finalize(struct isl_ctx *ctx,
2329                 struct isl_basic_map *bmap)
2330 {
2331         bmap = remove_redundant_divs(ctx, bmap);
2332         if (!bmap)
2333                 return NULL;
2334         F_SET(bmap, ISL_BASIC_SET_FINAL);
2335         return bmap;
2336 }
2337
2338 struct isl_basic_set *isl_basic_set_finalize(struct isl_ctx *ctx,
2339                 struct isl_basic_set *bset)
2340 {
2341         return (struct isl_basic_set *)
2342                 isl_basic_map_finalize(ctx,
2343                         (struct isl_basic_map *)bset);
2344 }
2345
2346 struct isl_set *isl_set_finalize(struct isl_ctx *ctx, struct isl_set *set)
2347 {
2348         int i;
2349
2350         if (!set)
2351                 return NULL;
2352         for (i = 0; i < set->n; ++i) {
2353                 set->p[i] = isl_basic_set_finalize(ctx, set->p[i]);
2354                 if (!set->p[i])
2355                         goto error;
2356         }
2357         return set;
2358 error:
2359         isl_set_free(ctx, set);
2360         return NULL;
2361 }
2362
2363 struct isl_map *isl_map_finalize(struct isl_ctx *ctx, struct isl_map *map)
2364 {
2365         int i;
2366
2367         if (!map)
2368                 return NULL;
2369         for (i = 0; i < map->n; ++i) {
2370                 map->p[i] = isl_basic_map_finalize(ctx, map->p[i]);
2371                 if (!map->p[i])
2372                         goto error;
2373         }
2374         return map;
2375 error:
2376         isl_map_free(ctx, map);
2377         return NULL;
2378 }
2379
2380 struct isl_basic_map *isl_basic_map_identity(struct isl_ctx *ctx,
2381                 unsigned nparam, unsigned dim)
2382 {
2383         struct isl_basic_map *bmap;
2384         int i;
2385
2386         bmap = isl_basic_map_alloc(ctx, nparam, dim, dim, 0, dim, 0);
2387         if (!bmap)
2388                 goto error;
2389
2390         for (i = 0; i < dim; ++i) {
2391                 int j = isl_basic_map_alloc_equality(ctx, bmap);
2392                 if (j < 0)
2393                         goto error;
2394                 isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
2395                 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], -1);
2396         }
2397         return isl_basic_map_finalize(ctx, bmap);
2398 error:
2399         isl_basic_map_free(ctx, bmap);
2400         return NULL;
2401 }
2402
2403 struct isl_map *isl_map_identity(struct isl_ctx *ctx,
2404                 unsigned nparam, unsigned dim)
2405 {
2406         struct isl_map *map = isl_map_alloc(ctx, nparam, dim, dim, 1,
2407                                                 ISL_MAP_DISJOINT);
2408         if (!map)
2409                 goto error;
2410         map = isl_map_add(ctx, map,
2411                 isl_basic_map_identity(ctx, nparam, dim));
2412         return map;
2413 error:
2414         isl_map_free(ctx, map);
2415         return NULL;
2416 }
2417
2418 int isl_set_is_equal(struct isl_ctx *ctx,
2419                 struct isl_set *set1, struct isl_set *set2)
2420 {
2421         return isl_map_is_equal(ctx,
2422                         (struct isl_map *)set1, (struct isl_map *)set2);
2423 }
2424
2425 int isl_set_is_subset(struct isl_ctx *ctx,
2426                 struct isl_set *set1, struct isl_set *set2)
2427 {
2428         return isl_map_is_subset(ctx,
2429                         (struct isl_map *)set1, (struct isl_map *)set2);
2430 }
2431
2432 int isl_basic_map_is_subset(struct isl_ctx *ctx,
2433                 struct isl_basic_map *bmap1,
2434                 struct isl_basic_map *bmap2)
2435 {
2436         int is_subset;
2437         struct isl_map *map1;
2438         struct isl_map *map2;
2439
2440         if (!bmap1 || !bmap2)
2441                 return -1;
2442
2443         map1 = isl_map_from_basic_map(ctx,
2444                         isl_basic_map_copy(ctx, bmap1));
2445         map2 = isl_map_from_basic_map(ctx,
2446                         isl_basic_map_copy(ctx, bmap2));
2447
2448         is_subset = isl_map_is_subset(ctx, map1, map2);
2449
2450         isl_map_free(ctx, map1);
2451         isl_map_free(ctx, map2);
2452
2453         return is_subset;
2454 }
2455
2456 int isl_map_is_empty(struct isl_ctx *ctx, struct isl_map *map)
2457 {
2458         int i;
2459         int is_empty;
2460
2461         if (!map)
2462                 return -1;
2463         for (i = 0; i < map->n; ++i) {
2464                 is_empty = isl_basic_map_is_empty(ctx, map->p[i]);
2465                 if (is_empty < 0)
2466                         return -1;
2467                 if (!is_empty)
2468                         return 0;
2469         }
2470         return 1;
2471 }
2472
2473 int isl_set_is_empty(struct isl_ctx *ctx, struct isl_set *set)
2474 {
2475         return isl_map_is_empty(ctx, (struct isl_map *)set);
2476 }
2477
2478 int isl_map_is_subset(struct isl_ctx *ctx, struct isl_map *map1,
2479                 struct isl_map *map2)
2480 {
2481         int i;
2482         int is_subset = 0;
2483         struct isl_map *diff;
2484
2485         if (!map1 || !map2)
2486                 return -1;
2487
2488         if (isl_map_is_empty(ctx, map1))
2489                 return 1;
2490
2491         if (isl_map_is_empty(ctx, map2))
2492                 return 0;
2493
2494         diff = isl_map_subtract(ctx, isl_map_copy(ctx, map1),
2495                                      isl_map_copy(ctx, map2));
2496         if (!diff)
2497                 return -1;
2498
2499         is_subset = isl_map_is_empty(ctx, diff);
2500         isl_map_free(ctx, diff);
2501
2502         return is_subset;
2503 }
2504
2505 int isl_map_is_equal(struct isl_ctx *ctx,
2506                 struct isl_map *map1, struct isl_map *map2)
2507 {
2508         int is_subset;
2509
2510         if (!map1 || !map2)
2511                 return -1;
2512         is_subset = isl_map_is_subset(ctx, map1, map2);
2513         if (is_subset != 1)
2514                 return is_subset;
2515         is_subset = isl_map_is_subset(ctx, map2, map1);
2516         return is_subset;
2517 }
2518
2519 int isl_basic_map_is_strict_subset(struct isl_ctx *ctx,
2520                 struct isl_basic_map *bmap1,
2521                 struct isl_basic_map *bmap2)
2522 {
2523         int is_subset;
2524
2525         if (!bmap1 || !bmap2)
2526                 return -1;
2527         is_subset = isl_basic_map_is_subset(ctx, bmap1, bmap2);
2528         if (is_subset != 1)
2529                 return is_subset;
2530         is_subset = isl_basic_map_is_subset(ctx, bmap2, bmap1);
2531         if (is_subset == -1)
2532                 return is_subset;
2533         return !is_subset;
2534 }
2535
2536 int isl_basic_map_is_empty(struct isl_ctx *ctx,
2537                 struct isl_basic_map *bmap)
2538 {
2539         struct isl_basic_set *bset = NULL;
2540         struct isl_vec *sample = NULL;
2541         int empty;
2542
2543         if (!bmap)
2544                 return -1;
2545
2546         if (F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
2547                 return 1;
2548
2549         bset = isl_basic_map_underlying_set(ctx,
2550                         isl_basic_map_copy(ctx, bmap));
2551         if (!bset)
2552                 return -1;
2553         sample = isl_basic_set_sample(ctx, bset);
2554         if (!sample)
2555                 return -1;
2556         empty = sample->size == 0;
2557         isl_vec_free(ctx, sample);
2558
2559         return empty;
2560 }
2561
2562 struct isl_map *isl_basic_map_union(
2563                 struct isl_ctx *ctx, struct isl_basic_map *bmap1,
2564                 struct isl_basic_map *bmap2)
2565 {
2566         struct isl_map *map;
2567         if (!bmap1 || !bmap2)
2568                 return NULL;
2569
2570         isl_assert(ctx, bmap1->nparam == bmap2->nparam, goto error);
2571         isl_assert(ctx, bmap1->n_in == bmap2->n_in, goto error);
2572         isl_assert(ctx, bmap1->n_out == bmap2->n_out, goto error);
2573
2574         map = isl_map_alloc(ctx, bmap1->nparam,
2575                                 bmap1->n_in, bmap1->n_out, 2, 0);
2576         if (!map)
2577                 goto error;
2578         map = isl_map_add(ctx, map, bmap1);
2579         map = isl_map_add(ctx, map, bmap2);
2580         return map;
2581 error:
2582         isl_basic_map_free(ctx, bmap1);
2583         isl_basic_map_free(ctx, bmap2);
2584         return NULL;
2585 }
2586
2587 struct isl_set *isl_basic_set_union(
2588                 struct isl_ctx *ctx, struct isl_basic_set *bset1,
2589                 struct isl_basic_set *bset2)
2590 {
2591         return (struct isl_set *)isl_basic_map_union(ctx,
2592                                             (struct isl_basic_map *)bset1,
2593                                             (struct isl_basic_map *)bset2);
2594 }
2595
2596 /* Order divs such that any div only depends on previous divs */
2597 static struct isl_basic_map *order_divs(struct isl_ctx *ctx,
2598                 struct isl_basic_map *bmap)
2599 {
2600         int i;
2601         unsigned off = bmap->nparam + bmap->n_in + bmap->n_out;
2602
2603         for (i = 0; i < bmap->n_div; ++i) {
2604                 int pos;
2605                 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
2606                                                             bmap->n_div-i);
2607                 if (pos == -1)
2608                         continue;
2609                 swap_div(bmap, i, pos);
2610                 --i;
2611         }
2612         return bmap;
2613 }
2614
2615 static int find_div(struct isl_basic_map *dst,
2616                         struct isl_basic_map *src, unsigned div)
2617 {
2618         int i;
2619
2620         unsigned total = src->nparam + src->n_in + src->n_out + src->n_div;
2621
2622         for (i = 0; i < dst->n_div; ++i)
2623                 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total) &&
2624                     isl_seq_first_non_zero(dst->div[i]+1+1+total,
2625                                                 dst->n_div - src->n_div) == -1)
2626                         return i;
2627         return -1;
2628 }
2629
2630 /* For a div d = floor(f/m), add the constraints
2631  *
2632  *              f - m d >= 0
2633  *              -(f-(n-1)) + m d >= 0
2634  *
2635  * Note that the second constraint is the negation of
2636  *
2637  *              f - m d >= n
2638  */
2639 static int add_div_constraints(struct isl_ctx *ctx,
2640                 struct isl_basic_map *bmap, unsigned div)
2641 {
2642         int i, j;
2643         unsigned div_pos = 1 + bmap->nparam + bmap->n_in + bmap->n_out + div;
2644         unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
2645
2646         i = isl_basic_map_alloc_inequality(ctx, bmap);
2647         if (i < 0)
2648                 return -1;
2649         isl_seq_cpy(bmap->ineq[i], bmap->div[div]+1, 1+total);
2650         isl_int_neg(bmap->ineq[i][div_pos], bmap->div[div][0]);
2651
2652         j = isl_basic_map_alloc_inequality(ctx, bmap);
2653         if (j < 0)
2654                 return -1;
2655         isl_seq_neg(bmap->ineq[j], bmap->ineq[i], 1 + total);
2656         isl_int_add(bmap->ineq[j][0], bmap->ineq[j][0], bmap->ineq[j][div_pos]);
2657         isl_int_sub_ui(bmap->ineq[j][0], bmap->ineq[j][0], 1);
2658         return j;
2659 }
2660
2661 struct isl_basic_map *isl_basic_map_align_divs(struct isl_ctx *ctx,
2662                 struct isl_basic_map *dst, struct isl_basic_map *src)
2663 {
2664         int i;
2665         unsigned total = src->nparam + src->n_in + src->n_out + src->n_div;
2666
2667         if (src->n_div == 0)
2668                 return dst;
2669
2670         src = order_divs(ctx, src);
2671         dst = isl_basic_map_extend(ctx, dst, dst->nparam, dst->n_in,
2672                         dst->n_out, src->n_div, 0, 2 * src->n_div);
2673         if (!dst)
2674                 return NULL;
2675         for (i = 0; i < src->n_div; ++i) {
2676                 int j = find_div(dst, src, i);
2677                 if (j < 0) {
2678                         j = isl_basic_map_alloc_div(ctx, dst);
2679                         if (j < 0)
2680                                 goto error;
2681                         isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
2682                         if (add_div_constraints(ctx, dst, j) < 0)
2683                                 goto error;
2684                 }
2685                 if (j != i)
2686                         swap_div(dst, i, j);
2687         }
2688         return dst;
2689 error:
2690         isl_basic_map_free(ctx, dst);
2691         return NULL;
2692 }
2693
2694 static struct isl_map *add_cut_constraint(struct isl_ctx *ctx,
2695                 struct isl_map *dst,
2696                 struct isl_basic_map *src, isl_int *c,
2697                 unsigned len, unsigned extra, int oppose)
2698 {
2699         struct isl_basic_map *copy = NULL;
2700         int is_empty;
2701         int k;
2702
2703         copy = isl_basic_map_copy(ctx, src);
2704         copy = isl_basic_map_cow(ctx, copy);
2705         if (!copy)
2706                 goto error;
2707         copy = isl_basic_map_extend(ctx, copy,
2708                 copy->nparam, copy->n_in, copy->n_out, 0, 0, 1);
2709         k = isl_basic_map_alloc_inequality(ctx, copy);
2710         if (k < 0)
2711                 goto error;
2712         if (oppose)
2713                 isl_seq_neg(copy->ineq[k], c, len);
2714         else
2715                 isl_seq_cpy(copy->ineq[k], c, len);
2716         isl_seq_clr(copy->ineq[k]+len, extra);
2717         isl_inequality_negate(ctx, copy, k);
2718         copy = isl_basic_map_simplify(ctx, copy);
2719         copy = isl_basic_map_finalize(ctx, copy);
2720         is_empty = isl_basic_map_is_empty(ctx, copy);
2721         if (is_empty < 0)
2722                 goto error;
2723         if (!is_empty)
2724                 dst = isl_map_add(ctx, dst, copy);
2725         else
2726                 isl_basic_map_free(ctx, copy);
2727         return dst;
2728 error:
2729         isl_basic_map_free(ctx, copy);
2730         isl_map_free(ctx, dst);
2731         return NULL;
2732 }
2733
2734 static struct isl_map *subtract(struct isl_ctx *ctx, struct isl_map *map,
2735                 struct isl_basic_map *bmap)
2736 {
2737         int i, j, k;
2738         unsigned flags = 0;
2739         struct isl_map *rest = NULL;
2740         unsigned max;
2741         unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
2742
2743         assert(bmap);
2744
2745         if (!map)
2746                 goto error;
2747
2748         if (F_ISSET(map, ISL_MAP_DISJOINT))
2749                 FL_SET(flags, ISL_MAP_DISJOINT);
2750
2751         max = map->n * (2 * bmap->n_eq + bmap->n_ineq);
2752         rest = isl_map_alloc(ctx, map->nparam, map->n_in, map->n_out,
2753                                 max, flags);
2754         if (!rest)
2755                 goto error;
2756
2757         for (i = 0; i < map->n; ++i) {
2758                 map->p[i] = isl_basic_map_align_divs(ctx, map->p[i], bmap);
2759                 if (!map->p[i])
2760                         goto error;
2761         }
2762
2763         for (j = 0; j < map->n; ++j)
2764                 map->p[j] = isl_basic_map_cow(ctx, map->p[j]);
2765
2766         for (i = 0; i < bmap->n_eq; ++i) {
2767                 for (j = 0; j < map->n; ++j) {
2768                         rest = add_cut_constraint(ctx, rest,
2769                                 map->p[j], bmap->eq[i],
2770                                 1+total, map->p[j]->n_div - bmap->n_div, 0);
2771                         if (!rest)
2772                                 goto error;
2773
2774                         rest = add_cut_constraint(ctx, rest,
2775                                 map->p[j], bmap->eq[i],
2776                                 1+total, map->p[j]->n_div - bmap->n_div, 1);
2777                         if (!rest)
2778                                 goto error;
2779
2780                         map->p[j] = isl_basic_map_extend(ctx, map->p[j],
2781                                 map->p[j]->nparam, map->p[j]->n_in,
2782                                 map->p[j]->n_out, 0, 1, 0);
2783                         if (!map->p[j])
2784                                 goto error;
2785                         k = isl_basic_map_alloc_equality(ctx, map->p[j]);
2786                         if (k < 0)
2787                                 goto error;
2788                         isl_seq_cpy(map->p[j]->eq[k], bmap->eq[i], 1+total);
2789                         isl_seq_clr(map->p[j]->eq[k]+1+total,
2790                                         map->p[j]->n_div - bmap->n_div);
2791                 }
2792         }
2793
2794         for (i = 0; i < bmap->n_ineq; ++i) {
2795                 for (j = 0; j < map->n; ++j) {
2796                         rest = add_cut_constraint(ctx, rest,
2797                                 map->p[j], bmap->ineq[i],
2798                                 1+total, map->p[j]->n_div - bmap->n_div, 0);
2799                         if (!rest)
2800                                 goto error;
2801
2802                         map->p[j] = isl_basic_map_extend(ctx, map->p[j],
2803                                 map->p[j]->nparam, map->p[j]->n_in,
2804                                 map->p[j]->n_out, 0, 0, 1);
2805                         if (!map->p[j])
2806                                 goto error;
2807                         k = isl_basic_map_alloc_inequality(ctx, map->p[j]);
2808                         if (k < 0)
2809                                 goto error;
2810                         isl_seq_cpy(map->p[j]->ineq[k], bmap->ineq[i], 1+total);
2811                         isl_seq_clr(map->p[j]->ineq[k]+1+total,
2812                                         map->p[j]->n_div - bmap->n_div);
2813                 }
2814         }
2815
2816         isl_map_free(ctx, map);
2817         return rest;
2818 error:
2819         isl_map_free(ctx, map);
2820         isl_map_free(ctx, rest);
2821         return NULL;
2822 }
2823
2824 struct isl_map *isl_map_subtract(struct isl_ctx *ctx, struct isl_map *map1,
2825                 struct isl_map *map2)
2826 {
2827         int i;
2828         if (!map1 || !map2)
2829                 goto error;
2830
2831         isl_assert(ctx, map1->nparam == map2->nparam, goto error);
2832         isl_assert(ctx, map1->n_in == map2->n_in, goto error);
2833         isl_assert(ctx, map1->n_out == map2->n_out, goto error);
2834
2835         if (isl_map_is_empty(ctx, map2)) {
2836                 isl_map_free(ctx, map2);
2837                 return map1;
2838         }
2839
2840         map1 = isl_map_compute_divs(ctx, map1);
2841         map2 = isl_map_compute_divs(ctx, map2);
2842         if (!map1 || !map2)
2843                 goto error;
2844
2845         for (i = 0; map1 && i < map2->n; ++i)
2846                 map1 = subtract(ctx, map1, map2->p[i]);
2847
2848         isl_map_free(ctx, map2);
2849         return map1;
2850 error:
2851         isl_map_free(ctx, map1);
2852         isl_map_free(ctx, map2);
2853         return NULL;
2854 }
2855
2856 struct isl_set *isl_set_subtract(struct isl_ctx *ctx, struct isl_set *set1,
2857                 struct isl_set *set2)
2858 {
2859         return (struct isl_set *)
2860                 isl_map_subtract(ctx,
2861                         (struct isl_map *)set1, (struct isl_map *)set2);
2862 }
2863
2864 struct isl_set *isl_set_apply(struct isl_ctx *ctx, struct isl_set *set,
2865                 struct isl_map *map)
2866 {
2867         isl_assert(ctx, set->dim == map->n_in, goto error);
2868         map = isl_map_intersect_domain(ctx, map, set);
2869         set = isl_map_range(ctx, map);
2870         return set;
2871 error:
2872         isl_set_free(ctx, set);
2873         isl_map_free(ctx, map);
2874         return NULL;
2875 }