isl_aff_ceil: compute ceil(e/m) as floor((e + m - 1)/m)
[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, let f be the expression
998  *
999  *      e/m
1000  *
1001  * then return
1002  *
1003  *      floor((e + m - 1)/m)
1004  */
1005 __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
1006 {
1007         if (!aff)
1008                 return NULL;
1009
1010         if (isl_int_is_one(aff->v->el[0]))
1011                 return aff;
1012
1013         aff = isl_aff_cow(aff);
1014         if (!aff)
1015                 return NULL;
1016         aff->v = isl_vec_cow(aff->v);
1017         if (!aff->v)
1018                 return isl_aff_free(aff);
1019
1020         isl_int_add(aff->v->el[1], aff->v->el[1], aff->v->el[0]);
1021         isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1);
1022         aff = isl_aff_floor(aff);
1023
1024         return aff;
1025 }
1026
1027 /* Apply the expansion computed by isl_merge_divs.
1028  * The expansion itself is given by "exp" while the resulting
1029  * list of divs is given by "div".
1030  */
1031 __isl_give isl_aff *isl_aff_expand_divs( __isl_take isl_aff *aff,
1032         __isl_take isl_mat *div, int *exp)
1033 {
1034         int i, j;
1035         int old_n_div;
1036         int new_n_div;
1037         int offset;
1038
1039         aff = isl_aff_cow(aff);
1040         if (!aff || !div)
1041                 goto error;
1042
1043         old_n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1044         new_n_div = isl_mat_rows(div);
1045         if (new_n_div < old_n_div)
1046                 isl_die(isl_mat_get_ctx(div), isl_error_invalid,
1047                         "not an expansion", goto error);
1048
1049         aff->v = isl_vec_extend(aff->v, aff->v->size + new_n_div - old_n_div);
1050         if (!aff->v)
1051                 goto error;
1052
1053         offset = 1 + isl_local_space_offset(aff->ls, isl_dim_div);
1054         j = old_n_div - 1;
1055         for (i = new_n_div - 1; i >= 0; --i) {
1056                 if (j >= 0 && exp[j] == i) {
1057                         if (i != j)
1058                                 isl_int_swap(aff->v->el[offset + i],
1059                                              aff->v->el[offset + j]);
1060                         j--;
1061                 } else
1062                         isl_int_set_si(aff->v->el[offset + i], 0);
1063         }
1064
1065         aff->ls = isl_local_space_replace_divs(aff->ls, isl_mat_copy(div));
1066         if (!aff->ls)
1067                 goto error;
1068         isl_mat_free(div);
1069         return aff;
1070 error:
1071         isl_aff_free(aff);
1072         isl_mat_free(div);
1073         return NULL;
1074 }
1075
1076 /* Add two affine expressions that live in the same local space.
1077  */
1078 static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1,
1079         __isl_take isl_aff *aff2)
1080 {
1081         isl_int gcd, f;
1082
1083         aff1 = isl_aff_cow(aff1);
1084         if (!aff1 || !aff2)
1085                 goto error;
1086
1087         aff1->v = isl_vec_cow(aff1->v);
1088         if (!aff1->v)
1089                 goto error;
1090
1091         isl_int_init(gcd);
1092         isl_int_init(f);
1093         isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0]);
1094         isl_int_divexact(f, aff2->v->el[0], gcd);
1095         isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1);
1096         isl_int_divexact(f, aff1->v->el[0], gcd);
1097         isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1);
1098         isl_int_divexact(f, aff2->v->el[0], gcd);
1099         isl_int_mul(aff1->v->el[0], aff1->v->el[0], f);
1100         isl_int_clear(f);
1101         isl_int_clear(gcd);
1102
1103         isl_aff_free(aff2);
1104         return aff1;
1105 error:
1106         isl_aff_free(aff1);
1107         isl_aff_free(aff2);
1108         return NULL;
1109 }
1110
1111 __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
1112         __isl_take isl_aff *aff2)
1113 {
1114         isl_ctx *ctx;
1115         int *exp1 = NULL;
1116         int *exp2 = NULL;
1117         isl_mat *div;
1118
1119         if (!aff1 || !aff2)
1120                 goto error;
1121
1122         ctx = isl_aff_get_ctx(aff1);
1123         if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim))
1124                 isl_die(ctx, isl_error_invalid,
1125                         "spaces don't match", goto error);
1126
1127         if (aff1->ls->div->n_row == 0 && aff2->ls->div->n_row == 0)
1128                 return add_expanded(aff1, aff2);
1129
1130         exp1 = isl_alloc_array(ctx, int, aff1->ls->div->n_row);
1131         exp2 = isl_alloc_array(ctx, int, aff2->ls->div->n_row);
1132         if (!exp1 || !exp2)
1133                 goto error;
1134
1135         div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2);
1136         aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1);
1137         aff2 = isl_aff_expand_divs(aff2, div, exp2);
1138         free(exp1);
1139         free(exp2);
1140
1141         return add_expanded(aff1, aff2);
1142 error:
1143         free(exp1);
1144         free(exp2);
1145         isl_aff_free(aff1);
1146         isl_aff_free(aff2);
1147         return NULL;
1148 }
1149
1150 __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
1151         __isl_take isl_aff *aff2)
1152 {
1153         return isl_aff_add(aff1, isl_aff_neg(aff2));
1154 }
1155
1156 __isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f)
1157 {
1158         isl_int gcd;
1159
1160         if (isl_int_is_one(f))
1161                 return aff;
1162
1163         aff = isl_aff_cow(aff);
1164         if (!aff)
1165                 return NULL;
1166         aff->v = isl_vec_cow(aff->v);
1167         if (!aff->v)
1168                 return isl_aff_free(aff);
1169
1170         isl_int_init(gcd);
1171         isl_int_gcd(gcd, aff->v->el[0], f);
1172         isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd);
1173         isl_int_divexact(gcd, f, gcd);
1174         isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
1175         isl_int_clear(gcd);
1176
1177         return aff;
1178 }
1179
1180 __isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
1181 {
1182         isl_int gcd;
1183
1184         if (isl_int_is_one(f))
1185                 return aff;
1186
1187         aff = isl_aff_cow(aff);
1188         if (!aff)
1189                 return NULL;
1190
1191         if (isl_int_is_zero(f))
1192                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1193                         "cannot scale down by zero", return isl_aff_free(aff));
1194
1195         aff->v = isl_vec_cow(aff->v);
1196         if (!aff->v)
1197                 return isl_aff_free(aff);
1198
1199         isl_int_init(gcd);
1200         isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd);
1201         isl_int_gcd(gcd, gcd, f);
1202         isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
1203         isl_int_divexact(gcd, f, gcd);
1204         isl_int_mul(aff->v->el[0], aff->v->el[0], gcd);
1205         isl_int_clear(gcd);
1206
1207         return aff;
1208 }
1209
1210 __isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f)
1211 {
1212         isl_int v;
1213
1214         if (f == 1)
1215                 return aff;
1216
1217         isl_int_init(v);
1218         isl_int_set_ui(v, f);
1219         aff = isl_aff_scale_down(aff, v);
1220         isl_int_clear(v);
1221
1222         return aff;
1223 }
1224
1225 __isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff,
1226         enum isl_dim_type type, unsigned pos, const char *s)
1227 {
1228         aff = isl_aff_cow(aff);
1229         if (!aff)
1230                 return NULL;
1231         if (type == isl_dim_out)
1232                 isl_die(aff->v->ctx, isl_error_invalid,
1233                         "cannot set name of output/set dimension",
1234                         return isl_aff_free(aff));
1235         if (type == isl_dim_in)
1236                 type = isl_dim_set;
1237         aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s);
1238         if (!aff->ls)
1239                 return isl_aff_free(aff);
1240
1241         return aff;
1242 }
1243
1244 __isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff,
1245         enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
1246 {
1247         aff = isl_aff_cow(aff);
1248         if (!aff)
1249                 return isl_id_free(id);
1250         if (type == isl_dim_out)
1251                 isl_die(aff->v->ctx, isl_error_invalid,
1252                         "cannot set name of output/set dimension",
1253                         goto error);
1254         if (type == isl_dim_in)
1255                 type = isl_dim_set;
1256         aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id);
1257         if (!aff->ls)
1258                 return isl_aff_free(aff);
1259
1260         return aff;
1261 error:
1262         isl_id_free(id);
1263         isl_aff_free(aff);
1264         return NULL;
1265 }
1266
1267 /* Exploit the equalities in "eq" to simplify the affine expression
1268  * and the expressions of the integer divisions in the local space.
1269  * The integer divisions in this local space are assumed to appear
1270  * as regular dimensions in "eq".
1271  */
1272 static __isl_give isl_aff *isl_aff_substitute_equalities_lifted(
1273         __isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
1274 {
1275         int i, j;
1276         unsigned total;
1277         unsigned n_div;
1278
1279         if (!eq)
1280                 goto error;
1281         if (eq->n_eq == 0) {
1282                 isl_basic_set_free(eq);
1283                 return aff;
1284         }
1285
1286         aff = isl_aff_cow(aff);
1287         if (!aff)
1288                 goto error;
1289
1290         aff->ls = isl_local_space_substitute_equalities(aff->ls,
1291                                                         isl_basic_set_copy(eq));
1292         aff->v = isl_vec_cow(aff->v);
1293         if (!aff->ls || !aff->v)
1294                 goto error;
1295
1296         total = 1 + isl_space_dim(eq->dim, isl_dim_all);
1297         n_div = eq->n_div;
1298         for (i = 0; i < eq->n_eq; ++i) {
1299                 j = isl_seq_last_non_zero(eq->eq[i], total + n_div);
1300                 if (j < 0 || j == 0 || j >= total)
1301                         continue;
1302
1303                 isl_seq_elim(aff->v->el + 1, eq->eq[i], j, total,
1304                                 &aff->v->el[0]);
1305         }
1306
1307         isl_basic_set_free(eq);
1308         aff = isl_aff_normalize(aff);
1309         return aff;
1310 error:
1311         isl_basic_set_free(eq);
1312         isl_aff_free(aff);
1313         return NULL;
1314 }
1315
1316 /* Exploit the equalities in "eq" to simplify the affine expression
1317  * and the expressions of the integer divisions in the local space.
1318  */
1319 static __isl_give isl_aff *isl_aff_substitute_equalities(
1320         __isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
1321 {
1322         int n_div;
1323
1324         if (!aff || !eq)
1325                 goto error;
1326         n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1327         if (n_div > 0)
1328                 eq = isl_basic_set_add(eq, isl_dim_set, n_div);
1329         return isl_aff_substitute_equalities_lifted(aff, eq);
1330 error:
1331         isl_basic_set_free(eq);
1332         isl_aff_free(aff);
1333         return NULL;
1334 }
1335
1336 /* Look for equalities among the variables shared by context and aff
1337  * and the integer divisions of aff, if any.
1338  * The equalities are then used to eliminate coefficients and/or integer
1339  * divisions from aff.
1340  */
1341 __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff,
1342         __isl_take isl_set *context)
1343 {
1344         isl_basic_set *hull;
1345         int n_div;
1346
1347         if (!aff)
1348                 goto error;
1349         n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1350         if (n_div > 0) {
1351                 isl_basic_set *bset;
1352                 isl_local_space *ls;
1353                 context = isl_set_add_dims(context, isl_dim_set, n_div);
1354                 ls = isl_aff_get_domain_local_space(aff);
1355                 bset = isl_basic_set_from_local_space(ls);
1356                 bset = isl_basic_set_lift(bset);
1357                 bset = isl_basic_set_flatten(bset);
1358                 context = isl_set_intersect(context,
1359                                             isl_set_from_basic_set(bset));
1360         }
1361
1362         hull = isl_set_affine_hull(context);
1363         return isl_aff_substitute_equalities_lifted(aff, hull);
1364 error:
1365         isl_aff_free(aff);
1366         isl_set_free(context);
1367         return NULL;
1368 }
1369
1370 __isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
1371         __isl_take isl_set *context)
1372 {
1373         isl_set *dom_context = isl_set_universe(isl_aff_get_domain_space(aff));
1374         dom_context = isl_set_intersect_params(dom_context, context);
1375         return isl_aff_gist(aff, dom_context);
1376 }
1377
1378 /* Return a basic set containing those elements in the space
1379  * of aff where it is non-negative.
1380  * If "rational" is set, then return a rational basic set.
1381  */
1382 static __isl_give isl_basic_set *aff_nonneg_basic_set(
1383         __isl_take isl_aff *aff, int rational)
1384 {
1385         isl_constraint *ineq;
1386         isl_basic_set *bset;
1387
1388         ineq = isl_inequality_from_aff(aff);
1389
1390         bset = isl_basic_set_from_constraint(ineq);
1391         if (rational)
1392                 bset = isl_basic_set_set_rational(bset);
1393         bset = isl_basic_set_simplify(bset);
1394         return bset;
1395 }
1396
1397 /* Return a basic set containing those elements in the space
1398  * of aff where it is non-negative.
1399  */
1400 __isl_give isl_basic_set *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff)
1401 {
1402         return aff_nonneg_basic_set(aff, 0);
1403 }
1404
1405 /* Return a basic set containing those elements in the domain space
1406  * of aff where it is negative.
1407  */
1408 __isl_give isl_basic_set *isl_aff_neg_basic_set(__isl_take isl_aff *aff)
1409 {
1410         aff = isl_aff_neg(aff);
1411         aff = isl_aff_add_constant_num_si(aff, -1);
1412         return isl_aff_nonneg_basic_set(aff);
1413 }
1414
1415 /* Return a basic set containing those elements in the space
1416  * of aff where it is zero.
1417  * If "rational" is set, then return a rational basic set.
1418  */
1419 static __isl_give isl_basic_set *aff_zero_basic_set(__isl_take isl_aff *aff,
1420         int rational)
1421 {
1422         isl_constraint *ineq;
1423         isl_basic_set *bset;
1424
1425         ineq = isl_equality_from_aff(aff);
1426
1427         bset = isl_basic_set_from_constraint(ineq);
1428         if (rational)
1429                 bset = isl_basic_set_set_rational(bset);
1430         bset = isl_basic_set_simplify(bset);
1431         return bset;
1432 }
1433
1434 /* Return a basic set containing those elements in the space
1435  * of aff where it is zero.
1436  */
1437 __isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
1438 {
1439         return aff_zero_basic_set(aff, 0);
1440 }
1441
1442 /* Return a basic set containing those elements in the shared space
1443  * of aff1 and aff2 where aff1 is greater than or equal to aff2.
1444  */
1445 __isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
1446         __isl_take isl_aff *aff2)
1447 {
1448         aff1 = isl_aff_sub(aff1, aff2);
1449
1450         return isl_aff_nonneg_basic_set(aff1);
1451 }
1452
1453 /* Return a basic set containing those elements in the shared space
1454  * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
1455  */
1456 __isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
1457         __isl_take isl_aff *aff2)
1458 {
1459         return isl_aff_ge_basic_set(aff2, aff1);
1460 }
1461
1462 __isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_set *dom,
1463         __isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
1464 {
1465         aff1 = isl_aff_add(aff1, aff2);
1466         aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
1467         return aff1;
1468 }
1469
1470 int isl_aff_is_empty(__isl_keep isl_aff *aff)
1471 {
1472         if (!aff)
1473                 return -1;
1474
1475         return 0;
1476 }
1477
1478 /* Check whether the given affine expression has non-zero coefficient
1479  * for any dimension in the given range or if any of these dimensions
1480  * appear with non-zero coefficients in any of the integer divisions
1481  * involved in the affine expression.
1482  */
1483 int isl_aff_involves_dims(__isl_keep isl_aff *aff,
1484         enum isl_dim_type type, unsigned first, unsigned n)
1485 {
1486         int i;
1487         isl_ctx *ctx;
1488         int *active = NULL;
1489         int involves = 0;
1490
1491         if (!aff)
1492                 return -1;
1493         if (n == 0)
1494                 return 0;
1495
1496         ctx = isl_aff_get_ctx(aff);
1497         if (first + n > isl_aff_dim(aff, type))
1498                 isl_die(ctx, isl_error_invalid,
1499                         "range out of bounds", return -1);
1500
1501         active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
1502         if (!active)
1503                 goto error;
1504
1505         first += isl_local_space_offset(aff->ls, type) - 1;
1506         for (i = 0; i < n; ++i)
1507                 if (active[first + i]) {
1508                         involves = 1;
1509                         break;
1510                 }
1511
1512         free(active);
1513
1514         return involves;
1515 error:
1516         free(active);
1517         return -1;
1518 }
1519
1520 __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
1521         enum isl_dim_type type, unsigned first, unsigned n)
1522 {
1523         isl_ctx *ctx;
1524
1525         if (!aff)
1526                 return NULL;
1527         if (type == isl_dim_out)
1528                 isl_die(aff->v->ctx, isl_error_invalid,
1529                         "cannot drop output/set dimension",
1530                         return isl_aff_free(aff));
1531         if (type == isl_dim_in)
1532                 type = isl_dim_set;
1533         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1534                 return aff;
1535
1536         ctx = isl_aff_get_ctx(aff);
1537         if (first + n > isl_local_space_dim(aff->ls, type))
1538                 isl_die(ctx, isl_error_invalid, "range out of bounds",
1539                         return isl_aff_free(aff));
1540
1541         aff = isl_aff_cow(aff);
1542         if (!aff)
1543                 return NULL;
1544
1545         aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
1546         if (!aff->ls)
1547                 return isl_aff_free(aff);
1548
1549         first += 1 + isl_local_space_offset(aff->ls, type);
1550         aff->v = isl_vec_drop_els(aff->v, first, n);
1551         if (!aff->v)
1552                 return isl_aff_free(aff);
1553
1554         return aff;
1555 }
1556
1557 /* Project the domain of the affine expression onto its parameter space.
1558  * The affine expression may not involve any of the domain dimensions.
1559  */
1560 __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
1561 {
1562         isl_space *space;
1563         unsigned n;
1564         int involves;
1565
1566         n = isl_aff_dim(aff, isl_dim_in);
1567         involves = isl_aff_involves_dims(aff, isl_dim_in, 0, n);
1568         if (involves < 0)
1569                 return isl_aff_free(aff);
1570         if (involves)
1571                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1572                     "affine expression involves some of the domain dimensions",
1573                     return isl_aff_free(aff));
1574         aff = isl_aff_drop_dims(aff, isl_dim_in, 0, n);
1575         space = isl_aff_get_domain_space(aff);
1576         space = isl_space_params(space);
1577         aff = isl_aff_reset_domain_space(aff, space);
1578         return aff;
1579 }
1580
1581 __isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
1582         enum isl_dim_type type, unsigned first, unsigned n)
1583 {
1584         isl_ctx *ctx;
1585
1586         if (!aff)
1587                 return NULL;
1588         if (type == isl_dim_out)
1589                 isl_die(aff->v->ctx, isl_error_invalid,
1590                         "cannot insert output/set dimensions",
1591                         return isl_aff_free(aff));
1592         if (type == isl_dim_in)
1593                 type = isl_dim_set;
1594         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1595                 return aff;
1596
1597         ctx = isl_aff_get_ctx(aff);
1598         if (first > isl_local_space_dim(aff->ls, type))
1599                 isl_die(ctx, isl_error_invalid, "position out of bounds",
1600                         return isl_aff_free(aff));
1601
1602         aff = isl_aff_cow(aff);
1603         if (!aff)
1604                 return NULL;
1605
1606         aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
1607         if (!aff->ls)
1608                 return isl_aff_free(aff);
1609
1610         first += 1 + isl_local_space_offset(aff->ls, type);
1611         aff->v = isl_vec_insert_zero_els(aff->v, first, n);
1612         if (!aff->v)
1613                 return isl_aff_free(aff);
1614
1615         return aff;
1616 }
1617
1618 __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
1619         enum isl_dim_type type, unsigned n)
1620 {
1621         unsigned pos;
1622
1623         pos = isl_aff_dim(aff, type);
1624
1625         return isl_aff_insert_dims(aff, type, pos, n);
1626 }
1627
1628 __isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff,
1629         enum isl_dim_type type, unsigned n)
1630 {
1631         unsigned pos;
1632
1633         pos = isl_pw_aff_dim(pwaff, type);
1634
1635         return isl_pw_aff_insert_dims(pwaff, type, pos, n);
1636 }
1637
1638 __isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff)
1639 {
1640         isl_set *dom = isl_set_universe(isl_aff_get_domain_space(aff));
1641         return isl_pw_aff_alloc(dom, aff);
1642 }
1643
1644 #undef PW
1645 #define PW isl_pw_aff
1646 #undef EL
1647 #define EL isl_aff
1648 #undef EL_IS_ZERO
1649 #define EL_IS_ZERO is_empty
1650 #undef ZERO
1651 #define ZERO empty
1652 #undef IS_ZERO
1653 #define IS_ZERO is_empty
1654 #undef FIELD
1655 #define FIELD aff
1656 #undef DEFAULT_IS_ZERO
1657 #define DEFAULT_IS_ZERO 0
1658
1659 #define NO_EVAL
1660 #define NO_OPT
1661 #define NO_MOVE_DIMS
1662 #define NO_LIFT
1663 #define NO_MORPH
1664
1665 #include <isl_pw_templ.c>
1666
1667 static __isl_give isl_set *align_params_pw_pw_set_and(
1668         __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2,
1669         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
1670                                     __isl_take isl_pw_aff *pwaff2))
1671 {
1672         if (!pwaff1 || !pwaff2)
1673                 goto error;
1674         if (isl_space_match(pwaff1->dim, isl_dim_param,
1675                           pwaff2->dim, isl_dim_param))
1676                 return fn(pwaff1, pwaff2);
1677         if (!isl_space_has_named_params(pwaff1->dim) ||
1678             !isl_space_has_named_params(pwaff2->dim))
1679                 isl_die(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid,
1680                         "unaligned unnamed parameters", goto error);
1681         pwaff1 = isl_pw_aff_align_params(pwaff1, isl_pw_aff_get_space(pwaff2));
1682         pwaff2 = isl_pw_aff_align_params(pwaff2, isl_pw_aff_get_space(pwaff1));
1683         return fn(pwaff1, pwaff2);
1684 error:
1685         isl_pw_aff_free(pwaff1);
1686         isl_pw_aff_free(pwaff2);
1687         return NULL;
1688 }
1689
1690 /* Compute a piecewise quasi-affine expression with a domain that
1691  * is the union of those of pwaff1 and pwaff2 and such that on each
1692  * cell, the quasi-affine expression is the better (according to cmp)
1693  * of those of pwaff1 and pwaff2.  If only one of pwaff1 or pwaff2
1694  * is defined on a given cell, then the associated expression
1695  * is the defined one.
1696  */
1697 static __isl_give isl_pw_aff *pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
1698         __isl_take isl_pw_aff *pwaff2,
1699         __isl_give isl_basic_set *(*cmp)(__isl_take isl_aff *aff1,
1700                                         __isl_take isl_aff *aff2))
1701 {
1702         int i, j, n;
1703         isl_pw_aff *res;
1704         isl_ctx *ctx;
1705         isl_set *set;
1706
1707         if (!pwaff1 || !pwaff2)
1708                 goto error;
1709
1710         ctx = isl_space_get_ctx(pwaff1->dim);
1711         if (!isl_space_is_equal(pwaff1->dim, pwaff2->dim))
1712                 isl_die(ctx, isl_error_invalid,
1713                         "arguments should live in same space", goto error);
1714
1715         if (isl_pw_aff_is_empty(pwaff1)) {
1716                 isl_pw_aff_free(pwaff1);
1717                 return pwaff2;
1718         }
1719
1720         if (isl_pw_aff_is_empty(pwaff2)) {
1721                 isl_pw_aff_free(pwaff2);
1722                 return pwaff1;
1723         }
1724
1725         n = 2 * (pwaff1->n + 1) * (pwaff2->n + 1);
1726         res = isl_pw_aff_alloc_size(isl_space_copy(pwaff1->dim), n);
1727
1728         for (i = 0; i < pwaff1->n; ++i) {
1729                 set = isl_set_copy(pwaff1->p[i].set);
1730                 for (j = 0; j < pwaff2->n; ++j) {
1731                         struct isl_set *common;
1732                         isl_set *better;
1733
1734                         common = isl_set_intersect(
1735                                         isl_set_copy(pwaff1->p[i].set),
1736                                         isl_set_copy(pwaff2->p[j].set));
1737                         better = isl_set_from_basic_set(cmp(
1738                                         isl_aff_copy(pwaff2->p[j].aff),
1739                                         isl_aff_copy(pwaff1->p[i].aff)));
1740                         better = isl_set_intersect(common, better);
1741                         if (isl_set_plain_is_empty(better)) {
1742                                 isl_set_free(better);
1743                                 continue;
1744                         }
1745                         set = isl_set_subtract(set, isl_set_copy(better));
1746
1747                         res = isl_pw_aff_add_piece(res, better,
1748                                                 isl_aff_copy(pwaff2->p[j].aff));
1749                 }
1750                 res = isl_pw_aff_add_piece(res, set,
1751                                                 isl_aff_copy(pwaff1->p[i].aff));
1752         }
1753
1754         for (j = 0; j < pwaff2->n; ++j) {
1755                 set = isl_set_copy(pwaff2->p[j].set);
1756                 for (i = 0; i < pwaff1->n; ++i)
1757                         set = isl_set_subtract(set,
1758                                         isl_set_copy(pwaff1->p[i].set));
1759                 res = isl_pw_aff_add_piece(res, set,
1760                                                 isl_aff_copy(pwaff2->p[j].aff));
1761         }
1762
1763         isl_pw_aff_free(pwaff1);
1764         isl_pw_aff_free(pwaff2);
1765
1766         return res;
1767 error:
1768         isl_pw_aff_free(pwaff1);
1769         isl_pw_aff_free(pwaff2);
1770         return NULL;
1771 }
1772
1773 /* Compute a piecewise quasi-affine expression with a domain that
1774  * is the union of those of pwaff1 and pwaff2 and such that on each
1775  * cell, the quasi-affine expression is the maximum of those of pwaff1
1776  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
1777  * cell, then the associated expression is the defined one.
1778  */
1779 static __isl_give isl_pw_aff *pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
1780         __isl_take isl_pw_aff *pwaff2)
1781 {
1782         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_ge_basic_set);
1783 }
1784
1785 __isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
1786         __isl_take isl_pw_aff *pwaff2)
1787 {
1788         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
1789                                                         &pw_aff_union_max);
1790 }
1791
1792 /* Compute a piecewise quasi-affine expression with a domain that
1793  * is the union of those of pwaff1 and pwaff2 and such that on each
1794  * cell, the quasi-affine expression is the minimum of those of pwaff1
1795  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
1796  * cell, then the associated expression is the defined one.
1797  */
1798 static __isl_give isl_pw_aff *pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
1799         __isl_take isl_pw_aff *pwaff2)
1800 {
1801         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_le_basic_set);
1802 }
1803
1804 __isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
1805         __isl_take isl_pw_aff *pwaff2)
1806 {
1807         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
1808                                                         &pw_aff_union_min);
1809 }
1810
1811 __isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
1812         __isl_take isl_pw_aff *pwaff2, int max)
1813 {
1814         if (max)
1815                 return isl_pw_aff_union_max(pwaff1, pwaff2);
1816         else
1817                 return isl_pw_aff_union_min(pwaff1, pwaff2);
1818 }
1819
1820 /* Construct a map with as domain the domain of pwaff and
1821  * one-dimensional range corresponding to the affine expressions.
1822  */
1823 static __isl_give isl_map *map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1824 {
1825         int i;
1826         isl_space *dim;
1827         isl_map *map;
1828
1829         if (!pwaff)
1830                 return NULL;
1831
1832         dim = isl_pw_aff_get_space(pwaff);
1833         map = isl_map_empty(dim);
1834
1835         for (i = 0; i < pwaff->n; ++i) {
1836                 isl_basic_map *bmap;
1837                 isl_map *map_i;
1838
1839                 bmap = isl_basic_map_from_aff(isl_aff_copy(pwaff->p[i].aff));
1840                 map_i = isl_map_from_basic_map(bmap);
1841                 map_i = isl_map_intersect_domain(map_i,
1842                                                 isl_set_copy(pwaff->p[i].set));
1843                 map = isl_map_union_disjoint(map, map_i);
1844         }
1845
1846         isl_pw_aff_free(pwaff);
1847
1848         return map;
1849 }
1850
1851 /* Construct a map with as domain the domain of pwaff and
1852  * one-dimensional range corresponding to the affine expressions.
1853  */
1854 __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1855 {
1856         if (!pwaff)
1857                 return NULL;
1858         if (isl_space_is_set(pwaff->dim))
1859                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1860                         "space of input is not a map",
1861                         return isl_pw_aff_free(pwaff));
1862         return map_from_pw_aff(pwaff);
1863 }
1864
1865 /* Construct a one-dimensional set with as parameter domain
1866  * the domain of pwaff and the single set dimension
1867  * corresponding to the affine expressions.
1868  */
1869 __isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1870 {
1871         if (!pwaff)
1872                 return NULL;
1873         if (!isl_space_is_set(pwaff->dim))
1874                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1875                         "space of input is not a set",
1876                         return isl_pw_aff_free(pwaff));
1877         return map_from_pw_aff(pwaff);
1878 }
1879
1880 /* Return a set containing those elements in the domain
1881  * of pwaff where it is non-negative.
1882  */
1883 __isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
1884 {
1885         int i;
1886         isl_set *set;
1887
1888         if (!pwaff)
1889                 return NULL;
1890
1891         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
1892
1893         for (i = 0; i < pwaff->n; ++i) {
1894                 isl_basic_set *bset;
1895                 isl_set *set_i;
1896                 int rational;
1897
1898                 rational = isl_set_has_rational(pwaff->p[i].set);
1899                 bset = aff_nonneg_basic_set(isl_aff_copy(pwaff->p[i].aff),
1900                                                 rational);
1901                 set_i = isl_set_from_basic_set(bset);
1902                 set_i = isl_set_intersect(set_i, isl_set_copy(pwaff->p[i].set));
1903                 set = isl_set_union_disjoint(set, set_i);
1904         }
1905
1906         isl_pw_aff_free(pwaff);
1907
1908         return set;
1909 }
1910
1911 /* Return a set containing those elements in the domain
1912  * of pwaff where it is zero (if complement is 0) or not zero
1913  * (if complement is 1).
1914  */
1915 static __isl_give isl_set *pw_aff_zero_set(__isl_take isl_pw_aff *pwaff,
1916         int complement)
1917 {
1918         int i;
1919         isl_set *set;
1920
1921         if (!pwaff)
1922                 return NULL;
1923
1924         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
1925
1926         for (i = 0; i < pwaff->n; ++i) {
1927                 isl_basic_set *bset;
1928                 isl_set *set_i, *zero;
1929                 int rational;
1930
1931                 rational = isl_set_has_rational(pwaff->p[i].set);
1932                 bset = aff_zero_basic_set(isl_aff_copy(pwaff->p[i].aff),
1933                                                 rational);
1934                 zero = isl_set_from_basic_set(bset);
1935                 set_i = isl_set_copy(pwaff->p[i].set);
1936                 if (complement)
1937                         set_i = isl_set_subtract(set_i, zero);
1938                 else
1939                         set_i = isl_set_intersect(set_i, zero);
1940                 set = isl_set_union_disjoint(set, set_i);
1941         }
1942
1943         isl_pw_aff_free(pwaff);
1944
1945         return set;
1946 }
1947
1948 /* Return a set containing those elements in the domain
1949  * of pwaff where it is zero.
1950  */
1951 __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
1952 {
1953         return pw_aff_zero_set(pwaff, 0);
1954 }
1955
1956 /* Return a set containing those elements in the domain
1957  * of pwaff where it is not zero.
1958  */
1959 __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
1960 {
1961         return pw_aff_zero_set(pwaff, 1);
1962 }
1963
1964 /* Return a set containing those elements in the shared domain
1965  * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
1966  *
1967  * We compute the difference on the shared domain and then construct
1968  * the set of values where this difference is non-negative.
1969  * If strict is set, we first subtract 1 from the difference.
1970  * If equal is set, we only return the elements where pwaff1 and pwaff2
1971  * are equal.
1972  */
1973 static __isl_give isl_set *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
1974         __isl_take isl_pw_aff *pwaff2, int strict, int equal)
1975 {
1976         isl_set *set1, *set2;
1977
1978         set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
1979         set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
1980         set1 = isl_set_intersect(set1, set2);
1981         pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
1982         pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
1983         pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
1984
1985         if (strict) {
1986                 isl_space *dim = isl_set_get_space(set1);
1987                 isl_aff *aff;
1988                 aff = isl_aff_zero_on_domain(isl_local_space_from_space(dim));
1989                 aff = isl_aff_add_constant_si(aff, -1);
1990                 pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
1991         } else
1992                 isl_set_free(set1);
1993
1994         if (equal)
1995                 return isl_pw_aff_zero_set(pwaff1);
1996         return isl_pw_aff_nonneg_set(pwaff1);
1997 }
1998
1999 /* Return a set containing those elements in the shared domain
2000  * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
2001  */
2002 static __isl_give isl_set *pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
2003         __isl_take isl_pw_aff *pwaff2)
2004 {
2005         return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
2006 }
2007
2008 __isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
2009         __isl_take isl_pw_aff *pwaff2)
2010 {
2011         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_eq_set);
2012 }
2013
2014 /* Return a set containing those elements in the shared domain
2015  * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
2016  */
2017 static __isl_give isl_set *pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
2018         __isl_take isl_pw_aff *pwaff2)
2019 {
2020         return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
2021 }
2022
2023 __isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
2024         __isl_take isl_pw_aff *pwaff2)
2025 {
2026         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ge_set);
2027 }
2028
2029 /* Return a set containing those elements in the shared domain
2030  * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
2031  */
2032 static __isl_give isl_set *pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
2033         __isl_take isl_pw_aff *pwaff2)
2034 {
2035         return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
2036 }
2037
2038 __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
2039         __isl_take isl_pw_aff *pwaff2)
2040 {
2041         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_gt_set);
2042 }
2043
2044 __isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
2045         __isl_take isl_pw_aff *pwaff2)
2046 {
2047         return isl_pw_aff_ge_set(pwaff2, pwaff1);
2048 }
2049
2050 __isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
2051         __isl_take isl_pw_aff *pwaff2)
2052 {
2053         return isl_pw_aff_gt_set(pwaff2, pwaff1);
2054 }
2055
2056 /* Return a set containing those elements in the shared domain
2057  * of the elements of list1 and list2 where each element in list1
2058  * has the relation specified by "fn" with each element in list2.
2059  */
2060 static __isl_give isl_set *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
2061         __isl_take isl_pw_aff_list *list2,
2062         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
2063                                     __isl_take isl_pw_aff *pwaff2))
2064 {
2065         int i, j;
2066         isl_ctx *ctx;
2067         isl_set *set;
2068
2069         if (!list1 || !list2)
2070                 goto error;
2071
2072         ctx = isl_pw_aff_list_get_ctx(list1);
2073         if (list1->n < 1 || list2->n < 1)
2074                 isl_die(ctx, isl_error_invalid,
2075                         "list should contain at least one element", goto error);
2076
2077         set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
2078         for (i = 0; i < list1->n; ++i)
2079                 for (j = 0; j < list2->n; ++j) {
2080                         isl_set *set_ij;
2081
2082                         set_ij = fn(isl_pw_aff_copy(list1->p[i]),
2083                                     isl_pw_aff_copy(list2->p[j]));
2084                         set = isl_set_intersect(set, set_ij);
2085                 }
2086
2087         isl_pw_aff_list_free(list1);
2088         isl_pw_aff_list_free(list2);
2089         return set;
2090 error:
2091         isl_pw_aff_list_free(list1);
2092         isl_pw_aff_list_free(list2);
2093         return NULL;
2094 }
2095
2096 /* Return a set containing those elements in the shared domain
2097  * of the elements of list1 and list2 where each element in list1
2098  * is equal to each element in list2.
2099  */
2100 __isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
2101         __isl_take isl_pw_aff_list *list2)
2102 {
2103         return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
2104 }
2105
2106 __isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
2107         __isl_take isl_pw_aff_list *list2)
2108 {
2109         return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
2110 }
2111
2112 /* Return a set containing those elements in the shared domain
2113  * of the elements of list1 and list2 where each element in list1
2114  * is less than or equal to each element in list2.
2115  */
2116 __isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
2117         __isl_take isl_pw_aff_list *list2)
2118 {
2119         return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
2120 }
2121
2122 __isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
2123         __isl_take isl_pw_aff_list *list2)
2124 {
2125         return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
2126 }
2127
2128 __isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
2129         __isl_take isl_pw_aff_list *list2)
2130 {
2131         return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
2132 }
2133
2134 __isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
2135         __isl_take isl_pw_aff_list *list2)
2136 {
2137         return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
2138 }
2139
2140
2141 /* Return a set containing those elements in the shared domain
2142  * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
2143  */
2144 static __isl_give isl_set *pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
2145         __isl_take isl_pw_aff *pwaff2)
2146 {
2147         isl_set *set_lt, *set_gt;
2148
2149         set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
2150                                    isl_pw_aff_copy(pwaff2));
2151         set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
2152         return isl_set_union_disjoint(set_lt, set_gt);
2153 }
2154
2155 __isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
2156         __isl_take isl_pw_aff *pwaff2)
2157 {
2158         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ne_set);
2159 }
2160
2161 __isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
2162         isl_int v)
2163 {
2164         int i;
2165
2166         if (isl_int_is_one(v))
2167                 return pwaff;
2168         if (!isl_int_is_pos(v))
2169                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
2170                         "factor needs to be positive",
2171                         return isl_pw_aff_free(pwaff));
2172         pwaff = isl_pw_aff_cow(pwaff);
2173         if (!pwaff)
2174                 return NULL;
2175         if (pwaff->n == 0)
2176                 return pwaff;
2177
2178         for (i = 0; i < pwaff->n; ++i) {
2179                 pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v);
2180                 if (!pwaff->p[i].aff)
2181                         return isl_pw_aff_free(pwaff);
2182         }
2183
2184         return pwaff;
2185 }
2186
2187 __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
2188 {
2189         int i;
2190
2191         pwaff = isl_pw_aff_cow(pwaff);
2192         if (!pwaff)
2193                 return NULL;
2194         if (pwaff->n == 0)
2195                 return pwaff;
2196
2197         for (i = 0; i < pwaff->n; ++i) {
2198                 pwaff->p[i].aff = isl_aff_floor(pwaff->p[i].aff);
2199                 if (!pwaff->p[i].aff)
2200                         return isl_pw_aff_free(pwaff);
2201         }
2202
2203         return pwaff;
2204 }
2205
2206 __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
2207 {
2208         int i;
2209
2210         pwaff = isl_pw_aff_cow(pwaff);
2211         if (!pwaff)
2212                 return NULL;
2213         if (pwaff->n == 0)
2214                 return pwaff;
2215
2216         for (i = 0; i < pwaff->n; ++i) {
2217                 pwaff->p[i].aff = isl_aff_ceil(pwaff->p[i].aff);
2218                 if (!pwaff->p[i].aff)
2219                         return isl_pw_aff_free(pwaff);
2220         }
2221
2222         return pwaff;
2223 }
2224
2225 /* Assuming that "cond1" and "cond2" are disjoint,
2226  * return an affine expression that is equal to pwaff1 on cond1
2227  * and to pwaff2 on cond2.
2228  */
2229 static __isl_give isl_pw_aff *isl_pw_aff_select(
2230         __isl_take isl_set *cond1, __isl_take isl_pw_aff *pwaff1,
2231         __isl_take isl_set *cond2, __isl_take isl_pw_aff *pwaff2)
2232 {
2233         pwaff1 = isl_pw_aff_intersect_domain(pwaff1, cond1);
2234         pwaff2 = isl_pw_aff_intersect_domain(pwaff2, cond2);
2235
2236         return isl_pw_aff_add_disjoint(pwaff1, pwaff2);
2237 }
2238
2239 /* Return an affine expression that is equal to pwaff_true for elements
2240  * where "cond" is non-zero and to pwaff_false for elements where "cond"
2241  * is zero.
2242  * That is, return cond ? pwaff_true : pwaff_false;
2243  */
2244 __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond,
2245         __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
2246 {
2247         isl_set *cond_true, *cond_false;
2248
2249         cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond));
2250         cond_false = isl_pw_aff_zero_set(cond);
2251         return isl_pw_aff_select(cond_true, pwaff_true,
2252                                  cond_false, pwaff_false);
2253 }
2254
2255 int isl_aff_is_cst(__isl_keep isl_aff *aff)
2256 {
2257         if (!aff)
2258                 return -1;
2259
2260         return isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2) == -1;
2261 }
2262
2263 /* Check whether pwaff is a piecewise constant.
2264  */
2265 int isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
2266 {
2267         int i;
2268
2269         if (!pwaff)
2270                 return -1;
2271
2272         for (i = 0; i < pwaff->n; ++i) {
2273                 int is_cst = isl_aff_is_cst(pwaff->p[i].aff);
2274                 if (is_cst < 0 || !is_cst)
2275                         return is_cst;
2276         }
2277
2278         return 1;
2279 }
2280
2281 __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
2282         __isl_take isl_aff *aff2)
2283 {
2284         if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
2285                 return isl_aff_mul(aff2, aff1);
2286
2287         if (!isl_aff_is_cst(aff2))
2288                 isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,
2289                         "at least one affine expression should be constant",
2290                         goto error);
2291
2292         aff1 = isl_aff_cow(aff1);
2293         if (!aff1 || !aff2)
2294                 goto error;
2295
2296         aff1 = isl_aff_scale(aff1, aff2->v->el[1]);
2297         aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]);
2298
2299         isl_aff_free(aff2);
2300         return aff1;
2301 error:
2302         isl_aff_free(aff1);
2303         isl_aff_free(aff2);
2304         return NULL;
2305 }
2306
2307 /* Divide "aff1" by "aff2", assuming "aff2" is a piecewise constant.
2308  */
2309 __isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1,
2310         __isl_take isl_aff *aff2)
2311 {
2312         int is_cst;
2313         int neg;
2314
2315         is_cst = isl_aff_is_cst(aff2);
2316         if (is_cst < 0)
2317                 goto error;
2318         if (!is_cst)
2319                 isl_die(isl_aff_get_ctx(aff2), isl_error_invalid,
2320                         "second argument should be a constant", goto error);
2321
2322         if (!aff2)
2323                 goto error;
2324
2325         neg = isl_int_is_neg(aff2->v->el[1]);
2326         if (neg) {
2327                 isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
2328                 isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
2329         }
2330
2331         aff1 = isl_aff_scale(aff1, aff2->v->el[0]);
2332         aff1 = isl_aff_scale_down(aff1, aff2->v->el[1]);
2333
2334         if (neg) {
2335                 isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
2336                 isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
2337         }
2338
2339         isl_aff_free(aff2);
2340         return aff1;
2341 error:
2342         isl_aff_free(aff1);
2343         isl_aff_free(aff2);
2344         return NULL;
2345 }
2346
2347 static __isl_give isl_pw_aff *pw_aff_add(__isl_take isl_pw_aff *pwaff1,
2348         __isl_take isl_pw_aff *pwaff2)
2349 {
2350         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
2351 }
2352
2353 __isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
2354         __isl_take isl_pw_aff *pwaff2)
2355 {
2356         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_add);
2357 }
2358
2359 __isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1,
2360         __isl_take isl_pw_aff *pwaff2)
2361 {
2362         return isl_pw_aff_union_add_(pwaff1, pwaff2);
2363 }
2364
2365 static __isl_give isl_pw_aff *pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
2366         __isl_take isl_pw_aff *pwaff2)
2367 {
2368         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
2369 }
2370
2371 __isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
2372         __isl_take isl_pw_aff *pwaff2)
2373 {
2374         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_mul);
2375 }
2376
2377 static __isl_give isl_pw_aff *pw_aff_div(__isl_take isl_pw_aff *pa1,
2378         __isl_take isl_pw_aff *pa2)
2379 {
2380         return isl_pw_aff_on_shared_domain(pa1, pa2, &isl_aff_div);
2381 }
2382
2383 /* Divide "pa1" by "pa2", assuming "pa2" is a piecewise constant.
2384  */
2385 __isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1,
2386         __isl_take isl_pw_aff *pa2)
2387 {
2388         int is_cst;
2389
2390         is_cst = isl_pw_aff_is_cst(pa2);
2391         if (is_cst < 0)
2392                 goto error;
2393         if (!is_cst)
2394                 isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
2395                         "second argument should be a piecewise constant",
2396                         goto error);
2397         return isl_pw_aff_align_params_pw_pw_and(pa1, pa2, &pw_aff_div);
2398 error:
2399         isl_pw_aff_free(pa1);
2400         isl_pw_aff_free(pa2);
2401         return NULL;
2402 }
2403
2404 /* Compute the quotient of the integer division of "pa1" by "pa2"
2405  * with rounding towards zero.
2406  * "pa2" is assumed to be a piecewise constant.
2407  *
2408  * In particular, return
2409  *
2410  *      pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)
2411  *
2412  */
2413 __isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1,
2414         __isl_take isl_pw_aff *pa2)
2415 {
2416         int is_cst;
2417         isl_set *cond;
2418         isl_pw_aff *f, *c;
2419
2420         is_cst = isl_pw_aff_is_cst(pa2);
2421         if (is_cst < 0)
2422                 goto error;
2423         if (!is_cst)
2424                 isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
2425                         "second argument should be a piecewise constant",
2426                         goto error);
2427
2428         pa1 = isl_pw_aff_div(pa1, pa2);
2429
2430         cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1));
2431         f = isl_pw_aff_floor(isl_pw_aff_copy(pa1));
2432         c = isl_pw_aff_ceil(pa1);
2433         return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c);
2434 error:
2435         isl_pw_aff_free(pa1);
2436         isl_pw_aff_free(pa2);
2437         return NULL;
2438 }
2439
2440 /* Compute the remainder of the integer division of "pa1" by "pa2"
2441  * with rounding towards zero.
2442  * "pa2" is assumed to be a piecewise constant.
2443  *
2444  * In particular, return
2445  *
2446  *      pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2))
2447  *
2448  */
2449 __isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1,
2450         __isl_take isl_pw_aff *pa2)
2451 {
2452         int is_cst;
2453         isl_pw_aff *res;
2454
2455         is_cst = isl_pw_aff_is_cst(pa2);
2456         if (is_cst < 0)
2457                 goto error;
2458         if (!is_cst)
2459                 isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
2460                         "second argument should be a piecewise constant",
2461                         goto error);
2462         res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2));
2463         res = isl_pw_aff_mul(pa2, res);
2464         res = isl_pw_aff_sub(pa1, res);
2465         return res;
2466 error:
2467         isl_pw_aff_free(pa1);
2468         isl_pw_aff_free(pa2);
2469         return NULL;
2470 }
2471
2472 static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
2473         __isl_take isl_pw_aff *pwaff2)
2474 {
2475         isl_set *le;
2476         isl_set *dom;
2477
2478         dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
2479                                 isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
2480         le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
2481                                 isl_pw_aff_copy(pwaff2));
2482         dom = isl_set_subtract(dom, isl_set_copy(le));
2483         return isl_pw_aff_select(le, pwaff1, dom, pwaff2);
2484 }
2485
2486 __isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
2487         __isl_take isl_pw_aff *pwaff2)
2488 {
2489         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_min);
2490 }
2491
2492 static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
2493         __isl_take isl_pw_aff *pwaff2)
2494 {
2495         isl_set *ge;
2496         isl_set *dom;
2497
2498         dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
2499                                 isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
2500         ge = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
2501                                 isl_pw_aff_copy(pwaff2));
2502         dom = isl_set_subtract(dom, isl_set_copy(ge));
2503         return isl_pw_aff_select(ge, pwaff1, dom, pwaff2);
2504 }
2505
2506 __isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
2507         __isl_take isl_pw_aff *pwaff2)
2508 {
2509         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_max);
2510 }
2511
2512 static __isl_give isl_pw_aff *pw_aff_list_reduce(
2513         __isl_take isl_pw_aff_list *list,
2514         __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pwaff1,
2515                                         __isl_take isl_pw_aff *pwaff2))
2516 {
2517         int i;
2518         isl_ctx *ctx;
2519         isl_pw_aff *res;
2520
2521         if (!list)
2522                 return NULL;
2523
2524         ctx = isl_pw_aff_list_get_ctx(list);
2525         if (list->n < 1)
2526                 isl_die(ctx, isl_error_invalid,
2527                         "list should contain at least one element",
2528                         return isl_pw_aff_list_free(list));
2529
2530         res = isl_pw_aff_copy(list->p[0]);
2531         for (i = 1; i < list->n; ++i)
2532                 res = fn(res, isl_pw_aff_copy(list->p[i]));
2533
2534         isl_pw_aff_list_free(list);
2535         return res;
2536 }
2537
2538 /* Return an isl_pw_aff that maps each element in the intersection of the
2539  * domains of the elements of list to the minimal corresponding affine
2540  * expression.
2541  */
2542 __isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
2543 {
2544         return pw_aff_list_reduce(list, &isl_pw_aff_min);
2545 }
2546
2547 /* Return an isl_pw_aff that maps each element in the intersection of the
2548  * domains of the elements of list to the maximal corresponding affine
2549  * expression.
2550  */
2551 __isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
2552 {
2553         return pw_aff_list_reduce(list, &isl_pw_aff_max);
2554 }
2555
2556 /* Mark the domains of "pwaff" as rational.
2557  */
2558 __isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff)
2559 {
2560         int i;
2561
2562         pwaff = isl_pw_aff_cow(pwaff);
2563         if (!pwaff)
2564                 return NULL;
2565         if (pwaff->n == 0)
2566                 return pwaff;
2567
2568         for (i = 0; i < pwaff->n; ++i) {
2569                 pwaff->p[i].set = isl_set_set_rational(pwaff->p[i].set);
2570                 if (!pwaff->p[i].set)
2571                         return isl_pw_aff_free(pwaff);
2572         }
2573
2574         return pwaff;
2575 }
2576
2577 /* Mark the domains of the elements of "list" as rational.
2578  */
2579 __isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational(
2580         __isl_take isl_pw_aff_list *list)
2581 {
2582         int i;
2583
2584         if (!list)
2585                 return NULL;
2586         if (list->n == 0)
2587                 return list;
2588
2589         for (i = 0; i < list->n; ++i) {
2590                 isl_pw_aff *pa;
2591
2592                 pa = isl_pw_aff_list_get_pw_aff(list, i);
2593                 pa = isl_pw_aff_set_rational(pa);
2594                 list = isl_pw_aff_list_set_pw_aff(list, i, pa);
2595         }
2596
2597         return list;
2598 }
2599
2600 #undef BASE
2601 #define BASE aff
2602
2603 #include <isl_multi_templ.c>
2604
2605 /* Create an isl_pw_multi_aff with the given isl_multi_aff on a universe
2606  * domain.
2607  */
2608 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff(
2609         __isl_take isl_multi_aff *ma)
2610 {
2611         isl_set *dom = isl_set_universe(isl_multi_aff_get_domain_space(ma));
2612         return isl_pw_multi_aff_alloc(dom, ma);
2613 }
2614
2615 /* Create a piecewise multi-affine expression in the given space that maps each
2616  * input dimension to the corresponding output dimension.
2617  */
2618 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
2619         __isl_take isl_space *space)
2620 {
2621         return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space));
2622 }
2623
2624 __isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *maff1,
2625         __isl_take isl_multi_aff *maff2)
2626 {
2627         int i;
2628         isl_ctx *ctx;
2629
2630         maff1 = isl_multi_aff_cow(maff1);
2631         if (!maff1 || !maff2)
2632                 goto error;
2633
2634         ctx = isl_multi_aff_get_ctx(maff1);
2635         if (!isl_space_is_equal(maff1->space, maff2->space))
2636                 isl_die(ctx, isl_error_invalid,
2637                         "spaces don't match", goto error);
2638
2639         for (i = 0; i < maff1->n; ++i) {
2640                 maff1->p[i] = isl_aff_add(maff1->p[i],
2641                                             isl_aff_copy(maff2->p[i]));
2642                 if (!maff1->p[i])
2643                         goto error;
2644         }
2645
2646         isl_multi_aff_free(maff2);
2647         return maff1;
2648 error:
2649         isl_multi_aff_free(maff1);
2650         isl_multi_aff_free(maff2);
2651         return NULL;
2652 }
2653
2654 /* Given two multi-affine expressions A -> B and C -> D,
2655  * construct a multi-affine expression [A -> C] -> [B -> D].
2656  */
2657 __isl_give isl_multi_aff *isl_multi_aff_product(
2658         __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
2659 {
2660         int i;
2661         isl_aff *aff;
2662         isl_space *space;
2663         isl_multi_aff *res;
2664         int in1, in2, out1, out2;
2665
2666         in1 = isl_multi_aff_dim(ma1, isl_dim_in);
2667         in2 = isl_multi_aff_dim(ma2, isl_dim_in);
2668         out1 = isl_multi_aff_dim(ma1, isl_dim_out);
2669         out2 = isl_multi_aff_dim(ma2, isl_dim_out);
2670         space = isl_space_product(isl_multi_aff_get_space(ma1),
2671                                   isl_multi_aff_get_space(ma2));
2672         res = isl_multi_aff_alloc(isl_space_copy(space));
2673         space = isl_space_domain(space);
2674
2675         for (i = 0; i < out1; ++i) {
2676                 aff = isl_multi_aff_get_aff(ma1, i);
2677                 aff = isl_aff_insert_dims(aff, isl_dim_in, in1, in2);
2678                 aff = isl_aff_reset_domain_space(aff, isl_space_copy(space));
2679                 res = isl_multi_aff_set_aff(res, i, aff);
2680         }
2681
2682         for (i = 0; i < out2; ++i) {
2683                 aff = isl_multi_aff_get_aff(ma2, i);
2684                 aff = isl_aff_insert_dims(aff, isl_dim_in, 0, in1);
2685                 aff = isl_aff_reset_domain_space(aff, isl_space_copy(space));
2686                 res = isl_multi_aff_set_aff(res, out1 + i, aff);
2687         }
2688
2689         isl_space_free(space);
2690         isl_multi_aff_free(ma1);
2691         isl_multi_aff_free(ma2);
2692         return res;
2693 }
2694
2695 /* Exploit the equalities in "eq" to simplify the affine expressions.
2696  */
2697 static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
2698         __isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq)
2699 {
2700         int i;
2701
2702         maff = isl_multi_aff_cow(maff);
2703         if (!maff || !eq)
2704                 goto error;
2705
2706         for (i = 0; i < maff->n; ++i) {
2707                 maff->p[i] = isl_aff_substitute_equalities(maff->p[i],
2708                                                     isl_basic_set_copy(eq));
2709                 if (!maff->p[i])
2710                         goto error;
2711         }
2712
2713         isl_basic_set_free(eq);
2714         return maff;
2715 error:
2716         isl_basic_set_free(eq);
2717         isl_multi_aff_free(maff);
2718         return NULL;
2719 }
2720
2721 __isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
2722         isl_int f)
2723 {
2724         int i;
2725
2726         maff = isl_multi_aff_cow(maff);
2727         if (!maff)
2728                 return NULL;
2729
2730         for (i = 0; i < maff->n; ++i) {
2731                 maff->p[i] = isl_aff_scale(maff->p[i], f);
2732                 if (!maff->p[i])
2733                         return isl_multi_aff_free(maff);
2734         }
2735
2736         return maff;
2737 }
2738
2739 __isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_set *dom,
2740         __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
2741 {
2742         maff1 = isl_multi_aff_add(maff1, maff2);
2743         maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
2744         return maff1;
2745 }
2746
2747 int isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
2748 {
2749         if (!maff)
2750                 return -1;
2751
2752         return 0;
2753 }
2754
2755 int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1,
2756         __isl_keep isl_multi_aff *maff2)
2757 {
2758         int i;
2759         int equal;
2760
2761         if (!maff1 || !maff2)
2762                 return -1;
2763         if (maff1->n != maff2->n)
2764                 return 0;
2765         equal = isl_space_is_equal(maff1->space, maff2->space);
2766         if (equal < 0 || !equal)
2767                 return equal;
2768
2769         for (i = 0; i < maff1->n; ++i) {
2770                 equal = isl_aff_plain_is_equal(maff1->p[i], maff2->p[i]);
2771                 if (equal < 0 || !equal)
2772                         return equal;
2773         }
2774
2775         return 1;
2776 }
2777
2778 /* Return the set of domain elements where "ma1" is lexicographically
2779  * smaller than or equal to "ma2".
2780  */
2781 __isl_give isl_set *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1,
2782         __isl_take isl_multi_aff *ma2)
2783 {
2784         return isl_multi_aff_lex_ge_set(ma2, ma1);
2785 }
2786
2787 /* Return the set of domain elements where "ma1" is lexicographically
2788  * greater than or equal to "ma2".
2789  */
2790 __isl_give isl_set *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1,
2791         __isl_take isl_multi_aff *ma2)
2792 {
2793         isl_space *space;
2794         isl_map *map1, *map2;
2795         isl_map *map, *ge;
2796
2797         map1 = isl_map_from_multi_aff(ma1);
2798         map2 = isl_map_from_multi_aff(ma2);
2799         map = isl_map_range_product(map1, map2);
2800         space = isl_space_range(isl_map_get_space(map));
2801         space = isl_space_domain(isl_space_unwrap(space));
2802         ge = isl_map_lex_ge(space);
2803         map = isl_map_intersect_range(map, isl_map_wrap(ge));
2804
2805         return isl_map_domain(map);
2806 }
2807
2808 #undef PW
2809 #define PW isl_pw_multi_aff
2810 #undef EL
2811 #define EL isl_multi_aff
2812 #undef EL_IS_ZERO
2813 #define EL_IS_ZERO is_empty
2814 #undef ZERO
2815 #define ZERO empty
2816 #undef IS_ZERO
2817 #define IS_ZERO is_empty
2818 #undef FIELD
2819 #define FIELD maff
2820 #undef DEFAULT_IS_ZERO
2821 #define DEFAULT_IS_ZERO 0
2822
2823 #define NO_NEG
2824 #define NO_EVAL
2825 #define NO_OPT
2826 #define NO_INVOLVES_DIMS
2827 #define NO_MOVE_DIMS
2828 #define NO_INSERT_DIMS
2829 #define NO_LIFT
2830 #define NO_MORPH
2831
2832 #include <isl_pw_templ.c>
2833
2834 #undef UNION
2835 #define UNION isl_union_pw_multi_aff
2836 #undef PART
2837 #define PART isl_pw_multi_aff
2838 #undef PARTS
2839 #define PARTS pw_multi_aff
2840 #define ALIGN_DOMAIN
2841
2842 #define NO_EVAL
2843
2844 #include <isl_union_templ.c>
2845
2846 /* Given a function "cmp" that returns the set of elements where
2847  * "ma1" is "better" than "ma2", return the intersection of this
2848  * set with "dom1" and "dom2".
2849  */
2850 static __isl_give isl_set *shared_and_better(__isl_keep isl_set *dom1,
2851         __isl_keep isl_set *dom2, __isl_keep isl_multi_aff *ma1,
2852         __isl_keep isl_multi_aff *ma2,
2853         __isl_give isl_set *(*cmp)(__isl_take isl_multi_aff *ma1,
2854                                     __isl_take isl_multi_aff *ma2))
2855 {
2856         isl_set *common;
2857         isl_set *better;
2858         int is_empty;
2859
2860         common = isl_set_intersect(isl_set_copy(dom1), isl_set_copy(dom2));
2861         is_empty = isl_set_plain_is_empty(common);
2862         if (is_empty >= 0 && is_empty)
2863                 return common;
2864         if (is_empty < 0)
2865                 return isl_set_free(common);
2866         better = cmp(isl_multi_aff_copy(ma1), isl_multi_aff_copy(ma2));
2867         better = isl_set_intersect(common, better);
2868
2869         return better;
2870 }
2871
2872 /* Given a function "cmp" that returns the set of elements where
2873  * "ma1" is "better" than "ma2", return a piecewise multi affine
2874  * expression defined on the union of the definition domains
2875  * of "pma1" and "pma2" that maps to the "best" of "pma1" and
2876  * "pma2" on each cell.  If only one of the two input functions
2877  * is defined on a given cell, then it is considered the best.
2878  */
2879 static __isl_give isl_pw_multi_aff *pw_multi_aff_union_opt(
2880         __isl_take isl_pw_multi_aff *pma1,
2881         __isl_take isl_pw_multi_aff *pma2,
2882         __isl_give isl_set *(*cmp)(__isl_take isl_multi_aff *ma1,
2883                                     __isl_take isl_multi_aff *ma2))
2884 {
2885         int i, j, n;
2886         isl_pw_multi_aff *res = NULL;
2887         isl_ctx *ctx;
2888         isl_set *set = NULL;
2889
2890         if (!pma1 || !pma2)
2891                 goto error;
2892
2893         ctx = isl_space_get_ctx(pma1->dim);
2894         if (!isl_space_is_equal(pma1->dim, pma2->dim))
2895                 isl_die(ctx, isl_error_invalid,
2896                         "arguments should live in the same space", goto error);
2897
2898         if (isl_pw_multi_aff_is_empty(pma1)) {
2899                 isl_pw_multi_aff_free(pma1);
2900                 return pma2;
2901         }
2902
2903         if (isl_pw_multi_aff_is_empty(pma2)) {
2904                 isl_pw_multi_aff_free(pma2);
2905                 return pma1;
2906         }
2907
2908         n = 2 * (pma1->n + 1) * (pma2->n + 1);
2909         res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma1->dim), n);
2910
2911         for (i = 0; i < pma1->n; ++i) {
2912                 set = isl_set_copy(pma1->p[i].set);
2913                 for (j = 0; j < pma2->n; ++j) {
2914                         isl_set *better;
2915                         int is_empty;
2916
2917                         better = shared_and_better(pma2->p[j].set,
2918                                         pma1->p[i].set, pma2->p[j].maff,
2919                                         pma1->p[i].maff, cmp);
2920                         is_empty = isl_set_plain_is_empty(better);
2921                         if (is_empty < 0 || is_empty) {
2922                                 isl_set_free(better);
2923                                 if (is_empty < 0)
2924                                         goto error;
2925                                 continue;
2926                         }
2927                         set = isl_set_subtract(set, isl_set_copy(better));
2928
2929                         res = isl_pw_multi_aff_add_piece(res, better,
2930                                         isl_multi_aff_copy(pma2->p[j].maff));
2931                 }
2932                 res = isl_pw_multi_aff_add_piece(res, set,
2933                                         isl_multi_aff_copy(pma1->p[i].maff));
2934         }
2935
2936         for (j = 0; j < pma2->n; ++j) {
2937                 set = isl_set_copy(pma2->p[j].set);
2938                 for (i = 0; i < pma1->n; ++i)
2939                         set = isl_set_subtract(set,
2940                                         isl_set_copy(pma1->p[i].set));
2941                 res = isl_pw_multi_aff_add_piece(res, set,
2942                                         isl_multi_aff_copy(pma2->p[j].maff));
2943         }
2944
2945         isl_pw_multi_aff_free(pma1);
2946         isl_pw_multi_aff_free(pma2);
2947
2948         return res;
2949 error:
2950         isl_pw_multi_aff_free(pma1);
2951         isl_pw_multi_aff_free(pma2);
2952         isl_set_free(set);
2953         return isl_pw_multi_aff_free(res);
2954 }
2955
2956 static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmax(
2957         __isl_take isl_pw_multi_aff *pma1,
2958         __isl_take isl_pw_multi_aff *pma2)
2959 {
2960         return pw_multi_aff_union_opt(pma1, pma2, &isl_multi_aff_lex_ge_set);
2961 }
2962
2963 /* Given two piecewise multi affine expressions, return a piecewise
2964  * multi-affine expression defined on the union of the definition domains
2965  * of the inputs that is equal to the lexicographic maximum of the two
2966  * inputs on each cell.  If only one of the two inputs is defined on
2967  * a given cell, then it is considered to be the maximum.
2968  */
2969 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax(
2970         __isl_take isl_pw_multi_aff *pma1,
2971         __isl_take isl_pw_multi_aff *pma2)
2972 {
2973         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
2974                                                     &pw_multi_aff_union_lexmax);
2975 }
2976
2977 static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmin(
2978         __isl_take isl_pw_multi_aff *pma1,
2979         __isl_take isl_pw_multi_aff *pma2)
2980 {
2981         return pw_multi_aff_union_opt(pma1, pma2, &isl_multi_aff_lex_le_set);
2982 }
2983
2984 /* Given two piecewise multi affine expressions, return a piecewise
2985  * multi-affine expression defined on the union of the definition domains
2986  * of the inputs that is equal to the lexicographic minimum of the two
2987  * inputs on each cell.  If only one of the two inputs is defined on
2988  * a given cell, then it is considered to be the minimum.
2989  */
2990 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin(
2991         __isl_take isl_pw_multi_aff *pma1,
2992         __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_union_lexmin);
2996 }
2997
2998 static __isl_give isl_pw_multi_aff *pw_multi_aff_add(
2999         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3000 {
3001         return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
3002                                                 &isl_multi_aff_add);
3003 }
3004
3005 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
3006         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3007 {
3008         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
3009                                                 &pw_multi_aff_add);
3010 }
3011
3012 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add(
3013         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3014 {
3015         return isl_pw_multi_aff_union_add_(pma1, pma2);
3016 }
3017
3018 /* Given two piecewise multi-affine expressions A -> B and C -> D,
3019  * construct a piecewise multi-affine expression [A -> C] -> [B -> D].
3020  */
3021 static __isl_give isl_pw_multi_aff *pw_multi_aff_product(
3022         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3023 {
3024         int i, j, n;
3025         isl_space *space;
3026         isl_pw_multi_aff *res;
3027
3028         if (!pma1 || !pma2)
3029                 goto error;
3030
3031         n = pma1->n * pma2->n;
3032         space = isl_space_product(isl_space_copy(pma1->dim),
3033                                   isl_space_copy(pma2->dim));
3034         res = isl_pw_multi_aff_alloc_size(space, n);
3035
3036         for (i = 0; i < pma1->n; ++i) {
3037                 for (j = 0; j < pma2->n; ++j) {
3038                         isl_set *domain;
3039                         isl_multi_aff *ma;
3040
3041                         domain = isl_set_product(isl_set_copy(pma1->p[i].set),
3042                                                  isl_set_copy(pma2->p[j].set));
3043                         ma = isl_multi_aff_product(
3044                                         isl_multi_aff_copy(pma1->p[i].maff),
3045                                         isl_multi_aff_copy(pma2->p[i].maff));
3046                         res = isl_pw_multi_aff_add_piece(res, domain, ma);
3047                 }
3048         }
3049
3050         isl_pw_multi_aff_free(pma1);
3051         isl_pw_multi_aff_free(pma2);
3052         return res;
3053 error:
3054         isl_pw_multi_aff_free(pma1);
3055         isl_pw_multi_aff_free(pma2);
3056         return NULL;
3057 }
3058
3059 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_product(
3060         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
3061 {
3062         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
3063                                                 &pw_multi_aff_product);
3064 }
3065
3066 /* Construct a map mapping the domain of the piecewise multi-affine expression
3067  * to its range, with each dimension in the range equated to the
3068  * corresponding affine expression on its cell.
3069  */
3070 __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
3071 {
3072         int i;
3073         isl_map *map;
3074
3075         if (!pma)
3076                 return NULL;
3077
3078         map = isl_map_empty(isl_pw_multi_aff_get_space(pma));
3079
3080         for (i = 0; i < pma->n; ++i) {
3081                 isl_multi_aff *maff;
3082                 isl_basic_map *bmap;
3083                 isl_map *map_i;
3084
3085                 maff = isl_multi_aff_copy(pma->p[i].maff);
3086                 bmap = isl_basic_map_from_multi_aff(maff);
3087                 map_i = isl_map_from_basic_map(bmap);
3088                 map_i = isl_map_intersect_domain(map_i,
3089                                                 isl_set_copy(pma->p[i].set));
3090                 map = isl_map_union_disjoint(map, map_i);
3091         }
3092
3093         isl_pw_multi_aff_free(pma);
3094         return map;
3095 }
3096
3097 __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
3098 {
3099         if (!pma)
3100                 return NULL;
3101
3102         if (!isl_space_is_set(pma->dim))
3103                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
3104                         "isl_pw_multi_aff cannot be converted into an isl_set",
3105                         return isl_pw_multi_aff_free(pma));
3106
3107         return isl_map_from_pw_multi_aff(pma);
3108 }
3109
3110 /* Given a basic map with a single output dimension that is defined
3111  * in terms of the parameters and input dimensions using an equality,
3112  * extract an isl_aff that expresses the output dimension in terms
3113  * of the parameters and input dimensions.
3114  *
3115  * Since some applications expect the result of isl_pw_multi_aff_from_map
3116  * to only contain integer affine expressions, we compute the floor
3117  * of the expression before returning.
3118  *
3119  * This function shares some similarities with
3120  * isl_basic_map_has_defining_equality and isl_constraint_get_bound.
3121  */
3122 static __isl_give isl_aff *extract_isl_aff_from_basic_map(
3123         __isl_take isl_basic_map *bmap)
3124 {
3125         int i;
3126         unsigned offset;
3127         unsigned total;
3128         isl_local_space *ls;
3129         isl_aff *aff;
3130
3131         if (!bmap)
3132                 return NULL;
3133         if (isl_basic_map_dim(bmap, isl_dim_out) != 1)
3134                 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
3135                         "basic map should have a single output dimension",
3136                         goto error);
3137         offset = isl_basic_map_offset(bmap, isl_dim_out);
3138         total = isl_basic_map_total_dim(bmap);
3139         for (i = 0; i < bmap->n_eq; ++i) {
3140                 if (isl_int_is_zero(bmap->eq[i][offset]))
3141                         continue;
3142                 if (isl_seq_first_non_zero(bmap->eq[i] + offset + 1,
3143                                            1 + total - (offset + 1)) != -1)
3144                         continue;
3145                 break;
3146         }
3147         if (i >= bmap->n_eq)
3148                 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
3149                         "unable to find suitable equality", goto error);
3150         ls = isl_basic_map_get_local_space(bmap);
3151         aff = isl_aff_alloc(isl_local_space_domain(ls));
3152         if (!aff)
3153                 goto error;
3154         if (isl_int_is_neg(bmap->eq[i][offset]))
3155                 isl_seq_cpy(aff->v->el + 1, bmap->eq[i], offset);
3156         else
3157                 isl_seq_neg(aff->v->el + 1, bmap->eq[i], offset);
3158         isl_seq_clr(aff->v->el + 1 + offset, aff->v->size - (1 + offset));
3159         isl_int_abs(aff->v->el[0], bmap->eq[i][offset]);
3160         isl_basic_map_free(bmap);
3161
3162         aff = isl_aff_remove_unused_divs(aff);
3163         aff = isl_aff_floor(aff);
3164         return aff;
3165 error:
3166         isl_basic_map_free(bmap);
3167         return NULL;
3168 }
3169
3170 /* Given a basic map where each output dimension is defined
3171  * in terms of the parameters and input dimensions using an equality,
3172  * extract an isl_multi_aff that expresses the output dimensions in terms
3173  * of the parameters and input dimensions.
3174  */
3175 static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map(
3176         __isl_take isl_basic_map *bmap)
3177 {
3178         int i;
3179         unsigned n_out;
3180         isl_multi_aff *ma;
3181
3182         if (!bmap)
3183                 return NULL;
3184
3185         ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap));
3186         n_out = isl_basic_map_dim(bmap, isl_dim_out);
3187
3188         for (i = 0; i < n_out; ++i) {
3189                 isl_basic_map *bmap_i;
3190                 isl_aff *aff;
3191
3192                 bmap_i = isl_basic_map_copy(bmap);
3193                 bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out,
3194                                                         i + 1, n_out - (1 + i));
3195                 bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out, 0, i);
3196                 aff = extract_isl_aff_from_basic_map(bmap_i);
3197                 ma = isl_multi_aff_set_aff(ma, i, aff);
3198         }
3199
3200         isl_basic_map_free(bmap);
3201
3202         return ma;
3203 }
3204
3205 /* Create an isl_pw_multi_aff that is equivalent to
3206  * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain).
3207  * The given basic map is such that each output dimension is defined
3208  * in terms of the parameters and input dimensions using an equality.
3209  */
3210 static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
3211         __isl_take isl_set *domain, __isl_take isl_basic_map *bmap)
3212 {
3213         isl_multi_aff *ma;
3214
3215         ma = extract_isl_multi_aff_from_basic_map(bmap);
3216         return isl_pw_multi_aff_alloc(domain, ma);
3217 }
3218
3219 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
3220  * This obviously only works if the input "map" is single-valued.
3221  * If so, we compute the lexicographic minimum of the image in the form
3222  * of an isl_pw_multi_aff.  Since the image is unique, it is equal
3223  * to its lexicographic minimum.
3224  * If the input is not single-valued, we produce an error.
3225  */
3226 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_base(
3227         __isl_take isl_map *map)
3228 {
3229         int i;
3230         int sv;
3231         isl_pw_multi_aff *pma;
3232
3233         sv = isl_map_is_single_valued(map);
3234         if (sv < 0)
3235                 goto error;
3236         if (!sv)
3237                 isl_die(isl_map_get_ctx(map), isl_error_invalid,
3238                         "map is not single-valued", goto error);
3239         map = isl_map_make_disjoint(map);
3240         if (!map)
3241                 return NULL;
3242
3243         pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
3244
3245         for (i = 0; i < map->n; ++i) {
3246                 isl_pw_multi_aff *pma_i;
3247                 isl_basic_map *bmap;
3248                 bmap = isl_basic_map_copy(map->p[i]);
3249                 pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
3250                 pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
3251         }
3252
3253         isl_map_free(map);
3254         return pma;
3255 error:
3256         isl_map_free(map);
3257         return NULL;
3258 }
3259
3260 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
3261  * taking into account that the output dimension at position "d"
3262  * can be represented as
3263  *
3264  *      x = floor((e(...) + c1) / m)
3265  *
3266  * given that constraint "i" is of the form
3267  *
3268  *      e(...) + c1 - m x >= 0
3269  *
3270  *
3271  * Let "map" be of the form
3272  *
3273  *      A -> B
3274  *
3275  * We construct a mapping
3276  *
3277  *      A -> [A -> x = floor(...)]
3278  *
3279  * apply that to the map, obtaining
3280  *
3281  *      [A -> x = floor(...)] -> B
3282  *
3283  * and equate dimension "d" to x.
3284  * We then compute a isl_pw_multi_aff representation of the resulting map
3285  * and plug in the mapping above.
3286  */
3287 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div(
3288         __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i)
3289 {
3290         isl_ctx *ctx;
3291         isl_space *space;
3292         isl_local_space *ls;
3293         isl_multi_aff *ma;
3294         isl_aff *aff;
3295         isl_vec *v;
3296         isl_map *insert;
3297         int offset;
3298         int n;
3299         int n_in;
3300         isl_pw_multi_aff *pma;
3301         int is_set;
3302
3303         is_set = isl_map_is_set(map);
3304
3305         offset = isl_basic_map_offset(hull, isl_dim_out);
3306         ctx = isl_map_get_ctx(map);
3307         space = isl_space_domain(isl_map_get_space(map));
3308         n_in = isl_space_dim(space, isl_dim_set);
3309         n = isl_space_dim(space, isl_dim_all);
3310
3311         v = isl_vec_alloc(ctx, 1 + 1 + n);
3312         if (v) {
3313                 isl_int_neg(v->el[0], hull->ineq[i][offset + d]);
3314                 isl_seq_cpy(v->el + 1, hull->ineq[i], 1 + n);
3315         }
3316         isl_basic_map_free(hull);
3317
3318         ls = isl_local_space_from_space(isl_space_copy(space));
3319         aff = isl_aff_alloc_vec(ls, v);
3320         aff = isl_aff_floor(aff);
3321         if (is_set) {
3322                 isl_space_free(space);
3323                 ma = isl_multi_aff_from_aff(aff);
3324         } else {
3325                 ma = isl_multi_aff_identity(isl_space_map_from_set(space));
3326                 ma = isl_multi_aff_range_product(ma,
3327                                                 isl_multi_aff_from_aff(aff));
3328         }
3329
3330         insert = isl_map_from_multi_aff(isl_multi_aff_copy(ma));
3331         map = isl_map_apply_domain(map, insert);
3332         map = isl_map_equate(map, isl_dim_in, n_in, isl_dim_out, d);
3333         pma = isl_pw_multi_aff_from_map(map);
3334         pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma);
3335
3336         return pma;
3337 }
3338
3339 /* Is constraint "c" of the form
3340  *
3341  *      e(...) + c1 - m x >= 0
3342  *
3343  * or
3344  *
3345  *      -e(...) + c2 + m x >= 0
3346  *
3347  * where m > 1 and e only depends on parameters and input dimemnsions?
3348  *
3349  * "offset" is the offset of the output dimensions
3350  * "pos" is the position of output dimension x.
3351  */
3352 static int is_potential_div_constraint(isl_int *c, int offset, int d, int total)
3353 {
3354         if (isl_int_is_zero(c[offset + d]))
3355                 return 0;
3356         if (isl_int_is_one(c[offset + d]))
3357                 return 0;
3358         if (isl_int_is_negone(c[offset + d]))
3359                 return 0;
3360         if (isl_seq_first_non_zero(c + offset, d) != -1)
3361                 return 0;
3362         if (isl_seq_first_non_zero(c + offset + d + 1,
3363                                     total - (offset + d + 1)) != -1)
3364                 return 0;
3365         return 1;
3366 }
3367
3368 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
3369  *
3370  * As a special case, we first check if there is any pair of constraints,
3371  * shared by all the basic maps in "map" that force a given dimension
3372  * to be equal to the floor of some affine combination of the input dimensions.
3373  *
3374  * In particular, if we can find two constraints
3375  *
3376  *      e(...) + c1 - m x >= 0          i.e.,           m x <= e(...) + c1
3377  *
3378  * and
3379  *
3380  *      -e(...) + c2 + m x >= 0         i.e.,           m x >= e(...) - c2
3381  *
3382  * where m > 1 and e only depends on parameters and input dimemnsions,
3383  * and such that
3384  *
3385  *      c1 + c2 < m                     i.e.,           -c2 >= c1 - (m - 1)
3386  *
3387  * then we know that we can take
3388  *
3389  *      x = floor((e(...) + c1) / m)
3390  *
3391  * without having to perform any computation.
3392  *
3393  * Note that we know that
3394  *
3395  *      c1 + c2 >= 1
3396  *
3397  * If c1 + c2 were 0, then we would have detected an equality during
3398  * simplification.  If c1 + c2 were negative, then we would have detected
3399  * a contradiction.
3400  */
3401 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_div(
3402         __isl_take isl_map *map)
3403 {
3404         int d, dim;
3405         int i, j, n;
3406         int offset, total;
3407         isl_int sum;
3408         isl_basic_map *hull;
3409
3410         hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
3411         if (!hull)
3412                 goto error;
3413
3414         isl_int_init(sum);
3415         dim = isl_map_dim(map, isl_dim_out);
3416         offset = isl_basic_map_offset(hull, isl_dim_out);
3417         total = 1 + isl_basic_map_total_dim(hull);
3418         n = hull->n_ineq;
3419         for (d = 0; d < dim; ++d) {
3420                 for (i = 0; i < n; ++i) {
3421                         if (!is_potential_div_constraint(hull->ineq[i],
3422                                                         offset, d, total))
3423                                 continue;
3424                         for (j = i + 1; j < n; ++j) {
3425                                 if (!isl_seq_is_neg(hull->ineq[i] + 1,
3426                                                 hull->ineq[j] + 1, total - 1))
3427                                         continue;
3428                                 isl_int_add(sum, hull->ineq[i][0],
3429                                                 hull->ineq[j][0]);
3430                                 if (isl_int_abs_lt(sum,
3431                                                     hull->ineq[i][offset + d]))
3432                                         break;
3433
3434                         }
3435                         if (j >= n)
3436                                 continue;
3437                         isl_int_clear(sum);
3438                         if (isl_int_is_pos(hull->ineq[j][offset + d]))
3439                                 j = i;
3440                         return pw_multi_aff_from_map_div(map, hull, d, j);
3441                 }
3442         }
3443         isl_int_clear(sum);
3444         isl_basic_map_free(hull);
3445         return pw_multi_aff_from_map_base(map);
3446 error:
3447         isl_map_free(map);
3448         isl_basic_map_free(hull);
3449         return NULL;
3450 }
3451
3452 /* Given an affine expression
3453  *
3454  *      [A -> B] -> f(A,B)
3455  *
3456  * construct an isl_multi_aff
3457  *
3458  *      [A -> B] -> B'
3459  *
3460  * such that dimension "d" in B' is set to "aff" and the remaining
3461  * dimensions are set equal to the corresponding dimensions in B.
3462  * "n_in" is the dimension of the space A.
3463  * "n_out" is the dimension of the space B.
3464  *
3465  * If "is_set" is set, then the affine expression is of the form
3466  *
3467  *      [B] -> f(B)
3468  *
3469  * and we construct an isl_multi_aff
3470  *
3471  *      B -> B'
3472  */
3473 static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d,
3474         unsigned n_in, unsigned n_out, int is_set)
3475 {
3476         int i;
3477         isl_multi_aff *ma;
3478         isl_space *space, *space2;
3479         isl_local_space *ls;
3480
3481         space = isl_aff_get_domain_space(aff);
3482         ls = isl_local_space_from_space(isl_space_copy(space));
3483         space2 = isl_space_copy(space);
3484         if (!is_set)
3485                 space2 = isl_space_range(isl_space_unwrap(space2));
3486         space = isl_space_map_from_domain_and_range(space, space2);
3487         ma = isl_multi_aff_alloc(space);
3488         ma = isl_multi_aff_set_aff(ma, d, aff);
3489
3490         for (i = 0; i < n_out; ++i) {
3491                 if (i == d)
3492                         continue;
3493                 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
3494                                                 isl_dim_set, n_in + i);
3495                 ma = isl_multi_aff_set_aff(ma, i, aff);
3496         }
3497
3498         isl_local_space_free(ls);
3499
3500         return ma;
3501 }
3502
3503 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
3504  * taking into account that the dimension at position "d" can be written as
3505  *
3506  *      x = m a + f(..)                                         (1)
3507  *
3508  * where m is equal to "gcd".
3509  * "i" is the index of the equality in "hull" that defines f(..).
3510  * In particular, the equality is of the form
3511  *
3512  *      f(..) - x + m g(existentials) = 0
3513  *
3514  * or
3515  *
3516  *      -f(..) + x + m g(existentials) = 0
3517  *
3518  * We basically plug (1) into "map", resulting in a map with "a"
3519  * in the range instead of "x".  The corresponding isl_pw_multi_aff
3520  * defining "a" is then plugged back into (1) to obtain a definition fro "x".
3521  *
3522  * Specifically, given the input map
3523  *
3524  *      A -> B
3525  *
3526  * We first wrap it into a set
3527  *
3528  *      [A -> B]
3529  *
3530  * and define (1) on top of the corresponding space, resulting in "aff".
3531  * We use this to create an isl_multi_aff that maps the output position "d"
3532  * from "a" to "x", leaving all other (intput and output) dimensions unchanged.
3533  * We plug this into the wrapped map, unwrap the result and compute the
3534  * corresponding isl_pw_multi_aff.
3535  * The result is an expression
3536  *
3537  *      A -> T(A)
3538  *
3539  * We adjust that to
3540  *
3541  *      A -> [A -> T(A)]
3542  *
3543  * so that we can plug that into "aff", after extending the latter to
3544  * a mapping
3545  *
3546  *      [A -> B] -> B'
3547  *
3548  *
3549  * If "map" is actually a set, then there is no "A" space, meaning
3550  * that we do not need to perform any wrapping, and that the result
3551  * of the recursive call is of the form
3552  *
3553  *      [T]
3554  *
3555  * which is plugged into a mapping of the form
3556  *
3557  *      B -> B'
3558  */
3559 static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride(
3560         __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i,
3561         isl_int gcd)
3562 {
3563         isl_set *set;
3564         isl_space *space;
3565         isl_local_space *ls;
3566         isl_aff *aff;
3567         isl_multi_aff *ma;
3568         isl_pw_multi_aff *pma, *id;
3569         unsigned n_in;
3570         unsigned o_out;
3571         unsigned n_out;
3572         int is_set;
3573
3574         is_set = isl_map_is_set(map);
3575
3576         n_in = isl_basic_map_dim(hull, isl_dim_in);
3577         n_out = isl_basic_map_dim(hull, isl_dim_out);
3578         o_out = isl_basic_map_offset(hull, isl_dim_out);
3579
3580         if (is_set)
3581                 set = map;
3582         else
3583                 set = isl_map_wrap(map);
3584         space = isl_space_map_from_set(isl_set_get_space(set));
3585         ma = isl_multi_aff_identity(space);
3586         ls = isl_local_space_from_space(isl_set_get_space(set));
3587         aff = isl_aff_alloc(ls);
3588         if (aff) {
3589                 isl_int_set_si(aff->v->el[0], 1);
3590                 if (isl_int_is_one(hull->eq[i][o_out + d]))
3591                         isl_seq_neg(aff->v->el + 1, hull->eq[i],
3592                                     aff->v->size - 1);
3593                 else
3594                         isl_seq_cpy(aff->v->el + 1, hull->eq[i],
3595                                     aff->v->size - 1);
3596                 isl_int_set(aff->v->el[1 + o_out + d], gcd);
3597         }
3598         ma = isl_multi_aff_set_aff(ma, n_in + d, isl_aff_copy(aff));
3599         set = isl_set_preimage_multi_aff(set, ma);
3600
3601         ma = range_map(aff, d, n_in, n_out, is_set);
3602
3603         if (is_set)
3604                 map = set;
3605         else
3606                 map = isl_set_unwrap(set);
3607         pma = isl_pw_multi_aff_from_map(set);
3608
3609         if (!is_set) {
3610                 space = isl_pw_multi_aff_get_domain_space(pma);
3611                 space = isl_space_map_from_set(space);
3612                 id = isl_pw_multi_aff_identity(space);
3613                 pma = isl_pw_multi_aff_range_product(id, pma);
3614         }
3615         id = isl_pw_multi_aff_from_multi_aff(ma);
3616         pma = isl_pw_multi_aff_pullback_pw_multi_aff(id, pma);
3617
3618         isl_basic_map_free(hull);
3619         return pma;
3620 }
3621
3622 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
3623  *
3624  * As a special case, we first check if all output dimensions are uniquely
3625  * defined in terms of the parameters and input dimensions over the entire
3626  * domain.  If so, we extract the desired isl_pw_multi_aff directly
3627  * from the affine hull of "map" and its domain.
3628  *
3629  * Otherwise, we check if any of the output dimensions is "strided".
3630  * That is, we check if can be written as
3631  *
3632  *      x = m a + f(..)
3633  *
3634  * with m greater than 1, a some combination of existentiall quantified
3635  * variables and f and expression in the parameters and input dimensions.
3636  * If so, we remove the stride in pw_multi_aff_from_map_stride.
3637  *
3638  * Otherwise, we continue with pw_multi_aff_from_map_check_div for a further
3639  * special case.
3640  */
3641 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
3642 {
3643         int i, j;
3644         int sv;
3645         isl_basic_map *hull;
3646         unsigned n_out;
3647         unsigned o_out;
3648         unsigned n_div;
3649         unsigned o_div;
3650         isl_int gcd;
3651
3652         if (!map)
3653                 return NULL;
3654
3655         hull = isl_map_affine_hull(isl_map_copy(map));
3656         sv = isl_basic_map_plain_is_single_valued(hull);
3657         if (sv >= 0 && sv)
3658                 return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
3659         if (sv < 0)
3660                 hull = isl_basic_map_free(hull);
3661         if (!hull)
3662                 goto error;
3663
3664         n_div = isl_basic_map_dim(hull, isl_dim_div);
3665         o_div = isl_basic_map_offset(hull, isl_dim_div);
3666
3667         if (n_div == 0) {
3668                 isl_basic_map_free(hull);
3669                 return pw_multi_aff_from_map_check_div(map);
3670         }
3671
3672         isl_int_init(gcd);
3673
3674         n_out = isl_basic_map_dim(hull, isl_dim_out);
3675         o_out = isl_basic_map_offset(hull, isl_dim_out);
3676
3677         for (i = 0; i < n_out; ++i) {
3678                 for (j = 0; j < hull->n_eq; ++j) {
3679                         isl_int *eq = hull->eq[j];
3680                         isl_pw_multi_aff *res;
3681
3682                         if (!isl_int_is_one(eq[o_out + i]) &&
3683                             !isl_int_is_negone(eq[o_out + i]))
3684                                 continue;
3685                         if (isl_seq_first_non_zero(eq + o_out, i) != -1)
3686                                 continue;
3687                         if (isl_seq_first_non_zero(eq + o_out + i + 1,
3688                                                     n_out - (i + 1)) != -1)
3689                                 continue;
3690                         isl_seq_gcd(eq + o_div, n_div, &gcd);
3691                         if (isl_int_is_zero(gcd))
3692                                 continue;
3693                         if (isl_int_is_one(gcd))
3694                                 continue;
3695
3696                         res = pw_multi_aff_from_map_stride(map, hull,
3697                                                                 i, j, gcd);
3698                         isl_int_clear(gcd);
3699                         return res;
3700                 }
3701         }
3702
3703         isl_int_clear(gcd);
3704         isl_basic_map_free(hull);
3705         return pw_multi_aff_from_map_check_div(map);
3706 error:
3707         isl_map_free(map);
3708         return NULL;
3709 }
3710
3711 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
3712 {
3713         return isl_pw_multi_aff_from_map(set);
3714 }
3715
3716 /* Return the piecewise affine expression "set ? 1 : 0".
3717  */
3718 __isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_set *set)
3719 {
3720         isl_pw_aff *pa;
3721         isl_space *space = isl_set_get_space(set);
3722         isl_local_space *ls = isl_local_space_from_space(space);
3723         isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls));
3724         isl_aff *one = isl_aff_zero_on_domain(ls);
3725
3726         one = isl_aff_add_constant_si(one, 1);
3727         pa = isl_pw_aff_alloc(isl_set_copy(set), one);
3728         set = isl_set_complement(set);
3729         pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero));
3730
3731         return pa;
3732 }
3733
3734 /* Plug in "subs" for dimension "type", "pos" of "aff".
3735  *
3736  * Let i be the dimension to replace and let "subs" be of the form
3737  *
3738  *      f/d
3739  *
3740  * and "aff" of the form
3741  *
3742  *      (a i + g)/m
3743  *
3744  * The result is
3745  *
3746  *      (a f + d g')/(m d)
3747  *
3748  * where g' is the result of plugging in "subs" in each of the integer
3749  * divisions in g.
3750  */
3751 __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
3752         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
3753 {
3754         isl_ctx *ctx;
3755         isl_int v;
3756
3757         aff = isl_aff_cow(aff);
3758         if (!aff || !subs)
3759                 return isl_aff_free(aff);
3760
3761         ctx = isl_aff_get_ctx(aff);
3762         if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
3763                 isl_die(ctx, isl_error_invalid,
3764                         "spaces don't match", return isl_aff_free(aff));
3765         if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
3766                 isl_die(ctx, isl_error_unsupported,
3767                         "cannot handle divs yet", return isl_aff_free(aff));
3768
3769         aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
3770         if (!aff->ls)
3771                 return isl_aff_free(aff);
3772
3773         aff->v = isl_vec_cow(aff->v);
3774         if (!aff->v)
3775                 return isl_aff_free(aff);
3776
3777         pos += isl_local_space_offset(aff->ls, type);
3778
3779         isl_int_init(v);
3780         isl_seq_substitute(aff->v->el, pos, subs->v->el,
3781                             aff->v->size, subs->v->size, v);
3782         isl_int_clear(v);
3783
3784         return aff;
3785 }
3786
3787 /* Plug in "subs" for dimension "type", "pos" in each of the affine
3788  * expressions in "maff".
3789  */
3790 __isl_give isl_multi_aff *isl_multi_aff_substitute(
3791         __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
3792         __isl_keep isl_aff *subs)
3793 {
3794         int i;
3795
3796         maff = isl_multi_aff_cow(maff);
3797         if (!maff || !subs)
3798                 return isl_multi_aff_free(maff);
3799
3800         if (type == isl_dim_in)
3801                 type = isl_dim_set;
3802
3803         for (i = 0; i < maff->n; ++i) {
3804                 maff->p[i] = isl_aff_substitute(maff->p[i], type, pos, subs);
3805                 if (!maff->p[i])
3806                         return isl_multi_aff_free(maff);
3807         }
3808
3809         return maff;
3810 }
3811
3812 /* Plug in "subs" for dimension "type", "pos" of "pma".
3813  *
3814  * pma is of the form
3815  *
3816  *      A_i(v) -> M_i(v)
3817  *
3818  * while subs is of the form
3819  *
3820  *      v' = B_j(v) -> S_j
3821  *
3822  * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
3823  * has a contribution in the result, in particular
3824  *
3825  *      C_ij(S_j) -> M_i(S_j)
3826  *
3827  * Note that plugging in S_j in C_ij may also result in an empty set
3828  * and this contribution should simply be discarded.
3829  */
3830 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
3831         __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
3832         __isl_keep isl_pw_aff *subs)
3833 {
3834         int i, j, n;
3835         isl_pw_multi_aff *res;
3836
3837         if (!pma || !subs)
3838                 return isl_pw_multi_aff_free(pma);
3839
3840         n = pma->n * subs->n;
3841         res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
3842
3843         for (i = 0; i < pma->n; ++i) {
3844                 for (j = 0; j < subs->n; ++j) {
3845                         isl_set *common;
3846                         isl_multi_aff *res_ij;
3847                         int empty;
3848
3849                         common = isl_set_intersect(
3850                                         isl_set_copy(pma->p[i].set),
3851                                         isl_set_copy(subs->p[j].set));
3852                         common = isl_set_substitute(common,
3853                                         type, pos, subs->p[j].aff);
3854                         empty = isl_set_plain_is_empty(common);
3855                         if (empty < 0 || empty) {
3856                                 isl_set_free(common);
3857                                 if (empty < 0)
3858                                         goto error;
3859                                 continue;
3860                         }
3861
3862                         res_ij = isl_multi_aff_substitute(
3863                                         isl_multi_aff_copy(pma->p[i].maff),
3864                                         type, pos, subs->p[j].aff);
3865
3866                         res = isl_pw_multi_aff_add_piece(res, common, res_ij);
3867                 }
3868         }
3869
3870         isl_pw_multi_aff_free(pma);
3871         return res;
3872 error:
3873         isl_pw_multi_aff_free(pma);
3874         isl_pw_multi_aff_free(res);
3875         return NULL;
3876 }
3877
3878 /* Compute the preimage of the affine expression "src" under "ma"
3879  * and put the result in "dst".  If "has_denom" is set (to one),
3880  * then "src" and "dst" have an extra initial denominator.
3881  * "n_div_ma" is the number of existentials in "ma"
3882  * "n_div_bset" is the number of existentials in "src"
3883  * The resulting "dst" (which is assumed to have been allocated by
3884  * the caller) contains coefficients for both sets of existentials,
3885  * first those in "ma" and then those in "src".
3886  * f, c1, c2 and g are temporary objects that have been initialized
3887  * by the caller.
3888  *
3889  * Let src represent the expression
3890  *
3891  *      (a(p) + b x + c(divs))/d
3892  *
3893  * and let ma represent the expressions
3894  *
3895  *      x_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i
3896  *
3897  * We start out with the following expression for dst:
3898  *
3899  *      (a(p) + 0 y + 0 divs' + f \sum_i b_i x_i + c(divs))/d
3900  *
3901  * with the multiplication factor f initially equal to 1.
3902  * For each x_i that we substitute, we multiply the numerator
3903  * (and denominator) of dst by c_1 = m_i and add the numerator
3904  * of the x_i expression multiplied by c_2 = f b_i,
3905  * after removing the common factors of c_1 and c_2.
3906  * The multiplication factor f also needs to be multiplied by c_1
3907  * for the next x_j, j > i.
3908  */
3909 void isl_seq_preimage(isl_int *dst, isl_int *src,
3910         __isl_keep isl_multi_aff *ma, int n_div_ma, int n_div_bset,
3911         isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom)
3912 {
3913         int i;
3914         int n_param, n_in, n_out;
3915         int o_div_bset;
3916
3917         n_param = isl_multi_aff_dim(ma, isl_dim_param);
3918         n_in = isl_multi_aff_dim(ma, isl_dim_in);
3919         n_out = isl_multi_aff_dim(ma, isl_dim_out);
3920
3921         o_div_bset = has_denom + 1 + n_param + n_in + n_div_ma;
3922
3923         isl_seq_cpy(dst, src, has_denom + 1 + n_param);
3924         isl_seq_clr(dst + has_denom + 1 + n_param, n_in + n_div_ma);
3925         isl_seq_cpy(dst + o_div_bset,
3926                     src + has_denom + 1 + n_param + n_out, n_div_bset);
3927
3928         isl_int_set_si(f, 1);
3929
3930         for (i = 0; i < n_out; ++i) {
3931                 if (isl_int_is_zero(src[has_denom + 1 + n_param + i]))
3932                         continue;
3933                 isl_int_set(c1, ma->p[i]->v->el[0]);
3934                 isl_int_mul(c2, f, src[has_denom + 1 + n_param + i]);
3935                 isl_int_gcd(g, c1, c2);
3936                 isl_int_divexact(c1, c1, g);
3937                 isl_int_divexact(c2, c2, g);
3938
3939                 isl_int_mul(f, f, c1);
3940                 isl_seq_combine(dst + has_denom, c1, dst + has_denom,
3941                                 c2, ma->p[i]->v->el + 1, ma->p[i]->v->size - 1);
3942                 isl_seq_scale(dst + o_div_bset,
3943                                 dst + o_div_bset, c1, n_div_bset);
3944                 if (has_denom)
3945                         isl_int_mul(dst[0], dst[0], c1);
3946         }
3947 }
3948
3949 /* Compute the pullback of "aff" by the function represented by "ma".
3950  * In other words, plug in "ma" in "aff".  The result is an affine expression
3951  * defined over the domain space of "ma".
3952  *
3953  * If "aff" is represented by
3954  *
3955  *      (a(p) + b x + c(divs))/d
3956  *
3957  * and ma is represented by
3958  *
3959  *      x = D(p) + F(y) + G(divs')
3960  *
3961  * then the result is
3962  *
3963  *      (a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d
3964  *
3965  * The divs in the local space of the input are similarly adjusted
3966  * through a call to isl_local_space_preimage_multi_aff.
3967  */
3968 __isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff,
3969         __isl_take isl_multi_aff *ma)
3970 {
3971         isl_aff *res = NULL;
3972         isl_local_space *ls;
3973         int n_div_aff, n_div_ma;
3974         isl_int f, c1, c2, g;
3975
3976         ma = isl_multi_aff_align_divs(ma);
3977         if (!aff || !ma)
3978                 goto error;
3979
3980         n_div_aff = isl_aff_dim(aff, isl_dim_div);
3981         n_div_ma = ma->n ? isl_aff_dim(ma->p[0], isl_dim_div) : 0;
3982
3983         ls = isl_aff_get_domain_local_space(aff);
3984         ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma));
3985         res = isl_aff_alloc(ls);
3986         if (!res)
3987                 goto error;
3988
3989         isl_int_init(f);
3990         isl_int_init(c1);
3991         isl_int_init(c2);
3992         isl_int_init(g);
3993
3994         isl_seq_preimage(res->v->el, aff->v->el, ma, n_div_ma, n_div_aff,
3995                         f, c1, c2, g, 1);
3996
3997         isl_int_clear(f);
3998         isl_int_clear(c1);
3999         isl_int_clear(c2);
4000         isl_int_clear(g);
4001
4002         isl_aff_free(aff);
4003         isl_multi_aff_free(ma);
4004         res = isl_aff_normalize(res);
4005         return res;
4006 error:
4007         isl_aff_free(aff);
4008         isl_multi_aff_free(ma);
4009         isl_aff_free(res);
4010         return NULL;
4011 }
4012
4013 /* Compute the pullback of "ma1" by the function represented by "ma2".
4014  * In other words, plug in "ma2" in "ma1".
4015  */
4016 __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
4017         __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
4018 {
4019         int i;
4020         isl_space *space = NULL;
4021
4022         ma2 = isl_multi_aff_align_divs(ma2);
4023         ma1 = isl_multi_aff_cow(ma1);
4024         if (!ma1 || !ma2)
4025                 goto error;
4026
4027         space = isl_space_join(isl_multi_aff_get_space(ma2),
4028                                 isl_multi_aff_get_space(ma1));
4029
4030         for (i = 0; i < ma1->n; ++i) {
4031                 ma1->p[i] = isl_aff_pullback_multi_aff(ma1->p[i],
4032                                                     isl_multi_aff_copy(ma2));
4033                 if (!ma1->p[i])
4034                         goto error;
4035         }
4036
4037         ma1 = isl_multi_aff_reset_space(ma1, space);
4038         isl_multi_aff_free(ma2);
4039         return ma1;
4040 error:
4041         isl_space_free(space);
4042         isl_multi_aff_free(ma2);
4043         isl_multi_aff_free(ma1);
4044         return NULL;
4045 }
4046
4047 /* Extend the local space of "dst" to include the divs
4048  * in the local space of "src".
4049  */
4050 __isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
4051         __isl_keep isl_aff *src)
4052 {
4053         isl_ctx *ctx;
4054         int *exp1 = NULL;
4055         int *exp2 = NULL;
4056         isl_mat *div;
4057
4058         if (!src || !dst)
4059                 return isl_aff_free(dst);
4060
4061         ctx = isl_aff_get_ctx(src);
4062         if (!isl_space_is_equal(src->ls->dim, dst->ls->dim))
4063                 isl_die(ctx, isl_error_invalid,
4064                         "spaces don't match", goto error);
4065
4066         if (src->ls->div->n_row == 0)
4067                 return dst;
4068
4069         exp1 = isl_alloc_array(ctx, int, src->ls->div->n_row);
4070         exp2 = isl_alloc_array(ctx, int, dst->ls->div->n_row);
4071         if (!exp1 || !exp2)
4072                 goto error;
4073
4074         div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
4075         dst = isl_aff_expand_divs(dst, div, exp2);
4076         free(exp1);
4077         free(exp2);
4078
4079         return dst;
4080 error:
4081         free(exp1);
4082         free(exp2);
4083         return isl_aff_free(dst);
4084 }
4085
4086 /* Adjust the local spaces of the affine expressions in "maff"
4087  * such that they all have the save divs.
4088  */
4089 __isl_give isl_multi_aff *isl_multi_aff_align_divs(
4090         __isl_take isl_multi_aff *maff)
4091 {
4092         int i;
4093
4094         if (!maff)
4095                 return NULL;
4096         if (maff->n == 0)
4097                 return maff;
4098         maff = isl_multi_aff_cow(maff);
4099         if (!maff)
4100                 return NULL;
4101
4102         for (i = 1; i < maff->n; ++i)
4103                 maff->p[0] = isl_aff_align_divs(maff->p[0], maff->p[i]);
4104         for (i = 1; i < maff->n; ++i) {
4105                 maff->p[i] = isl_aff_align_divs(maff->p[i], maff->p[0]);
4106                 if (!maff->p[i])
4107                         return isl_multi_aff_free(maff);
4108         }
4109
4110         return maff;
4111 }
4112
4113 __isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
4114 {
4115         aff = isl_aff_cow(aff);
4116         if (!aff)
4117                 return NULL;
4118
4119         aff->ls = isl_local_space_lift(aff->ls);
4120         if (!aff->ls)
4121                 return isl_aff_free(aff);
4122
4123         return aff;
4124 }
4125
4126 /* Lift "maff" to a space with extra dimensions such that the result
4127  * has no more existentially quantified variables.
4128  * If "ls" is not NULL, then *ls is assigned the local space that lies
4129  * at the basis of the lifting applied to "maff".
4130  */
4131 __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
4132         __isl_give isl_local_space **ls)
4133 {
4134         int i;
4135         isl_space *space;
4136         unsigned n_div;
4137
4138         if (ls)
4139                 *ls = NULL;
4140
4141         if (!maff)
4142                 return NULL;
4143
4144         if (maff->n == 0) {
4145                 if (ls) {
4146                         isl_space *space = isl_multi_aff_get_domain_space(maff);
4147                         *ls = isl_local_space_from_space(space);
4148                         if (!*ls)
4149                                 return isl_multi_aff_free(maff);
4150                 }
4151                 return maff;
4152         }
4153
4154         maff = isl_multi_aff_cow(maff);
4155         maff = isl_multi_aff_align_divs(maff);
4156         if (!maff)
4157                 return NULL;
4158
4159         n_div = isl_aff_dim(maff->p[0], isl_dim_div);
4160         space = isl_multi_aff_get_space(maff);
4161         space = isl_space_lift(isl_space_domain(space), n_div);
4162         space = isl_space_extend_domain_with_range(space,
4163                                                 isl_multi_aff_get_space(maff));
4164         if (!space)
4165                 return isl_multi_aff_free(maff);
4166         isl_space_free(maff->space);
4167         maff->space = space;
4168
4169         if (ls) {
4170                 *ls = isl_aff_get_domain_local_space(maff->p[0]);
4171                 if (!*ls)
4172                         return isl_multi_aff_free(maff);
4173         }
4174
4175         for (i = 0; i < maff->n; ++i) {
4176                 maff->p[i] = isl_aff_lift(maff->p[i]);
4177                 if (!maff->p[i])
4178                         goto error;
4179         }
4180
4181         return maff;
4182 error:
4183         if (ls)
4184                 isl_local_space_free(*ls);
4185         return isl_multi_aff_free(maff);
4186 }
4187
4188
4189 /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
4190  */
4191 __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
4192         __isl_keep isl_pw_multi_aff *pma, int pos)
4193 {
4194         int i;
4195         int n_out;
4196         isl_space *space;
4197         isl_pw_aff *pa;
4198
4199         if (!pma)
4200                 return NULL;
4201
4202         n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
4203         if (pos < 0 || pos >= n_out)
4204                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4205                         "index out of bounds", return NULL);
4206
4207         space = isl_pw_multi_aff_get_space(pma);
4208         space = isl_space_drop_dims(space, isl_dim_out,
4209                                     pos + 1, n_out - pos - 1);
4210         space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
4211
4212         pa = isl_pw_aff_alloc_size(space, pma->n);
4213         for (i = 0; i < pma->n; ++i) {
4214                 isl_aff *aff;
4215                 aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
4216                 pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
4217         }
4218
4219         return pa;
4220 }
4221
4222 /* Return an isl_pw_multi_aff with the given "set" as domain and
4223  * an unnamed zero-dimensional range.
4224  */
4225 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain(
4226         __isl_take isl_set *set)
4227 {
4228         isl_multi_aff *ma;
4229         isl_space *space;
4230
4231         space = isl_set_get_space(set);
4232         space = isl_space_from_domain(space);
4233         ma = isl_multi_aff_zero(space);
4234         return isl_pw_multi_aff_alloc(set, ma);
4235 }
4236
4237 /* Add an isl_pw_multi_aff with the given "set" as domain and
4238  * an unnamed zero-dimensional range to *user.
4239  */
4240 static int add_pw_multi_aff_from_domain(__isl_take isl_set *set, void *user)
4241 {
4242         isl_union_pw_multi_aff **upma = user;
4243         isl_pw_multi_aff *pma;
4244
4245         pma = isl_pw_multi_aff_from_domain(set);
4246         *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
4247
4248         return 0;
4249 }
4250
4251 /* Return an isl_union_pw_multi_aff with the given "uset" as domain and
4252  * an unnamed zero-dimensional range.
4253  */
4254 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
4255         __isl_take isl_union_set *uset)
4256 {
4257         isl_space *space;
4258         isl_union_pw_multi_aff *upma;
4259
4260         if (!uset)
4261                 return NULL;
4262
4263         space = isl_union_set_get_space(uset);
4264         upma = isl_union_pw_multi_aff_empty(space);
4265
4266         if (isl_union_set_foreach_set(uset,
4267                                     &add_pw_multi_aff_from_domain, &upma) < 0)
4268                 goto error;
4269
4270         isl_union_set_free(uset);
4271         return upma;
4272 error:
4273         isl_union_set_free(uset);
4274         isl_union_pw_multi_aff_free(upma);
4275         return NULL;
4276 }
4277
4278 /* Convert "pma" to an isl_map and add it to *umap.
4279  */
4280 static int map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma, void *user)
4281 {
4282         isl_union_map **umap = user;
4283         isl_map *map;
4284
4285         map = isl_map_from_pw_multi_aff(pma);
4286         *umap = isl_union_map_add_map(*umap, map);
4287
4288         return 0;
4289 }
4290
4291 /* Construct a union map mapping the domain of the union
4292  * piecewise multi-affine expression to its range, with each dimension
4293  * in the range equated to the corresponding affine expression on its cell.
4294  */
4295 __isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff(
4296         __isl_take isl_union_pw_multi_aff *upma)
4297 {
4298         isl_space *space;
4299         isl_union_map *umap;
4300
4301         if (!upma)
4302                 return NULL;
4303
4304         space = isl_union_pw_multi_aff_get_space(upma);
4305         umap = isl_union_map_empty(space);
4306
4307         if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
4308                                         &map_from_pw_multi_aff, &umap) < 0)
4309                 goto error;
4310
4311         isl_union_pw_multi_aff_free(upma);
4312         return umap;
4313 error:
4314         isl_union_pw_multi_aff_free(upma);
4315         isl_union_map_free(umap);
4316         return NULL;
4317 }
4318
4319 /* Local data for bin_entry and the callback "fn".
4320  */
4321 struct isl_union_pw_multi_aff_bin_data {
4322         isl_union_pw_multi_aff *upma2;
4323         isl_union_pw_multi_aff *res;
4324         isl_pw_multi_aff *pma;
4325         int (*fn)(void **entry, void *user);
4326 };
4327
4328 /* Given an isl_pw_multi_aff from upma1, store it in data->pma
4329  * and call data->fn for each isl_pw_multi_aff in data->upma2.
4330  */
4331 static int bin_entry(void **entry, void *user)
4332 {
4333         struct isl_union_pw_multi_aff_bin_data *data = user;
4334         isl_pw_multi_aff *pma = *entry;
4335
4336         data->pma = pma;
4337         if (isl_hash_table_foreach(data->upma2->dim->ctx, &data->upma2->table,
4338                                    data->fn, data) < 0)
4339                 return -1;
4340
4341         return 0;
4342 }
4343
4344 /* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2".
4345  * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is
4346  * passed as user field) and the isl_pw_multi_aff from upma2 is available
4347  * as *entry.  The callback should adjust data->res if desired.
4348  */
4349 static __isl_give isl_union_pw_multi_aff *bin_op(
4350         __isl_take isl_union_pw_multi_aff *upma1,
4351         __isl_take isl_union_pw_multi_aff *upma2,
4352         int (*fn)(void **entry, void *user))
4353 {
4354         isl_space *space;
4355         struct isl_union_pw_multi_aff_bin_data data = { NULL, NULL, NULL, fn };
4356
4357         space = isl_union_pw_multi_aff_get_space(upma2);
4358         upma1 = isl_union_pw_multi_aff_align_params(upma1, space);
4359         space = isl_union_pw_multi_aff_get_space(upma1);
4360         upma2 = isl_union_pw_multi_aff_align_params(upma2, space);
4361
4362         if (!upma1 || !upma2)
4363                 goto error;
4364
4365         data.upma2 = upma2;
4366         data.res = isl_union_pw_multi_aff_alloc(isl_space_copy(upma1->dim),
4367                                        upma1->table.n);
4368         if (isl_hash_table_foreach(upma1->dim->ctx, &upma1->table,
4369                                    &bin_entry, &data) < 0)
4370                 goto error;
4371
4372         isl_union_pw_multi_aff_free(upma1);
4373         isl_union_pw_multi_aff_free(upma2);
4374         return data.res;
4375 error:
4376         isl_union_pw_multi_aff_free(upma1);
4377         isl_union_pw_multi_aff_free(upma2);
4378         isl_union_pw_multi_aff_free(data.res);
4379         return NULL;
4380 }
4381
4382 /* Given two aligned isl_pw_multi_affs A -> B and C -> D,
4383  * construct an isl_pw_multi_aff (A * C) -> [B -> D].
4384  */
4385 static __isl_give isl_pw_multi_aff *pw_multi_aff_range_product(
4386         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4387 {
4388         isl_space *space;
4389
4390         space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
4391                                         isl_pw_multi_aff_get_space(pma2));
4392         return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
4393                                             &isl_multi_aff_range_product);
4394 }
4395
4396 /* Given two isl_pw_multi_affs A -> B and C -> D,
4397  * construct an isl_pw_multi_aff (A * C) -> [B -> D].
4398  */
4399 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product(
4400         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4401 {
4402         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4403                                             &pw_multi_aff_range_product);
4404 }
4405
4406 /* Given two aligned isl_pw_multi_affs A -> B and C -> D,
4407  * construct an isl_pw_multi_aff (A * C) -> (B, D).
4408  */
4409 static __isl_give isl_pw_multi_aff *pw_multi_aff_flat_range_product(
4410         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4411 {
4412         isl_space *space;
4413
4414         space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
4415                                         isl_pw_multi_aff_get_space(pma2));
4416         space = isl_space_flatten_range(space);
4417         return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
4418                                             &isl_multi_aff_flat_range_product);
4419 }
4420
4421 /* Given two isl_pw_multi_affs A -> B and C -> D,
4422  * construct an isl_pw_multi_aff (A * C) -> (B, D).
4423  */
4424 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product(
4425         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4426 {
4427         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4428                                             &pw_multi_aff_flat_range_product);
4429 }
4430
4431 /* If data->pma and *entry have the same domain space, then compute
4432  * their flat range product and the result to data->res.
4433  */
4434 static int flat_range_product_entry(void **entry, void *user)
4435 {
4436         struct isl_union_pw_multi_aff_bin_data *data = user;
4437         isl_pw_multi_aff *pma2 = *entry;
4438
4439         if (!isl_space_tuple_match(data->pma->dim, isl_dim_in,
4440                                  pma2->dim, isl_dim_in))
4441                 return 0;
4442
4443         pma2 = isl_pw_multi_aff_flat_range_product(
4444                                         isl_pw_multi_aff_copy(data->pma),
4445                                         isl_pw_multi_aff_copy(pma2));
4446
4447         data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
4448
4449         return 0;
4450 }
4451
4452 /* Given two isl_union_pw_multi_affs A -> B and C -> D,
4453  * construct an isl_union_pw_multi_aff (A * C) -> (B, D).
4454  */
4455 __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product(
4456         __isl_take isl_union_pw_multi_aff *upma1,
4457         __isl_take isl_union_pw_multi_aff *upma2)
4458 {
4459         return bin_op(upma1, upma2, &flat_range_product_entry);
4460 }
4461
4462 /* Replace the affine expressions at position "pos" in "pma" by "pa".
4463  * The parameters are assumed to have been aligned.
4464  *
4465  * The implementation essentially performs an isl_pw_*_on_shared_domain,
4466  * except that it works on two different isl_pw_* types.
4467  */
4468 static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff(
4469         __isl_take isl_pw_multi_aff *pma, unsigned pos,
4470         __isl_take isl_pw_aff *pa)
4471 {
4472         int i, j, n;
4473         isl_pw_multi_aff *res = NULL;
4474
4475         if (!pma || !pa)
4476                 goto error;
4477
4478         if (!isl_space_tuple_match(pma->dim, isl_dim_in, pa->dim, isl_dim_in))
4479                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4480                         "domains don't match", goto error);
4481         if (pos >= isl_pw_multi_aff_dim(pma, isl_dim_out))
4482                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4483                         "index out of bounds", goto error);
4484
4485         n = pma->n * pa->n;
4486         res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n);
4487
4488         for (i = 0; i < pma->n; ++i) {
4489                 for (j = 0; j < pa->n; ++j) {
4490                         isl_set *common;
4491                         isl_multi_aff *res_ij;
4492                         int empty;
4493
4494                         common = isl_set_intersect(isl_set_copy(pma->p[i].set),
4495                                                    isl_set_copy(pa->p[j].set));
4496                         empty = isl_set_plain_is_empty(common);
4497                         if (empty < 0 || empty) {
4498                                 isl_set_free(common);
4499                                 if (empty < 0)
4500                                         goto error;
4501                                 continue;
4502                         }
4503
4504                         res_ij = isl_multi_aff_set_aff(
4505                                         isl_multi_aff_copy(pma->p[i].maff), pos,
4506                                         isl_aff_copy(pa->p[j].aff));
4507                         res_ij = isl_multi_aff_gist(res_ij,
4508                                         isl_set_copy(common));
4509
4510                         res = isl_pw_multi_aff_add_piece(res, common, res_ij);
4511                 }
4512         }
4513
4514         isl_pw_multi_aff_free(pma);
4515         isl_pw_aff_free(pa);
4516         return res;
4517 error:
4518         isl_pw_multi_aff_free(pma);
4519         isl_pw_aff_free(pa);
4520         return isl_pw_multi_aff_free(res);
4521 }
4522
4523 /* Replace the affine expressions at position "pos" in "pma" by "pa".
4524  */
4525 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff(
4526         __isl_take isl_pw_multi_aff *pma, unsigned pos,
4527         __isl_take isl_pw_aff *pa)
4528 {
4529         if (!pma || !pa)
4530                 goto error;
4531         if (isl_space_match(pma->dim, isl_dim_param, pa->dim, isl_dim_param))
4532                 return pw_multi_aff_set_pw_aff(pma, pos, pa);
4533         if (!isl_space_has_named_params(pma->dim) ||
4534             !isl_space_has_named_params(pa->dim))
4535                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4536                         "unaligned unnamed parameters", goto error);
4537         pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa));
4538         pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma));
4539         return pw_multi_aff_set_pw_aff(pma, pos, pa);
4540 error:
4541         isl_pw_multi_aff_free(pma);
4542         isl_pw_aff_free(pa);
4543         return NULL;
4544 }
4545
4546 #undef BASE
4547 #define BASE pw_aff
4548
4549 #include <isl_multi_templ.c>