isl_multi_aff_drop_dims: handle removal of output dimensions
[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
1044         ineq = isl_inequality_from_aff(aff);
1045
1046         return isl_basic_set_from_constraint(ineq);
1047 }
1048
1049 /* Return a basic set containing those elements in the space
1050  * of aff where it is zero.
1051  */
1052 __isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
1053 {
1054         isl_constraint *ineq;
1055
1056         ineq = isl_equality_from_aff(aff);
1057
1058         return isl_basic_set_from_constraint(ineq);
1059 }
1060
1061 /* Return a basic set containing those elements in the shared space
1062  * of aff1 and aff2 where aff1 is greater than or equal to aff2.
1063  */
1064 __isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
1065         __isl_take isl_aff *aff2)
1066 {
1067         aff1 = isl_aff_sub(aff1, aff2);
1068
1069         return isl_aff_nonneg_basic_set(aff1);
1070 }
1071
1072 /* Return a basic set containing those elements in the shared space
1073  * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
1074  */
1075 __isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
1076         __isl_take isl_aff *aff2)
1077 {
1078         return isl_aff_ge_basic_set(aff2, aff1);
1079 }
1080
1081 __isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_set *dom,
1082         __isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
1083 {
1084         aff1 = isl_aff_add(aff1, aff2);
1085         aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
1086         return aff1;
1087 }
1088
1089 int isl_aff_is_empty(__isl_keep isl_aff *aff)
1090 {
1091         if (!aff)
1092                 return -1;
1093
1094         return 0;
1095 }
1096
1097 /* Check whether the given affine expression has non-zero coefficient
1098  * for any dimension in the given range or if any of these dimensions
1099  * appear with non-zero coefficients in any of the integer divisions
1100  * involved in the affine expression.
1101  */
1102 int isl_aff_involves_dims(__isl_keep isl_aff *aff,
1103         enum isl_dim_type type, unsigned first, unsigned n)
1104 {
1105         int i;
1106         isl_ctx *ctx;
1107         int *active = NULL;
1108         int involves = 0;
1109
1110         if (!aff)
1111                 return -1;
1112         if (n == 0)
1113                 return 0;
1114
1115         ctx = isl_aff_get_ctx(aff);
1116         if (first + n > isl_aff_dim(aff, type))
1117                 isl_die(ctx, isl_error_invalid,
1118                         "range out of bounds", return -1);
1119
1120         active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
1121         if (!active)
1122                 goto error;
1123
1124         first += isl_local_space_offset(aff->ls, type) - 1;
1125         for (i = 0; i < n; ++i)
1126                 if (active[first + i]) {
1127                         involves = 1;
1128                         break;
1129                 }
1130
1131         free(active);
1132
1133         return involves;
1134 error:
1135         free(active);
1136         return -1;
1137 }
1138
1139 __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
1140         enum isl_dim_type type, unsigned first, unsigned n)
1141 {
1142         isl_ctx *ctx;
1143
1144         if (!aff)
1145                 return NULL;
1146         if (type == isl_dim_out)
1147                 isl_die(aff->v->ctx, isl_error_invalid,
1148                         "cannot drop output/set dimension",
1149                         return isl_aff_free(aff));
1150         if (type == isl_dim_in)
1151                 type = isl_dim_set;
1152         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1153                 return aff;
1154
1155         ctx = isl_aff_get_ctx(aff);
1156         if (first + n > isl_local_space_dim(aff->ls, type))
1157                 isl_die(ctx, isl_error_invalid, "range out of bounds",
1158                         return isl_aff_free(aff));
1159
1160         aff = isl_aff_cow(aff);
1161         if (!aff)
1162                 return NULL;
1163
1164         aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
1165         if (!aff->ls)
1166                 return isl_aff_free(aff);
1167
1168         first += 1 + isl_local_space_offset(aff->ls, type);
1169         aff->v = isl_vec_drop_els(aff->v, first, n);
1170         if (!aff->v)
1171                 return isl_aff_free(aff);
1172
1173         return aff;
1174 }
1175
1176 /* Project the domain of the affine expression onto its parameter space.
1177  * The affine expression may not involve any of the domain dimensions.
1178  */
1179 __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
1180 {
1181         isl_space *space;
1182         unsigned n;
1183         int involves;
1184
1185         n = isl_aff_dim(aff, isl_dim_in);
1186         involves = isl_aff_involves_dims(aff, isl_dim_in, 0, n);
1187         if (involves < 0)
1188                 return isl_aff_free(aff);
1189         if (involves)
1190                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1191                     "affine expression involves some of the domain dimensions",
1192                     return isl_aff_free(aff));
1193         aff = isl_aff_drop_dims(aff, isl_dim_in, 0, n);
1194         space = isl_aff_get_domain_space(aff);
1195         space = isl_space_params(space);
1196         aff = isl_aff_reset_domain_space(aff, space);
1197         return aff;
1198 }
1199
1200 __isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
1201         enum isl_dim_type type, unsigned first, unsigned n)
1202 {
1203         isl_ctx *ctx;
1204
1205         if (!aff)
1206                 return NULL;
1207         if (type == isl_dim_out)
1208                 isl_die(aff->v->ctx, isl_error_invalid,
1209                         "cannot insert output/set dimensions",
1210                         return isl_aff_free(aff));
1211         if (type == isl_dim_in)
1212                 type = isl_dim_set;
1213         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1214                 return aff;
1215
1216         ctx = isl_aff_get_ctx(aff);
1217         if (first > isl_local_space_dim(aff->ls, type))
1218                 isl_die(ctx, isl_error_invalid, "position out of bounds",
1219                         return isl_aff_free(aff));
1220
1221         aff = isl_aff_cow(aff);
1222         if (!aff)
1223                 return NULL;
1224
1225         aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
1226         if (!aff->ls)
1227                 return isl_aff_free(aff);
1228
1229         first += 1 + isl_local_space_offset(aff->ls, type);
1230         aff->v = isl_vec_insert_zero_els(aff->v, first, n);
1231         if (!aff->v)
1232                 return isl_aff_free(aff);
1233
1234         return aff;
1235 }
1236
1237 __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
1238         enum isl_dim_type type, unsigned n)
1239 {
1240         unsigned pos;
1241
1242         pos = isl_aff_dim(aff, type);
1243
1244         return isl_aff_insert_dims(aff, type, pos, n);
1245 }
1246
1247 __isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff,
1248         enum isl_dim_type type, unsigned n)
1249 {
1250         unsigned pos;
1251
1252         pos = isl_pw_aff_dim(pwaff, type);
1253
1254         return isl_pw_aff_insert_dims(pwaff, type, pos, n);
1255 }
1256
1257 __isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff)
1258 {
1259         isl_set *dom = isl_set_universe(isl_aff_get_domain_space(aff));
1260         return isl_pw_aff_alloc(dom, aff);
1261 }
1262
1263 #undef PW
1264 #define PW isl_pw_aff
1265 #undef EL
1266 #define EL isl_aff
1267 #undef EL_IS_ZERO
1268 #define EL_IS_ZERO is_empty
1269 #undef ZERO
1270 #define ZERO empty
1271 #undef IS_ZERO
1272 #define IS_ZERO is_empty
1273 #undef FIELD
1274 #define FIELD aff
1275 #undef DEFAULT_IS_ZERO
1276 #define DEFAULT_IS_ZERO 0
1277
1278 #define NO_EVAL
1279 #define NO_OPT
1280 #define NO_MOVE_DIMS
1281 #define NO_LIFT
1282 #define NO_MORPH
1283
1284 #include <isl_pw_templ.c>
1285
1286 static __isl_give isl_set *align_params_pw_pw_set_and(
1287         __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2,
1288         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
1289                                     __isl_take isl_pw_aff *pwaff2))
1290 {
1291         if (!pwaff1 || !pwaff2)
1292                 goto error;
1293         if (isl_space_match(pwaff1->dim, isl_dim_param,
1294                           pwaff2->dim, isl_dim_param))
1295                 return fn(pwaff1, pwaff2);
1296         if (!isl_space_has_named_params(pwaff1->dim) ||
1297             !isl_space_has_named_params(pwaff2->dim))
1298                 isl_die(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid,
1299                         "unaligned unnamed parameters", goto error);
1300         pwaff1 = isl_pw_aff_align_params(pwaff1, isl_pw_aff_get_space(pwaff2));
1301         pwaff2 = isl_pw_aff_align_params(pwaff2, isl_pw_aff_get_space(pwaff1));
1302         return fn(pwaff1, pwaff2);
1303 error:
1304         isl_pw_aff_free(pwaff1);
1305         isl_pw_aff_free(pwaff2);
1306         return NULL;
1307 }
1308
1309 /* Compute a piecewise quasi-affine expression with a domain that
1310  * is the union of those of pwaff1 and pwaff2 and such that on each
1311  * cell, the quasi-affine expression is the better (according to cmp)
1312  * of those of pwaff1 and pwaff2.  If only one of pwaff1 or pwaff2
1313  * is defined on a given cell, then the associated expression
1314  * is the defined one.
1315  */
1316 static __isl_give isl_pw_aff *pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
1317         __isl_take isl_pw_aff *pwaff2,
1318         __isl_give isl_basic_set *(*cmp)(__isl_take isl_aff *aff1,
1319                                         __isl_take isl_aff *aff2))
1320 {
1321         int i, j, n;
1322         isl_pw_aff *res;
1323         isl_ctx *ctx;
1324         isl_set *set;
1325
1326         if (!pwaff1 || !pwaff2)
1327                 goto error;
1328
1329         ctx = isl_space_get_ctx(pwaff1->dim);
1330         if (!isl_space_is_equal(pwaff1->dim, pwaff2->dim))
1331                 isl_die(ctx, isl_error_invalid,
1332                         "arguments should live in same space", goto error);
1333
1334         if (isl_pw_aff_is_empty(pwaff1)) {
1335                 isl_pw_aff_free(pwaff1);
1336                 return pwaff2;
1337         }
1338
1339         if (isl_pw_aff_is_empty(pwaff2)) {
1340                 isl_pw_aff_free(pwaff2);
1341                 return pwaff1;
1342         }
1343
1344         n = 2 * (pwaff1->n + 1) * (pwaff2->n + 1);
1345         res = isl_pw_aff_alloc_size(isl_space_copy(pwaff1->dim), n);
1346
1347         for (i = 0; i < pwaff1->n; ++i) {
1348                 set = isl_set_copy(pwaff1->p[i].set);
1349                 for (j = 0; j < pwaff2->n; ++j) {
1350                         struct isl_set *common;
1351                         isl_set *better;
1352
1353                         common = isl_set_intersect(
1354                                         isl_set_copy(pwaff1->p[i].set),
1355                                         isl_set_copy(pwaff2->p[j].set));
1356                         better = isl_set_from_basic_set(cmp(
1357                                         isl_aff_copy(pwaff2->p[j].aff),
1358                                         isl_aff_copy(pwaff1->p[i].aff)));
1359                         better = isl_set_intersect(common, better);
1360                         if (isl_set_plain_is_empty(better)) {
1361                                 isl_set_free(better);
1362                                 continue;
1363                         }
1364                         set = isl_set_subtract(set, isl_set_copy(better));
1365
1366                         res = isl_pw_aff_add_piece(res, better,
1367                                                 isl_aff_copy(pwaff2->p[j].aff));
1368                 }
1369                 res = isl_pw_aff_add_piece(res, set,
1370                                                 isl_aff_copy(pwaff1->p[i].aff));
1371         }
1372
1373         for (j = 0; j < pwaff2->n; ++j) {
1374                 set = isl_set_copy(pwaff2->p[j].set);
1375                 for (i = 0; i < pwaff1->n; ++i)
1376                         set = isl_set_subtract(set,
1377                                         isl_set_copy(pwaff1->p[i].set));
1378                 res = isl_pw_aff_add_piece(res, set,
1379                                                 isl_aff_copy(pwaff2->p[j].aff));
1380         }
1381
1382         isl_pw_aff_free(pwaff1);
1383         isl_pw_aff_free(pwaff2);
1384
1385         return res;
1386 error:
1387         isl_pw_aff_free(pwaff1);
1388         isl_pw_aff_free(pwaff2);
1389         return NULL;
1390 }
1391
1392 /* Compute a piecewise quasi-affine expression with a domain that
1393  * is the union of those of pwaff1 and pwaff2 and such that on each
1394  * cell, the quasi-affine expression is the maximum of those of pwaff1
1395  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
1396  * cell, then the associated expression is the defined one.
1397  */
1398 static __isl_give isl_pw_aff *pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
1399         __isl_take isl_pw_aff *pwaff2)
1400 {
1401         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_ge_basic_set);
1402 }
1403
1404 __isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
1405         __isl_take isl_pw_aff *pwaff2)
1406 {
1407         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
1408                                                         &pw_aff_union_max);
1409 }
1410
1411 /* Compute a piecewise quasi-affine expression with a domain that
1412  * is the union of those of pwaff1 and pwaff2 and such that on each
1413  * cell, the quasi-affine expression is the minimum of those of pwaff1
1414  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
1415  * cell, then the associated expression is the defined one.
1416  */
1417 static __isl_give isl_pw_aff *pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
1418         __isl_take isl_pw_aff *pwaff2)
1419 {
1420         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_le_basic_set);
1421 }
1422
1423 __isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
1424         __isl_take isl_pw_aff *pwaff2)
1425 {
1426         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
1427                                                         &pw_aff_union_min);
1428 }
1429
1430 __isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
1431         __isl_take isl_pw_aff *pwaff2, int max)
1432 {
1433         if (max)
1434                 return isl_pw_aff_union_max(pwaff1, pwaff2);
1435         else
1436                 return isl_pw_aff_union_min(pwaff1, pwaff2);
1437 }
1438
1439 /* Construct a map with as domain the domain of pwaff and
1440  * one-dimensional range corresponding to the affine expressions.
1441  */
1442 static __isl_give isl_map *map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1443 {
1444         int i;
1445         isl_space *dim;
1446         isl_map *map;
1447
1448         if (!pwaff)
1449                 return NULL;
1450
1451         dim = isl_pw_aff_get_space(pwaff);
1452         map = isl_map_empty(dim);
1453
1454         for (i = 0; i < pwaff->n; ++i) {
1455                 isl_basic_map *bmap;
1456                 isl_map *map_i;
1457
1458                 bmap = isl_basic_map_from_aff(isl_aff_copy(pwaff->p[i].aff));
1459                 map_i = isl_map_from_basic_map(bmap);
1460                 map_i = isl_map_intersect_domain(map_i,
1461                                                 isl_set_copy(pwaff->p[i].set));
1462                 map = isl_map_union_disjoint(map, map_i);
1463         }
1464
1465         isl_pw_aff_free(pwaff);
1466
1467         return map;
1468 }
1469
1470 /* Construct a map with as domain the domain of pwaff and
1471  * one-dimensional range corresponding to the affine expressions.
1472  */
1473 __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1474 {
1475         if (!pwaff)
1476                 return NULL;
1477         if (isl_space_is_set(pwaff->dim))
1478                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1479                         "space of input is not a map",
1480                         return isl_pw_aff_free(pwaff));
1481         return map_from_pw_aff(pwaff);
1482 }
1483
1484 /* Construct a one-dimensional set with as parameter domain
1485  * the domain of pwaff and the single set dimension
1486  * corresponding to the affine expressions.
1487  */
1488 __isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1489 {
1490         if (!pwaff)
1491                 return NULL;
1492         if (!isl_space_is_set(pwaff->dim))
1493                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1494                         "space of input is not a set",
1495                         return isl_pw_aff_free(pwaff));
1496         return map_from_pw_aff(pwaff);
1497 }
1498
1499 /* Return a set containing those elements in the domain
1500  * of pwaff where it is non-negative.
1501  */
1502 __isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
1503 {
1504         int i;
1505         isl_set *set;
1506
1507         if (!pwaff)
1508                 return NULL;
1509
1510         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
1511
1512         for (i = 0; i < pwaff->n; ++i) {
1513                 isl_basic_set *bset;
1514                 isl_set *set_i;
1515
1516                 bset = isl_aff_nonneg_basic_set(isl_aff_copy(pwaff->p[i].aff));
1517                 set_i = isl_set_from_basic_set(bset);
1518                 set_i = isl_set_intersect(set_i, isl_set_copy(pwaff->p[i].set));
1519                 set = isl_set_union_disjoint(set, set_i);
1520         }
1521
1522         isl_pw_aff_free(pwaff);
1523
1524         return set;
1525 }
1526
1527 /* Return a set containing those elements in the domain
1528  * of pwaff where it is zero.
1529  */
1530 __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
1531 {
1532         int i;
1533         isl_set *set;
1534
1535         if (!pwaff)
1536                 return NULL;
1537
1538         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
1539
1540         for (i = 0; i < pwaff->n; ++i) {
1541                 isl_basic_set *bset;
1542                 isl_set *set_i;
1543
1544                 bset = isl_aff_zero_basic_set(isl_aff_copy(pwaff->p[i].aff));
1545                 set_i = isl_set_from_basic_set(bset);
1546                 set_i = isl_set_intersect(set_i, isl_set_copy(pwaff->p[i].set));
1547                 set = isl_set_union_disjoint(set, set_i);
1548         }
1549
1550         isl_pw_aff_free(pwaff);
1551
1552         return set;
1553 }
1554
1555 /* Return a set containing those elements in the domain
1556  * of pwaff where it is not zero.
1557  */
1558 __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
1559 {
1560         return isl_set_complement(isl_pw_aff_zero_set(pwaff));
1561 }
1562
1563 /* Return a set containing those elements in the shared domain
1564  * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
1565  *
1566  * We compute the difference on the shared domain and then construct
1567  * the set of values where this difference is non-negative.
1568  * If strict is set, we first subtract 1 from the difference.
1569  * If equal is set, we only return the elements where pwaff1 and pwaff2
1570  * are equal.
1571  */
1572 static __isl_give isl_set *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
1573         __isl_take isl_pw_aff *pwaff2, int strict, int equal)
1574 {
1575         isl_set *set1, *set2;
1576
1577         set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
1578         set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
1579         set1 = isl_set_intersect(set1, set2);
1580         pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
1581         pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
1582         pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
1583
1584         if (strict) {
1585                 isl_space *dim = isl_set_get_space(set1);
1586                 isl_aff *aff;
1587                 aff = isl_aff_zero_on_domain(isl_local_space_from_space(dim));
1588                 aff = isl_aff_add_constant_si(aff, -1);
1589                 pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
1590         } else
1591                 isl_set_free(set1);
1592
1593         if (equal)
1594                 return isl_pw_aff_zero_set(pwaff1);
1595         return isl_pw_aff_nonneg_set(pwaff1);
1596 }
1597
1598 /* Return a set containing those elements in the shared domain
1599  * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
1600  */
1601 static __isl_give isl_set *pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
1602         __isl_take isl_pw_aff *pwaff2)
1603 {
1604         return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
1605 }
1606
1607 __isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
1608         __isl_take isl_pw_aff *pwaff2)
1609 {
1610         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_eq_set);
1611 }
1612
1613 /* Return a set containing those elements in the shared domain
1614  * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
1615  */
1616 static __isl_give isl_set *pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
1617         __isl_take isl_pw_aff *pwaff2)
1618 {
1619         return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
1620 }
1621
1622 __isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
1623         __isl_take isl_pw_aff *pwaff2)
1624 {
1625         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ge_set);
1626 }
1627
1628 /* Return a set containing those elements in the shared domain
1629  * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
1630  */
1631 static __isl_give isl_set *pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
1632         __isl_take isl_pw_aff *pwaff2)
1633 {
1634         return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
1635 }
1636
1637 __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
1638         __isl_take isl_pw_aff *pwaff2)
1639 {
1640         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_gt_set);
1641 }
1642
1643 __isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
1644         __isl_take isl_pw_aff *pwaff2)
1645 {
1646         return isl_pw_aff_ge_set(pwaff2, pwaff1);
1647 }
1648
1649 __isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
1650         __isl_take isl_pw_aff *pwaff2)
1651 {
1652         return isl_pw_aff_gt_set(pwaff2, pwaff1);
1653 }
1654
1655 /* Return a set containing those elements in the shared domain
1656  * of the elements of list1 and list2 where each element in list1
1657  * has the relation specified by "fn" with each element in list2.
1658  */
1659 static __isl_give isl_set *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
1660         __isl_take isl_pw_aff_list *list2,
1661         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
1662                                     __isl_take isl_pw_aff *pwaff2))
1663 {
1664         int i, j;
1665         isl_ctx *ctx;
1666         isl_set *set;
1667
1668         if (!list1 || !list2)
1669                 goto error;
1670
1671         ctx = isl_pw_aff_list_get_ctx(list1);
1672         if (list1->n < 1 || list2->n < 1)
1673                 isl_die(ctx, isl_error_invalid,
1674                         "list should contain at least one element", goto error);
1675
1676         set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
1677         for (i = 0; i < list1->n; ++i)
1678                 for (j = 0; j < list2->n; ++j) {
1679                         isl_set *set_ij;
1680
1681                         set_ij = fn(isl_pw_aff_copy(list1->p[i]),
1682                                     isl_pw_aff_copy(list2->p[j]));
1683                         set = isl_set_intersect(set, set_ij);
1684                 }
1685
1686         isl_pw_aff_list_free(list1);
1687         isl_pw_aff_list_free(list2);
1688         return set;
1689 error:
1690         isl_pw_aff_list_free(list1);
1691         isl_pw_aff_list_free(list2);
1692         return NULL;
1693 }
1694
1695 /* Return a set containing those elements in the shared domain
1696  * of the elements of list1 and list2 where each element in list1
1697  * is equal to each element in list2.
1698  */
1699 __isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
1700         __isl_take isl_pw_aff_list *list2)
1701 {
1702         return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
1703 }
1704
1705 __isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
1706         __isl_take isl_pw_aff_list *list2)
1707 {
1708         return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
1709 }
1710
1711 /* Return a set containing those elements in the shared domain
1712  * of the elements of list1 and list2 where each element in list1
1713  * is less than or equal to each element in list2.
1714  */
1715 __isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
1716         __isl_take isl_pw_aff_list *list2)
1717 {
1718         return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
1719 }
1720
1721 __isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
1722         __isl_take isl_pw_aff_list *list2)
1723 {
1724         return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
1725 }
1726
1727 __isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
1728         __isl_take isl_pw_aff_list *list2)
1729 {
1730         return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
1731 }
1732
1733 __isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
1734         __isl_take isl_pw_aff_list *list2)
1735 {
1736         return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
1737 }
1738
1739
1740 /* Return a set containing those elements in the shared domain
1741  * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
1742  */
1743 static __isl_give isl_set *pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
1744         __isl_take isl_pw_aff *pwaff2)
1745 {
1746         isl_set *set_lt, *set_gt;
1747
1748         set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
1749                                    isl_pw_aff_copy(pwaff2));
1750         set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
1751         return isl_set_union_disjoint(set_lt, set_gt);
1752 }
1753
1754 __isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
1755         __isl_take isl_pw_aff *pwaff2)
1756 {
1757         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ne_set);
1758 }
1759
1760 __isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
1761         isl_int v)
1762 {
1763         int i;
1764
1765         if (isl_int_is_one(v))
1766                 return pwaff;
1767         if (!isl_int_is_pos(v))
1768                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1769                         "factor needs to be positive",
1770                         return isl_pw_aff_free(pwaff));
1771         pwaff = isl_pw_aff_cow(pwaff);
1772         if (!pwaff)
1773                 return NULL;
1774         if (pwaff->n == 0)
1775                 return pwaff;
1776
1777         for (i = 0; i < pwaff->n; ++i) {
1778                 pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v);
1779                 if (!pwaff->p[i].aff)
1780                         return isl_pw_aff_free(pwaff);
1781         }
1782
1783         return pwaff;
1784 }
1785
1786 __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
1787 {
1788         int i;
1789
1790         pwaff = isl_pw_aff_cow(pwaff);
1791         if (!pwaff)
1792                 return NULL;
1793         if (pwaff->n == 0)
1794                 return pwaff;
1795
1796         for (i = 0; i < pwaff->n; ++i) {
1797                 pwaff->p[i].aff = isl_aff_floor(pwaff->p[i].aff);
1798                 if (!pwaff->p[i].aff)
1799                         return isl_pw_aff_free(pwaff);
1800         }
1801
1802         return pwaff;
1803 }
1804
1805 __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
1806 {
1807         int i;
1808
1809         pwaff = isl_pw_aff_cow(pwaff);
1810         if (!pwaff)
1811                 return NULL;
1812         if (pwaff->n == 0)
1813                 return pwaff;
1814
1815         for (i = 0; i < pwaff->n; ++i) {
1816                 pwaff->p[i].aff = isl_aff_ceil(pwaff->p[i].aff);
1817                 if (!pwaff->p[i].aff)
1818                         return isl_pw_aff_free(pwaff);
1819         }
1820
1821         return pwaff;
1822 }
1823
1824 /* Return an affine expression that is equal to pwaff_true for elements
1825  * in "cond" and to pwaff_false for elements not in "cond".
1826  * That is, return cond ? pwaff_true : pwaff_false;
1827  */
1828 __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_set *cond,
1829         __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
1830 {
1831         isl_set *comp;
1832
1833         comp = isl_set_complement(isl_set_copy(cond));
1834         pwaff_true = isl_pw_aff_intersect_domain(pwaff_true, cond);
1835         pwaff_false = isl_pw_aff_intersect_domain(pwaff_false, comp);
1836
1837         return isl_pw_aff_add_disjoint(pwaff_true, pwaff_false);
1838 }
1839
1840 int isl_aff_is_cst(__isl_keep isl_aff *aff)
1841 {
1842         if (!aff)
1843                 return -1;
1844
1845         return isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2) == -1;
1846 }
1847
1848 /* Check whether pwaff is a piecewise constant.
1849  */
1850 int isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
1851 {
1852         int i;
1853
1854         if (!pwaff)
1855                 return -1;
1856
1857         for (i = 0; i < pwaff->n; ++i) {
1858                 int is_cst = isl_aff_is_cst(pwaff->p[i].aff);
1859                 if (is_cst < 0 || !is_cst)
1860                         return is_cst;
1861         }
1862
1863         return 1;
1864 }
1865
1866 __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
1867         __isl_take isl_aff *aff2)
1868 {
1869         if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
1870                 return isl_aff_mul(aff2, aff1);
1871
1872         if (!isl_aff_is_cst(aff2))
1873                 isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,
1874                         "at least one affine expression should be constant",
1875                         goto error);
1876
1877         aff1 = isl_aff_cow(aff1);
1878         if (!aff1 || !aff2)
1879                 goto error;
1880
1881         aff1 = isl_aff_scale(aff1, aff2->v->el[1]);
1882         aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]);
1883
1884         isl_aff_free(aff2);
1885         return aff1;
1886 error:
1887         isl_aff_free(aff1);
1888         isl_aff_free(aff2);
1889         return NULL;
1890 }
1891
1892 static __isl_give isl_pw_aff *pw_aff_add(__isl_take isl_pw_aff *pwaff1,
1893         __isl_take isl_pw_aff *pwaff2)
1894 {
1895         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
1896 }
1897
1898 __isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
1899         __isl_take isl_pw_aff *pwaff2)
1900 {
1901         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_add);
1902 }
1903
1904 __isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1,
1905         __isl_take isl_pw_aff *pwaff2)
1906 {
1907         return isl_pw_aff_union_add_(pwaff1, pwaff2);
1908 }
1909
1910 static __isl_give isl_pw_aff *pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
1911         __isl_take isl_pw_aff *pwaff2)
1912 {
1913         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
1914 }
1915
1916 __isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
1917         __isl_take isl_pw_aff *pwaff2)
1918 {
1919         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_mul);
1920 }
1921
1922 static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
1923         __isl_take isl_pw_aff *pwaff2)
1924 {
1925         isl_set *le;
1926
1927         le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
1928                                 isl_pw_aff_copy(pwaff2));
1929         return isl_pw_aff_cond(le, pwaff1, pwaff2);
1930 }
1931
1932 __isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
1933         __isl_take isl_pw_aff *pwaff2)
1934 {
1935         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_min);
1936 }
1937
1938 static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
1939         __isl_take isl_pw_aff *pwaff2)
1940 {
1941         isl_set *le;
1942
1943         le = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
1944                                 isl_pw_aff_copy(pwaff2));
1945         return isl_pw_aff_cond(le, pwaff1, pwaff2);
1946 }
1947
1948 __isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
1949         __isl_take isl_pw_aff *pwaff2)
1950 {
1951         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_max);
1952 }
1953
1954 static __isl_give isl_pw_aff *pw_aff_list_reduce(
1955         __isl_take isl_pw_aff_list *list,
1956         __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pwaff1,
1957                                         __isl_take isl_pw_aff *pwaff2))
1958 {
1959         int i;
1960         isl_ctx *ctx;
1961         isl_pw_aff *res;
1962
1963         if (!list)
1964                 return NULL;
1965
1966         ctx = isl_pw_aff_list_get_ctx(list);
1967         if (list->n < 1)
1968                 isl_die(ctx, isl_error_invalid,
1969                         "list should contain at least one element",
1970                         return isl_pw_aff_list_free(list));
1971
1972         res = isl_pw_aff_copy(list->p[0]);
1973         for (i = 1; i < list->n; ++i)
1974                 res = fn(res, isl_pw_aff_copy(list->p[i]));
1975
1976         isl_pw_aff_list_free(list);
1977         return res;
1978 }
1979
1980 /* Return an isl_pw_aff that maps each element in the intersection of the
1981  * domains of the elements of list to the minimal corresponding affine
1982  * expression.
1983  */
1984 __isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
1985 {
1986         return pw_aff_list_reduce(list, &isl_pw_aff_min);
1987 }
1988
1989 /* Return an isl_pw_aff that maps each element in the intersection of the
1990  * domains of the elements of list to the maximal corresponding affine
1991  * expression.
1992  */
1993 __isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
1994 {
1995         return pw_aff_list_reduce(list, &isl_pw_aff_max);
1996 }
1997
1998 #undef BASE
1999 #define BASE aff
2000
2001 #include <isl_multi_templ.c>
2002
2003 __isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *maff1,
2004         __isl_take isl_multi_aff *maff2)
2005 {
2006         int i;
2007         isl_ctx *ctx;
2008
2009         maff1 = isl_multi_aff_cow(maff1);
2010         if (!maff1 || !maff2)
2011                 goto error;
2012
2013         ctx = isl_multi_aff_get_ctx(maff1);
2014         if (!isl_space_is_equal(maff1->space, maff2->space))
2015                 isl_die(ctx, isl_error_invalid,
2016                         "spaces don't match", goto error);
2017
2018         for (i = 0; i < maff1->n; ++i) {
2019                 maff1->p[i] = isl_aff_add(maff1->p[i],
2020                                             isl_aff_copy(maff2->p[i]));
2021                 if (!maff1->p[i])
2022                         goto error;
2023         }
2024
2025         isl_multi_aff_free(maff2);
2026         return maff1;
2027 error:
2028         isl_multi_aff_free(maff1);
2029         isl_multi_aff_free(maff2);
2030         return NULL;
2031 }
2032
2033 /* Exploit the equalities in "eq" to simplify the affine expressions.
2034  */
2035 static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
2036         __isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq)
2037 {
2038         int i;
2039
2040         maff = isl_multi_aff_cow(maff);
2041         if (!maff || !eq)
2042                 goto error;
2043
2044         for (i = 0; i < maff->n; ++i) {
2045                 maff->p[i] = isl_aff_substitute_equalities(maff->p[i],
2046                                                     isl_basic_set_copy(eq));
2047                 if (!maff->p[i])
2048                         goto error;
2049         }
2050
2051         isl_basic_set_free(eq);
2052         return maff;
2053 error:
2054         isl_basic_set_free(eq);
2055         isl_multi_aff_free(maff);
2056         return NULL;
2057 }
2058
2059 __isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
2060         isl_int f)
2061 {
2062         int i;
2063
2064         maff = isl_multi_aff_cow(maff);
2065         if (!maff)
2066                 return NULL;
2067
2068         for (i = 0; i < maff->n; ++i) {
2069                 maff->p[i] = isl_aff_scale(maff->p[i], f);
2070                 if (!maff->p[i])
2071                         return isl_multi_aff_free(maff);
2072         }
2073
2074         return maff;
2075 }
2076
2077 __isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_set *dom,
2078         __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
2079 {
2080         maff1 = isl_multi_aff_add(maff1, maff2);
2081         maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
2082         return maff1;
2083 }
2084
2085 int isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
2086 {
2087         if (!maff)
2088                 return -1;
2089
2090         return 0;
2091 }
2092
2093 int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1,
2094         __isl_keep isl_multi_aff *maff2)
2095 {
2096         int i;
2097         int equal;
2098
2099         if (!maff1 || !maff2)
2100                 return -1;
2101         if (maff1->n != maff2->n)
2102                 return 0;
2103         equal = isl_space_is_equal(maff1->space, maff2->space);
2104         if (equal < 0 || !equal)
2105                 return equal;
2106
2107         for (i = 0; i < maff1->n; ++i) {
2108                 equal = isl_aff_plain_is_equal(maff1->p[i], maff2->p[i]);
2109                 if (equal < 0 || !equal)
2110                         return equal;
2111         }
2112
2113         return 1;
2114 }
2115
2116 __isl_give isl_multi_aff *isl_multi_aff_set_dim_name(
2117         __isl_take isl_multi_aff *maff,
2118         enum isl_dim_type type, unsigned pos, const char *s)
2119 {
2120         int i;
2121
2122         maff = isl_multi_aff_cow(maff);
2123         if (!maff)
2124                 return NULL;
2125
2126         maff->space = isl_space_set_dim_name(maff->space, type, pos, s);
2127         if (!maff->space)
2128                 return isl_multi_aff_free(maff);
2129         for (i = 0; i < maff->n; ++i) {
2130                 maff->p[i] = isl_aff_set_dim_name(maff->p[i], type, pos, s);
2131                 if (!maff->p[i])
2132                         return isl_multi_aff_free(maff);
2133         }
2134
2135         return maff;
2136 }
2137
2138 __isl_give isl_multi_aff *isl_multi_aff_drop_dims(__isl_take isl_multi_aff *maff,
2139         enum isl_dim_type type, unsigned first, unsigned n)
2140 {
2141         int i;
2142
2143         maff = isl_multi_aff_cow(maff);
2144         if (!maff)
2145                 return NULL;
2146
2147         maff->space = isl_space_drop_dims(maff->space, type, first, n);
2148         if (!maff->space)
2149                 return isl_multi_aff_free(maff);
2150
2151         if (type == isl_dim_out) {
2152                 for (i = 0; i < n; ++i)
2153                         isl_aff_free(maff->p[first + i]);
2154                 for (i = first; i + n < maff->n; ++i)
2155                         maff->p[i] = maff->p[i + n];
2156                 maff->n -= n;
2157                 return maff;
2158         }
2159
2160         for (i = 0; i < maff->n; ++i) {
2161                 maff->p[i] = isl_aff_drop_dims(maff->p[i], type, first, n);
2162                 if (!maff->p[i])
2163                         return isl_multi_aff_free(maff);
2164         }
2165
2166         return maff;
2167 }
2168
2169 #undef PW
2170 #define PW isl_pw_multi_aff
2171 #undef EL
2172 #define EL isl_multi_aff
2173 #undef EL_IS_ZERO
2174 #define EL_IS_ZERO is_empty
2175 #undef ZERO
2176 #define ZERO empty
2177 #undef IS_ZERO
2178 #define IS_ZERO is_empty
2179 #undef FIELD
2180 #define FIELD maff
2181 #undef DEFAULT_IS_ZERO
2182 #define DEFAULT_IS_ZERO 0
2183
2184 #define NO_NEG
2185 #define NO_EVAL
2186 #define NO_OPT
2187 #define NO_INVOLVES_DIMS
2188 #define NO_MOVE_DIMS
2189 #define NO_INSERT_DIMS
2190 #define NO_LIFT
2191 #define NO_MORPH
2192
2193 #include <isl_pw_templ.c>
2194
2195 static __isl_give isl_pw_multi_aff *pw_multi_aff_add(
2196         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
2197 {
2198         return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
2199                                                 &isl_multi_aff_add);
2200 }
2201
2202 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
2203         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
2204 {
2205         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
2206                                                 &pw_multi_aff_add);
2207 }
2208
2209 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add(
2210         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
2211 {
2212         return isl_pw_multi_aff_union_add_(pma1, pma2);
2213 }
2214
2215 /* Construct a map mapping the domain the piecewise multi-affine expression
2216  * to its range, with each dimension in the range equated to the
2217  * corresponding affine expression on its cell.
2218  */
2219 __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
2220 {
2221         int i;
2222         isl_map *map;
2223
2224         if (!pma)
2225                 return NULL;
2226
2227         map = isl_map_empty(isl_pw_multi_aff_get_space(pma));
2228
2229         for (i = 0; i < pma->n; ++i) {
2230                 isl_multi_aff *maff;
2231                 isl_basic_map *bmap;
2232                 isl_map *map_i;
2233
2234                 maff = isl_multi_aff_copy(pma->p[i].maff);
2235                 bmap = isl_basic_map_from_multi_aff(maff);
2236                 map_i = isl_map_from_basic_map(bmap);
2237                 map_i = isl_map_intersect_domain(map_i,
2238                                                 isl_set_copy(pma->p[i].set));
2239                 map = isl_map_union_disjoint(map, map_i);
2240         }
2241
2242         isl_pw_multi_aff_free(pma);
2243         return map;
2244 }
2245
2246 __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
2247 {
2248         if (!isl_space_is_set(pma->dim))
2249                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
2250                         "isl_pw_multi_aff cannot be converted into an isl_set",
2251                         return isl_pw_multi_aff_free(pma));
2252
2253         return isl_map_from_pw_multi_aff(pma);
2254 }
2255
2256 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
2257  * This obivously only works if the input "map" is single-valued.
2258  * If so, we compute the lexicographic minimum of the image in the form
2259  * of an isl_pw_multi_aff.  Since the image is unique, it is equal
2260  * to its lexicographic minimum.
2261  * If the input is not single-valued, we produce an error.
2262  */
2263 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
2264 {
2265         int i;
2266         int sv;
2267         isl_pw_multi_aff *pma;
2268
2269         if (!map)
2270                 return NULL;
2271
2272         sv = isl_map_is_single_valued(map);
2273         if (sv < 0)
2274                 goto error;
2275         if (!sv)
2276                 isl_die(isl_map_get_ctx(map), isl_error_invalid,
2277                         "map is not single-valued", goto error);
2278         map = isl_map_make_disjoint(map);
2279         if (!map)
2280                 return NULL;
2281
2282         pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
2283
2284         for (i = 0; i < map->n; ++i) {
2285                 isl_pw_multi_aff *pma_i;
2286                 isl_basic_map *bmap;
2287                 bmap = isl_basic_map_copy(map->p[i]);
2288                 pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
2289                 pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
2290         }
2291
2292         isl_map_free(map);
2293         return pma;
2294 error:
2295         isl_map_free(map);
2296         return NULL;
2297 }
2298
2299 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
2300 {
2301         return isl_pw_multi_aff_from_map(set);
2302 }
2303
2304 /* Plug in "subs" for dimension "type", "pos" of "aff".
2305  *
2306  * Let i be the dimension to replace and let "subs" be of the form
2307  *
2308  *      f/d
2309  *
2310  * and "aff" of the form
2311  *
2312  *      (a i + g)/m
2313  *
2314  * The result is
2315  *
2316  *      floor((a f + d g')/(m d))
2317  *
2318  * where g' is the result of plugging in "subs" in each of the integer
2319  * divisions in g.
2320  */
2321 __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
2322         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
2323 {
2324         isl_ctx *ctx;
2325         isl_int v;
2326
2327         aff = isl_aff_cow(aff);
2328         if (!aff || !subs)
2329                 return isl_aff_free(aff);
2330
2331         ctx = isl_aff_get_ctx(aff);
2332         if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
2333                 isl_die(ctx, isl_error_invalid,
2334                         "spaces don't match", return isl_aff_free(aff));
2335         if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
2336                 isl_die(ctx, isl_error_unsupported,
2337                         "cannot handle divs yet", return isl_aff_free(aff));
2338
2339         aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
2340         if (!aff->ls)
2341                 return isl_aff_free(aff);
2342
2343         aff->v = isl_vec_cow(aff->v);
2344         if (!aff->v)
2345                 return isl_aff_free(aff);
2346
2347         pos += isl_local_space_offset(aff->ls, type);
2348
2349         isl_int_init(v);
2350         isl_int_set(v, aff->v->el[1 + pos]);
2351         isl_int_set_si(aff->v->el[1 + pos], 0);
2352         isl_seq_combine(aff->v->el + 1, subs->v->el[0], aff->v->el + 1,
2353                         v, subs->v->el + 1, subs->v->size - 1);
2354         isl_int_mul(aff->v->el[0], aff->v->el[0], subs->v->el[0]);
2355         isl_int_clear(v);
2356
2357         return aff;
2358 }
2359
2360 /* Plug in "subs" for dimension "type", "pos" in each of the affine
2361  * expressions in "maff".
2362  */
2363 __isl_give isl_multi_aff *isl_multi_aff_substitute(
2364         __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
2365         __isl_keep isl_aff *subs)
2366 {
2367         int i;
2368
2369         maff = isl_multi_aff_cow(maff);
2370         if (!maff || !subs)
2371                 return isl_multi_aff_free(maff);
2372
2373         if (type == isl_dim_in)
2374                 type = isl_dim_set;
2375
2376         for (i = 0; i < maff->n; ++i) {
2377                 maff->p[i] = isl_aff_substitute(maff->p[i], type, pos, subs);
2378                 if (!maff->p[i])
2379                         return isl_multi_aff_free(maff);
2380         }
2381
2382         return maff;
2383 }
2384
2385 /* Plug in "subs" for dimension "type", "pos" of "pma".
2386  *
2387  * pma is of the form
2388  *
2389  *      A_i(v) -> M_i(v)
2390  *
2391  * while subs is of the form
2392  *
2393  *      v' = B_j(v) -> S_j
2394  *
2395  * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
2396  * has a contribution in the result, in particular
2397  *
2398  *      C_ij(S_j) -> M_i(S_j)
2399  *
2400  * Note that plugging in S_j in C_ij may also result in an empty set
2401  * and this contribution should simply be discarded.
2402  */
2403 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
2404         __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
2405         __isl_keep isl_pw_aff *subs)
2406 {
2407         int i, j, n;
2408         isl_pw_multi_aff *res;
2409
2410         if (!pma || !subs)
2411                 return isl_pw_multi_aff_free(pma);
2412
2413         n = pma->n * subs->n;
2414         res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
2415
2416         for (i = 0; i < pma->n; ++i) {
2417                 for (j = 0; j < subs->n; ++j) {
2418                         isl_set *common;
2419                         isl_multi_aff *res_ij;
2420                         common = isl_set_intersect(
2421                                         isl_set_copy(pma->p[i].set),
2422                                         isl_set_copy(subs->p[j].set));
2423                         common = isl_set_substitute(common,
2424                                         type, pos, subs->p[j].aff);
2425                         if (isl_set_plain_is_empty(common)) {
2426                                 isl_set_free(common);
2427                                 continue;
2428                         }
2429
2430                         res_ij = isl_multi_aff_substitute(
2431                                         isl_multi_aff_copy(pma->p[i].maff),
2432                                         type, pos, subs->p[j].aff);
2433
2434                         res = isl_pw_multi_aff_add_piece(res, common, res_ij);
2435                 }
2436         }
2437
2438         isl_pw_multi_aff_free(pma);
2439         return res;
2440 }
2441
2442 /* Extend the local space of "dst" to include the divs
2443  * in the local space of "src".
2444  */
2445 __isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
2446         __isl_keep isl_aff *src)
2447 {
2448         isl_ctx *ctx;
2449         int *exp1 = NULL;
2450         int *exp2 = NULL;
2451         isl_mat *div;
2452
2453         if (!src || !dst)
2454                 return isl_aff_free(dst);
2455
2456         ctx = isl_aff_get_ctx(src);
2457         if (!isl_space_is_equal(src->ls->dim, dst->ls->dim))
2458                 isl_die(ctx, isl_error_invalid,
2459                         "spaces don't match", goto error);
2460
2461         if (src->ls->div->n_row == 0)
2462                 return dst;
2463
2464         exp1 = isl_alloc_array(ctx, int, src->ls->div->n_row);
2465         exp2 = isl_alloc_array(ctx, int, dst->ls->div->n_row);
2466         if (!exp1 || !exp2)
2467                 goto error;
2468
2469         div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
2470         dst = isl_aff_expand_divs(dst, div, exp2);
2471         free(exp1);
2472         free(exp2);
2473
2474         return dst;
2475 error:
2476         free(exp1);
2477         free(exp2);
2478         return isl_aff_free(dst);
2479 }
2480
2481 /* Adjust the local spaces of the affine expressions in "maff"
2482  * such that they all have the save divs.
2483  */
2484 __isl_give isl_multi_aff *isl_multi_aff_align_divs(
2485         __isl_take isl_multi_aff *maff)
2486 {
2487         int i;
2488
2489         if (!maff)
2490                 return NULL;
2491         if (maff->n == 0)
2492                 return maff;
2493         maff = isl_multi_aff_cow(maff);
2494         if (!maff)
2495                 return NULL;
2496
2497         for (i = 1; i < maff->n; ++i)
2498                 maff->p[0] = isl_aff_align_divs(maff->p[0], maff->p[i]);
2499         for (i = 1; i < maff->n; ++i) {
2500                 maff->p[i] = isl_aff_align_divs(maff->p[i], maff->p[0]);
2501                 if (!maff->p[i])
2502                         return isl_multi_aff_free(maff);
2503         }
2504
2505         return maff;
2506 }
2507
2508 __isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
2509 {
2510         aff = isl_aff_cow(aff);
2511         if (!aff)
2512                 return NULL;
2513
2514         aff->ls = isl_local_space_lift(aff->ls);
2515         if (!aff->ls)
2516                 return isl_aff_free(aff);
2517
2518         return aff;
2519 }
2520
2521 /* Lift "maff" to a space with extra dimensions such that the result
2522  * has no more existentially quantified variables.
2523  * If "ls" is not NULL, then *ls is assigned the local space that lies
2524  * at the basis of the lifting applied to "maff".
2525  */
2526 __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
2527         __isl_give isl_local_space **ls)
2528 {
2529         int i;
2530         isl_space *space;
2531         unsigned n_div;
2532
2533         if (ls)
2534                 *ls = NULL;
2535
2536         if (!maff)
2537                 return NULL;
2538
2539         if (maff->n == 0) {
2540                 if (ls) {
2541                         isl_space *space = isl_multi_aff_get_domain_space(maff);
2542                         *ls = isl_local_space_from_space(space);
2543                         if (!*ls)
2544                                 return isl_multi_aff_free(maff);
2545                 }
2546                 return maff;
2547         }
2548
2549         maff = isl_multi_aff_cow(maff);
2550         maff = isl_multi_aff_align_divs(maff);
2551         if (!maff)
2552                 return NULL;
2553
2554         n_div = isl_aff_dim(maff->p[0], isl_dim_div);
2555         space = isl_multi_aff_get_space(maff);
2556         space = isl_space_lift(isl_space_domain(space), n_div);
2557         space = isl_space_extend_domain_with_range(space,
2558                                                 isl_multi_aff_get_space(maff));
2559         if (!space)
2560                 return isl_multi_aff_free(maff);
2561         isl_space_free(maff->space);
2562         maff->space = space;
2563
2564         if (ls) {
2565                 *ls = isl_aff_get_domain_local_space(maff->p[0]);
2566                 if (!*ls)
2567                         return isl_multi_aff_free(maff);
2568         }
2569
2570         for (i = 0; i < maff->n; ++i) {
2571                 maff->p[i] = isl_aff_lift(maff->p[i]);
2572                 if (!maff->p[i])
2573                         goto error;
2574         }
2575
2576         return maff;
2577 error:
2578         if (ls)
2579                 isl_local_space_free(*ls);
2580         return isl_multi_aff_free(maff);
2581 }
2582
2583
2584 /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
2585  */
2586 __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
2587         __isl_keep isl_pw_multi_aff *pma, int pos)
2588 {
2589         int i;
2590         int n_out;
2591         isl_space *space;
2592         isl_pw_aff *pa;
2593
2594         if (!pma)
2595                 return NULL;
2596
2597         n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
2598         if (pos < 0 || pos >= n_out)
2599                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
2600                         "index out of bounds", return NULL);
2601
2602         space = isl_pw_multi_aff_get_space(pma);
2603         space = isl_space_drop_dims(space, isl_dim_out,
2604                                     pos + 1, n_out - pos - 1);
2605         space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
2606
2607         pa = isl_pw_aff_alloc_size(space, pma->n);
2608         for (i = 0; i < pma->n; ++i) {
2609                 isl_aff *aff;
2610                 aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
2611                 pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
2612         }
2613
2614         return pa;
2615 }