Merge branch 'maint'
[platform/upstream/isl.git] / isl_aff.c
1 /*
2  * Copyright 2011      INRIA Saclay
3  * Copyright 2011      Sven Verdoolaege
4  *
5  * Use of this software is governed by the GNU LGPLv2.1 license
6  *
7  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
8  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
9  * 91893 Orsay, France
10  */
11
12 #include <isl_ctx_private.h>
13 #include <isl_map_private.h>
14 #include <isl_aff_private.h>
15 #include <isl_space_private.h>
16 #include <isl_local_space_private.h>
17 #include <isl_mat_private.h>
18 #include <isl_list_private.h>
19 #include <isl/constraint.h>
20 #include <isl/seq.h>
21 #include <isl/set.h>
22 #include <isl_config.h>
23
24 __isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls,
25         __isl_take isl_vec *v)
26 {
27         isl_aff *aff;
28
29         if (!ls || !v)
30                 goto error;
31
32         aff = isl_calloc_type(v->ctx, struct isl_aff);
33         if (!aff)
34                 goto error;
35
36         aff->ref = 1;
37         aff->ls = ls;
38         aff->v = v;
39
40         return aff;
41 error:
42         isl_local_space_free(ls);
43         isl_vec_free(v);
44         return NULL;
45 }
46
47 __isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls)
48 {
49         isl_ctx *ctx;
50         isl_vec *v;
51         unsigned total;
52
53         if (!ls)
54                 return NULL;
55
56         ctx = isl_local_space_get_ctx(ls);
57         if (!isl_local_space_divs_known(ls))
58                 isl_die(ctx, isl_error_invalid, "local space has unknown divs",
59                         goto error);
60         if (!isl_local_space_is_set(ls))
61                 isl_die(ctx, isl_error_invalid,
62                         "domain of affine expression should be a set",
63                         goto error);
64
65         total = isl_local_space_dim(ls, isl_dim_all);
66         v = isl_vec_alloc(ctx, 1 + 1 + total);
67         return isl_aff_alloc_vec(ls, v);
68 error:
69         isl_local_space_free(ls);
70         return NULL;
71 }
72
73 __isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls)
74 {
75         isl_aff *aff;
76
77         aff = isl_aff_alloc(ls);
78         if (!aff)
79                 return NULL;
80
81         isl_int_set_si(aff->v->el[0], 1);
82         isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
83
84         return aff;
85 }
86
87 __isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff)
88 {
89         if (!aff)
90                 return NULL;
91
92         aff->ref++;
93         return aff;
94 }
95
96 __isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff)
97 {
98         if (!aff)
99                 return NULL;
100
101         return isl_aff_alloc_vec(isl_local_space_copy(aff->ls),
102                                  isl_vec_copy(aff->v));
103 }
104
105 __isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff)
106 {
107         if (!aff)
108                 return NULL;
109
110         if (aff->ref == 1)
111                 return aff;
112         aff->ref--;
113         return isl_aff_dup(aff);
114 }
115
116 void *isl_aff_free(__isl_take isl_aff *aff)
117 {
118         if (!aff)
119                 return NULL;
120
121         if (--aff->ref > 0)
122                 return NULL;
123
124         isl_local_space_free(aff->ls);
125         isl_vec_free(aff->v);
126
127         free(aff);
128
129         return NULL;
130 }
131
132 isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff)
133 {
134         return aff ? isl_local_space_get_ctx(aff->ls) : NULL;
135 }
136
137 /* Externally, an isl_aff has a map space, but internally, the
138  * ls field corresponds to the domain of that space.
139  */
140 int isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
141 {
142         if (!aff)
143                 return 0;
144         if (type == isl_dim_out)
145                 return 1;
146         if (type == isl_dim_in)
147                 type = isl_dim_set;
148         return isl_local_space_dim(aff->ls, type);
149 }
150
151 __isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff)
152 {
153         return aff ? isl_local_space_get_space(aff->ls) : NULL;
154 }
155
156 __isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff)
157 {
158         isl_space *space;
159         if (!aff)
160                 return NULL;
161         space = isl_local_space_get_space(aff->ls);
162         space = isl_space_from_domain(space);
163         space = isl_space_add_dims(space, isl_dim_out, 1);
164         return space;
165 }
166
167 __isl_give isl_local_space *isl_aff_get_domain_local_space(
168         __isl_keep isl_aff *aff)
169 {
170         return aff ? isl_local_space_copy(aff->ls) : NULL;
171 }
172
173 __isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff)
174 {
175         isl_local_space *ls;
176         if (!aff)
177                 return NULL;
178         ls = isl_local_space_copy(aff->ls);
179         ls = isl_local_space_from_domain(ls);
180         ls = isl_local_space_add_dims(ls, isl_dim_out, 1);
181         return ls;
182 }
183
184 /* Externally, an isl_aff has a map space, but internally, the
185  * ls field corresponds to the domain of that space.
186  */
187 const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff,
188         enum isl_dim_type type, unsigned pos)
189 {
190         if (!aff)
191                 return NULL;
192         if (type == isl_dim_out)
193                 return NULL;
194         if (type == isl_dim_in)
195                 type = isl_dim_set;
196         return isl_local_space_get_dim_name(aff->ls, type, pos);
197 }
198
199 __isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff,
200         __isl_take isl_space *dim)
201 {
202         aff = isl_aff_cow(aff);
203         if (!aff || !dim)
204                 goto error;
205
206         aff->ls = isl_local_space_reset_space(aff->ls, dim);
207         if (!aff->ls)
208                 return isl_aff_free(aff);
209
210         return aff;
211 error:
212         isl_aff_free(aff);
213         isl_space_free(dim);
214         return NULL;
215 }
216
217 /* Reset the space of "aff".  This function is called from isl_pw_templ.c
218  * and doesn't know if the space of an element object is represented
219  * directly or through its domain.  It therefore passes along both.
220  */
221 __isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff,
222         __isl_take isl_space *space, __isl_take isl_space *domain)
223 {
224         isl_space_free(space);
225         return isl_aff_reset_domain_space(aff, domain);
226 }
227
228 /* Reorder the coefficients of the affine expression based
229  * on the given reodering.
230  * The reordering r is assumed to have been extended with the local
231  * variables.
232  */
233 static __isl_give isl_vec *vec_reorder(__isl_take isl_vec *vec,
234         __isl_take isl_reordering *r, int n_div)
235 {
236         isl_vec *res;
237         int i;
238
239         if (!vec || !r)
240                 goto error;
241
242         res = isl_vec_alloc(vec->ctx,
243                             2 + isl_space_dim(r->dim, isl_dim_all) + n_div);
244         isl_seq_cpy(res->el, vec->el, 2);
245         isl_seq_clr(res->el + 2, res->size - 2);
246         for (i = 0; i < r->len; ++i)
247                 isl_int_set(res->el[2 + r->pos[i]], vec->el[2 + i]);
248
249         isl_reordering_free(r);
250         isl_vec_free(vec);
251         return res;
252 error:
253         isl_vec_free(vec);
254         isl_reordering_free(r);
255         return NULL;
256 }
257
258 /* Reorder the dimensions of the domain of "aff" according
259  * to the given reordering.
260  */
261 __isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff,
262         __isl_take isl_reordering *r)
263 {
264         aff = isl_aff_cow(aff);
265         if (!aff)
266                 goto error;
267
268         r = isl_reordering_extend(r, aff->ls->div->n_row);
269         aff->v = vec_reorder(aff->v, isl_reordering_copy(r),
270                                 aff->ls->div->n_row);
271         aff->ls = isl_local_space_realign(aff->ls, r);
272
273         if (!aff->v || !aff->ls)
274                 return isl_aff_free(aff);
275
276         return aff;
277 error:
278         isl_aff_free(aff);
279         isl_reordering_free(r);
280         return NULL;
281 }
282
283 __isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff,
284         __isl_take isl_space *model)
285 {
286         if (!aff || !model)
287                 goto error;
288
289         if (!isl_space_match(aff->ls->dim, isl_dim_param,
290                              model, isl_dim_param)) {
291                 isl_reordering *exp;
292
293                 model = isl_space_drop_dims(model, isl_dim_in,
294                                         0, isl_space_dim(model, isl_dim_in));
295                 model = isl_space_drop_dims(model, isl_dim_out,
296                                         0, isl_space_dim(model, isl_dim_out));
297                 exp = isl_parameter_alignment_reordering(aff->ls->dim, model);
298                 exp = isl_reordering_extend_space(exp,
299                                         isl_aff_get_domain_space(aff));
300                 aff = isl_aff_realign_domain(aff, exp);
301         }
302
303         isl_space_free(model);
304         return aff;
305 error:
306         isl_space_free(model);
307         isl_aff_free(aff);
308         return NULL;
309 }
310
311 int isl_aff_plain_is_zero(__isl_keep isl_aff *aff)
312 {
313         if (!aff)
314                 return -1;
315
316         return isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1) < 0;
317 }
318
319 int isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
320 {
321         int equal;
322
323         if (!aff1 || !aff2)
324                 return -1;
325
326         equal = isl_local_space_is_equal(aff1->ls, aff2->ls);
327         if (equal < 0 || !equal)
328                 return equal;
329
330         return isl_vec_is_equal(aff1->v, aff2->v);
331 }
332
333 int isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v)
334 {
335         if (!aff)
336                 return -1;
337         isl_int_set(*v, aff->v->el[0]);
338         return 0;
339 }
340
341 int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v)
342 {
343         if (!aff)
344                 return -1;
345         isl_int_set(*v, aff->v->el[1]);
346         return 0;
347 }
348
349 int isl_aff_get_coefficient(__isl_keep isl_aff *aff,
350         enum isl_dim_type type, int pos, isl_int *v)
351 {
352         if (!aff)
353                 return -1;
354
355         if (type == isl_dim_out)
356                 isl_die(aff->v->ctx, isl_error_invalid,
357                         "output/set dimension does not have a coefficient",
358                         return -1);
359         if (type == isl_dim_in)
360                 type = isl_dim_set;
361
362         if (pos >= isl_local_space_dim(aff->ls, type))
363                 isl_die(aff->v->ctx, isl_error_invalid,
364                         "position out of bounds", return -1);
365
366         pos += isl_local_space_offset(aff->ls, type);
367         isl_int_set(*v, aff->v->el[1 + pos]);
368
369         return 0;
370 }
371
372 __isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v)
373 {
374         aff = isl_aff_cow(aff);
375         if (!aff)
376                 return NULL;
377
378         aff->v = isl_vec_cow(aff->v);
379         if (!aff->v)
380                 return isl_aff_free(aff);
381
382         isl_int_set(aff->v->el[0], v);
383
384         return aff;
385 }
386
387 __isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v)
388 {
389         aff = isl_aff_cow(aff);
390         if (!aff)
391                 return NULL;
392
393         aff->v = isl_vec_cow(aff->v);
394         if (!aff->v)
395                 return isl_aff_free(aff);
396
397         isl_int_set(aff->v->el[1], v);
398
399         return aff;
400 }
401
402 __isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v)
403 {
404         if (isl_int_is_zero(v))
405                 return aff;
406
407         aff = isl_aff_cow(aff);
408         if (!aff)
409                 return NULL;
410
411         aff->v = isl_vec_cow(aff->v);
412         if (!aff->v)
413                 return isl_aff_free(aff);
414
415         isl_int_addmul(aff->v->el[1], aff->v->el[0], v);
416
417         return aff;
418 }
419
420 __isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
421 {
422         isl_int t;
423
424         isl_int_init(t);
425         isl_int_set_si(t, v);
426         aff = isl_aff_add_constant(aff, t);
427         isl_int_clear(t);
428
429         return aff;
430 }
431
432 __isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
433 {
434         aff = isl_aff_cow(aff);
435         if (!aff)
436                 return NULL;
437
438         aff->v = isl_vec_cow(aff->v);
439         if (!aff->v)
440                 return isl_aff_free(aff);
441
442         isl_int_set_si(aff->v->el[1], v);
443
444         return aff;
445 }
446
447 __isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
448         enum isl_dim_type type, int pos, isl_int v)
449 {
450         if (!aff)
451                 return NULL;
452
453         if (type == isl_dim_out)
454                 isl_die(aff->v->ctx, isl_error_invalid,
455                         "output/set dimension does not have a coefficient",
456                         return isl_aff_free(aff));
457         if (type == isl_dim_in)
458                 type = isl_dim_set;
459
460         if (pos >= isl_local_space_dim(aff->ls, type))
461                 isl_die(aff->v->ctx, isl_error_invalid,
462                         "position out of bounds", return isl_aff_free(aff));
463
464         aff = isl_aff_cow(aff);
465         if (!aff)
466                 return NULL;
467
468         aff->v = isl_vec_cow(aff->v);
469         if (!aff->v)
470                 return isl_aff_free(aff);
471
472         pos += isl_local_space_offset(aff->ls, type);
473         isl_int_set(aff->v->el[1 + pos], v);
474
475         return aff;
476 }
477
478 __isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff,
479         enum isl_dim_type type, int pos, int v)
480 {
481         if (!aff)
482                 return NULL;
483
484         if (type == isl_dim_out)
485                 isl_die(aff->v->ctx, isl_error_invalid,
486                         "output/set dimension does not have a coefficient",
487                         return isl_aff_free(aff));
488         if (type == isl_dim_in)
489                 type = isl_dim_set;
490
491         if (pos >= isl_local_space_dim(aff->ls, type))
492                 isl_die(aff->v->ctx, isl_error_invalid,
493                         "position out of bounds", return isl_aff_free(aff));
494
495         aff = isl_aff_cow(aff);
496         if (!aff)
497                 return NULL;
498
499         aff->v = isl_vec_cow(aff->v);
500         if (!aff->v)
501                 return isl_aff_free(aff);
502
503         pos += isl_local_space_offset(aff->ls, type);
504         isl_int_set_si(aff->v->el[1 + pos], v);
505
506         return aff;
507 }
508
509 __isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff,
510         enum isl_dim_type type, int pos, isl_int v)
511 {
512         if (!aff)
513                 return NULL;
514
515         if (type == isl_dim_out)
516                 isl_die(aff->v->ctx, isl_error_invalid,
517                         "output/set dimension does not have a coefficient",
518                         return isl_aff_free(aff));
519         if (type == isl_dim_in)
520                 type = isl_dim_set;
521
522         if (pos >= isl_local_space_dim(aff->ls, type))
523                 isl_die(aff->v->ctx, isl_error_invalid,
524                         "position out of bounds", return isl_aff_free(aff));
525
526         aff = isl_aff_cow(aff);
527         if (!aff)
528                 return NULL;
529
530         aff->v = isl_vec_cow(aff->v);
531         if (!aff->v)
532                 return isl_aff_free(aff);
533
534         pos += isl_local_space_offset(aff->ls, type);
535         isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v);
536
537         return aff;
538 }
539
540 __isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff,
541         enum isl_dim_type type, int pos, int v)
542 {
543         isl_int t;
544
545         isl_int_init(t);
546         isl_int_set_si(t, v);
547         aff = isl_aff_add_coefficient(aff, type, pos, t);
548         isl_int_clear(t);
549
550         return aff;
551 }
552
553 __isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos)
554 {
555         if (!aff)
556                 return NULL;
557
558         return isl_local_space_get_div(aff->ls, pos);
559 }
560
561 __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
562 {
563         aff = isl_aff_cow(aff);
564         if (!aff)
565                 return NULL;
566         aff->v = isl_vec_cow(aff->v);
567         if (!aff->v)
568                 return isl_aff_free(aff);
569
570         isl_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1);
571
572         return aff;
573 }
574
575 __isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff)
576 {
577         if (!aff)
578                 return NULL;
579         aff->v = isl_vec_normalize(aff->v);
580         if (!aff->v)
581                 return isl_aff_free(aff);
582         return aff;
583 }
584
585 /* Given f, return floor(f).
586  * If f is an integer expression, then just return f.
587  * Otherwise, if f = g/m, write g = q m + r,
588  * create a new div d = [r/m] and return the expression q + d.
589  * The coefficients in r are taken to lie between -m/2 and m/2.
590  */
591 __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
592 {
593         int i;
594         int size;
595         isl_ctx *ctx;
596         isl_vec *div;
597
598         if (!aff)
599                 return NULL;
600
601         if (isl_int_is_one(aff->v->el[0]))
602                 return aff;
603
604         aff = isl_aff_cow(aff);
605         if (!aff)
606                 return NULL;
607
608         aff->v = isl_vec_cow(aff->v);
609         div = isl_vec_copy(aff->v);
610         div = isl_vec_cow(div);
611         if (!div)
612                 return isl_aff_free(aff);
613
614         ctx = isl_aff_get_ctx(aff);
615         isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two);
616         for (i = 1; i < aff->v->size; ++i) {
617                 isl_int_fdiv_r(div->el[i], div->el[i], div->el[0]);
618                 isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0]);
619                 if (isl_int_gt(div->el[i], aff->v->el[0])) {
620                         isl_int_sub(div->el[i], div->el[i], div->el[0]);
621                         isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1);
622                 }
623         }
624
625         aff->ls = isl_local_space_add_div(aff->ls, div);
626         if (!aff->ls)
627                 return isl_aff_free(aff);
628
629         size = aff->v->size;
630         aff->v = isl_vec_extend(aff->v, size + 1);
631         if (!aff->v)
632                 return isl_aff_free(aff);
633         isl_int_set_si(aff->v->el[0], 1);
634         isl_int_set_si(aff->v->el[size], 1);
635
636         return aff;
637 }
638
639 /* Compute
640  *
641  *      aff mod m = aff - m * floor(aff/m)
642  */
643 __isl_give isl_aff *isl_aff_mod(__isl_take isl_aff *aff, isl_int m)
644 {
645         isl_aff *res;
646
647         res = isl_aff_copy(aff);
648         aff = isl_aff_scale_down(aff, m);
649         aff = isl_aff_floor(aff);
650         aff = isl_aff_scale(aff, m);
651         res = isl_aff_sub(res, aff);
652
653         return res;
654 }
655
656 /* Compute
657  *
658  *      pwaff mod m = pwaff - m * floor(pwaff/m)
659  */
660 __isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m)
661 {
662         isl_pw_aff *res;
663
664         res = isl_pw_aff_copy(pwaff);
665         pwaff = isl_pw_aff_scale_down(pwaff, m);
666         pwaff = isl_pw_aff_floor(pwaff);
667         pwaff = isl_pw_aff_scale(pwaff, m);
668         res = isl_pw_aff_sub(res, pwaff);
669
670         return res;
671 }
672
673 /* Given f, return ceil(f).
674  * If f is an integer expression, then just return f.
675  * Otherwise, create a new div d = [-f] and return the expression -d.
676  */
677 __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
678 {
679         if (!aff)
680                 return NULL;
681
682         if (isl_int_is_one(aff->v->el[0]))
683                 return aff;
684
685         aff = isl_aff_neg(aff);
686         aff = isl_aff_floor(aff);
687         aff = isl_aff_neg(aff);
688
689         return aff;
690 }
691
692 /* Apply the expansion computed by isl_merge_divs.
693  * The expansion itself is given by "exp" while the resulting
694  * list of divs is given by "div".
695  */
696 __isl_give isl_aff *isl_aff_expand_divs( __isl_take isl_aff *aff,
697         __isl_take isl_mat *div, int *exp)
698 {
699         int i, j;
700         int old_n_div;
701         int new_n_div;
702         int offset;
703
704         aff = isl_aff_cow(aff);
705         if (!aff || !div)
706                 goto error;
707
708         old_n_div = isl_local_space_dim(aff->ls, isl_dim_div);
709         new_n_div = isl_mat_rows(div);
710         if (new_n_div < old_n_div)
711                 isl_die(isl_mat_get_ctx(div), isl_error_invalid,
712                         "not an expansion", goto error);
713
714         aff->v = isl_vec_extend(aff->v, aff->v->size + new_n_div - old_n_div);
715         if (!aff->v)
716                 goto error;
717
718         offset = 1 + isl_local_space_offset(aff->ls, isl_dim_div);
719         j = old_n_div - 1;
720         for (i = new_n_div - 1; i >= 0; --i) {
721                 if (j >= 0 && exp[j] == i) {
722                         if (i != j)
723                                 isl_int_swap(aff->v->el[offset + i],
724                                              aff->v->el[offset + j]);
725                         j--;
726                 } else
727                         isl_int_set_si(aff->v->el[offset + i], 0);
728         }
729
730         aff->ls = isl_local_space_replace_divs(aff->ls, isl_mat_copy(div));
731         if (!aff->ls)
732                 goto error;
733         isl_mat_free(div);
734         return aff;
735 error:
736         isl_aff_free(aff);
737         isl_mat_free(div);
738         return NULL;
739 }
740
741 /* Add two affine expressions that live in the same local space.
742  */
743 static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1,
744         __isl_take isl_aff *aff2)
745 {
746         isl_int gcd, f;
747
748         aff1 = isl_aff_cow(aff1);
749         if (!aff1 || !aff2)
750                 goto error;
751
752         aff1->v = isl_vec_cow(aff1->v);
753         if (!aff1->v)
754                 goto error;
755
756         isl_int_init(gcd);
757         isl_int_init(f);
758         isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0]);
759         isl_int_divexact(f, aff2->v->el[0], gcd);
760         isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1);
761         isl_int_divexact(f, aff1->v->el[0], gcd);
762         isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1);
763         isl_int_divexact(f, aff2->v->el[0], gcd);
764         isl_int_mul(aff1->v->el[0], aff1->v->el[0], f);
765         isl_int_clear(f);
766         isl_int_clear(gcd);
767
768         isl_aff_free(aff2);
769         return aff1;
770 error:
771         isl_aff_free(aff1);
772         isl_aff_free(aff2);
773         return NULL;
774 }
775
776 __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
777         __isl_take isl_aff *aff2)
778 {
779         isl_ctx *ctx;
780         int *exp1 = NULL;
781         int *exp2 = NULL;
782         isl_mat *div;
783
784         if (!aff1 || !aff2)
785                 goto error;
786
787         ctx = isl_aff_get_ctx(aff1);
788         if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim))
789                 isl_die(ctx, isl_error_invalid,
790                         "spaces don't match", goto error);
791
792         if (aff1->ls->div->n_row == 0 && aff2->ls->div->n_row == 0)
793                 return add_expanded(aff1, aff2);
794
795         exp1 = isl_alloc_array(ctx, int, aff1->ls->div->n_row);
796         exp2 = isl_alloc_array(ctx, int, aff2->ls->div->n_row);
797         if (!exp1 || !exp2)
798                 goto error;
799
800         div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2);
801         aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1);
802         aff2 = isl_aff_expand_divs(aff2, div, exp2);
803         free(exp1);
804         free(exp2);
805
806         return add_expanded(aff1, aff2);
807 error:
808         free(exp1);
809         free(exp2);
810         isl_aff_free(aff1);
811         isl_aff_free(aff2);
812         return NULL;
813 }
814
815 __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
816         __isl_take isl_aff *aff2)
817 {
818         return isl_aff_add(aff1, isl_aff_neg(aff2));
819 }
820
821 __isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f)
822 {
823         isl_int gcd;
824
825         if (isl_int_is_one(f))
826                 return aff;
827
828         aff = isl_aff_cow(aff);
829         if (!aff)
830                 return NULL;
831         aff->v = isl_vec_cow(aff->v);
832         if (!aff->v)
833                 return isl_aff_free(aff);
834
835         isl_int_init(gcd);
836         isl_int_gcd(gcd, aff->v->el[0], f);
837         isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd);
838         isl_int_divexact(gcd, f, gcd);
839         isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
840         isl_int_clear(gcd);
841
842         return aff;
843 }
844
845 __isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
846 {
847         isl_int gcd;
848
849         if (isl_int_is_one(f))
850                 return aff;
851
852         aff = isl_aff_cow(aff);
853         if (!aff)
854                 return NULL;
855         aff->v = isl_vec_cow(aff->v);
856         if (!aff->v)
857                 return isl_aff_free(aff);
858
859         isl_int_init(gcd);
860         isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd);
861         isl_int_gcd(gcd, gcd, f);
862         isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
863         isl_int_divexact(gcd, f, gcd);
864         isl_int_mul(aff->v->el[0], aff->v->el[0], gcd);
865         isl_int_clear(gcd);
866
867         return aff;
868 }
869
870 __isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f)
871 {
872         isl_int v;
873
874         if (f == 1)
875                 return aff;
876
877         isl_int_init(v);
878         isl_int_set_ui(v, f);
879         aff = isl_aff_scale_down(aff, v);
880         isl_int_clear(v);
881
882         return aff;
883 }
884
885 __isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff,
886         enum isl_dim_type type, unsigned pos, const char *s)
887 {
888         aff = isl_aff_cow(aff);
889         if (!aff)
890                 return NULL;
891         if (type == isl_dim_out)
892                 isl_die(aff->v->ctx, isl_error_invalid,
893                         "cannot set name of output/set dimension",
894                         return isl_aff_free(aff));
895         if (type == isl_dim_in)
896                 type = isl_dim_set;
897         aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s);
898         if (!aff->ls)
899                 return isl_aff_free(aff);
900
901         return aff;
902 }
903
904 __isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff,
905         enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
906 {
907         aff = isl_aff_cow(aff);
908         if (!aff)
909                 return isl_id_free(id);
910         if (type == isl_dim_out)
911                 isl_die(aff->v->ctx, isl_error_invalid,
912                         "cannot set name of output/set dimension",
913                         goto error);
914         if (type == isl_dim_in)
915                 type = isl_dim_set;
916         aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id);
917         if (!aff->ls)
918                 return isl_aff_free(aff);
919
920         return aff;
921 error:
922         isl_id_free(id);
923         isl_aff_free(aff);
924         return NULL;
925 }
926
927 /* Exploit the equalities in "eq" to simplify the affine expression
928  * and the expressions of the integer divisions in the local space.
929  * The integer divisions in this local space are assumed to appear
930  * as regular dimensions in "eq".
931  */
932 static __isl_give isl_aff *isl_aff_substitute_equalities_lifted(
933         __isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
934 {
935         int i, j;
936         unsigned total;
937         unsigned n_div;
938
939         if (!eq)
940                 goto error;
941         if (eq->n_eq == 0) {
942                 isl_basic_set_free(eq);
943                 return aff;
944         }
945
946         aff = isl_aff_cow(aff);
947         if (!aff)
948                 goto error;
949
950         aff->ls = isl_local_space_substitute_equalities(aff->ls,
951                                                         isl_basic_set_copy(eq));
952         if (!aff->ls)
953                 goto error;
954
955         total = 1 + isl_space_dim(eq->dim, isl_dim_all);
956         n_div = eq->n_div;
957         for (i = 0; i < eq->n_eq; ++i) {
958                 j = isl_seq_last_non_zero(eq->eq[i], total + n_div);
959                 if (j < 0 || j == 0 || j >= total)
960                         continue;
961
962                 isl_seq_elim(aff->v->el + 1, eq->eq[i], j, total,
963                                 &aff->v->el[0]);
964         }
965
966         isl_basic_set_free(eq);
967         aff = isl_aff_normalize(aff);
968         return aff;
969 error:
970         isl_basic_set_free(eq);
971         isl_aff_free(aff);
972         return NULL;
973 }
974
975 /* Exploit the equalities in "eq" to simplify the affine expression
976  * and the expressions of the integer divisions in the local space.
977  */
978 static __isl_give isl_aff *isl_aff_substitute_equalities(
979         __isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
980 {
981         int n_div;
982
983         if (!aff || !eq)
984                 goto error;
985         n_div = isl_local_space_dim(aff->ls, isl_dim_div);
986         if (n_div > 0)
987                 eq = isl_basic_set_add(eq, isl_dim_set, n_div);
988         return isl_aff_substitute_equalities_lifted(aff, eq);
989 error:
990         isl_basic_set_free(eq);
991         isl_aff_free(aff);
992         return NULL;
993 }
994
995 /* Look for equalities among the variables shared by context and aff
996  * and the integer divisions of aff, if any.
997  * The equalities are then used to eliminate coefficients and/or integer
998  * divisions from aff.
999  */
1000 __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff,
1001         __isl_take isl_set *context)
1002 {
1003         isl_basic_set *hull;
1004         int n_div;
1005
1006         if (!aff)
1007                 goto error;
1008         n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1009         if (n_div > 0) {
1010                 isl_basic_set *bset;
1011                 isl_local_space *ls;
1012                 context = isl_set_add_dims(context, isl_dim_set, n_div);
1013                 ls = isl_aff_get_domain_local_space(aff);
1014                 bset = isl_basic_set_from_local_space(ls);
1015                 bset = isl_basic_set_lift(bset);
1016                 bset = isl_basic_set_flatten(bset);
1017                 context = isl_set_intersect(context,
1018                                             isl_set_from_basic_set(bset));
1019         }
1020
1021         hull = isl_set_affine_hull(context);
1022         return isl_aff_substitute_equalities_lifted(aff, hull);
1023 error:
1024         isl_aff_free(aff);
1025         isl_set_free(context);
1026         return NULL;
1027 }
1028
1029 __isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
1030         __isl_take isl_set *context)
1031 {
1032         isl_set *dom_context = isl_set_universe(isl_aff_get_domain_space(aff));
1033         dom_context = isl_set_intersect_params(dom_context, context);
1034         return isl_aff_gist(aff, dom_context);
1035 }
1036
1037 /* Return a basic set containing those elements in the space
1038  * of aff where it is non-negative.
1039  */
1040 __isl_give isl_basic_set *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff)
1041 {
1042         isl_constraint *ineq;
1043         isl_basic_set *bset;
1044
1045         ineq = isl_inequality_from_aff(aff);
1046
1047         bset = isl_basic_set_from_constraint(ineq);
1048         bset = isl_basic_set_simplify(bset);
1049         return bset;
1050 }
1051
1052 /* Return a basic set containing those elements in the space
1053  * of aff where it is zero.
1054  */
1055 __isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
1056 {
1057         isl_constraint *ineq;
1058         isl_basic_set *bset;
1059
1060         ineq = isl_equality_from_aff(aff);
1061
1062         bset = isl_basic_set_from_constraint(ineq);
1063         bset = isl_basic_set_simplify(bset);
1064         return bset;
1065 }
1066
1067 /* Return a basic set containing those elements in the shared space
1068  * of aff1 and aff2 where aff1 is greater than or equal to aff2.
1069  */
1070 __isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
1071         __isl_take isl_aff *aff2)
1072 {
1073         aff1 = isl_aff_sub(aff1, aff2);
1074
1075         return isl_aff_nonneg_basic_set(aff1);
1076 }
1077
1078 /* Return a basic set containing those elements in the shared space
1079  * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
1080  */
1081 __isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
1082         __isl_take isl_aff *aff2)
1083 {
1084         return isl_aff_ge_basic_set(aff2, aff1);
1085 }
1086
1087 __isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_set *dom,
1088         __isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
1089 {
1090         aff1 = isl_aff_add(aff1, aff2);
1091         aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
1092         return aff1;
1093 }
1094
1095 int isl_aff_is_empty(__isl_keep isl_aff *aff)
1096 {
1097         if (!aff)
1098                 return -1;
1099
1100         return 0;
1101 }
1102
1103 /* Check whether the given affine expression has non-zero coefficient
1104  * for any dimension in the given range or if any of these dimensions
1105  * appear with non-zero coefficients in any of the integer divisions
1106  * involved in the affine expression.
1107  */
1108 int isl_aff_involves_dims(__isl_keep isl_aff *aff,
1109         enum isl_dim_type type, unsigned first, unsigned n)
1110 {
1111         int i;
1112         isl_ctx *ctx;
1113         int *active = NULL;
1114         int involves = 0;
1115
1116         if (!aff)
1117                 return -1;
1118         if (n == 0)
1119                 return 0;
1120
1121         ctx = isl_aff_get_ctx(aff);
1122         if (first + n > isl_aff_dim(aff, type))
1123                 isl_die(ctx, isl_error_invalid,
1124                         "range out of bounds", return -1);
1125
1126         active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
1127         if (!active)
1128                 goto error;
1129
1130         first += isl_local_space_offset(aff->ls, type) - 1;
1131         for (i = 0; i < n; ++i)
1132                 if (active[first + i]) {
1133                         involves = 1;
1134                         break;
1135                 }
1136
1137         free(active);
1138
1139         return involves;
1140 error:
1141         free(active);
1142         return -1;
1143 }
1144
1145 __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
1146         enum isl_dim_type type, unsigned first, unsigned n)
1147 {
1148         isl_ctx *ctx;
1149
1150         if (!aff)
1151                 return NULL;
1152         if (type == isl_dim_out)
1153                 isl_die(aff->v->ctx, isl_error_invalid,
1154                         "cannot drop output/set dimension",
1155                         return isl_aff_free(aff));
1156         if (type == isl_dim_in)
1157                 type = isl_dim_set;
1158         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1159                 return aff;
1160
1161         ctx = isl_aff_get_ctx(aff);
1162         if (first + n > isl_local_space_dim(aff->ls, type))
1163                 isl_die(ctx, isl_error_invalid, "range out of bounds",
1164                         return isl_aff_free(aff));
1165
1166         aff = isl_aff_cow(aff);
1167         if (!aff)
1168                 return NULL;
1169
1170         aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
1171         if (!aff->ls)
1172                 return isl_aff_free(aff);
1173
1174         first += 1 + isl_local_space_offset(aff->ls, type);
1175         aff->v = isl_vec_drop_els(aff->v, first, n);
1176         if (!aff->v)
1177                 return isl_aff_free(aff);
1178
1179         return aff;
1180 }
1181
1182 /* Project the domain of the affine expression onto its parameter space.
1183  * The affine expression may not involve any of the domain dimensions.
1184  */
1185 __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
1186 {
1187         isl_space *space;
1188         unsigned n;
1189         int involves;
1190
1191         n = isl_aff_dim(aff, isl_dim_in);
1192         involves = isl_aff_involves_dims(aff, isl_dim_in, 0, n);
1193         if (involves < 0)
1194                 return isl_aff_free(aff);
1195         if (involves)
1196                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1197                     "affine expression involves some of the domain dimensions",
1198                     return isl_aff_free(aff));
1199         aff = isl_aff_drop_dims(aff, isl_dim_in, 0, n);
1200         space = isl_aff_get_domain_space(aff);
1201         space = isl_space_params(space);
1202         aff = isl_aff_reset_domain_space(aff, space);
1203         return aff;
1204 }
1205
1206 __isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
1207         enum isl_dim_type type, unsigned first, unsigned n)
1208 {
1209         isl_ctx *ctx;
1210
1211         if (!aff)
1212                 return NULL;
1213         if (type == isl_dim_out)
1214                 isl_die(aff->v->ctx, isl_error_invalid,
1215                         "cannot insert output/set dimensions",
1216                         return isl_aff_free(aff));
1217         if (type == isl_dim_in)
1218                 type = isl_dim_set;
1219         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1220                 return aff;
1221
1222         ctx = isl_aff_get_ctx(aff);
1223         if (first > isl_local_space_dim(aff->ls, type))
1224                 isl_die(ctx, isl_error_invalid, "position out of bounds",
1225                         return isl_aff_free(aff));
1226
1227         aff = isl_aff_cow(aff);
1228         if (!aff)
1229                 return NULL;
1230
1231         aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
1232         if (!aff->ls)
1233                 return isl_aff_free(aff);
1234
1235         first += 1 + isl_local_space_offset(aff->ls, type);
1236         aff->v = isl_vec_insert_zero_els(aff->v, first, n);
1237         if (!aff->v)
1238                 return isl_aff_free(aff);
1239
1240         return aff;
1241 }
1242
1243 __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
1244         enum isl_dim_type type, unsigned n)
1245 {
1246         unsigned pos;
1247
1248         pos = isl_aff_dim(aff, type);
1249
1250         return isl_aff_insert_dims(aff, type, pos, n);
1251 }
1252
1253 __isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff,
1254         enum isl_dim_type type, unsigned n)
1255 {
1256         unsigned pos;
1257
1258         pos = isl_pw_aff_dim(pwaff, type);
1259
1260         return isl_pw_aff_insert_dims(pwaff, type, pos, n);
1261 }
1262
1263 __isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff)
1264 {
1265         isl_set *dom = isl_set_universe(isl_aff_get_domain_space(aff));
1266         return isl_pw_aff_alloc(dom, aff);
1267 }
1268
1269 #undef PW
1270 #define PW isl_pw_aff
1271 #undef EL
1272 #define EL isl_aff
1273 #undef EL_IS_ZERO
1274 #define EL_IS_ZERO is_empty
1275 #undef ZERO
1276 #define ZERO empty
1277 #undef IS_ZERO
1278 #define IS_ZERO is_empty
1279 #undef FIELD
1280 #define FIELD aff
1281 #undef DEFAULT_IS_ZERO
1282 #define DEFAULT_IS_ZERO 0
1283
1284 #define NO_EVAL
1285 #define NO_OPT
1286 #define NO_MOVE_DIMS
1287 #define NO_LIFT
1288 #define NO_MORPH
1289
1290 #include <isl_pw_templ.c>
1291
1292 static __isl_give isl_set *align_params_pw_pw_set_and(
1293         __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2,
1294         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
1295                                     __isl_take isl_pw_aff *pwaff2))
1296 {
1297         if (!pwaff1 || !pwaff2)
1298                 goto error;
1299         if (isl_space_match(pwaff1->dim, isl_dim_param,
1300                           pwaff2->dim, isl_dim_param))
1301                 return fn(pwaff1, pwaff2);
1302         if (!isl_space_has_named_params(pwaff1->dim) ||
1303             !isl_space_has_named_params(pwaff2->dim))
1304                 isl_die(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid,
1305                         "unaligned unnamed parameters", goto error);
1306         pwaff1 = isl_pw_aff_align_params(pwaff1, isl_pw_aff_get_space(pwaff2));
1307         pwaff2 = isl_pw_aff_align_params(pwaff2, isl_pw_aff_get_space(pwaff1));
1308         return fn(pwaff1, pwaff2);
1309 error:
1310         isl_pw_aff_free(pwaff1);
1311         isl_pw_aff_free(pwaff2);
1312         return NULL;
1313 }
1314
1315 /* Compute a piecewise quasi-affine expression with a domain that
1316  * is the union of those of pwaff1 and pwaff2 and such that on each
1317  * cell, the quasi-affine expression is the better (according to cmp)
1318  * of those of pwaff1 and pwaff2.  If only one of pwaff1 or pwaff2
1319  * is defined on a given cell, then the associated expression
1320  * is the defined one.
1321  */
1322 static __isl_give isl_pw_aff *pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
1323         __isl_take isl_pw_aff *pwaff2,
1324         __isl_give isl_basic_set *(*cmp)(__isl_take isl_aff *aff1,
1325                                         __isl_take isl_aff *aff2))
1326 {
1327         int i, j, n;
1328         isl_pw_aff *res;
1329         isl_ctx *ctx;
1330         isl_set *set;
1331
1332         if (!pwaff1 || !pwaff2)
1333                 goto error;
1334
1335         ctx = isl_space_get_ctx(pwaff1->dim);
1336         if (!isl_space_is_equal(pwaff1->dim, pwaff2->dim))
1337                 isl_die(ctx, isl_error_invalid,
1338                         "arguments should live in same space", goto error);
1339
1340         if (isl_pw_aff_is_empty(pwaff1)) {
1341                 isl_pw_aff_free(pwaff1);
1342                 return pwaff2;
1343         }
1344
1345         if (isl_pw_aff_is_empty(pwaff2)) {
1346                 isl_pw_aff_free(pwaff2);
1347                 return pwaff1;
1348         }
1349
1350         n = 2 * (pwaff1->n + 1) * (pwaff2->n + 1);
1351         res = isl_pw_aff_alloc_size(isl_space_copy(pwaff1->dim), n);
1352
1353         for (i = 0; i < pwaff1->n; ++i) {
1354                 set = isl_set_copy(pwaff1->p[i].set);
1355                 for (j = 0; j < pwaff2->n; ++j) {
1356                         struct isl_set *common;
1357                         isl_set *better;
1358
1359                         common = isl_set_intersect(
1360                                         isl_set_copy(pwaff1->p[i].set),
1361                                         isl_set_copy(pwaff2->p[j].set));
1362                         better = isl_set_from_basic_set(cmp(
1363                                         isl_aff_copy(pwaff2->p[j].aff),
1364                                         isl_aff_copy(pwaff1->p[i].aff)));
1365                         better = isl_set_intersect(common, better);
1366                         if (isl_set_plain_is_empty(better)) {
1367                                 isl_set_free(better);
1368                                 continue;
1369                         }
1370                         set = isl_set_subtract(set, isl_set_copy(better));
1371
1372                         res = isl_pw_aff_add_piece(res, better,
1373                                                 isl_aff_copy(pwaff2->p[j].aff));
1374                 }
1375                 res = isl_pw_aff_add_piece(res, set,
1376                                                 isl_aff_copy(pwaff1->p[i].aff));
1377         }
1378
1379         for (j = 0; j < pwaff2->n; ++j) {
1380                 set = isl_set_copy(pwaff2->p[j].set);
1381                 for (i = 0; i < pwaff1->n; ++i)
1382                         set = isl_set_subtract(set,
1383                                         isl_set_copy(pwaff1->p[i].set));
1384                 res = isl_pw_aff_add_piece(res, set,
1385                                                 isl_aff_copy(pwaff2->p[j].aff));
1386         }
1387
1388         isl_pw_aff_free(pwaff1);
1389         isl_pw_aff_free(pwaff2);
1390
1391         return res;
1392 error:
1393         isl_pw_aff_free(pwaff1);
1394         isl_pw_aff_free(pwaff2);
1395         return NULL;
1396 }
1397
1398 /* Compute a piecewise quasi-affine expression with a domain that
1399  * is the union of those of pwaff1 and pwaff2 and such that on each
1400  * cell, the quasi-affine expression is the maximum of those of pwaff1
1401  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
1402  * cell, then the associated expression is the defined one.
1403  */
1404 static __isl_give isl_pw_aff *pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
1405         __isl_take isl_pw_aff *pwaff2)
1406 {
1407         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_ge_basic_set);
1408 }
1409
1410 __isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
1411         __isl_take isl_pw_aff *pwaff2)
1412 {
1413         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
1414                                                         &pw_aff_union_max);
1415 }
1416
1417 /* Compute a piecewise quasi-affine expression with a domain that
1418  * is the union of those of pwaff1 and pwaff2 and such that on each
1419  * cell, the quasi-affine expression is the minimum of those of pwaff1
1420  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
1421  * cell, then the associated expression is the defined one.
1422  */
1423 static __isl_give isl_pw_aff *pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
1424         __isl_take isl_pw_aff *pwaff2)
1425 {
1426         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_le_basic_set);
1427 }
1428
1429 __isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
1430         __isl_take isl_pw_aff *pwaff2)
1431 {
1432         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
1433                                                         &pw_aff_union_min);
1434 }
1435
1436 __isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
1437         __isl_take isl_pw_aff *pwaff2, int max)
1438 {
1439         if (max)
1440                 return isl_pw_aff_union_max(pwaff1, pwaff2);
1441         else
1442                 return isl_pw_aff_union_min(pwaff1, pwaff2);
1443 }
1444
1445 /* Construct a map with as domain the domain of pwaff and
1446  * one-dimensional range corresponding to the affine expressions.
1447  */
1448 static __isl_give isl_map *map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1449 {
1450         int i;
1451         isl_space *dim;
1452         isl_map *map;
1453
1454         if (!pwaff)
1455                 return NULL;
1456
1457         dim = isl_pw_aff_get_space(pwaff);
1458         map = isl_map_empty(dim);
1459
1460         for (i = 0; i < pwaff->n; ++i) {
1461                 isl_basic_map *bmap;
1462                 isl_map *map_i;
1463
1464                 bmap = isl_basic_map_from_aff(isl_aff_copy(pwaff->p[i].aff));
1465                 map_i = isl_map_from_basic_map(bmap);
1466                 map_i = isl_map_intersect_domain(map_i,
1467                                                 isl_set_copy(pwaff->p[i].set));
1468                 map = isl_map_union_disjoint(map, map_i);
1469         }
1470
1471         isl_pw_aff_free(pwaff);
1472
1473         return map;
1474 }
1475
1476 /* Construct a map with as domain the domain of pwaff and
1477  * one-dimensional range corresponding to the affine expressions.
1478  */
1479 __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1480 {
1481         if (!pwaff)
1482                 return NULL;
1483         if (isl_space_is_set(pwaff->dim))
1484                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1485                         "space of input is not a map",
1486                         return isl_pw_aff_free(pwaff));
1487         return map_from_pw_aff(pwaff);
1488 }
1489
1490 /* Construct a one-dimensional set with as parameter domain
1491  * the domain of pwaff and the single set dimension
1492  * corresponding to the affine expressions.
1493  */
1494 __isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1495 {
1496         if (!pwaff)
1497                 return NULL;
1498         if (!isl_space_is_set(pwaff->dim))
1499                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1500                         "space of input is not a set",
1501                         return isl_pw_aff_free(pwaff));
1502         return map_from_pw_aff(pwaff);
1503 }
1504
1505 /* Return a set containing those elements in the domain
1506  * of pwaff where it is non-negative.
1507  */
1508 __isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
1509 {
1510         int i;
1511         isl_set *set;
1512
1513         if (!pwaff)
1514                 return NULL;
1515
1516         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
1517
1518         for (i = 0; i < pwaff->n; ++i) {
1519                 isl_basic_set *bset;
1520                 isl_set *set_i;
1521
1522                 bset = isl_aff_nonneg_basic_set(isl_aff_copy(pwaff->p[i].aff));
1523                 set_i = isl_set_from_basic_set(bset);
1524                 set_i = isl_set_intersect(set_i, isl_set_copy(pwaff->p[i].set));
1525                 set = isl_set_union_disjoint(set, set_i);
1526         }
1527
1528         isl_pw_aff_free(pwaff);
1529
1530         return set;
1531 }
1532
1533 /* Return a set containing those elements in the domain
1534  * of pwaff where it is zero (if complement is 0) or not zero
1535  * (if complement is 1).
1536  */
1537 static __isl_give isl_set *pw_aff_zero_set(__isl_take isl_pw_aff *pwaff,
1538         int complement)
1539 {
1540         int i;
1541         isl_set *set;
1542
1543         if (!pwaff)
1544                 return NULL;
1545
1546         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
1547
1548         for (i = 0; i < pwaff->n; ++i) {
1549                 isl_basic_set *bset;
1550                 isl_set *set_i, *zero;
1551
1552                 bset = isl_aff_zero_basic_set(isl_aff_copy(pwaff->p[i].aff));
1553                 zero = isl_set_from_basic_set(bset);
1554                 set_i = isl_set_copy(pwaff->p[i].set);
1555                 if (complement)
1556                         set_i = isl_set_subtract(set_i, zero);
1557                 else
1558                         set_i = isl_set_intersect(set_i, zero);
1559                 set = isl_set_union_disjoint(set, set_i);
1560         }
1561
1562         isl_pw_aff_free(pwaff);
1563
1564         return set;
1565 }
1566
1567 /* Return a set containing those elements in the domain
1568  * of pwaff where it is zero.
1569  */
1570 __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
1571 {
1572         return pw_aff_zero_set(pwaff, 0);
1573 }
1574
1575 /* Return a set containing those elements in the domain
1576  * of pwaff where it is not zero.
1577  */
1578 __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
1579 {
1580         return pw_aff_zero_set(pwaff, 1);
1581 }
1582
1583 /* Return a set containing those elements in the shared domain
1584  * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
1585  *
1586  * We compute the difference on the shared domain and then construct
1587  * the set of values where this difference is non-negative.
1588  * If strict is set, we first subtract 1 from the difference.
1589  * If equal is set, we only return the elements where pwaff1 and pwaff2
1590  * are equal.
1591  */
1592 static __isl_give isl_set *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
1593         __isl_take isl_pw_aff *pwaff2, int strict, int equal)
1594 {
1595         isl_set *set1, *set2;
1596
1597         set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
1598         set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
1599         set1 = isl_set_intersect(set1, set2);
1600         pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
1601         pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
1602         pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
1603
1604         if (strict) {
1605                 isl_space *dim = isl_set_get_space(set1);
1606                 isl_aff *aff;
1607                 aff = isl_aff_zero_on_domain(isl_local_space_from_space(dim));
1608                 aff = isl_aff_add_constant_si(aff, -1);
1609                 pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
1610         } else
1611                 isl_set_free(set1);
1612
1613         if (equal)
1614                 return isl_pw_aff_zero_set(pwaff1);
1615         return isl_pw_aff_nonneg_set(pwaff1);
1616 }
1617
1618 /* Return a set containing those elements in the shared domain
1619  * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
1620  */
1621 static __isl_give isl_set *pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
1622         __isl_take isl_pw_aff *pwaff2)
1623 {
1624         return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
1625 }
1626
1627 __isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
1628         __isl_take isl_pw_aff *pwaff2)
1629 {
1630         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_eq_set);
1631 }
1632
1633 /* Return a set containing those elements in the shared domain
1634  * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
1635  */
1636 static __isl_give isl_set *pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
1637         __isl_take isl_pw_aff *pwaff2)
1638 {
1639         return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
1640 }
1641
1642 __isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
1643         __isl_take isl_pw_aff *pwaff2)
1644 {
1645         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ge_set);
1646 }
1647
1648 /* Return a set containing those elements in the shared domain
1649  * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
1650  */
1651 static __isl_give isl_set *pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
1652         __isl_take isl_pw_aff *pwaff2)
1653 {
1654         return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
1655 }
1656
1657 __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
1658         __isl_take isl_pw_aff *pwaff2)
1659 {
1660         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_gt_set);
1661 }
1662
1663 __isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
1664         __isl_take isl_pw_aff *pwaff2)
1665 {
1666         return isl_pw_aff_ge_set(pwaff2, pwaff1);
1667 }
1668
1669 __isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
1670         __isl_take isl_pw_aff *pwaff2)
1671 {
1672         return isl_pw_aff_gt_set(pwaff2, pwaff1);
1673 }
1674
1675 /* Return a set containing those elements in the shared domain
1676  * of the elements of list1 and list2 where each element in list1
1677  * has the relation specified by "fn" with each element in list2.
1678  */
1679 static __isl_give isl_set *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
1680         __isl_take isl_pw_aff_list *list2,
1681         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
1682                                     __isl_take isl_pw_aff *pwaff2))
1683 {
1684         int i, j;
1685         isl_ctx *ctx;
1686         isl_set *set;
1687
1688         if (!list1 || !list2)
1689                 goto error;
1690
1691         ctx = isl_pw_aff_list_get_ctx(list1);
1692         if (list1->n < 1 || list2->n < 1)
1693                 isl_die(ctx, isl_error_invalid,
1694                         "list should contain at least one element", goto error);
1695
1696         set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
1697         for (i = 0; i < list1->n; ++i)
1698                 for (j = 0; j < list2->n; ++j) {
1699                         isl_set *set_ij;
1700
1701                         set_ij = fn(isl_pw_aff_copy(list1->p[i]),
1702                                     isl_pw_aff_copy(list2->p[j]));
1703                         set = isl_set_intersect(set, set_ij);
1704                 }
1705
1706         isl_pw_aff_list_free(list1);
1707         isl_pw_aff_list_free(list2);
1708         return set;
1709 error:
1710         isl_pw_aff_list_free(list1);
1711         isl_pw_aff_list_free(list2);
1712         return NULL;
1713 }
1714
1715 /* Return a set containing those elements in the shared domain
1716  * of the elements of list1 and list2 where each element in list1
1717  * is equal to each element in list2.
1718  */
1719 __isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
1720         __isl_take isl_pw_aff_list *list2)
1721 {
1722         return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
1723 }
1724
1725 __isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
1726         __isl_take isl_pw_aff_list *list2)
1727 {
1728         return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
1729 }
1730
1731 /* Return a set containing those elements in the shared domain
1732  * of the elements of list1 and list2 where each element in list1
1733  * is less than or equal to each element in list2.
1734  */
1735 __isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
1736         __isl_take isl_pw_aff_list *list2)
1737 {
1738         return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
1739 }
1740
1741 __isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
1742         __isl_take isl_pw_aff_list *list2)
1743 {
1744         return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
1745 }
1746
1747 __isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
1748         __isl_take isl_pw_aff_list *list2)
1749 {
1750         return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
1751 }
1752
1753 __isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
1754         __isl_take isl_pw_aff_list *list2)
1755 {
1756         return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
1757 }
1758
1759
1760 /* Return a set containing those elements in the shared domain
1761  * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
1762  */
1763 static __isl_give isl_set *pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
1764         __isl_take isl_pw_aff *pwaff2)
1765 {
1766         isl_set *set_lt, *set_gt;
1767
1768         set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
1769                                    isl_pw_aff_copy(pwaff2));
1770         set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
1771         return isl_set_union_disjoint(set_lt, set_gt);
1772 }
1773
1774 __isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
1775         __isl_take isl_pw_aff *pwaff2)
1776 {
1777         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ne_set);
1778 }
1779
1780 __isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
1781         isl_int v)
1782 {
1783         int i;
1784
1785         if (isl_int_is_one(v))
1786                 return pwaff;
1787         if (!isl_int_is_pos(v))
1788                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1789                         "factor needs to be positive",
1790                         return isl_pw_aff_free(pwaff));
1791         pwaff = isl_pw_aff_cow(pwaff);
1792         if (!pwaff)
1793                 return NULL;
1794         if (pwaff->n == 0)
1795                 return pwaff;
1796
1797         for (i = 0; i < pwaff->n; ++i) {
1798                 pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v);
1799                 if (!pwaff->p[i].aff)
1800                         return isl_pw_aff_free(pwaff);
1801         }
1802
1803         return pwaff;
1804 }
1805
1806 __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
1807 {
1808         int i;
1809
1810         pwaff = isl_pw_aff_cow(pwaff);
1811         if (!pwaff)
1812                 return NULL;
1813         if (pwaff->n == 0)
1814                 return pwaff;
1815
1816         for (i = 0; i < pwaff->n; ++i) {
1817                 pwaff->p[i].aff = isl_aff_floor(pwaff->p[i].aff);
1818                 if (!pwaff->p[i].aff)
1819                         return isl_pw_aff_free(pwaff);
1820         }
1821
1822         return pwaff;
1823 }
1824
1825 __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
1826 {
1827         int i;
1828
1829         pwaff = isl_pw_aff_cow(pwaff);
1830         if (!pwaff)
1831                 return NULL;
1832         if (pwaff->n == 0)
1833                 return pwaff;
1834
1835         for (i = 0; i < pwaff->n; ++i) {
1836                 pwaff->p[i].aff = isl_aff_ceil(pwaff->p[i].aff);
1837                 if (!pwaff->p[i].aff)
1838                         return isl_pw_aff_free(pwaff);
1839         }
1840
1841         return pwaff;
1842 }
1843
1844 /* Return an affine expression that is equal to pwaff_true for elements
1845  * in "cond" and to pwaff_false for elements not in "cond".
1846  * That is, return cond ? pwaff_true : pwaff_false;
1847  */
1848 __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_set *cond,
1849         __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
1850 {
1851         isl_set *comp;
1852
1853         comp = isl_set_complement(isl_set_copy(cond));
1854         pwaff_true = isl_pw_aff_intersect_domain(pwaff_true, cond);
1855         pwaff_false = isl_pw_aff_intersect_domain(pwaff_false, comp);
1856
1857         return isl_pw_aff_add_disjoint(pwaff_true, pwaff_false);
1858 }
1859
1860 int isl_aff_is_cst(__isl_keep isl_aff *aff)
1861 {
1862         if (!aff)
1863                 return -1;
1864
1865         return isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2) == -1;
1866 }
1867
1868 /* Check whether pwaff is a piecewise constant.
1869  */
1870 int isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
1871 {
1872         int i;
1873
1874         if (!pwaff)
1875                 return -1;
1876
1877         for (i = 0; i < pwaff->n; ++i) {
1878                 int is_cst = isl_aff_is_cst(pwaff->p[i].aff);
1879                 if (is_cst < 0 || !is_cst)
1880                         return is_cst;
1881         }
1882
1883         return 1;
1884 }
1885
1886 __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
1887         __isl_take isl_aff *aff2)
1888 {
1889         if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
1890                 return isl_aff_mul(aff2, aff1);
1891
1892         if (!isl_aff_is_cst(aff2))
1893                 isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,
1894                         "at least one affine expression should be constant",
1895                         goto error);
1896
1897         aff1 = isl_aff_cow(aff1);
1898         if (!aff1 || !aff2)
1899                 goto error;
1900
1901         aff1 = isl_aff_scale(aff1, aff2->v->el[1]);
1902         aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]);
1903
1904         isl_aff_free(aff2);
1905         return aff1;
1906 error:
1907         isl_aff_free(aff1);
1908         isl_aff_free(aff2);
1909         return NULL;
1910 }
1911
1912 static __isl_give isl_pw_aff *pw_aff_add(__isl_take isl_pw_aff *pwaff1,
1913         __isl_take isl_pw_aff *pwaff2)
1914 {
1915         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
1916 }
1917
1918 __isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
1919         __isl_take isl_pw_aff *pwaff2)
1920 {
1921         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_add);
1922 }
1923
1924 __isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1,
1925         __isl_take isl_pw_aff *pwaff2)
1926 {
1927         return isl_pw_aff_union_add_(pwaff1, pwaff2);
1928 }
1929
1930 static __isl_give isl_pw_aff *pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
1931         __isl_take isl_pw_aff *pwaff2)
1932 {
1933         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
1934 }
1935
1936 __isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
1937         __isl_take isl_pw_aff *pwaff2)
1938 {
1939         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_mul);
1940 }
1941
1942 static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
1943         __isl_take isl_pw_aff *pwaff2)
1944 {
1945         isl_set *le;
1946
1947         le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
1948                                 isl_pw_aff_copy(pwaff2));
1949         return isl_pw_aff_cond(le, pwaff1, pwaff2);
1950 }
1951
1952 __isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
1953         __isl_take isl_pw_aff *pwaff2)
1954 {
1955         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_min);
1956 }
1957
1958 static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
1959         __isl_take isl_pw_aff *pwaff2)
1960 {
1961         isl_set *le;
1962
1963         le = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
1964                                 isl_pw_aff_copy(pwaff2));
1965         return isl_pw_aff_cond(le, pwaff1, pwaff2);
1966 }
1967
1968 __isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
1969         __isl_take isl_pw_aff *pwaff2)
1970 {
1971         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_max);
1972 }
1973
1974 static __isl_give isl_pw_aff *pw_aff_list_reduce(
1975         __isl_take isl_pw_aff_list *list,
1976         __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pwaff1,
1977                                         __isl_take isl_pw_aff *pwaff2))
1978 {
1979         int i;
1980         isl_ctx *ctx;
1981         isl_pw_aff *res;
1982
1983         if (!list)
1984                 return NULL;
1985
1986         ctx = isl_pw_aff_list_get_ctx(list);
1987         if (list->n < 1)
1988                 isl_die(ctx, isl_error_invalid,
1989                         "list should contain at least one element",
1990                         return isl_pw_aff_list_free(list));
1991
1992         res = isl_pw_aff_copy(list->p[0]);
1993         for (i = 1; i < list->n; ++i)
1994                 res = fn(res, isl_pw_aff_copy(list->p[i]));
1995
1996         isl_pw_aff_list_free(list);
1997         return res;
1998 }
1999
2000 /* Return an isl_pw_aff that maps each element in the intersection of the
2001  * domains of the elements of list to the minimal corresponding affine
2002  * expression.
2003  */
2004 __isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
2005 {
2006         return pw_aff_list_reduce(list, &isl_pw_aff_min);
2007 }
2008
2009 /* Return an isl_pw_aff that maps each element in the intersection of the
2010  * domains of the elements of list to the maximal corresponding affine
2011  * expression.
2012  */
2013 __isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
2014 {
2015         return pw_aff_list_reduce(list, &isl_pw_aff_max);
2016 }
2017
2018 #undef BASE
2019 #define BASE aff
2020
2021 #include <isl_multi_templ.c>
2022
2023 __isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *maff1,
2024         __isl_take isl_multi_aff *maff2)
2025 {
2026         int i;
2027         isl_ctx *ctx;
2028
2029         maff1 = isl_multi_aff_cow(maff1);
2030         if (!maff1 || !maff2)
2031                 goto error;
2032
2033         ctx = isl_multi_aff_get_ctx(maff1);
2034         if (!isl_space_is_equal(maff1->space, maff2->space))
2035                 isl_die(ctx, isl_error_invalid,
2036                         "spaces don't match", goto error);
2037
2038         for (i = 0; i < maff1->n; ++i) {
2039                 maff1->p[i] = isl_aff_add(maff1->p[i],
2040                                             isl_aff_copy(maff2->p[i]));
2041                 if (!maff1->p[i])
2042                         goto error;
2043         }
2044
2045         isl_multi_aff_free(maff2);
2046         return maff1;
2047 error:
2048         isl_multi_aff_free(maff1);
2049         isl_multi_aff_free(maff2);
2050         return NULL;
2051 }
2052
2053 /* Exploit the equalities in "eq" to simplify the affine expressions.
2054  */
2055 static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
2056         __isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq)
2057 {
2058         int i;
2059
2060         maff = isl_multi_aff_cow(maff);
2061         if (!maff || !eq)
2062                 goto error;
2063
2064         for (i = 0; i < maff->n; ++i) {
2065                 maff->p[i] = isl_aff_substitute_equalities(maff->p[i],
2066                                                     isl_basic_set_copy(eq));
2067                 if (!maff->p[i])
2068                         goto error;
2069         }
2070
2071         isl_basic_set_free(eq);
2072         return maff;
2073 error:
2074         isl_basic_set_free(eq);
2075         isl_multi_aff_free(maff);
2076         return NULL;
2077 }
2078
2079 __isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
2080         isl_int f)
2081 {
2082         int i;
2083
2084         maff = isl_multi_aff_cow(maff);
2085         if (!maff)
2086                 return NULL;
2087
2088         for (i = 0; i < maff->n; ++i) {
2089                 maff->p[i] = isl_aff_scale(maff->p[i], f);
2090                 if (!maff->p[i])
2091                         return isl_multi_aff_free(maff);
2092         }
2093
2094         return maff;
2095 }
2096
2097 __isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_set *dom,
2098         __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
2099 {
2100         maff1 = isl_multi_aff_add(maff1, maff2);
2101         maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
2102         return maff1;
2103 }
2104
2105 int isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
2106 {
2107         if (!maff)
2108                 return -1;
2109
2110         return 0;
2111 }
2112
2113 int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1,
2114         __isl_keep isl_multi_aff *maff2)
2115 {
2116         int i;
2117         int equal;
2118
2119         if (!maff1 || !maff2)
2120                 return -1;
2121         if (maff1->n != maff2->n)
2122                 return 0;
2123         equal = isl_space_is_equal(maff1->space, maff2->space);
2124         if (equal < 0 || !equal)
2125                 return equal;
2126
2127         for (i = 0; i < maff1->n; ++i) {
2128                 equal = isl_aff_plain_is_equal(maff1->p[i], maff2->p[i]);
2129                 if (equal < 0 || !equal)
2130                         return equal;
2131         }
2132
2133         return 1;
2134 }
2135
2136 __isl_give isl_multi_aff *isl_multi_aff_set_dim_name(
2137         __isl_take isl_multi_aff *maff,
2138         enum isl_dim_type type, unsigned pos, const char *s)
2139 {
2140         int i;
2141
2142         maff = isl_multi_aff_cow(maff);
2143         if (!maff)
2144                 return NULL;
2145
2146         maff->space = isl_space_set_dim_name(maff->space, type, pos, s);
2147         if (!maff->space)
2148                 return isl_multi_aff_free(maff);
2149         for (i = 0; i < maff->n; ++i) {
2150                 maff->p[i] = isl_aff_set_dim_name(maff->p[i], type, pos, s);
2151                 if (!maff->p[i])
2152                         return isl_multi_aff_free(maff);
2153         }
2154
2155         return maff;
2156 }
2157
2158 __isl_give isl_multi_aff *isl_multi_aff_drop_dims(__isl_take isl_multi_aff *maff,
2159         enum isl_dim_type type, unsigned first, unsigned n)
2160 {
2161         int i;
2162
2163         maff = isl_multi_aff_cow(maff);
2164         if (!maff)
2165                 return NULL;
2166
2167         maff->space = isl_space_drop_dims(maff->space, type, first, n);
2168         if (!maff->space)
2169                 return isl_multi_aff_free(maff);
2170
2171         if (type == isl_dim_out) {
2172                 for (i = 0; i < n; ++i)
2173                         isl_aff_free(maff->p[first + i]);
2174                 for (i = first; i + n < maff->n; ++i)
2175                         maff->p[i] = maff->p[i + n];
2176                 maff->n -= n;
2177                 return maff;
2178         }
2179
2180         for (i = 0; i < maff->n; ++i) {
2181                 maff->p[i] = isl_aff_drop_dims(maff->p[i], type, first, n);
2182                 if (!maff->p[i])
2183                         return isl_multi_aff_free(maff);
2184         }
2185
2186         return maff;
2187 }
2188
2189 #undef PW
2190 #define PW isl_pw_multi_aff
2191 #undef EL
2192 #define EL isl_multi_aff
2193 #undef EL_IS_ZERO
2194 #define EL_IS_ZERO is_empty
2195 #undef ZERO
2196 #define ZERO empty
2197 #undef IS_ZERO
2198 #define IS_ZERO is_empty
2199 #undef FIELD
2200 #define FIELD maff
2201 #undef DEFAULT_IS_ZERO
2202 #define DEFAULT_IS_ZERO 0
2203
2204 #define NO_NEG
2205 #define NO_EVAL
2206 #define NO_OPT
2207 #define NO_INVOLVES_DIMS
2208 #define NO_MOVE_DIMS
2209 #define NO_INSERT_DIMS
2210 #define NO_LIFT
2211 #define NO_MORPH
2212
2213 #include <isl_pw_templ.c>
2214
2215 static __isl_give isl_pw_multi_aff *pw_multi_aff_add(
2216         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
2217 {
2218         return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
2219                                                 &isl_multi_aff_add);
2220 }
2221
2222 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
2223         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
2224 {
2225         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
2226                                                 &pw_multi_aff_add);
2227 }
2228
2229 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add(
2230         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
2231 {
2232         return isl_pw_multi_aff_union_add_(pma1, pma2);
2233 }
2234
2235 /* Construct a map mapping the domain the piecewise multi-affine expression
2236  * to its range, with each dimension in the range equated to the
2237  * corresponding affine expression on its cell.
2238  */
2239 __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
2240 {
2241         int i;
2242         isl_map *map;
2243
2244         if (!pma)
2245                 return NULL;
2246
2247         map = isl_map_empty(isl_pw_multi_aff_get_space(pma));
2248
2249         for (i = 0; i < pma->n; ++i) {
2250                 isl_multi_aff *maff;
2251                 isl_basic_map *bmap;
2252                 isl_map *map_i;
2253
2254                 maff = isl_multi_aff_copy(pma->p[i].maff);
2255                 bmap = isl_basic_map_from_multi_aff(maff);
2256                 map_i = isl_map_from_basic_map(bmap);
2257                 map_i = isl_map_intersect_domain(map_i,
2258                                                 isl_set_copy(pma->p[i].set));
2259                 map = isl_map_union_disjoint(map, map_i);
2260         }
2261
2262         isl_pw_multi_aff_free(pma);
2263         return map;
2264 }
2265
2266 __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
2267 {
2268         if (!isl_space_is_set(pma->dim))
2269                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
2270                         "isl_pw_multi_aff cannot be converted into an isl_set",
2271                         return isl_pw_multi_aff_free(pma));
2272
2273         return isl_map_from_pw_multi_aff(pma);
2274 }
2275
2276 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
2277  * This obivously only works if the input "map" is single-valued.
2278  * If so, we compute the lexicographic minimum of the image in the form
2279  * of an isl_pw_multi_aff.  Since the image is unique, it is equal
2280  * to its lexicographic minimum.
2281  * If the input is not single-valued, we produce an error.
2282  */
2283 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
2284 {
2285         int i;
2286         int sv;
2287         isl_pw_multi_aff *pma;
2288
2289         if (!map)
2290                 return NULL;
2291
2292         sv = isl_map_is_single_valued(map);
2293         if (sv < 0)
2294                 goto error;
2295         if (!sv)
2296                 isl_die(isl_map_get_ctx(map), isl_error_invalid,
2297                         "map is not single-valued", goto error);
2298         map = isl_map_make_disjoint(map);
2299         if (!map)
2300                 return NULL;
2301
2302         pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
2303
2304         for (i = 0; i < map->n; ++i) {
2305                 isl_pw_multi_aff *pma_i;
2306                 isl_basic_map *bmap;
2307                 bmap = isl_basic_map_copy(map->p[i]);
2308                 pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
2309                 pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
2310         }
2311
2312         isl_map_free(map);
2313         return pma;
2314 error:
2315         isl_map_free(map);
2316         return NULL;
2317 }
2318
2319 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
2320 {
2321         return isl_pw_multi_aff_from_map(set);
2322 }
2323
2324 /* Plug in "subs" for dimension "type", "pos" of "aff".
2325  *
2326  * Let i be the dimension to replace and let "subs" be of the form
2327  *
2328  *      f/d
2329  *
2330  * and "aff" of the form
2331  *
2332  *      (a i + g)/m
2333  *
2334  * The result is
2335  *
2336  *      floor((a f + d g')/(m d))
2337  *
2338  * where g' is the result of plugging in "subs" in each of the integer
2339  * divisions in g.
2340  */
2341 __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
2342         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
2343 {
2344         isl_ctx *ctx;
2345         isl_int v;
2346
2347         aff = isl_aff_cow(aff);
2348         if (!aff || !subs)
2349                 return isl_aff_free(aff);
2350
2351         ctx = isl_aff_get_ctx(aff);
2352         if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
2353                 isl_die(ctx, isl_error_invalid,
2354                         "spaces don't match", return isl_aff_free(aff));
2355         if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
2356                 isl_die(ctx, isl_error_unsupported,
2357                         "cannot handle divs yet", return isl_aff_free(aff));
2358
2359         aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
2360         if (!aff->ls)
2361                 return isl_aff_free(aff);
2362
2363         aff->v = isl_vec_cow(aff->v);
2364         if (!aff->v)
2365                 return isl_aff_free(aff);
2366
2367         pos += isl_local_space_offset(aff->ls, type);
2368
2369         isl_int_init(v);
2370         isl_int_set(v, aff->v->el[1 + pos]);
2371         isl_int_set_si(aff->v->el[1 + pos], 0);
2372         isl_seq_combine(aff->v->el + 1, subs->v->el[0], aff->v->el + 1,
2373                         v, subs->v->el + 1, subs->v->size - 1);
2374         isl_int_mul(aff->v->el[0], aff->v->el[0], subs->v->el[0]);
2375         isl_int_clear(v);
2376
2377         return aff;
2378 }
2379
2380 /* Plug in "subs" for dimension "type", "pos" in each of the affine
2381  * expressions in "maff".
2382  */
2383 __isl_give isl_multi_aff *isl_multi_aff_substitute(
2384         __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
2385         __isl_keep isl_aff *subs)
2386 {
2387         int i;
2388
2389         maff = isl_multi_aff_cow(maff);
2390         if (!maff || !subs)
2391                 return isl_multi_aff_free(maff);
2392
2393         if (type == isl_dim_in)
2394                 type = isl_dim_set;
2395
2396         for (i = 0; i < maff->n; ++i) {
2397                 maff->p[i] = isl_aff_substitute(maff->p[i], type, pos, subs);
2398                 if (!maff->p[i])
2399                         return isl_multi_aff_free(maff);
2400         }
2401
2402         return maff;
2403 }
2404
2405 /* Plug in "subs" for dimension "type", "pos" of "pma".
2406  *
2407  * pma is of the form
2408  *
2409  *      A_i(v) -> M_i(v)
2410  *
2411  * while subs is of the form
2412  *
2413  *      v' = B_j(v) -> S_j
2414  *
2415  * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
2416  * has a contribution in the result, in particular
2417  *
2418  *      C_ij(S_j) -> M_i(S_j)
2419  *
2420  * Note that plugging in S_j in C_ij may also result in an empty set
2421  * and this contribution should simply be discarded.
2422  */
2423 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
2424         __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
2425         __isl_keep isl_pw_aff *subs)
2426 {
2427         int i, j, n;
2428         isl_pw_multi_aff *res;
2429
2430         if (!pma || !subs)
2431                 return isl_pw_multi_aff_free(pma);
2432
2433         n = pma->n * subs->n;
2434         res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
2435
2436         for (i = 0; i < pma->n; ++i) {
2437                 for (j = 0; j < subs->n; ++j) {
2438                         isl_set *common;
2439                         isl_multi_aff *res_ij;
2440                         common = isl_set_intersect(
2441                                         isl_set_copy(pma->p[i].set),
2442                                         isl_set_copy(subs->p[j].set));
2443                         common = isl_set_substitute(common,
2444                                         type, pos, subs->p[j].aff);
2445                         if (isl_set_plain_is_empty(common)) {
2446                                 isl_set_free(common);
2447                                 continue;
2448                         }
2449
2450                         res_ij = isl_multi_aff_substitute(
2451                                         isl_multi_aff_copy(pma->p[i].maff),
2452                                         type, pos, subs->p[j].aff);
2453
2454                         res = isl_pw_multi_aff_add_piece(res, common, res_ij);
2455                 }
2456         }
2457
2458         isl_pw_multi_aff_free(pma);
2459         return res;
2460 }
2461
2462 /* Extend the local space of "dst" to include the divs
2463  * in the local space of "src".
2464  */
2465 __isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
2466         __isl_keep isl_aff *src)
2467 {
2468         isl_ctx *ctx;
2469         int *exp1 = NULL;
2470         int *exp2 = NULL;
2471         isl_mat *div;
2472
2473         if (!src || !dst)
2474                 return isl_aff_free(dst);
2475
2476         ctx = isl_aff_get_ctx(src);
2477         if (!isl_space_is_equal(src->ls->dim, dst->ls->dim))
2478                 isl_die(ctx, isl_error_invalid,
2479                         "spaces don't match", goto error);
2480
2481         if (src->ls->div->n_row == 0)
2482                 return dst;
2483
2484         exp1 = isl_alloc_array(ctx, int, src->ls->div->n_row);
2485         exp2 = isl_alloc_array(ctx, int, dst->ls->div->n_row);
2486         if (!exp1 || !exp2)
2487                 goto error;
2488
2489         div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
2490         dst = isl_aff_expand_divs(dst, div, exp2);
2491         free(exp1);
2492         free(exp2);
2493
2494         return dst;
2495 error:
2496         free(exp1);
2497         free(exp2);
2498         return isl_aff_free(dst);
2499 }
2500
2501 /* Adjust the local spaces of the affine expressions in "maff"
2502  * such that they all have the save divs.
2503  */
2504 __isl_give isl_multi_aff *isl_multi_aff_align_divs(
2505         __isl_take isl_multi_aff *maff)
2506 {
2507         int i;
2508
2509         if (!maff)
2510                 return NULL;
2511         if (maff->n == 0)
2512                 return maff;
2513         maff = isl_multi_aff_cow(maff);
2514         if (!maff)
2515                 return NULL;
2516
2517         for (i = 1; i < maff->n; ++i)
2518                 maff->p[0] = isl_aff_align_divs(maff->p[0], maff->p[i]);
2519         for (i = 1; i < maff->n; ++i) {
2520                 maff->p[i] = isl_aff_align_divs(maff->p[i], maff->p[0]);
2521                 if (!maff->p[i])
2522                         return isl_multi_aff_free(maff);
2523         }
2524
2525         return maff;
2526 }
2527
2528 __isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
2529 {
2530         aff = isl_aff_cow(aff);
2531         if (!aff)
2532                 return NULL;
2533
2534         aff->ls = isl_local_space_lift(aff->ls);
2535         if (!aff->ls)
2536                 return isl_aff_free(aff);
2537
2538         return aff;
2539 }
2540
2541 /* Lift "maff" to a space with extra dimensions such that the result
2542  * has no more existentially quantified variables.
2543  * If "ls" is not NULL, then *ls is assigned the local space that lies
2544  * at the basis of the lifting applied to "maff".
2545  */
2546 __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
2547         __isl_give isl_local_space **ls)
2548 {
2549         int i;
2550         isl_space *space;
2551         unsigned n_div;
2552
2553         if (ls)
2554                 *ls = NULL;
2555
2556         if (!maff)
2557                 return NULL;
2558
2559         if (maff->n == 0) {
2560                 if (ls) {
2561                         isl_space *space = isl_multi_aff_get_domain_space(maff);
2562                         *ls = isl_local_space_from_space(space);
2563                         if (!*ls)
2564                                 return isl_multi_aff_free(maff);
2565                 }
2566                 return maff;
2567         }
2568
2569         maff = isl_multi_aff_cow(maff);
2570         maff = isl_multi_aff_align_divs(maff);
2571         if (!maff)
2572                 return NULL;
2573
2574         n_div = isl_aff_dim(maff->p[0], isl_dim_div);
2575         space = isl_multi_aff_get_space(maff);
2576         space = isl_space_lift(isl_space_domain(space), n_div);
2577         space = isl_space_extend_domain_with_range(space,
2578                                                 isl_multi_aff_get_space(maff));
2579         if (!space)
2580                 return isl_multi_aff_free(maff);
2581         isl_space_free(maff->space);
2582         maff->space = space;
2583
2584         if (ls) {
2585                 *ls = isl_aff_get_domain_local_space(maff->p[0]);
2586                 if (!*ls)
2587                         return isl_multi_aff_free(maff);
2588         }
2589
2590         for (i = 0; i < maff->n; ++i) {
2591                 maff->p[i] = isl_aff_lift(maff->p[i]);
2592                 if (!maff->p[i])
2593                         goto error;
2594         }
2595
2596         return maff;
2597 error:
2598         if (ls)
2599                 isl_local_space_free(*ls);
2600         return isl_multi_aff_free(maff);
2601 }
2602
2603
2604 /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
2605  */
2606 __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
2607         __isl_keep isl_pw_multi_aff *pma, int pos)
2608 {
2609         int i;
2610         int n_out;
2611         isl_space *space;
2612         isl_pw_aff *pa;
2613
2614         if (!pma)
2615                 return NULL;
2616
2617         n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
2618         if (pos < 0 || pos >= n_out)
2619                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
2620                         "index out of bounds", return NULL);
2621
2622         space = isl_pw_multi_aff_get_space(pma);
2623         space = isl_space_drop_dims(space, isl_dim_out,
2624                                     pos + 1, n_out - pos - 1);
2625         space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
2626
2627         pa = isl_pw_aff_alloc_size(space, pma->n);
2628         for (i = 0; i < pma->n; ++i) {
2629                 isl_aff *aff;
2630                 aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
2631                 pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
2632         }
2633
2634         return pa;
2635 }