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