add isl_multi_aff_pullback_multi_aff
[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  * As a special case, we first check if all output dimensions are uniquely
3213  * defined in terms of the parameters and input dimensions over the entire
3214  * domain.  If so, we extract the desired isl_pw_multi_aff directly
3215  * from the affine hull of "map" and its domain.
3216  */
3217 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
3218 {
3219         int i;
3220         int sv;
3221         isl_pw_multi_aff *pma;
3222         isl_basic_map *hull;
3223
3224         if (!map)
3225                 return NULL;
3226
3227         hull = isl_map_affine_hull(isl_map_copy(map));
3228         sv = isl_basic_map_plain_is_single_valued(hull);
3229         if (sv >= 0 && sv)
3230                 return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
3231         isl_basic_map_free(hull);
3232         if (sv < 0)
3233                 goto error;
3234
3235         sv = isl_map_is_single_valued(map);
3236         if (sv < 0)
3237                 goto error;
3238         if (!sv)
3239                 isl_die(isl_map_get_ctx(map), isl_error_invalid,
3240                         "map is not single-valued", goto error);
3241         map = isl_map_make_disjoint(map);
3242         if (!map)
3243                 return NULL;
3244
3245         pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
3246
3247         for (i = 0; i < map->n; ++i) {
3248                 isl_pw_multi_aff *pma_i;
3249                 isl_basic_map *bmap;
3250                 bmap = isl_basic_map_copy(map->p[i]);
3251                 pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
3252                 pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
3253         }
3254
3255         isl_map_free(map);
3256         return pma;
3257 error:
3258         isl_map_free(map);
3259         return NULL;
3260 }
3261
3262 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
3263 {
3264         return isl_pw_multi_aff_from_map(set);
3265 }
3266
3267 /* Return the piecewise affine expression "set ? 1 : 0".
3268  */
3269 __isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_set *set)
3270 {
3271         isl_pw_aff *pa;
3272         isl_space *space = isl_set_get_space(set);
3273         isl_local_space *ls = isl_local_space_from_space(space);
3274         isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls));
3275         isl_aff *one = isl_aff_zero_on_domain(ls);
3276
3277         one = isl_aff_add_constant_si(one, 1);
3278         pa = isl_pw_aff_alloc(isl_set_copy(set), one);
3279         set = isl_set_complement(set);
3280         pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero));
3281
3282         return pa;
3283 }
3284
3285 /* Plug in "subs" for dimension "type", "pos" of "aff".
3286  *
3287  * Let i be the dimension to replace and let "subs" be of the form
3288  *
3289  *      f/d
3290  *
3291  * and "aff" of the form
3292  *
3293  *      (a i + g)/m
3294  *
3295  * The result is
3296  *
3297  *      (a f + d g')/(m d)
3298  *
3299  * where g' is the result of plugging in "subs" in each of the integer
3300  * divisions in g.
3301  */
3302 __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
3303         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
3304 {
3305         isl_ctx *ctx;
3306         isl_int v;
3307
3308         aff = isl_aff_cow(aff);
3309         if (!aff || !subs)
3310                 return isl_aff_free(aff);
3311
3312         ctx = isl_aff_get_ctx(aff);
3313         if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
3314                 isl_die(ctx, isl_error_invalid,
3315                         "spaces don't match", return isl_aff_free(aff));
3316         if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
3317                 isl_die(ctx, isl_error_unsupported,
3318                         "cannot handle divs yet", return isl_aff_free(aff));
3319
3320         aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
3321         if (!aff->ls)
3322                 return isl_aff_free(aff);
3323
3324         aff->v = isl_vec_cow(aff->v);
3325         if (!aff->v)
3326                 return isl_aff_free(aff);
3327
3328         pos += isl_local_space_offset(aff->ls, type);
3329
3330         isl_int_init(v);
3331         isl_seq_substitute(aff->v->el, pos, subs->v->el,
3332                             aff->v->size, subs->v->size, v);
3333         isl_int_clear(v);
3334
3335         return aff;
3336 }
3337
3338 /* Plug in "subs" for dimension "type", "pos" in each of the affine
3339  * expressions in "maff".
3340  */
3341 __isl_give isl_multi_aff *isl_multi_aff_substitute(
3342         __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
3343         __isl_keep isl_aff *subs)
3344 {
3345         int i;
3346
3347         maff = isl_multi_aff_cow(maff);
3348         if (!maff || !subs)
3349                 return isl_multi_aff_free(maff);
3350
3351         if (type == isl_dim_in)
3352                 type = isl_dim_set;
3353
3354         for (i = 0; i < maff->n; ++i) {
3355                 maff->p[i] = isl_aff_substitute(maff->p[i], type, pos, subs);
3356                 if (!maff->p[i])
3357                         return isl_multi_aff_free(maff);
3358         }
3359
3360         return maff;
3361 }
3362
3363 /* Plug in "subs" for dimension "type", "pos" of "pma".
3364  *
3365  * pma is of the form
3366  *
3367  *      A_i(v) -> M_i(v)
3368  *
3369  * while subs is of the form
3370  *
3371  *      v' = B_j(v) -> S_j
3372  *
3373  * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
3374  * has a contribution in the result, in particular
3375  *
3376  *      C_ij(S_j) -> M_i(S_j)
3377  *
3378  * Note that plugging in S_j in C_ij may also result in an empty set
3379  * and this contribution should simply be discarded.
3380  */
3381 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
3382         __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
3383         __isl_keep isl_pw_aff *subs)
3384 {
3385         int i, j, n;
3386         isl_pw_multi_aff *res;
3387
3388         if (!pma || !subs)
3389                 return isl_pw_multi_aff_free(pma);
3390
3391         n = pma->n * subs->n;
3392         res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
3393
3394         for (i = 0; i < pma->n; ++i) {
3395                 for (j = 0; j < subs->n; ++j) {
3396                         isl_set *common;
3397                         isl_multi_aff *res_ij;
3398                         common = isl_set_intersect(
3399                                         isl_set_copy(pma->p[i].set),
3400                                         isl_set_copy(subs->p[j].set));
3401                         common = isl_set_substitute(common,
3402                                         type, pos, subs->p[j].aff);
3403                         if (isl_set_plain_is_empty(common)) {
3404                                 isl_set_free(common);
3405                                 continue;
3406                         }
3407
3408                         res_ij = isl_multi_aff_substitute(
3409                                         isl_multi_aff_copy(pma->p[i].maff),
3410                                         type, pos, subs->p[j].aff);
3411
3412                         res = isl_pw_multi_aff_add_piece(res, common, res_ij);
3413                 }
3414         }
3415
3416         isl_pw_multi_aff_free(pma);
3417         return res;
3418 }
3419
3420 /* Compute the preimage of the affine expression "src" under "ma"
3421  * and put the result in "dst".  If "has_denom" is set (to one),
3422  * then "src" and "dst" have an extra initial denominator.
3423  * "n_div_ma" is the number of existentials in "ma"
3424  * "n_div_bset" is the number of existentials in "src"
3425  * The resulting "dst" (which is assumed to have been allocated by
3426  * the caller) contains coefficients for both sets of existentials,
3427  * first those in "ma" and then those in "src".
3428  * f, c1, c2 and g are temporary objects that have been initialized
3429  * by the caller.
3430  *
3431  * Let src represent the expression
3432  *
3433  *      (a(p) + b x + c(divs))/d
3434  *
3435  * and let ma represent the expressions
3436  *
3437  *      x_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i
3438  *
3439  * We start out with the following expression for dst:
3440  *
3441  *      (a(p) + 0 y + 0 divs' + f \sum_i b_i x_i + c(divs))/d
3442  *
3443  * with the multiplication factor f initially equal to 1.
3444  * For each x_i that we substitute, we multiply the numerator
3445  * (and denominator) of dst by c_1 = m_i and add the numerator
3446  * of the x_i expression multiplied by c_2 = f b_i,
3447  * after removing the common factors of c_1 and c_2.
3448  * The multiplication factor f also needs to be multiplied by c_1
3449  * for the next x_j, j > i.
3450  */
3451 void isl_seq_preimage(isl_int *dst, isl_int *src,
3452         __isl_keep isl_multi_aff *ma, int n_div_ma, int n_div_bset,
3453         isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom)
3454 {
3455         int i;
3456         int n_param, n_in, n_out;
3457         int o_div_bset;
3458
3459         n_param = isl_multi_aff_dim(ma, isl_dim_param);
3460         n_in = isl_multi_aff_dim(ma, isl_dim_in);
3461         n_out = isl_multi_aff_dim(ma, isl_dim_out);
3462
3463         o_div_bset = has_denom + 1 + n_param + n_in + n_div_ma;
3464
3465         isl_seq_cpy(dst, src, has_denom + 1 + n_param);
3466         isl_seq_clr(dst + has_denom + 1 + n_param, n_in + n_div_ma);
3467         isl_seq_cpy(dst + o_div_bset,
3468                     src + has_denom + 1 + n_param + n_out, n_div_bset);
3469
3470         isl_int_set_si(f, 1);
3471
3472         for (i = 0; i < n_out; ++i) {
3473                 if (isl_int_is_zero(src[has_denom + 1 + n_param + i]))
3474                         continue;
3475                 isl_int_set(c1, ma->p[i]->v->el[0]);
3476                 isl_int_mul(c2, f, src[has_denom + 1 + n_param + i]);
3477                 isl_int_gcd(g, c1, c2);
3478                 isl_int_divexact(c1, c1, g);
3479                 isl_int_divexact(c2, c2, g);
3480
3481                 isl_int_mul(f, f, c1);
3482                 isl_seq_combine(dst + has_denom, c1, dst + has_denom,
3483                                 c2, ma->p[i]->v->el + 1, ma->p[i]->v->size - 1);
3484                 isl_seq_scale(dst + o_div_bset,
3485                                 dst + o_div_bset, c1, n_div_bset);
3486                 if (has_denom)
3487                         isl_int_mul(dst[0], dst[0], c1);
3488         }
3489 }
3490
3491 /* Compute the pullback of "aff" by the function represented by "ma".
3492  * In other words, plug in "ma" in "aff".  The result is an affine expression
3493  * defined over the domain space of "ma".
3494  *
3495  * If "aff" is represented by
3496  *
3497  *      (a(p) + b x + c(divs))/d
3498  *
3499  * and ma is represented by
3500  *
3501  *      x = D(p) + F(y) + G(divs')
3502  *
3503  * then the result is
3504  *
3505  *      (a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d
3506  *
3507  * The divs in the local space of the input are similarly adjusted
3508  * through a call to isl_local_space_preimage_multi_aff.
3509  */
3510 __isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff,
3511         __isl_take isl_multi_aff *ma)
3512 {
3513         isl_aff *res = NULL;
3514         isl_local_space *ls;
3515         int n_div_aff, n_div_ma;
3516         isl_int f, c1, c2, g;
3517
3518         ma = isl_multi_aff_align_divs(ma);
3519         if (!aff || !ma)
3520                 goto error;
3521
3522         n_div_aff = isl_aff_dim(aff, isl_dim_div);
3523         n_div_ma = ma->n ? isl_aff_dim(ma->p[0], isl_dim_div) : 0;
3524
3525         ls = isl_aff_get_domain_local_space(aff);
3526         ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma));
3527         res = isl_aff_alloc(ls);
3528         if (!res)
3529                 goto error;
3530
3531         isl_int_init(f);
3532         isl_int_init(c1);
3533         isl_int_init(c2);
3534         isl_int_init(g);
3535
3536         isl_seq_preimage(res->v->el, aff->v->el, ma, n_div_ma, n_div_aff,
3537                         f, c1, c2, g, 1);
3538
3539         isl_int_clear(f);
3540         isl_int_clear(c1);
3541         isl_int_clear(c2);
3542         isl_int_clear(g);
3543
3544         isl_aff_free(aff);
3545         isl_multi_aff_free(ma);
3546         res = isl_aff_normalize(res);
3547         return res;
3548 error:
3549         isl_aff_free(aff);
3550         isl_multi_aff_free(ma);
3551         isl_aff_free(res);
3552         return NULL;
3553 }
3554
3555 /* Compute the pullback of "ma1" by the function represented by "ma2".
3556  * In other words, plug in "ma2" in "ma1".
3557  */
3558 __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
3559         __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
3560 {
3561         int i;
3562         isl_space *space = NULL;
3563
3564         ma2 = isl_multi_aff_align_divs(ma2);
3565         ma1 = isl_multi_aff_cow(ma1);
3566         if (!ma1 || !ma2)
3567                 goto error;
3568
3569         space = isl_space_join(isl_multi_aff_get_space(ma2),
3570                                 isl_multi_aff_get_space(ma1));
3571
3572         for (i = 0; i < ma1->n; ++i) {
3573                 ma1->p[i] = isl_aff_pullback_multi_aff(ma1->p[i],
3574                                                     isl_multi_aff_copy(ma2));
3575                 if (!ma1->p[i])
3576                         goto error;
3577         }
3578
3579         ma1 = isl_multi_aff_reset_space(ma1, space);
3580         isl_multi_aff_free(ma2);
3581         return ma1;
3582 error:
3583         isl_space_free(space);
3584         isl_multi_aff_free(ma2);
3585         isl_multi_aff_free(ma1);
3586         return NULL;
3587 }
3588
3589 /* Extend the local space of "dst" to include the divs
3590  * in the local space of "src".
3591  */
3592 __isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
3593         __isl_keep isl_aff *src)
3594 {
3595         isl_ctx *ctx;
3596         int *exp1 = NULL;
3597         int *exp2 = NULL;
3598         isl_mat *div;
3599
3600         if (!src || !dst)
3601                 return isl_aff_free(dst);
3602
3603         ctx = isl_aff_get_ctx(src);
3604         if (!isl_space_is_equal(src->ls->dim, dst->ls->dim))
3605                 isl_die(ctx, isl_error_invalid,
3606                         "spaces don't match", goto error);
3607
3608         if (src->ls->div->n_row == 0)
3609                 return dst;
3610
3611         exp1 = isl_alloc_array(ctx, int, src->ls->div->n_row);
3612         exp2 = isl_alloc_array(ctx, int, dst->ls->div->n_row);
3613         if (!exp1 || !exp2)
3614                 goto error;
3615
3616         div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
3617         dst = isl_aff_expand_divs(dst, div, exp2);
3618         free(exp1);
3619         free(exp2);
3620
3621         return dst;
3622 error:
3623         free(exp1);
3624         free(exp2);
3625         return isl_aff_free(dst);
3626 }
3627
3628 /* Adjust the local spaces of the affine expressions in "maff"
3629  * such that they all have the save divs.
3630  */
3631 __isl_give isl_multi_aff *isl_multi_aff_align_divs(
3632         __isl_take isl_multi_aff *maff)
3633 {
3634         int i;
3635
3636         if (!maff)
3637                 return NULL;
3638         if (maff->n == 0)
3639                 return maff;
3640         maff = isl_multi_aff_cow(maff);
3641         if (!maff)
3642                 return NULL;
3643
3644         for (i = 1; i < maff->n; ++i)
3645                 maff->p[0] = isl_aff_align_divs(maff->p[0], maff->p[i]);
3646         for (i = 1; i < maff->n; ++i) {
3647                 maff->p[i] = isl_aff_align_divs(maff->p[i], maff->p[0]);
3648                 if (!maff->p[i])
3649                         return isl_multi_aff_free(maff);
3650         }
3651
3652         return maff;
3653 }
3654
3655 __isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
3656 {
3657         aff = isl_aff_cow(aff);
3658         if (!aff)
3659                 return NULL;
3660
3661         aff->ls = isl_local_space_lift(aff->ls);
3662         if (!aff->ls)
3663                 return isl_aff_free(aff);
3664
3665         return aff;
3666 }
3667
3668 /* Lift "maff" to a space with extra dimensions such that the result
3669  * has no more existentially quantified variables.
3670  * If "ls" is not NULL, then *ls is assigned the local space that lies
3671  * at the basis of the lifting applied to "maff".
3672  */
3673 __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
3674         __isl_give isl_local_space **ls)
3675 {
3676         int i;
3677         isl_space *space;
3678         unsigned n_div;
3679
3680         if (ls)
3681                 *ls = NULL;
3682
3683         if (!maff)
3684                 return NULL;
3685
3686         if (maff->n == 0) {
3687                 if (ls) {
3688                         isl_space *space = isl_multi_aff_get_domain_space(maff);
3689                         *ls = isl_local_space_from_space(space);
3690                         if (!*ls)
3691                                 return isl_multi_aff_free(maff);
3692                 }
3693                 return maff;
3694         }
3695
3696         maff = isl_multi_aff_cow(maff);
3697         maff = isl_multi_aff_align_divs(maff);
3698         if (!maff)
3699                 return NULL;
3700
3701         n_div = isl_aff_dim(maff->p[0], isl_dim_div);
3702         space = isl_multi_aff_get_space(maff);
3703         space = isl_space_lift(isl_space_domain(space), n_div);
3704         space = isl_space_extend_domain_with_range(space,
3705                                                 isl_multi_aff_get_space(maff));
3706         if (!space)
3707                 return isl_multi_aff_free(maff);
3708         isl_space_free(maff->space);
3709         maff->space = space;
3710
3711         if (ls) {
3712                 *ls = isl_aff_get_domain_local_space(maff->p[0]);
3713                 if (!*ls)
3714                         return isl_multi_aff_free(maff);
3715         }
3716
3717         for (i = 0; i < maff->n; ++i) {
3718                 maff->p[i] = isl_aff_lift(maff->p[i]);
3719                 if (!maff->p[i])
3720                         goto error;
3721         }
3722
3723         return maff;
3724 error:
3725         if (ls)
3726                 isl_local_space_free(*ls);
3727         return isl_multi_aff_free(maff);
3728 }
3729
3730
3731 /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
3732  */
3733 __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
3734         __isl_keep isl_pw_multi_aff *pma, int pos)
3735 {
3736         int i;
3737         int n_out;
3738         isl_space *space;
3739         isl_pw_aff *pa;
3740
3741         if (!pma)
3742                 return NULL;
3743
3744         n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
3745         if (pos < 0 || pos >= n_out)
3746                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
3747                         "index out of bounds", return NULL);
3748
3749         space = isl_pw_multi_aff_get_space(pma);
3750         space = isl_space_drop_dims(space, isl_dim_out,
3751                                     pos + 1, n_out - pos - 1);
3752         space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
3753
3754         pa = isl_pw_aff_alloc_size(space, pma->n);
3755         for (i = 0; i < pma->n; ++i) {
3756                 isl_aff *aff;
3757                 aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
3758                 pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
3759         }
3760
3761         return pa;
3762 }
3763
3764 /* Return an isl_pw_multi_aff with the given "set" as domain and
3765  * an unnamed zero-dimensional range.
3766  */
3767 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain(
3768         __isl_take isl_set *set)
3769 {
3770         isl_multi_aff *ma;
3771         isl_space *space;
3772
3773         space = isl_set_get_space(set);
3774         space = isl_space_from_domain(space);
3775         ma = isl_multi_aff_zero(space);
3776         return isl_pw_multi_aff_alloc(set, ma);
3777 }
3778
3779 /* Add an isl_pw_multi_aff with the given "set" as domain and
3780  * an unnamed zero-dimensional range to *user.
3781  */
3782 static int add_pw_multi_aff_from_domain(__isl_take isl_set *set, void *user)
3783 {
3784         isl_union_pw_multi_aff **upma = user;
3785         isl_pw_multi_aff *pma;
3786
3787         pma = isl_pw_multi_aff_from_domain(set);
3788         *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
3789
3790         return 0;
3791 }
3792
3793 /* Return an isl_union_pw_multi_aff with the given "uset" as domain and
3794  * an unnamed zero-dimensional range.
3795  */
3796 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
3797         __isl_take isl_union_set *uset)
3798 {
3799         isl_space *space;
3800         isl_union_pw_multi_aff *upma;
3801
3802         if (!uset)
3803                 return NULL;
3804
3805         space = isl_union_set_get_space(uset);
3806         upma = isl_union_pw_multi_aff_empty(space);
3807
3808         if (isl_union_set_foreach_set(uset,
3809                                     &add_pw_multi_aff_from_domain, &upma) < 0)
3810                 goto error;
3811
3812         isl_union_set_free(uset);
3813         return upma;
3814 error:
3815         isl_union_set_free(uset);
3816         isl_union_pw_multi_aff_free(upma);
3817         return NULL;
3818 }
3819
3820 /* Convert "pma" to an isl_map and add it to *umap.
3821  */
3822 static int map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma, void *user)
3823 {
3824         isl_union_map **umap = user;
3825         isl_map *map;
3826
3827         map = isl_map_from_pw_multi_aff(pma);
3828         *umap = isl_union_map_add_map(*umap, map);
3829
3830         return 0;
3831 }
3832
3833 /* Construct a union map mapping the domain of the union
3834  * piecewise multi-affine expression to its range, with each dimension
3835  * in the range equated to the corresponding affine expression on its cell.
3836  */
3837 __isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff(
3838         __isl_take isl_union_pw_multi_aff *upma)
3839 {
3840         isl_space *space;
3841         isl_union_map *umap;
3842
3843         if (!upma)
3844                 return NULL;
3845
3846         space = isl_union_pw_multi_aff_get_space(upma);
3847         umap = isl_union_map_empty(space);
3848
3849         if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
3850                                         &map_from_pw_multi_aff, &umap) < 0)
3851                 goto error;
3852
3853         isl_union_pw_multi_aff_free(upma);
3854         return umap;
3855 error:
3856         isl_union_pw_multi_aff_free(upma);
3857         isl_union_map_free(umap);
3858         return NULL;
3859 }
3860
3861 /* Local data for bin_entry and the callback "fn".
3862  */
3863 struct isl_union_pw_multi_aff_bin_data {
3864         isl_union_pw_multi_aff *upma2;
3865         isl_union_pw_multi_aff *res;
3866         isl_pw_multi_aff *pma;
3867         int (*fn)(void **entry, void *user);
3868 };
3869
3870 /* Given an isl_pw_multi_aff from upma1, store it in data->pma
3871  * and call data->fn for each isl_pw_multi_aff in data->upma2.
3872  */
3873 static int bin_entry(void **entry, void *user)
3874 {
3875         struct isl_union_pw_multi_aff_bin_data *data = user;
3876         isl_pw_multi_aff *pma = *entry;
3877
3878         data->pma = pma;
3879         if (isl_hash_table_foreach(data->upma2->dim->ctx, &data->upma2->table,
3880                                    data->fn, data) < 0)
3881                 return -1;
3882
3883         return 0;
3884 }
3885
3886 /* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2".
3887  * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is
3888  * passed as user field) and the isl_pw_multi_aff from upma2 is available
3889  * as *entry.  The callback should adjust data->res if desired.
3890  */
3891 static __isl_give isl_union_pw_multi_aff *bin_op(
3892         __isl_take isl_union_pw_multi_aff *upma1,
3893         __isl_take isl_union_pw_multi_aff *upma2,
3894         int (*fn)(void **entry, void *user))
3895 {
3896         isl_space *space;
3897         struct isl_union_pw_multi_aff_bin_data data = { NULL, NULL, NULL, fn };
3898
3899         space = isl_union_pw_multi_aff_get_space(upma2);
3900         upma1 = isl_union_pw_multi_aff_align_params(upma1, space);
3901         space = isl_union_pw_multi_aff_get_space(upma1);
3902         upma2 = isl_union_pw_multi_aff_align_params(upma2, space);
3903
3904         if (!upma1 || !upma2)
3905                 goto error;
3906
3907         data.upma2 = upma2;
3908         data.res = isl_union_pw_multi_aff_alloc(isl_space_copy(upma1->dim),
3909                                        upma1->table.n);
3910         if (isl_hash_table_foreach(upma1->dim->ctx, &upma1->table,
3911                                    &bin_entry, &data) < 0)
3912                 goto error;
3913
3914         isl_union_pw_multi_aff_free(upma1);
3915         isl_union_pw_multi_aff_free(upma2);
3916         return data.res;
3917 error:
3918         isl_union_pw_multi_aff_free(upma1);
3919         isl_union_pw_multi_aff_free(upma2);
3920         isl_union_pw_multi_aff_free(data.res);
3921         return NULL;
3922 }
3923
3924 /* Given two aligned isl_pw_multi_affs A -> B and C -> D,
3925  * construct an isl_pw_multi_aff (A * C) -> [B -> D].
3926  */
3927 static __isl_give isl_pw_multi_aff *pw_multi_aff_range_product(
3928         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3929 {
3930         isl_space *space;
3931
3932         space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
3933                                         isl_pw_multi_aff_get_space(pma2));
3934         return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
3935                                             &isl_multi_aff_range_product);
3936 }
3937
3938 /* Given two isl_pw_multi_affs A -> B and C -> D,
3939  * construct an isl_pw_multi_aff (A * C) -> [B -> D].
3940  */
3941 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product(
3942         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3943 {
3944         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
3945                                             &pw_multi_aff_range_product);
3946 }
3947
3948 /* Given two aligned isl_pw_multi_affs A -> B and C -> D,
3949  * construct an isl_pw_multi_aff (A * C) -> (B, D).
3950  */
3951 static __isl_give isl_pw_multi_aff *pw_multi_aff_flat_range_product(
3952         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3953 {
3954         isl_space *space;
3955
3956         space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
3957                                         isl_pw_multi_aff_get_space(pma2));
3958         space = isl_space_flatten_range(space);
3959         return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
3960                                             &isl_multi_aff_flat_range_product);
3961 }
3962
3963 /* Given two isl_pw_multi_affs A -> B and C -> D,
3964  * construct an isl_pw_multi_aff (A * C) -> (B, D).
3965  */
3966 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product(
3967         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3968 {
3969         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
3970                                             &pw_multi_aff_flat_range_product);
3971 }
3972
3973 /* If data->pma and *entry have the same domain space, then compute
3974  * their flat range product and the result to data->res.
3975  */
3976 static int flat_range_product_entry(void **entry, void *user)
3977 {
3978         struct isl_union_pw_multi_aff_bin_data *data = user;
3979         isl_pw_multi_aff *pma2 = *entry;
3980
3981         if (!isl_space_tuple_match(data->pma->dim, isl_dim_in,
3982                                  pma2->dim, isl_dim_in))
3983                 return 0;
3984
3985         pma2 = isl_pw_multi_aff_flat_range_product(
3986                                         isl_pw_multi_aff_copy(data->pma),
3987                                         isl_pw_multi_aff_copy(pma2));
3988
3989         data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
3990
3991         return 0;
3992 }
3993
3994 /* Given two isl_union_pw_multi_affs A -> B and C -> D,
3995  * construct an isl_union_pw_multi_aff (A * C) -> (B, D).
3996  */
3997 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product(
3998         __isl_take isl_union_pw_multi_aff *upma1,
3999         __isl_take isl_union_pw_multi_aff *upma2)
4000 {
4001         return bin_op(upma1, upma2, &flat_range_product_entry);
4002 }
4003
4004 /* Replace the affine expressions at position "pos" in "pma" by "pa".
4005  * The parameters are assumed to have been aligned.
4006  *
4007  * The implementation essentially performs an isl_pw_*_on_shared_domain,
4008  * except that it works on two different isl_pw_* types.
4009  */
4010 static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff(
4011         __isl_take isl_pw_multi_aff *pma, unsigned pos,
4012         __isl_take isl_pw_aff *pa)
4013 {
4014         int i, j, n;
4015         isl_pw_multi_aff *res = NULL;
4016
4017         if (!pma || !pa)
4018                 goto error;
4019
4020         if (!isl_space_tuple_match(pma->dim, isl_dim_in, pa->dim, isl_dim_in))
4021                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4022                         "domains don't match", goto error);
4023         if (pos >= isl_pw_multi_aff_dim(pma, isl_dim_out))
4024                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4025                         "index out of bounds", goto error);
4026
4027         n = pma->n * pa->n;
4028         res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n);
4029
4030         for (i = 0; i < pma->n; ++i) {
4031                 for (j = 0; j < pa->n; ++j) {
4032                         isl_set *common;
4033                         isl_multi_aff *res_ij;
4034                         int empty;
4035
4036                         common = isl_set_intersect(isl_set_copy(pma->p[i].set),
4037                                                    isl_set_copy(pa->p[j].set));
4038                         empty = isl_set_plain_is_empty(common);
4039                         if (empty < 0 || empty) {
4040                                 isl_set_free(common);
4041                                 if (empty < 0)
4042                                         goto error;
4043                                 continue;
4044                         }
4045
4046                         res_ij = isl_multi_aff_set_aff(
4047                                         isl_multi_aff_copy(pma->p[i].maff), pos,
4048                                         isl_aff_copy(pa->p[j].aff));
4049                         res_ij = isl_multi_aff_gist(res_ij,
4050                                         isl_set_copy(common));
4051
4052                         res = isl_pw_multi_aff_add_piece(res, common, res_ij);
4053                 }
4054         }
4055
4056         isl_pw_multi_aff_free(pma);
4057         isl_pw_aff_free(pa);
4058         return res;
4059 error:
4060         isl_pw_multi_aff_free(pma);
4061         isl_pw_aff_free(pa);
4062         return isl_pw_multi_aff_free(res);
4063 }
4064
4065 /* Replace the affine expressions at position "pos" in "pma" by "pa".
4066  */
4067 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff(
4068         __isl_take isl_pw_multi_aff *pma, unsigned pos,
4069         __isl_take isl_pw_aff *pa)
4070 {
4071         if (!pma || !pa)
4072                 goto error;
4073         if (isl_space_match(pma->dim, isl_dim_param, pa->dim, isl_dim_param))
4074                 return pw_multi_aff_set_pw_aff(pma, pos, pa);
4075         if (!isl_space_has_named_params(pma->dim) ||
4076             !isl_space_has_named_params(pa->dim))
4077                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4078                         "unaligned unnamed parameters", goto error);
4079         pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa));
4080         pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma));
4081         return pw_multi_aff_set_pw_aff(pma, pos, pa);
4082 error:
4083         isl_pw_multi_aff_free(pma);
4084         isl_pw_aff_free(pa);
4085         return NULL;
4086 }
4087
4088 #undef BASE
4089 #define BASE pw_aff
4090
4091 #include <isl_multi_templ.c>