add isl_qpolynomial_get_den
[platform/upstream/isl.git] / isl_polynomial.c
1 #include <isl_seq.h>
2 #include <isl_polynomial_private.h>
3 #include <isl_point_private.h>
4 #include <isl_dim_private.h>
5 #include <isl_map_private.h>
6
7 int isl_upoly_is_cst(__isl_keep struct isl_upoly *up)
8 {
9         if (!up)
10                 return -1;
11
12         return up->var < 0;
13 }
14
15 __isl_keep struct isl_upoly_cst *isl_upoly_as_cst(__isl_keep struct isl_upoly *up)
16 {
17         if (!up)
18                 return NULL;
19
20         isl_assert(up->ctx, up->var < 0, return NULL);
21
22         return (struct isl_upoly_cst *)up;
23 }
24
25 __isl_keep struct isl_upoly_rec *isl_upoly_as_rec(__isl_keep struct isl_upoly *up)
26 {
27         if (!up)
28                 return NULL;
29
30         isl_assert(up->ctx, up->var >= 0, return NULL);
31
32         return (struct isl_upoly_rec *)up;
33 }
34
35 int isl_upoly_is_zero(__isl_keep struct isl_upoly *up)
36 {
37         struct isl_upoly_cst *cst;
38
39         if (!up)
40                 return -1;
41         if (!isl_upoly_is_cst(up))
42                 return 0;
43
44         cst = isl_upoly_as_cst(up);
45         if (!cst)
46                 return -1;
47
48         return isl_int_is_zero(cst->n) && isl_int_is_pos(cst->d);
49 }
50
51 int isl_upoly_is_nan(__isl_keep struct isl_upoly *up)
52 {
53         struct isl_upoly_cst *cst;
54
55         if (!up)
56                 return -1;
57         if (!isl_upoly_is_cst(up))
58                 return 0;
59
60         cst = isl_upoly_as_cst(up);
61         if (!cst)
62                 return -1;
63
64         return isl_int_is_zero(cst->n) && isl_int_is_zero(cst->d);
65 }
66
67 int isl_upoly_is_infty(__isl_keep struct isl_upoly *up)
68 {
69         struct isl_upoly_cst *cst;
70
71         if (!up)
72                 return -1;
73         if (!isl_upoly_is_cst(up))
74                 return 0;
75
76         cst = isl_upoly_as_cst(up);
77         if (!cst)
78                 return -1;
79
80         return isl_int_is_pos(cst->n) && isl_int_is_zero(cst->d);
81 }
82
83 int isl_upoly_is_neginfty(__isl_keep struct isl_upoly *up)
84 {
85         struct isl_upoly_cst *cst;
86
87         if (!up)
88                 return -1;
89         if (!isl_upoly_is_cst(up))
90                 return 0;
91
92         cst = isl_upoly_as_cst(up);
93         if (!cst)
94                 return -1;
95
96         return isl_int_is_neg(cst->n) && isl_int_is_zero(cst->d);
97 }
98
99 int isl_upoly_is_one(__isl_keep struct isl_upoly *up)
100 {
101         struct isl_upoly_cst *cst;
102
103         if (!up)
104                 return -1;
105         if (!isl_upoly_is_cst(up))
106                 return 0;
107
108         cst = isl_upoly_as_cst(up);
109         if (!cst)
110                 return -1;
111
112         return isl_int_eq(cst->n, cst->d) && isl_int_is_pos(cst->d);
113 }
114
115 int isl_upoly_is_negone(__isl_keep struct isl_upoly *up)
116 {
117         struct isl_upoly_cst *cst;
118
119         if (!up)
120                 return -1;
121         if (!isl_upoly_is_cst(up))
122                 return 0;
123
124         cst = isl_upoly_as_cst(up);
125         if (!cst)
126                 return -1;
127
128         return isl_int_is_negone(cst->n) && isl_int_is_one(cst->d);
129 }
130
131 __isl_give struct isl_upoly_cst *isl_upoly_cst_alloc(struct isl_ctx *ctx)
132 {
133         struct isl_upoly_cst *cst;
134
135         cst = isl_alloc_type(ctx, struct isl_upoly_cst);
136         if (!cst)
137                 return NULL;
138
139         cst->up.ref = 1;
140         cst->up.ctx = ctx;
141         isl_ctx_ref(ctx);
142         cst->up.var = -1;
143
144         isl_int_init(cst->n);
145         isl_int_init(cst->d);
146
147         return cst;
148 }
149
150 __isl_give struct isl_upoly *isl_upoly_zero(struct isl_ctx *ctx)
151 {
152         struct isl_upoly_cst *cst;
153
154         cst = isl_upoly_cst_alloc(ctx);
155         if (!cst)
156                 return NULL;
157
158         isl_int_set_si(cst->n, 0);
159         isl_int_set_si(cst->d, 1);
160
161         return &cst->up;
162 }
163
164 __isl_give struct isl_upoly *isl_upoly_infty(struct isl_ctx *ctx)
165 {
166         struct isl_upoly_cst *cst;
167
168         cst = isl_upoly_cst_alloc(ctx);
169         if (!cst)
170                 return NULL;
171
172         isl_int_set_si(cst->n, 1);
173         isl_int_set_si(cst->d, 0);
174
175         return &cst->up;
176 }
177
178 __isl_give struct isl_upoly *isl_upoly_nan(struct isl_ctx *ctx)
179 {
180         struct isl_upoly_cst *cst;
181
182         cst = isl_upoly_cst_alloc(ctx);
183         if (!cst)
184                 return NULL;
185
186         isl_int_set_si(cst->n, 0);
187         isl_int_set_si(cst->d, 0);
188
189         return &cst->up;
190 }
191
192 __isl_give struct isl_upoly *isl_upoly_rat_cst(struct isl_ctx *ctx,
193         isl_int n, isl_int d)
194 {
195         struct isl_upoly_cst *cst;
196
197         cst = isl_upoly_cst_alloc(ctx);
198         if (!cst)
199                 return NULL;
200
201         isl_int_set(cst->n, n);
202         isl_int_set(cst->d, d);
203
204         return &cst->up;
205 }
206
207 __isl_give struct isl_upoly_rec *isl_upoly_alloc_rec(struct isl_ctx *ctx,
208         int var, int size)
209 {
210         struct isl_upoly_rec *rec;
211
212         isl_assert(ctx, var >= 0, return NULL);
213         isl_assert(ctx, size >= 0, return NULL);
214         rec = isl_calloc(dim->ctx, struct isl_upoly_rec,
215                         sizeof(struct isl_upoly_rec) +
216                         (size - 1) * sizeof(struct isl_upoly *));
217         if (!rec)
218                 return NULL;
219
220         rec->up.ref = 1;
221         rec->up.ctx = ctx;
222         isl_ctx_ref(ctx);
223         rec->up.var = var;
224
225         rec->n = 0;
226         rec->size = size;
227
228         return rec;
229 error:
230         isl_upoly_free(&rec->up);
231         return NULL;
232 }
233
234 int isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp)
235 {
236         struct isl_upoly_cst *cst;
237
238         if (!qp)
239                 return -1;
240
241         return isl_upoly_is_zero(qp->upoly);
242 }
243
244 int isl_qpolynomial_is_one(__isl_keep isl_qpolynomial *qp)
245 {
246         struct isl_upoly_cst *cst;
247
248         if (!qp)
249                 return -1;
250
251         return isl_upoly_is_one(qp->upoly);
252 }
253
254 static void upoly_free_cst(__isl_take struct isl_upoly_cst *cst)
255 {
256         isl_int_clear(cst->n);
257         isl_int_clear(cst->d);
258 }
259
260 static void upoly_free_rec(__isl_take struct isl_upoly_rec *rec)
261 {
262         int i;
263
264         for (i = 0; i < rec->n; ++i)
265                 isl_upoly_free(rec->p[i]);
266 }
267
268 __isl_give struct isl_upoly *isl_upoly_copy(__isl_keep struct isl_upoly *up)
269 {
270         if (!up)
271                 return NULL;
272
273         up->ref++;
274         return up;
275 }
276
277 __isl_give struct isl_upoly *isl_upoly_dup_cst(__isl_keep struct isl_upoly *up)
278 {
279         struct isl_upoly_cst *cst;
280         struct isl_upoly_cst *dup;
281
282         cst = isl_upoly_as_cst(up);
283         if (!cst)
284                 return NULL;
285
286         dup = isl_upoly_as_cst(isl_upoly_zero(up->ctx));
287         if (!dup)
288                 return NULL;
289         isl_int_set(dup->n, cst->n);
290         isl_int_set(dup->d, cst->d);
291
292         return &dup->up;
293 }
294
295 __isl_give struct isl_upoly *isl_upoly_dup_rec(__isl_keep struct isl_upoly *up)
296 {
297         int i;
298         struct isl_upoly_rec *rec;
299         struct isl_upoly_rec *dup;
300
301         rec = isl_upoly_as_rec(up);
302         if (!rec)
303                 return NULL;
304
305         dup = isl_upoly_alloc_rec(up->ctx, up->var, rec->n);
306         if (!dup)
307                 return NULL;
308
309         for (i = 0; i < rec->n; ++i) {
310                 dup->p[i] = isl_upoly_copy(rec->p[i]);
311                 if (!dup->p[i])
312                         goto error;
313                 dup->n++;
314         }
315
316         return &dup->up;
317 error:
318         isl_upoly_free(&dup->up);
319         return NULL;
320 }
321
322 __isl_give struct isl_upoly *isl_upoly_dup(__isl_keep struct isl_upoly *up)
323 {
324         struct isl_upoly *dup;
325
326         if (!up)
327                 return NULL;
328
329         if (isl_upoly_is_cst(up))
330                 return isl_upoly_dup_cst(up);
331         else
332                 return isl_upoly_dup_rec(up);
333 }
334
335 __isl_give struct isl_upoly *isl_upoly_cow(__isl_take struct isl_upoly *up)
336 {
337         if (!up)
338                 return NULL;
339
340         if (up->ref == 1)
341                 return up;
342         up->ref--;
343         return isl_upoly_dup(up);
344 }
345
346 void isl_upoly_free(__isl_take struct isl_upoly *up)
347 {
348         if (!up)
349                 return;
350
351         if (--up->ref > 0)
352                 return;
353
354         if (up->var < 0)
355                 upoly_free_cst((struct isl_upoly_cst *)up);
356         else
357                 upoly_free_rec((struct isl_upoly_rec *)up);
358
359         isl_ctx_deref(up->ctx);
360         free(up);
361 }
362
363 static void isl_upoly_cst_reduce(__isl_keep struct isl_upoly_cst *cst)
364 {
365         isl_int gcd;
366
367         isl_int_init(gcd);
368         isl_int_gcd(gcd, cst->n, cst->d);
369         if (!isl_int_is_zero(gcd) && !isl_int_is_one(gcd)) {
370                 isl_int_divexact(cst->n, cst->n, gcd);
371                 isl_int_divexact(cst->d, cst->d, gcd);
372         }
373         isl_int_clear(gcd);
374 }
375
376 __isl_give struct isl_upoly *isl_upoly_sum_cst(__isl_take struct isl_upoly *up1,
377         __isl_take struct isl_upoly *up2)
378 {
379         struct isl_upoly_cst *cst1;
380         struct isl_upoly_cst *cst2;
381
382         up1 = isl_upoly_cow(up1);
383         if (!up1 || !up2)
384                 goto error;
385
386         cst1 = isl_upoly_as_cst(up1);
387         cst2 = isl_upoly_as_cst(up2);
388
389         if (isl_int_eq(cst1->d, cst2->d))
390                 isl_int_add(cst1->n, cst1->n, cst2->n);
391         else {
392                 isl_int_mul(cst1->n, cst1->n, cst2->d);
393                 isl_int_addmul(cst1->n, cst2->n, cst1->d);
394                 isl_int_mul(cst1->d, cst1->d, cst2->d);
395         }
396
397         isl_upoly_cst_reduce(cst1);
398
399         isl_upoly_free(up2);
400         return up1;
401 error:
402         isl_upoly_free(up1);
403         isl_upoly_free(up2);
404         return NULL;
405 }
406
407 static __isl_give struct isl_upoly *replace_by_zero(
408         __isl_take struct isl_upoly *up)
409 {
410         struct isl_ctx *ctx;
411
412         if (!up)
413                 return NULL;
414         ctx = up->ctx;
415         isl_upoly_free(up);
416         return isl_upoly_zero(ctx);
417 }
418
419 static __isl_give struct isl_upoly *replace_by_constant_term(
420         __isl_take struct isl_upoly *up)
421 {
422         struct isl_upoly_rec *rec;
423         struct isl_upoly *cst;
424
425         if (!up)
426                 return NULL;
427
428         rec = isl_upoly_as_rec(up);
429         if (!rec)
430                 goto error;
431         isl_assert(up->ctx, rec->n == 1, goto error);
432         cst = isl_upoly_copy(rec->p[0]);
433         isl_upoly_free(up);
434         return cst;
435 error:
436         isl_upoly_free(up);
437         return NULL;
438 }
439
440 __isl_give struct isl_upoly *isl_upoly_sum(__isl_take struct isl_upoly *up1,
441         __isl_take struct isl_upoly *up2)
442 {
443         int i;
444         struct isl_upoly_rec *rec1, *rec2;
445
446         if (!up1 || !up2)
447                 goto error;
448
449         if (isl_upoly_is_nan(up1)) {
450                 isl_upoly_free(up2);
451                 return up1;
452         }
453
454         if (isl_upoly_is_nan(up2)) {
455                 isl_upoly_free(up1);
456                 return up2;
457         }
458
459         if (isl_upoly_is_zero(up1)) {
460                 isl_upoly_free(up1);
461                 return up2;
462         }
463
464         if (isl_upoly_is_zero(up2)) {
465                 isl_upoly_free(up2);
466                 return up1;
467         }
468
469         if (up1->var < up2->var)
470                 return isl_upoly_sum(up2, up1);
471
472         if (up2->var < up1->var) {
473                 struct isl_upoly_rec *rec;
474                 if (isl_upoly_is_infty(up2) || isl_upoly_is_neginfty(up2)) {
475                         isl_upoly_free(up1);
476                         return up2;
477                 }
478                 up1 = isl_upoly_cow(up1);
479                 rec = isl_upoly_as_rec(up1);
480                 if (!rec)
481                         goto error;
482                 rec->p[0] = isl_upoly_sum(rec->p[0], up2);
483                 if (rec->n == 1)
484                         up1 = replace_by_constant_term(up1);
485                 return up1;
486         }
487
488         if (isl_upoly_is_cst(up1))
489                 return isl_upoly_sum_cst(up1, up2);
490
491         rec1 = isl_upoly_as_rec(up1);
492         rec2 = isl_upoly_as_rec(up2);
493         if (!rec1 || !rec2)
494                 goto error;
495
496         if (rec1->n < rec2->n)
497                 return isl_upoly_sum(up2, up1);
498
499         up1 = isl_upoly_cow(up1);
500         rec1 = isl_upoly_as_rec(up1);
501         if (!rec1)
502                 goto error;
503
504         for (i = rec2->n - 1; i >= 0; --i) {
505                 rec1->p[i] = isl_upoly_sum(rec1->p[i],
506                                             isl_upoly_copy(rec2->p[i]));
507                 if (!rec1->p[i])
508                         goto error;
509                 if (i == rec1->n - 1 && isl_upoly_is_zero(rec1->p[i])) {
510                         isl_upoly_free(rec1->p[i]);
511                         rec1->n--;
512                 }
513         }
514
515         if (rec1->n == 0)
516                 up1 = replace_by_zero(up1);
517         else if (rec1->n == 1)
518                 up1 = replace_by_constant_term(up1);
519
520         isl_upoly_free(up2);
521
522         return up1;
523 error:
524         isl_upoly_free(up1);
525         isl_upoly_free(up2);
526         return NULL;
527 }
528
529 __isl_give struct isl_upoly *isl_upoly_neg_cst(__isl_take struct isl_upoly *up)
530 {
531         struct isl_upoly_cst *cst;
532
533         if (isl_upoly_is_zero(up))
534                 return up;
535
536         up = isl_upoly_cow(up);
537         if (!up)
538                 return NULL;
539
540         cst = isl_upoly_as_cst(up);
541
542         isl_int_neg(cst->n, cst->n);
543
544         return up;
545 }
546
547 __isl_give struct isl_upoly *isl_upoly_neg(__isl_take struct isl_upoly *up)
548 {
549         int i;
550         struct isl_upoly_rec *rec;
551
552         if (!up)
553                 return NULL;
554
555         if (isl_upoly_is_cst(up))
556                 return isl_upoly_neg_cst(up);
557
558         up = isl_upoly_cow(up);
559         rec = isl_upoly_as_rec(up);
560         if (!rec)
561                 goto error;
562
563         for (i = 0; i < rec->n; ++i) {
564                 rec->p[i] = isl_upoly_neg(rec->p[i]);
565                 if (!rec->p[i])
566                         goto error;
567         }
568
569         return up;
570 error:
571         isl_upoly_free(up);
572         return NULL;
573 }
574
575 __isl_give struct isl_upoly *isl_upoly_mul_cst(__isl_take struct isl_upoly *up1,
576         __isl_take struct isl_upoly *up2)
577 {
578         struct isl_upoly_cst *cst1;
579         struct isl_upoly_cst *cst2;
580
581         up1 = isl_upoly_cow(up1);
582         if (!up1 || !up2)
583                 goto error;
584
585         cst1 = isl_upoly_as_cst(up1);
586         cst2 = isl_upoly_as_cst(up2);
587
588         isl_int_mul(cst1->n, cst1->n, cst2->n);
589         isl_int_mul(cst1->d, cst1->d, cst2->d);
590
591         isl_upoly_cst_reduce(cst1);
592
593         isl_upoly_free(up2);
594         return up1;
595 error:
596         isl_upoly_free(up1);
597         isl_upoly_free(up2);
598         return NULL;
599 }
600
601 __isl_give struct isl_upoly *isl_upoly_mul_rec(__isl_take struct isl_upoly *up1,
602         __isl_take struct isl_upoly *up2)
603 {
604         struct isl_upoly_rec *rec1;
605         struct isl_upoly_rec *rec2;
606         struct isl_upoly_rec *res;
607         int i, j;
608         int size;
609
610         rec1 = isl_upoly_as_rec(up1);
611         rec2 = isl_upoly_as_rec(up2);
612         if (!rec1 || !rec2)
613                 goto error;
614         size = rec1->n + rec2->n - 1;
615         res = isl_upoly_alloc_rec(up1->ctx, up1->var, size);
616         if (!res)
617                 goto error;
618
619         for (i = 0; i < rec1->n; ++i) {
620                 res->p[i] = isl_upoly_mul(isl_upoly_copy(rec2->p[0]),
621                                             isl_upoly_copy(rec1->p[i]));
622                 if (!res->p[i])
623                         goto error;
624                 res->n++;
625         }
626         for (; i < size; ++i) {
627                 res->p[i] = isl_upoly_zero(up1->ctx);
628                 if (!res->p[i])
629                         goto error;
630                 res->n++;
631         }
632         for (i = 0; i < rec1->n; ++i) {
633                 for (j = 1; j < rec2->n; ++j) {
634                         struct isl_upoly *up;
635                         up = isl_upoly_mul(isl_upoly_copy(rec2->p[j]),
636                                             isl_upoly_copy(rec1->p[i]));
637                         res->p[i + j] = isl_upoly_sum(res->p[i + j], up);
638                         if (!res->p[i + j])
639                                 goto error;
640                 }
641         }
642
643         isl_upoly_free(up1);
644         isl_upoly_free(up2);
645
646         return &res->up;
647 error:
648         isl_upoly_free(up1);
649         isl_upoly_free(up2);
650         isl_upoly_free(&res->up);
651         return NULL;
652 }
653
654 __isl_give struct isl_upoly *isl_upoly_mul(__isl_take struct isl_upoly *up1,
655         __isl_take struct isl_upoly *up2)
656 {
657         if (!up1 || !up2)
658                 goto error;
659
660         if (isl_upoly_is_nan(up1)) {
661                 isl_upoly_free(up2);
662                 return up1;
663         }
664
665         if (isl_upoly_is_nan(up2)) {
666                 isl_upoly_free(up1);
667                 return up2;
668         }
669
670         if (isl_upoly_is_zero(up1)) {
671                 isl_upoly_free(up2);
672                 return up1;
673         }
674
675         if (isl_upoly_is_zero(up2)) {
676                 isl_upoly_free(up1);
677                 return up2;
678         }
679
680         if (isl_upoly_is_one(up1)) {
681                 isl_upoly_free(up1);
682                 return up2;
683         }
684
685         if (isl_upoly_is_one(up2)) {
686                 isl_upoly_free(up2);
687                 return up1;
688         }
689
690         if (up1->var < up2->var)
691                 return isl_upoly_mul(up2, up1);
692
693         if (up2->var < up1->var) {
694                 int i;
695                 struct isl_upoly_rec *rec;
696                 if (isl_upoly_is_infty(up2) || isl_upoly_is_neginfty(up2)) {
697                         isl_ctx *ctx = up1->ctx;
698                         isl_upoly_free(up1);
699                         isl_upoly_free(up2);
700                         return isl_upoly_nan(ctx);
701                 }
702                 up1 = isl_upoly_cow(up1);
703                 rec = isl_upoly_as_rec(up1);
704                 if (!rec)
705                         goto error;
706
707                 for (i = 0; i < rec->n; ++i) {
708                         rec->p[i] = isl_upoly_mul(rec->p[i],
709                                                     isl_upoly_copy(up2));
710                         if (!rec->p[i])
711                                 goto error;
712                 }
713                 isl_upoly_free(up2);
714                 return up1;
715         }
716
717         if (isl_upoly_is_cst(up1))
718                 return isl_upoly_mul_cst(up1, up2);
719
720         return isl_upoly_mul_rec(up1, up2);
721 error:
722         isl_upoly_free(up1);
723         isl_upoly_free(up2);
724         return NULL;
725 }
726
727 __isl_give isl_qpolynomial *isl_qpolynomial_alloc(__isl_take isl_dim *dim,
728         unsigned n_div)
729 {
730         struct isl_qpolynomial *qp;
731         unsigned total;
732
733         if (!dim)
734                 return NULL;
735
736         total = isl_dim_total(dim);
737
738         qp = isl_calloc_type(dim->ctx, struct isl_qpolynomial);
739         if (!qp)
740                 return NULL;
741
742         qp->ref = 1;
743         qp->div = isl_mat_alloc(dim->ctx, n_div, 1 + 1 + total + n_div);
744         if (!qp->div)
745                 goto error;
746
747         qp->dim = dim;
748
749         return qp;
750 error:
751         isl_dim_free(dim);
752         isl_qpolynomial_free(qp);
753         return NULL;
754 }
755
756 __isl_give isl_qpolynomial *isl_qpolynomial_copy(__isl_keep isl_qpolynomial *qp)
757 {
758         if (!qp)
759                 return NULL;
760
761         qp->ref++;
762         return qp;
763 }
764
765 __isl_give isl_qpolynomial *isl_qpolynomial_dup(__isl_keep isl_qpolynomial *qp)
766 {
767         struct isl_qpolynomial *dup;
768
769         if (!qp)
770                 return NULL;
771
772         dup = isl_qpolynomial_alloc(isl_dim_copy(qp->dim), qp->div->n_row);
773         if (!dup)
774                 return NULL;
775         isl_mat_free(dup->div);
776         dup->div = isl_mat_copy(qp->div);
777         if (!dup->div)
778                 goto error;
779         dup->upoly = isl_upoly_copy(qp->upoly);
780         if (!dup->upoly)
781                 goto error;
782
783         return dup;
784 error:
785         isl_qpolynomial_free(dup);
786         return NULL;
787 }
788
789 __isl_give isl_qpolynomial *isl_qpolynomial_cow(__isl_take isl_qpolynomial *qp)
790 {
791         if (!qp)
792                 return NULL;
793
794         if (qp->ref == 1)
795                 return qp;
796         qp->ref--;
797         return isl_qpolynomial_dup(qp);
798 }
799
800 void isl_qpolynomial_free(__isl_take isl_qpolynomial *qp)
801 {
802         if (!qp)
803                 return;
804
805         if (--qp->ref > 0)
806                 return;
807
808         isl_dim_free(qp->dim);
809         isl_mat_free(qp->div);
810         isl_upoly_free(qp->upoly);
811
812         free(qp);
813 }
814
815 static int compatible_divs(__isl_keep isl_mat *div1, __isl_keep isl_mat *div2)
816 {
817         int n_row, n_col;
818         int equal;
819
820         isl_assert(div1->ctx, div1->n_row >= div2->n_row &&
821                                 div1->n_col >= div2->n_col, return -1);
822
823         if (div1->n_row == div2->n_row)
824                 return isl_mat_is_equal(div1, div2);
825
826         n_row = div1->n_row;
827         n_col = div1->n_col;
828         div1->n_row = div2->n_row;
829         div1->n_col = div2->n_col;
830
831         equal = isl_mat_is_equal(div1, div2);
832
833         div1->n_row = n_row;
834         div1->n_col = n_col;
835
836         return equal;
837 }
838
839 static void expand_row(__isl_keep isl_mat *dst, int d,
840         __isl_keep isl_mat *src, int s, int *exp)
841 {
842         int i;
843         unsigned c = src->n_col - src->n_row;
844
845         isl_seq_cpy(dst->row[d], src->row[s], c);
846         isl_seq_clr(dst->row[d] + c, dst->n_col - c);
847
848         for (i = 0; i < s; ++i)
849                 isl_int_set(dst->row[d][c + exp[i]], src->row[s][c + i]);
850 }
851
852 static int cmp_row(__isl_keep isl_mat *div, int i, int j)
853 {
854         int li, lj;
855
856         li = isl_seq_last_non_zero(div->row[i], div->n_col);
857         lj = isl_seq_last_non_zero(div->row[j], div->n_col);
858
859         if (li != lj)
860                 return li - lj;
861
862         return isl_seq_cmp(div->row[i], div->row[j], div->n_col);
863 }
864
865 static __isl_give isl_mat *merge_divs(__isl_keep isl_mat *div1,
866         __isl_keep isl_mat *div2, int *exp1, int *exp2)
867 {
868         int i, j, k;
869         isl_mat *div = NULL;
870         unsigned d = div1->n_col - div1->n_row;
871
872         div = isl_mat_alloc(div1->ctx, 1 + div1->n_row + div2->n_row,
873                                 d + div1->n_row + div2->n_row);
874         if (!div)
875                 return NULL;
876
877         for (i = 0, j = 0, k = 0; i < div1->n_row && j < div2->n_row; ++k) {
878                 int cmp;
879
880                 expand_row(div, k, div1, i, exp1);
881                 expand_row(div, k + 1, div2, j, exp2);
882
883                 cmp = cmp_row(div, k, k + 1);
884                 if (cmp == 0) {
885                         exp1[i++] = k;
886                         exp2[j++] = k;
887                 } else if (cmp < 0) {
888                         exp1[i++] = k;
889                 } else {
890                         exp2[j++] = k;
891                         isl_seq_cpy(div->row[k], div->row[k + 1], div->n_col);
892                 }
893         }
894         for (; i < div1->n_row; ++i, ++k) {
895                 expand_row(div, k, div1, i, exp1);
896                 exp1[i] = k;
897         }
898         for (; j < div2->n_row; ++j, ++k) {
899                 expand_row(div, k, div2, j, exp2);
900                 exp2[j] = k;
901         }
902
903         div->n_row = k;
904         div->n_col = d + k;
905
906         return div;
907 }
908
909 static __isl_give struct isl_upoly *expand(__isl_take struct isl_upoly *up,
910         int *exp, int first)
911 {
912         int i;
913         struct isl_upoly_rec *rec;
914
915         if (isl_upoly_is_cst(up))
916                 return up;
917
918         if (up->var < first)
919                 return up;
920
921         if (exp[up->var - first] == up->var - first)
922                 return up;
923
924         up = isl_upoly_cow(up);
925         if (!up)
926                 goto error;
927
928         up->var = exp[up->var - first] + first;
929
930         rec = isl_upoly_as_rec(up);
931         if (!rec)
932                 goto error;
933
934         for (i = 0; i < rec->n; ++i) {
935                 rec->p[i] = expand(rec->p[i], exp, first);
936                 if (!rec->p[i])
937                         goto error;
938         }
939
940         return up;
941 error:
942         isl_upoly_free(up);
943         return NULL;
944 }
945
946 static __isl_give isl_qpolynomial *with_merged_divs(
947         __isl_give isl_qpolynomial *(*fn)(__isl_take isl_qpolynomial *qp1,
948                                           __isl_take isl_qpolynomial *qp2),
949         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
950 {
951         int *exp1 = NULL;
952         int *exp2 = NULL;
953         isl_mat *div = NULL;
954
955         qp1 = isl_qpolynomial_cow(qp1);
956         qp2 = isl_qpolynomial_cow(qp2);
957
958         if (!qp1 || !qp2)
959                 goto error;
960
961         isl_assert(qp1->div->ctx, qp1->div->n_row >= qp2->div->n_row &&
962                                 qp1->div->n_col >= qp2->div->n_col, goto error);
963
964         exp1 = isl_alloc_array(qp1->div->ctx, int, qp1->div->n_row);
965         exp2 = isl_alloc_array(qp2->div->ctx, int, qp2->div->n_row);
966         if (!exp1 || !exp2)
967                 goto error;
968
969         div = merge_divs(qp1->div, qp2->div, exp1, exp2);
970         if (!div)
971                 goto error;
972
973         isl_mat_free(qp1->div);
974         qp1->div = isl_mat_copy(div);
975         isl_mat_free(qp2->div);
976         qp2->div = isl_mat_copy(div);
977
978         qp1->upoly = expand(qp1->upoly, exp1, div->n_col - div->n_row - 2);
979         qp2->upoly = expand(qp2->upoly, exp2, div->n_col - div->n_row - 2);
980
981         if (!qp1->upoly || !qp2->upoly)
982                 goto error;
983
984         isl_mat_free(div);
985         free(exp1);
986         free(exp2);
987
988         return fn(qp1, qp2);
989 error:
990         isl_mat_free(div);
991         free(exp1);
992         free(exp2);
993         isl_qpolynomial_free(qp1);
994         isl_qpolynomial_free(qp2);
995         return NULL;
996 }
997
998 __isl_give isl_qpolynomial *isl_qpolynomial_add(__isl_take isl_qpolynomial *qp1,
999         __isl_take isl_qpolynomial *qp2)
1000 {
1001         qp1 = isl_qpolynomial_cow(qp1);
1002
1003         if (!qp1 || !qp2)
1004                 goto error;
1005
1006         if (qp1->div->n_row < qp2->div->n_row)
1007                 return isl_qpolynomial_add(qp2, qp1);
1008
1009         isl_assert(qp1->dim->ctx, isl_dim_equal(qp1->dim, qp2->dim), goto error);
1010         if (!compatible_divs(qp1->div, qp2->div))
1011                 return with_merged_divs(isl_qpolynomial_add, qp1, qp2);
1012
1013         qp1->upoly = isl_upoly_sum(qp1->upoly, isl_upoly_copy(qp2->upoly));
1014         if (!qp1->upoly)
1015                 goto error;
1016
1017         isl_qpolynomial_free(qp2);
1018
1019         return qp1;
1020 error:
1021         isl_qpolynomial_free(qp1);
1022         isl_qpolynomial_free(qp2);
1023         return NULL;
1024 }
1025
1026 __isl_give isl_qpolynomial *isl_qpolynomial_sub(__isl_take isl_qpolynomial *qp1,
1027         __isl_take isl_qpolynomial *qp2)
1028 {
1029         return isl_qpolynomial_add(qp1, isl_qpolynomial_neg(qp2));
1030 }
1031
1032 __isl_give isl_qpolynomial *isl_qpolynomial_neg(__isl_take isl_qpolynomial *qp)
1033 {
1034         qp = isl_qpolynomial_cow(qp);
1035
1036         if (!qp)
1037                 return NULL;
1038
1039         qp->upoly = isl_upoly_neg(qp->upoly);
1040         if (!qp->upoly)
1041                 goto error;
1042
1043         return qp;
1044 error:
1045         isl_qpolynomial_free(qp);
1046         return NULL;
1047 }
1048
1049 __isl_give isl_qpolynomial *isl_qpolynomial_mul(__isl_take isl_qpolynomial *qp1,
1050         __isl_take isl_qpolynomial *qp2)
1051 {
1052         qp1 = isl_qpolynomial_cow(qp1);
1053
1054         if (!qp1 || !qp2)
1055                 goto error;
1056
1057         if (qp1->div->n_row < qp2->div->n_row)
1058                 return isl_qpolynomial_mul(qp2, qp1);
1059
1060         isl_assert(qp1->dim->ctx, isl_dim_equal(qp1->dim, qp2->dim), goto error);
1061         if (!compatible_divs(qp1->div, qp2->div))
1062                 return with_merged_divs(isl_qpolynomial_mul, qp1, qp2);
1063
1064         qp1->upoly = isl_upoly_mul(qp1->upoly, isl_upoly_copy(qp2->upoly));
1065         if (!qp1->upoly)
1066                 goto error;
1067
1068         isl_qpolynomial_free(qp2);
1069
1070         return qp1;
1071 error:
1072         isl_qpolynomial_free(qp1);
1073         isl_qpolynomial_free(qp2);
1074         return NULL;
1075 }
1076
1077 __isl_give isl_qpolynomial *isl_qpolynomial_zero(__isl_take isl_dim *dim)
1078 {
1079         struct isl_qpolynomial *qp;
1080         struct isl_upoly_cst *cst;
1081
1082         qp = isl_qpolynomial_alloc(dim, 0);
1083         if (!qp)
1084                 return NULL;
1085
1086         qp->upoly = isl_upoly_zero(dim->ctx);
1087         if (!qp->upoly)
1088                 goto error;
1089
1090         return qp;
1091 error:
1092         isl_qpolynomial_free(qp);
1093         return NULL;
1094 }
1095
1096 __isl_give isl_qpolynomial *isl_qpolynomial_infty(__isl_take isl_dim *dim)
1097 {
1098         struct isl_qpolynomial *qp;
1099         struct isl_upoly_cst *cst;
1100
1101         qp = isl_qpolynomial_alloc(dim, 0);
1102         if (!qp)
1103                 return NULL;
1104
1105         qp->upoly = isl_upoly_infty(dim->ctx);
1106         if (!qp->upoly)
1107                 goto error;
1108
1109         return qp;
1110 error:
1111         isl_qpolynomial_free(qp);
1112         return NULL;
1113 }
1114
1115 __isl_give isl_qpolynomial *isl_qpolynomial_nan(__isl_take isl_dim *dim)
1116 {
1117         struct isl_qpolynomial *qp;
1118         struct isl_upoly_cst *cst;
1119
1120         qp = isl_qpolynomial_alloc(dim, 0);
1121         if (!qp)
1122                 return NULL;
1123
1124         qp->upoly = isl_upoly_nan(dim->ctx);
1125         if (!qp->upoly)
1126                 goto error;
1127
1128         return qp;
1129 error:
1130         isl_qpolynomial_free(qp);
1131         return NULL;
1132 }
1133
1134 __isl_give isl_qpolynomial *isl_qpolynomial_cst(__isl_take isl_dim *dim,
1135         isl_int v)
1136 {
1137         struct isl_qpolynomial *qp;
1138         struct isl_upoly_cst *cst;
1139
1140         qp = isl_qpolynomial_alloc(dim, 0);
1141         if (!qp)
1142                 return NULL;
1143
1144         qp->upoly = isl_upoly_zero(dim->ctx);
1145         if (!qp->upoly)
1146                 goto error;
1147         cst = isl_upoly_as_cst(qp->upoly);
1148         isl_int_set(cst->n, v);
1149
1150         return qp;
1151 error:
1152         isl_qpolynomial_free(qp);
1153         return NULL;
1154 }
1155
1156 int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp,
1157         isl_int *n, isl_int *d)
1158 {
1159         struct isl_upoly_cst *cst;
1160
1161         if (!qp)
1162                 return -1;
1163
1164         if (!isl_upoly_is_cst(qp->upoly))
1165                 return 0;
1166
1167         cst = isl_upoly_as_cst(qp->upoly);
1168         if (!cst)
1169                 return -1;
1170
1171         if (n)
1172                 isl_int_set(*n, cst->n);
1173         if (d)
1174                 isl_int_set(*d, cst->d);
1175
1176         return 1;
1177 }
1178
1179 static void upoly_update_den(__isl_keep struct isl_upoly *up, isl_int *d)
1180 {
1181         int i;
1182         struct isl_upoly_rec *rec;
1183
1184         if (isl_upoly_is_cst(up)) {
1185                 struct isl_upoly_cst *cst;
1186                 cst = isl_upoly_as_cst(up);
1187                 if (!cst)
1188                         return;
1189                 isl_int_lcm(*d, *d, cst->d);
1190                 return;
1191         }
1192
1193         rec = isl_upoly_as_rec(up);
1194         if (!rec)
1195                 return;
1196
1197         for (i = 0; i < rec->n; ++i)
1198                 upoly_update_den(rec->p[i], d);
1199 }
1200
1201 void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d)
1202 {
1203         isl_int_set_si(*d, 1);
1204         if (!qp)
1205                 return;
1206         upoly_update_den(qp->upoly, d);
1207 }
1208
1209 __isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_dim *dim,
1210         int pos, int power)
1211 {
1212         int i;
1213         struct isl_qpolynomial *qp;
1214         struct isl_upoly_rec *rec;
1215         struct isl_upoly_cst *cst;
1216         struct isl_ctx *ctx;
1217
1218         if (!dim)
1219                 return NULL;
1220
1221         ctx = dim->ctx;
1222
1223         qp = isl_qpolynomial_alloc(dim, 0);
1224         if (!qp)
1225                 return NULL;
1226
1227         qp->upoly = &isl_upoly_alloc_rec(ctx, pos, 1 + power)->up;
1228         if (!qp->upoly)
1229                 goto error;
1230         rec = isl_upoly_as_rec(qp->upoly);
1231         for (i = 0; i < 1 + power; ++i) {
1232                 rec->p[i] = isl_upoly_zero(ctx);
1233                 if (!rec->p[i])
1234                         goto error;
1235                 rec->n++;
1236         }
1237         cst = isl_upoly_as_cst(rec->p[power]);
1238         isl_int_set_si(cst->n, 1);
1239
1240         return qp;
1241 error:
1242         isl_qpolynomial_free(qp);
1243         return NULL;
1244 }
1245
1246 __isl_give isl_qpolynomial *isl_qpolynomial_var(__isl_take isl_dim *dim,
1247         enum isl_dim_type type, unsigned pos)
1248 {
1249         if (!dim)
1250                 return NULL;
1251
1252         isl_assert(dim->ctx, isl_dim_size(dim, isl_dim_in) == 0, goto error);
1253         isl_assert(dim->ctx, pos < isl_dim_size(dim, type), goto error);
1254
1255         if (type == isl_dim_set)
1256                 pos += isl_dim_size(dim, isl_dim_param);
1257
1258         return isl_qpolynomial_pow(dim, pos, 1);
1259 error:
1260         isl_dim_free(dim);
1261         return NULL;
1262 }
1263
1264 __isl_give isl_qpolynomial *isl_qpolynomial_div_pow(__isl_take isl_div *div,
1265         int power)
1266 {
1267         struct isl_qpolynomial *qp = NULL;
1268         struct isl_upoly_rec *rec;
1269         struct isl_upoly_cst *cst;
1270         int i;
1271         int pos;
1272
1273         if (!div)
1274                 return NULL;
1275         isl_assert(div->ctx, div->bmap->n_div == 1, goto error);
1276
1277         qp = isl_qpolynomial_alloc(isl_basic_map_get_dim(div->bmap), 1);
1278         if (!qp)
1279                 goto error;
1280
1281         isl_seq_cpy(qp->div->row[0], div->line[0], qp->div->n_col - 1);
1282         isl_int_set_si(qp->div->row[0][qp->div->n_col - 1], 0);
1283
1284         pos = isl_dim_total(qp->dim);
1285         qp->upoly = &isl_upoly_alloc_rec(div->ctx, pos, 1 + power)->up;
1286         if (!qp->upoly)
1287                 goto error;
1288         rec = isl_upoly_as_rec(qp->upoly);
1289         for (i = 0; i < 1 + power; ++i) {
1290                 rec->p[i] = isl_upoly_zero(div->ctx);
1291                 if (!rec->p[i])
1292                         goto error;
1293                 rec->n++;
1294         }
1295         cst = isl_upoly_as_cst(rec->p[power]);
1296         isl_int_set_si(cst->n, 1);
1297
1298         isl_div_free(div);
1299
1300         return qp;
1301 error:
1302         isl_qpolynomial_free(qp);
1303         isl_div_free(div);
1304         return NULL;
1305 }
1306
1307 __isl_give isl_qpolynomial *isl_qpolynomial_div(__isl_take isl_div *div)
1308 {
1309         return isl_qpolynomial_div_pow(div, 1);
1310 }
1311
1312 __isl_give isl_qpolynomial *isl_qpolynomial_rat_cst(__isl_take isl_dim *dim,
1313         const isl_int n, const isl_int d)
1314 {
1315         struct isl_qpolynomial *qp;
1316         struct isl_upoly_cst *cst;
1317
1318         qp = isl_qpolynomial_alloc(dim, 0);
1319         if (!qp)
1320                 return NULL;
1321
1322         qp->upoly = isl_upoly_zero(dim->ctx);
1323         if (!qp->upoly)
1324                 goto error;
1325         cst = isl_upoly_as_cst(qp->upoly);
1326         isl_int_set(cst->n, n);
1327         isl_int_set(cst->d, d);
1328
1329         return qp;
1330 error:
1331         isl_qpolynomial_free(qp);
1332         return NULL;
1333 }
1334
1335 #undef PW
1336 #define PW isl_pw_qpolynomial
1337 #undef EL
1338 #define EL isl_qpolynomial
1339 #undef IS_ZERO
1340 #define IS_ZERO is_zero
1341 #undef FIELD
1342 #define FIELD qp
1343 #undef ADD
1344 #define ADD add
1345
1346 #include <isl_pw_templ.c>
1347
1348 #undef PW
1349 #define PW isl_pw_qpolynomial_fold
1350 #undef EL
1351 #define EL isl_qpolynomial_fold
1352 #undef IS_ZERO
1353 #define IS_ZERO is_empty
1354 #undef FIELD
1355 #define FIELD fold
1356 #undef ADD
1357 #define ADD fold
1358
1359 #include <isl_pw_templ.c>
1360
1361 int isl_pw_qpolynomial_is_one(__isl_keep isl_pw_qpolynomial *pwqp)
1362 {
1363         if (!pwqp)
1364                 return -1;
1365
1366         if (pwqp->n != -1)
1367                 return 0;
1368
1369         if (!isl_set_fast_is_universe(pwqp->p[0].set))
1370                 return 0;
1371
1372         return isl_qpolynomial_is_one(pwqp->p[0].qp);
1373 }
1374
1375 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul(
1376         __isl_take isl_pw_qpolynomial *pwqp1,
1377         __isl_take isl_pw_qpolynomial *pwqp2)
1378 {
1379         int i, j, n;
1380         struct isl_pw_qpolynomial *res;
1381         isl_set *set;
1382
1383         if (!pwqp1 || !pwqp2)
1384                 goto error;
1385
1386         isl_assert(pwqp1->dim->ctx, isl_dim_equal(pwqp1->dim, pwqp2->dim),
1387                         goto error);
1388
1389         if (isl_pw_qpolynomial_is_zero(pwqp1)) {
1390                 isl_pw_qpolynomial_free(pwqp2);
1391                 return pwqp1;
1392         }
1393
1394         if (isl_pw_qpolynomial_is_zero(pwqp2)) {
1395                 isl_pw_qpolynomial_free(pwqp1);
1396                 return pwqp2;
1397         }
1398
1399         if (isl_pw_qpolynomial_is_one(pwqp1)) {
1400                 isl_pw_qpolynomial_free(pwqp1);
1401                 return pwqp2;
1402         }
1403
1404         if (isl_pw_qpolynomial_is_one(pwqp2)) {
1405                 isl_pw_qpolynomial_free(pwqp2);
1406                 return pwqp1;
1407         }
1408
1409         n = pwqp1->n * pwqp2->n;
1410         res = isl_pw_qpolynomial_alloc_(isl_dim_copy(pwqp1->dim), n);
1411
1412         for (i = 0; i < pwqp1->n; ++i) {
1413                 for (j = 0; j < pwqp2->n; ++j) {
1414                         struct isl_set *common;
1415                         struct isl_qpolynomial *prod;
1416                         common = isl_set_intersect(isl_set_copy(pwqp1->p[i].set),
1417                                                 isl_set_copy(pwqp2->p[j].set));
1418                         if (isl_set_fast_is_empty(common)) {
1419                                 isl_set_free(common);
1420                                 continue;
1421                         }
1422
1423                         prod = isl_qpolynomial_mul(
1424                                 isl_qpolynomial_copy(pwqp1->p[i].qp),
1425                                 isl_qpolynomial_copy(pwqp2->p[j].qp));
1426
1427                         res = isl_pw_qpolynomial_add_piece(res, common, prod);
1428                 }
1429         }
1430
1431         isl_pw_qpolynomial_free(pwqp1);
1432         isl_pw_qpolynomial_free(pwqp2);
1433
1434         return res;
1435 error:
1436         isl_pw_qpolynomial_free(pwqp1);
1437         isl_pw_qpolynomial_free(pwqp2);
1438         return NULL;
1439 }
1440
1441 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg(
1442         __isl_take isl_pw_qpolynomial *pwqp)
1443 {
1444         int i, j, n;
1445         struct isl_pw_qpolynomial *res;
1446         isl_set *set;
1447
1448         if (!pwqp)
1449                 return NULL;
1450
1451         if (isl_pw_qpolynomial_is_zero(pwqp))
1452                 return pwqp;
1453
1454         pwqp = isl_pw_qpolynomial_cow(pwqp);
1455
1456         for (i = 0; i < pwqp->n; ++i) {
1457                 pwqp->p[i].qp = isl_qpolynomial_neg(pwqp->p[i].qp);
1458                 if (!pwqp->p[i].qp)
1459                         goto error;
1460         }
1461
1462         return pwqp;
1463 error:
1464         isl_pw_qpolynomial_free(pwqp);
1465         return NULL;
1466 }
1467
1468 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub(
1469         __isl_take isl_pw_qpolynomial *pwqp1,
1470         __isl_take isl_pw_qpolynomial *pwqp2)
1471 {
1472         return isl_pw_qpolynomial_add(pwqp1, isl_pw_qpolynomial_neg(pwqp2));
1473 }
1474
1475 __isl_give struct isl_upoly *isl_upoly_eval(
1476         __isl_take struct isl_upoly *up, __isl_take isl_vec *vec)
1477 {
1478         int i;
1479         struct isl_upoly_rec *rec;
1480         struct isl_upoly *res;
1481         struct isl_upoly *base;
1482
1483         if (isl_upoly_is_cst(up)) {
1484                 isl_vec_free(vec);
1485                 return up;
1486         }
1487
1488         rec = isl_upoly_as_rec(up);
1489         if (!rec)
1490                 goto error;
1491
1492         isl_assert(up->ctx, rec->n >= 1, goto error);
1493
1494         base = isl_upoly_rat_cst(up->ctx, vec->el[1 + up->var], vec->el[0]);
1495
1496         res = isl_upoly_eval(isl_upoly_copy(rec->p[rec->n - 1]),
1497                                 isl_vec_copy(vec));
1498
1499         for (i = rec->n - 2; i >= 0; --i) {
1500                 res = isl_upoly_mul(res, isl_upoly_copy(base));
1501                 res = isl_upoly_sum(res, 
1502                             isl_upoly_eval(isl_upoly_copy(rec->p[i]),
1503                                                             isl_vec_copy(vec)));
1504         }
1505
1506         isl_upoly_free(base);
1507         isl_upoly_free(up);
1508         isl_vec_free(vec);
1509         return res;
1510 error:
1511         isl_upoly_free(up);
1512         isl_vec_free(vec);
1513         return NULL;
1514 }
1515
1516 __isl_give isl_qpolynomial *isl_qpolynomial_eval(
1517         __isl_take isl_qpolynomial *qp, __isl_take isl_point *pnt)
1518 {
1519         isl_vec *ext;
1520         struct isl_upoly *up;
1521         isl_dim *dim;
1522
1523         if (!qp || !pnt)
1524                 goto error;
1525         isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, qp->dim), goto error);
1526
1527         if (qp->div->n_row == 0)
1528                 ext = isl_vec_copy(pnt->vec);
1529         else {
1530                 int i;
1531                 unsigned dim = isl_dim_total(qp->dim);
1532                 ext = isl_vec_alloc(qp->dim->ctx, 1 + dim + qp->div->n_row);
1533                 if (!ext)
1534                         goto error;
1535
1536                 isl_seq_cpy(ext->el, pnt->vec->el, pnt->vec->size);
1537                 for (i = 0; i < qp->div->n_row; ++i) {
1538                         isl_seq_inner_product(qp->div->row[i] + 1, ext->el,
1539                                                 1 + dim + i, &ext->el[1+dim+i]);
1540                         isl_int_fdiv_q(ext->el[1+dim+i], ext->el[1+dim+i],
1541                                         qp->div->row[i][0]);
1542                 }
1543         }
1544
1545         up = isl_upoly_eval(isl_upoly_copy(qp->upoly), ext);
1546         if (!up)
1547                 goto error;
1548
1549         dim = isl_dim_copy(qp->dim);
1550         isl_qpolynomial_free(qp);
1551         isl_point_free(pnt);
1552
1553         qp = isl_qpolynomial_alloc(dim, 0);
1554         if (!qp)
1555                 isl_upoly_free(up);
1556         else
1557                 qp->upoly = up;
1558
1559         return qp;
1560 error:
1561         isl_qpolynomial_free(qp);
1562         isl_point_free(pnt);
1563         return NULL;
1564 }
1565
1566 int isl_upoly_cmp(__isl_keep struct isl_upoly_cst *cst1,
1567         __isl_keep struct isl_upoly_cst *cst2)
1568 {
1569         int cmp;
1570         isl_int t;
1571         isl_int_init(t);
1572         isl_int_mul(t, cst1->n, cst2->d);
1573         isl_int_submul(t, cst2->n, cst1->d);
1574         cmp = isl_int_sgn(t);
1575         isl_int_clear(t);
1576         return cmp;
1577 }
1578
1579 static __isl_give isl_qpolynomial *qpolynomial_min(
1580         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
1581 {
1582         struct isl_upoly_cst *cst1, *cst2;
1583         int cmp;
1584
1585         if (!qp1 || !qp2)
1586                 goto error;
1587         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
1588         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
1589         cst1 = isl_upoly_as_cst(qp1->upoly);
1590         cst2 = isl_upoly_as_cst(qp2->upoly);
1591         cmp = isl_upoly_cmp(cst1, cst2);
1592
1593         if (cmp <= 0) {
1594                 isl_qpolynomial_free(qp2);
1595         } else {
1596                 isl_qpolynomial_free(qp1);
1597                 qp1 = qp2;
1598         }
1599         return qp1;
1600 error:
1601         isl_qpolynomial_free(qp1);
1602         isl_qpolynomial_free(qp2);
1603         return NULL;
1604 }
1605
1606 static __isl_give isl_qpolynomial *qpolynomial_max(
1607         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
1608 {
1609         struct isl_upoly_cst *cst1, *cst2;
1610         int cmp;
1611
1612         if (!qp1 || !qp2)
1613                 goto error;
1614         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
1615         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
1616         cst1 = isl_upoly_as_cst(qp1->upoly);
1617         cst2 = isl_upoly_as_cst(qp2->upoly);
1618         cmp = isl_upoly_cmp(cst1, cst2);
1619
1620         if (cmp >= 0) {
1621                 isl_qpolynomial_free(qp2);
1622         } else {
1623                 isl_qpolynomial_free(qp1);
1624                 qp1 = qp2;
1625         }
1626         return qp1;
1627 error:
1628         isl_qpolynomial_free(qp1);
1629         isl_qpolynomial_free(qp2);
1630         return NULL;
1631 }
1632
1633 __isl_give isl_qpolynomial *isl_qpolynomial_fold_eval(
1634         __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt)
1635 {
1636         isl_qpolynomial *qp;
1637
1638         if (!fold || !pnt)
1639                 goto error;
1640         isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, fold->dim), goto error);
1641         isl_assert(pnt->dim->ctx,
1642                 fold->type == isl_fold_max || fold->type == isl_fold_min,
1643                 goto error);
1644
1645         if (fold->n == 0)
1646                 qp = isl_qpolynomial_zero(isl_dim_copy(fold->dim));
1647         else {
1648                 int i;
1649                 qp = isl_qpolynomial_eval(isl_qpolynomial_copy(fold->qp[0]),
1650                                                 isl_point_copy(pnt));
1651                 for (i = 1; i < fold->n; ++i) {
1652                         isl_qpolynomial *qp_i;
1653                         qp_i = isl_qpolynomial_eval(
1654                                             isl_qpolynomial_copy(fold->qp[i]),
1655                                             isl_point_copy(pnt));
1656                         if (fold->type == isl_fold_max)
1657                                 qp = qpolynomial_max(qp, qp_i);
1658                         else
1659                                 qp = qpolynomial_min(qp, qp_i);
1660                 }
1661         }
1662         isl_qpolynomial_fold_free(fold);
1663         isl_point_free(pnt);
1664
1665         return qp;
1666 error:
1667         isl_qpolynomial_fold_free(fold);
1668         isl_point_free(pnt);
1669         return NULL;
1670 }
1671
1672 __isl_give isl_qpolynomial *isl_qpolynomial_move(__isl_take isl_qpolynomial *qp,
1673         enum isl_dim_type dst_type, unsigned dst_pos,
1674         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
1675 {
1676         if (!qp)
1677                 return NULL;
1678
1679         qp->dim = isl_dim_move(qp->dim, dst_type, dst_pos, src_type, src_pos, n);
1680         if (!qp->dim)
1681                 goto error;
1682         
1683         /* Do something to polynomials when needed; later */
1684
1685         return qp;
1686 error:
1687         isl_qpolynomial_free(qp);
1688         return NULL;
1689 }
1690
1691 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_move(
1692         __isl_take isl_pw_qpolynomial *pwqp,
1693         enum isl_dim_type dst_type, unsigned dst_pos,
1694         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
1695 {
1696         int i;
1697
1698         if (!pwqp)
1699                 return NULL;
1700
1701         pwqp->dim = isl_dim_move(pwqp->dim,
1702                                     dst_type, dst_pos, src_type, src_pos, n);
1703         if (!pwqp->dim)
1704                 goto error;
1705
1706         for (i = 0; i < pwqp->n; ++i) {
1707                 pwqp->p[i].set = isl_set_move(pwqp->p[i].set, dst_type, dst_pos,
1708                                                 src_type, src_pos, n);
1709                 if (!pwqp->p[i].set)
1710                         goto error;
1711                 pwqp->p[i].qp = isl_qpolynomial_move(pwqp->p[i].qp,
1712                                         dst_type, dst_pos, src_type, src_pos, n);
1713                 if (!pwqp->p[i].qp)
1714                         goto error;
1715         }
1716
1717         return pwqp;
1718 error:
1719         isl_pw_qpolynomial_free(pwqp);
1720         return NULL;
1721 }
1722
1723 __isl_give isl_dim *isl_pw_qpolynomial_get_dim(
1724         __isl_keep isl_pw_qpolynomial *pwqp)
1725 {
1726         if (!pwqp)
1727                 return NULL;
1728
1729         return isl_dim_copy(pwqp->dim);
1730 }
1731
1732 unsigned isl_pw_qpolynomial_dim(__isl_keep isl_pw_qpolynomial *pwqp,
1733         enum isl_dim_type type)
1734 {
1735         return pwqp ? isl_dim_size(pwqp->dim, type) : 0;
1736 }
1737
1738 __isl_give isl_term *isl_term_alloc(__isl_take isl_dim *dim,
1739         __isl_take isl_mat *div)
1740 {
1741         isl_term *term;
1742         int n;
1743
1744         if (!dim || !div)
1745                 goto error;
1746
1747         n = isl_dim_total(dim) + div->n_row;
1748
1749         term = isl_calloc(dim->ctx, struct isl_term,
1750                         sizeof(struct isl_term) + (n - 1) * sizeof(int));
1751         if (!term)
1752                 goto error;
1753
1754         term->ref = 1;
1755         term->dim = dim;
1756         term->div = div;
1757         isl_int_init(term->n);
1758         isl_int_init(term->d);
1759         
1760         return term;
1761 error:
1762         isl_dim_free(dim);
1763         isl_mat_free(div);
1764         return NULL;
1765 }
1766
1767 __isl_give isl_term *isl_term_copy(__isl_keep isl_term *term)
1768 {
1769         if (!term)
1770                 return NULL;
1771
1772         term->ref++;
1773         return term;
1774 }
1775
1776 __isl_give isl_term *isl_term_dup(__isl_keep isl_term *term)
1777 {
1778         int i;
1779         isl_term *dup;
1780         unsigned total;
1781
1782         if (term)
1783                 return NULL;
1784
1785         total = isl_dim_total(term->dim) + term->div->n_row;
1786
1787         dup = isl_term_alloc(isl_dim_copy(term->dim), isl_mat_copy(term->div));
1788         if (!dup)
1789                 return NULL;
1790
1791         isl_int_set(dup->n, term->n);
1792         isl_int_set(dup->d, term->d);
1793
1794         for (i = 0; i < total; ++i)
1795                 dup->pow[i] = term->pow[i];
1796
1797         return dup;
1798 }
1799
1800 __isl_give isl_term *isl_term_cow(__isl_take isl_term *term)
1801 {
1802         if (!term)
1803                 return NULL;
1804
1805         if (term->ref == 1)
1806                 return term;
1807         term->ref--;
1808         return isl_term_dup(term);
1809 }
1810
1811 void isl_term_free(__isl_take isl_term *term)
1812 {
1813         if (!term)
1814                 return;
1815
1816         if (--term->ref > 0)
1817                 return;
1818
1819         isl_dim_free(term->dim);
1820         isl_mat_free(term->div);
1821         isl_int_clear(term->n);
1822         isl_int_clear(term->d);
1823         free(term);
1824 }
1825
1826 unsigned isl_term_dim(__isl_keep isl_term *term, enum isl_dim_type type)
1827 {
1828         if (!term)
1829                 return 0;
1830
1831         switch (type) {
1832         case isl_dim_param:
1833         case isl_dim_in:
1834         case isl_dim_out:       return isl_dim_size(term->dim, type);
1835         case isl_dim_div:       return term->div->n_row;
1836         case isl_dim_all:       return isl_dim_total(term->dim) + term->div->n_row;
1837         }
1838 }
1839
1840 isl_ctx *isl_term_get_ctx(__isl_keep isl_term *term)
1841 {
1842         return term ? term->dim->ctx : NULL;
1843 }
1844
1845 void isl_term_get_num(__isl_keep isl_term *term, isl_int *n)
1846 {
1847         if (!term)
1848                 return;
1849         isl_int_set(*n, term->n);
1850 }
1851
1852 void isl_term_get_den(__isl_keep isl_term *term, isl_int *d)
1853 {
1854         if (!term)
1855                 return;
1856         isl_int_set(*d, term->d);
1857 }
1858
1859 int isl_term_get_exp(__isl_keep isl_term *term,
1860         enum isl_dim_type type, unsigned pos)
1861 {
1862         if (!term)
1863                 return -1;
1864
1865         isl_assert(term->dim->ctx, pos < isl_term_dim(term, type), return -1);
1866
1867         if (type >= isl_dim_set)
1868                 pos += isl_dim_size(term->dim, isl_dim_param);
1869         if (type >= isl_dim_div)
1870                 pos += isl_dim_size(term->dim, isl_dim_set);
1871
1872         return term->pow[pos];
1873 }
1874
1875 __isl_give isl_div *isl_term_get_div(__isl_keep isl_term *term, unsigned pos)
1876 {
1877         isl_basic_map *bmap;
1878         unsigned total;
1879         int k;
1880
1881         if (!term)
1882                 return NULL;
1883
1884         isl_assert(term->dim->ctx, pos < isl_term_dim(term, isl_dim_div),
1885                         return NULL);
1886
1887         total = term->div->n_col - term->div->n_row - 2;
1888         /* No nested divs for now */
1889         isl_assert(term->dim->ctx,
1890                 isl_seq_first_non_zero(term->div->row[pos] + 2 + total,
1891                                         term->div->n_row) == -1,
1892                 return NULL);
1893
1894         bmap = isl_basic_map_alloc_dim(isl_dim_copy(term->dim), 1, 0, 0);
1895         if ((k = isl_basic_map_alloc_div(bmap)) < 0)
1896                 goto error;
1897
1898         isl_seq_cpy(bmap->div[k], term->div->row[pos], 2 + total);
1899
1900         return isl_basic_map_div(bmap, k);
1901 error:
1902         isl_basic_map_free(bmap);
1903         return NULL;
1904 }
1905
1906 __isl_give isl_term *isl_upoly_foreach_term(__isl_keep struct isl_upoly *up,
1907         int (*fn)(__isl_take isl_term *term, void *user),
1908         __isl_take isl_term *term, void *user)
1909 {
1910         int i;
1911         struct isl_upoly_rec *rec;
1912
1913         if (!up || !term)
1914                 goto error;
1915
1916         if (isl_upoly_is_zero(up))
1917                 return term;
1918
1919         isl_assert(up->ctx, !isl_upoly_is_nan(up), goto error);
1920         isl_assert(up->ctx, !isl_upoly_is_infty(up), goto error);
1921         isl_assert(up->ctx, !isl_upoly_is_neginfty(up), goto error);
1922
1923         if (isl_upoly_is_cst(up)) {
1924                 struct isl_upoly_cst *cst;
1925                 cst = isl_upoly_as_cst(up);
1926                 if (!cst)
1927                         goto error;
1928                 term = isl_term_cow(term);
1929                 if (!term)
1930                         goto error;
1931                 isl_int_set(term->n, cst->n);
1932                 isl_int_set(term->d, cst->d);
1933                 if (fn(isl_term_copy(term), user) < 0)
1934                         goto error;
1935                 return term;
1936         }
1937
1938         rec = isl_upoly_as_rec(up);
1939         if (!rec)
1940                 goto error;
1941
1942         for (i = 0; i < rec->n; ++i) {
1943                 term = isl_term_cow(term);
1944                 if (!term)
1945                         goto error;
1946                 term->pow[up->var] = i;
1947                 term = isl_upoly_foreach_term(rec->p[i], fn, term, user);
1948                 if (!term)
1949                         goto error;
1950         }
1951         term->pow[up->var] = 0;
1952
1953         return term;
1954 error:
1955         isl_term_free(term);
1956         return NULL;
1957 }
1958
1959 int isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp,
1960         int (*fn)(__isl_take isl_term *term, void *user), void *user)
1961 {
1962         isl_term *term;
1963
1964         if (!qp)
1965                 return -1;
1966
1967         term = isl_term_alloc(isl_dim_copy(qp->dim), isl_mat_copy(qp->div));
1968         if (!term)
1969                 return -1;
1970
1971         term = isl_upoly_foreach_term(qp->upoly, fn, term, user);
1972
1973         isl_term_free(term);
1974
1975         return term ? 0 : -1;
1976 }
1977
1978 int isl_pw_qpolynomial_foreach_piece(__isl_keep isl_pw_qpolynomial *pwqp,
1979         int (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp,
1980                     void *user), void *user)
1981 {
1982         int i;
1983
1984         if (!pwqp)
1985                 return -1;
1986
1987         for (i = 0; i < pwqp->n; ++i)
1988                 if (fn(isl_set_copy(pwqp->p[i].set),
1989                                 isl_qpolynomial_copy(pwqp->p[i].qp), user) < 0)
1990                         return -1;
1991
1992         return 0;
1993 }
1994
1995 static int any_divs(__isl_keep isl_set *set)
1996 {
1997         int i;
1998
1999         if (!set)
2000                 return -1;
2001
2002         for (i = 0; i < set->n; ++i)
2003                 if (set->p[i]->n_div > 0)
2004                         return 1;
2005
2006         return 0;
2007 }
2008
2009 __isl_give isl_qpolynomial *isl_qpolynomial_lift(__isl_take isl_qpolynomial *qp,
2010         __isl_take isl_dim *dim)
2011 {
2012         if (!qp || !dim)
2013                 goto error;
2014
2015         if (isl_dim_equal(qp->dim, dim)) {
2016                 isl_dim_free(dim);
2017                 return qp;
2018         }
2019
2020         qp = isl_qpolynomial_cow(qp);
2021         if (!qp)
2022                 goto error;
2023
2024         if (qp->div->n_row) {
2025                 int i;
2026                 int extra;
2027                 unsigned total;
2028                 int *exp;
2029
2030                 extra = isl_dim_size(dim, isl_dim_set) -
2031                                 isl_dim_size(qp->dim, isl_dim_set);
2032                 total = isl_dim_total(qp->dim);
2033                 exp = isl_alloc_array(qp->div->ctx, int, qp->div->n_row);
2034                 if (!exp)
2035                         goto error;
2036                 for (i = 0; i < qp->div->n_row; ++i)
2037                         exp[i] = extra + i;
2038                 qp->upoly = expand(qp->upoly, exp, total);
2039                 free(exp);
2040                 if (!qp->upoly)
2041                         goto error;
2042                 qp->div = isl_mat_insert_cols(qp->div, 2 + total, extra);
2043                 if (!qp->div)
2044                         goto error;
2045                 for (i = 0; i < qp->div->n_row; ++i)
2046                         isl_seq_clr(qp->div->row[i] + 2 + total, extra);
2047         }
2048
2049         isl_dim_free(qp->dim);
2050         qp->dim = dim;
2051
2052         return qp;
2053 error:
2054         isl_dim_free(dim);
2055         isl_qpolynomial_free(qp);
2056         return NULL;
2057 }
2058
2059 static int foreach_lifted_subset(__isl_take isl_set *set,
2060         __isl_take isl_qpolynomial *qp,
2061         int (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp,
2062                     void *user), void *user)
2063 {
2064         int i;
2065
2066         if (!set || !qp)
2067                 goto error;
2068
2069         for (i = 0; i < set->n; ++i) {
2070                 isl_set *lift;
2071                 isl_qpolynomial *copy;
2072
2073                 lift = isl_set_from_basic_set(isl_basic_set_copy(set->p[i]));
2074                 lift = isl_set_lift(lift);
2075
2076                 copy = isl_qpolynomial_copy(qp);
2077                 copy = isl_qpolynomial_lift(copy, isl_set_get_dim(lift));
2078
2079                 if (fn(lift, copy, user) < 0)
2080                         goto error;
2081         }
2082
2083         isl_set_free(set);
2084         isl_qpolynomial_free(qp);
2085
2086         return 0;
2087 error:
2088         isl_set_free(set);
2089         isl_qpolynomial_free(qp);
2090         return -1;
2091 }
2092
2093 int isl_pw_qpolynomial_foreach_lifted_piece(__isl_keep isl_pw_qpolynomial *pwqp,
2094         int (*fn)(__isl_take isl_set *set, __isl_take isl_qpolynomial *qp,
2095                     void *user), void *user)
2096 {
2097         int i;
2098
2099         if (!pwqp)
2100                 return -1;
2101
2102         for (i = 0; i < pwqp->n; ++i) {
2103                 isl_set *set;
2104                 isl_qpolynomial *qp;
2105
2106                 set = isl_set_copy(pwqp->p[i].set);
2107                 qp = isl_qpolynomial_copy(pwqp->p[i].qp);
2108                 if (!any_divs(set)) {
2109                         if (fn(set, qp, user) < 0)
2110                                 return -1;
2111                         continue;
2112                 }
2113                 if (foreach_lifted_subset(set, qp, fn, user) < 0)
2114                         return -1;
2115         }
2116
2117         return 0;
2118 }
2119
2120 static __isl_give isl_qpolynomial_fold *qpolynomial_fold_alloc(
2121         enum isl_fold type, __isl_take isl_dim *dim, int n)
2122 {
2123         isl_qpolynomial_fold *fold;
2124
2125         if (!dim)
2126                 goto error;
2127
2128         isl_assert(dim->ctx, n >= 0, goto error);
2129         fold = isl_alloc(dim->ctx, struct isl_qpolynomial_fold,
2130                         sizeof(struct isl_qpolynomial_fold) +
2131                         (n - 1) * sizeof(struct isl_qpolynomial *));
2132         if (!fold)
2133                 goto error;
2134
2135         fold->ref = 1;
2136         fold->size = n;
2137         fold->n = 0;
2138         fold->type = type;
2139         fold->dim = dim;
2140
2141         return fold;
2142 error:
2143         isl_dim_free(dim);
2144         return NULL;
2145 }
2146
2147 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type,
2148         __isl_take isl_dim *dim)
2149 {
2150         return qpolynomial_fold_alloc(type, dim, 0);
2151 }
2152
2153 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_alloc(
2154         enum isl_fold type, __isl_take isl_qpolynomial *qp)
2155 {
2156         isl_qpolynomial_fold *fold;
2157
2158         if (!qp)
2159                 return NULL;
2160
2161         fold = qpolynomial_fold_alloc(type, isl_dim_copy(qp->dim), 1);
2162         if (!fold)
2163                 goto error;
2164
2165         fold->qp[0] = qp;
2166         fold->n++;
2167
2168         return fold;
2169 error:
2170         isl_qpolynomial_fold_free(fold);
2171         isl_qpolynomial_free(qp);
2172         return NULL;
2173 }
2174
2175 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy(
2176         __isl_keep isl_qpolynomial_fold *fold)
2177 {
2178         if (!fold)
2179                 return NULL;
2180
2181         fold->ref++;
2182         return fold;
2183 }
2184
2185 void isl_qpolynomial_fold_free(__isl_take isl_qpolynomial_fold *fold)
2186 {
2187         int i;
2188
2189         if (!fold)
2190                 return;
2191         if (--fold->ref > 0)
2192                 return;
2193
2194         for (i = 0; i < fold->n; ++i)
2195                 isl_qpolynomial_free(fold->qp[i]);
2196         isl_dim_free(fold->dim);
2197         free(fold);
2198 }
2199
2200 int isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold)
2201 {
2202         if (!fold)
2203                 return -1;
2204
2205         return fold->n == 0;
2206 }
2207
2208 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold(
2209         __isl_take isl_qpolynomial_fold *fold1,
2210         __isl_take isl_qpolynomial_fold *fold2)
2211 {
2212         int i;
2213         struct isl_qpolynomial_fold *res = NULL;
2214
2215         if (!fold1 || !fold2)
2216                 goto error;
2217
2218         isl_assert(fold1->dim->ctx, fold1->type == fold2->type, goto error);
2219         isl_assert(fold1->dim->ctx, isl_dim_equal(fold1->dim, fold2->dim),
2220                         goto error);
2221
2222         if (isl_qpolynomial_fold_is_empty(fold1)) {
2223                 isl_qpolynomial_fold_free(fold1);
2224                 return fold2;
2225         }
2226
2227         if (isl_qpolynomial_fold_is_empty(fold2)) {
2228                 isl_qpolynomial_fold_free(fold2);
2229                 return fold1;
2230         }
2231
2232         res = qpolynomial_fold_alloc(fold1->type, isl_dim_copy(fold1->dim),
2233                                         fold1->n + fold2->n);
2234         if (!res)
2235                 goto error;
2236
2237         for (i = 0; i < fold1->n; ++i) {
2238                 res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]);
2239                 if (!res->qp[res->n])
2240                         goto error;
2241                 res->n++;
2242         }
2243
2244         for (i = 0; i < fold2->n; ++i) {
2245                 res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]);
2246                 if (!res->qp[res->n])
2247                         goto error;
2248                 res->n++;
2249         }
2250
2251         isl_qpolynomial_fold_free(fold1);
2252         isl_qpolynomial_fold_free(fold2);
2253
2254         return res;
2255 error:
2256         isl_qpolynomial_fold_free(res);
2257         isl_qpolynomial_fold_free(fold1);
2258         isl_qpolynomial_fold_free(fold2);
2259         return NULL;
2260 }
2261
2262 __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_from_pw_qpolynomial(
2263         enum isl_fold type, __isl_take isl_pw_qpolynomial *pwqp)
2264 {
2265         int i;
2266         isl_pw_qpolynomial_fold *pwf;
2267
2268         if (!pwqp)
2269                 return NULL;
2270         
2271         pwf = isl_pw_qpolynomial_fold_alloc_(isl_dim_copy(pwqp->dim), pwqp->n);
2272
2273         for (i = 0; i < pwqp->n; ++i)
2274                 pwf = isl_pw_qpolynomial_fold_add_piece(pwf,
2275                         isl_set_copy(pwqp->p[i].set),
2276                         isl_qpolynomial_fold_alloc(type,
2277                                 isl_qpolynomial_copy(pwqp->p[i].qp)));
2278
2279         isl_pw_qpolynomial_free(pwqp);
2280
2281         return pwf;
2282 }
2283
2284 static int up_set_active(__isl_keep struct isl_upoly *up, int *active, int d)
2285 {
2286         struct isl_upoly_rec *rec;
2287         int i;
2288
2289         if (!up)
2290                 return -1;
2291
2292         if (isl_upoly_is_cst(up))
2293                 return 0;
2294
2295         if (up->var < d)
2296                 active[up->var] = 1;
2297
2298         rec = isl_upoly_as_rec(up);
2299         for (i = 0; i < rec->n; ++i)
2300                 if (up_set_active(rec->p[i], active, d) < 0)
2301                         return -1;
2302
2303         return 0;
2304 }
2305
2306 static int set_active(__isl_keep isl_qpolynomial *qp, int *active)
2307 {
2308         int i, j;
2309         int d = isl_dim_total(qp->dim);
2310
2311         for (i = 0; i < d; ++i)
2312                 for (j = 0; j < qp->div->n_row; ++j) {
2313                         if (isl_int_is_zero(qp->div->row[j][2 + i]))
2314                                 continue;
2315                         active[i] = 1;
2316                         break;
2317                 }
2318
2319         return up_set_active(qp->upoly, active, d);
2320 }
2321
2322 /* For each parameter or variable that does not appear in qp,
2323  * first eliminate the variable from all constraints and then set it to zero.
2324  */
2325 static __isl_give isl_set *fix_inactive(__isl_take isl_set *set,
2326         __isl_keep isl_qpolynomial *qp)
2327 {
2328         int *active = NULL;
2329         int i;
2330         int d;
2331         unsigned nparam;
2332         unsigned nvar;
2333
2334         if (!set || !qp)
2335                 goto error;
2336
2337         d = isl_dim_total(set->dim);
2338         active = isl_calloc_array(set->ctx, int, d);
2339         if (set_active(qp, active) < 0)
2340                 goto error;
2341
2342         for (i = 0; i < d; ++i)
2343                 if (!active[i])
2344                         break;
2345
2346         if (i == d) {
2347                 free(active);
2348                 return set;
2349         }
2350
2351         nparam = isl_dim_size(set->dim, isl_dim_param);
2352         nvar = isl_dim_size(set->dim, isl_dim_set);
2353         for (i = 0; i < nparam; ++i) {
2354                 if (active[i])
2355                         continue;
2356                 set = isl_set_eliminate(set, isl_dim_param, i, 1);
2357                 set = isl_set_fix_si(set, isl_dim_param, i, 0);
2358         }
2359         for (i = 0; i < nvar; ++i) {
2360                 if (active[i])
2361                         continue;
2362                 set = isl_set_eliminate(set, isl_dim_set, i, 1);
2363                 set = isl_set_fix_si(set, isl_dim_set, i, 0);
2364         }
2365
2366         free(active);
2367
2368         return set;
2369 error:
2370         free(active);
2371         isl_set_free(set);
2372         return NULL;
2373 }
2374
2375 struct isl_max_data {
2376         isl_qpolynomial *qp;
2377         int first;
2378         isl_qpolynomial *max;
2379 };
2380
2381 static int max_fn(__isl_take isl_point *pnt, void *user)
2382 {
2383         struct isl_max_data *data = (struct isl_max_data *)user;
2384         isl_qpolynomial *val;
2385
2386         val = isl_qpolynomial_eval(isl_qpolynomial_copy(data->qp), pnt);
2387         if (data->first) {
2388                 data->first = 0;
2389                 data->max = val;
2390         } else {
2391                 data->max = qpolynomial_max(data->max, val);
2392         }
2393
2394         return 0;
2395 }
2396
2397 static __isl_give isl_qpolynomial *guarded_qpolynomial_max(
2398         __isl_take isl_set *set, __isl_take isl_qpolynomial *qp)
2399 {
2400         struct isl_max_data data = { NULL, 1, NULL };
2401
2402         if (!set || !qp)
2403                 goto error;
2404
2405         if (isl_upoly_is_cst(qp->upoly)) {
2406                 isl_set_free(set);
2407                 return qp;
2408         }
2409
2410         set = fix_inactive(set, qp);
2411
2412         data.qp = qp;
2413         if (isl_set_foreach_point(set, max_fn, &data) < 0)
2414                 goto error;
2415
2416         isl_set_free(set);
2417         isl_qpolynomial_free(qp);
2418         return data.max;
2419 error:
2420         isl_set_free(set);
2421         isl_qpolynomial_free(qp);
2422         isl_qpolynomial_free(data.max);
2423         return NULL;
2424 }
2425
2426 /* Compute the maximal value attained by the piecewise quasipolynomial
2427  * on its domain or zero if the domain is empty.
2428  * In the worst case, the domain is scanned completely,
2429  * so the domain is assumed to be bounded.
2430  */
2431 __isl_give isl_qpolynomial *isl_pw_qpolynomial_max(
2432         __isl_take isl_pw_qpolynomial *pwqp)
2433 {
2434         int i;
2435         isl_qpolynomial *max;
2436
2437         if (!pwqp)
2438                 return NULL;
2439
2440         if (pwqp->n == 0) {
2441                 isl_dim *dim = isl_dim_copy(pwqp->dim);
2442                 isl_pw_qpolynomial_free(pwqp);
2443                 return isl_qpolynomial_zero(dim);
2444         }
2445
2446         max = guarded_qpolynomial_max(isl_set_copy(pwqp->p[0].set),
2447                                         isl_qpolynomial_copy(pwqp->p[0].qp));
2448         for (i = 1; i < pwqp->n; ++i) {
2449                 isl_qpolynomial *max_i;
2450                 max_i = guarded_qpolynomial_max(isl_set_copy(pwqp->p[i].set),
2451                                             isl_qpolynomial_copy(pwqp->p[i].qp));
2452                 max = qpolynomial_max(max, max_i);
2453         }
2454
2455         isl_pw_qpolynomial_free(pwqp);
2456         return max;
2457 }