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