add isl_aff_get_coefficient_val
[platform/upstream/isl.git] / isl_aff.c
1 /*
2  * Copyright 2011      INRIA Saclay
3  * Copyright 2011      Sven Verdoolaege
4  * Copyright 2012-2013 Ecole Normale Superieure
5  *
6  * Use of this software is governed by the MIT license
7  *
8  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
9  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
10  * 91893 Orsay, France
11  * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
12  */
13
14 #include <isl_ctx_private.h>
15 #define ISL_DIM_H
16 #include <isl_map_private.h>
17 #include <isl_union_map_private.h>
18 #include <isl_aff_private.h>
19 #include <isl_space_private.h>
20 #include <isl_local_space_private.h>
21 #include <isl_mat_private.h>
22 #include <isl/constraint.h>
23 #include <isl/seq.h>
24 #include <isl/set.h>
25 #include <isl_val_private.h>
26 #include <isl_config.h>
27
28 #undef BASE
29 #define BASE aff
30
31 #include <isl_list_templ.c>
32
33 #undef BASE
34 #define BASE pw_aff
35
36 #include <isl_list_templ.c>
37
38 __isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls,
39         __isl_take isl_vec *v)
40 {
41         isl_aff *aff;
42
43         if (!ls || !v)
44                 goto error;
45
46         aff = isl_calloc_type(v->ctx, struct isl_aff);
47         if (!aff)
48                 goto error;
49
50         aff->ref = 1;
51         aff->ls = ls;
52         aff->v = v;
53
54         return aff;
55 error:
56         isl_local_space_free(ls);
57         isl_vec_free(v);
58         return NULL;
59 }
60
61 __isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls)
62 {
63         isl_ctx *ctx;
64         isl_vec *v;
65         unsigned total;
66
67         if (!ls)
68                 return NULL;
69
70         ctx = isl_local_space_get_ctx(ls);
71         if (!isl_local_space_divs_known(ls))
72                 isl_die(ctx, isl_error_invalid, "local space has unknown divs",
73                         goto error);
74         if (!isl_local_space_is_set(ls))
75                 isl_die(ctx, isl_error_invalid,
76                         "domain of affine expression should be a set",
77                         goto error);
78
79         total = isl_local_space_dim(ls, isl_dim_all);
80         v = isl_vec_alloc(ctx, 1 + 1 + total);
81         return isl_aff_alloc_vec(ls, v);
82 error:
83         isl_local_space_free(ls);
84         return NULL;
85 }
86
87 __isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls)
88 {
89         isl_aff *aff;
90
91         aff = isl_aff_alloc(ls);
92         if (!aff)
93                 return NULL;
94
95         isl_int_set_si(aff->v->el[0], 1);
96         isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
97
98         return aff;
99 }
100
101 /* Return a piecewise affine expression defined on the specified domain
102  * that is equal to zero.
103  */
104 __isl_give isl_pw_aff *isl_pw_aff_zero_on_domain(__isl_take isl_local_space *ls)
105 {
106         return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls));
107 }
108
109 /* Return an affine expression that is equal to the specified dimension
110  * in "ls".
111  */
112 __isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls,
113         enum isl_dim_type type, unsigned pos)
114 {
115         isl_space *space;
116         isl_aff *aff;
117
118         if (!ls)
119                 return NULL;
120
121         space = isl_local_space_get_space(ls);
122         if (!space)
123                 goto error;
124         if (isl_space_is_map(space))
125                 isl_die(isl_space_get_ctx(space), isl_error_invalid,
126                         "expecting (parameter) set space", goto error);
127         if (pos >= isl_local_space_dim(ls, type))
128                 isl_die(isl_space_get_ctx(space), isl_error_invalid,
129                         "position out of bounds", goto error);
130
131         isl_space_free(space);
132         aff = isl_aff_alloc(ls);
133         if (!aff)
134                 return NULL;
135
136         pos += isl_local_space_offset(aff->ls, type);
137
138         isl_int_set_si(aff->v->el[0], 1);
139         isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
140         isl_int_set_si(aff->v->el[1 + pos], 1);
141
142         return aff;
143 error:
144         isl_local_space_free(ls);
145         isl_space_free(space);
146         return NULL;
147 }
148
149 /* Return a piecewise affine expression that is equal to
150  * the specified dimension in "ls".
151  */
152 __isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls,
153         enum isl_dim_type type, unsigned pos)
154 {
155         return isl_pw_aff_from_aff(isl_aff_var_on_domain(ls, type, pos));
156 }
157
158 __isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff)
159 {
160         if (!aff)
161                 return NULL;
162
163         aff->ref++;
164         return aff;
165 }
166
167 __isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff)
168 {
169         if (!aff)
170                 return NULL;
171
172         return isl_aff_alloc_vec(isl_local_space_copy(aff->ls),
173                                  isl_vec_copy(aff->v));
174 }
175
176 __isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff)
177 {
178         if (!aff)
179                 return NULL;
180
181         if (aff->ref == 1)
182                 return aff;
183         aff->ref--;
184         return isl_aff_dup(aff);
185 }
186
187 void *isl_aff_free(__isl_take isl_aff *aff)
188 {
189         if (!aff)
190                 return NULL;
191
192         if (--aff->ref > 0)
193                 return NULL;
194
195         isl_local_space_free(aff->ls);
196         isl_vec_free(aff->v);
197
198         free(aff);
199
200         return NULL;
201 }
202
203 isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff)
204 {
205         return aff ? isl_local_space_get_ctx(aff->ls) : NULL;
206 }
207
208 /* Externally, an isl_aff has a map space, but internally, the
209  * ls field corresponds to the domain of that space.
210  */
211 int isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
212 {
213         if (!aff)
214                 return 0;
215         if (type == isl_dim_out)
216                 return 1;
217         if (type == isl_dim_in)
218                 type = isl_dim_set;
219         return isl_local_space_dim(aff->ls, type);
220 }
221
222 __isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff)
223 {
224         return aff ? isl_local_space_get_space(aff->ls) : NULL;
225 }
226
227 __isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff)
228 {
229         isl_space *space;
230         if (!aff)
231                 return NULL;
232         space = isl_local_space_get_space(aff->ls);
233         space = isl_space_from_domain(space);
234         space = isl_space_add_dims(space, isl_dim_out, 1);
235         return space;
236 }
237
238 __isl_give isl_local_space *isl_aff_get_domain_local_space(
239         __isl_keep isl_aff *aff)
240 {
241         return aff ? isl_local_space_copy(aff->ls) : NULL;
242 }
243
244 __isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff)
245 {
246         isl_local_space *ls;
247         if (!aff)
248                 return NULL;
249         ls = isl_local_space_copy(aff->ls);
250         ls = isl_local_space_from_domain(ls);
251         ls = isl_local_space_add_dims(ls, isl_dim_out, 1);
252         return ls;
253 }
254
255 /* Externally, an isl_aff has a map space, but internally, the
256  * ls field corresponds to the domain of that space.
257  */
258 const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff,
259         enum isl_dim_type type, unsigned pos)
260 {
261         if (!aff)
262                 return NULL;
263         if (type == isl_dim_out)
264                 return NULL;
265         if (type == isl_dim_in)
266                 type = isl_dim_set;
267         return isl_local_space_get_dim_name(aff->ls, type, pos);
268 }
269
270 __isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff,
271         __isl_take isl_space *dim)
272 {
273         aff = isl_aff_cow(aff);
274         if (!aff || !dim)
275                 goto error;
276
277         aff->ls = isl_local_space_reset_space(aff->ls, dim);
278         if (!aff->ls)
279                 return isl_aff_free(aff);
280
281         return aff;
282 error:
283         isl_aff_free(aff);
284         isl_space_free(dim);
285         return NULL;
286 }
287
288 /* Reset the space of "aff".  This function is called from isl_pw_templ.c
289  * and doesn't know if the space of an element object is represented
290  * directly or through its domain.  It therefore passes along both.
291  */
292 __isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff,
293         __isl_take isl_space *space, __isl_take isl_space *domain)
294 {
295         isl_space_free(space);
296         return isl_aff_reset_domain_space(aff, domain);
297 }
298
299 /* Reorder the coefficients of the affine expression based
300  * on the given reodering.
301  * The reordering r is assumed to have been extended with the local
302  * variables.
303  */
304 static __isl_give isl_vec *vec_reorder(__isl_take isl_vec *vec,
305         __isl_take isl_reordering *r, int n_div)
306 {
307         isl_vec *res;
308         int i;
309
310         if (!vec || !r)
311                 goto error;
312
313         res = isl_vec_alloc(vec->ctx,
314                             2 + isl_space_dim(r->dim, isl_dim_all) + n_div);
315         isl_seq_cpy(res->el, vec->el, 2);
316         isl_seq_clr(res->el + 2, res->size - 2);
317         for (i = 0; i < r->len; ++i)
318                 isl_int_set(res->el[2 + r->pos[i]], vec->el[2 + i]);
319
320         isl_reordering_free(r);
321         isl_vec_free(vec);
322         return res;
323 error:
324         isl_vec_free(vec);
325         isl_reordering_free(r);
326         return NULL;
327 }
328
329 /* Reorder the dimensions of the domain of "aff" according
330  * to the given reordering.
331  */
332 __isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff,
333         __isl_take isl_reordering *r)
334 {
335         aff = isl_aff_cow(aff);
336         if (!aff)
337                 goto error;
338
339         r = isl_reordering_extend(r, aff->ls->div->n_row);
340         aff->v = vec_reorder(aff->v, isl_reordering_copy(r),
341                                 aff->ls->div->n_row);
342         aff->ls = isl_local_space_realign(aff->ls, r);
343
344         if (!aff->v || !aff->ls)
345                 return isl_aff_free(aff);
346
347         return aff;
348 error:
349         isl_aff_free(aff);
350         isl_reordering_free(r);
351         return NULL;
352 }
353
354 __isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff,
355         __isl_take isl_space *model)
356 {
357         if (!aff || !model)
358                 goto error;
359
360         if (!isl_space_match(aff->ls->dim, isl_dim_param,
361                              model, isl_dim_param)) {
362                 isl_reordering *exp;
363
364                 model = isl_space_drop_dims(model, isl_dim_in,
365                                         0, isl_space_dim(model, isl_dim_in));
366                 model = isl_space_drop_dims(model, isl_dim_out,
367                                         0, isl_space_dim(model, isl_dim_out));
368                 exp = isl_parameter_alignment_reordering(aff->ls->dim, model);
369                 exp = isl_reordering_extend_space(exp,
370                                         isl_aff_get_domain_space(aff));
371                 aff = isl_aff_realign_domain(aff, exp);
372         }
373
374         isl_space_free(model);
375         return aff;
376 error:
377         isl_space_free(model);
378         isl_aff_free(aff);
379         return NULL;
380 }
381
382 int isl_aff_plain_is_zero(__isl_keep isl_aff *aff)
383 {
384         if (!aff)
385                 return -1;
386
387         return isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1) < 0;
388 }
389
390 int isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
391 {
392         int equal;
393
394         if (!aff1 || !aff2)
395                 return -1;
396
397         equal = isl_local_space_is_equal(aff1->ls, aff2->ls);
398         if (equal < 0 || !equal)
399                 return equal;
400
401         return isl_vec_is_equal(aff1->v, aff2->v);
402 }
403
404 int isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v)
405 {
406         if (!aff)
407                 return -1;
408         isl_int_set(*v, aff->v->el[0]);
409         return 0;
410 }
411
412 int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v)
413 {
414         if (!aff)
415                 return -1;
416         isl_int_set(*v, aff->v->el[1]);
417         return 0;
418 }
419
420 /* Return the constant term of "aff".
421  */
422 __isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff)
423 {
424         isl_ctx *ctx;
425         isl_val *v;
426
427         if (!aff)
428                 return NULL;
429
430         ctx = isl_aff_get_ctx(aff);
431         v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]);
432         return isl_val_normalize(v);
433 }
434
435 int isl_aff_get_coefficient(__isl_keep isl_aff *aff,
436         enum isl_dim_type type, int pos, isl_int *v)
437 {
438         if (!aff)
439                 return -1;
440
441         if (type == isl_dim_out)
442                 isl_die(aff->v->ctx, isl_error_invalid,
443                         "output/set dimension does not have a coefficient",
444                         return -1);
445         if (type == isl_dim_in)
446                 type = isl_dim_set;
447
448         if (pos >= isl_local_space_dim(aff->ls, type))
449                 isl_die(aff->v->ctx, isl_error_invalid,
450                         "position out of bounds", return -1);
451
452         pos += isl_local_space_offset(aff->ls, type);
453         isl_int_set(*v, aff->v->el[1 + pos]);
454
455         return 0;
456 }
457
458 /* Return the coefficient of the variable of type "type" at position "pos"
459  * of "aff".
460  */
461 __isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff,
462         enum isl_dim_type type, int pos)
463 {
464         isl_ctx *ctx;
465         isl_val *v;
466
467         if (!aff)
468                 return NULL;
469
470         ctx = isl_aff_get_ctx(aff);
471         if (type == isl_dim_out)
472                 isl_die(ctx, isl_error_invalid,
473                         "output/set dimension does not have a coefficient",
474                         return NULL);
475         if (type == isl_dim_in)
476                 type = isl_dim_set;
477
478         if (pos >= isl_local_space_dim(aff->ls, type))
479                 isl_die(ctx, isl_error_invalid,
480                         "position out of bounds", return NULL);
481
482         pos += isl_local_space_offset(aff->ls, type);
483         v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]);
484         return isl_val_normalize(v);
485 }
486
487 __isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v)
488 {
489         aff = isl_aff_cow(aff);
490         if (!aff)
491                 return NULL;
492
493         aff->v = isl_vec_cow(aff->v);
494         if (!aff->v)
495                 return isl_aff_free(aff);
496
497         isl_int_set(aff->v->el[0], v);
498
499         return aff;
500 }
501
502 __isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v)
503 {
504         aff = isl_aff_cow(aff);
505         if (!aff)
506                 return NULL;
507
508         aff->v = isl_vec_cow(aff->v);
509         if (!aff->v)
510                 return isl_aff_free(aff);
511
512         isl_int_set(aff->v->el[1], v);
513
514         return aff;
515 }
516
517 /* Replace the constant term of "aff" by "v".
518  */
519 __isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff,
520         __isl_take isl_val *v)
521 {
522         if (!aff || !v)
523                 goto error;
524
525         if (!isl_val_is_rat(v))
526                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
527                         "expecting rational value", goto error);
528
529         if (isl_int_eq(aff->v->el[1], v->n) &&
530             isl_int_eq(aff->v->el[0], v->d)) {
531                 isl_val_free(v);
532                 return aff;
533         }
534
535         aff = isl_aff_cow(aff);
536         if (!aff)
537                 goto error;
538         aff->v = isl_vec_cow(aff->v);
539         if (!aff->v)
540                 goto error;
541
542         if (isl_int_eq(aff->v->el[0], v->d)) {
543                 isl_int_set(aff->v->el[1], v->n);
544         } else if (isl_int_is_one(v->d)) {
545                 isl_int_mul(aff->v->el[1], aff->v->el[0], v->n);
546         } else {
547                 isl_seq_scale(aff->v->el + 1,
548                                 aff->v->el + 1, v->d, aff->v->size - 1);
549                 isl_int_mul(aff->v->el[1], aff->v->el[0], v->n);
550                 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
551                 aff->v = isl_vec_normalize(aff->v);
552                 if (!aff->v)
553                         goto error;
554         }
555
556         isl_val_free(v);
557         return aff;
558 error:
559         isl_aff_free(aff);
560         isl_val_free(v);
561         return NULL;
562 }
563
564 __isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v)
565 {
566         if (isl_int_is_zero(v))
567                 return aff;
568
569         aff = isl_aff_cow(aff);
570         if (!aff)
571                 return NULL;
572
573         aff->v = isl_vec_cow(aff->v);
574         if (!aff->v)
575                 return isl_aff_free(aff);
576
577         isl_int_addmul(aff->v->el[1], aff->v->el[0], v);
578
579         return aff;
580 }
581
582 /* Add "v" to the constant term of "aff".
583  */
584 __isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff,
585         __isl_take isl_val *v)
586 {
587         if (!aff || !v)
588                 goto error;
589
590         if (isl_val_is_zero(v)) {
591                 isl_val_free(v);
592                 return aff;
593         }
594
595         if (!isl_val_is_rat(v))
596                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
597                         "expecting rational value", goto error);
598
599         aff = isl_aff_cow(aff);
600         if (!aff)
601                 goto error;
602
603         aff->v = isl_vec_cow(aff->v);
604         if (!aff->v)
605                 goto error;
606
607         if (isl_int_is_one(v->d)) {
608                 isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n);
609         } else if (isl_int_eq(aff->v->el[0], v->d)) {
610                 isl_int_add(aff->v->el[1], aff->v->el[1], v->n);
611                 aff->v = isl_vec_normalize(aff->v);
612                 if (!aff->v)
613                         goto error;
614         } else {
615                 isl_seq_scale(aff->v->el + 1,
616                                 aff->v->el + 1, v->d, aff->v->size - 1);
617                 isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n);
618                 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
619                 aff->v = isl_vec_normalize(aff->v);
620                 if (!aff->v)
621                         goto error;
622         }
623
624         isl_val_free(v);
625         return aff;
626 error:
627         isl_aff_free(aff);
628         isl_val_free(v);
629         return NULL;
630 }
631
632 __isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
633 {
634         isl_int t;
635
636         isl_int_init(t);
637         isl_int_set_si(t, v);
638         aff = isl_aff_add_constant(aff, t);
639         isl_int_clear(t);
640
641         return aff;
642 }
643
644 /* Add "v" to the numerator of the constant term of "aff".
645  */
646 __isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v)
647 {
648         if (isl_int_is_zero(v))
649                 return aff;
650
651         aff = isl_aff_cow(aff);
652         if (!aff)
653                 return NULL;
654
655         aff->v = isl_vec_cow(aff->v);
656         if (!aff->v)
657                 return isl_aff_free(aff);
658
659         isl_int_add(aff->v->el[1], aff->v->el[1], v);
660
661         return aff;
662 }
663
664 /* Add "v" to the numerator of the constant term of "aff".
665  */
666 __isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v)
667 {
668         isl_int t;
669
670         if (v == 0)
671                 return aff;
672
673         isl_int_init(t);
674         isl_int_set_si(t, v);
675         aff = isl_aff_add_constant_num(aff, t);
676         isl_int_clear(t);
677
678         return aff;
679 }
680
681 __isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
682 {
683         aff = isl_aff_cow(aff);
684         if (!aff)
685                 return NULL;
686
687         aff->v = isl_vec_cow(aff->v);
688         if (!aff->v)
689                 return isl_aff_free(aff);
690
691         isl_int_set_si(aff->v->el[1], v);
692
693         return aff;
694 }
695
696 __isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
697         enum isl_dim_type type, int pos, isl_int v)
698 {
699         if (!aff)
700                 return NULL;
701
702         if (type == isl_dim_out)
703                 isl_die(aff->v->ctx, isl_error_invalid,
704                         "output/set dimension does not have a coefficient",
705                         return isl_aff_free(aff));
706         if (type == isl_dim_in)
707                 type = isl_dim_set;
708
709         if (pos >= isl_local_space_dim(aff->ls, type))
710                 isl_die(aff->v->ctx, isl_error_invalid,
711                         "position out of bounds", return isl_aff_free(aff));
712
713         aff = isl_aff_cow(aff);
714         if (!aff)
715                 return NULL;
716
717         aff->v = isl_vec_cow(aff->v);
718         if (!aff->v)
719                 return isl_aff_free(aff);
720
721         pos += isl_local_space_offset(aff->ls, type);
722         isl_int_set(aff->v->el[1 + pos], v);
723
724         return aff;
725 }
726
727 __isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff,
728         enum isl_dim_type type, int pos, int v)
729 {
730         if (!aff)
731                 return NULL;
732
733         if (type == isl_dim_out)
734                 isl_die(aff->v->ctx, isl_error_invalid,
735                         "output/set dimension does not have a coefficient",
736                         return isl_aff_free(aff));
737         if (type == isl_dim_in)
738                 type = isl_dim_set;
739
740         if (pos >= isl_local_space_dim(aff->ls, type))
741                 isl_die(aff->v->ctx, isl_error_invalid,
742                         "position out of bounds", return isl_aff_free(aff));
743
744         aff = isl_aff_cow(aff);
745         if (!aff)
746                 return NULL;
747
748         aff->v = isl_vec_cow(aff->v);
749         if (!aff->v)
750                 return isl_aff_free(aff);
751
752         pos += isl_local_space_offset(aff->ls, type);
753         isl_int_set_si(aff->v->el[1 + pos], v);
754
755         return aff;
756 }
757
758 /* Replace the coefficient of the variable of type "type" at position "pos"
759  * of "aff" by "v".
760  */
761 __isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff,
762         enum isl_dim_type type, int pos, __isl_take isl_val *v)
763 {
764         if (!aff || !v)
765                 goto error;
766
767         if (type == isl_dim_out)
768                 isl_die(aff->v->ctx, isl_error_invalid,
769                         "output/set dimension does not have a coefficient",
770                         goto error);
771         if (type == isl_dim_in)
772                 type = isl_dim_set;
773
774         if (pos >= isl_local_space_dim(aff->ls, type))
775                 isl_die(aff->v->ctx, isl_error_invalid,
776                         "position out of bounds", goto error);
777
778         if (!isl_val_is_rat(v))
779                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
780                         "expecting rational value", goto error);
781
782         pos += isl_local_space_offset(aff->ls, type);
783         if (isl_int_eq(aff->v->el[1 + pos], v->n) &&
784             isl_int_eq(aff->v->el[0], v->d)) {
785                 isl_val_free(v);
786                 return aff;
787         }
788
789         aff = isl_aff_cow(aff);
790         if (!aff)
791                 goto error;
792         aff->v = isl_vec_cow(aff->v);
793         if (!aff->v)
794                 goto error;
795
796         if (isl_int_eq(aff->v->el[0], v->d)) {
797                 isl_int_set(aff->v->el[1 + pos], v->n);
798         } else if (isl_int_is_one(v->d)) {
799                 isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n);
800         } else {
801                 isl_seq_scale(aff->v->el + 1,
802                                 aff->v->el + 1, v->d, aff->v->size - 1);
803                 isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n);
804                 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
805                 aff->v = isl_vec_normalize(aff->v);
806                 if (!aff->v)
807                         goto error;
808         }
809
810         isl_val_free(v);
811         return aff;
812 error:
813         isl_aff_free(aff);
814         isl_val_free(v);
815         return NULL;
816 }
817
818 __isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff,
819         enum isl_dim_type type, int pos, isl_int v)
820 {
821         if (!aff)
822                 return NULL;
823
824         if (type == isl_dim_out)
825                 isl_die(aff->v->ctx, isl_error_invalid,
826                         "output/set dimension does not have a coefficient",
827                         return isl_aff_free(aff));
828         if (type == isl_dim_in)
829                 type = isl_dim_set;
830
831         if (pos >= isl_local_space_dim(aff->ls, type))
832                 isl_die(aff->v->ctx, isl_error_invalid,
833                         "position out of bounds", return isl_aff_free(aff));
834
835         aff = isl_aff_cow(aff);
836         if (!aff)
837                 return NULL;
838
839         aff->v = isl_vec_cow(aff->v);
840         if (!aff->v)
841                 return isl_aff_free(aff);
842
843         pos += isl_local_space_offset(aff->ls, type);
844         isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v);
845
846         return aff;
847 }
848
849 /* Add "v" to the coefficient of the variable of type "type"
850  * at position "pos" of "aff".
851  */
852 __isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff,
853         enum isl_dim_type type, int pos, __isl_take isl_val *v)
854 {
855         if (!aff || !v)
856                 goto error;
857
858         if (isl_val_is_zero(v)) {
859                 isl_val_free(v);
860                 return aff;
861         }
862
863         if (type == isl_dim_out)
864                 isl_die(aff->v->ctx, isl_error_invalid,
865                         "output/set dimension does not have a coefficient",
866                         goto error);
867         if (type == isl_dim_in)
868                 type = isl_dim_set;
869
870         if (pos >= isl_local_space_dim(aff->ls, type))
871                 isl_die(aff->v->ctx, isl_error_invalid,
872                         "position out of bounds", goto error);
873
874         if (!isl_val_is_rat(v))
875                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
876                         "expecting rational value", goto error);
877
878         aff = isl_aff_cow(aff);
879         if (!aff)
880                 goto error;
881
882         aff->v = isl_vec_cow(aff->v);
883         if (!aff->v)
884                 goto error;
885
886         pos += isl_local_space_offset(aff->ls, type);
887         if (isl_int_is_one(v->d)) {
888                 isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n);
889         } else if (isl_int_eq(aff->v->el[0], v->d)) {
890                 isl_int_add(aff->v->el[1 + pos], aff->v->el[1 + pos], v->n);
891                 aff->v = isl_vec_normalize(aff->v);
892                 if (!aff->v)
893                         goto error;
894         } else {
895                 isl_seq_scale(aff->v->el + 1,
896                                 aff->v->el + 1, v->d, aff->v->size - 1);
897                 isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n);
898                 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
899                 aff->v = isl_vec_normalize(aff->v);
900                 if (!aff->v)
901                         goto error;
902         }
903
904         isl_val_free(v);
905         return aff;
906 error:
907         isl_aff_free(aff);
908         isl_val_free(v);
909         return NULL;
910 }
911
912 __isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff,
913         enum isl_dim_type type, int pos, int v)
914 {
915         isl_int t;
916
917         isl_int_init(t);
918         isl_int_set_si(t, v);
919         aff = isl_aff_add_coefficient(aff, type, pos, t);
920         isl_int_clear(t);
921
922         return aff;
923 }
924
925 __isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos)
926 {
927         if (!aff)
928                 return NULL;
929
930         return isl_local_space_get_div(aff->ls, pos);
931 }
932
933 __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
934 {
935         aff = isl_aff_cow(aff);
936         if (!aff)
937                 return NULL;
938         aff->v = isl_vec_cow(aff->v);
939         if (!aff->v)
940                 return isl_aff_free(aff);
941
942         isl_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1);
943
944         return aff;
945 }
946
947 /* Remove divs from the local space that do not appear in the affine
948  * expression.
949  * We currently only remove divs at the end.
950  * Some intermediate divs may also not appear directly in the affine
951  * expression, but we would also need to check that no other divs are
952  * defined in terms of them.
953  */
954 __isl_give isl_aff *isl_aff_remove_unused_divs( __isl_take isl_aff *aff)
955 {
956         int pos;
957         int off;
958         int n;
959
960         if (!aff)
961                 return NULL;
962
963         n = isl_local_space_dim(aff->ls, isl_dim_div);
964         off = isl_local_space_offset(aff->ls, isl_dim_div);
965
966         pos = isl_seq_last_non_zero(aff->v->el + 1 + off, n) + 1;
967         if (pos == n)
968                 return aff;
969
970         aff = isl_aff_cow(aff);
971         if (!aff)
972                 return NULL;
973
974         aff->ls = isl_local_space_drop_dims(aff->ls, isl_dim_div, pos, n - pos);
975         aff->v = isl_vec_drop_els(aff->v, 1 + off + pos, n - pos);
976         if (!aff->ls || !aff->v)
977                 return isl_aff_free(aff);
978
979         return aff;
980 }
981
982 /* Given two affine expressions "p" of length p_len (including the
983  * denominator and the constant term) and "subs" of length subs_len,
984  * plug in "subs" for the variable at position "pos".
985  * The variables of "subs" and "p" are assumed to match up to subs_len,
986  * but "p" may have additional variables.
987  * "v" is an initialized isl_int that can be used internally.
988  *
989  * In particular, if "p" represents the expression
990  *
991  *      (a i + g)/m
992  *
993  * with i the variable at position "pos" and "subs" represents the expression
994  *
995  *      f/d
996  *
997  * then the result represents the expression
998  *
999  *      (a f + d g)/(m d)
1000  *
1001  */
1002 void isl_seq_substitute(isl_int *p, int pos, isl_int *subs,
1003         int p_len, int subs_len, isl_int v)
1004 {
1005         isl_int_set(v, p[1 + pos]);
1006         isl_int_set_si(p[1 + pos], 0);
1007         isl_seq_combine(p + 1, subs[0], p + 1, v, subs + 1, subs_len - 1);
1008         isl_seq_scale(p + subs_len, p + subs_len, subs[0], p_len - subs_len);
1009         isl_int_mul(p[0], p[0], subs[0]);
1010 }
1011
1012 /* Look for any divs in the aff->ls with a denominator equal to one
1013  * and plug them into the affine expression and any subsequent divs
1014  * that may reference the div.
1015  */
1016 static __isl_give isl_aff *plug_in_integral_divs(__isl_take isl_aff *aff)
1017 {
1018         int i, n;
1019         int len;
1020         isl_int v;
1021         isl_vec *vec;
1022         isl_local_space *ls;
1023         unsigned pos;
1024
1025         if (!aff)
1026                 return NULL;
1027
1028         n = isl_local_space_dim(aff->ls, isl_dim_div);
1029         len = aff->v->size;
1030         for (i = 0; i < n; ++i) {
1031                 if (!isl_int_is_one(aff->ls->div->row[i][0]))
1032                         continue;
1033                 ls = isl_local_space_copy(aff->ls);
1034                 ls = isl_local_space_substitute_seq(ls, isl_dim_div, i,
1035                                 aff->ls->div->row[i], len, i + 1, n - (i + 1));
1036                 vec = isl_vec_copy(aff->v);
1037                 vec = isl_vec_cow(vec);
1038                 if (!ls || !vec)
1039                         goto error;
1040
1041                 isl_int_init(v);
1042
1043                 pos = isl_local_space_offset(aff->ls, isl_dim_div) + i;
1044                 isl_seq_substitute(vec->el, pos, aff->ls->div->row[i],
1045                                         len, len, v);
1046
1047                 isl_int_clear(v);
1048
1049                 isl_vec_free(aff->v);
1050                 aff->v = vec;
1051                 isl_local_space_free(aff->ls);
1052                 aff->ls = ls;
1053         }
1054
1055         return aff;
1056 error:
1057         isl_vec_free(vec);
1058         isl_local_space_free(ls);
1059         return isl_aff_free(aff);
1060 }
1061
1062 /* Look for any divs j that appear with a unit coefficient inside
1063  * the definitions of other divs i and plug them into the definitions
1064  * of the divs i.
1065  *
1066  * In particular, an expression of the form
1067  *
1068  *      floor((f(..) + floor(g(..)/n))/m)
1069  *
1070  * is simplified to
1071  *
1072  *      floor((n * f(..) + g(..))/(n * m))
1073  *
1074  * This simplification is correct because we can move the expression
1075  * f(..) into the inner floor in the original expression to obtain
1076  *
1077  *      floor(floor((n * f(..) + g(..))/n)/m)
1078  *
1079  * from which we can derive the simplified expression.
1080  */
1081 static __isl_give isl_aff *plug_in_unit_divs(__isl_take isl_aff *aff)
1082 {
1083         int i, j, n;
1084         int off;
1085
1086         if (!aff)
1087                 return NULL;
1088
1089         n = isl_local_space_dim(aff->ls, isl_dim_div);
1090         off = isl_local_space_offset(aff->ls, isl_dim_div);
1091         for (i = 1; i < n; ++i) {
1092                 for (j = 0; j < i; ++j) {
1093                         if (!isl_int_is_one(aff->ls->div->row[i][1 + off + j]))
1094                                 continue;
1095                         aff->ls = isl_local_space_substitute_seq(aff->ls,
1096                                 isl_dim_div, j, aff->ls->div->row[j],
1097                                 aff->v->size, i, 1);
1098                         if (!aff->ls)
1099                                 return isl_aff_free(aff);
1100                 }
1101         }
1102
1103         return aff;
1104 }
1105
1106 /* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL.
1107  *
1108  * Even though this function is only called on isl_affs with a single
1109  * reference, we are careful to only change aff->v and aff->ls together.
1110  */
1111 static __isl_give isl_aff *swap_div(__isl_take isl_aff *aff, int a, int b)
1112 {
1113         unsigned off = isl_local_space_offset(aff->ls, isl_dim_div);
1114         isl_local_space *ls;
1115         isl_vec *v;
1116
1117         ls = isl_local_space_copy(aff->ls);
1118         ls = isl_local_space_swap_div(ls, a, b);
1119         v = isl_vec_copy(aff->v);
1120         v = isl_vec_cow(v);
1121         if (!ls || !v)
1122                 goto error;
1123
1124         isl_int_swap(v->el[1 + off + a], v->el[1 + off + b]);
1125         isl_vec_free(aff->v);
1126         aff->v = v;
1127         isl_local_space_free(aff->ls);
1128         aff->ls = ls;
1129
1130         return aff;
1131 error:
1132         isl_vec_free(v);
1133         isl_local_space_free(ls);
1134         return isl_aff_free(aff);
1135 }
1136
1137 /* Merge divs "a" and "b" in "aff", which is assumed to be non-NULL.
1138  *
1139  * We currently do not actually remove div "b", but simply add its
1140  * coefficient to that of "a" and then zero it out.
1141  */
1142 static __isl_give isl_aff *merge_divs(__isl_take isl_aff *aff, int a, int b)
1143 {
1144         unsigned off = isl_local_space_offset(aff->ls, isl_dim_div);
1145
1146         if (isl_int_is_zero(aff->v->el[1 + off + b]))
1147                 return aff;
1148
1149         aff->v = isl_vec_cow(aff->v);
1150         if (!aff->v)
1151                 return isl_aff_free(aff);
1152
1153         isl_int_add(aff->v->el[1 + off + a],
1154                     aff->v->el[1 + off + a], aff->v->el[1 + off + b]);
1155         isl_int_set_si(aff->v->el[1 + off + b], 0);
1156
1157         return aff;
1158 }
1159
1160 /* Sort the divs in the local space of "aff" according to
1161  * the comparison function "cmp_row" in isl_local_space.c,
1162  * combining the coefficients of identical divs.
1163  *
1164  * Reordering divs does not change the semantics of "aff",
1165  * so there is no need to call isl_aff_cow.
1166  * Moreover, this function is currently only called on isl_affs
1167  * with a single reference.
1168  */
1169 static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff)
1170 {
1171         int i, j, n;
1172         unsigned off;
1173
1174         if (!aff)
1175                 return NULL;
1176
1177         off = isl_local_space_offset(aff->ls, isl_dim_div);
1178         n = isl_aff_dim(aff, isl_dim_div);
1179         for (i = 1; i < n; ++i) {
1180                 for (j = i - 1; j >= 0; --j) {
1181                         int cmp = isl_mat_cmp_div(aff->ls->div, j, j + 1);
1182                         if (cmp < 0)
1183                                 break;
1184                         if (cmp == 0)
1185                                 aff = merge_divs(aff, j, j + 1);
1186                         else
1187                                 aff = swap_div(aff, j, j + 1);
1188                         if (!aff)
1189                                 return NULL;
1190                 }
1191         }
1192
1193         return aff;
1194 }
1195
1196 /* Normalize the representation of "aff".
1197  *
1198  * This function should only be called of "new" isl_affs, i.e.,
1199  * with only a single reference.  We therefore do not need to
1200  * worry about affecting other instances.
1201  */
1202 __isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff)
1203 {
1204         if (!aff)
1205                 return NULL;
1206         aff->v = isl_vec_normalize(aff->v);
1207         if (!aff->v)
1208                 return isl_aff_free(aff);
1209         aff = plug_in_integral_divs(aff);
1210         aff = plug_in_unit_divs(aff);
1211         aff = sort_divs(aff);
1212         aff = isl_aff_remove_unused_divs(aff);
1213         return aff;
1214 }
1215
1216 /* Given f, return floor(f).
1217  * If f is an integer expression, then just return f.
1218  * If f is a constant, then return the constant floor(f).
1219  * Otherwise, if f = g/m, write g = q m + r,
1220  * create a new div d = [r/m] and return the expression q + d.
1221  * The coefficients in r are taken to lie between -m/2 and m/2.
1222  */
1223 __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
1224 {
1225         int i;
1226         int size;
1227         isl_ctx *ctx;
1228         isl_vec *div;
1229
1230         if (!aff)
1231                 return NULL;
1232
1233         if (isl_int_is_one(aff->v->el[0]))
1234                 return aff;
1235
1236         aff = isl_aff_cow(aff);
1237         if (!aff)
1238                 return NULL;
1239
1240         aff->v = isl_vec_cow(aff->v);
1241         if (!aff->v)
1242                 return isl_aff_free(aff);
1243
1244         if (isl_aff_is_cst(aff)) {
1245                 isl_int_fdiv_q(aff->v->el[1], aff->v->el[1], aff->v->el[0]);
1246                 isl_int_set_si(aff->v->el[0], 1);
1247                 return aff;
1248         }
1249
1250         div = isl_vec_copy(aff->v);
1251         div = isl_vec_cow(div);
1252         if (!div)
1253                 return isl_aff_free(aff);
1254
1255         ctx = isl_aff_get_ctx(aff);
1256         isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two);
1257         for (i = 1; i < aff->v->size; ++i) {
1258                 isl_int_fdiv_r(div->el[i], div->el[i], div->el[0]);
1259                 isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0]);
1260                 if (isl_int_gt(div->el[i], aff->v->el[0])) {
1261                         isl_int_sub(div->el[i], div->el[i], div->el[0]);
1262                         isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1);
1263                 }
1264         }
1265
1266         aff->ls = isl_local_space_add_div(aff->ls, div);
1267         if (!aff->ls)
1268                 return isl_aff_free(aff);
1269
1270         size = aff->v->size;
1271         aff->v = isl_vec_extend(aff->v, size + 1);
1272         if (!aff->v)
1273                 return isl_aff_free(aff);
1274         isl_int_set_si(aff->v->el[0], 1);
1275         isl_int_set_si(aff->v->el[size], 1);
1276
1277         aff = isl_aff_normalize(aff);
1278
1279         return aff;
1280 }
1281
1282 /* Compute
1283  *
1284  *      aff mod m = aff - m * floor(aff/m)
1285  */
1286 __isl_give isl_aff *isl_aff_mod(__isl_take isl_aff *aff, isl_int m)
1287 {
1288         isl_aff *res;
1289
1290         res = isl_aff_copy(aff);
1291         aff = isl_aff_scale_down(aff, m);
1292         aff = isl_aff_floor(aff);
1293         aff = isl_aff_scale(aff, m);
1294         res = isl_aff_sub(res, aff);
1295
1296         return res;
1297 }
1298
1299 /* Compute
1300  *
1301  *      pwaff mod m = pwaff - m * floor(pwaff/m)
1302  */
1303 __isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m)
1304 {
1305         isl_pw_aff *res;
1306
1307         res = isl_pw_aff_copy(pwaff);
1308         pwaff = isl_pw_aff_scale_down(pwaff, m);
1309         pwaff = isl_pw_aff_floor(pwaff);
1310         pwaff = isl_pw_aff_scale(pwaff, m);
1311         res = isl_pw_aff_sub(res, pwaff);
1312
1313         return res;
1314 }
1315
1316 /* Given f, return ceil(f).
1317  * If f is an integer expression, then just return f.
1318  * Otherwise, let f be the expression
1319  *
1320  *      e/m
1321  *
1322  * then return
1323  *
1324  *      floor((e + m - 1)/m)
1325  */
1326 __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
1327 {
1328         if (!aff)
1329                 return NULL;
1330
1331         if (isl_int_is_one(aff->v->el[0]))
1332                 return aff;
1333
1334         aff = isl_aff_cow(aff);
1335         if (!aff)
1336                 return NULL;
1337         aff->v = isl_vec_cow(aff->v);
1338         if (!aff->v)
1339                 return isl_aff_free(aff);
1340
1341         isl_int_add(aff->v->el[1], aff->v->el[1], aff->v->el[0]);
1342         isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1);
1343         aff = isl_aff_floor(aff);
1344
1345         return aff;
1346 }
1347
1348 /* Apply the expansion computed by isl_merge_divs.
1349  * The expansion itself is given by "exp" while the resulting
1350  * list of divs is given by "div".
1351  */
1352 __isl_give isl_aff *isl_aff_expand_divs( __isl_take isl_aff *aff,
1353         __isl_take isl_mat *div, int *exp)
1354 {
1355         int i, j;
1356         int old_n_div;
1357         int new_n_div;
1358         int offset;
1359
1360         aff = isl_aff_cow(aff);
1361         if (!aff || !div)
1362                 goto error;
1363
1364         old_n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1365         new_n_div = isl_mat_rows(div);
1366         if (new_n_div < old_n_div)
1367                 isl_die(isl_mat_get_ctx(div), isl_error_invalid,
1368                         "not an expansion", goto error);
1369
1370         aff->v = isl_vec_extend(aff->v, aff->v->size + new_n_div - old_n_div);
1371         if (!aff->v)
1372                 goto error;
1373
1374         offset = 1 + isl_local_space_offset(aff->ls, isl_dim_div);
1375         j = old_n_div - 1;
1376         for (i = new_n_div - 1; i >= 0; --i) {
1377                 if (j >= 0 && exp[j] == i) {
1378                         if (i != j)
1379                                 isl_int_swap(aff->v->el[offset + i],
1380                                              aff->v->el[offset + j]);
1381                         j--;
1382                 } else
1383                         isl_int_set_si(aff->v->el[offset + i], 0);
1384         }
1385
1386         aff->ls = isl_local_space_replace_divs(aff->ls, isl_mat_copy(div));
1387         if (!aff->ls)
1388                 goto error;
1389         isl_mat_free(div);
1390         return aff;
1391 error:
1392         isl_aff_free(aff);
1393         isl_mat_free(div);
1394         return NULL;
1395 }
1396
1397 /* Add two affine expressions that live in the same local space.
1398  */
1399 static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1,
1400         __isl_take isl_aff *aff2)
1401 {
1402         isl_int gcd, f;
1403
1404         aff1 = isl_aff_cow(aff1);
1405         if (!aff1 || !aff2)
1406                 goto error;
1407
1408         aff1->v = isl_vec_cow(aff1->v);
1409         if (!aff1->v)
1410                 goto error;
1411
1412         isl_int_init(gcd);
1413         isl_int_init(f);
1414         isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0]);
1415         isl_int_divexact(f, aff2->v->el[0], gcd);
1416         isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1);
1417         isl_int_divexact(f, aff1->v->el[0], gcd);
1418         isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1);
1419         isl_int_divexact(f, aff2->v->el[0], gcd);
1420         isl_int_mul(aff1->v->el[0], aff1->v->el[0], f);
1421         isl_int_clear(f);
1422         isl_int_clear(gcd);
1423
1424         isl_aff_free(aff2);
1425         return aff1;
1426 error:
1427         isl_aff_free(aff1);
1428         isl_aff_free(aff2);
1429         return NULL;
1430 }
1431
1432 __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
1433         __isl_take isl_aff *aff2)
1434 {
1435         isl_ctx *ctx;
1436         int *exp1 = NULL;
1437         int *exp2 = NULL;
1438         isl_mat *div;
1439
1440         if (!aff1 || !aff2)
1441                 goto error;
1442
1443         ctx = isl_aff_get_ctx(aff1);
1444         if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim))
1445                 isl_die(ctx, isl_error_invalid,
1446                         "spaces don't match", goto error);
1447
1448         if (aff1->ls->div->n_row == 0 && aff2->ls->div->n_row == 0)
1449                 return add_expanded(aff1, aff2);
1450
1451         exp1 = isl_alloc_array(ctx, int, aff1->ls->div->n_row);
1452         exp2 = isl_alloc_array(ctx, int, aff2->ls->div->n_row);
1453         if (!exp1 || !exp2)
1454                 goto error;
1455
1456         div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2);
1457         aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1);
1458         aff2 = isl_aff_expand_divs(aff2, div, exp2);
1459         free(exp1);
1460         free(exp2);
1461
1462         return add_expanded(aff1, aff2);
1463 error:
1464         free(exp1);
1465         free(exp2);
1466         isl_aff_free(aff1);
1467         isl_aff_free(aff2);
1468         return NULL;
1469 }
1470
1471 __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
1472         __isl_take isl_aff *aff2)
1473 {
1474         return isl_aff_add(aff1, isl_aff_neg(aff2));
1475 }
1476
1477 __isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f)
1478 {
1479         isl_int gcd;
1480
1481         if (isl_int_is_one(f))
1482                 return aff;
1483
1484         aff = isl_aff_cow(aff);
1485         if (!aff)
1486                 return NULL;
1487         aff->v = isl_vec_cow(aff->v);
1488         if (!aff->v)
1489                 return isl_aff_free(aff);
1490
1491         if (isl_int_is_pos(f) && isl_int_is_divisible_by(aff->v->el[0], f)) {
1492                 isl_int_divexact(aff->v->el[0], aff->v->el[0], f);
1493                 return aff;
1494         }
1495
1496         isl_int_init(gcd);
1497         isl_int_gcd(gcd, aff->v->el[0], f);
1498         isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd);
1499         isl_int_divexact(gcd, f, gcd);
1500         isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
1501         isl_int_clear(gcd);
1502
1503         return aff;
1504 }
1505
1506 __isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
1507 {
1508         isl_int gcd;
1509
1510         if (isl_int_is_one(f))
1511                 return aff;
1512
1513         aff = isl_aff_cow(aff);
1514         if (!aff)
1515                 return NULL;
1516
1517         if (isl_int_is_zero(f))
1518                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1519                         "cannot scale down by zero", return isl_aff_free(aff));
1520
1521         aff->v = isl_vec_cow(aff->v);
1522         if (!aff->v)
1523                 return isl_aff_free(aff);
1524
1525         isl_int_init(gcd);
1526         isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd);
1527         isl_int_gcd(gcd, gcd, f);
1528         isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
1529         isl_int_divexact(gcd, f, gcd);
1530         isl_int_mul(aff->v->el[0], aff->v->el[0], gcd);
1531         isl_int_clear(gcd);
1532
1533         return aff;
1534 }
1535
1536 __isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f)
1537 {
1538         isl_int v;
1539
1540         if (f == 1)
1541                 return aff;
1542
1543         isl_int_init(v);
1544         isl_int_set_ui(v, f);
1545         aff = isl_aff_scale_down(aff, v);
1546         isl_int_clear(v);
1547
1548         return aff;
1549 }
1550
1551 __isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff,
1552         enum isl_dim_type type, unsigned pos, const char *s)
1553 {
1554         aff = isl_aff_cow(aff);
1555         if (!aff)
1556                 return NULL;
1557         if (type == isl_dim_out)
1558                 isl_die(aff->v->ctx, isl_error_invalid,
1559                         "cannot set name of output/set dimension",
1560                         return isl_aff_free(aff));
1561         if (type == isl_dim_in)
1562                 type = isl_dim_set;
1563         aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s);
1564         if (!aff->ls)
1565                 return isl_aff_free(aff);
1566
1567         return aff;
1568 }
1569
1570 __isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff,
1571         enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
1572 {
1573         aff = isl_aff_cow(aff);
1574         if (!aff)
1575                 return isl_id_free(id);
1576         if (type == isl_dim_out)
1577                 isl_die(aff->v->ctx, isl_error_invalid,
1578                         "cannot set name of output/set dimension",
1579                         goto error);
1580         if (type == isl_dim_in)
1581                 type = isl_dim_set;
1582         aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id);
1583         if (!aff->ls)
1584                 return isl_aff_free(aff);
1585
1586         return aff;
1587 error:
1588         isl_id_free(id);
1589         isl_aff_free(aff);
1590         return NULL;
1591 }
1592
1593 /* Exploit the equalities in "eq" to simplify the affine expression
1594  * and the expressions of the integer divisions in the local space.
1595  * The integer divisions in this local space are assumed to appear
1596  * as regular dimensions in "eq".
1597  */
1598 static __isl_give isl_aff *isl_aff_substitute_equalities_lifted(
1599         __isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
1600 {
1601         int i, j;
1602         unsigned total;
1603         unsigned n_div;
1604
1605         if (!eq)
1606                 goto error;
1607         if (eq->n_eq == 0) {
1608                 isl_basic_set_free(eq);
1609                 return aff;
1610         }
1611
1612         aff = isl_aff_cow(aff);
1613         if (!aff)
1614                 goto error;
1615
1616         aff->ls = isl_local_space_substitute_equalities(aff->ls,
1617                                                         isl_basic_set_copy(eq));
1618         aff->v = isl_vec_cow(aff->v);
1619         if (!aff->ls || !aff->v)
1620                 goto error;
1621
1622         total = 1 + isl_space_dim(eq->dim, isl_dim_all);
1623         n_div = eq->n_div;
1624         for (i = 0; i < eq->n_eq; ++i) {
1625                 j = isl_seq_last_non_zero(eq->eq[i], total + n_div);
1626                 if (j < 0 || j == 0 || j >= total)
1627                         continue;
1628
1629                 isl_seq_elim(aff->v->el + 1, eq->eq[i], j, total,
1630                                 &aff->v->el[0]);
1631         }
1632
1633         isl_basic_set_free(eq);
1634         aff = isl_aff_normalize(aff);
1635         return aff;
1636 error:
1637         isl_basic_set_free(eq);
1638         isl_aff_free(aff);
1639         return NULL;
1640 }
1641
1642 /* Exploit the equalities in "eq" to simplify the affine expression
1643  * and the expressions of the integer divisions in the local space.
1644  */
1645 static __isl_give isl_aff *isl_aff_substitute_equalities(
1646         __isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
1647 {
1648         int n_div;
1649
1650         if (!aff || !eq)
1651                 goto error;
1652         n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1653         if (n_div > 0)
1654                 eq = isl_basic_set_add_dims(eq, isl_dim_set, n_div);
1655         return isl_aff_substitute_equalities_lifted(aff, eq);
1656 error:
1657         isl_basic_set_free(eq);
1658         isl_aff_free(aff);
1659         return NULL;
1660 }
1661
1662 /* Look for equalities among the variables shared by context and aff
1663  * and the integer divisions of aff, if any.
1664  * The equalities are then used to eliminate coefficients and/or integer
1665  * divisions from aff.
1666  */
1667 __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff,
1668         __isl_take isl_set *context)
1669 {
1670         isl_basic_set *hull;
1671         int n_div;
1672
1673         if (!aff)
1674                 goto error;
1675         n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1676         if (n_div > 0) {
1677                 isl_basic_set *bset;
1678                 isl_local_space *ls;
1679                 context = isl_set_add_dims(context, isl_dim_set, n_div);
1680                 ls = isl_aff_get_domain_local_space(aff);
1681                 bset = isl_basic_set_from_local_space(ls);
1682                 bset = isl_basic_set_lift(bset);
1683                 bset = isl_basic_set_flatten(bset);
1684                 context = isl_set_intersect(context,
1685                                             isl_set_from_basic_set(bset));
1686         }
1687
1688         hull = isl_set_affine_hull(context);
1689         return isl_aff_substitute_equalities_lifted(aff, hull);
1690 error:
1691         isl_aff_free(aff);
1692         isl_set_free(context);
1693         return NULL;
1694 }
1695
1696 __isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
1697         __isl_take isl_set *context)
1698 {
1699         isl_set *dom_context = isl_set_universe(isl_aff_get_domain_space(aff));
1700         dom_context = isl_set_intersect_params(dom_context, context);
1701         return isl_aff_gist(aff, dom_context);
1702 }
1703
1704 /* Return a basic set containing those elements in the space
1705  * of aff where it is non-negative.
1706  * If "rational" is set, then return a rational basic set.
1707  */
1708 static __isl_give isl_basic_set *aff_nonneg_basic_set(
1709         __isl_take isl_aff *aff, int rational)
1710 {
1711         isl_constraint *ineq;
1712         isl_basic_set *bset;
1713
1714         ineq = isl_inequality_from_aff(aff);
1715
1716         bset = isl_basic_set_from_constraint(ineq);
1717         if (rational)
1718                 bset = isl_basic_set_set_rational(bset);
1719         bset = isl_basic_set_simplify(bset);
1720         return bset;
1721 }
1722
1723 /* Return a basic set containing those elements in the space
1724  * of aff where it is non-negative.
1725  */
1726 __isl_give isl_basic_set *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff)
1727 {
1728         return aff_nonneg_basic_set(aff, 0);
1729 }
1730
1731 /* Return a basic set containing those elements in the domain space
1732  * of aff where it is negative.
1733  */
1734 __isl_give isl_basic_set *isl_aff_neg_basic_set(__isl_take isl_aff *aff)
1735 {
1736         aff = isl_aff_neg(aff);
1737         aff = isl_aff_add_constant_num_si(aff, -1);
1738         return isl_aff_nonneg_basic_set(aff);
1739 }
1740
1741 /* Return a basic set containing those elements in the space
1742  * of aff where it is zero.
1743  * If "rational" is set, then return a rational basic set.
1744  */
1745 static __isl_give isl_basic_set *aff_zero_basic_set(__isl_take isl_aff *aff,
1746         int rational)
1747 {
1748         isl_constraint *ineq;
1749         isl_basic_set *bset;
1750
1751         ineq = isl_equality_from_aff(aff);
1752
1753         bset = isl_basic_set_from_constraint(ineq);
1754         if (rational)
1755                 bset = isl_basic_set_set_rational(bset);
1756         bset = isl_basic_set_simplify(bset);
1757         return bset;
1758 }
1759
1760 /* Return a basic set containing those elements in the space
1761  * of aff where it is zero.
1762  */
1763 __isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
1764 {
1765         return aff_zero_basic_set(aff, 0);
1766 }
1767
1768 /* Return a basic set containing those elements in the shared space
1769  * of aff1 and aff2 where aff1 is greater than or equal to aff2.
1770  */
1771 __isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
1772         __isl_take isl_aff *aff2)
1773 {
1774         aff1 = isl_aff_sub(aff1, aff2);
1775
1776         return isl_aff_nonneg_basic_set(aff1);
1777 }
1778
1779 /* Return a basic set containing those elements in the shared space
1780  * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
1781  */
1782 __isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
1783         __isl_take isl_aff *aff2)
1784 {
1785         return isl_aff_ge_basic_set(aff2, aff1);
1786 }
1787
1788 __isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_set *dom,
1789         __isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
1790 {
1791         aff1 = isl_aff_add(aff1, aff2);
1792         aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
1793         return aff1;
1794 }
1795
1796 int isl_aff_is_empty(__isl_keep isl_aff *aff)
1797 {
1798         if (!aff)
1799                 return -1;
1800
1801         return 0;
1802 }
1803
1804 /* Check whether the given affine expression has non-zero coefficient
1805  * for any dimension in the given range or if any of these dimensions
1806  * appear with non-zero coefficients in any of the integer divisions
1807  * involved in the affine expression.
1808  */
1809 int isl_aff_involves_dims(__isl_keep isl_aff *aff,
1810         enum isl_dim_type type, unsigned first, unsigned n)
1811 {
1812         int i;
1813         isl_ctx *ctx;
1814         int *active = NULL;
1815         int involves = 0;
1816
1817         if (!aff)
1818                 return -1;
1819         if (n == 0)
1820                 return 0;
1821
1822         ctx = isl_aff_get_ctx(aff);
1823         if (first + n > isl_aff_dim(aff, type))
1824                 isl_die(ctx, isl_error_invalid,
1825                         "range out of bounds", return -1);
1826
1827         active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
1828         if (!active)
1829                 goto error;
1830
1831         first += isl_local_space_offset(aff->ls, type) - 1;
1832         for (i = 0; i < n; ++i)
1833                 if (active[first + i]) {
1834                         involves = 1;
1835                         break;
1836                 }
1837
1838         free(active);
1839
1840         return involves;
1841 error:
1842         free(active);
1843         return -1;
1844 }
1845
1846 __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
1847         enum isl_dim_type type, unsigned first, unsigned n)
1848 {
1849         isl_ctx *ctx;
1850
1851         if (!aff)
1852                 return NULL;
1853         if (type == isl_dim_out)
1854                 isl_die(aff->v->ctx, isl_error_invalid,
1855                         "cannot drop output/set dimension",
1856                         return isl_aff_free(aff));
1857         if (type == isl_dim_in)
1858                 type = isl_dim_set;
1859         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1860                 return aff;
1861
1862         ctx = isl_aff_get_ctx(aff);
1863         if (first + n > isl_local_space_dim(aff->ls, type))
1864                 isl_die(ctx, isl_error_invalid, "range out of bounds",
1865                         return isl_aff_free(aff));
1866
1867         aff = isl_aff_cow(aff);
1868         if (!aff)
1869                 return NULL;
1870
1871         aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
1872         if (!aff->ls)
1873                 return isl_aff_free(aff);
1874
1875         first += 1 + isl_local_space_offset(aff->ls, type);
1876         aff->v = isl_vec_drop_els(aff->v, first, n);
1877         if (!aff->v)
1878                 return isl_aff_free(aff);
1879
1880         return aff;
1881 }
1882
1883 /* Project the domain of the affine expression onto its parameter space.
1884  * The affine expression may not involve any of the domain dimensions.
1885  */
1886 __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
1887 {
1888         isl_space *space;
1889         unsigned n;
1890         int involves;
1891
1892         n = isl_aff_dim(aff, isl_dim_in);
1893         involves = isl_aff_involves_dims(aff, isl_dim_in, 0, n);
1894         if (involves < 0)
1895                 return isl_aff_free(aff);
1896         if (involves)
1897                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1898                     "affine expression involves some of the domain dimensions",
1899                     return isl_aff_free(aff));
1900         aff = isl_aff_drop_dims(aff, isl_dim_in, 0, n);
1901         space = isl_aff_get_domain_space(aff);
1902         space = isl_space_params(space);
1903         aff = isl_aff_reset_domain_space(aff, space);
1904         return aff;
1905 }
1906
1907 __isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
1908         enum isl_dim_type type, unsigned first, unsigned n)
1909 {
1910         isl_ctx *ctx;
1911
1912         if (!aff)
1913                 return NULL;
1914         if (type == isl_dim_out)
1915                 isl_die(aff->v->ctx, isl_error_invalid,
1916                         "cannot insert output/set dimensions",
1917                         return isl_aff_free(aff));
1918         if (type == isl_dim_in)
1919                 type = isl_dim_set;
1920         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1921                 return aff;
1922
1923         ctx = isl_aff_get_ctx(aff);
1924         if (first > isl_local_space_dim(aff->ls, type))
1925                 isl_die(ctx, isl_error_invalid, "position out of bounds",
1926                         return isl_aff_free(aff));
1927
1928         aff = isl_aff_cow(aff);
1929         if (!aff)
1930                 return NULL;
1931
1932         aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
1933         if (!aff->ls)
1934                 return isl_aff_free(aff);
1935
1936         first += 1 + isl_local_space_offset(aff->ls, type);
1937         aff->v = isl_vec_insert_zero_els(aff->v, first, n);
1938         if (!aff->v)
1939                 return isl_aff_free(aff);
1940
1941         return aff;
1942 }
1943
1944 __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
1945         enum isl_dim_type type, unsigned n)
1946 {
1947         unsigned pos;
1948
1949         pos = isl_aff_dim(aff, type);
1950
1951         return isl_aff_insert_dims(aff, type, pos, n);
1952 }
1953
1954 __isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff,
1955         enum isl_dim_type type, unsigned n)
1956 {
1957         unsigned pos;
1958
1959         pos = isl_pw_aff_dim(pwaff, type);
1960
1961         return isl_pw_aff_insert_dims(pwaff, type, pos, n);
1962 }
1963
1964 __isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff)
1965 {
1966         isl_set *dom = isl_set_universe(isl_aff_get_domain_space(aff));
1967         return isl_pw_aff_alloc(dom, aff);
1968 }
1969
1970 #undef PW
1971 #define PW isl_pw_aff
1972 #undef EL
1973 #define EL isl_aff
1974 #undef EL_IS_ZERO
1975 #define EL_IS_ZERO is_empty
1976 #undef ZERO
1977 #define ZERO empty
1978 #undef IS_ZERO
1979 #define IS_ZERO is_empty
1980 #undef FIELD
1981 #define FIELD aff
1982 #undef DEFAULT_IS_ZERO
1983 #define DEFAULT_IS_ZERO 0
1984
1985 #define NO_EVAL
1986 #define NO_OPT
1987 #define NO_MOVE_DIMS
1988 #define NO_LIFT
1989 #define NO_MORPH
1990
1991 #include <isl_pw_templ.c>
1992
1993 static __isl_give isl_set *align_params_pw_pw_set_and(
1994         __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2,
1995         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
1996                                     __isl_take isl_pw_aff *pwaff2))
1997 {
1998         if (!pwaff1 || !pwaff2)
1999                 goto error;
2000         if (isl_space_match(pwaff1->dim, isl_dim_param,
2001                           pwaff2->dim, isl_dim_param))
2002                 return fn(pwaff1, pwaff2);
2003         if (!isl_space_has_named_params(pwaff1->dim) ||
2004             !isl_space_has_named_params(pwaff2->dim))
2005                 isl_die(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid,
2006                         "unaligned unnamed parameters", goto error);
2007         pwaff1 = isl_pw_aff_align_params(pwaff1, isl_pw_aff_get_space(pwaff2));
2008         pwaff2 = isl_pw_aff_align_params(pwaff2, isl_pw_aff_get_space(pwaff1));
2009         return fn(pwaff1, pwaff2);
2010 error:
2011         isl_pw_aff_free(pwaff1);
2012         isl_pw_aff_free(pwaff2);
2013         return NULL;
2014 }
2015
2016 /* Compute a piecewise quasi-affine expression with a domain that
2017  * is the union of those of pwaff1 and pwaff2 and such that on each
2018  * cell, the quasi-affine expression is the better (according to cmp)
2019  * of those of pwaff1 and pwaff2.  If only one of pwaff1 or pwaff2
2020  * is defined on a given cell, then the associated expression
2021  * is the defined one.
2022  */
2023 static __isl_give isl_pw_aff *pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
2024         __isl_take isl_pw_aff *pwaff2,
2025         __isl_give isl_basic_set *(*cmp)(__isl_take isl_aff *aff1,
2026                                         __isl_take isl_aff *aff2))
2027 {
2028         int i, j, n;
2029         isl_pw_aff *res;
2030         isl_ctx *ctx;
2031         isl_set *set;
2032
2033         if (!pwaff1 || !pwaff2)
2034                 goto error;
2035
2036         ctx = isl_space_get_ctx(pwaff1->dim);
2037         if (!isl_space_is_equal(pwaff1->dim, pwaff2->dim))
2038                 isl_die(ctx, isl_error_invalid,
2039                         "arguments should live in same space", goto error);
2040
2041         if (isl_pw_aff_is_empty(pwaff1)) {
2042                 isl_pw_aff_free(pwaff1);
2043                 return pwaff2;
2044         }
2045
2046         if (isl_pw_aff_is_empty(pwaff2)) {
2047                 isl_pw_aff_free(pwaff2);
2048                 return pwaff1;
2049         }
2050
2051         n = 2 * (pwaff1->n + 1) * (pwaff2->n + 1);
2052         res = isl_pw_aff_alloc_size(isl_space_copy(pwaff1->dim), n);
2053
2054         for (i = 0; i < pwaff1->n; ++i) {
2055                 set = isl_set_copy(pwaff1->p[i].set);
2056                 for (j = 0; j < pwaff2->n; ++j) {
2057                         struct isl_set *common;
2058                         isl_set *better;
2059
2060                         common = isl_set_intersect(
2061                                         isl_set_copy(pwaff1->p[i].set),
2062                                         isl_set_copy(pwaff2->p[j].set));
2063                         better = isl_set_from_basic_set(cmp(
2064                                         isl_aff_copy(pwaff2->p[j].aff),
2065                                         isl_aff_copy(pwaff1->p[i].aff)));
2066                         better = isl_set_intersect(common, better);
2067                         if (isl_set_plain_is_empty(better)) {
2068                                 isl_set_free(better);
2069                                 continue;
2070                         }
2071                         set = isl_set_subtract(set, isl_set_copy(better));
2072
2073                         res = isl_pw_aff_add_piece(res, better,
2074                                                 isl_aff_copy(pwaff2->p[j].aff));
2075                 }
2076                 res = isl_pw_aff_add_piece(res, set,
2077                                                 isl_aff_copy(pwaff1->p[i].aff));
2078         }
2079
2080         for (j = 0; j < pwaff2->n; ++j) {
2081                 set = isl_set_copy(pwaff2->p[j].set);
2082                 for (i = 0; i < pwaff1->n; ++i)
2083                         set = isl_set_subtract(set,
2084                                         isl_set_copy(pwaff1->p[i].set));
2085                 res = isl_pw_aff_add_piece(res, set,
2086                                                 isl_aff_copy(pwaff2->p[j].aff));
2087         }
2088
2089         isl_pw_aff_free(pwaff1);
2090         isl_pw_aff_free(pwaff2);
2091
2092         return res;
2093 error:
2094         isl_pw_aff_free(pwaff1);
2095         isl_pw_aff_free(pwaff2);
2096         return NULL;
2097 }
2098
2099 /* Compute a piecewise quasi-affine expression with a domain that
2100  * is the union of those of pwaff1 and pwaff2 and such that on each
2101  * cell, the quasi-affine expression is the maximum of those of pwaff1
2102  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
2103  * cell, then the associated expression is the defined one.
2104  */
2105 static __isl_give isl_pw_aff *pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
2106         __isl_take isl_pw_aff *pwaff2)
2107 {
2108         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_ge_basic_set);
2109 }
2110
2111 __isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
2112         __isl_take isl_pw_aff *pwaff2)
2113 {
2114         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
2115                                                         &pw_aff_union_max);
2116 }
2117
2118 /* Compute a piecewise quasi-affine expression with a domain that
2119  * is the union of those of pwaff1 and pwaff2 and such that on each
2120  * cell, the quasi-affine expression is the minimum of those of pwaff1
2121  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
2122  * cell, then the associated expression is the defined one.
2123  */
2124 static __isl_give isl_pw_aff *pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
2125         __isl_take isl_pw_aff *pwaff2)
2126 {
2127         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_le_basic_set);
2128 }
2129
2130 __isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
2131         __isl_take isl_pw_aff *pwaff2)
2132 {
2133         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
2134                                                         &pw_aff_union_min);
2135 }
2136
2137 __isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
2138         __isl_take isl_pw_aff *pwaff2, int max)
2139 {
2140         if (max)
2141                 return isl_pw_aff_union_max(pwaff1, pwaff2);
2142         else
2143                 return isl_pw_aff_union_min(pwaff1, pwaff2);
2144 }
2145
2146 /* Construct a map with as domain the domain of pwaff and
2147  * one-dimensional range corresponding to the affine expressions.
2148  */
2149 static __isl_give isl_map *map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
2150 {
2151         int i;
2152         isl_space *dim;
2153         isl_map *map;
2154
2155         if (!pwaff)
2156                 return NULL;
2157
2158         dim = isl_pw_aff_get_space(pwaff);
2159         map = isl_map_empty(dim);
2160
2161         for (i = 0; i < pwaff->n; ++i) {
2162                 isl_basic_map *bmap;
2163                 isl_map *map_i;
2164
2165                 bmap = isl_basic_map_from_aff(isl_aff_copy(pwaff->p[i].aff));
2166                 map_i = isl_map_from_basic_map(bmap);
2167                 map_i = isl_map_intersect_domain(map_i,
2168                                                 isl_set_copy(pwaff->p[i].set));
2169                 map = isl_map_union_disjoint(map, map_i);
2170         }
2171
2172         isl_pw_aff_free(pwaff);
2173
2174         return map;
2175 }
2176
2177 /* Construct a map with as domain the domain of pwaff and
2178  * one-dimensional range corresponding to the affine expressions.
2179  */
2180 __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
2181 {
2182         if (!pwaff)
2183                 return NULL;
2184         if (isl_space_is_set(pwaff->dim))
2185                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
2186                         "space of input is not a map",
2187                         return isl_pw_aff_free(pwaff));
2188         return map_from_pw_aff(pwaff);
2189 }
2190
2191 /* Construct a one-dimensional set with as parameter domain
2192  * the domain of pwaff and the single set dimension
2193  * corresponding to the affine expressions.
2194  */
2195 __isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff)
2196 {
2197         if (!pwaff)
2198                 return NULL;
2199         if (!isl_space_is_set(pwaff->dim))
2200                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
2201                         "space of input is not a set",
2202                         return isl_pw_aff_free(pwaff));
2203         return map_from_pw_aff(pwaff);
2204 }
2205
2206 /* Return a set containing those elements in the domain
2207  * of pwaff where it is non-negative.
2208  */
2209 __isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
2210 {
2211         int i;
2212         isl_set *set;
2213
2214         if (!pwaff)
2215                 return NULL;
2216
2217         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
2218
2219         for (i = 0; i < pwaff->n; ++i) {
2220                 isl_basic_set *bset;
2221                 isl_set *set_i;
2222                 int rational;
2223
2224                 rational = isl_set_has_rational(pwaff->p[i].set);
2225                 bset = aff_nonneg_basic_set(isl_aff_copy(pwaff->p[i].aff),
2226                                                 rational);
2227                 set_i = isl_set_from_basic_set(bset);
2228                 set_i = isl_set_intersect(set_i, isl_set_copy(pwaff->p[i].set));
2229                 set = isl_set_union_disjoint(set, set_i);
2230         }
2231
2232         isl_pw_aff_free(pwaff);
2233
2234         return set;
2235 }
2236
2237 /* Return a set containing those elements in the domain
2238  * of pwaff where it is zero (if complement is 0) or not zero
2239  * (if complement is 1).
2240  */
2241 static __isl_give isl_set *pw_aff_zero_set(__isl_take isl_pw_aff *pwaff,
2242         int complement)
2243 {
2244         int i;
2245         isl_set *set;
2246
2247         if (!pwaff)
2248                 return NULL;
2249
2250         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
2251
2252         for (i = 0; i < pwaff->n; ++i) {
2253                 isl_basic_set *bset;
2254                 isl_set *set_i, *zero;
2255                 int rational;
2256
2257                 rational = isl_set_has_rational(pwaff->p[i].set);
2258                 bset = aff_zero_basic_set(isl_aff_copy(pwaff->p[i].aff),
2259                                                 rational);
2260                 zero = isl_set_from_basic_set(bset);
2261                 set_i = isl_set_copy(pwaff->p[i].set);
2262                 if (complement)
2263                         set_i = isl_set_subtract(set_i, zero);
2264                 else
2265                         set_i = isl_set_intersect(set_i, zero);
2266                 set = isl_set_union_disjoint(set, set_i);
2267         }
2268
2269         isl_pw_aff_free(pwaff);
2270
2271         return set;
2272 }
2273
2274 /* Return a set containing those elements in the domain
2275  * of pwaff where it is zero.
2276  */
2277 __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
2278 {
2279         return pw_aff_zero_set(pwaff, 0);
2280 }
2281
2282 /* Return a set containing those elements in the domain
2283  * of pwaff where it is not zero.
2284  */
2285 __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
2286 {
2287         return pw_aff_zero_set(pwaff, 1);
2288 }
2289
2290 /* Return a set containing those elements in the shared domain
2291  * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
2292  *
2293  * We compute the difference on the shared domain and then construct
2294  * the set of values where this difference is non-negative.
2295  * If strict is set, we first subtract 1 from the difference.
2296  * If equal is set, we only return the elements where pwaff1 and pwaff2
2297  * are equal.
2298  */
2299 static __isl_give isl_set *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
2300         __isl_take isl_pw_aff *pwaff2, int strict, int equal)
2301 {
2302         isl_set *set1, *set2;
2303
2304         set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
2305         set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
2306         set1 = isl_set_intersect(set1, set2);
2307         pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
2308         pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
2309         pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
2310
2311         if (strict) {
2312                 isl_space *dim = isl_set_get_space(set1);
2313                 isl_aff *aff;
2314                 aff = isl_aff_zero_on_domain(isl_local_space_from_space(dim));
2315                 aff = isl_aff_add_constant_si(aff, -1);
2316                 pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
2317         } else
2318                 isl_set_free(set1);
2319
2320         if (equal)
2321                 return isl_pw_aff_zero_set(pwaff1);
2322         return isl_pw_aff_nonneg_set(pwaff1);
2323 }
2324
2325 /* Return a set containing those elements in the shared domain
2326  * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
2327  */
2328 static __isl_give isl_set *pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
2329         __isl_take isl_pw_aff *pwaff2)
2330 {
2331         return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
2332 }
2333
2334 __isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
2335         __isl_take isl_pw_aff *pwaff2)
2336 {
2337         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_eq_set);
2338 }
2339
2340 /* Return a set containing those elements in the shared domain
2341  * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
2342  */
2343 static __isl_give isl_set *pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
2344         __isl_take isl_pw_aff *pwaff2)
2345 {
2346         return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
2347 }
2348
2349 __isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
2350         __isl_take isl_pw_aff *pwaff2)
2351 {
2352         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ge_set);
2353 }
2354
2355 /* Return a set containing those elements in the shared domain
2356  * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
2357  */
2358 static __isl_give isl_set *pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
2359         __isl_take isl_pw_aff *pwaff2)
2360 {
2361         return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
2362 }
2363
2364 __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
2365         __isl_take isl_pw_aff *pwaff2)
2366 {
2367         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_gt_set);
2368 }
2369
2370 __isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
2371         __isl_take isl_pw_aff *pwaff2)
2372 {
2373         return isl_pw_aff_ge_set(pwaff2, pwaff1);
2374 }
2375
2376 __isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
2377         __isl_take isl_pw_aff *pwaff2)
2378 {
2379         return isl_pw_aff_gt_set(pwaff2, pwaff1);
2380 }
2381
2382 /* Return a set containing those elements in the shared domain
2383  * of the elements of list1 and list2 where each element in list1
2384  * has the relation specified by "fn" with each element in list2.
2385  */
2386 static __isl_give isl_set *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
2387         __isl_take isl_pw_aff_list *list2,
2388         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
2389                                     __isl_take isl_pw_aff *pwaff2))
2390 {
2391         int i, j;
2392         isl_ctx *ctx;
2393         isl_set *set;
2394
2395         if (!list1 || !list2)
2396                 goto error;
2397
2398         ctx = isl_pw_aff_list_get_ctx(list1);
2399         if (list1->n < 1 || list2->n < 1)
2400                 isl_die(ctx, isl_error_invalid,
2401                         "list should contain at least one element", goto error);
2402
2403         set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
2404         for (i = 0; i < list1->n; ++i)
2405                 for (j = 0; j < list2->n; ++j) {
2406                         isl_set *set_ij;
2407
2408                         set_ij = fn(isl_pw_aff_copy(list1->p[i]),
2409                                     isl_pw_aff_copy(list2->p[j]));
2410                         set = isl_set_intersect(set, set_ij);
2411                 }
2412
2413         isl_pw_aff_list_free(list1);
2414         isl_pw_aff_list_free(list2);
2415         return set;
2416 error:
2417         isl_pw_aff_list_free(list1);
2418         isl_pw_aff_list_free(list2);
2419         return NULL;
2420 }
2421
2422 /* Return a set containing those elements in the shared domain
2423  * of the elements of list1 and list2 where each element in list1
2424  * is equal to each element in list2.
2425  */
2426 __isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
2427         __isl_take isl_pw_aff_list *list2)
2428 {
2429         return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
2430 }
2431
2432 __isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
2433         __isl_take isl_pw_aff_list *list2)
2434 {
2435         return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
2436 }
2437
2438 /* Return a set containing those elements in the shared domain
2439  * of the elements of list1 and list2 where each element in list1
2440  * is less than or equal to each element in list2.
2441  */
2442 __isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
2443         __isl_take isl_pw_aff_list *list2)
2444 {
2445         return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
2446 }
2447
2448 __isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
2449         __isl_take isl_pw_aff_list *list2)
2450 {
2451         return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
2452 }
2453
2454 __isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
2455         __isl_take isl_pw_aff_list *list2)
2456 {
2457         return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
2458 }
2459
2460 __isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
2461         __isl_take isl_pw_aff_list *list2)
2462 {
2463         return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
2464 }
2465
2466
2467 /* Return a set containing those elements in the shared domain
2468  * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
2469  */
2470 static __isl_give isl_set *pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
2471         __isl_take isl_pw_aff *pwaff2)
2472 {
2473         isl_set *set_lt, *set_gt;
2474
2475         set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
2476                                    isl_pw_aff_copy(pwaff2));
2477         set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
2478         return isl_set_union_disjoint(set_lt, set_gt);
2479 }
2480
2481 __isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
2482         __isl_take isl_pw_aff *pwaff2)
2483 {
2484         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ne_set);
2485 }
2486
2487 __isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
2488         isl_int v)
2489 {
2490         int i;
2491
2492         if (isl_int_is_one(v))
2493                 return pwaff;
2494         if (!isl_int_is_pos(v))
2495                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
2496                         "factor needs to be positive",
2497                         return isl_pw_aff_free(pwaff));
2498         pwaff = isl_pw_aff_cow(pwaff);
2499         if (!pwaff)
2500                 return NULL;
2501         if (pwaff->n == 0)
2502                 return pwaff;
2503
2504         for (i = 0; i < pwaff->n; ++i) {
2505                 pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v);
2506                 if (!pwaff->p[i].aff)
2507                         return isl_pw_aff_free(pwaff);
2508         }
2509
2510         return pwaff;
2511 }
2512
2513 __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
2514 {
2515         int i;
2516
2517         pwaff = isl_pw_aff_cow(pwaff);
2518         if (!pwaff)
2519                 return NULL;
2520         if (pwaff->n == 0)
2521                 return pwaff;
2522
2523         for (i = 0; i < pwaff->n; ++i) {
2524                 pwaff->p[i].aff = isl_aff_floor(pwaff->p[i].aff);
2525                 if (!pwaff->p[i].aff)
2526                         return isl_pw_aff_free(pwaff);
2527         }
2528
2529         return pwaff;
2530 }
2531
2532 __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
2533 {
2534         int i;
2535
2536         pwaff = isl_pw_aff_cow(pwaff);
2537         if (!pwaff)
2538                 return NULL;
2539         if (pwaff->n == 0)
2540                 return pwaff;
2541
2542         for (i = 0; i < pwaff->n; ++i) {
2543                 pwaff->p[i].aff = isl_aff_ceil(pwaff->p[i].aff);
2544                 if (!pwaff->p[i].aff)
2545                         return isl_pw_aff_free(pwaff);
2546         }
2547
2548         return pwaff;
2549 }
2550
2551 /* Assuming that "cond1" and "cond2" are disjoint,
2552  * return an affine expression that is equal to pwaff1 on cond1
2553  * and to pwaff2 on cond2.
2554  */
2555 static __isl_give isl_pw_aff *isl_pw_aff_select(
2556         __isl_take isl_set *cond1, __isl_take isl_pw_aff *pwaff1,
2557         __isl_take isl_set *cond2, __isl_take isl_pw_aff *pwaff2)
2558 {
2559         pwaff1 = isl_pw_aff_intersect_domain(pwaff1, cond1);
2560         pwaff2 = isl_pw_aff_intersect_domain(pwaff2, cond2);
2561
2562         return isl_pw_aff_add_disjoint(pwaff1, pwaff2);
2563 }
2564
2565 /* Return an affine expression that is equal to pwaff_true for elements
2566  * where "cond" is non-zero and to pwaff_false for elements where "cond"
2567  * is zero.
2568  * That is, return cond ? pwaff_true : pwaff_false;
2569  */
2570 __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond,
2571         __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
2572 {
2573         isl_set *cond_true, *cond_false;
2574
2575         cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond));
2576         cond_false = isl_pw_aff_zero_set(cond);
2577         return isl_pw_aff_select(cond_true, pwaff_true,
2578                                  cond_false, pwaff_false);
2579 }
2580
2581 int isl_aff_is_cst(__isl_keep isl_aff *aff)
2582 {
2583         if (!aff)
2584                 return -1;
2585
2586         return isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2) == -1;
2587 }
2588
2589 /* Check whether pwaff is a piecewise constant.
2590  */
2591 int isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
2592 {
2593         int i;
2594
2595         if (!pwaff)
2596                 return -1;
2597
2598         for (i = 0; i < pwaff->n; ++i) {
2599                 int is_cst = isl_aff_is_cst(pwaff->p[i].aff);
2600                 if (is_cst < 0 || !is_cst)
2601                         return is_cst;
2602         }
2603
2604         return 1;
2605 }
2606
2607 __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
2608         __isl_take isl_aff *aff2)
2609 {
2610         if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
2611                 return isl_aff_mul(aff2, aff1);
2612
2613         if (!isl_aff_is_cst(aff2))
2614                 isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,
2615                         "at least one affine expression should be constant",
2616                         goto error);
2617
2618         aff1 = isl_aff_cow(aff1);
2619         if (!aff1 || !aff2)
2620                 goto error;
2621
2622         aff1 = isl_aff_scale(aff1, aff2->v->el[1]);
2623         aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]);
2624
2625         isl_aff_free(aff2);
2626         return aff1;
2627 error:
2628         isl_aff_free(aff1);
2629         isl_aff_free(aff2);
2630         return NULL;
2631 }
2632
2633 /* Divide "aff1" by "aff2", assuming "aff2" is a piecewise constant.
2634  */
2635 __isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1,
2636         __isl_take isl_aff *aff2)
2637 {
2638         int is_cst;
2639         int neg;
2640
2641         is_cst = isl_aff_is_cst(aff2);
2642         if (is_cst < 0)
2643                 goto error;
2644         if (!is_cst)
2645                 isl_die(isl_aff_get_ctx(aff2), isl_error_invalid,
2646                         "second argument should be a constant", goto error);
2647
2648         if (!aff2)
2649                 goto error;
2650
2651         neg = isl_int_is_neg(aff2->v->el[1]);
2652         if (neg) {
2653                 isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
2654                 isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
2655         }
2656
2657         aff1 = isl_aff_scale(aff1, aff2->v->el[0]);
2658         aff1 = isl_aff_scale_down(aff1, aff2->v->el[1]);
2659
2660         if (neg) {
2661                 isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
2662                 isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
2663         }
2664
2665         isl_aff_free(aff2);
2666         return aff1;
2667 error:
2668         isl_aff_free(aff1);
2669         isl_aff_free(aff2);
2670         return NULL;
2671 }
2672
2673 static __isl_give isl_pw_aff *pw_aff_add(__isl_take isl_pw_aff *pwaff1,
2674         __isl_take isl_pw_aff *pwaff2)
2675 {
2676         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
2677 }
2678
2679 __isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
2680         __isl_take isl_pw_aff *pwaff2)
2681 {
2682         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_add);
2683 }
2684
2685 __isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1,
2686         __isl_take isl_pw_aff *pwaff2)
2687 {
2688         return isl_pw_aff_union_add_(pwaff1, pwaff2);
2689 }
2690
2691 static __isl_give isl_pw_aff *pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
2692         __isl_take isl_pw_aff *pwaff2)
2693 {
2694         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
2695 }
2696
2697 __isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
2698         __isl_take isl_pw_aff *pwaff2)
2699 {
2700         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_mul);
2701 }
2702
2703 static __isl_give isl_pw_aff *pw_aff_div(__isl_take isl_pw_aff *pa1,
2704         __isl_take isl_pw_aff *pa2)
2705 {
2706         return isl_pw_aff_on_shared_domain(pa1, pa2, &isl_aff_div);
2707 }
2708
2709 /* Divide "pa1" by "pa2", assuming "pa2" is a piecewise constant.
2710  */
2711 __isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1,
2712         __isl_take isl_pw_aff *pa2)
2713 {
2714         int is_cst;
2715
2716         is_cst = isl_pw_aff_is_cst(pa2);
2717         if (is_cst < 0)
2718                 goto error;
2719         if (!is_cst)
2720                 isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
2721                         "second argument should be a piecewise constant",
2722                         goto error);
2723         return isl_pw_aff_align_params_pw_pw_and(pa1, pa2, &pw_aff_div);
2724 error:
2725         isl_pw_aff_free(pa1);
2726         isl_pw_aff_free(pa2);
2727         return NULL;
2728 }
2729
2730 /* Compute the quotient of the integer division of "pa1" by "pa2"
2731  * with rounding towards zero.
2732  * "pa2" is assumed to be a piecewise constant.
2733  *
2734  * In particular, return
2735  *
2736  *      pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)
2737  *
2738  */
2739 __isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1,
2740         __isl_take isl_pw_aff *pa2)
2741 {
2742         int is_cst;
2743         isl_set *cond;
2744         isl_pw_aff *f, *c;
2745
2746         is_cst = isl_pw_aff_is_cst(pa2);
2747         if (is_cst < 0)
2748                 goto error;
2749         if (!is_cst)
2750                 isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
2751                         "second argument should be a piecewise constant",
2752                         goto error);
2753
2754         pa1 = isl_pw_aff_div(pa1, pa2);
2755
2756         cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1));
2757         f = isl_pw_aff_floor(isl_pw_aff_copy(pa1));
2758         c = isl_pw_aff_ceil(pa1);
2759         return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c);
2760 error:
2761         isl_pw_aff_free(pa1);
2762         isl_pw_aff_free(pa2);
2763         return NULL;
2764 }
2765
2766 /* Compute the remainder of the integer division of "pa1" by "pa2"
2767  * with rounding towards zero.
2768  * "pa2" is assumed to be a piecewise constant.
2769  *
2770  * In particular, return
2771  *
2772  *      pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2))
2773  *
2774  */
2775 __isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1,
2776         __isl_take isl_pw_aff *pa2)
2777 {
2778         int is_cst;
2779         isl_pw_aff *res;
2780
2781         is_cst = isl_pw_aff_is_cst(pa2);
2782         if (is_cst < 0)
2783                 goto error;
2784         if (!is_cst)
2785                 isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
2786                         "second argument should be a piecewise constant",
2787                         goto error);
2788         res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2));
2789         res = isl_pw_aff_mul(pa2, res);
2790         res = isl_pw_aff_sub(pa1, res);
2791         return res;
2792 error:
2793         isl_pw_aff_free(pa1);
2794         isl_pw_aff_free(pa2);
2795         return NULL;
2796 }
2797
2798 static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
2799         __isl_take isl_pw_aff *pwaff2)
2800 {
2801         isl_set *le;
2802         isl_set *dom;
2803
2804         dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
2805                                 isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
2806         le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
2807                                 isl_pw_aff_copy(pwaff2));
2808         dom = isl_set_subtract(dom, isl_set_copy(le));
2809         return isl_pw_aff_select(le, pwaff1, dom, pwaff2);
2810 }
2811
2812 __isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
2813         __isl_take isl_pw_aff *pwaff2)
2814 {
2815         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_min);
2816 }
2817
2818 static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
2819         __isl_take isl_pw_aff *pwaff2)
2820 {
2821         isl_set *ge;
2822         isl_set *dom;
2823
2824         dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
2825                                 isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
2826         ge = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
2827                                 isl_pw_aff_copy(pwaff2));
2828         dom = isl_set_subtract(dom, isl_set_copy(ge));
2829         return isl_pw_aff_select(ge, pwaff1, dom, pwaff2);
2830 }
2831
2832 __isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
2833         __isl_take isl_pw_aff *pwaff2)
2834 {
2835         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_max);
2836 }
2837
2838 static __isl_give isl_pw_aff *pw_aff_list_reduce(
2839         __isl_take isl_pw_aff_list *list,
2840         __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pwaff1,
2841                                         __isl_take isl_pw_aff *pwaff2))
2842 {
2843         int i;
2844         isl_ctx *ctx;
2845         isl_pw_aff *res;
2846
2847         if (!list)
2848                 return NULL;
2849
2850         ctx = isl_pw_aff_list_get_ctx(list);
2851         if (list->n < 1)
2852                 isl_die(ctx, isl_error_invalid,
2853                         "list should contain at least one element",
2854                         return isl_pw_aff_list_free(list));
2855
2856         res = isl_pw_aff_copy(list->p[0]);
2857         for (i = 1; i < list->n; ++i)
2858                 res = fn(res, isl_pw_aff_copy(list->p[i]));
2859
2860         isl_pw_aff_list_free(list);
2861         return res;
2862 }
2863
2864 /* Return an isl_pw_aff that maps each element in the intersection of the
2865  * domains of the elements of list to the minimal corresponding affine
2866  * expression.
2867  */
2868 __isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
2869 {
2870         return pw_aff_list_reduce(list, &isl_pw_aff_min);
2871 }
2872
2873 /* Return an isl_pw_aff that maps each element in the intersection of the
2874  * domains of the elements of list to the maximal corresponding affine
2875  * expression.
2876  */
2877 __isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
2878 {
2879         return pw_aff_list_reduce(list, &isl_pw_aff_max);
2880 }
2881
2882 /* Mark the domains of "pwaff" as rational.
2883  */
2884 __isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff)
2885 {
2886         int i;
2887
2888         pwaff = isl_pw_aff_cow(pwaff);
2889         if (!pwaff)
2890                 return NULL;
2891         if (pwaff->n == 0)
2892                 return pwaff;
2893
2894         for (i = 0; i < pwaff->n; ++i) {
2895                 pwaff->p[i].set = isl_set_set_rational(pwaff->p[i].set);
2896                 if (!pwaff->p[i].set)
2897                         return isl_pw_aff_free(pwaff);
2898         }
2899
2900         return pwaff;
2901 }
2902
2903 /* Mark the domains of the elements of "list" as rational.
2904  */
2905 __isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational(
2906         __isl_take isl_pw_aff_list *list)
2907 {
2908         int i, n;
2909
2910         if (!list)
2911                 return NULL;
2912         if (list->n == 0)
2913                 return list;
2914
2915         n = list->n;
2916         for (i = 0; i < n; ++i) {
2917                 isl_pw_aff *pa;
2918
2919                 pa = isl_pw_aff_list_get_pw_aff(list, i);
2920                 pa = isl_pw_aff_set_rational(pa);
2921                 list = isl_pw_aff_list_set_pw_aff(list, i, pa);
2922         }
2923
2924         return list;
2925 }
2926
2927 /* Check that the domain space of "aff" matches "space".
2928  *
2929  * Return 0 on success and -1 on error.
2930  */
2931 int isl_aff_check_match_domain_space(__isl_keep isl_aff *aff,
2932         __isl_keep isl_space *space)
2933 {
2934         isl_space *aff_space;
2935         int match;
2936
2937         if (!aff || !space)
2938                 return -1;
2939
2940         aff_space = isl_aff_get_domain_space(aff);
2941
2942         match = isl_space_match(space, isl_dim_param, aff_space, isl_dim_param);
2943         if (match < 0)
2944                 goto error;
2945         if (!match)
2946                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2947                         "parameters don't match", goto error);
2948         match = isl_space_tuple_match(space, isl_dim_in,
2949                                         aff_space, isl_dim_set);
2950         if (match < 0)
2951                 goto error;
2952         if (!match)
2953                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2954                         "domains don't match", goto error);
2955         isl_space_free(aff_space);
2956         return 0;
2957 error:
2958         isl_space_free(aff_space);
2959         return -1;
2960 }
2961
2962 #undef BASE
2963 #define BASE aff
2964
2965 #include <isl_multi_templ.c>
2966
2967 /* Create an isl_pw_multi_aff with the given isl_multi_aff on a universe
2968  * domain.
2969  */
2970 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff(
2971         __isl_take isl_multi_aff *ma)
2972 {
2973         isl_set *dom = isl_set_universe(isl_multi_aff_get_domain_space(ma));
2974         return isl_pw_multi_aff_alloc(dom, ma);
2975 }
2976
2977 /* Create a piecewise multi-affine expression in the given space that maps each
2978  * input dimension to the corresponding output dimension.
2979  */
2980 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
2981         __isl_take isl_space *space)
2982 {
2983         return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space));
2984 }
2985
2986 __isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *maff1,
2987         __isl_take isl_multi_aff *maff2)
2988 {
2989         return isl_multi_aff_bin_op(maff1, maff2, &isl_aff_add);
2990 }
2991
2992 /* Subtract "ma2" from "ma1" and return the result.
2993  */
2994 __isl_give isl_multi_aff *isl_multi_aff_sub(__isl_take isl_multi_aff *ma1,
2995         __isl_take isl_multi_aff *ma2)
2996 {
2997         return isl_multi_aff_bin_op(ma1, ma2, &isl_aff_sub);
2998 }
2999
3000 /* Given two multi-affine expressions A -> B and C -> D,
3001  * construct a multi-affine expression [A -> C] -> [B -> D].
3002  */
3003 __isl_give isl_multi_aff *isl_multi_aff_product(
3004         __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
3005 {
3006         int i;
3007         isl_aff *aff;
3008         isl_space *space;
3009         isl_multi_aff *res;
3010         int in1, in2, out1, out2;
3011
3012         in1 = isl_multi_aff_dim(ma1, isl_dim_in);
3013         in2 = isl_multi_aff_dim(ma2, isl_dim_in);
3014         out1 = isl_multi_aff_dim(ma1, isl_dim_out);
3015         out2 = isl_multi_aff_dim(ma2, isl_dim_out);
3016         space = isl_space_product(isl_multi_aff_get_space(ma1),
3017                                   isl_multi_aff_get_space(ma2));
3018         res = isl_multi_aff_alloc(isl_space_copy(space));
3019         space = isl_space_domain(space);
3020
3021         for (i = 0; i < out1; ++i) {
3022                 aff = isl_multi_aff_get_aff(ma1, i);
3023                 aff = isl_aff_insert_dims(aff, isl_dim_in, in1, in2);
3024                 aff = isl_aff_reset_domain_space(aff, isl_space_copy(space));
3025                 res = isl_multi_aff_set_aff(res, i, aff);
3026         }
3027
3028         for (i = 0; i < out2; ++i) {
3029                 aff = isl_multi_aff_get_aff(ma2, i);
3030                 aff = isl_aff_insert_dims(aff, isl_dim_in, 0, in1);
3031                 aff = isl_aff_reset_domain_space(aff, isl_space_copy(space));
3032                 res = isl_multi_aff_set_aff(res, out1 + i, aff);
3033         }
3034
3035         isl_space_free(space);
3036         isl_multi_aff_free(ma1);
3037         isl_multi_aff_free(ma2);
3038         return res;
3039 }
3040
3041 /* Exploit the equalities in "eq" to simplify the affine expressions.
3042  */
3043 static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
3044         __isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq)
3045 {
3046         int i;
3047
3048         maff = isl_multi_aff_cow(maff);
3049         if (!maff || !eq)
3050                 goto error;
3051
3052         for (i = 0; i < maff->n; ++i) {
3053                 maff->p[i] = isl_aff_substitute_equalities(maff->p[i],
3054                                                     isl_basic_set_copy(eq));
3055                 if (!maff->p[i])
3056                         goto error;
3057         }
3058
3059         isl_basic_set_free(eq);
3060         return maff;
3061 error:
3062         isl_basic_set_free(eq);
3063         isl_multi_aff_free(maff);
3064         return NULL;
3065 }
3066
3067 __isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
3068         isl_int f)
3069 {
3070         int i;
3071
3072         maff = isl_multi_aff_cow(maff);
3073         if (!maff)
3074                 return NULL;
3075
3076         for (i = 0; i < maff->n; ++i) {
3077                 maff->p[i] = isl_aff_scale(maff->p[i], f);
3078                 if (!maff->p[i])
3079                         return isl_multi_aff_free(maff);
3080         }
3081
3082         return maff;
3083 }
3084
3085 __isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_set *dom,
3086         __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
3087 {
3088         maff1 = isl_multi_aff_add(maff1, maff2);
3089         maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
3090         return maff1;
3091 }
3092
3093 int isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
3094 {
3095         if (!maff)
3096                 return -1;
3097
3098         return 0;
3099 }
3100
3101 int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1,
3102         __isl_keep isl_multi_aff *maff2)
3103 {
3104         int i;
3105         int equal;
3106
3107         if (!maff1 || !maff2)
3108                 return -1;
3109         if (maff1->n != maff2->n)
3110                 return 0;
3111         equal = isl_space_is_equal(maff1->space, maff2->space);
3112         if (equal < 0 || !equal)
3113                 return equal;
3114
3115         for (i = 0; i < maff1->n; ++i) {
3116                 equal = isl_aff_plain_is_equal(maff1->p[i], maff2->p[i]);
3117                 if (equal < 0 || !equal)
3118                         return equal;
3119         }
3120
3121         return 1;
3122 }
3123
3124 /* Return the set of domain elements where "ma1" is lexicographically
3125  * smaller than or equal to "ma2".
3126  */
3127 __isl_give isl_set *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1,
3128         __isl_take isl_multi_aff *ma2)
3129 {
3130         return isl_multi_aff_lex_ge_set(ma2, ma1);
3131 }
3132
3133 /* Return the set of domain elements where "ma1" is lexicographically
3134  * greater than or equal to "ma2".
3135  */
3136 __isl_give isl_set *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1,
3137         __isl_take isl_multi_aff *ma2)
3138 {
3139         isl_space *space;
3140         isl_map *map1, *map2;
3141         isl_map *map, *ge;
3142
3143         map1 = isl_map_from_multi_aff(ma1);
3144         map2 = isl_map_from_multi_aff(ma2);
3145         map = isl_map_range_product(map1, map2);
3146         space = isl_space_range(isl_map_get_space(map));
3147         space = isl_space_domain(isl_space_unwrap(space));
3148         ge = isl_map_lex_ge(space);
3149         map = isl_map_intersect_range(map, isl_map_wrap(ge));
3150
3151         return isl_map_domain(map);
3152 }
3153
3154 #undef PW
3155 #define PW isl_pw_multi_aff
3156 #undef EL
3157 #define EL isl_multi_aff
3158 #undef EL_IS_ZERO
3159 #define EL_IS_ZERO is_empty
3160 #undef ZERO
3161 #define ZERO empty
3162 #undef IS_ZERO
3163 #define IS_ZERO is_empty
3164 #undef FIELD
3165 #define FIELD maff
3166 #undef DEFAULT_IS_ZERO
3167 #define DEFAULT_IS_ZERO 0
3168
3169 #define NO_NEG
3170 #define NO_EVAL
3171 #define NO_OPT
3172 #define NO_INVOLVES_DIMS
3173 #define NO_MOVE_DIMS
3174 #define NO_INSERT_DIMS
3175 #define NO_LIFT
3176 #define NO_MORPH
3177
3178 #include <isl_pw_templ.c>
3179
3180 #undef UNION
3181 #define UNION isl_union_pw_multi_aff
3182 #undef PART
3183 #define PART isl_pw_multi_aff
3184 #undef PARTS
3185 #define PARTS pw_multi_aff
3186 #define ALIGN_DOMAIN
3187
3188 #define NO_EVAL
3189
3190 #include <isl_union_templ.c>
3191
3192 /* Given a function "cmp" that returns the set of elements where
3193  * "ma1" is "better" than "ma2", return the intersection of this
3194  * set with "dom1" and "dom2".
3195  */
3196 static __isl_give isl_set *shared_and_better(__isl_keep isl_set *dom1,
3197         __isl_keep isl_set *dom2, __isl_keep isl_multi_aff *ma1,
3198         __isl_keep isl_multi_aff *ma2,
3199         __isl_give isl_set *(*cmp)(__isl_take isl_multi_aff *ma1,
3200                                     __isl_take isl_multi_aff *ma2))
3201 {
3202         isl_set *common;
3203         isl_set *better;
3204         int is_empty;
3205
3206         common = isl_set_intersect(isl_set_copy(dom1), isl_set_copy(dom2));
3207         is_empty = isl_set_plain_is_empty(common);
3208         if (is_empty >= 0 && is_empty)
3209                 return common;
3210         if (is_empty < 0)
3211                 return isl_set_free(common);
3212         better = cmp(isl_multi_aff_copy(ma1), isl_multi_aff_copy(ma2));
3213         better = isl_set_intersect(common, better);
3214
3215         return better;
3216 }
3217
3218 /* Given a function "cmp" that returns the set of elements where
3219  * "ma1" is "better" than "ma2", return a piecewise multi affine
3220  * expression defined on the union of the definition domains
3221  * of "pma1" and "pma2" that maps to the "best" of "pma1" and
3222  * "pma2" on each cell.  If only one of the two input functions
3223  * is defined on a given cell, then it is considered the best.
3224  */
3225 static __isl_give isl_pw_multi_aff *pw_multi_aff_union_opt(
3226         __isl_take isl_pw_multi_aff *pma1,
3227         __isl_take isl_pw_multi_aff *pma2,
3228         __isl_give isl_set *(*cmp)(__isl_take isl_multi_aff *ma1,
3229                                     __isl_take isl_multi_aff *ma2))
3230 {
3231         int i, j, n;
3232         isl_pw_multi_aff *res = NULL;
3233         isl_ctx *ctx;
3234         isl_set *set = NULL;
3235
3236         if (!pma1 || !pma2)
3237                 goto error;
3238
3239         ctx = isl_space_get_ctx(pma1->dim);
3240         if (!isl_space_is_equal(pma1->dim, pma2->dim))
3241                 isl_die(ctx, isl_error_invalid,
3242                         "arguments should live in the same space", goto error);
3243
3244         if (isl_pw_multi_aff_is_empty(pma1)) {
3245                 isl_pw_multi_aff_free(pma1);
3246                 return pma2;
3247         }
3248
3249         if (isl_pw_multi_aff_is_empty(pma2)) {
3250                 isl_pw_multi_aff_free(pma2);
3251                 return pma1;
3252         }
3253
3254         n = 2 * (pma1->n + 1) * (pma2->n + 1);
3255         res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma1->dim), n);
3256
3257         for (i = 0; i < pma1->n; ++i) {
3258                 set = isl_set_copy(pma1->p[i].set);
3259                 for (j = 0; j < pma2->n; ++j) {
3260                         isl_set *better;
3261                         int is_empty;
3262
3263                         better = shared_and_better(pma2->p[j].set,
3264                                         pma1->p[i].set, pma2->p[j].maff,
3265                                         pma1->p[i].maff, cmp);
3266                         is_empty = isl_set_plain_is_empty(better);
3267                         if (is_empty < 0 || is_empty) {
3268                                 isl_set_free(better);
3269                                 if (is_empty < 0)
3270                                         goto error;
3271                                 continue;
3272                         }
3273                         set = isl_set_subtract(set, isl_set_copy(better));
3274
3275                         res = isl_pw_multi_aff_add_piece(res, better,
3276                                         isl_multi_aff_copy(pma2->p[j].maff));
3277                 }
3278                 res = isl_pw_multi_aff_add_piece(res, set,
3279                                         isl_multi_aff_copy(pma1->p[i].maff));
3280         }
3281
3282         for (j = 0; j < pma2->n; ++j) {
3283                 set = isl_set_copy(pma2->p[j].set);
3284                 for (i = 0; i < pma1->n; ++i)
3285                         set = isl_set_subtract(set,
3286                                         isl_set_copy(pma1->p[i].set));
3287                 res = isl_pw_multi_aff_add_piece(res, set,
3288                                         isl_multi_aff_copy(pma2->p[j].maff));
3289         }
3290
3291         isl_pw_multi_aff_free(pma1);
3292         isl_pw_multi_aff_free(pma2);
3293
3294         return res;
3295 error:
3296         isl_pw_multi_aff_free(pma1);
3297         isl_pw_multi_aff_free(pma2);
3298         isl_set_free(set);
3299         return isl_pw_multi_aff_free(res);
3300 }
3301
3302 static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmax(
3303         __isl_take isl_pw_multi_aff *pma1,
3304         __isl_take isl_pw_multi_aff *pma2)
3305 {
3306         return pw_multi_aff_union_opt(pma1, pma2, &isl_multi_aff_lex_ge_set);
3307 }
3308
3309 /* Given two piecewise multi affine expressions, return a piecewise
3310  * multi-affine expression defined on the union of the definition domains
3311  * of the inputs that is equal to the lexicographic maximum of the two
3312  * inputs on each cell.  If only one of the two inputs is defined on
3313  * a given cell, then it is considered to be the maximum.
3314  */
3315 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax(
3316         __isl_take isl_pw_multi_aff *pma1,
3317         __isl_take isl_pw_multi_aff *pma2)
3318 {
3319         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
3320                                                     &pw_multi_aff_union_lexmax);
3321 }
3322
3323 static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmin(
3324         __isl_take isl_pw_multi_aff *pma1,
3325         __isl_take isl_pw_multi_aff *pma2)
3326 {
3327         return pw_multi_aff_union_opt(pma1, pma2, &isl_multi_aff_lex_le_set);
3328 }
3329
3330 /* Given two piecewise multi affine expressions, return a piecewise
3331  * multi-affine expression defined on the union of the definition domains
3332  * of the inputs that is equal to the lexicographic minimum of the two
3333  * inputs on each cell.  If only one of the two inputs is defined on
3334  * a given cell, then it is considered to be the minimum.
3335  */
3336 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin(
3337         __isl_take isl_pw_multi_aff *pma1,
3338         __isl_take isl_pw_multi_aff *pma2)
3339 {
3340         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
3341                                                     &pw_multi_aff_union_lexmin);
3342 }
3343
3344 static __isl_give isl_pw_multi_aff *pw_multi_aff_add(
3345         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3346 {
3347         return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
3348                                                 &isl_multi_aff_add);
3349 }
3350
3351 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
3352         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3353 {
3354         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
3355                                                 &pw_multi_aff_add);
3356 }
3357
3358 static __isl_give isl_pw_multi_aff *pw_multi_aff_sub(
3359         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3360 {
3361         return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
3362                                                 &isl_multi_aff_sub);
3363 }
3364
3365 /* Subtract "pma2" from "pma1" and return the result.
3366  */
3367 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub(
3368         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3369 {
3370         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
3371                                                 &pw_multi_aff_sub);
3372 }
3373
3374 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add(
3375         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3376 {
3377         return isl_pw_multi_aff_union_add_(pma1, pma2);
3378 }
3379
3380 /* Given two piecewise multi-affine expressions A -> B and C -> D,
3381  * construct a piecewise multi-affine expression [A -> C] -> [B -> D].
3382  */
3383 static __isl_give isl_pw_multi_aff *pw_multi_aff_product(
3384         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3385 {
3386         int i, j, n;
3387         isl_space *space;
3388         isl_pw_multi_aff *res;
3389
3390         if (!pma1 || !pma2)
3391                 goto error;
3392
3393         n = pma1->n * pma2->n;
3394         space = isl_space_product(isl_space_copy(pma1->dim),
3395                                   isl_space_copy(pma2->dim));
3396         res = isl_pw_multi_aff_alloc_size(space, n);
3397
3398         for (i = 0; i < pma1->n; ++i) {
3399                 for (j = 0; j < pma2->n; ++j) {
3400                         isl_set *domain;
3401                         isl_multi_aff *ma;
3402
3403                         domain = isl_set_product(isl_set_copy(pma1->p[i].set),
3404                                                  isl_set_copy(pma2->p[j].set));
3405                         ma = isl_multi_aff_product(
3406                                         isl_multi_aff_copy(pma1->p[i].maff),
3407                                         isl_multi_aff_copy(pma2->p[i].maff));
3408                         res = isl_pw_multi_aff_add_piece(res, domain, ma);
3409                 }
3410         }
3411
3412         isl_pw_multi_aff_free(pma1);
3413         isl_pw_multi_aff_free(pma2);
3414         return res;
3415 error:
3416         isl_pw_multi_aff_free(pma1);
3417         isl_pw_multi_aff_free(pma2);
3418         return NULL;
3419 }
3420
3421 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_product(
3422         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3423 {
3424         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
3425                                                 &pw_multi_aff_product);
3426 }
3427
3428 /* Construct a map mapping the domain of the piecewise multi-affine expression
3429  * to its range, with each dimension in the range equated to the
3430  * corresponding affine expression on its cell.
3431  */
3432 __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
3433 {
3434         int i;
3435         isl_map *map;
3436
3437         if (!pma)
3438                 return NULL;
3439
3440         map = isl_map_empty(isl_pw_multi_aff_get_space(pma));
3441
3442         for (i = 0; i < pma->n; ++i) {
3443                 isl_multi_aff *maff;
3444                 isl_basic_map *bmap;
3445                 isl_map *map_i;
3446
3447                 maff = isl_multi_aff_copy(pma->p[i].maff);
3448                 bmap = isl_basic_map_from_multi_aff(maff);
3449                 map_i = isl_map_from_basic_map(bmap);
3450                 map_i = isl_map_intersect_domain(map_i,
3451                                                 isl_set_copy(pma->p[i].set));
3452                 map = isl_map_union_disjoint(map, map_i);
3453         }
3454
3455         isl_pw_multi_aff_free(pma);
3456         return map;
3457 }
3458
3459 __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
3460 {
3461         if (!pma)
3462                 return NULL;
3463
3464         if (!isl_space_is_set(pma->dim))
3465                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
3466                         "isl_pw_multi_aff cannot be converted into an isl_set",
3467                         return isl_pw_multi_aff_free(pma));
3468
3469         return isl_map_from_pw_multi_aff(pma);
3470 }
3471
3472 /* Given a basic map with a single output dimension that is defined
3473  * in terms of the parameters and input dimensions using an equality,
3474  * extract an isl_aff that expresses the output dimension in terms
3475  * of the parameters and input dimensions.
3476  *
3477  * Since some applications expect the result of isl_pw_multi_aff_from_map
3478  * to only contain integer affine expressions, we compute the floor
3479  * of the expression before returning.
3480  *
3481  * This function shares some similarities with
3482  * isl_basic_map_has_defining_equality and isl_constraint_get_bound.
3483  */
3484 static __isl_give isl_aff *extract_isl_aff_from_basic_map(
3485         __isl_take isl_basic_map *bmap)
3486 {
3487         int i;
3488         unsigned offset;
3489         unsigned total;
3490         isl_local_space *ls;
3491         isl_aff *aff;
3492
3493         if (!bmap)
3494                 return NULL;
3495         if (isl_basic_map_dim(bmap, isl_dim_out) != 1)
3496                 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
3497                         "basic map should have a single output dimension",
3498                         goto error);
3499         offset = isl_basic_map_offset(bmap, isl_dim_out);
3500         total = isl_basic_map_total_dim(bmap);
3501         for (i = 0; i < bmap->n_eq; ++i) {
3502                 if (isl_int_is_zero(bmap->eq[i][offset]))
3503                         continue;
3504                 if (isl_seq_first_non_zero(bmap->eq[i] + offset + 1,
3505                                            1 + total - (offset + 1)) != -1)
3506                         continue;
3507                 break;
3508         }
3509         if (i >= bmap->n_eq)
3510                 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
3511                         "unable to find suitable equality", goto error);
3512         ls = isl_basic_map_get_local_space(bmap);
3513         aff = isl_aff_alloc(isl_local_space_domain(ls));
3514         if (!aff)
3515                 goto error;
3516         if (isl_int_is_neg(bmap->eq[i][offset]))
3517                 isl_seq_cpy(aff->v->el + 1, bmap->eq[i], offset);
3518         else
3519                 isl_seq_neg(aff->v->el + 1, bmap->eq[i], offset);
3520         isl_seq_clr(aff->v->el + 1 + offset, aff->v->size - (1 + offset));
3521         isl_int_abs(aff->v->el[0], bmap->eq[i][offset]);
3522         isl_basic_map_free(bmap);
3523
3524         aff = isl_aff_remove_unused_divs(aff);
3525         aff = isl_aff_floor(aff);
3526         return aff;
3527 error:
3528         isl_basic_map_free(bmap);
3529         return NULL;
3530 }
3531
3532 /* Given a basic map where each output dimension is defined
3533  * in terms of the parameters and input dimensions using an equality,
3534  * extract an isl_multi_aff that expresses the output dimensions in terms
3535  * of the parameters and input dimensions.
3536  */
3537 static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map(
3538         __isl_take isl_basic_map *bmap)
3539 {
3540         int i;
3541         unsigned n_out;
3542         isl_multi_aff *ma;
3543
3544         if (!bmap)
3545                 return NULL;
3546
3547         ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap));
3548         n_out = isl_basic_map_dim(bmap, isl_dim_out);
3549
3550         for (i = 0; i < n_out; ++i) {
3551                 isl_basic_map *bmap_i;
3552                 isl_aff *aff;
3553
3554                 bmap_i = isl_basic_map_copy(bmap);
3555                 bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out,
3556                                                         i + 1, n_out - (1 + i));
3557                 bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out, 0, i);
3558                 aff = extract_isl_aff_from_basic_map(bmap_i);
3559                 ma = isl_multi_aff_set_aff(ma, i, aff);
3560         }
3561
3562         isl_basic_map_free(bmap);
3563
3564         return ma;
3565 }
3566
3567 /* Create an isl_pw_multi_aff that is equivalent to
3568  * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain).
3569  * The given basic map is such that each output dimension is defined
3570  * in terms of the parameters and input dimensions using an equality.
3571  */
3572 static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
3573         __isl_take isl_set *domain, __isl_take isl_basic_map *bmap)
3574 {
3575         isl_multi_aff *ma;
3576
3577         ma = extract_isl_multi_aff_from_basic_map(bmap);
3578         return isl_pw_multi_aff_alloc(domain, ma);
3579 }
3580
3581 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
3582  * This obviously only works if the input "map" is single-valued.
3583  * If so, we compute the lexicographic minimum of the image in the form
3584  * of an isl_pw_multi_aff.  Since the image is unique, it is equal
3585  * to its lexicographic minimum.
3586  * If the input is not single-valued, we produce an error.
3587  */
3588 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_base(
3589         __isl_take isl_map *map)
3590 {
3591         int i;
3592         int sv;
3593         isl_pw_multi_aff *pma;
3594
3595         sv = isl_map_is_single_valued(map);
3596         if (sv < 0)
3597                 goto error;
3598         if (!sv)
3599                 isl_die(isl_map_get_ctx(map), isl_error_invalid,
3600                         "map is not single-valued", goto error);
3601         map = isl_map_make_disjoint(map);
3602         if (!map)
3603                 return NULL;
3604
3605         pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
3606
3607         for (i = 0; i < map->n; ++i) {
3608                 isl_pw_multi_aff *pma_i;
3609                 isl_basic_map *bmap;
3610                 bmap = isl_basic_map_copy(map->p[i]);
3611                 pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
3612                 pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
3613         }
3614
3615         isl_map_free(map);
3616         return pma;
3617 error:
3618         isl_map_free(map);
3619         return NULL;
3620 }
3621
3622 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
3623  * taking into account that the output dimension at position "d"
3624  * can be represented as
3625  *
3626  *      x = floor((e(...) + c1) / m)
3627  *
3628  * given that constraint "i" is of the form
3629  *
3630  *      e(...) + c1 - m x >= 0
3631  *
3632  *
3633  * Let "map" be of the form
3634  *
3635  *      A -> B
3636  *
3637  * We construct a mapping
3638  *
3639  *      A -> [A -> x = floor(...)]
3640  *
3641  * apply that to the map, obtaining
3642  *
3643  *      [A -> x = floor(...)] -> B
3644  *
3645  * and equate dimension "d" to x.
3646  * We then compute a isl_pw_multi_aff representation of the resulting map
3647  * and plug in the mapping above.
3648  */
3649 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div(
3650         __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i)
3651 {
3652         isl_ctx *ctx;
3653         isl_space *space;
3654         isl_local_space *ls;
3655         isl_multi_aff *ma;
3656         isl_aff *aff;
3657         isl_vec *v;
3658         isl_map *insert;
3659         int offset;
3660         int n;
3661         int n_in;
3662         isl_pw_multi_aff *pma;
3663         int is_set;
3664
3665         is_set = isl_map_is_set(map);
3666
3667         offset = isl_basic_map_offset(hull, isl_dim_out);
3668         ctx = isl_map_get_ctx(map);
3669         space = isl_space_domain(isl_map_get_space(map));
3670         n_in = isl_space_dim(space, isl_dim_set);
3671         n = isl_space_dim(space, isl_dim_all);
3672
3673         v = isl_vec_alloc(ctx, 1 + 1 + n);
3674         if (v) {
3675                 isl_int_neg(v->el[0], hull->ineq[i][offset + d]);
3676                 isl_seq_cpy(v->el + 1, hull->ineq[i], 1 + n);
3677         }
3678         isl_basic_map_free(hull);
3679
3680         ls = isl_local_space_from_space(isl_space_copy(space));
3681         aff = isl_aff_alloc_vec(ls, v);
3682         aff = isl_aff_floor(aff);
3683         if (is_set) {
3684                 isl_space_free(space);
3685                 ma = isl_multi_aff_from_aff(aff);
3686         } else {
3687                 ma = isl_multi_aff_identity(isl_space_map_from_set(space));
3688                 ma = isl_multi_aff_range_product(ma,
3689                                                 isl_multi_aff_from_aff(aff));
3690         }
3691
3692         insert = isl_map_from_multi_aff(isl_multi_aff_copy(ma));
3693         map = isl_map_apply_domain(map, insert);
3694         map = isl_map_equate(map, isl_dim_in, n_in, isl_dim_out, d);
3695         pma = isl_pw_multi_aff_from_map(map);
3696         pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma);
3697
3698         return pma;
3699 }
3700
3701 /* Is constraint "c" of the form
3702  *
3703  *      e(...) + c1 - m x >= 0
3704  *
3705  * or
3706  *
3707  *      -e(...) + c2 + m x >= 0
3708  *
3709  * where m > 1 and e only depends on parameters and input dimemnsions?
3710  *
3711  * "offset" is the offset of the output dimensions
3712  * "pos" is the position of output dimension x.
3713  */
3714 static int is_potential_div_constraint(isl_int *c, int offset, int d, int total)
3715 {
3716         if (isl_int_is_zero(c[offset + d]))
3717                 return 0;
3718         if (isl_int_is_one(c[offset + d]))
3719                 return 0;
3720         if (isl_int_is_negone(c[offset + d]))
3721                 return 0;
3722         if (isl_seq_first_non_zero(c + offset, d) != -1)
3723                 return 0;
3724         if (isl_seq_first_non_zero(c + offset + d + 1,
3725                                     total - (offset + d + 1)) != -1)
3726                 return 0;
3727         return 1;
3728 }
3729
3730 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
3731  *
3732  * As a special case, we first check if there is any pair of constraints,
3733  * shared by all the basic maps in "map" that force a given dimension
3734  * to be equal to the floor of some affine combination of the input dimensions.
3735  *
3736  * In particular, if we can find two constraints
3737  *
3738  *      e(...) + c1 - m x >= 0          i.e.,           m x <= e(...) + c1
3739  *
3740  * and
3741  *
3742  *      -e(...) + c2 + m x >= 0         i.e.,           m x >= e(...) - c2
3743  *
3744  * where m > 1 and e only depends on parameters and input dimemnsions,
3745  * and such that
3746  *
3747  *      c1 + c2 < m                     i.e.,           -c2 >= c1 - (m - 1)
3748  *
3749  * then we know that we can take
3750  *
3751  *      x = floor((e(...) + c1) / m)
3752  *
3753  * without having to perform any computation.
3754  *
3755  * Note that we know that
3756  *
3757  *      c1 + c2 >= 1
3758  *
3759  * If c1 + c2 were 0, then we would have detected an equality during
3760  * simplification.  If c1 + c2 were negative, then we would have detected
3761  * a contradiction.
3762  */
3763 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_div(
3764         __isl_take isl_map *map)
3765 {
3766         int d, dim;
3767         int i, j, n;
3768         int offset, total;
3769         isl_int sum;
3770         isl_basic_map *hull;
3771
3772         hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
3773         if (!hull)
3774                 goto error;
3775
3776         isl_int_init(sum);
3777         dim = isl_map_dim(map, isl_dim_out);
3778         offset = isl_basic_map_offset(hull, isl_dim_out);
3779         total = 1 + isl_basic_map_total_dim(hull);
3780         n = hull->n_ineq;
3781         for (d = 0; d < dim; ++d) {
3782                 for (i = 0; i < n; ++i) {
3783                         if (!is_potential_div_constraint(hull->ineq[i],
3784                                                         offset, d, total))
3785                                 continue;
3786                         for (j = i + 1; j < n; ++j) {
3787                                 if (!isl_seq_is_neg(hull->ineq[i] + 1,
3788                                                 hull->ineq[j] + 1, total - 1))
3789                                         continue;
3790                                 isl_int_add(sum, hull->ineq[i][0],
3791                                                 hull->ineq[j][0]);
3792                                 if (isl_int_abs_lt(sum,
3793                                                     hull->ineq[i][offset + d]))
3794                                         break;
3795
3796                         }
3797                         if (j >= n)
3798                                 continue;
3799                         isl_int_clear(sum);
3800                         if (isl_int_is_pos(hull->ineq[j][offset + d]))
3801                                 j = i;
3802                         return pw_multi_aff_from_map_div(map, hull, d, j);
3803                 }
3804         }
3805         isl_int_clear(sum);
3806         isl_basic_map_free(hull);
3807         return pw_multi_aff_from_map_base(map);
3808 error:
3809         isl_map_free(map);
3810         isl_basic_map_free(hull);
3811         return NULL;
3812 }
3813
3814 /* Given an affine expression
3815  *
3816  *      [A -> B] -> f(A,B)
3817  *
3818  * construct an isl_multi_aff
3819  *
3820  *      [A -> B] -> B'
3821  *
3822  * such that dimension "d" in B' is set to "aff" and the remaining
3823  * dimensions are set equal to the corresponding dimensions in B.
3824  * "n_in" is the dimension of the space A.
3825  * "n_out" is the dimension of the space B.
3826  *
3827  * If "is_set" is set, then the affine expression is of the form
3828  *
3829  *      [B] -> f(B)
3830  *
3831  * and we construct an isl_multi_aff
3832  *
3833  *      B -> B'
3834  */
3835 static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d,
3836         unsigned n_in, unsigned n_out, int is_set)
3837 {
3838         int i;
3839         isl_multi_aff *ma;
3840         isl_space *space, *space2;
3841         isl_local_space *ls;
3842
3843         space = isl_aff_get_domain_space(aff);
3844         ls = isl_local_space_from_space(isl_space_copy(space));
3845         space2 = isl_space_copy(space);
3846         if (!is_set)
3847                 space2 = isl_space_range(isl_space_unwrap(space2));
3848         space = isl_space_map_from_domain_and_range(space, space2);
3849         ma = isl_multi_aff_alloc(space);
3850         ma = isl_multi_aff_set_aff(ma, d, aff);
3851
3852         for (i = 0; i < n_out; ++i) {
3853                 if (i == d)
3854                         continue;
3855                 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
3856                                                 isl_dim_set, n_in + i);
3857                 ma = isl_multi_aff_set_aff(ma, i, aff);
3858         }
3859
3860         isl_local_space_free(ls);
3861
3862         return ma;
3863 }
3864
3865 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
3866  * taking into account that the dimension at position "d" can be written as
3867  *
3868  *      x = m a + f(..)                                         (1)
3869  *
3870  * where m is equal to "gcd".
3871  * "i" is the index of the equality in "hull" that defines f(..).
3872  * In particular, the equality is of the form
3873  *
3874  *      f(..) - x + m g(existentials) = 0
3875  *
3876  * or
3877  *
3878  *      -f(..) + x + m g(existentials) = 0
3879  *
3880  * We basically plug (1) into "map", resulting in a map with "a"
3881  * in the range instead of "x".  The corresponding isl_pw_multi_aff
3882  * defining "a" is then plugged back into (1) to obtain a definition fro "x".
3883  *
3884  * Specifically, given the input map
3885  *
3886  *      A -> B
3887  *
3888  * We first wrap it into a set
3889  *
3890  *      [A -> B]
3891  *
3892  * and define (1) on top of the corresponding space, resulting in "aff".
3893  * We use this to create an isl_multi_aff that maps the output position "d"
3894  * from "a" to "x", leaving all other (intput and output) dimensions unchanged.
3895  * We plug this into the wrapped map, unwrap the result and compute the
3896  * corresponding isl_pw_multi_aff.
3897  * The result is an expression
3898  *
3899  *      A -> T(A)
3900  *
3901  * We adjust that to
3902  *
3903  *      A -> [A -> T(A)]
3904  *
3905  * so that we can plug that into "aff", after extending the latter to
3906  * a mapping
3907  *
3908  *      [A -> B] -> B'
3909  *
3910  *
3911  * If "map" is actually a set, then there is no "A" space, meaning
3912  * that we do not need to perform any wrapping, and that the result
3913  * of the recursive call is of the form
3914  *
3915  *      [T]
3916  *
3917  * which is plugged into a mapping of the form
3918  *
3919  *      B -> B'
3920  */
3921 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride(
3922         __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i,
3923         isl_int gcd)
3924 {
3925         isl_set *set;
3926         isl_space *space;
3927         isl_local_space *ls;
3928         isl_aff *aff;
3929         isl_multi_aff *ma;
3930         isl_pw_multi_aff *pma, *id;
3931         unsigned n_in;
3932         unsigned o_out;
3933         unsigned n_out;
3934         int is_set;
3935
3936         is_set = isl_map_is_set(map);
3937
3938         n_in = isl_basic_map_dim(hull, isl_dim_in);
3939         n_out = isl_basic_map_dim(hull, isl_dim_out);
3940         o_out = isl_basic_map_offset(hull, isl_dim_out);
3941
3942         if (is_set)
3943                 set = map;
3944         else
3945                 set = isl_map_wrap(map);
3946         space = isl_space_map_from_set(isl_set_get_space(set));
3947         ma = isl_multi_aff_identity(space);
3948         ls = isl_local_space_from_space(isl_set_get_space(set));
3949         aff = isl_aff_alloc(ls);
3950         if (aff) {
3951                 isl_int_set_si(aff->v->el[0], 1);
3952                 if (isl_int_is_one(hull->eq[i][o_out + d]))
3953                         isl_seq_neg(aff->v->el + 1, hull->eq[i],
3954                                     aff->v->size - 1);
3955                 else
3956                         isl_seq_cpy(aff->v->el + 1, hull->eq[i],
3957                                     aff->v->size - 1);
3958                 isl_int_set(aff->v->el[1 + o_out + d], gcd);
3959         }
3960         ma = isl_multi_aff_set_aff(ma, n_in + d, isl_aff_copy(aff));
3961         set = isl_set_preimage_multi_aff(set, ma);
3962
3963         ma = range_map(aff, d, n_in, n_out, is_set);
3964
3965         if (is_set)
3966                 map = set;
3967         else
3968                 map = isl_set_unwrap(set);
3969         pma = isl_pw_multi_aff_from_map(set);
3970
3971         if (!is_set) {
3972                 space = isl_pw_multi_aff_get_domain_space(pma);
3973                 space = isl_space_map_from_set(space);
3974                 id = isl_pw_multi_aff_identity(space);
3975                 pma = isl_pw_multi_aff_range_product(id, pma);
3976         }
3977         id = isl_pw_multi_aff_from_multi_aff(ma);
3978         pma = isl_pw_multi_aff_pullback_pw_multi_aff(id, pma);
3979
3980         isl_basic_map_free(hull);
3981         return pma;
3982 }
3983
3984 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
3985  *
3986  * As a special case, we first check if all output dimensions are uniquely
3987  * defined in terms of the parameters and input dimensions over the entire
3988  * domain.  If so, we extract the desired isl_pw_multi_aff directly
3989  * from the affine hull of "map" and its domain.
3990  *
3991  * Otherwise, we check if any of the output dimensions is "strided".
3992  * That is, we check if can be written as
3993  *
3994  *      x = m a + f(..)
3995  *
3996  * with m greater than 1, a some combination of existentiall quantified
3997  * variables and f and expression in the parameters and input dimensions.
3998  * If so, we remove the stride in pw_multi_aff_from_map_stride.
3999  *
4000  * Otherwise, we continue with pw_multi_aff_from_map_check_div for a further
4001  * special case.
4002  */
4003 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
4004 {
4005         int i, j;
4006         int sv;
4007         isl_basic_map *hull;
4008         unsigned n_out;
4009         unsigned o_out;
4010         unsigned n_div;
4011         unsigned o_div;
4012         isl_int gcd;
4013
4014         if (!map)
4015                 return NULL;
4016
4017         hull = isl_map_affine_hull(isl_map_copy(map));
4018         sv = isl_basic_map_plain_is_single_valued(hull);
4019         if (sv >= 0 && sv)
4020                 return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
4021         if (sv < 0)
4022                 hull = isl_basic_map_free(hull);
4023         if (!hull)
4024                 goto error;
4025
4026         n_div = isl_basic_map_dim(hull, isl_dim_div);
4027         o_div = isl_basic_map_offset(hull, isl_dim_div);
4028
4029         if (n_div == 0) {
4030                 isl_basic_map_free(hull);
4031                 return pw_multi_aff_from_map_check_div(map);
4032         }
4033
4034         isl_int_init(gcd);
4035
4036         n_out = isl_basic_map_dim(hull, isl_dim_out);
4037         o_out = isl_basic_map_offset(hull, isl_dim_out);
4038
4039         for (i = 0; i < n_out; ++i) {
4040                 for (j = 0; j < hull->n_eq; ++j) {
4041                         isl_int *eq = hull->eq[j];
4042                         isl_pw_multi_aff *res;
4043
4044                         if (!isl_int_is_one(eq[o_out + i]) &&
4045                             !isl_int_is_negone(eq[o_out + i]))
4046                                 continue;
4047                         if (isl_seq_first_non_zero(eq + o_out, i) != -1)
4048                                 continue;
4049                         if (isl_seq_first_non_zero(eq + o_out + i + 1,
4050                                                     n_out - (i + 1)) != -1)
4051                                 continue;
4052                         isl_seq_gcd(eq + o_div, n_div, &gcd);
4053                         if (isl_int_is_zero(gcd))
4054                                 continue;
4055                         if (isl_int_is_one(gcd))
4056                                 continue;
4057
4058                         res = pw_multi_aff_from_map_stride(map, hull,
4059                                                                 i, j, gcd);
4060                         isl_int_clear(gcd);
4061                         return res;
4062                 }
4063         }
4064
4065         isl_int_clear(gcd);
4066         isl_basic_map_free(hull);
4067         return pw_multi_aff_from_map_check_div(map);
4068 error:
4069         isl_map_free(map);
4070         return NULL;
4071 }
4072
4073 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
4074 {
4075         return isl_pw_multi_aff_from_map(set);
4076 }
4077
4078 /* Convert "map" into an isl_pw_multi_aff (if possible) and
4079  * add it to *user.
4080  */
4081 static int pw_multi_aff_from_map(__isl_take isl_map *map, void *user)
4082 {
4083         isl_union_pw_multi_aff **upma = user;
4084         isl_pw_multi_aff *pma;
4085
4086         pma = isl_pw_multi_aff_from_map(map);
4087         *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
4088
4089         return *upma ? 0 : -1;
4090 }
4091
4092 /* Try and create an isl_union_pw_multi_aff that is equivalent
4093  * to the given isl_union_map.
4094  * The isl_union_map is required to be single-valued in each space.
4095  * Otherwise, an error is produced.
4096  */
4097 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map(
4098         __isl_take isl_union_map *umap)
4099 {
4100         isl_space *space;
4101         isl_union_pw_multi_aff *upma;
4102
4103         space = isl_union_map_get_space(umap);
4104         upma = isl_union_pw_multi_aff_empty(space);
4105         if (isl_union_map_foreach_map(umap, &pw_multi_aff_from_map, &upma) < 0)
4106                 upma = isl_union_pw_multi_aff_free(upma);
4107         isl_union_map_free(umap);
4108
4109         return upma;
4110 }
4111
4112 /* Try and create an isl_union_pw_multi_aff that is equivalent
4113  * to the given isl_union_set.
4114  * The isl_union_set is required to be a singleton in each space.
4115  * Otherwise, an error is produced.
4116  */
4117 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set(
4118         __isl_take isl_union_set *uset)
4119 {
4120         return isl_union_pw_multi_aff_from_union_map(uset);
4121 }
4122
4123 /* Return the piecewise affine expression "set ? 1 : 0".
4124  */
4125 __isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_set *set)
4126 {
4127         isl_pw_aff *pa;
4128         isl_space *space = isl_set_get_space(set);
4129         isl_local_space *ls = isl_local_space_from_space(space);
4130         isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls));
4131         isl_aff *one = isl_aff_zero_on_domain(ls);
4132
4133         one = isl_aff_add_constant_si(one, 1);
4134         pa = isl_pw_aff_alloc(isl_set_copy(set), one);
4135         set = isl_set_complement(set);
4136         pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero));
4137
4138         return pa;
4139 }
4140
4141 /* Plug in "subs" for dimension "type", "pos" of "aff".
4142  *
4143  * Let i be the dimension to replace and let "subs" be of the form
4144  *
4145  *      f/d
4146  *
4147  * and "aff" of the form
4148  *
4149  *      (a i + g)/m
4150  *
4151  * The result is
4152  *
4153  *      (a f + d g')/(m d)
4154  *
4155  * where g' is the result of plugging in "subs" in each of the integer
4156  * divisions in g.
4157  */
4158 __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
4159         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
4160 {
4161         isl_ctx *ctx;
4162         isl_int v;
4163
4164         aff = isl_aff_cow(aff);
4165         if (!aff || !subs)
4166                 return isl_aff_free(aff);
4167
4168         ctx = isl_aff_get_ctx(aff);
4169         if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
4170                 isl_die(ctx, isl_error_invalid,
4171                         "spaces don't match", return isl_aff_free(aff));
4172         if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
4173                 isl_die(ctx, isl_error_unsupported,
4174                         "cannot handle divs yet", return isl_aff_free(aff));
4175
4176         aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
4177         if (!aff->ls)
4178                 return isl_aff_free(aff);
4179
4180         aff->v = isl_vec_cow(aff->v);
4181         if (!aff->v)
4182                 return isl_aff_free(aff);
4183
4184         pos += isl_local_space_offset(aff->ls, type);
4185
4186         isl_int_init(v);
4187         isl_seq_substitute(aff->v->el, pos, subs->v->el,
4188                             aff->v->size, subs->v->size, v);
4189         isl_int_clear(v);
4190
4191         return aff;
4192 }
4193
4194 /* Plug in "subs" for dimension "type", "pos" in each of the affine
4195  * expressions in "maff".
4196  */
4197 __isl_give isl_multi_aff *isl_multi_aff_substitute(
4198         __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
4199         __isl_keep isl_aff *subs)
4200 {
4201         int i;
4202
4203         maff = isl_multi_aff_cow(maff);
4204         if (!maff || !subs)
4205                 return isl_multi_aff_free(maff);
4206
4207         if (type == isl_dim_in)
4208                 type = isl_dim_set;
4209
4210         for (i = 0; i < maff->n; ++i) {
4211                 maff->p[i] = isl_aff_substitute(maff->p[i], type, pos, subs);
4212                 if (!maff->p[i])
4213                         return isl_multi_aff_free(maff);
4214         }
4215
4216         return maff;
4217 }
4218
4219 /* Plug in "subs" for dimension "type", "pos" of "pma".
4220  *
4221  * pma is of the form
4222  *
4223  *      A_i(v) -> M_i(v)
4224  *
4225  * while subs is of the form
4226  *
4227  *      v' = B_j(v) -> S_j
4228  *
4229  * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
4230  * has a contribution in the result, in particular
4231  *
4232  *      C_ij(S_j) -> M_i(S_j)
4233  *
4234  * Note that plugging in S_j in C_ij may also result in an empty set
4235  * and this contribution should simply be discarded.
4236  */
4237 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
4238         __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
4239         __isl_keep isl_pw_aff *subs)
4240 {
4241         int i, j, n;
4242         isl_pw_multi_aff *res;
4243
4244         if (!pma || !subs)
4245                 return isl_pw_multi_aff_free(pma);
4246
4247         n = pma->n * subs->n;
4248         res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
4249
4250         for (i = 0; i < pma->n; ++i) {
4251                 for (j = 0; j < subs->n; ++j) {
4252                         isl_set *common;
4253                         isl_multi_aff *res_ij;
4254                         int empty;
4255
4256                         common = isl_set_intersect(
4257                                         isl_set_copy(pma->p[i].set),
4258                                         isl_set_copy(subs->p[j].set));
4259                         common = isl_set_substitute(common,
4260                                         type, pos, subs->p[j].aff);
4261                         empty = isl_set_plain_is_empty(common);
4262                         if (empty < 0 || empty) {
4263                                 isl_set_free(common);
4264                                 if (empty < 0)
4265                                         goto error;
4266                                 continue;
4267                         }
4268
4269                         res_ij = isl_multi_aff_substitute(
4270                                         isl_multi_aff_copy(pma->p[i].maff),
4271                                         type, pos, subs->p[j].aff);
4272
4273                         res = isl_pw_multi_aff_add_piece(res, common, res_ij);
4274                 }
4275         }
4276
4277         isl_pw_multi_aff_free(pma);
4278         return res;
4279 error:
4280         isl_pw_multi_aff_free(pma);
4281         isl_pw_multi_aff_free(res);
4282         return NULL;
4283 }
4284
4285 /* Compute the preimage of a range of dimensions in the affine expression "src"
4286  * under "ma" and put the result in "dst".  The number of dimensions in "src"
4287  * that precede the range is given by "n_before".  The number of dimensions
4288  * in the range is given by the number of output dimensions of "ma".
4289  * The number of dimensions that follow the range is given by "n_after".
4290  * If "has_denom" is set (to one),
4291  * then "src" and "dst" have an extra initial denominator.
4292  * "n_div_ma" is the number of existentials in "ma"
4293  * "n_div_bset" is the number of existentials in "src"
4294  * The resulting "dst" (which is assumed to have been allocated by
4295  * the caller) contains coefficients for both sets of existentials,
4296  * first those in "ma" and then those in "src".
4297  * f, c1, c2 and g are temporary objects that have been initialized
4298  * by the caller.
4299  *
4300  * Let src represent the expression
4301  *
4302  *      (a(p) + f_u u + b v + f_w w + c(divs))/d
4303  *
4304  * and let ma represent the expressions
4305  *
4306  *      v_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i
4307  *
4308  * We start out with the following expression for dst:
4309  *
4310  *      (a(p) + f_u u + 0 y + f_w w + 0 divs' + c(divs) + f \sum_i b_i v_i)/d
4311  *
4312  * with the multiplication factor f initially equal to 1
4313  * and f \sum_i b_i v_i kept separately.
4314  * For each x_i that we substitute, we multiply the numerator
4315  * (and denominator) of dst by c_1 = m_i and add the numerator
4316  * of the x_i expression multiplied by c_2 = f b_i,
4317  * after removing the common factors of c_1 and c_2.
4318  * The multiplication factor f also needs to be multiplied by c_1
4319  * for the next x_j, j > i.
4320  */
4321 void isl_seq_preimage(isl_int *dst, isl_int *src,
4322         __isl_keep isl_multi_aff *ma, int n_before, int n_after,
4323         int n_div_ma, int n_div_bmap,
4324         isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom)
4325 {
4326         int i;
4327         int n_param, n_in, n_out;
4328         int o_dst, o_src;
4329
4330         n_param = isl_multi_aff_dim(ma, isl_dim_param);
4331         n_in = isl_multi_aff_dim(ma, isl_dim_in);
4332         n_out = isl_multi_aff_dim(ma, isl_dim_out);
4333
4334         isl_seq_cpy(dst, src, has_denom + 1 + n_param + n_before);
4335         o_dst = o_src = has_denom + 1 + n_param + n_before;
4336         isl_seq_clr(dst + o_dst, n_in);
4337         o_dst += n_in;
4338         o_src += n_out;
4339         isl_seq_cpy(dst + o_dst, src + o_src, n_after);
4340         o_dst += n_after;
4341         o_src += n_after;
4342         isl_seq_clr(dst + o_dst, n_div_ma);
4343         o_dst += n_div_ma;
4344         isl_seq_cpy(dst + o_dst, src + o_src, n_div_bmap);
4345
4346         isl_int_set_si(f, 1);
4347
4348         for (i = 0; i < n_out; ++i) {
4349                 int offset = has_denom + 1 + n_param + n_before + i;
4350
4351                 if (isl_int_is_zero(src[offset]))
4352                         continue;
4353                 isl_int_set(c1, ma->p[i]->v->el[0]);
4354                 isl_int_mul(c2, f, src[offset]);
4355                 isl_int_gcd(g, c1, c2);
4356                 isl_int_divexact(c1, c1, g);
4357                 isl_int_divexact(c2, c2, g);
4358
4359                 isl_int_mul(f, f, c1);
4360                 o_dst = has_denom;
4361                 o_src = 1;
4362                 isl_seq_combine(dst + o_dst, c1, dst + o_dst,
4363                                 c2, ma->p[i]->v->el + o_src, 1 + n_param);
4364                 o_dst += 1 + n_param;
4365                 o_src += 1 + n_param;
4366                 isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_before);
4367                 o_dst += n_before;
4368                 isl_seq_combine(dst + o_dst, c1, dst + o_dst,
4369                                 c2, ma->p[i]->v->el + o_src, n_in);
4370                 o_dst += n_in;
4371                 o_src += n_in;
4372                 isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_after);
4373                 o_dst += n_after;
4374                 isl_seq_combine(dst + o_dst, c1, dst + o_dst,
4375                                 c2, ma->p[i]->v->el + o_src, n_div_ma);
4376                 o_dst += n_div_ma;
4377                 o_src += n_div_ma;
4378                 isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_div_bmap);
4379                 if (has_denom)
4380                         isl_int_mul(dst[0], dst[0], c1);
4381         }
4382 }
4383
4384 /* Compute the pullback of "aff" by the function represented by "ma".
4385  * In other words, plug in "ma" in "aff".  The result is an affine expression
4386  * defined over the domain space of "ma".
4387  *
4388  * If "aff" is represented by
4389  *
4390  *      (a(p) + b x + c(divs))/d
4391  *
4392  * and ma is represented by
4393  *
4394  *      x = D(p) + F(y) + G(divs')
4395  *
4396  * then the result is
4397  *
4398  *      (a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d
4399  *
4400  * The divs in the local space of the input are similarly adjusted
4401  * through a call to isl_local_space_preimage_multi_aff.
4402  */
4403 __isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff,
4404         __isl_take isl_multi_aff *ma)
4405 {
4406         isl_aff *res = NULL;
4407         isl_local_space *ls;
4408         int n_div_aff, n_div_ma;
4409         isl_int f, c1, c2, g;
4410
4411         ma = isl_multi_aff_align_divs(ma);
4412         if (!aff || !ma)
4413                 goto error;
4414
4415         n_div_aff = isl_aff_dim(aff, isl_dim_div);
4416         n_div_ma = ma->n ? isl_aff_dim(ma->p[0], isl_dim_div) : 0;
4417
4418         ls = isl_aff_get_domain_local_space(aff);
4419         ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma));
4420         res = isl_aff_alloc(ls);
4421         if (!res)
4422                 goto error;
4423
4424         isl_int_init(f);
4425         isl_int_init(c1);
4426         isl_int_init(c2);
4427         isl_int_init(g);
4428
4429         isl_seq_preimage(res->v->el, aff->v->el, ma, 0, 0, n_div_ma, n_div_aff,
4430                         f, c1, c2, g, 1);
4431
4432         isl_int_clear(f);
4433         isl_int_clear(c1);
4434         isl_int_clear(c2);
4435         isl_int_clear(g);
4436
4437         isl_aff_free(aff);
4438         isl_multi_aff_free(ma);
4439         res = isl_aff_normalize(res);
4440         return res;
4441 error:
4442         isl_aff_free(aff);
4443         isl_multi_aff_free(ma);
4444         isl_aff_free(res);
4445         return NULL;
4446 }
4447
4448 /* Compute the pullback of "ma1" by the function represented by "ma2".
4449  * In other words, plug in "ma2" in "ma1".
4450  */
4451 __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
4452         __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
4453 {
4454         int i;
4455         isl_space *space = NULL;
4456
4457         ma2 = isl_multi_aff_align_divs(ma2);
4458         ma1 = isl_multi_aff_cow(ma1);
4459         if (!ma1 || !ma2)
4460                 goto error;
4461
4462         space = isl_space_join(isl_multi_aff_get_space(ma2),
4463                                 isl_multi_aff_get_space(ma1));
4464
4465         for (i = 0; i < ma1->n; ++i) {
4466                 ma1->p[i] = isl_aff_pullback_multi_aff(ma1->p[i],
4467                                                     isl_multi_aff_copy(ma2));
4468                 if (!ma1->p[i])
4469                         goto error;
4470         }
4471
4472         ma1 = isl_multi_aff_reset_space(ma1, space);
4473         isl_multi_aff_free(ma2);
4474         return ma1;
4475 error:
4476         isl_space_free(space);
4477         isl_multi_aff_free(ma2);
4478         isl_multi_aff_free(ma1);
4479         return NULL;
4480 }
4481
4482 /* Extend the local space of "dst" to include the divs
4483  * in the local space of "src".
4484  */
4485 __isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
4486         __isl_keep isl_aff *src)
4487 {
4488         isl_ctx *ctx;
4489         int *exp1 = NULL;
4490         int *exp2 = NULL;
4491         isl_mat *div;
4492
4493         if (!src || !dst)
4494                 return isl_aff_free(dst);
4495
4496         ctx = isl_aff_get_ctx(src);
4497         if (!isl_space_is_equal(src->ls->dim, dst->ls->dim))
4498                 isl_die(ctx, isl_error_invalid,
4499                         "spaces don't match", goto error);
4500
4501         if (src->ls->div->n_row == 0)
4502                 return dst;
4503
4504         exp1 = isl_alloc_array(ctx, int, src->ls->div->n_row);
4505         exp2 = isl_alloc_array(ctx, int, dst->ls->div->n_row);
4506         if (!exp1 || !exp2)
4507                 goto error;
4508
4509         div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
4510         dst = isl_aff_expand_divs(dst, div, exp2);
4511         free(exp1);
4512         free(exp2);
4513
4514         return dst;
4515 error:
4516         free(exp1);
4517         free(exp2);
4518         return isl_aff_free(dst);
4519 }
4520
4521 /* Adjust the local spaces of the affine expressions in "maff"
4522  * such that they all have the save divs.
4523  */
4524 __isl_give isl_multi_aff *isl_multi_aff_align_divs(
4525         __isl_take isl_multi_aff *maff)
4526 {
4527         int i;
4528
4529         if (!maff)
4530                 return NULL;
4531         if (maff->n == 0)
4532                 return maff;
4533         maff = isl_multi_aff_cow(maff);
4534         if (!maff)
4535                 return NULL;
4536
4537         for (i = 1; i < maff->n; ++i)
4538                 maff->p[0] = isl_aff_align_divs(maff->p[0], maff->p[i]);
4539         for (i = 1; i < maff->n; ++i) {
4540                 maff->p[i] = isl_aff_align_divs(maff->p[i], maff->p[0]);
4541                 if (!maff->p[i])
4542                         return isl_multi_aff_free(maff);
4543         }
4544
4545         return maff;
4546 }
4547
4548 __isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
4549 {
4550         aff = isl_aff_cow(aff);
4551         if (!aff)
4552                 return NULL;
4553
4554         aff->ls = isl_local_space_lift(aff->ls);
4555         if (!aff->ls)
4556                 return isl_aff_free(aff);
4557
4558         return aff;
4559 }
4560
4561 /* Lift "maff" to a space with extra dimensions such that the result
4562  * has no more existentially quantified variables.
4563  * If "ls" is not NULL, then *ls is assigned the local space that lies
4564  * at the basis of the lifting applied to "maff".
4565  */
4566 __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
4567         __isl_give isl_local_space **ls)
4568 {
4569         int i;
4570         isl_space *space;
4571         unsigned n_div;
4572
4573         if (ls)
4574                 *ls = NULL;
4575
4576         if (!maff)
4577                 return NULL;
4578
4579         if (maff->n == 0) {
4580                 if (ls) {
4581                         isl_space *space = isl_multi_aff_get_domain_space(maff);
4582                         *ls = isl_local_space_from_space(space);
4583                         if (!*ls)
4584                                 return isl_multi_aff_free(maff);
4585                 }
4586                 return maff;
4587         }
4588
4589         maff = isl_multi_aff_cow(maff);
4590         maff = isl_multi_aff_align_divs(maff);
4591         if (!maff)
4592                 return NULL;
4593
4594         n_div = isl_aff_dim(maff->p[0], isl_dim_div);
4595         space = isl_multi_aff_get_space(maff);
4596         space = isl_space_lift(isl_space_domain(space), n_div);
4597         space = isl_space_extend_domain_with_range(space,
4598                                                 isl_multi_aff_get_space(maff));
4599         if (!space)
4600                 return isl_multi_aff_free(maff);
4601         isl_space_free(maff->space);
4602         maff->space = space;
4603
4604         if (ls) {
4605                 *ls = isl_aff_get_domain_local_space(maff->p[0]);
4606                 if (!*ls)
4607                         return isl_multi_aff_free(maff);
4608         }
4609
4610         for (i = 0; i < maff->n; ++i) {
4611                 maff->p[i] = isl_aff_lift(maff->p[i]);
4612                 if (!maff->p[i])
4613                         goto error;
4614         }
4615
4616         return maff;
4617 error:
4618         if (ls)
4619                 isl_local_space_free(*ls);
4620         return isl_multi_aff_free(maff);
4621 }
4622
4623
4624 /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
4625  */
4626 __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
4627         __isl_keep isl_pw_multi_aff *pma, int pos)
4628 {
4629         int i;
4630         int n_out;
4631         isl_space *space;
4632         isl_pw_aff *pa;
4633
4634         if (!pma)
4635                 return NULL;
4636
4637         n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
4638         if (pos < 0 || pos >= n_out)
4639                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4640                         "index out of bounds", return NULL);
4641
4642         space = isl_pw_multi_aff_get_space(pma);
4643         space = isl_space_drop_dims(space, isl_dim_out,
4644                                     pos + 1, n_out - pos - 1);
4645         space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
4646
4647         pa = isl_pw_aff_alloc_size(space, pma->n);
4648         for (i = 0; i < pma->n; ++i) {
4649                 isl_aff *aff;
4650                 aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
4651                 pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
4652         }
4653
4654         return pa;
4655 }
4656
4657 /* Return an isl_pw_multi_aff with the given "set" as domain and
4658  * an unnamed zero-dimensional range.
4659  */
4660 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain(
4661         __isl_take isl_set *set)
4662 {
4663         isl_multi_aff *ma;
4664         isl_space *space;
4665
4666         space = isl_set_get_space(set);
4667         space = isl_space_from_domain(space);
4668         ma = isl_multi_aff_zero(space);
4669         return isl_pw_multi_aff_alloc(set, ma);
4670 }
4671
4672 /* Add an isl_pw_multi_aff with the given "set" as domain and
4673  * an unnamed zero-dimensional range to *user.
4674  */
4675 static int add_pw_multi_aff_from_domain(__isl_take isl_set *set, void *user)
4676 {
4677         isl_union_pw_multi_aff **upma = user;
4678         isl_pw_multi_aff *pma;
4679
4680         pma = isl_pw_multi_aff_from_domain(set);
4681         *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
4682
4683         return 0;
4684 }
4685
4686 /* Return an isl_union_pw_multi_aff with the given "uset" as domain and
4687  * an unnamed zero-dimensional range.
4688  */
4689 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
4690         __isl_take isl_union_set *uset)
4691 {
4692         isl_space *space;
4693         isl_union_pw_multi_aff *upma;
4694
4695         if (!uset)
4696                 return NULL;
4697
4698         space = isl_union_set_get_space(uset);
4699         upma = isl_union_pw_multi_aff_empty(space);
4700
4701         if (isl_union_set_foreach_set(uset,
4702                                     &add_pw_multi_aff_from_domain, &upma) < 0)
4703                 goto error;
4704
4705         isl_union_set_free(uset);
4706         return upma;
4707 error:
4708         isl_union_set_free(uset);
4709         isl_union_pw_multi_aff_free(upma);
4710         return NULL;
4711 }
4712
4713 /* Convert "pma" to an isl_map and add it to *umap.
4714  */
4715 static int map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma, void *user)
4716 {
4717         isl_union_map **umap = user;
4718         isl_map *map;
4719
4720         map = isl_map_from_pw_multi_aff(pma);
4721         *umap = isl_union_map_add_map(*umap, map);
4722
4723         return 0;
4724 }
4725
4726 /* Construct a union map mapping the domain of the union
4727  * piecewise multi-affine expression to its range, with each dimension
4728  * in the range equated to the corresponding affine expression on its cell.
4729  */
4730 __isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff(
4731         __isl_take isl_union_pw_multi_aff *upma)
4732 {
4733         isl_space *space;
4734         isl_union_map *umap;
4735
4736         if (!upma)
4737                 return NULL;
4738
4739         space = isl_union_pw_multi_aff_get_space(upma);
4740         umap = isl_union_map_empty(space);
4741
4742         if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
4743                                         &map_from_pw_multi_aff, &umap) < 0)
4744                 goto error;
4745
4746         isl_union_pw_multi_aff_free(upma);
4747         return umap;
4748 error:
4749         isl_union_pw_multi_aff_free(upma);
4750         isl_union_map_free(umap);
4751         return NULL;
4752 }
4753
4754 /* Local data for bin_entry and the callback "fn".
4755  */
4756 struct isl_union_pw_multi_aff_bin_data {
4757         isl_union_pw_multi_aff *upma2;
4758         isl_union_pw_multi_aff *res;
4759         isl_pw_multi_aff *pma;
4760         int (*fn)(void **entry, void *user);
4761 };
4762
4763 /* Given an isl_pw_multi_aff from upma1, store it in data->pma
4764  * and call data->fn for each isl_pw_multi_aff in data->upma2.
4765  */
4766 static int bin_entry(void **entry, void *user)
4767 {
4768         struct isl_union_pw_multi_aff_bin_data *data = user;
4769         isl_pw_multi_aff *pma = *entry;
4770
4771         data->pma = pma;
4772         if (isl_hash_table_foreach(data->upma2->dim->ctx, &data->upma2->table,
4773                                    data->fn, data) < 0)
4774                 return -1;
4775
4776         return 0;
4777 }
4778
4779 /* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2".
4780  * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is
4781  * passed as user field) and the isl_pw_multi_aff from upma2 is available
4782  * as *entry.  The callback should adjust data->res if desired.
4783  */
4784 static __isl_give isl_union_pw_multi_aff *bin_op(
4785         __isl_take isl_union_pw_multi_aff *upma1,
4786         __isl_take isl_union_pw_multi_aff *upma2,
4787         int (*fn)(void **entry, void *user))
4788 {
4789         isl_space *space;
4790         struct isl_union_pw_multi_aff_bin_data data = { NULL, NULL, NULL, fn };
4791
4792         space = isl_union_pw_multi_aff_get_space(upma2);
4793         upma1 = isl_union_pw_multi_aff_align_params(upma1, space);
4794         space = isl_union_pw_multi_aff_get_space(upma1);
4795         upma2 = isl_union_pw_multi_aff_align_params(upma2, space);
4796
4797         if (!upma1 || !upma2)
4798                 goto error;
4799
4800         data.upma2 = upma2;
4801         data.res = isl_union_pw_multi_aff_alloc(isl_space_copy(upma1->dim),
4802                                        upma1->table.n);
4803         if (isl_hash_table_foreach(upma1->dim->ctx, &upma1->table,
4804                                    &bin_entry, &data) < 0)
4805                 goto error;
4806
4807         isl_union_pw_multi_aff_free(upma1);
4808         isl_union_pw_multi_aff_free(upma2);
4809         return data.res;
4810 error:
4811         isl_union_pw_multi_aff_free(upma1);
4812         isl_union_pw_multi_aff_free(upma2);
4813         isl_union_pw_multi_aff_free(data.res);
4814         return NULL;
4815 }
4816
4817 /* Given two aligned isl_pw_multi_affs A -> B and C -> D,
4818  * construct an isl_pw_multi_aff (A * C) -> [B -> D].
4819  */
4820 static __isl_give isl_pw_multi_aff *pw_multi_aff_range_product(
4821         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4822 {
4823         isl_space *space;
4824
4825         space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
4826                                         isl_pw_multi_aff_get_space(pma2));
4827         return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
4828                                             &isl_multi_aff_range_product);
4829 }
4830
4831 /* Given two isl_pw_multi_affs A -> B and C -> D,
4832  * construct an isl_pw_multi_aff (A * C) -> [B -> D].
4833  */
4834 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product(
4835         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4836 {
4837         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4838                                             &pw_multi_aff_range_product);
4839 }
4840
4841 /* Given two aligned isl_pw_multi_affs A -> B and C -> D,
4842  * construct an isl_pw_multi_aff (A * C) -> (B, D).
4843  */
4844 static __isl_give isl_pw_multi_aff *pw_multi_aff_flat_range_product(
4845         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4846 {
4847         isl_space *space;
4848
4849         space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
4850                                         isl_pw_multi_aff_get_space(pma2));
4851         space = isl_space_flatten_range(space);
4852         return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
4853                                             &isl_multi_aff_flat_range_product);
4854 }
4855
4856 /* Given two isl_pw_multi_affs A -> B and C -> D,
4857  * construct an isl_pw_multi_aff (A * C) -> (B, D).
4858  */
4859 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product(
4860         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4861 {
4862         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4863                                             &pw_multi_aff_flat_range_product);
4864 }
4865
4866 /* If data->pma and *entry have the same domain space, then compute
4867  * their flat range product and the result to data->res.
4868  */
4869 static int flat_range_product_entry(void **entry, void *user)
4870 {
4871         struct isl_union_pw_multi_aff_bin_data *data = user;
4872         isl_pw_multi_aff *pma2 = *entry;
4873
4874         if (!isl_space_tuple_match(data->pma->dim, isl_dim_in,
4875                                  pma2->dim, isl_dim_in))
4876                 return 0;
4877
4878         pma2 = isl_pw_multi_aff_flat_range_product(
4879                                         isl_pw_multi_aff_copy(data->pma),
4880                                         isl_pw_multi_aff_copy(pma2));
4881
4882         data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
4883
4884         return 0;
4885 }
4886
4887 /* Given two isl_union_pw_multi_affs A -> B and C -> D,
4888  * construct an isl_union_pw_multi_aff (A * C) -> (B, D).
4889  */
4890 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product(
4891         __isl_take isl_union_pw_multi_aff *upma1,
4892         __isl_take isl_union_pw_multi_aff *upma2)
4893 {
4894         return bin_op(upma1, upma2, &flat_range_product_entry);
4895 }
4896
4897 /* Replace the affine expressions at position "pos" in "pma" by "pa".
4898  * The parameters are assumed to have been aligned.
4899  *
4900  * The implementation essentially performs an isl_pw_*_on_shared_domain,
4901  * except that it works on two different isl_pw_* types.
4902  */
4903 static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff(
4904         __isl_take isl_pw_multi_aff *pma, unsigned pos,
4905         __isl_take isl_pw_aff *pa)
4906 {
4907         int i, j, n;
4908         isl_pw_multi_aff *res = NULL;
4909
4910         if (!pma || !pa)
4911                 goto error;
4912
4913         if (!isl_space_tuple_match(pma->dim, isl_dim_in, pa->dim, isl_dim_in))
4914                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4915                         "domains don't match", goto error);
4916         if (pos >= isl_pw_multi_aff_dim(pma, isl_dim_out))
4917                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4918                         "index out of bounds", goto error);
4919
4920         n = pma->n * pa->n;
4921         res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n);
4922
4923         for (i = 0; i < pma->n; ++i) {
4924                 for (j = 0; j < pa->n; ++j) {
4925                         isl_set *common;
4926                         isl_multi_aff *res_ij;
4927                         int empty;
4928
4929                         common = isl_set_intersect(isl_set_copy(pma->p[i].set),
4930                                                    isl_set_copy(pa->p[j].set));
4931                         empty = isl_set_plain_is_empty(common);
4932                         if (empty < 0 || empty) {
4933                                 isl_set_free(common);
4934                                 if (empty < 0)
4935                                         goto error;
4936                                 continue;
4937                         }
4938
4939                         res_ij = isl_multi_aff_set_aff(
4940                                         isl_multi_aff_copy(pma->p[i].maff), pos,
4941                                         isl_aff_copy(pa->p[j].aff));
4942                         res_ij = isl_multi_aff_gist(res_ij,
4943                                         isl_set_copy(common));
4944
4945                         res = isl_pw_multi_aff_add_piece(res, common, res_ij);
4946                 }
4947         }
4948
4949         isl_pw_multi_aff_free(pma);
4950         isl_pw_aff_free(pa);
4951         return res;
4952 error:
4953         isl_pw_multi_aff_free(pma);
4954         isl_pw_aff_free(pa);
4955         return isl_pw_multi_aff_free(res);
4956 }
4957
4958 /* Replace the affine expressions at position "pos" in "pma" by "pa".
4959  */
4960 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff(
4961         __isl_take isl_pw_multi_aff *pma, unsigned pos,
4962         __isl_take isl_pw_aff *pa)
4963 {
4964         if (!pma || !pa)
4965                 goto error;
4966         if (isl_space_match(pma->dim, isl_dim_param, pa->dim, isl_dim_param))
4967                 return pw_multi_aff_set_pw_aff(pma, pos, pa);
4968         if (!isl_space_has_named_params(pma->dim) ||
4969             !isl_space_has_named_params(pa->dim))
4970                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4971                         "unaligned unnamed parameters", goto error);
4972         pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa));
4973         pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma));
4974         return pw_multi_aff_set_pw_aff(pma, pos, pa);
4975 error:
4976         isl_pw_multi_aff_free(pma);
4977         isl_pw_aff_free(pa);
4978         return NULL;
4979 }
4980
4981 /* Check that the domain space of "pa" matches "space".
4982  *
4983  * Return 0 on success and -1 on error.
4984  */
4985 int isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa,
4986         __isl_keep isl_space *space)
4987 {
4988         isl_space *pa_space;
4989         int match;
4990
4991         if (!pa || !space)
4992                 return -1;
4993
4994         pa_space = isl_pw_aff_get_space(pa);
4995
4996         match = isl_space_match(space, isl_dim_param, pa_space, isl_dim_param);
4997         if (match < 0)
4998                 goto error;
4999         if (!match)
5000                 isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
5001                         "parameters don't match", goto error);
5002         match = isl_space_tuple_match(space, isl_dim_in, pa_space, isl_dim_in);
5003         if (match < 0)
5004                 goto error;
5005         if (!match)
5006                 isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
5007                         "domains don't match", goto error);
5008         isl_space_free(pa_space);
5009         return 0;
5010 error:
5011         isl_space_free(pa_space);
5012         return -1;
5013 }
5014
5015 #undef BASE
5016 #define BASE pw_aff
5017
5018 #include <isl_multi_templ.c>
5019
5020 /* Scale the first elements of "ma" by the corresponding elements of "vec".
5021  */
5022 __isl_give isl_multi_aff *isl_multi_aff_scale_vec(__isl_take isl_multi_aff *ma,
5023         __isl_take isl_vec *vec)
5024 {
5025         int i, n;
5026         isl_int v;
5027
5028         if (!ma || !vec)
5029                 goto error;
5030
5031         n = isl_multi_aff_dim(ma, isl_dim_out);
5032         if (isl_vec_size(vec) < n)
5033                 n = isl_vec_size(vec);
5034
5035         isl_int_init(v);
5036         for (i = 0; i < n; ++i) {
5037                 isl_aff *aff;
5038
5039                 isl_vec_get_element(vec, i, &v);
5040
5041                 aff = isl_multi_aff_get_aff(ma, i);
5042                 aff = isl_aff_scale(aff, v);
5043                 ma = isl_multi_aff_set_aff(ma, i, aff);
5044         }
5045         isl_int_clear(v);
5046
5047         isl_vec_free(vec);
5048         return ma;
5049 error:
5050         isl_vec_free(vec);
5051         isl_multi_aff_free(ma);
5052         return NULL;
5053 }
5054
5055 /* Scale the first elements of "pma" by the corresponding elements of "vec".
5056  */
5057 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_vec(
5058         __isl_take isl_pw_multi_aff *pma, __isl_take isl_vec *v)
5059 {
5060         int i;
5061
5062         pma = isl_pw_multi_aff_cow(pma);
5063         if (!pma || !v)
5064                 goto error;
5065
5066         for (i = 0; i < pma->n; ++i) {
5067                 pma->p[i].maff = isl_multi_aff_scale_vec(pma->p[i].maff,
5068                                                         isl_vec_copy(v));
5069                 if (!pma->p[i].maff)
5070                         goto error;
5071         }
5072
5073         isl_vec_free(v);
5074         return pma;
5075 error:
5076         isl_vec_free(v);
5077         isl_pw_multi_aff_free(pma);
5078         return NULL;
5079 }
5080
5081 /* This function is called for each entry of an isl_union_pw_multi_aff.
5082  * Replace the entry by the result of applying isl_pw_multi_aff_scale_vec
5083  * to the original entry with the isl_vec in "user" as extra argument.
5084  */
5085 static int union_pw_multi_aff_scale_vec_entry(void **entry, void *user)
5086 {
5087         isl_pw_multi_aff **pma = (isl_pw_multi_aff **) entry;
5088         isl_vec *v = user;
5089
5090         *pma = isl_pw_multi_aff_scale_vec(*pma, isl_vec_copy(v));
5091         if (!*pma)
5092                 return -1;
5093
5094         return 0;
5095 }
5096
5097 /* Scale the first elements of "upma" by the corresponding elements of "vec".
5098  */
5099 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_vec(
5100         __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_vec *v)
5101 {
5102         upma = isl_union_pw_multi_aff_cow(upma);
5103         if (!upma || !v)
5104                 goto error;
5105
5106         if (isl_hash_table_foreach(upma->dim->ctx, &upma->table,
5107                                    &union_pw_multi_aff_scale_vec_entry, v) < 0)
5108                 goto error;
5109
5110         isl_vec_free(v);
5111         return upma;
5112 error:
5113         isl_vec_free(v);
5114         isl_union_pw_multi_aff_free(upma);
5115         return NULL;
5116 }