isl_qpolynomial_move_dims: plug memory leak and fix reordering of divs
[platform/upstream/isl.git] / isl_polynomial.c
1 /*
2  * Copyright 2010      INRIA Saclay
3  *
4  * Use of this software is governed by the GNU LGPLv2.1 license
5  *
6  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
8  * 91893 Orsay, France 
9  */
10
11 #include <stdlib.h>
12 #include <isl_seq.h>
13 #include <isl_union_map_private.h>
14 #include <isl_polynomial_private.h>
15 #include <isl_point_private.h>
16 #include <isl_dim_private.h>
17 #include <isl_map_private.h>
18
19 static unsigned pos(__isl_keep isl_dim *dim, enum isl_dim_type type)
20 {
21         switch (type) {
22         case isl_dim_param:     return 0;
23         case isl_dim_in:        return dim->nparam;
24         case isl_dim_out:       return dim->nparam + dim->n_in;
25         default:                return 0;
26         }
27 }
28
29 int isl_upoly_is_cst(__isl_keep struct isl_upoly *up)
30 {
31         if (!up)
32                 return -1;
33
34         return up->var < 0;
35 }
36
37 __isl_keep struct isl_upoly_cst *isl_upoly_as_cst(__isl_keep struct isl_upoly *up)
38 {
39         if (!up)
40                 return NULL;
41
42         isl_assert(up->ctx, up->var < 0, return NULL);
43
44         return (struct isl_upoly_cst *)up;
45 }
46
47 __isl_keep struct isl_upoly_rec *isl_upoly_as_rec(__isl_keep struct isl_upoly *up)
48 {
49         if (!up)
50                 return NULL;
51
52         isl_assert(up->ctx, up->var >= 0, return NULL);
53
54         return (struct isl_upoly_rec *)up;
55 }
56
57 int isl_upoly_is_equal(__isl_keep struct isl_upoly *up1,
58         __isl_keep struct isl_upoly *up2)
59 {
60         int i;
61         struct isl_upoly_rec *rec1, *rec2;
62
63         if (!up1 || !up2)
64                 return -1;
65         if (up1 == up2)
66                 return 1;
67         if (up1->var != up2->var)
68                 return 0;
69         if (isl_upoly_is_cst(up1)) {
70                 struct isl_upoly_cst *cst1, *cst2;
71                 cst1 = isl_upoly_as_cst(up1);
72                 cst2 = isl_upoly_as_cst(up2);
73                 if (!cst1 || !cst2)
74                         return -1;
75                 return isl_int_eq(cst1->n, cst2->n) &&
76                        isl_int_eq(cst1->d, cst2->d);
77         }
78
79         rec1 = isl_upoly_as_rec(up1);
80         rec2 = isl_upoly_as_rec(up2);
81         if (!rec1 || !rec2)
82                 return -1;
83
84         if (rec1->n != rec2->n)
85                 return 0;
86
87         for (i = 0; i < rec1->n; ++i) {
88                 int eq = isl_upoly_is_equal(rec1->p[i], rec2->p[i]);
89                 if (eq < 0 || !eq)
90                         return eq;
91         }
92
93         return 1;
94 }
95
96 int isl_upoly_is_zero(__isl_keep struct isl_upoly *up)
97 {
98         struct isl_upoly_cst *cst;
99
100         if (!up)
101                 return -1;
102         if (!isl_upoly_is_cst(up))
103                 return 0;
104
105         cst = isl_upoly_as_cst(up);
106         if (!cst)
107                 return -1;
108
109         return isl_int_is_zero(cst->n) && isl_int_is_pos(cst->d);
110 }
111
112 int isl_upoly_sgn(__isl_keep struct isl_upoly *up)
113 {
114         struct isl_upoly_cst *cst;
115
116         if (!up)
117                 return 0;
118         if (!isl_upoly_is_cst(up))
119                 return 0;
120
121         cst = isl_upoly_as_cst(up);
122         if (!cst)
123                 return 0;
124
125         return isl_int_sgn(cst->n);
126 }
127
128 int isl_upoly_is_nan(__isl_keep struct isl_upoly *up)
129 {
130         struct isl_upoly_cst *cst;
131
132         if (!up)
133                 return -1;
134         if (!isl_upoly_is_cst(up))
135                 return 0;
136
137         cst = isl_upoly_as_cst(up);
138         if (!cst)
139                 return -1;
140
141         return isl_int_is_zero(cst->n) && isl_int_is_zero(cst->d);
142 }
143
144 int isl_upoly_is_infty(__isl_keep struct isl_upoly *up)
145 {
146         struct isl_upoly_cst *cst;
147
148         if (!up)
149                 return -1;
150         if (!isl_upoly_is_cst(up))
151                 return 0;
152
153         cst = isl_upoly_as_cst(up);
154         if (!cst)
155                 return -1;
156
157         return isl_int_is_pos(cst->n) && isl_int_is_zero(cst->d);
158 }
159
160 int isl_upoly_is_neginfty(__isl_keep struct isl_upoly *up)
161 {
162         struct isl_upoly_cst *cst;
163
164         if (!up)
165                 return -1;
166         if (!isl_upoly_is_cst(up))
167                 return 0;
168
169         cst = isl_upoly_as_cst(up);
170         if (!cst)
171                 return -1;
172
173         return isl_int_is_neg(cst->n) && isl_int_is_zero(cst->d);
174 }
175
176 int isl_upoly_is_one(__isl_keep struct isl_upoly *up)
177 {
178         struct isl_upoly_cst *cst;
179
180         if (!up)
181                 return -1;
182         if (!isl_upoly_is_cst(up))
183                 return 0;
184
185         cst = isl_upoly_as_cst(up);
186         if (!cst)
187                 return -1;
188
189         return isl_int_eq(cst->n, cst->d) && isl_int_is_pos(cst->d);
190 }
191
192 int isl_upoly_is_negone(__isl_keep struct isl_upoly *up)
193 {
194         struct isl_upoly_cst *cst;
195
196         if (!up)
197                 return -1;
198         if (!isl_upoly_is_cst(up))
199                 return 0;
200
201         cst = isl_upoly_as_cst(up);
202         if (!cst)
203                 return -1;
204
205         return isl_int_is_negone(cst->n) && isl_int_is_one(cst->d);
206 }
207
208 __isl_give struct isl_upoly_cst *isl_upoly_cst_alloc(struct isl_ctx *ctx)
209 {
210         struct isl_upoly_cst *cst;
211
212         cst = isl_alloc_type(ctx, struct isl_upoly_cst);
213         if (!cst)
214                 return NULL;
215
216         cst->up.ref = 1;
217         cst->up.ctx = ctx;
218         isl_ctx_ref(ctx);
219         cst->up.var = -1;
220
221         isl_int_init(cst->n);
222         isl_int_init(cst->d);
223
224         return cst;
225 }
226
227 __isl_give struct isl_upoly *isl_upoly_zero(struct isl_ctx *ctx)
228 {
229         struct isl_upoly_cst *cst;
230
231         cst = isl_upoly_cst_alloc(ctx);
232         if (!cst)
233                 return NULL;
234
235         isl_int_set_si(cst->n, 0);
236         isl_int_set_si(cst->d, 1);
237
238         return &cst->up;
239 }
240
241 __isl_give struct isl_upoly *isl_upoly_infty(struct isl_ctx *ctx)
242 {
243         struct isl_upoly_cst *cst;
244
245         cst = isl_upoly_cst_alloc(ctx);
246         if (!cst)
247                 return NULL;
248
249         isl_int_set_si(cst->n, 1);
250         isl_int_set_si(cst->d, 0);
251
252         return &cst->up;
253 }
254
255 __isl_give struct isl_upoly *isl_upoly_neginfty(struct isl_ctx *ctx)
256 {
257         struct isl_upoly_cst *cst;
258
259         cst = isl_upoly_cst_alloc(ctx);
260         if (!cst)
261                 return NULL;
262
263         isl_int_set_si(cst->n, -1);
264         isl_int_set_si(cst->d, 0);
265
266         return &cst->up;
267 }
268
269 __isl_give struct isl_upoly *isl_upoly_nan(struct isl_ctx *ctx)
270 {
271         struct isl_upoly_cst *cst;
272
273         cst = isl_upoly_cst_alloc(ctx);
274         if (!cst)
275                 return NULL;
276
277         isl_int_set_si(cst->n, 0);
278         isl_int_set_si(cst->d, 0);
279
280         return &cst->up;
281 }
282
283 __isl_give struct isl_upoly *isl_upoly_rat_cst(struct isl_ctx *ctx,
284         isl_int n, isl_int d)
285 {
286         struct isl_upoly_cst *cst;
287
288         cst = isl_upoly_cst_alloc(ctx);
289         if (!cst)
290                 return NULL;
291
292         isl_int_set(cst->n, n);
293         isl_int_set(cst->d, d);
294
295         return &cst->up;
296 }
297
298 __isl_give struct isl_upoly_rec *isl_upoly_alloc_rec(struct isl_ctx *ctx,
299         int var, int size)
300 {
301         struct isl_upoly_rec *rec;
302
303         isl_assert(ctx, var >= 0, return NULL);
304         isl_assert(ctx, size >= 0, return NULL);
305         rec = isl_calloc(ctx, struct isl_upoly_rec,
306                         sizeof(struct isl_upoly_rec) +
307                         (size - 1) * sizeof(struct isl_upoly *));
308         if (!rec)
309                 return NULL;
310
311         rec->up.ref = 1;
312         rec->up.ctx = ctx;
313         isl_ctx_ref(ctx);
314         rec->up.var = var;
315
316         rec->n = 0;
317         rec->size = size;
318
319         return rec;
320 }
321
322 __isl_give isl_qpolynomial *isl_qpolynomial_reset_dim(
323         __isl_take isl_qpolynomial *qp, __isl_take isl_dim *dim)
324 {
325         if (!qp || !dim)
326                 goto error;
327
328         isl_dim_free(qp->dim);
329         qp->dim = dim;
330
331         return qp;
332 error:
333         isl_qpolynomial_free(qp);
334         isl_dim_free(dim);
335         return NULL;
336 }
337
338 isl_ctx *isl_qpolynomial_get_ctx(__isl_keep isl_qpolynomial *qp)
339 {
340         return qp ? qp->dim->ctx : NULL;
341 }
342
343 __isl_give isl_dim *isl_qpolynomial_get_dim(__isl_keep isl_qpolynomial *qp)
344 {
345         return qp ? isl_dim_copy(qp->dim) : NULL;
346 }
347
348 unsigned isl_qpolynomial_dim(__isl_keep isl_qpolynomial *qp,
349         enum isl_dim_type type)
350 {
351         return qp ? isl_dim_size(qp->dim, type) : 0;
352 }
353
354 int isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp)
355 {
356         return qp ? isl_upoly_is_zero(qp->upoly) : -1;
357 }
358
359 int isl_qpolynomial_is_one(__isl_keep isl_qpolynomial *qp)
360 {
361         return qp ? isl_upoly_is_one(qp->upoly) : -1;
362 }
363
364 int isl_qpolynomial_is_nan(__isl_keep isl_qpolynomial *qp)
365 {
366         return qp ? isl_upoly_is_nan(qp->upoly) : -1;
367 }
368
369 int isl_qpolynomial_is_infty(__isl_keep isl_qpolynomial *qp)
370 {
371         return qp ? isl_upoly_is_infty(qp->upoly) : -1;
372 }
373
374 int isl_qpolynomial_is_neginfty(__isl_keep isl_qpolynomial *qp)
375 {
376         return qp ? isl_upoly_is_neginfty(qp->upoly) : -1;
377 }
378
379 int isl_qpolynomial_sgn(__isl_keep isl_qpolynomial *qp)
380 {
381         return qp ? isl_upoly_sgn(qp->upoly) : 0;
382 }
383
384 static void upoly_free_cst(__isl_take struct isl_upoly_cst *cst)
385 {
386         isl_int_clear(cst->n);
387         isl_int_clear(cst->d);
388 }
389
390 static void upoly_free_rec(__isl_take struct isl_upoly_rec *rec)
391 {
392         int i;
393
394         for (i = 0; i < rec->n; ++i)
395                 isl_upoly_free(rec->p[i]);
396 }
397
398 __isl_give struct isl_upoly *isl_upoly_copy(__isl_keep struct isl_upoly *up)
399 {
400         if (!up)
401                 return NULL;
402
403         up->ref++;
404         return up;
405 }
406
407 __isl_give struct isl_upoly *isl_upoly_dup_cst(__isl_keep struct isl_upoly *up)
408 {
409         struct isl_upoly_cst *cst;
410         struct isl_upoly_cst *dup;
411
412         cst = isl_upoly_as_cst(up);
413         if (!cst)
414                 return NULL;
415
416         dup = isl_upoly_as_cst(isl_upoly_zero(up->ctx));
417         if (!dup)
418                 return NULL;
419         isl_int_set(dup->n, cst->n);
420         isl_int_set(dup->d, cst->d);
421
422         return &dup->up;
423 }
424
425 __isl_give struct isl_upoly *isl_upoly_dup_rec(__isl_keep struct isl_upoly *up)
426 {
427         int i;
428         struct isl_upoly_rec *rec;
429         struct isl_upoly_rec *dup;
430
431         rec = isl_upoly_as_rec(up);
432         if (!rec)
433                 return NULL;
434
435         dup = isl_upoly_alloc_rec(up->ctx, up->var, rec->n);
436         if (!dup)
437                 return NULL;
438
439         for (i = 0; i < rec->n; ++i) {
440                 dup->p[i] = isl_upoly_copy(rec->p[i]);
441                 if (!dup->p[i])
442                         goto error;
443                 dup->n++;
444         }
445
446         return &dup->up;
447 error:
448         isl_upoly_free(&dup->up);
449         return NULL;
450 }
451
452 __isl_give struct isl_upoly *isl_upoly_dup(__isl_keep struct isl_upoly *up)
453 {
454         struct isl_upoly *dup;
455
456         if (!up)
457                 return NULL;
458
459         if (isl_upoly_is_cst(up))
460                 return isl_upoly_dup_cst(up);
461         else
462                 return isl_upoly_dup_rec(up);
463 }
464
465 __isl_give struct isl_upoly *isl_upoly_cow(__isl_take struct isl_upoly *up)
466 {
467         if (!up)
468                 return NULL;
469
470         if (up->ref == 1)
471                 return up;
472         up->ref--;
473         return isl_upoly_dup(up);
474 }
475
476 void isl_upoly_free(__isl_take struct isl_upoly *up)
477 {
478         if (!up)
479                 return;
480
481         if (--up->ref > 0)
482                 return;
483
484         if (up->var < 0)
485                 upoly_free_cst((struct isl_upoly_cst *)up);
486         else
487                 upoly_free_rec((struct isl_upoly_rec *)up);
488
489         isl_ctx_deref(up->ctx);
490         free(up);
491 }
492
493 static void isl_upoly_cst_reduce(__isl_keep struct isl_upoly_cst *cst)
494 {
495         isl_int gcd;
496
497         isl_int_init(gcd);
498         isl_int_gcd(gcd, cst->n, cst->d);
499         if (!isl_int_is_zero(gcd) && !isl_int_is_one(gcd)) {
500                 isl_int_divexact(cst->n, cst->n, gcd);
501                 isl_int_divexact(cst->d, cst->d, gcd);
502         }
503         isl_int_clear(gcd);
504 }
505
506 __isl_give struct isl_upoly *isl_upoly_sum_cst(__isl_take struct isl_upoly *up1,
507         __isl_take struct isl_upoly *up2)
508 {
509         struct isl_upoly_cst *cst1;
510         struct isl_upoly_cst *cst2;
511
512         up1 = isl_upoly_cow(up1);
513         if (!up1 || !up2)
514                 goto error;
515
516         cst1 = isl_upoly_as_cst(up1);
517         cst2 = isl_upoly_as_cst(up2);
518
519         if (isl_int_eq(cst1->d, cst2->d))
520                 isl_int_add(cst1->n, cst1->n, cst2->n);
521         else {
522                 isl_int_mul(cst1->n, cst1->n, cst2->d);
523                 isl_int_addmul(cst1->n, cst2->n, cst1->d);
524                 isl_int_mul(cst1->d, cst1->d, cst2->d);
525         }
526
527         isl_upoly_cst_reduce(cst1);
528
529         isl_upoly_free(up2);
530         return up1;
531 error:
532         isl_upoly_free(up1);
533         isl_upoly_free(up2);
534         return NULL;
535 }
536
537 static __isl_give struct isl_upoly *replace_by_zero(
538         __isl_take struct isl_upoly *up)
539 {
540         struct isl_ctx *ctx;
541
542         if (!up)
543                 return NULL;
544         ctx = up->ctx;
545         isl_upoly_free(up);
546         return isl_upoly_zero(ctx);
547 }
548
549 static __isl_give struct isl_upoly *replace_by_constant_term(
550         __isl_take struct isl_upoly *up)
551 {
552         struct isl_upoly_rec *rec;
553         struct isl_upoly *cst;
554
555         if (!up)
556                 return NULL;
557
558         rec = isl_upoly_as_rec(up);
559         if (!rec)
560                 goto error;
561         cst = isl_upoly_copy(rec->p[0]);
562         isl_upoly_free(up);
563         return cst;
564 error:
565         isl_upoly_free(up);
566         return NULL;
567 }
568
569 __isl_give struct isl_upoly *isl_upoly_sum(__isl_take struct isl_upoly *up1,
570         __isl_take struct isl_upoly *up2)
571 {
572         int i;
573         struct isl_upoly_rec *rec1, *rec2;
574
575         if (!up1 || !up2)
576                 goto error;
577
578         if (isl_upoly_is_nan(up1)) {
579                 isl_upoly_free(up2);
580                 return up1;
581         }
582
583         if (isl_upoly_is_nan(up2)) {
584                 isl_upoly_free(up1);
585                 return up2;
586         }
587
588         if (isl_upoly_is_zero(up1)) {
589                 isl_upoly_free(up1);
590                 return up2;
591         }
592
593         if (isl_upoly_is_zero(up2)) {
594                 isl_upoly_free(up2);
595                 return up1;
596         }
597
598         if (up1->var < up2->var)
599                 return isl_upoly_sum(up2, up1);
600
601         if (up2->var < up1->var) {
602                 struct isl_upoly_rec *rec;
603                 if (isl_upoly_is_infty(up2) || isl_upoly_is_neginfty(up2)) {
604                         isl_upoly_free(up1);
605                         return up2;
606                 }
607                 up1 = isl_upoly_cow(up1);
608                 rec = isl_upoly_as_rec(up1);
609                 if (!rec)
610                         goto error;
611                 rec->p[0] = isl_upoly_sum(rec->p[0], up2);
612                 if (rec->n == 1)
613                         up1 = replace_by_constant_term(up1);
614                 return up1;
615         }
616
617         if (isl_upoly_is_cst(up1))
618                 return isl_upoly_sum_cst(up1, up2);
619
620         rec1 = isl_upoly_as_rec(up1);
621         rec2 = isl_upoly_as_rec(up2);
622         if (!rec1 || !rec2)
623                 goto error;
624
625         if (rec1->n < rec2->n)
626                 return isl_upoly_sum(up2, up1);
627
628         up1 = isl_upoly_cow(up1);
629         rec1 = isl_upoly_as_rec(up1);
630         if (!rec1)
631                 goto error;
632
633         for (i = rec2->n - 1; i >= 0; --i) {
634                 rec1->p[i] = isl_upoly_sum(rec1->p[i],
635                                             isl_upoly_copy(rec2->p[i]));
636                 if (!rec1->p[i])
637                         goto error;
638                 if (i == rec1->n - 1 && isl_upoly_is_zero(rec1->p[i])) {
639                         isl_upoly_free(rec1->p[i]);
640                         rec1->n--;
641                 }
642         }
643
644         if (rec1->n == 0)
645                 up1 = replace_by_zero(up1);
646         else if (rec1->n == 1)
647                 up1 = replace_by_constant_term(up1);
648
649         isl_upoly_free(up2);
650
651         return up1;
652 error:
653         isl_upoly_free(up1);
654         isl_upoly_free(up2);
655         return NULL;
656 }
657
658 __isl_give struct isl_upoly *isl_upoly_neg_cst(__isl_take struct isl_upoly *up)
659 {
660         struct isl_upoly_cst *cst;
661
662         if (isl_upoly_is_zero(up))
663                 return up;
664
665         up = isl_upoly_cow(up);
666         if (!up)
667                 return NULL;
668
669         cst = isl_upoly_as_cst(up);
670
671         isl_int_neg(cst->n, cst->n);
672
673         return up;
674 }
675
676 __isl_give struct isl_upoly *isl_upoly_neg(__isl_take struct isl_upoly *up)
677 {
678         int i;
679         struct isl_upoly_rec *rec;
680
681         if (!up)
682                 return NULL;
683
684         if (isl_upoly_is_cst(up))
685                 return isl_upoly_neg_cst(up);
686
687         up = isl_upoly_cow(up);
688         rec = isl_upoly_as_rec(up);
689         if (!rec)
690                 goto error;
691
692         for (i = 0; i < rec->n; ++i) {
693                 rec->p[i] = isl_upoly_neg(rec->p[i]);
694                 if (!rec->p[i])
695                         goto error;
696         }
697
698         return up;
699 error:
700         isl_upoly_free(up);
701         return NULL;
702 }
703
704 __isl_give struct isl_upoly *isl_upoly_mul_cst(__isl_take struct isl_upoly *up1,
705         __isl_take struct isl_upoly *up2)
706 {
707         struct isl_upoly_cst *cst1;
708         struct isl_upoly_cst *cst2;
709
710         up1 = isl_upoly_cow(up1);
711         if (!up1 || !up2)
712                 goto error;
713
714         cst1 = isl_upoly_as_cst(up1);
715         cst2 = isl_upoly_as_cst(up2);
716
717         isl_int_mul(cst1->n, cst1->n, cst2->n);
718         isl_int_mul(cst1->d, cst1->d, cst2->d);
719
720         isl_upoly_cst_reduce(cst1);
721
722         isl_upoly_free(up2);
723         return up1;
724 error:
725         isl_upoly_free(up1);
726         isl_upoly_free(up2);
727         return NULL;
728 }
729
730 __isl_give struct isl_upoly *isl_upoly_mul_rec(__isl_take struct isl_upoly *up1,
731         __isl_take struct isl_upoly *up2)
732 {
733         struct isl_upoly_rec *rec1;
734         struct isl_upoly_rec *rec2;
735         struct isl_upoly_rec *res;
736         int i, j;
737         int size;
738
739         rec1 = isl_upoly_as_rec(up1);
740         rec2 = isl_upoly_as_rec(up2);
741         if (!rec1 || !rec2)
742                 goto error;
743         size = rec1->n + rec2->n - 1;
744         res = isl_upoly_alloc_rec(up1->ctx, up1->var, size);
745         if (!res)
746                 goto error;
747
748         for (i = 0; i < rec1->n; ++i) {
749                 res->p[i] = isl_upoly_mul(isl_upoly_copy(rec2->p[0]),
750                                             isl_upoly_copy(rec1->p[i]));
751                 if (!res->p[i])
752                         goto error;
753                 res->n++;
754         }
755         for (; i < size; ++i) {
756                 res->p[i] = isl_upoly_zero(up1->ctx);
757                 if (!res->p[i])
758                         goto error;
759                 res->n++;
760         }
761         for (i = 0; i < rec1->n; ++i) {
762                 for (j = 1; j < rec2->n; ++j) {
763                         struct isl_upoly *up;
764                         up = isl_upoly_mul(isl_upoly_copy(rec2->p[j]),
765                                             isl_upoly_copy(rec1->p[i]));
766                         res->p[i + j] = isl_upoly_sum(res->p[i + j], up);
767                         if (!res->p[i + j])
768                                 goto error;
769                 }
770         }
771
772         isl_upoly_free(up1);
773         isl_upoly_free(up2);
774
775         return &res->up;
776 error:
777         isl_upoly_free(up1);
778         isl_upoly_free(up2);
779         isl_upoly_free(&res->up);
780         return NULL;
781 }
782
783 __isl_give struct isl_upoly *isl_upoly_mul(__isl_take struct isl_upoly *up1,
784         __isl_take struct isl_upoly *up2)
785 {
786         if (!up1 || !up2)
787                 goto error;
788
789         if (isl_upoly_is_nan(up1)) {
790                 isl_upoly_free(up2);
791                 return up1;
792         }
793
794         if (isl_upoly_is_nan(up2)) {
795                 isl_upoly_free(up1);
796                 return up2;
797         }
798
799         if (isl_upoly_is_zero(up1)) {
800                 isl_upoly_free(up2);
801                 return up1;
802         }
803
804         if (isl_upoly_is_zero(up2)) {
805                 isl_upoly_free(up1);
806                 return up2;
807         }
808
809         if (isl_upoly_is_one(up1)) {
810                 isl_upoly_free(up1);
811                 return up2;
812         }
813
814         if (isl_upoly_is_one(up2)) {
815                 isl_upoly_free(up2);
816                 return up1;
817         }
818
819         if (up1->var < up2->var)
820                 return isl_upoly_mul(up2, up1);
821
822         if (up2->var < up1->var) {
823                 int i;
824                 struct isl_upoly_rec *rec;
825                 if (isl_upoly_is_infty(up2) || isl_upoly_is_neginfty(up2)) {
826                         isl_ctx *ctx = up1->ctx;
827                         isl_upoly_free(up1);
828                         isl_upoly_free(up2);
829                         return isl_upoly_nan(ctx);
830                 }
831                 up1 = isl_upoly_cow(up1);
832                 rec = isl_upoly_as_rec(up1);
833                 if (!rec)
834                         goto error;
835
836                 for (i = 0; i < rec->n; ++i) {
837                         rec->p[i] = isl_upoly_mul(rec->p[i],
838                                                     isl_upoly_copy(up2));
839                         if (!rec->p[i])
840                                 goto error;
841                 }
842                 isl_upoly_free(up2);
843                 return up1;
844         }
845
846         if (isl_upoly_is_cst(up1))
847                 return isl_upoly_mul_cst(up1, up2);
848
849         return isl_upoly_mul_rec(up1, up2);
850 error:
851         isl_upoly_free(up1);
852         isl_upoly_free(up2);
853         return NULL;
854 }
855
856 __isl_give isl_qpolynomial *isl_qpolynomial_alloc(__isl_take isl_dim *dim,
857         unsigned n_div, __isl_take struct isl_upoly *up)
858 {
859         struct isl_qpolynomial *qp = NULL;
860         unsigned total;
861
862         if (!dim || !up)
863                 goto error;
864
865         total = isl_dim_total(dim);
866
867         qp = isl_calloc_type(dim->ctx, struct isl_qpolynomial);
868         if (!qp)
869                 goto error;
870
871         qp->ref = 1;
872         qp->div = isl_mat_alloc(dim->ctx, n_div, 1 + 1 + total + n_div);
873         if (!qp->div)
874                 goto error;
875
876         qp->dim = dim;
877         qp->upoly = up;
878
879         return qp;
880 error:
881         isl_dim_free(dim);
882         isl_upoly_free(up);
883         isl_qpolynomial_free(qp);
884         return NULL;
885 }
886
887 __isl_give isl_qpolynomial *isl_qpolynomial_copy(__isl_keep isl_qpolynomial *qp)
888 {
889         if (!qp)
890                 return NULL;
891
892         qp->ref++;
893         return qp;
894 }
895
896 __isl_give isl_qpolynomial *isl_qpolynomial_dup(__isl_keep isl_qpolynomial *qp)
897 {
898         struct isl_qpolynomial *dup;
899
900         if (!qp)
901                 return NULL;
902
903         dup = isl_qpolynomial_alloc(isl_dim_copy(qp->dim), qp->div->n_row,
904                                     isl_upoly_copy(qp->upoly));
905         if (!dup)
906                 return NULL;
907         isl_mat_free(dup->div);
908         dup->div = isl_mat_copy(qp->div);
909         if (!dup->div)
910                 goto error;
911
912         return dup;
913 error:
914         isl_qpolynomial_free(dup);
915         return NULL;
916 }
917
918 __isl_give isl_qpolynomial *isl_qpolynomial_cow(__isl_take isl_qpolynomial *qp)
919 {
920         if (!qp)
921                 return NULL;
922
923         if (qp->ref == 1)
924                 return qp;
925         qp->ref--;
926         return isl_qpolynomial_dup(qp);
927 }
928
929 void isl_qpolynomial_free(__isl_take isl_qpolynomial *qp)
930 {
931         if (!qp)
932                 return;
933
934         if (--qp->ref > 0)
935                 return;
936
937         isl_dim_free(qp->dim);
938         isl_mat_free(qp->div);
939         isl_upoly_free(qp->upoly);
940
941         free(qp);
942 }
943
944 __isl_give struct isl_upoly *isl_upoly_pow(isl_ctx *ctx, int pos, int power)
945 {
946         int i;
947         struct isl_upoly *up;
948         struct isl_upoly_rec *rec;
949         struct isl_upoly_cst *cst;
950
951         rec = isl_upoly_alloc_rec(ctx, pos, 1 + power);
952         if (!rec)
953                 return NULL;
954         for (i = 0; i < 1 + power; ++i) {
955                 rec->p[i] = isl_upoly_zero(ctx);
956                 if (!rec->p[i])
957                         goto error;
958                 rec->n++;
959         }
960         cst = isl_upoly_as_cst(rec->p[power]);
961         isl_int_set_si(cst->n, 1);
962
963         return &rec->up;
964 error:
965         isl_upoly_free(&rec->up);
966         return NULL;
967 }
968
969 /* r array maps original positions to new positions.
970  */
971 static __isl_give struct isl_upoly *reorder(__isl_take struct isl_upoly *up,
972         int *r)
973 {
974         int i;
975         struct isl_upoly_rec *rec;
976         struct isl_upoly *base;
977         struct isl_upoly *res;
978
979         if (isl_upoly_is_cst(up))
980                 return up;
981
982         rec = isl_upoly_as_rec(up);
983         if (!rec)
984                 goto error;
985
986         isl_assert(up->ctx, rec->n >= 1, goto error);
987
988         base = isl_upoly_pow(up->ctx, r[up->var], 1);
989         res = reorder(isl_upoly_copy(rec->p[rec->n - 1]), r);
990
991         for (i = rec->n - 2; i >= 0; --i) {
992                 res = isl_upoly_mul(res, isl_upoly_copy(base));
993                 res = isl_upoly_sum(res, reorder(isl_upoly_copy(rec->p[i]), r));
994         }
995
996         isl_upoly_free(base);
997         isl_upoly_free(up);
998
999         return res;
1000 error:
1001         isl_upoly_free(up);
1002         return NULL;
1003 }
1004
1005 static int compatible_divs(__isl_keep isl_mat *div1, __isl_keep isl_mat *div2)
1006 {
1007         int n_row, n_col;
1008         int equal;
1009
1010         isl_assert(div1->ctx, div1->n_row >= div2->n_row &&
1011                                 div1->n_col >= div2->n_col, return -1);
1012
1013         if (div1->n_row == div2->n_row)
1014                 return isl_mat_is_equal(div1, div2);
1015
1016         n_row = div1->n_row;
1017         n_col = div1->n_col;
1018         div1->n_row = div2->n_row;
1019         div1->n_col = div2->n_col;
1020
1021         equal = isl_mat_is_equal(div1, div2);
1022
1023         div1->n_row = n_row;
1024         div1->n_col = n_col;
1025
1026         return equal;
1027 }
1028
1029 static void expand_row(__isl_keep isl_mat *dst, int d,
1030         __isl_keep isl_mat *src, int s, int *exp)
1031 {
1032         int i;
1033         unsigned c = src->n_col - src->n_row;
1034
1035         isl_seq_cpy(dst->row[d], src->row[s], c);
1036         isl_seq_clr(dst->row[d] + c, dst->n_col - c);
1037
1038         for (i = 0; i < s; ++i)
1039                 isl_int_set(dst->row[d][c + exp[i]], src->row[s][c + i]);
1040 }
1041
1042 static int cmp_row(__isl_keep isl_mat *div, int i, int j)
1043 {
1044         int li, lj;
1045
1046         li = isl_seq_last_non_zero(div->row[i], div->n_col);
1047         lj = isl_seq_last_non_zero(div->row[j], div->n_col);
1048
1049         if (li != lj)
1050                 return li - lj;
1051
1052         return isl_seq_cmp(div->row[i], div->row[j], div->n_col);
1053 }
1054
1055 struct isl_div_sort_info {
1056         isl_mat *div;
1057         int      row;
1058 };
1059
1060 static int div_sort_cmp(const void *p1, const void *p2)
1061 {
1062         const struct isl_div_sort_info *i1, *i2;
1063         i1 = (const struct isl_div_sort_info *) p1;
1064         i2 = (const struct isl_div_sort_info *) p2;
1065
1066         return cmp_row(i1->div, i1->row, i2->row);
1067 }
1068
1069 static __isl_give isl_qpolynomial *sort_divs(__isl_take isl_qpolynomial *qp)
1070 {
1071         int i;
1072         struct isl_div_sort_info *array = NULL;
1073         int *pos = NULL;
1074         int *reordering = NULL;
1075         unsigned div_pos;
1076
1077         if (!qp)
1078                 return NULL;
1079         if (qp->div->n_row <= 1)
1080                 return qp;
1081
1082         div_pos = isl_dim_total(qp->dim);
1083
1084         array = isl_alloc_array(qp->div->ctx, struct isl_div_sort_info,
1085                                 qp->div->n_row);
1086         pos = isl_alloc_array(qp->div->ctx, int, qp->div->n_row);
1087         reordering = isl_alloc_array(qp->div->ctx, int, qp->div->n_col - 2);
1088         if (!array || !pos || !reordering)
1089                 goto error;
1090
1091         for (i = 0; i < qp->div->n_row; ++i) {
1092                 array[i].div = qp->div;
1093                 array[i].row = i;
1094                 pos[i] = i;
1095         }
1096
1097         qsort(array, qp->div->n_row, sizeof(struct isl_div_sort_info),
1098                 div_sort_cmp);
1099
1100         for (i = 0; i < div_pos; ++i)
1101                 reordering[i] = i;
1102
1103         for (i = 0; i < qp->div->n_row; ++i)
1104                 reordering[div_pos + array[i].row] = div_pos + i;
1105
1106         for (i = 0; i < qp->div->n_row; ++i) {
1107                 int t;
1108                 if (pos[array[i].row] == i)
1109                         continue;
1110                 qp->div = isl_mat_cow(qp->div);
1111                 qp->div = isl_mat_swap_rows(qp->div, i, pos[array[i].row]);
1112                 t = pos[array[i].row];
1113                 pos[array[i].row] = pos[i];
1114                 pos[i] = t;
1115         }
1116
1117         qp->upoly = reorder(qp->upoly, reordering);
1118
1119         if (!qp->upoly || !qp->div)
1120                 goto error;
1121
1122         free(pos);
1123         free(array);
1124         free(reordering);
1125
1126         return qp;
1127 error:
1128         free(pos);
1129         free(array);
1130         free(reordering);
1131         isl_qpolynomial_free(qp);
1132         return NULL;
1133 }
1134
1135 static __isl_give isl_mat *merge_divs(__isl_keep isl_mat *div1,
1136         __isl_keep isl_mat *div2, int *exp1, int *exp2)
1137 {
1138         int i, j, k;
1139         isl_mat *div = NULL;
1140         unsigned d = div1->n_col - div1->n_row;
1141
1142         div = isl_mat_alloc(div1->ctx, 1 + div1->n_row + div2->n_row,
1143                                 d + div1->n_row + div2->n_row);
1144         if (!div)
1145                 return NULL;
1146
1147         for (i = 0, j = 0, k = 0; i < div1->n_row && j < div2->n_row; ++k) {
1148                 int cmp;
1149
1150                 expand_row(div, k, div1, i, exp1);
1151                 expand_row(div, k + 1, div2, j, exp2);
1152
1153                 cmp = cmp_row(div, k, k + 1);
1154                 if (cmp == 0) {
1155                         exp1[i++] = k;
1156                         exp2[j++] = k;
1157                 } else if (cmp < 0) {
1158                         exp1[i++] = k;
1159                 } else {
1160                         exp2[j++] = k;
1161                         isl_seq_cpy(div->row[k], div->row[k + 1], div->n_col);
1162                 }
1163         }
1164         for (; i < div1->n_row; ++i, ++k) {
1165                 expand_row(div, k, div1, i, exp1);
1166                 exp1[i] = k;
1167         }
1168         for (; j < div2->n_row; ++j, ++k) {
1169                 expand_row(div, k, div2, j, exp2);
1170                 exp2[j] = k;
1171         }
1172
1173         div->n_row = k;
1174         div->n_col = d + k;
1175
1176         return div;
1177 }
1178
1179 static __isl_give struct isl_upoly *expand(__isl_take struct isl_upoly *up,
1180         int *exp, int first)
1181 {
1182         int i;
1183         struct isl_upoly_rec *rec;
1184
1185         if (isl_upoly_is_cst(up))
1186                 return up;
1187
1188         if (up->var < first)
1189                 return up;
1190
1191         if (exp[up->var - first] == up->var - first)
1192                 return up;
1193
1194         up = isl_upoly_cow(up);
1195         if (!up)
1196                 goto error;
1197
1198         up->var = exp[up->var - first] + first;
1199
1200         rec = isl_upoly_as_rec(up);
1201         if (!rec)
1202                 goto error;
1203
1204         for (i = 0; i < rec->n; ++i) {
1205                 rec->p[i] = expand(rec->p[i], exp, first);
1206                 if (!rec->p[i])
1207                         goto error;
1208         }
1209
1210         return up;
1211 error:
1212         isl_upoly_free(up);
1213         return NULL;
1214 }
1215
1216 static __isl_give isl_qpolynomial *with_merged_divs(
1217         __isl_give isl_qpolynomial *(*fn)(__isl_take isl_qpolynomial *qp1,
1218                                           __isl_take isl_qpolynomial *qp2),
1219         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
1220 {
1221         int *exp1 = NULL;
1222         int *exp2 = NULL;
1223         isl_mat *div = NULL;
1224
1225         qp1 = isl_qpolynomial_cow(qp1);
1226         qp2 = isl_qpolynomial_cow(qp2);
1227
1228         if (!qp1 || !qp2)
1229                 goto error;
1230
1231         isl_assert(qp1->div->ctx, qp1->div->n_row >= qp2->div->n_row &&
1232                                 qp1->div->n_col >= qp2->div->n_col, goto error);
1233
1234         exp1 = isl_alloc_array(qp1->div->ctx, int, qp1->div->n_row);
1235         exp2 = isl_alloc_array(qp2->div->ctx, int, qp2->div->n_row);
1236         if (!exp1 || !exp2)
1237                 goto error;
1238
1239         div = merge_divs(qp1->div, qp2->div, exp1, exp2);
1240         if (!div)
1241                 goto error;
1242
1243         isl_mat_free(qp1->div);
1244         qp1->div = isl_mat_copy(div);
1245         isl_mat_free(qp2->div);
1246         qp2->div = isl_mat_copy(div);
1247
1248         qp1->upoly = expand(qp1->upoly, exp1, div->n_col - div->n_row - 2);
1249         qp2->upoly = expand(qp2->upoly, exp2, div->n_col - div->n_row - 2);
1250
1251         if (!qp1->upoly || !qp2->upoly)
1252                 goto error;
1253
1254         isl_mat_free(div);
1255         free(exp1);
1256         free(exp2);
1257
1258         return fn(qp1, qp2);
1259 error:
1260         isl_mat_free(div);
1261         free(exp1);
1262         free(exp2);
1263         isl_qpolynomial_free(qp1);
1264         isl_qpolynomial_free(qp2);
1265         return NULL;
1266 }
1267
1268 __isl_give isl_qpolynomial *isl_qpolynomial_add(__isl_take isl_qpolynomial *qp1,
1269         __isl_take isl_qpolynomial *qp2)
1270 {
1271         qp1 = isl_qpolynomial_cow(qp1);
1272
1273         if (!qp1 || !qp2)
1274                 goto error;
1275
1276         if (qp1->div->n_row < qp2->div->n_row)
1277                 return isl_qpolynomial_add(qp2, qp1);
1278
1279         isl_assert(qp1->dim->ctx, isl_dim_equal(qp1->dim, qp2->dim), goto error);
1280         if (!compatible_divs(qp1->div, qp2->div))
1281                 return with_merged_divs(isl_qpolynomial_add, qp1, qp2);
1282
1283         qp1->upoly = isl_upoly_sum(qp1->upoly, isl_upoly_copy(qp2->upoly));
1284         if (!qp1->upoly)
1285                 goto error;
1286
1287         isl_qpolynomial_free(qp2);
1288
1289         return qp1;
1290 error:
1291         isl_qpolynomial_free(qp1);
1292         isl_qpolynomial_free(qp2);
1293         return NULL;
1294 }
1295
1296 __isl_give isl_qpolynomial *isl_qpolynomial_sub(__isl_take isl_qpolynomial *qp1,
1297         __isl_take isl_qpolynomial *qp2)
1298 {
1299         return isl_qpolynomial_add(qp1, isl_qpolynomial_neg(qp2));
1300 }
1301
1302 __isl_give isl_qpolynomial *isl_qpolynomial_neg(__isl_take isl_qpolynomial *qp)
1303 {
1304         qp = isl_qpolynomial_cow(qp);
1305
1306         if (!qp)
1307                 return NULL;
1308
1309         qp->upoly = isl_upoly_neg(qp->upoly);
1310         if (!qp->upoly)
1311                 goto error;
1312
1313         return qp;
1314 error:
1315         isl_qpolynomial_free(qp);
1316         return NULL;
1317 }
1318
1319 __isl_give isl_qpolynomial *isl_qpolynomial_mul(__isl_take isl_qpolynomial *qp1,
1320         __isl_take isl_qpolynomial *qp2)
1321 {
1322         qp1 = isl_qpolynomial_cow(qp1);
1323
1324         if (!qp1 || !qp2)
1325                 goto error;
1326
1327         if (qp1->div->n_row < qp2->div->n_row)
1328                 return isl_qpolynomial_mul(qp2, qp1);
1329
1330         isl_assert(qp1->dim->ctx, isl_dim_equal(qp1->dim, qp2->dim), goto error);
1331         if (!compatible_divs(qp1->div, qp2->div))
1332                 return with_merged_divs(isl_qpolynomial_mul, qp1, qp2);
1333
1334         qp1->upoly = isl_upoly_mul(qp1->upoly, isl_upoly_copy(qp2->upoly));
1335         if (!qp1->upoly)
1336                 goto error;
1337
1338         isl_qpolynomial_free(qp2);
1339
1340         return qp1;
1341 error:
1342         isl_qpolynomial_free(qp1);
1343         isl_qpolynomial_free(qp2);
1344         return NULL;
1345 }
1346
1347 __isl_give isl_qpolynomial *isl_qpolynomial_zero(__isl_take isl_dim *dim)
1348 {
1349         return isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
1350 }
1351
1352 __isl_give isl_qpolynomial *isl_qpolynomial_infty(__isl_take isl_dim *dim)
1353 {
1354         return isl_qpolynomial_alloc(dim, 0, isl_upoly_infty(dim->ctx));
1355 }
1356
1357 __isl_give isl_qpolynomial *isl_qpolynomial_neginfty(__isl_take isl_dim *dim)
1358 {
1359         return isl_qpolynomial_alloc(dim, 0, isl_upoly_neginfty(dim->ctx));
1360 }
1361
1362 __isl_give isl_qpolynomial *isl_qpolynomial_nan(__isl_take isl_dim *dim)
1363 {
1364         return isl_qpolynomial_alloc(dim, 0, isl_upoly_nan(dim->ctx));
1365 }
1366
1367 __isl_give isl_qpolynomial *isl_qpolynomial_cst(__isl_take isl_dim *dim,
1368         isl_int v)
1369 {
1370         struct isl_qpolynomial *qp;
1371         struct isl_upoly_cst *cst;
1372
1373         qp = isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
1374         if (!qp)
1375                 return NULL;
1376
1377         cst = isl_upoly_as_cst(qp->upoly);
1378         isl_int_set(cst->n, v);
1379
1380         return qp;
1381 }
1382
1383 int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp,
1384         isl_int *n, isl_int *d)
1385 {
1386         struct isl_upoly_cst *cst;
1387
1388         if (!qp)
1389                 return -1;
1390
1391         if (!isl_upoly_is_cst(qp->upoly))
1392                 return 0;
1393
1394         cst = isl_upoly_as_cst(qp->upoly);
1395         if (!cst)
1396                 return -1;
1397
1398         if (n)
1399                 isl_int_set(*n, cst->n);
1400         if (d)
1401                 isl_int_set(*d, cst->d);
1402
1403         return 1;
1404 }
1405
1406 int isl_upoly_is_affine(__isl_keep struct isl_upoly *up)
1407 {
1408         int is_cst;
1409         struct isl_upoly_rec *rec;
1410
1411         if (!up)
1412                 return -1;
1413
1414         if (up->var < 0)
1415                 return 1;
1416
1417         rec = isl_upoly_as_rec(up);
1418         if (!rec)
1419                 return -1;
1420
1421         if (rec->n > 2)
1422                 return 0;
1423
1424         isl_assert(up->ctx, rec->n > 1, return -1);
1425
1426         is_cst = isl_upoly_is_cst(rec->p[1]);
1427         if (is_cst < 0)
1428                 return -1;
1429         if (!is_cst)
1430                 return 0;
1431
1432         return isl_upoly_is_affine(rec->p[0]);
1433 }
1434
1435 int isl_qpolynomial_is_affine(__isl_keep isl_qpolynomial *qp)
1436 {
1437         if (!qp)
1438                 return -1;
1439
1440         if (qp->div->n_row > 0)
1441                 return 0;
1442
1443         return isl_upoly_is_affine(qp->upoly);
1444 }
1445
1446 static void update_coeff(__isl_keep isl_vec *aff,
1447         __isl_keep struct isl_upoly_cst *cst, int pos)
1448 {
1449         isl_int gcd;
1450         isl_int f;
1451
1452         if (isl_int_is_zero(cst->n))
1453                 return;
1454
1455         isl_int_init(gcd);
1456         isl_int_init(f);
1457         isl_int_gcd(gcd, cst->d, aff->el[0]);
1458         isl_int_divexact(f, cst->d, gcd);
1459         isl_int_divexact(gcd, aff->el[0], gcd);
1460         isl_seq_scale(aff->el, aff->el, f, aff->size);
1461         isl_int_mul(aff->el[1 + pos], gcd, cst->n);
1462         isl_int_clear(gcd);
1463         isl_int_clear(f);
1464 }
1465
1466 int isl_upoly_update_affine(__isl_keep struct isl_upoly *up,
1467         __isl_keep isl_vec *aff)
1468 {
1469         struct isl_upoly_cst *cst;
1470         struct isl_upoly_rec *rec;
1471
1472         if (!up || !aff)
1473                 return -1;
1474
1475         if (up->var < 0) {
1476                 struct isl_upoly_cst *cst;
1477
1478                 cst = isl_upoly_as_cst(up);
1479                 if (!cst)
1480                         return -1;
1481                 update_coeff(aff, cst, 0);
1482                 return 0;
1483         }
1484
1485         rec = isl_upoly_as_rec(up);
1486         if (!rec)
1487                 return -1;
1488         isl_assert(up->ctx, rec->n == 2, return -1);
1489
1490         cst = isl_upoly_as_cst(rec->p[1]);
1491         if (!cst)
1492                 return -1;
1493         update_coeff(aff, cst, 1 + up->var);
1494
1495         return isl_upoly_update_affine(rec->p[0], aff);
1496 }
1497
1498 __isl_give isl_vec *isl_qpolynomial_extract_affine(
1499         __isl_keep isl_qpolynomial *qp)
1500 {
1501         isl_vec *aff;
1502         unsigned d;
1503
1504         if (!qp)
1505                 return NULL;
1506
1507         isl_assert(qp->div->ctx, qp->div->n_row == 0, return NULL);
1508         d = isl_dim_total(qp->dim);
1509         aff = isl_vec_alloc(qp->div->ctx, 2 + d);
1510         if (!aff)
1511                 return NULL;
1512
1513         isl_seq_clr(aff->el + 1, 1 + d);
1514         isl_int_set_si(aff->el[0], 1);
1515
1516         if (isl_upoly_update_affine(qp->upoly, aff) < 0)
1517                 goto error;
1518
1519         return aff;
1520 error:
1521         isl_vec_free(aff);
1522         return NULL;
1523 }
1524
1525 int isl_qpolynomial_is_equal(__isl_keep isl_qpolynomial *qp1,
1526         __isl_keep isl_qpolynomial *qp2)
1527 {
1528         if (!qp1 || !qp2)
1529                 return -1;
1530
1531         return isl_upoly_is_equal(qp1->upoly, qp2->upoly);
1532 }
1533
1534 static void upoly_update_den(__isl_keep struct isl_upoly *up, isl_int *d)
1535 {
1536         int i;
1537         struct isl_upoly_rec *rec;
1538
1539         if (isl_upoly_is_cst(up)) {
1540                 struct isl_upoly_cst *cst;
1541                 cst = isl_upoly_as_cst(up);
1542                 if (!cst)
1543                         return;
1544                 isl_int_lcm(*d, *d, cst->d);
1545                 return;
1546         }
1547
1548         rec = isl_upoly_as_rec(up);
1549         if (!rec)
1550                 return;
1551
1552         for (i = 0; i < rec->n; ++i)
1553                 upoly_update_den(rec->p[i], d);
1554 }
1555
1556 void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d)
1557 {
1558         isl_int_set_si(*d, 1);
1559         if (!qp)
1560                 return;
1561         upoly_update_den(qp->upoly, d);
1562 }
1563
1564 __isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_dim *dim,
1565         int pos, int power)
1566 {
1567         struct isl_ctx *ctx;
1568
1569         if (!dim)
1570                 return NULL;
1571
1572         ctx = dim->ctx;
1573
1574         return isl_qpolynomial_alloc(dim, 0, isl_upoly_pow(ctx, pos, power));
1575 }
1576
1577 __isl_give isl_qpolynomial *isl_qpolynomial_var(__isl_take isl_dim *dim,
1578         enum isl_dim_type type, unsigned pos)
1579 {
1580         if (!dim)
1581                 return NULL;
1582
1583         isl_assert(dim->ctx, isl_dim_size(dim, isl_dim_in) == 0, goto error);
1584         isl_assert(dim->ctx, pos < isl_dim_size(dim, type), goto error);
1585
1586         if (type == isl_dim_set)
1587                 pos += isl_dim_size(dim, isl_dim_param);
1588
1589         return isl_qpolynomial_pow(dim, pos, 1);
1590 error:
1591         isl_dim_free(dim);
1592         return NULL;
1593 }
1594
1595 __isl_give isl_qpolynomial *isl_qpolynomial_div_pow(__isl_take isl_div *div,
1596         int power)
1597 {
1598         struct isl_qpolynomial *qp = NULL;
1599         struct isl_upoly_rec *rec;
1600         struct isl_upoly_cst *cst;
1601         int i;
1602         int pos;
1603
1604         if (!div)
1605                 return NULL;
1606         isl_assert(div->ctx, div->bmap->n_div == 1, goto error);
1607
1608         pos = isl_dim_total(div->bmap->dim);
1609         rec = isl_upoly_alloc_rec(div->ctx, pos, 1 + power);
1610         qp = isl_qpolynomial_alloc(isl_basic_map_get_dim(div->bmap), 1,
1611                                    &rec->up);
1612         if (!qp)
1613                 goto error;
1614
1615         isl_seq_cpy(qp->div->row[0], div->line[0], qp->div->n_col - 1);
1616         isl_int_set_si(qp->div->row[0][qp->div->n_col - 1], 0);
1617
1618         for (i = 0; i < 1 + power; ++i) {
1619                 rec->p[i] = isl_upoly_zero(div->ctx);
1620                 if (!rec->p[i])
1621                         goto error;
1622                 rec->n++;
1623         }
1624         cst = isl_upoly_as_cst(rec->p[power]);
1625         isl_int_set_si(cst->n, 1);
1626
1627         isl_div_free(div);
1628
1629         return qp;
1630 error:
1631         isl_qpolynomial_free(qp);
1632         isl_div_free(div);
1633         return NULL;
1634 }
1635
1636 __isl_give isl_qpolynomial *isl_qpolynomial_div(__isl_take isl_div *div)
1637 {
1638         return isl_qpolynomial_div_pow(div, 1);
1639 }
1640
1641 __isl_give isl_qpolynomial *isl_qpolynomial_rat_cst(__isl_take isl_dim *dim,
1642         const isl_int n, const isl_int d)
1643 {
1644         struct isl_qpolynomial *qp;
1645         struct isl_upoly_cst *cst;
1646
1647         qp = isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
1648         if (!qp)
1649                 return NULL;
1650
1651         cst = isl_upoly_as_cst(qp->upoly);
1652         isl_int_set(cst->n, n);
1653         isl_int_set(cst->d, d);
1654
1655         return qp;
1656 }
1657
1658 static int up_set_active(__isl_keep struct isl_upoly *up, int *active, int d)
1659 {
1660         struct isl_upoly_rec *rec;
1661         int i;
1662
1663         if (!up)
1664                 return -1;
1665
1666         if (isl_upoly_is_cst(up))
1667                 return 0;
1668
1669         if (up->var < d)
1670                 active[up->var] = 1;
1671
1672         rec = isl_upoly_as_rec(up);
1673         for (i = 0; i < rec->n; ++i)
1674                 if (up_set_active(rec->p[i], active, d) < 0)
1675                         return -1;
1676
1677         return 0;
1678 }
1679
1680 static int set_active(__isl_keep isl_qpolynomial *qp, int *active)
1681 {
1682         int i, j;
1683         int d = isl_dim_total(qp->dim);
1684
1685         if (!qp || !active)
1686                 return -1;
1687
1688         for (i = 0; i < d; ++i)
1689                 for (j = 0; j < qp->div->n_row; ++j) {
1690                         if (isl_int_is_zero(qp->div->row[j][2 + i]))
1691                                 continue;
1692                         active[i] = 1;
1693                         break;
1694                 }
1695
1696         return up_set_active(qp->upoly, active, d);
1697 }
1698
1699 int isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp,
1700         enum isl_dim_type type, unsigned first, unsigned n)
1701 {
1702         int i;
1703         int *active = NULL;
1704         int involves = 0;
1705
1706         if (!qp)
1707                 return -1;
1708         if (n == 0)
1709                 return 0;
1710
1711         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
1712                         return -1);
1713         isl_assert(qp->dim->ctx, type == isl_dim_param ||
1714                                  type == isl_dim_set, return -1);
1715
1716         active = isl_calloc_array(set->ctx, int, isl_dim_total(qp->dim));
1717         if (set_active(qp, active) < 0)
1718                 goto error;
1719
1720         if (type == isl_dim_set)
1721                 first += isl_dim_size(qp->dim, isl_dim_param);
1722         for (i = 0; i < n; ++i)
1723                 if (active[first + i]) {
1724                         involves = 1;
1725                         break;
1726                 }
1727
1728         free(active);
1729
1730         return involves;
1731 error:
1732         free(active);
1733         return -1;
1734 }
1735
1736 __isl_give struct isl_upoly *isl_upoly_drop(__isl_take struct isl_upoly *up,
1737         unsigned first, unsigned n)
1738 {
1739         int i;
1740         struct isl_upoly_rec *rec;
1741
1742         if (!up)
1743                 return NULL;
1744         if (n == 0 || up->var < 0 || up->var < first)
1745                 return up;
1746         if (up->var < first + n) {
1747                 up = replace_by_constant_term(up);
1748                 return isl_upoly_drop(up, first, n);
1749         }
1750         up = isl_upoly_cow(up);
1751         if (!up)
1752                 return NULL;
1753         up->var -= n;
1754         rec = isl_upoly_as_rec(up);
1755         if (!rec)
1756                 goto error;
1757
1758         for (i = 0; i < rec->n; ++i) {
1759                 rec->p[i] = isl_upoly_drop(rec->p[i], first, n);
1760                 if (!rec->p[i])
1761                         goto error;
1762         }
1763
1764         return up;
1765 error:
1766         isl_upoly_free(up);
1767         return NULL;
1768 }
1769
1770 __isl_give isl_qpolynomial *isl_qpolynomial_drop_dims(
1771         __isl_take isl_qpolynomial *qp,
1772         enum isl_dim_type type, unsigned first, unsigned n)
1773 {
1774         if (!qp)
1775                 return NULL;
1776         if (n == 0 && !isl_dim_get_tuple_name(qp->dim, type))
1777                 return qp;
1778
1779         qp = isl_qpolynomial_cow(qp);
1780         if (!qp)
1781                 return NULL;
1782
1783         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
1784                         goto error);
1785         isl_assert(qp->dim->ctx, type == isl_dim_param ||
1786                                  type == isl_dim_set, goto error);
1787
1788         qp->dim = isl_dim_drop(qp->dim, type, first, n);
1789         if (!qp->dim)
1790                 goto error;
1791
1792         if (type == isl_dim_set)
1793                 first += isl_dim_size(qp->dim, isl_dim_param);
1794
1795         qp->div = isl_mat_drop_cols(qp->div, 2 + first, n);
1796         if (!qp->div)
1797                 goto error;
1798
1799         qp->upoly = isl_upoly_drop(qp->upoly, first, n);
1800         if (!qp->upoly)
1801                 goto error;
1802
1803         return qp;
1804 error:
1805         isl_qpolynomial_free(qp);
1806         return NULL;
1807 }
1808
1809 #undef PW
1810 #define PW isl_pw_qpolynomial
1811 #undef EL
1812 #define EL isl_qpolynomial
1813 #undef IS_ZERO
1814 #define IS_ZERO is_zero
1815 #undef FIELD
1816 #define FIELD qp
1817 #undef ADD
1818 #define ADD(d,e1,e2)    isl_qpolynomial_add(e1,e2) 
1819
1820 #include <isl_pw_templ.c>
1821
1822 #undef UNION
1823 #define UNION isl_union_pw_qpolynomial
1824 #undef PART
1825 #define PART isl_pw_qpolynomial
1826 #undef PARTS
1827 #define PARTS pw_qpolynomial
1828
1829 #include <isl_union_templ.c>
1830
1831 int isl_pw_qpolynomial_is_one(__isl_keep isl_pw_qpolynomial *pwqp)
1832 {
1833         if (!pwqp)
1834                 return -1;
1835
1836         if (pwqp->n != -1)
1837                 return 0;
1838
1839         if (!isl_set_fast_is_universe(pwqp->p[0].set))
1840                 return 0;
1841
1842         return isl_qpolynomial_is_one(pwqp->p[0].qp);
1843 }
1844
1845 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul(
1846         __isl_take isl_pw_qpolynomial *pwqp1,
1847         __isl_take isl_pw_qpolynomial *pwqp2)
1848 {
1849         int i, j, n;
1850         struct isl_pw_qpolynomial *res;
1851         isl_set *set;
1852
1853         if (!pwqp1 || !pwqp2)
1854                 goto error;
1855
1856         isl_assert(pwqp1->dim->ctx, isl_dim_equal(pwqp1->dim, pwqp2->dim),
1857                         goto error);
1858
1859         if (isl_pw_qpolynomial_is_zero(pwqp1)) {
1860                 isl_pw_qpolynomial_free(pwqp2);
1861                 return pwqp1;
1862         }
1863
1864         if (isl_pw_qpolynomial_is_zero(pwqp2)) {
1865                 isl_pw_qpolynomial_free(pwqp1);
1866                 return pwqp2;
1867         }
1868
1869         if (isl_pw_qpolynomial_is_one(pwqp1)) {
1870                 isl_pw_qpolynomial_free(pwqp1);
1871                 return pwqp2;
1872         }
1873
1874         if (isl_pw_qpolynomial_is_one(pwqp2)) {
1875                 isl_pw_qpolynomial_free(pwqp2);
1876                 return pwqp1;
1877         }
1878
1879         n = pwqp1->n * pwqp2->n;
1880         res = isl_pw_qpolynomial_alloc_(isl_dim_copy(pwqp1->dim), n);
1881
1882         for (i = 0; i < pwqp1->n; ++i) {
1883                 for (j = 0; j < pwqp2->n; ++j) {
1884                         struct isl_set *common;
1885                         struct isl_qpolynomial *prod;
1886                         common = isl_set_intersect(isl_set_copy(pwqp1->p[i].set),
1887                                                 isl_set_copy(pwqp2->p[j].set));
1888                         if (isl_set_fast_is_empty(common)) {
1889                                 isl_set_free(common);
1890                                 continue;
1891                         }
1892
1893                         prod = isl_qpolynomial_mul(
1894                                 isl_qpolynomial_copy(pwqp1->p[i].qp),
1895                                 isl_qpolynomial_copy(pwqp2->p[j].qp));
1896
1897                         res = isl_pw_qpolynomial_add_piece(res, common, prod);
1898                 }
1899         }
1900
1901         isl_pw_qpolynomial_free(pwqp1);
1902         isl_pw_qpolynomial_free(pwqp2);
1903
1904         return res;
1905 error:
1906         isl_pw_qpolynomial_free(pwqp1);
1907         isl_pw_qpolynomial_free(pwqp2);
1908         return NULL;
1909 }
1910
1911 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg(
1912         __isl_take isl_pw_qpolynomial *pwqp)
1913 {
1914         int i, j, n;
1915         struct isl_pw_qpolynomial *res;
1916         isl_set *set;
1917
1918         if (!pwqp)
1919                 return NULL;
1920
1921         if (isl_pw_qpolynomial_is_zero(pwqp))
1922                 return pwqp;
1923
1924         pwqp = isl_pw_qpolynomial_cow(pwqp);
1925
1926         for (i = 0; i < pwqp->n; ++i) {
1927                 pwqp->p[i].qp = isl_qpolynomial_neg(pwqp->p[i].qp);
1928                 if (!pwqp->p[i].qp)
1929                         goto error;
1930         }
1931
1932         return pwqp;
1933 error:
1934         isl_pw_qpolynomial_free(pwqp);
1935         return NULL;
1936 }
1937
1938 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub(
1939         __isl_take isl_pw_qpolynomial *pwqp1,
1940         __isl_take isl_pw_qpolynomial *pwqp2)
1941 {
1942         return isl_pw_qpolynomial_add(pwqp1, isl_pw_qpolynomial_neg(pwqp2));
1943 }
1944
1945 __isl_give struct isl_upoly *isl_upoly_eval(
1946         __isl_take struct isl_upoly *up, __isl_take isl_vec *vec)
1947 {
1948         int i;
1949         struct isl_upoly_rec *rec;
1950         struct isl_upoly *res;
1951         struct isl_upoly *base;
1952
1953         if (isl_upoly_is_cst(up)) {
1954                 isl_vec_free(vec);
1955                 return up;
1956         }
1957
1958         rec = isl_upoly_as_rec(up);
1959         if (!rec)
1960                 goto error;
1961
1962         isl_assert(up->ctx, rec->n >= 1, goto error);
1963
1964         base = isl_upoly_rat_cst(up->ctx, vec->el[1 + up->var], vec->el[0]);
1965
1966         res = isl_upoly_eval(isl_upoly_copy(rec->p[rec->n - 1]),
1967                                 isl_vec_copy(vec));
1968
1969         for (i = rec->n - 2; i >= 0; --i) {
1970                 res = isl_upoly_mul(res, isl_upoly_copy(base));
1971                 res = isl_upoly_sum(res, 
1972                             isl_upoly_eval(isl_upoly_copy(rec->p[i]),
1973                                                             isl_vec_copy(vec)));
1974         }
1975
1976         isl_upoly_free(base);
1977         isl_upoly_free(up);
1978         isl_vec_free(vec);
1979         return res;
1980 error:
1981         isl_upoly_free(up);
1982         isl_vec_free(vec);
1983         return NULL;
1984 }
1985
1986 __isl_give isl_qpolynomial *isl_qpolynomial_eval(
1987         __isl_take isl_qpolynomial *qp, __isl_take isl_point *pnt)
1988 {
1989         isl_vec *ext;
1990         struct isl_upoly *up;
1991         isl_dim *dim;
1992
1993         if (!qp || !pnt)
1994                 goto error;
1995         isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, qp->dim), goto error);
1996
1997         if (qp->div->n_row == 0)
1998                 ext = isl_vec_copy(pnt->vec);
1999         else {
2000                 int i;
2001                 unsigned dim = isl_dim_total(qp->dim);
2002                 ext = isl_vec_alloc(qp->dim->ctx, 1 + dim + qp->div->n_row);
2003                 if (!ext)
2004                         goto error;
2005
2006                 isl_seq_cpy(ext->el, pnt->vec->el, pnt->vec->size);
2007                 for (i = 0; i < qp->div->n_row; ++i) {
2008                         isl_seq_inner_product(qp->div->row[i] + 1, ext->el,
2009                                                 1 + dim + i, &ext->el[1+dim+i]);
2010                         isl_int_fdiv_q(ext->el[1+dim+i], ext->el[1+dim+i],
2011                                         qp->div->row[i][0]);
2012                 }
2013         }
2014
2015         up = isl_upoly_eval(isl_upoly_copy(qp->upoly), ext);
2016         if (!up)
2017                 goto error;
2018
2019         dim = isl_dim_copy(qp->dim);
2020         isl_qpolynomial_free(qp);
2021         isl_point_free(pnt);
2022
2023         return isl_qpolynomial_alloc(dim, 0, up);
2024 error:
2025         isl_qpolynomial_free(qp);
2026         isl_point_free(pnt);
2027         return NULL;
2028 }
2029
2030 int isl_upoly_cmp(__isl_keep struct isl_upoly_cst *cst1,
2031         __isl_keep struct isl_upoly_cst *cst2)
2032 {
2033         int cmp;
2034         isl_int t;
2035         isl_int_init(t);
2036         isl_int_mul(t, cst1->n, cst2->d);
2037         isl_int_submul(t, cst2->n, cst1->d);
2038         cmp = isl_int_sgn(t);
2039         isl_int_clear(t);
2040         return cmp;
2041 }
2042
2043 int isl_qpolynomial_le_cst(__isl_keep isl_qpolynomial *qp1,
2044         __isl_keep isl_qpolynomial *qp2)
2045 {
2046         struct isl_upoly_cst *cst1, *cst2;
2047
2048         if (!qp1 || !qp2)
2049                 return -1;
2050         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), return -1);
2051         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), return -1);
2052         if (isl_qpolynomial_is_nan(qp1))
2053                 return -1;
2054         if (isl_qpolynomial_is_nan(qp2))
2055                 return -1;
2056         cst1 = isl_upoly_as_cst(qp1->upoly);
2057         cst2 = isl_upoly_as_cst(qp2->upoly);
2058
2059         return isl_upoly_cmp(cst1, cst2) <= 0;
2060 }
2061
2062 __isl_give isl_qpolynomial *isl_qpolynomial_min_cst(
2063         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
2064 {
2065         struct isl_upoly_cst *cst1, *cst2;
2066         int cmp;
2067
2068         if (!qp1 || !qp2)
2069                 goto error;
2070         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
2071         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
2072         cst1 = isl_upoly_as_cst(qp1->upoly);
2073         cst2 = isl_upoly_as_cst(qp2->upoly);
2074         cmp = isl_upoly_cmp(cst1, cst2);
2075
2076         if (cmp <= 0) {
2077                 isl_qpolynomial_free(qp2);
2078         } else {
2079                 isl_qpolynomial_free(qp1);
2080                 qp1 = qp2;
2081         }
2082         return qp1;
2083 error:
2084         isl_qpolynomial_free(qp1);
2085         isl_qpolynomial_free(qp2);
2086         return NULL;
2087 }
2088
2089 __isl_give isl_qpolynomial *isl_qpolynomial_max_cst(
2090         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
2091 {
2092         struct isl_upoly_cst *cst1, *cst2;
2093         int cmp;
2094
2095         if (!qp1 || !qp2)
2096                 goto error;
2097         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
2098         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
2099         cst1 = isl_upoly_as_cst(qp1->upoly);
2100         cst2 = isl_upoly_as_cst(qp2->upoly);
2101         cmp = isl_upoly_cmp(cst1, cst2);
2102
2103         if (cmp >= 0) {
2104                 isl_qpolynomial_free(qp2);
2105         } else {
2106                 isl_qpolynomial_free(qp1);
2107                 qp1 = qp2;
2108         }
2109         return qp1;
2110 error:
2111         isl_qpolynomial_free(qp1);
2112         isl_qpolynomial_free(qp2);
2113         return NULL;
2114 }
2115
2116 __isl_give isl_qpolynomial *isl_qpolynomial_insert_dims(
2117         __isl_take isl_qpolynomial *qp, enum isl_dim_type type,
2118         unsigned first, unsigned n)
2119 {
2120         unsigned total;
2121         unsigned g_pos;
2122         int *exp;
2123
2124         if (n == 0)
2125                 return qp;
2126
2127         qp = isl_qpolynomial_cow(qp);
2128         if (!qp)
2129                 return NULL;
2130
2131         isl_assert(qp->div->ctx, first <= isl_dim_size(qp->dim, type),
2132                     goto error);
2133
2134         g_pos = pos(qp->dim, type) + first;
2135
2136         qp->div = isl_mat_insert_cols(qp->div, 2 + g_pos, n);
2137         if (!qp->div)
2138                 goto error;
2139
2140         total = qp->div->n_col - 2;
2141         if (total > g_pos) {
2142                 int i;
2143                 exp = isl_alloc_array(qp->div->ctx, int, total - g_pos);
2144                 if (!exp)
2145                         goto error;
2146                 for (i = 0; i < total - g_pos; ++i)
2147                         exp[i] = i + n;
2148                 qp->upoly = expand(qp->upoly, exp, g_pos);
2149                 free(exp);
2150                 if (!qp->upoly)
2151                         goto error;
2152         }
2153
2154         qp->dim = isl_dim_insert(qp->dim, type, first, n);
2155         if (!qp->dim)
2156                 goto error;
2157
2158         return qp;
2159 error:
2160         isl_qpolynomial_free(qp);
2161         return NULL;
2162 }
2163
2164 __isl_give isl_qpolynomial *isl_qpolynomial_add_dims(
2165         __isl_take isl_qpolynomial *qp, enum isl_dim_type type, unsigned n)
2166 {
2167         unsigned pos;
2168
2169         pos = isl_qpolynomial_dim(qp, type);
2170
2171         return isl_qpolynomial_insert_dims(qp, type, pos, n);
2172 }
2173
2174 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_insert_dims(
2175         __isl_take isl_pw_qpolynomial *pwqp, enum isl_dim_type type,
2176         unsigned first, unsigned n)
2177 {
2178         int i;
2179
2180         if (n == 0)
2181                 return pwqp;
2182
2183         pwqp = isl_pw_qpolynomial_cow(pwqp);
2184         if (!pwqp)
2185                 return NULL;
2186
2187         pwqp->dim = isl_dim_insert(pwqp->dim, type, first, n);
2188         if (!pwqp->dim)
2189                 goto error;
2190
2191         for (i = 0; i < pwqp->n; ++i) {
2192                 pwqp->p[i].set = isl_set_insert(pwqp->p[i].set, type, first, n);
2193                 if (!pwqp->p[i].set)
2194                         goto error;
2195                 pwqp->p[i].qp = isl_qpolynomial_insert_dims(pwqp->p[i].qp,
2196                                                                 type, first, n);
2197                 if (!pwqp->p[i].qp)
2198                         goto error;
2199         }
2200
2201         return pwqp;
2202 error:
2203         isl_pw_qpolynomial_free(pwqp);
2204         return NULL;
2205 }
2206
2207 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_dims(
2208         __isl_take isl_pw_qpolynomial *pwqp,
2209         enum isl_dim_type type, unsigned n)
2210 {
2211         unsigned pos;
2212
2213         pos = isl_pw_qpolynomial_dim(pwqp, type);
2214
2215         return isl_pw_qpolynomial_insert_dims(pwqp, type, pos, n);
2216 }
2217
2218 static int *reordering_move(isl_ctx *ctx,
2219         unsigned len, unsigned dst, unsigned src, unsigned n)
2220 {
2221         int i;
2222         int *reordering;
2223
2224         reordering = isl_alloc_array(ctx, int, len);
2225         if (!reordering)
2226                 return NULL;
2227
2228         if (dst <= src) {
2229                 for (i = 0; i < dst; ++i)
2230                         reordering[i] = i;
2231                 for (i = 0; i < n; ++i)
2232                         reordering[src + i] = dst + i;
2233                 for (i = 0; i < src - dst; ++i)
2234                         reordering[dst + i] = dst + n + i;
2235                 for (i = 0; i < len - src - n; ++i)
2236                         reordering[src + n + i] = src + n + i;
2237         } else {
2238                 for (i = 0; i < src; ++i)
2239                         reordering[i] = i;
2240                 for (i = 0; i < n; ++i)
2241                         reordering[src + i] = dst + i;
2242                 for (i = 0; i < dst - src; ++i)
2243                         reordering[src + n + i] = src + i;
2244                 for (i = 0; i < len - dst - n; ++i)
2245                         reordering[dst + n + i] = dst + n + i;
2246         }
2247
2248         return reordering;
2249 }
2250
2251 __isl_give isl_qpolynomial *isl_qpolynomial_move_dims(
2252         __isl_take isl_qpolynomial *qp,
2253         enum isl_dim_type dst_type, unsigned dst_pos,
2254         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2255 {
2256         unsigned g_dst_pos;
2257         unsigned g_src_pos;
2258         int *reordering;
2259
2260         qp = isl_qpolynomial_cow(qp);
2261         if (!qp)
2262                 return NULL;
2263
2264         isl_assert(qp->dim->ctx, src_pos + n <= isl_dim_size(qp->dim, src_type),
2265                 goto error);
2266
2267         g_dst_pos = pos(qp->dim, dst_type) + dst_pos;
2268         g_src_pos = pos(qp->dim, src_type) + src_pos;
2269         if (dst_type > src_type)
2270                 g_dst_pos -= n;
2271
2272         qp->div = isl_mat_move_cols(qp->div, 2 + g_dst_pos, 2 + g_src_pos, n);
2273         if (!qp->div)
2274                 goto error;
2275         qp = sort_divs(qp);
2276         if (!qp)
2277                 goto error;
2278
2279         reordering = reordering_move(qp->dim->ctx,
2280                                 qp->div->n_col - 2, g_dst_pos, g_src_pos, n);
2281         if (!reordering)
2282                 goto error;
2283
2284         qp->upoly = reorder(qp->upoly, reordering);
2285         free(reordering);
2286         if (!qp->upoly)
2287                 goto error;
2288
2289         qp->dim = isl_dim_move(qp->dim, dst_type, dst_pos, src_type, src_pos, n);
2290         if (!qp->dim)
2291                 goto error;
2292
2293         return qp;
2294 error:
2295         isl_qpolynomial_free(qp);
2296         return NULL;
2297 }
2298
2299 __isl_give struct isl_upoly *isl_upoly_from_affine(isl_ctx *ctx, isl_int *f,
2300         isl_int denom, unsigned len)
2301 {
2302         int i;
2303         struct isl_upoly *up;
2304
2305         isl_assert(ctx, len >= 1, return NULL);
2306
2307         up = isl_upoly_rat_cst(ctx, f[0], denom);
2308         for (i = 0; i < len - 1; ++i) {
2309                 struct isl_upoly *t;
2310                 struct isl_upoly *c;
2311
2312                 if (isl_int_is_zero(f[1 + i]))
2313                         continue;
2314
2315                 c = isl_upoly_rat_cst(ctx, f[1 + i], denom);
2316                 t = isl_upoly_pow(ctx, i, 1);
2317                 t = isl_upoly_mul(c, t);
2318                 up = isl_upoly_sum(up, t);
2319         }
2320
2321         return up;
2322 }
2323
2324 __isl_give isl_qpolynomial *isl_qpolynomial_from_affine(__isl_take isl_dim *dim,
2325         isl_int *f, isl_int denom)
2326 {
2327         struct isl_upoly *up;
2328
2329         if (!dim)
2330                 return NULL;
2331
2332         up = isl_upoly_from_affine(dim->ctx, f, denom, 1 + isl_dim_total(dim));
2333
2334         return isl_qpolynomial_alloc(dim, 0, up);
2335 }
2336
2337 __isl_give isl_qpolynomial *isl_qpolynomial_from_constraint(
2338         __isl_take isl_constraint *c, enum isl_dim_type type, unsigned pos)
2339 {
2340         isl_int denom;
2341         isl_dim *dim;
2342         struct isl_upoly *up;
2343         isl_qpolynomial *qp;
2344         int sgn;
2345
2346         if (!c)
2347                 return NULL;
2348
2349         isl_int_init(denom);
2350
2351         isl_constraint_get_coefficient(c, type, pos, &denom);
2352         isl_constraint_set_coefficient(c, type, pos, c->ctx->zero);
2353         sgn = isl_int_sgn(denom);
2354         isl_int_abs(denom, denom);
2355         up = isl_upoly_from_affine(c->ctx, c->line[0], denom,
2356                                         1 + isl_constraint_dim(c, isl_dim_all));
2357         if (sgn < 0)
2358                 isl_int_neg(denom, denom);
2359         isl_constraint_set_coefficient(c, type, pos, denom);
2360
2361         dim = isl_dim_copy(c->bmap->dim);
2362
2363         isl_int_clear(denom);
2364         isl_constraint_free(c);
2365
2366         qp = isl_qpolynomial_alloc(dim, 0, up);
2367         if (sgn > 0)
2368                 qp = isl_qpolynomial_neg(qp);
2369         return qp;
2370 }
2371
2372 __isl_give struct isl_upoly *isl_upoly_subs(__isl_take struct isl_upoly *up,
2373         unsigned first, unsigned n, __isl_keep struct isl_upoly **subs)
2374 {
2375         int i;
2376         struct isl_upoly_rec *rec;
2377         struct isl_upoly *base, *res;
2378
2379         if (!up)
2380                 return NULL;
2381
2382         if (isl_upoly_is_cst(up))
2383                 return up;
2384
2385         if (up->var < first)
2386                 return up;
2387
2388         rec = isl_upoly_as_rec(up);
2389         if (!rec)
2390                 goto error;
2391
2392         isl_assert(up->ctx, rec->n >= 1, goto error);
2393
2394         if (up->var >= first + n)
2395                 base = isl_upoly_pow(up->ctx, up->var, 1);
2396         else
2397                 base = isl_upoly_copy(subs[up->var - first]);
2398
2399         res = isl_upoly_subs(isl_upoly_copy(rec->p[rec->n - 1]), first, n, subs);
2400         for (i = rec->n - 2; i >= 0; --i) {
2401                 struct isl_upoly *t;
2402                 t = isl_upoly_subs(isl_upoly_copy(rec->p[i]), first, n, subs);
2403                 res = isl_upoly_mul(res, isl_upoly_copy(base));
2404                 res = isl_upoly_sum(res, t);
2405         }
2406
2407         isl_upoly_free(base);
2408         isl_upoly_free(up);
2409                                 
2410         return res;
2411 error:
2412         isl_upoly_free(up);
2413         return NULL;
2414 }       
2415
2416 /* For each 0 <= i < "n", replace variable "first" + i of type "type"
2417  * in "qp" by subs[i].
2418  */
2419 __isl_give isl_qpolynomial *isl_qpolynomial_substitute(
2420         __isl_take isl_qpolynomial *qp,
2421         enum isl_dim_type type, unsigned first, unsigned n,
2422         __isl_keep isl_qpolynomial **subs)
2423 {
2424         int i;
2425         struct isl_upoly **ups;
2426
2427         if (n == 0)
2428                 return qp;
2429
2430         qp = isl_qpolynomial_cow(qp);
2431         if (!qp)
2432                 return NULL;
2433         for (i = 0; i < n; ++i)
2434                 if (!subs[i])
2435                         goto error;
2436
2437         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
2438                         goto error);
2439
2440         for (i = 0; i < n; ++i)
2441                 isl_assert(qp->dim->ctx, isl_dim_equal(qp->dim, subs[i]->dim),
2442                                 goto error);
2443
2444         isl_assert(qp->dim->ctx, qp->div->n_row == 0, goto error);
2445         for (i = 0; i < n; ++i)
2446                 isl_assert(qp->dim->ctx, subs[i]->div->n_row == 0, goto error);
2447
2448         first += pos(qp->dim, type);
2449
2450         ups = isl_alloc_array(qp->dim->ctx, struct isl_upoly *, n);
2451         if (!ups)
2452                 goto error;
2453         for (i = 0; i < n; ++i)
2454                 ups[i] = subs[i]->upoly;
2455
2456         qp->upoly = isl_upoly_subs(qp->upoly, first, n, ups);
2457
2458         free(ups);
2459
2460         if (!qp->upoly)
2461                 goto error;
2462
2463         return qp;
2464 error:
2465         isl_qpolynomial_free(qp);
2466         return NULL;
2467 }
2468
2469 __isl_give isl_basic_set *add_div_constraints(__isl_take isl_basic_set *bset,
2470         __isl_take isl_mat *div)
2471 {
2472         int i;
2473         unsigned total;
2474
2475         if (!bset || !div)
2476                 goto error;
2477
2478         bset = isl_basic_set_extend_constraints(bset, 0, 2 * div->n_row);
2479         if (!bset)
2480                 goto error;
2481         total = isl_basic_set_total_dim(bset);
2482         for (i = 0; i < div->n_row; ++i)
2483                 if (isl_basic_set_add_div_constraints_var(bset,
2484                                     total - div->n_row + i, div->row[i]) < 0)
2485                         goto error;
2486
2487         isl_mat_free(div);
2488         return bset;
2489 error:
2490         isl_mat_free(div);
2491         isl_basic_set_free(bset);
2492         return NULL;
2493 }
2494
2495 /* Extend "bset" with extra set dimensions for each integer division
2496  * in "qp" and then call "fn" with the extended bset and the polynomial
2497  * that results from replacing each of the integer divisions by the
2498  * corresponding extra set dimension.
2499  */
2500 int isl_qpolynomial_as_polynomial_on_domain(__isl_keep isl_qpolynomial *qp,
2501         __isl_keep isl_basic_set *bset,
2502         int (*fn)(__isl_take isl_basic_set *bset,
2503                   __isl_take isl_qpolynomial *poly, void *user), void *user)
2504 {
2505         isl_dim *dim;
2506         isl_mat *div;
2507         isl_qpolynomial *poly;
2508
2509         if (!qp || !bset)
2510                 goto error;
2511         if (qp->div->n_row == 0)
2512                 return fn(isl_basic_set_copy(bset), isl_qpolynomial_copy(qp),
2513                           user);
2514
2515         div = isl_mat_copy(qp->div);
2516         dim = isl_dim_copy(qp->dim);
2517         dim = isl_dim_add(dim, isl_dim_set, qp->div->n_row);
2518         poly = isl_qpolynomial_alloc(dim, 0, isl_upoly_copy(qp->upoly));
2519         bset = isl_basic_set_copy(bset);
2520         bset = isl_basic_set_add(bset, isl_dim_set, qp->div->n_row);
2521         bset = add_div_constraints(bset, div);
2522
2523         return fn(bset, poly, user);
2524 error:
2525         return -1;
2526 }
2527
2528 /* Return total degree in variables first (inclusive) up to last (exclusive).
2529  */
2530 int isl_upoly_degree(__isl_keep struct isl_upoly *up, int first, int last)
2531 {
2532         int deg = -1;
2533         int i;
2534         struct isl_upoly_rec *rec;
2535
2536         if (!up)
2537                 return -2;
2538         if (isl_upoly_is_zero(up))
2539                 return -1;
2540         if (isl_upoly_is_cst(up) || up->var < first)
2541                 return 0;
2542
2543         rec = isl_upoly_as_rec(up);
2544         if (!rec)
2545                 return -2;
2546
2547         for (i = 0; i < rec->n; ++i) {
2548                 int d;
2549
2550                 if (isl_upoly_is_zero(rec->p[i]))
2551                         continue;
2552                 d = isl_upoly_degree(rec->p[i], first, last);
2553                 if (up->var < last)
2554                         d += i;
2555                 if (d > deg)
2556                         deg = d;
2557         }
2558
2559         return deg;
2560 }
2561
2562 /* Return total degree in set variables.
2563  */
2564 int isl_qpolynomial_degree(__isl_keep isl_qpolynomial *poly)
2565 {
2566         unsigned ovar;
2567         unsigned nvar;
2568
2569         if (!poly)
2570                 return -2;
2571
2572         ovar = isl_dim_offset(poly->dim, isl_dim_set);
2573         nvar = isl_dim_size(poly->dim, isl_dim_set);
2574         return isl_upoly_degree(poly->upoly, ovar, ovar + nvar);
2575 }
2576
2577 __isl_give struct isl_upoly *isl_upoly_coeff(__isl_keep struct isl_upoly *up,
2578         unsigned pos, int deg)
2579 {
2580         int i;
2581         struct isl_upoly_rec *rec;
2582
2583         if (!up)
2584                 return NULL;
2585
2586         if (isl_upoly_is_cst(up) || up->var < pos) {
2587                 if (deg == 0)
2588                         return isl_upoly_copy(up);
2589                 else
2590                         return isl_upoly_zero(up->ctx);
2591         }
2592
2593         rec = isl_upoly_as_rec(up);
2594         if (!rec)
2595                 return NULL;
2596
2597         if (up->var == pos) {
2598                 if (deg < rec->n)
2599                         return isl_upoly_copy(rec->p[deg]);
2600                 else
2601                         return isl_upoly_zero(up->ctx);
2602         }
2603
2604         up = isl_upoly_copy(up);
2605         up = isl_upoly_cow(up);
2606         rec = isl_upoly_as_rec(up);
2607         if (!rec)
2608                 goto error;
2609
2610         for (i = 0; i < rec->n; ++i) {
2611                 struct isl_upoly *t;
2612                 t = isl_upoly_coeff(rec->p[i], pos, deg);
2613                 if (!t)
2614                         goto error;
2615                 isl_upoly_free(rec->p[i]);
2616                 rec->p[i] = t;
2617         }
2618
2619         return up;
2620 error:
2621         isl_upoly_free(up);
2622         return NULL;
2623 }
2624
2625 /* Return coefficient of power "deg" of variable "t_pos" of type "type".
2626  */
2627 __isl_give isl_qpolynomial *isl_qpolynomial_coeff(
2628         __isl_keep isl_qpolynomial *qp,
2629         enum isl_dim_type type, unsigned t_pos, int deg)
2630 {
2631         unsigned g_pos;
2632         struct isl_upoly *up;
2633         isl_qpolynomial *c;
2634
2635         if (!qp)
2636                 return NULL;
2637
2638         isl_assert(qp->div->ctx, t_pos < isl_dim_size(qp->dim, type),
2639                         return NULL);
2640
2641         g_pos = pos(qp->dim, type) + t_pos;
2642         up = isl_upoly_coeff(qp->upoly, g_pos, deg);
2643
2644         c = isl_qpolynomial_alloc(isl_dim_copy(qp->dim), qp->div->n_row, up);
2645         if (!c)
2646                 return NULL;
2647         isl_mat_free(c->div);
2648         c->div = isl_mat_copy(qp->div);
2649         if (!c->div)
2650                 goto error;
2651         return c;
2652 error:
2653         isl_qpolynomial_free(c);
2654         return NULL;
2655 }
2656
2657 /* Homogenize the polynomial in the variables first (inclusive) up to
2658  * last (exclusive) by inserting powers of variable first.
2659  * Variable first is assumed not to appear in the input.
2660  */
2661 __isl_give struct isl_upoly *isl_upoly_homogenize(
2662         __isl_take struct isl_upoly *up, int deg, int target,
2663         int first, int last)
2664 {
2665         int i;
2666         struct isl_upoly_rec *rec;
2667
2668         if (!up)
2669                 return NULL;
2670         if (isl_upoly_is_zero(up))
2671                 return up;
2672         if (deg == target)
2673                 return up;
2674         if (isl_upoly_is_cst(up) || up->var < first) {
2675                 struct isl_upoly *hom;
2676
2677                 hom = isl_upoly_pow(up->ctx, first, target - deg);
2678                 if (!hom)
2679                         goto error;
2680                 rec = isl_upoly_as_rec(hom);
2681                 rec->p[target - deg] = isl_upoly_mul(rec->p[target - deg], up);
2682
2683                 return hom;
2684         }
2685
2686         up = isl_upoly_cow(up);
2687         rec = isl_upoly_as_rec(up);
2688         if (!rec)
2689                 goto error;
2690
2691         for (i = 0; i < rec->n; ++i) {
2692                 if (isl_upoly_is_zero(rec->p[i]))
2693                         continue;
2694                 rec->p[i] = isl_upoly_homogenize(rec->p[i],
2695                                 up->var < last ? deg + i : i, target,
2696                                 first, last);
2697                 if (!rec->p[i])
2698                         goto error;
2699         }
2700
2701         return up;
2702 error:
2703         isl_upoly_free(up);
2704         return NULL;
2705 }
2706
2707 /* Homogenize the polynomial in the set variables by introducing
2708  * powers of an extra set variable at position 0.
2709  */
2710 __isl_give isl_qpolynomial *isl_qpolynomial_homogenize(
2711         __isl_take isl_qpolynomial *poly)
2712 {
2713         unsigned ovar;
2714         unsigned nvar;
2715         int deg = isl_qpolynomial_degree(poly);
2716
2717         if (deg < -1)
2718                 goto error;
2719
2720         poly = isl_qpolynomial_insert_dims(poly, isl_dim_set, 0, 1);
2721         poly = isl_qpolynomial_cow(poly);
2722         if (!poly)
2723                 goto error;
2724
2725         ovar = isl_dim_offset(poly->dim, isl_dim_set);
2726         nvar = isl_dim_size(poly->dim, isl_dim_set);
2727         poly->upoly = isl_upoly_homogenize(poly->upoly, 0, deg,
2728                                                 ovar, ovar + nvar);
2729         if (!poly->upoly)
2730                 goto error;
2731
2732         return poly;
2733 error:
2734         isl_qpolynomial_free(poly);
2735         return NULL;
2736 }
2737
2738 __isl_give isl_term *isl_term_alloc(__isl_take isl_dim *dim,
2739         __isl_take isl_mat *div)
2740 {
2741         isl_term *term;
2742         int n;
2743
2744         if (!dim || !div)
2745                 goto error;
2746
2747         n = isl_dim_total(dim) + div->n_row;
2748
2749         term = isl_calloc(dim->ctx, struct isl_term,
2750                         sizeof(struct isl_term) + (n - 1) * sizeof(int));
2751         if (!term)
2752                 goto error;
2753
2754         term->ref = 1;
2755         term->dim = dim;
2756         term->div = div;
2757         isl_int_init(term->n);
2758         isl_int_init(term->d);
2759         
2760         return term;
2761 error:
2762         isl_dim_free(dim);
2763         isl_mat_free(div);
2764         return NULL;
2765 }
2766
2767 __isl_give isl_term *isl_term_copy(__isl_keep isl_term *term)
2768 {
2769         if (!term)
2770                 return NULL;
2771
2772         term->ref++;
2773         return term;
2774 }
2775
2776 __isl_give isl_term *isl_term_dup(__isl_keep isl_term *term)
2777 {
2778         int i;
2779         isl_term *dup;
2780         unsigned total;
2781
2782         if (term)
2783                 return NULL;
2784
2785         total = isl_dim_total(term->dim) + term->div->n_row;
2786
2787         dup = isl_term_alloc(isl_dim_copy(term->dim), isl_mat_copy(term->div));
2788         if (!dup)
2789                 return NULL;
2790
2791         isl_int_set(dup->n, term->n);
2792         isl_int_set(dup->d, term->d);
2793
2794         for (i = 0; i < total; ++i)
2795                 dup->pow[i] = term->pow[i];
2796
2797         return dup;
2798 }
2799
2800 __isl_give isl_term *isl_term_cow(__isl_take isl_term *term)
2801 {
2802         if (!term)
2803                 return NULL;
2804
2805         if (term->ref == 1)
2806                 return term;
2807         term->ref--;
2808         return isl_term_dup(term);
2809 }
2810
2811 void isl_term_free(__isl_take isl_term *term)
2812 {
2813         if (!term)
2814                 return;
2815
2816         if (--term->ref > 0)
2817                 return;
2818
2819         isl_dim_free(term->dim);
2820         isl_mat_free(term->div);
2821         isl_int_clear(term->n);
2822         isl_int_clear(term->d);
2823         free(term);
2824 }
2825
2826 unsigned isl_term_dim(__isl_keep isl_term *term, enum isl_dim_type type)
2827 {
2828         if (!term)
2829                 return 0;
2830
2831         switch (type) {
2832         case isl_dim_param:
2833         case isl_dim_in:
2834         case isl_dim_out:       return isl_dim_size(term->dim, type);
2835         case isl_dim_div:       return term->div->n_row;
2836         case isl_dim_all:       return isl_dim_total(term->dim) + term->div->n_row;
2837         default:                return 0;
2838         }
2839 }
2840
2841 isl_ctx *isl_term_get_ctx(__isl_keep isl_term *term)
2842 {
2843         return term ? term->dim->ctx : NULL;
2844 }
2845
2846 void isl_term_get_num(__isl_keep isl_term *term, isl_int *n)
2847 {
2848         if (!term)
2849                 return;
2850         isl_int_set(*n, term->n);
2851 }
2852
2853 void isl_term_get_den(__isl_keep isl_term *term, isl_int *d)
2854 {
2855         if (!term)
2856                 return;
2857         isl_int_set(*d, term->d);
2858 }
2859
2860 int isl_term_get_exp(__isl_keep isl_term *term,
2861         enum isl_dim_type type, unsigned pos)
2862 {
2863         if (!term)
2864                 return -1;
2865
2866         isl_assert(term->dim->ctx, pos < isl_term_dim(term, type), return -1);
2867
2868         if (type >= isl_dim_set)
2869                 pos += isl_dim_size(term->dim, isl_dim_param);
2870         if (type >= isl_dim_div)
2871                 pos += isl_dim_size(term->dim, isl_dim_set);
2872
2873         return term->pow[pos];
2874 }
2875
2876 __isl_give isl_div *isl_term_get_div(__isl_keep isl_term *term, unsigned pos)
2877 {
2878         isl_basic_map *bmap;
2879         unsigned total;
2880         int k;
2881
2882         if (!term)
2883                 return NULL;
2884
2885         isl_assert(term->dim->ctx, pos < isl_term_dim(term, isl_dim_div),
2886                         return NULL);
2887
2888         total = term->div->n_col - term->div->n_row - 2;
2889         /* No nested divs for now */
2890         isl_assert(term->dim->ctx,
2891                 isl_seq_first_non_zero(term->div->row[pos] + 2 + total,
2892                                         term->div->n_row) == -1,
2893                 return NULL);
2894
2895         bmap = isl_basic_map_alloc_dim(isl_dim_copy(term->dim), 1, 0, 0);
2896         if ((k = isl_basic_map_alloc_div(bmap)) < 0)
2897                 goto error;
2898
2899         isl_seq_cpy(bmap->div[k], term->div->row[pos], 2 + total);
2900
2901         return isl_basic_map_div(bmap, k);
2902 error:
2903         isl_basic_map_free(bmap);
2904         return NULL;
2905 }
2906
2907 __isl_give isl_term *isl_upoly_foreach_term(__isl_keep struct isl_upoly *up,
2908         int (*fn)(__isl_take isl_term *term, void *user),
2909         __isl_take isl_term *term, void *user)
2910 {
2911         int i;
2912         struct isl_upoly_rec *rec;
2913
2914         if (!up || !term)
2915                 goto error;
2916
2917         if (isl_upoly_is_zero(up))
2918                 return term;
2919
2920         isl_assert(up->ctx, !isl_upoly_is_nan(up), goto error);
2921         isl_assert(up->ctx, !isl_upoly_is_infty(up), goto error);
2922         isl_assert(up->ctx, !isl_upoly_is_neginfty(up), goto error);
2923
2924         if (isl_upoly_is_cst(up)) {
2925                 struct isl_upoly_cst *cst;
2926                 cst = isl_upoly_as_cst(up);
2927                 if (!cst)
2928                         goto error;
2929                 term = isl_term_cow(term);
2930                 if (!term)
2931                         goto error;
2932                 isl_int_set(term->n, cst->n);
2933                 isl_int_set(term->d, cst->d);
2934                 if (fn(isl_term_copy(term), user) < 0)
2935                         goto error;
2936                 return term;
2937         }
2938
2939         rec = isl_upoly_as_rec(up);
2940         if (!rec)
2941                 goto error;
2942
2943         for (i = 0; i < rec->n; ++i) {
2944                 term = isl_term_cow(term);
2945                 if (!term)
2946                         goto error;
2947                 term->pow[up->var] = i;
2948                 term = isl_upoly_foreach_term(rec->p[i], fn, term, user);
2949                 if (!term)
2950                         goto error;
2951         }
2952         term->pow[up->var] = 0;
2953
2954         return term;
2955 error:
2956         isl_term_free(term);
2957         return NULL;
2958 }
2959
2960 int isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp,
2961         int (*fn)(__isl_take isl_term *term, void *user), void *user)
2962 {
2963         isl_term *term;
2964
2965         if (!qp)
2966                 return -1;
2967
2968         term = isl_term_alloc(isl_dim_copy(qp->dim), isl_mat_copy(qp->div));
2969         if (!term)
2970                 return -1;
2971
2972         term = isl_upoly_foreach_term(qp->upoly, fn, term, user);
2973
2974         isl_term_free(term);
2975
2976         return term ? 0 : -1;
2977 }
2978
2979 __isl_give isl_qpolynomial *isl_qpolynomial_from_term(__isl_take isl_term *term)
2980 {
2981         struct isl_upoly *up;
2982         isl_qpolynomial *qp;
2983         int i, n;
2984
2985         if (!term)
2986                 return NULL;
2987
2988         n = isl_dim_total(term->dim) + term->div->n_row;
2989
2990         up = isl_upoly_rat_cst(term->dim->ctx, term->n, term->d);
2991         for (i = 0; i < n; ++i) {
2992                 if (!term->pow[i])
2993                         continue;
2994                 up = isl_upoly_mul(up,
2995                         isl_upoly_pow(term->dim->ctx, i, term->pow[i]));
2996         }
2997
2998         qp = isl_qpolynomial_alloc(isl_dim_copy(term->dim), term->div->n_row, up);
2999         if (!qp)
3000                 goto error;
3001         isl_mat_free(qp->div);
3002         qp->div = isl_mat_copy(term->div);
3003         if (!qp->div)
3004                 goto error;
3005
3006         isl_term_free(term);
3007         return qp;
3008 error:
3009         isl_qpolynomial_free(qp);
3010         isl_term_free(term);
3011         return NULL;
3012 }
3013
3014 __isl_give isl_qpolynomial *isl_qpolynomial_lift(__isl_take isl_qpolynomial *qp,
3015         __isl_take isl_dim *dim)
3016 {
3017         int i;
3018         int extra;
3019         unsigned total;
3020
3021         if (!qp || !dim)
3022                 goto error;
3023
3024         if (isl_dim_equal(qp->dim, dim)) {
3025                 isl_dim_free(dim);
3026                 return qp;
3027         }
3028
3029         qp = isl_qpolynomial_cow(qp);
3030         if (!qp)
3031                 goto error;
3032
3033         extra = isl_dim_size(dim, isl_dim_set) -
3034                         isl_dim_size(qp->dim, isl_dim_set);
3035         total = isl_dim_total(qp->dim);
3036         if (qp->div->n_row) {
3037                 int *exp;
3038
3039                 exp = isl_alloc_array(qp->div->ctx, int, qp->div->n_row);
3040                 if (!exp)
3041                         goto error;
3042                 for (i = 0; i < qp->div->n_row; ++i)
3043                         exp[i] = extra + i;
3044                 qp->upoly = expand(qp->upoly, exp, total);
3045                 free(exp);
3046                 if (!qp->upoly)
3047                         goto error;
3048         }
3049         qp->div = isl_mat_insert_cols(qp->div, 2 + total, extra);
3050         if (!qp->div)
3051                 goto error;
3052         for (i = 0; i < qp->div->n_row; ++i)
3053                 isl_seq_clr(qp->div->row[i] + 2 + total, extra);
3054
3055         isl_dim_free(qp->dim);
3056         qp->dim = dim;
3057
3058         return qp;
3059 error:
3060         isl_dim_free(dim);
3061         isl_qpolynomial_free(qp);
3062         return NULL;
3063 }
3064
3065 /* For each parameter or variable that does not appear in qp,
3066  * first eliminate the variable from all constraints and then set it to zero.
3067  */
3068 static __isl_give isl_set *fix_inactive(__isl_take isl_set *set,
3069         __isl_keep isl_qpolynomial *qp)
3070 {
3071         int *active = NULL;
3072         int i;
3073         int d;
3074         unsigned nparam;
3075         unsigned nvar;
3076
3077         if (!set || !qp)
3078                 goto error;
3079
3080         d = isl_dim_total(set->dim);
3081         active = isl_calloc_array(set->ctx, int, d);
3082         if (set_active(qp, active) < 0)
3083                 goto error;
3084
3085         for (i = 0; i < d; ++i)
3086                 if (!active[i])
3087                         break;
3088
3089         if (i == d) {
3090                 free(active);
3091                 return set;
3092         }
3093
3094         nparam = isl_dim_size(set->dim, isl_dim_param);
3095         nvar = isl_dim_size(set->dim, isl_dim_set);
3096         for (i = 0; i < nparam; ++i) {
3097                 if (active[i])
3098                         continue;
3099                 set = isl_set_eliminate(set, isl_dim_param, i, 1);
3100                 set = isl_set_fix_si(set, isl_dim_param, i, 0);
3101         }
3102         for (i = 0; i < nvar; ++i) {
3103                 if (active[nparam + i])
3104                         continue;
3105                 set = isl_set_eliminate(set, isl_dim_set, i, 1);
3106                 set = isl_set_fix_si(set, isl_dim_set, i, 0);
3107         }
3108
3109         free(active);
3110
3111         return set;
3112 error:
3113         free(active);
3114         isl_set_free(set);
3115         return NULL;
3116 }
3117
3118 struct isl_opt_data {
3119         isl_qpolynomial *qp;
3120         int first;
3121         isl_qpolynomial *opt;
3122         int max;
3123 };
3124
3125 static int opt_fn(__isl_take isl_point *pnt, void *user)
3126 {
3127         struct isl_opt_data *data = (struct isl_opt_data *)user;
3128         isl_qpolynomial *val;
3129
3130         val = isl_qpolynomial_eval(isl_qpolynomial_copy(data->qp), pnt);
3131         if (data->first) {
3132                 data->first = 0;
3133                 data->opt = val;
3134         } else if (data->max) {
3135                 data->opt = isl_qpolynomial_max_cst(data->opt, val);
3136         } else {
3137                 data->opt = isl_qpolynomial_min_cst(data->opt, val);
3138         }
3139
3140         return 0;
3141 }
3142
3143 __isl_give isl_qpolynomial *isl_qpolynomial_opt_on_domain(
3144         __isl_take isl_qpolynomial *qp, __isl_take isl_set *set, int max)
3145 {
3146         struct isl_opt_data data = { NULL, 1, NULL, max };
3147
3148         if (!set || !qp)
3149                 goto error;
3150
3151         if (isl_upoly_is_cst(qp->upoly)) {
3152                 isl_set_free(set);
3153                 return qp;
3154         }
3155
3156         set = fix_inactive(set, qp);
3157
3158         data.qp = qp;
3159         if (isl_set_foreach_point(set, opt_fn, &data) < 0)
3160                 goto error;
3161
3162         if (data.first)
3163                 data.opt = isl_qpolynomial_zero(isl_qpolynomial_get_dim(qp));
3164
3165         isl_set_free(set);
3166         isl_qpolynomial_free(qp);
3167         return data.opt;
3168 error:
3169         isl_set_free(set);
3170         isl_qpolynomial_free(qp);
3171         isl_qpolynomial_free(data.opt);
3172         return NULL;
3173 }
3174
3175 __isl_give isl_qpolynomial *isl_qpolynomial_morph(__isl_take isl_qpolynomial *qp,
3176         __isl_take isl_morph *morph)
3177 {
3178         int i;
3179         isl_ctx *ctx;
3180         struct isl_upoly *up;
3181         unsigned n_div;
3182         struct isl_upoly **subs;
3183         isl_mat *mat;
3184
3185         qp = isl_qpolynomial_cow(qp);
3186         if (!qp || !morph)
3187                 goto error;
3188
3189         ctx = qp->dim->ctx;
3190         isl_assert(ctx, isl_dim_equal(qp->dim, morph->dom->dim), goto error);
3191
3192         subs = isl_calloc_array(ctx, struct isl_upoly *, morph->inv->n_row - 1);
3193         if (!subs)
3194                 goto error;
3195
3196         for (i = 0; 1 + i < morph->inv->n_row; ++i)
3197                 subs[i] = isl_upoly_from_affine(ctx, morph->inv->row[1 + i],
3198                                         morph->inv->row[0][0], morph->inv->n_col);
3199
3200         qp->upoly = isl_upoly_subs(qp->upoly, 0, morph->inv->n_row - 1, subs);
3201
3202         for (i = 0; 1 + i < morph->inv->n_row; ++i)
3203                 isl_upoly_free(subs[i]);
3204         free(subs);
3205
3206         mat = isl_mat_diagonal(isl_mat_identity(ctx, 1), isl_mat_copy(morph->inv));
3207         mat = isl_mat_diagonal(mat, isl_mat_identity(ctx, qp->div->n_row));
3208         qp->div = isl_mat_product(qp->div, mat);
3209         isl_dim_free(qp->dim);
3210         qp->dim = isl_dim_copy(morph->ran->dim);
3211
3212         if (!qp->upoly || !qp->div || !qp->dim)
3213                 goto error;
3214
3215         isl_morph_free(morph);
3216
3217         return qp;
3218 error:
3219         isl_qpolynomial_free(qp);
3220         isl_morph_free(morph);
3221         return NULL;
3222 }
3223
3224 static int neg_entry(void **entry, void *user)
3225 {
3226         isl_pw_qpolynomial **pwqp = (isl_pw_qpolynomial **)entry;
3227
3228         *pwqp = isl_pw_qpolynomial_neg(*pwqp);
3229
3230         return *pwqp ? 0 : -1;
3231 }
3232
3233 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_neg(
3234         __isl_take isl_union_pw_qpolynomial *upwqp)
3235 {
3236         upwqp = isl_union_pw_qpolynomial_cow(upwqp);
3237         if (!upwqp)
3238                 return NULL;
3239
3240         if (isl_hash_table_foreach(upwqp->dim->ctx, &upwqp->table,
3241                                    &neg_entry, NULL) < 0)
3242                 goto error;
3243
3244         return upwqp;
3245 error:
3246         isl_union_pw_qpolynomial_free(upwqp);
3247         return NULL;
3248 }
3249
3250 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub(
3251         __isl_take isl_union_pw_qpolynomial *upwqp1,
3252         __isl_take isl_union_pw_qpolynomial *upwqp2)
3253 {
3254         return isl_union_pw_qpolynomial_add(upwqp1,
3255                                         isl_union_pw_qpolynomial_neg(upwqp2));
3256 }
3257
3258 static int mul_entry(void **entry, void *user)
3259 {
3260         struct isl_union_pw_qpolynomial_match_bin_data *data = user;
3261         uint32_t hash;
3262         struct isl_hash_table_entry *entry2;
3263         isl_pw_qpolynomial *pwpq = *entry;
3264         int empty;
3265
3266         hash = isl_dim_get_hash(pwpq->dim);
3267         entry2 = isl_hash_table_find(data->upwqp2->dim->ctx,
3268                                      &data->upwqp2->table,
3269                                      hash, &has_dim, pwpq->dim, 0);
3270         if (!entry2)
3271                 return 0;
3272
3273         pwpq = isl_pw_qpolynomial_copy(pwpq);
3274         pwpq = isl_pw_qpolynomial_mul(pwpq,
3275                                       isl_pw_qpolynomial_copy(entry2->data));
3276
3277         empty = isl_pw_qpolynomial_is_zero(pwpq);
3278         if (empty < 0) {
3279                 isl_pw_qpolynomial_free(pwpq);
3280                 return -1;
3281         }
3282         if (empty) {
3283                 isl_pw_qpolynomial_free(pwpq);
3284                 return 0;
3285         }
3286
3287         data->res = isl_union_pw_qpolynomial_add_pw_qpolynomial(data->res, pwpq);
3288
3289         return 0;
3290 }
3291
3292 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul(
3293         __isl_take isl_union_pw_qpolynomial *upwqp1,
3294         __isl_take isl_union_pw_qpolynomial *upwqp2)
3295 {
3296         return match_bin_op(upwqp1, upwqp2, &mul_entry);
3297 }