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