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