fix isl_pw_qpolynomial_reset_dim
[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 static int compatible_divs(__isl_keep isl_mat *div1, __isl_keep isl_mat *div2)
945 {
946         int n_row, n_col;
947         int equal;
948
949         isl_assert(div1->ctx, div1->n_row >= div2->n_row &&
950                                 div1->n_col >= div2->n_col, return -1);
951
952         if (div1->n_row == div2->n_row)
953                 return isl_mat_is_equal(div1, div2);
954
955         n_row = div1->n_row;
956         n_col = div1->n_col;
957         div1->n_row = div2->n_row;
958         div1->n_col = div2->n_col;
959
960         equal = isl_mat_is_equal(div1, div2);
961
962         div1->n_row = n_row;
963         div1->n_col = n_col;
964
965         return equal;
966 }
967
968 static void expand_row(__isl_keep isl_mat *dst, int d,
969         __isl_keep isl_mat *src, int s, int *exp)
970 {
971         int i;
972         unsigned c = src->n_col - src->n_row;
973
974         isl_seq_cpy(dst->row[d], src->row[s], c);
975         isl_seq_clr(dst->row[d] + c, dst->n_col - c);
976
977         for (i = 0; i < s; ++i)
978                 isl_int_set(dst->row[d][c + exp[i]], src->row[s][c + i]);
979 }
980
981 static int cmp_row(__isl_keep isl_mat *div, int i, int j)
982 {
983         int li, lj;
984
985         li = isl_seq_last_non_zero(div->row[i], div->n_col);
986         lj = isl_seq_last_non_zero(div->row[j], div->n_col);
987
988         if (li != lj)
989                 return li - lj;
990
991         return isl_seq_cmp(div->row[i], div->row[j], div->n_col);
992 }
993
994 struct isl_div_sort_info {
995         isl_mat *div;
996         int      row;
997 };
998
999 static int div_sort_cmp(const void *p1, const void *p2)
1000 {
1001         const struct isl_div_sort_info *i1, *i2;
1002         i1 = (const struct isl_div_sort_info *) p1;
1003         i2 = (const struct isl_div_sort_info *) p2;
1004
1005         return cmp_row(i1->div, i1->row, i2->row);
1006 }
1007
1008 static __isl_give isl_mat *sort_divs(__isl_take isl_mat *div)
1009 {
1010         int i;
1011         struct isl_div_sort_info *array = NULL;
1012         int *pos = NULL;
1013
1014         if (!div)
1015                 return NULL;
1016         if (div->n_row <= 1)
1017                 return div;
1018
1019         array = isl_alloc_array(div->ctx, struct isl_div_sort_info, div->n_row);
1020         pos = isl_alloc_array(div->ctx, int, div->n_row);
1021         if (!array || !pos)
1022                 goto error;
1023
1024         for (i = 0; i < div->n_row; ++i) {
1025                 array[i].div = div;
1026                 array[i].row = i;
1027                 pos[i] = i;
1028         }
1029
1030         qsort(array, div->n_row, sizeof(struct isl_div_sort_info),
1031                 div_sort_cmp);
1032
1033         for (i = 0; i < div->n_row; ++i) {
1034                 int t;
1035                 if (pos[array[i].row] == i)
1036                         continue;
1037                 div = isl_mat_cow(div);
1038                 div = isl_mat_swap_rows(div, i, pos[array[i].row]);
1039                 t = pos[array[i].row];
1040                 pos[array[i].row] = pos[i];
1041                 pos[i] = t;
1042         }
1043
1044         free(array);
1045
1046         return div;
1047 error:
1048         free(pos);
1049         free(array);
1050         isl_mat_free(div);
1051         return NULL;
1052 }
1053
1054 static __isl_give isl_mat *merge_divs(__isl_keep isl_mat *div1,
1055         __isl_keep isl_mat *div2, int *exp1, int *exp2)
1056 {
1057         int i, j, k;
1058         isl_mat *div = NULL;
1059         unsigned d = div1->n_col - div1->n_row;
1060
1061         div = isl_mat_alloc(div1->ctx, 1 + div1->n_row + div2->n_row,
1062                                 d + div1->n_row + div2->n_row);
1063         if (!div)
1064                 return NULL;
1065
1066         for (i = 0, j = 0, k = 0; i < div1->n_row && j < div2->n_row; ++k) {
1067                 int cmp;
1068
1069                 expand_row(div, k, div1, i, exp1);
1070                 expand_row(div, k + 1, div2, j, exp2);
1071
1072                 cmp = cmp_row(div, k, k + 1);
1073                 if (cmp == 0) {
1074                         exp1[i++] = k;
1075                         exp2[j++] = k;
1076                 } else if (cmp < 0) {
1077                         exp1[i++] = k;
1078                 } else {
1079                         exp2[j++] = k;
1080                         isl_seq_cpy(div->row[k], div->row[k + 1], div->n_col);
1081                 }
1082         }
1083         for (; i < div1->n_row; ++i, ++k) {
1084                 expand_row(div, k, div1, i, exp1);
1085                 exp1[i] = k;
1086         }
1087         for (; j < div2->n_row; ++j, ++k) {
1088                 expand_row(div, k, div2, j, exp2);
1089                 exp2[j] = k;
1090         }
1091
1092         div->n_row = k;
1093         div->n_col = d + k;
1094
1095         return div;
1096 }
1097
1098 static __isl_give struct isl_upoly *expand(__isl_take struct isl_upoly *up,
1099         int *exp, int first)
1100 {
1101         int i;
1102         struct isl_upoly_rec *rec;
1103
1104         if (isl_upoly_is_cst(up))
1105                 return up;
1106
1107         if (up->var < first)
1108                 return up;
1109
1110         if (exp[up->var - first] == up->var - first)
1111                 return up;
1112
1113         up = isl_upoly_cow(up);
1114         if (!up)
1115                 goto error;
1116
1117         up->var = exp[up->var - first] + first;
1118
1119         rec = isl_upoly_as_rec(up);
1120         if (!rec)
1121                 goto error;
1122
1123         for (i = 0; i < rec->n; ++i) {
1124                 rec->p[i] = expand(rec->p[i], exp, first);
1125                 if (!rec->p[i])
1126                         goto error;
1127         }
1128
1129         return up;
1130 error:
1131         isl_upoly_free(up);
1132         return NULL;
1133 }
1134
1135 static __isl_give isl_qpolynomial *with_merged_divs(
1136         __isl_give isl_qpolynomial *(*fn)(__isl_take isl_qpolynomial *qp1,
1137                                           __isl_take isl_qpolynomial *qp2),
1138         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
1139 {
1140         int *exp1 = NULL;
1141         int *exp2 = NULL;
1142         isl_mat *div = NULL;
1143
1144         qp1 = isl_qpolynomial_cow(qp1);
1145         qp2 = isl_qpolynomial_cow(qp2);
1146
1147         if (!qp1 || !qp2)
1148                 goto error;
1149
1150         isl_assert(qp1->div->ctx, qp1->div->n_row >= qp2->div->n_row &&
1151                                 qp1->div->n_col >= qp2->div->n_col, goto error);
1152
1153         exp1 = isl_alloc_array(qp1->div->ctx, int, qp1->div->n_row);
1154         exp2 = isl_alloc_array(qp2->div->ctx, int, qp2->div->n_row);
1155         if (!exp1 || !exp2)
1156                 goto error;
1157
1158         div = merge_divs(qp1->div, qp2->div, exp1, exp2);
1159         if (!div)
1160                 goto error;
1161
1162         isl_mat_free(qp1->div);
1163         qp1->div = isl_mat_copy(div);
1164         isl_mat_free(qp2->div);
1165         qp2->div = isl_mat_copy(div);
1166
1167         qp1->upoly = expand(qp1->upoly, exp1, div->n_col - div->n_row - 2);
1168         qp2->upoly = expand(qp2->upoly, exp2, div->n_col - div->n_row - 2);
1169
1170         if (!qp1->upoly || !qp2->upoly)
1171                 goto error;
1172
1173         isl_mat_free(div);
1174         free(exp1);
1175         free(exp2);
1176
1177         return fn(qp1, qp2);
1178 error:
1179         isl_mat_free(div);
1180         free(exp1);
1181         free(exp2);
1182         isl_qpolynomial_free(qp1);
1183         isl_qpolynomial_free(qp2);
1184         return NULL;
1185 }
1186
1187 __isl_give isl_qpolynomial *isl_qpolynomial_add(__isl_take isl_qpolynomial *qp1,
1188         __isl_take isl_qpolynomial *qp2)
1189 {
1190         qp1 = isl_qpolynomial_cow(qp1);
1191
1192         if (!qp1 || !qp2)
1193                 goto error;
1194
1195         if (qp1->div->n_row < qp2->div->n_row)
1196                 return isl_qpolynomial_add(qp2, qp1);
1197
1198         isl_assert(qp1->dim->ctx, isl_dim_equal(qp1->dim, qp2->dim), goto error);
1199         if (!compatible_divs(qp1->div, qp2->div))
1200                 return with_merged_divs(isl_qpolynomial_add, qp1, qp2);
1201
1202         qp1->upoly = isl_upoly_sum(qp1->upoly, isl_upoly_copy(qp2->upoly));
1203         if (!qp1->upoly)
1204                 goto error;
1205
1206         isl_qpolynomial_free(qp2);
1207
1208         return qp1;
1209 error:
1210         isl_qpolynomial_free(qp1);
1211         isl_qpolynomial_free(qp2);
1212         return NULL;
1213 }
1214
1215 __isl_give isl_qpolynomial *isl_qpolynomial_sub(__isl_take isl_qpolynomial *qp1,
1216         __isl_take isl_qpolynomial *qp2)
1217 {
1218         return isl_qpolynomial_add(qp1, isl_qpolynomial_neg(qp2));
1219 }
1220
1221 __isl_give isl_qpolynomial *isl_qpolynomial_neg(__isl_take isl_qpolynomial *qp)
1222 {
1223         qp = isl_qpolynomial_cow(qp);
1224
1225         if (!qp)
1226                 return NULL;
1227
1228         qp->upoly = isl_upoly_neg(qp->upoly);
1229         if (!qp->upoly)
1230                 goto error;
1231
1232         return qp;
1233 error:
1234         isl_qpolynomial_free(qp);
1235         return NULL;
1236 }
1237
1238 __isl_give isl_qpolynomial *isl_qpolynomial_mul(__isl_take isl_qpolynomial *qp1,
1239         __isl_take isl_qpolynomial *qp2)
1240 {
1241         qp1 = isl_qpolynomial_cow(qp1);
1242
1243         if (!qp1 || !qp2)
1244                 goto error;
1245
1246         if (qp1->div->n_row < qp2->div->n_row)
1247                 return isl_qpolynomial_mul(qp2, qp1);
1248
1249         isl_assert(qp1->dim->ctx, isl_dim_equal(qp1->dim, qp2->dim), goto error);
1250         if (!compatible_divs(qp1->div, qp2->div))
1251                 return with_merged_divs(isl_qpolynomial_mul, qp1, qp2);
1252
1253         qp1->upoly = isl_upoly_mul(qp1->upoly, isl_upoly_copy(qp2->upoly));
1254         if (!qp1->upoly)
1255                 goto error;
1256
1257         isl_qpolynomial_free(qp2);
1258
1259         return qp1;
1260 error:
1261         isl_qpolynomial_free(qp1);
1262         isl_qpolynomial_free(qp2);
1263         return NULL;
1264 }
1265
1266 __isl_give isl_qpolynomial *isl_qpolynomial_zero(__isl_take isl_dim *dim)
1267 {
1268         return isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
1269 }
1270
1271 __isl_give isl_qpolynomial *isl_qpolynomial_infty(__isl_take isl_dim *dim)
1272 {
1273         return isl_qpolynomial_alloc(dim, 0, isl_upoly_infty(dim->ctx));
1274 }
1275
1276 __isl_give isl_qpolynomial *isl_qpolynomial_neginfty(__isl_take isl_dim *dim)
1277 {
1278         return isl_qpolynomial_alloc(dim, 0, isl_upoly_neginfty(dim->ctx));
1279 }
1280
1281 __isl_give isl_qpolynomial *isl_qpolynomial_nan(__isl_take isl_dim *dim)
1282 {
1283         return isl_qpolynomial_alloc(dim, 0, isl_upoly_nan(dim->ctx));
1284 }
1285
1286 __isl_give isl_qpolynomial *isl_qpolynomial_cst(__isl_take isl_dim *dim,
1287         isl_int v)
1288 {
1289         struct isl_qpolynomial *qp;
1290         struct isl_upoly_cst *cst;
1291
1292         qp = isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
1293         if (!qp)
1294                 return NULL;
1295
1296         cst = isl_upoly_as_cst(qp->upoly);
1297         isl_int_set(cst->n, v);
1298
1299         return qp;
1300 }
1301
1302 int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp,
1303         isl_int *n, isl_int *d)
1304 {
1305         struct isl_upoly_cst *cst;
1306
1307         if (!qp)
1308                 return -1;
1309
1310         if (!isl_upoly_is_cst(qp->upoly))
1311                 return 0;
1312
1313         cst = isl_upoly_as_cst(qp->upoly);
1314         if (!cst)
1315                 return -1;
1316
1317         if (n)
1318                 isl_int_set(*n, cst->n);
1319         if (d)
1320                 isl_int_set(*d, cst->d);
1321
1322         return 1;
1323 }
1324
1325 int isl_upoly_is_affine(__isl_keep struct isl_upoly *up)
1326 {
1327         int is_cst;
1328         struct isl_upoly_rec *rec;
1329
1330         if (!up)
1331                 return -1;
1332
1333         if (up->var < 0)
1334                 return 1;
1335
1336         rec = isl_upoly_as_rec(up);
1337         if (!rec)
1338                 return -1;
1339
1340         if (rec->n > 2)
1341                 return 0;
1342
1343         isl_assert(up->ctx, rec->n > 1, return -1);
1344
1345         is_cst = isl_upoly_is_cst(rec->p[1]);
1346         if (is_cst < 0)
1347                 return -1;
1348         if (!is_cst)
1349                 return 0;
1350
1351         return isl_upoly_is_affine(rec->p[0]);
1352 }
1353
1354 int isl_qpolynomial_is_affine(__isl_keep isl_qpolynomial *qp)
1355 {
1356         if (!qp)
1357                 return -1;
1358
1359         if (qp->div->n_row > 0)
1360                 return 0;
1361
1362         return isl_upoly_is_affine(qp->upoly);
1363 }
1364
1365 static void update_coeff(__isl_keep isl_vec *aff,
1366         __isl_keep struct isl_upoly_cst *cst, int pos)
1367 {
1368         isl_int gcd;
1369         isl_int f;
1370
1371         if (isl_int_is_zero(cst->n))
1372                 return;
1373
1374         isl_int_init(gcd);
1375         isl_int_init(f);
1376         isl_int_gcd(gcd, cst->d, aff->el[0]);
1377         isl_int_divexact(f, cst->d, gcd);
1378         isl_int_divexact(gcd, aff->el[0], gcd);
1379         isl_seq_scale(aff->el, aff->el, f, aff->size);
1380         isl_int_mul(aff->el[1 + pos], gcd, cst->n);
1381         isl_int_clear(gcd);
1382         isl_int_clear(f);
1383 }
1384
1385 int isl_upoly_update_affine(__isl_keep struct isl_upoly *up,
1386         __isl_keep isl_vec *aff)
1387 {
1388         struct isl_upoly_cst *cst;
1389         struct isl_upoly_rec *rec;
1390
1391         if (!up || !aff)
1392                 return -1;
1393
1394         if (up->var < 0) {
1395                 struct isl_upoly_cst *cst;
1396
1397                 cst = isl_upoly_as_cst(up);
1398                 if (!cst)
1399                         return -1;
1400                 update_coeff(aff, cst, 0);
1401                 return 0;
1402         }
1403
1404         rec = isl_upoly_as_rec(up);
1405         if (!rec)
1406                 return -1;
1407         isl_assert(up->ctx, rec->n == 2, return -1);
1408
1409         cst = isl_upoly_as_cst(rec->p[1]);
1410         if (!cst)
1411                 return -1;
1412         update_coeff(aff, cst, 1 + up->var);
1413
1414         return isl_upoly_update_affine(rec->p[0], aff);
1415 }
1416
1417 __isl_give isl_vec *isl_qpolynomial_extract_affine(
1418         __isl_keep isl_qpolynomial *qp)
1419 {
1420         isl_vec *aff;
1421         unsigned d;
1422
1423         if (!qp)
1424                 return NULL;
1425
1426         isl_assert(qp->div->ctx, qp->div->n_row == 0, return NULL);
1427         d = isl_dim_total(qp->dim);
1428         aff = isl_vec_alloc(qp->div->ctx, 2 + d);
1429         if (!aff)
1430                 return NULL;
1431
1432         isl_seq_clr(aff->el + 1, 1 + d);
1433         isl_int_set_si(aff->el[0], 1);
1434
1435         if (isl_upoly_update_affine(qp->upoly, aff) < 0)
1436                 goto error;
1437
1438         return aff;
1439 error:
1440         isl_vec_free(aff);
1441         return NULL;
1442 }
1443
1444 int isl_qpolynomial_is_equal(__isl_keep isl_qpolynomial *qp1,
1445         __isl_keep isl_qpolynomial *qp2)
1446 {
1447         if (!qp1 || !qp2)
1448                 return -1;
1449
1450         return isl_upoly_is_equal(qp1->upoly, qp2->upoly);
1451 }
1452
1453 static void upoly_update_den(__isl_keep struct isl_upoly *up, isl_int *d)
1454 {
1455         int i;
1456         struct isl_upoly_rec *rec;
1457
1458         if (isl_upoly_is_cst(up)) {
1459                 struct isl_upoly_cst *cst;
1460                 cst = isl_upoly_as_cst(up);
1461                 if (!cst)
1462                         return;
1463                 isl_int_lcm(*d, *d, cst->d);
1464                 return;
1465         }
1466
1467         rec = isl_upoly_as_rec(up);
1468         if (!rec)
1469                 return;
1470
1471         for (i = 0; i < rec->n; ++i)
1472                 upoly_update_den(rec->p[i], d);
1473 }
1474
1475 void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d)
1476 {
1477         isl_int_set_si(*d, 1);
1478         if (!qp)
1479                 return;
1480         upoly_update_den(qp->upoly, d);
1481 }
1482
1483 __isl_give struct isl_upoly *isl_upoly_pow(isl_ctx *ctx, int pos, int power)
1484 {
1485         int i;
1486         struct isl_upoly *up;
1487         struct isl_upoly_rec *rec;
1488         struct isl_upoly_cst *cst;
1489
1490         rec = isl_upoly_alloc_rec(ctx, pos, 1 + power);
1491         if (!rec)
1492                 return NULL;
1493         for (i = 0; i < 1 + power; ++i) {
1494                 rec->p[i] = isl_upoly_zero(ctx);
1495                 if (!rec->p[i])
1496                         goto error;
1497                 rec->n++;
1498         }
1499         cst = isl_upoly_as_cst(rec->p[power]);
1500         isl_int_set_si(cst->n, 1);
1501
1502         return &rec->up;
1503 error:
1504         isl_upoly_free(&rec->up);
1505         return NULL;
1506 }
1507
1508 __isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_dim *dim,
1509         int pos, int power)
1510 {
1511         struct isl_ctx *ctx;
1512
1513         if (!dim)
1514                 return NULL;
1515
1516         ctx = dim->ctx;
1517
1518         return isl_qpolynomial_alloc(dim, 0, isl_upoly_pow(ctx, pos, power));
1519 }
1520
1521 __isl_give isl_qpolynomial *isl_qpolynomial_var(__isl_take isl_dim *dim,
1522         enum isl_dim_type type, unsigned pos)
1523 {
1524         if (!dim)
1525                 return NULL;
1526
1527         isl_assert(dim->ctx, isl_dim_size(dim, isl_dim_in) == 0, goto error);
1528         isl_assert(dim->ctx, pos < isl_dim_size(dim, type), goto error);
1529
1530         if (type == isl_dim_set)
1531                 pos += isl_dim_size(dim, isl_dim_param);
1532
1533         return isl_qpolynomial_pow(dim, pos, 1);
1534 error:
1535         isl_dim_free(dim);
1536         return NULL;
1537 }
1538
1539 __isl_give isl_qpolynomial *isl_qpolynomial_div_pow(__isl_take isl_div *div,
1540         int power)
1541 {
1542         struct isl_qpolynomial *qp = NULL;
1543         struct isl_upoly_rec *rec;
1544         struct isl_upoly_cst *cst;
1545         int i;
1546         int pos;
1547
1548         if (!div)
1549                 return NULL;
1550         isl_assert(div->ctx, div->bmap->n_div == 1, goto error);
1551
1552         pos = isl_dim_total(div->bmap->dim);
1553         rec = isl_upoly_alloc_rec(div->ctx, pos, 1 + power);
1554         qp = isl_qpolynomial_alloc(isl_basic_map_get_dim(div->bmap), 1,
1555                                    &rec->up);
1556         if (!qp)
1557                 goto error;
1558
1559         isl_seq_cpy(qp->div->row[0], div->line[0], qp->div->n_col - 1);
1560         isl_int_set_si(qp->div->row[0][qp->div->n_col - 1], 0);
1561
1562         for (i = 0; i < 1 + power; ++i) {
1563                 rec->p[i] = isl_upoly_zero(div->ctx);
1564                 if (!rec->p[i])
1565                         goto error;
1566                 rec->n++;
1567         }
1568         cst = isl_upoly_as_cst(rec->p[power]);
1569         isl_int_set_si(cst->n, 1);
1570
1571         isl_div_free(div);
1572
1573         return qp;
1574 error:
1575         isl_qpolynomial_free(qp);
1576         isl_div_free(div);
1577         return NULL;
1578 }
1579
1580 __isl_give isl_qpolynomial *isl_qpolynomial_div(__isl_take isl_div *div)
1581 {
1582         return isl_qpolynomial_div_pow(div, 1);
1583 }
1584
1585 __isl_give isl_qpolynomial *isl_qpolynomial_rat_cst(__isl_take isl_dim *dim,
1586         const isl_int n, const isl_int d)
1587 {
1588         struct isl_qpolynomial *qp;
1589         struct isl_upoly_cst *cst;
1590
1591         qp = isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
1592         if (!qp)
1593                 return NULL;
1594
1595         cst = isl_upoly_as_cst(qp->upoly);
1596         isl_int_set(cst->n, n);
1597         isl_int_set(cst->d, d);
1598
1599         return qp;
1600 }
1601
1602 static int up_set_active(__isl_keep struct isl_upoly *up, int *active, int d)
1603 {
1604         struct isl_upoly_rec *rec;
1605         int i;
1606
1607         if (!up)
1608                 return -1;
1609
1610         if (isl_upoly_is_cst(up))
1611                 return 0;
1612
1613         if (up->var < d)
1614                 active[up->var] = 1;
1615
1616         rec = isl_upoly_as_rec(up);
1617         for (i = 0; i < rec->n; ++i)
1618                 if (up_set_active(rec->p[i], active, d) < 0)
1619                         return -1;
1620
1621         return 0;
1622 }
1623
1624 static int set_active(__isl_keep isl_qpolynomial *qp, int *active)
1625 {
1626         int i, j;
1627         int d = isl_dim_total(qp->dim);
1628
1629         if (!qp || !active)
1630                 return -1;
1631
1632         for (i = 0; i < d; ++i)
1633                 for (j = 0; j < qp->div->n_row; ++j) {
1634                         if (isl_int_is_zero(qp->div->row[j][2 + i]))
1635                                 continue;
1636                         active[i] = 1;
1637                         break;
1638                 }
1639
1640         return up_set_active(qp->upoly, active, d);
1641 }
1642
1643 int isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp,
1644         enum isl_dim_type type, unsigned first, unsigned n)
1645 {
1646         int i;
1647         int *active = NULL;
1648         int involves = 0;
1649
1650         if (!qp)
1651                 return -1;
1652         if (n == 0)
1653                 return 0;
1654
1655         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
1656                         return -1);
1657         isl_assert(qp->dim->ctx, type == isl_dim_param ||
1658                                  type == isl_dim_set, return -1);
1659
1660         active = isl_calloc_array(set->ctx, int, isl_dim_total(qp->dim));
1661         if (set_active(qp, active) < 0)
1662                 goto error;
1663
1664         if (type == isl_dim_set)
1665                 first += isl_dim_size(qp->dim, isl_dim_param);
1666         for (i = 0; i < n; ++i)
1667                 if (active[first + i]) {
1668                         involves = 1;
1669                         break;
1670                 }
1671
1672         free(active);
1673
1674         return involves;
1675 error:
1676         free(active);
1677         return -1;
1678 }
1679
1680 __isl_give struct isl_upoly *isl_upoly_drop(__isl_take struct isl_upoly *up,
1681         unsigned first, unsigned n)
1682 {
1683         int i;
1684         struct isl_upoly_rec *rec;
1685
1686         if (!up)
1687                 return NULL;
1688         if (n == 0 || up->var < 0 || up->var < first)
1689                 return up;
1690         if (up->var < first + n) {
1691                 up = replace_by_constant_term(up);
1692                 return isl_upoly_drop(up, first, n);
1693         }
1694         up = isl_upoly_cow(up);
1695         if (!up)
1696                 return NULL;
1697         up->var -= n;
1698         rec = isl_upoly_as_rec(up);
1699         if (!rec)
1700                 goto error;
1701
1702         for (i = 0; i < rec->n; ++i) {
1703                 rec->p[i] = isl_upoly_drop(rec->p[i], first, n);
1704                 if (!rec->p[i])
1705                         goto error;
1706         }
1707
1708         return up;
1709 error:
1710         isl_upoly_free(up);
1711         return NULL;
1712 }
1713
1714 __isl_give isl_qpolynomial *isl_qpolynomial_drop_dims(
1715         __isl_take isl_qpolynomial *qp,
1716         enum isl_dim_type type, unsigned first, unsigned n)
1717 {
1718         if (!qp)
1719                 return NULL;
1720         if (n == 0 && !isl_dim_get_tuple_name(qp->dim, type))
1721                 return qp;
1722
1723         qp = isl_qpolynomial_cow(qp);
1724         if (!qp)
1725                 return NULL;
1726
1727         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
1728                         goto error);
1729         isl_assert(qp->dim->ctx, type == isl_dim_param ||
1730                                  type == isl_dim_set, goto error);
1731
1732         qp->dim = isl_dim_drop(qp->dim, type, first, n);
1733         if (!qp->dim)
1734                 goto error;
1735
1736         if (type == isl_dim_set)
1737                 first += isl_dim_size(qp->dim, isl_dim_param);
1738
1739         qp->div = isl_mat_drop_cols(qp->div, 2 + first, n);
1740         if (!qp->div)
1741                 goto error;
1742
1743         qp->upoly = isl_upoly_drop(qp->upoly, first, n);
1744         if (!qp->upoly)
1745                 goto error;
1746
1747         return qp;
1748 error:
1749         isl_qpolynomial_free(qp);
1750         return NULL;
1751 }
1752
1753 #undef PW
1754 #define PW isl_pw_qpolynomial
1755 #undef EL
1756 #define EL isl_qpolynomial
1757 #undef IS_ZERO
1758 #define IS_ZERO is_zero
1759 #undef FIELD
1760 #define FIELD qp
1761 #undef ADD
1762 #define ADD(d,e1,e2)    isl_qpolynomial_add(e1,e2) 
1763
1764 #include <isl_pw_templ.c>
1765
1766 #undef UNION
1767 #define UNION isl_union_pw_qpolynomial
1768 #undef PART
1769 #define PART isl_pw_qpolynomial
1770 #undef PARTS
1771 #define PARTS pw_qpolynomial
1772
1773 #include <isl_union_templ.c>
1774
1775 int isl_pw_qpolynomial_is_one(__isl_keep isl_pw_qpolynomial *pwqp)
1776 {
1777         if (!pwqp)
1778                 return -1;
1779
1780         if (pwqp->n != -1)
1781                 return 0;
1782
1783         if (!isl_set_fast_is_universe(pwqp->p[0].set))
1784                 return 0;
1785
1786         return isl_qpolynomial_is_one(pwqp->p[0].qp);
1787 }
1788
1789 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul(
1790         __isl_take isl_pw_qpolynomial *pwqp1,
1791         __isl_take isl_pw_qpolynomial *pwqp2)
1792 {
1793         int i, j, n;
1794         struct isl_pw_qpolynomial *res;
1795         isl_set *set;
1796
1797         if (!pwqp1 || !pwqp2)
1798                 goto error;
1799
1800         isl_assert(pwqp1->dim->ctx, isl_dim_equal(pwqp1->dim, pwqp2->dim),
1801                         goto error);
1802
1803         if (isl_pw_qpolynomial_is_zero(pwqp1)) {
1804                 isl_pw_qpolynomial_free(pwqp2);
1805                 return pwqp1;
1806         }
1807
1808         if (isl_pw_qpolynomial_is_zero(pwqp2)) {
1809                 isl_pw_qpolynomial_free(pwqp1);
1810                 return pwqp2;
1811         }
1812
1813         if (isl_pw_qpolynomial_is_one(pwqp1)) {
1814                 isl_pw_qpolynomial_free(pwqp1);
1815                 return pwqp2;
1816         }
1817
1818         if (isl_pw_qpolynomial_is_one(pwqp2)) {
1819                 isl_pw_qpolynomial_free(pwqp2);
1820                 return pwqp1;
1821         }
1822
1823         n = pwqp1->n * pwqp2->n;
1824         res = isl_pw_qpolynomial_alloc_(isl_dim_copy(pwqp1->dim), n);
1825
1826         for (i = 0; i < pwqp1->n; ++i) {
1827                 for (j = 0; j < pwqp2->n; ++j) {
1828                         struct isl_set *common;
1829                         struct isl_qpolynomial *prod;
1830                         common = isl_set_intersect(isl_set_copy(pwqp1->p[i].set),
1831                                                 isl_set_copy(pwqp2->p[j].set));
1832                         if (isl_set_fast_is_empty(common)) {
1833                                 isl_set_free(common);
1834                                 continue;
1835                         }
1836
1837                         prod = isl_qpolynomial_mul(
1838                                 isl_qpolynomial_copy(pwqp1->p[i].qp),
1839                                 isl_qpolynomial_copy(pwqp2->p[j].qp));
1840
1841                         res = isl_pw_qpolynomial_add_piece(res, common, prod);
1842                 }
1843         }
1844
1845         isl_pw_qpolynomial_free(pwqp1);
1846         isl_pw_qpolynomial_free(pwqp2);
1847
1848         return res;
1849 error:
1850         isl_pw_qpolynomial_free(pwqp1);
1851         isl_pw_qpolynomial_free(pwqp2);
1852         return NULL;
1853 }
1854
1855 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg(
1856         __isl_take isl_pw_qpolynomial *pwqp)
1857 {
1858         int i, j, n;
1859         struct isl_pw_qpolynomial *res;
1860         isl_set *set;
1861
1862         if (!pwqp)
1863                 return NULL;
1864
1865         if (isl_pw_qpolynomial_is_zero(pwqp))
1866                 return pwqp;
1867
1868         pwqp = isl_pw_qpolynomial_cow(pwqp);
1869
1870         for (i = 0; i < pwqp->n; ++i) {
1871                 pwqp->p[i].qp = isl_qpolynomial_neg(pwqp->p[i].qp);
1872                 if (!pwqp->p[i].qp)
1873                         goto error;
1874         }
1875
1876         return pwqp;
1877 error:
1878         isl_pw_qpolynomial_free(pwqp);
1879         return NULL;
1880 }
1881
1882 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub(
1883         __isl_take isl_pw_qpolynomial *pwqp1,
1884         __isl_take isl_pw_qpolynomial *pwqp2)
1885 {
1886         return isl_pw_qpolynomial_add(pwqp1, isl_pw_qpolynomial_neg(pwqp2));
1887 }
1888
1889 __isl_give struct isl_upoly *isl_upoly_eval(
1890         __isl_take struct isl_upoly *up, __isl_take isl_vec *vec)
1891 {
1892         int i;
1893         struct isl_upoly_rec *rec;
1894         struct isl_upoly *res;
1895         struct isl_upoly *base;
1896
1897         if (isl_upoly_is_cst(up)) {
1898                 isl_vec_free(vec);
1899                 return up;
1900         }
1901
1902         rec = isl_upoly_as_rec(up);
1903         if (!rec)
1904                 goto error;
1905
1906         isl_assert(up->ctx, rec->n >= 1, goto error);
1907
1908         base = isl_upoly_rat_cst(up->ctx, vec->el[1 + up->var], vec->el[0]);
1909
1910         res = isl_upoly_eval(isl_upoly_copy(rec->p[rec->n - 1]),
1911                                 isl_vec_copy(vec));
1912
1913         for (i = rec->n - 2; i >= 0; --i) {
1914                 res = isl_upoly_mul(res, isl_upoly_copy(base));
1915                 res = isl_upoly_sum(res, 
1916                             isl_upoly_eval(isl_upoly_copy(rec->p[i]),
1917                                                             isl_vec_copy(vec)));
1918         }
1919
1920         isl_upoly_free(base);
1921         isl_upoly_free(up);
1922         isl_vec_free(vec);
1923         return res;
1924 error:
1925         isl_upoly_free(up);
1926         isl_vec_free(vec);
1927         return NULL;
1928 }
1929
1930 __isl_give isl_qpolynomial *isl_qpolynomial_eval(
1931         __isl_take isl_qpolynomial *qp, __isl_take isl_point *pnt)
1932 {
1933         isl_vec *ext;
1934         struct isl_upoly *up;
1935         isl_dim *dim;
1936
1937         if (!qp || !pnt)
1938                 goto error;
1939         isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, qp->dim), goto error);
1940
1941         if (qp->div->n_row == 0)
1942                 ext = isl_vec_copy(pnt->vec);
1943         else {
1944                 int i;
1945                 unsigned dim = isl_dim_total(qp->dim);
1946                 ext = isl_vec_alloc(qp->dim->ctx, 1 + dim + qp->div->n_row);
1947                 if (!ext)
1948                         goto error;
1949
1950                 isl_seq_cpy(ext->el, pnt->vec->el, pnt->vec->size);
1951                 for (i = 0; i < qp->div->n_row; ++i) {
1952                         isl_seq_inner_product(qp->div->row[i] + 1, ext->el,
1953                                                 1 + dim + i, &ext->el[1+dim+i]);
1954                         isl_int_fdiv_q(ext->el[1+dim+i], ext->el[1+dim+i],
1955                                         qp->div->row[i][0]);
1956                 }
1957         }
1958
1959         up = isl_upoly_eval(isl_upoly_copy(qp->upoly), ext);
1960         if (!up)
1961                 goto error;
1962
1963         dim = isl_dim_copy(qp->dim);
1964         isl_qpolynomial_free(qp);
1965         isl_point_free(pnt);
1966
1967         return isl_qpolynomial_alloc(dim, 0, up);
1968 error:
1969         isl_qpolynomial_free(qp);
1970         isl_point_free(pnt);
1971         return NULL;
1972 }
1973
1974 int isl_upoly_cmp(__isl_keep struct isl_upoly_cst *cst1,
1975         __isl_keep struct isl_upoly_cst *cst2)
1976 {
1977         int cmp;
1978         isl_int t;
1979         isl_int_init(t);
1980         isl_int_mul(t, cst1->n, cst2->d);
1981         isl_int_submul(t, cst2->n, cst1->d);
1982         cmp = isl_int_sgn(t);
1983         isl_int_clear(t);
1984         return cmp;
1985 }
1986
1987 int isl_qpolynomial_le_cst(__isl_keep isl_qpolynomial *qp1,
1988         __isl_keep isl_qpolynomial *qp2)
1989 {
1990         struct isl_upoly_cst *cst1, *cst2;
1991
1992         if (!qp1 || !qp2)
1993                 return -1;
1994         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), return -1);
1995         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), return -1);
1996         if (isl_qpolynomial_is_nan(qp1))
1997                 return -1;
1998         if (isl_qpolynomial_is_nan(qp2))
1999                 return -1;
2000         cst1 = isl_upoly_as_cst(qp1->upoly);
2001         cst2 = isl_upoly_as_cst(qp2->upoly);
2002
2003         return isl_upoly_cmp(cst1, cst2) <= 0;
2004 }
2005
2006 __isl_give isl_qpolynomial *isl_qpolynomial_min_cst(
2007         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
2008 {
2009         struct isl_upoly_cst *cst1, *cst2;
2010         int cmp;
2011
2012         if (!qp1 || !qp2)
2013                 goto error;
2014         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
2015         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
2016         cst1 = isl_upoly_as_cst(qp1->upoly);
2017         cst2 = isl_upoly_as_cst(qp2->upoly);
2018         cmp = isl_upoly_cmp(cst1, cst2);
2019
2020         if (cmp <= 0) {
2021                 isl_qpolynomial_free(qp2);
2022         } else {
2023                 isl_qpolynomial_free(qp1);
2024                 qp1 = qp2;
2025         }
2026         return qp1;
2027 error:
2028         isl_qpolynomial_free(qp1);
2029         isl_qpolynomial_free(qp2);
2030         return NULL;
2031 }
2032
2033 __isl_give isl_qpolynomial *isl_qpolynomial_max_cst(
2034         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
2035 {
2036         struct isl_upoly_cst *cst1, *cst2;
2037         int cmp;
2038
2039         if (!qp1 || !qp2)
2040                 goto error;
2041         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
2042         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
2043         cst1 = isl_upoly_as_cst(qp1->upoly);
2044         cst2 = isl_upoly_as_cst(qp2->upoly);
2045         cmp = isl_upoly_cmp(cst1, cst2);
2046
2047         if (cmp >= 0) {
2048                 isl_qpolynomial_free(qp2);
2049         } else {
2050                 isl_qpolynomial_free(qp1);
2051                 qp1 = qp2;
2052         }
2053         return qp1;
2054 error:
2055         isl_qpolynomial_free(qp1);
2056         isl_qpolynomial_free(qp2);
2057         return NULL;
2058 }
2059
2060 __isl_give isl_qpolynomial *isl_qpolynomial_insert_dims(
2061         __isl_take isl_qpolynomial *qp, enum isl_dim_type type,
2062         unsigned first, unsigned n)
2063 {
2064         unsigned total;
2065         unsigned g_pos;
2066         int *exp;
2067
2068         if (n == 0)
2069                 return qp;
2070
2071         qp = isl_qpolynomial_cow(qp);
2072         if (!qp)
2073                 return NULL;
2074
2075         isl_assert(qp->div->ctx, first <= isl_dim_size(qp->dim, type),
2076                     goto error);
2077
2078         g_pos = pos(qp->dim, type) + first;
2079
2080         qp->div = isl_mat_insert_cols(qp->div, 2 + g_pos, n);
2081         if (!qp->div)
2082                 goto error;
2083
2084         total = qp->div->n_col - 2;
2085         if (total > g_pos) {
2086                 int i;
2087                 exp = isl_alloc_array(qp->div->ctx, int, total - g_pos);
2088                 if (!exp)
2089                         goto error;
2090                 for (i = 0; i < total - g_pos; ++i)
2091                         exp[i] = i + n;
2092                 qp->upoly = expand(qp->upoly, exp, g_pos);
2093                 free(exp);
2094                 if (!qp->upoly)
2095                         goto error;
2096         }
2097
2098         qp->dim = isl_dim_insert(qp->dim, type, first, n);
2099         if (!qp->dim)
2100                 goto error;
2101
2102         return qp;
2103 error:
2104         isl_qpolynomial_free(qp);
2105         return NULL;
2106 }
2107
2108 __isl_give isl_qpolynomial *isl_qpolynomial_add_dims(
2109         __isl_take isl_qpolynomial *qp, enum isl_dim_type type, unsigned n)
2110 {
2111         unsigned pos;
2112
2113         pos = isl_qpolynomial_dim(qp, type);
2114
2115         return isl_qpolynomial_insert_dims(qp, type, pos, n);
2116 }
2117
2118 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_dims(
2119         __isl_take isl_pw_qpolynomial *pwqp,
2120         enum isl_dim_type type, unsigned n)
2121 {
2122         int i;
2123
2124         if (n == 0)
2125                 return pwqp;
2126
2127         pwqp = isl_pw_qpolynomial_cow(pwqp);
2128         if (!pwqp)
2129                 return NULL;
2130
2131         pwqp->dim = isl_dim_add(pwqp->dim, type, n);
2132         if (!pwqp->dim)
2133                 goto error;
2134
2135         for (i = 0; i < pwqp->n; ++i) {
2136                 pwqp->p[i].set = isl_set_add(pwqp->p[i].set, type, n);
2137                 if (!pwqp->p[i].set)
2138                         goto error;
2139                 pwqp->p[i].qp = isl_qpolynomial_add_dims(pwqp->p[i].qp, type, n);
2140                 if (!pwqp->p[i].qp)
2141                         goto error;
2142         }
2143
2144         return pwqp;
2145 error:
2146         isl_pw_qpolynomial_free(pwqp);
2147         return NULL;
2148 }
2149
2150 static int *reordering_move(isl_ctx *ctx,
2151         unsigned len, unsigned dst, unsigned src, unsigned n)
2152 {
2153         int i;
2154         int *reordering;
2155
2156         reordering = isl_alloc_array(ctx, int, len);
2157         if (!reordering)
2158                 return NULL;
2159
2160         if (dst <= src) {
2161                 for (i = 0; i < dst; ++i)
2162                         reordering[i] = i;
2163                 for (i = 0; i < n; ++i)
2164                         reordering[src + i] = dst + i;
2165                 for (i = 0; i < src - dst; ++i)
2166                         reordering[dst + i] = dst + n + i;
2167                 for (i = 0; i < len - src - n; ++i)
2168                         reordering[src + n + i] = src + n + i;
2169         } else {
2170                 for (i = 0; i < src; ++i)
2171                         reordering[i] = i;
2172                 for (i = 0; i < n; ++i)
2173                         reordering[src + i] = dst + i;
2174                 for (i = 0; i < dst - src; ++i)
2175                         reordering[src + n + i] = src + i;
2176                 for (i = 0; i < len - dst - n; ++i)
2177                         reordering[dst + n + i] = dst + n + i;
2178         }
2179
2180         return reordering;
2181 }
2182
2183 static __isl_give struct isl_upoly *reorder(__isl_take struct isl_upoly *up,
2184         int *r)
2185 {
2186         int i;
2187         struct isl_upoly_rec *rec;
2188         struct isl_upoly *base;
2189         struct isl_upoly *res;
2190
2191         if (isl_upoly_is_cst(up))
2192                 return up;
2193
2194         rec = isl_upoly_as_rec(up);
2195         if (!rec)
2196                 goto error;
2197
2198         isl_assert(up->ctx, rec->n >= 1, goto error);
2199
2200         base = isl_upoly_pow(up->ctx, r[up->var], 1);
2201         res = reorder(isl_upoly_copy(rec->p[rec->n - 1]), r);
2202
2203         for (i = rec->n - 2; i >= 0; --i) {
2204                 res = isl_upoly_mul(res, isl_upoly_copy(base));
2205                 res = isl_upoly_sum(res, reorder(isl_upoly_copy(rec->p[i]), r));
2206         }
2207
2208         isl_upoly_free(base);
2209         isl_upoly_free(up);
2210
2211         return res;
2212 error:
2213         isl_upoly_free(up);
2214         return NULL;
2215 }
2216
2217 __isl_give isl_qpolynomial *isl_qpolynomial_move_dims(
2218         __isl_take isl_qpolynomial *qp,
2219         enum isl_dim_type dst_type, unsigned dst_pos,
2220         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2221 {
2222         unsigned g_dst_pos;
2223         unsigned g_src_pos;
2224         int *reordering;
2225
2226         qp = isl_qpolynomial_cow(qp);
2227         if (!qp)
2228                 return NULL;
2229
2230         isl_assert(qp->dim->ctx, src_pos + n <= isl_dim_size(qp->dim, src_type),
2231                 goto error);
2232
2233         g_dst_pos = pos(qp->dim, dst_type) + dst_pos;
2234         g_src_pos = pos(qp->dim, src_type) + src_pos;
2235         if (dst_type > src_type)
2236                 g_dst_pos -= n;
2237
2238         qp->div = isl_mat_move_cols(qp->div, 2 + g_dst_pos, 2 + g_src_pos, n);
2239         qp->div = sort_divs(qp->div);
2240         if (!qp->div)
2241                 goto error;
2242
2243         reordering = reordering_move(qp->dim->ctx,
2244                                 qp->div->n_col - 2, g_dst_pos, g_src_pos, n);
2245         if (!reordering)
2246                 goto error;
2247
2248         qp->upoly = reorder(qp->upoly, reordering);
2249         free(reordering);
2250         if (!qp->upoly)
2251                 goto error;
2252
2253         qp->dim = isl_dim_move(qp->dim, dst_type, dst_pos, src_type, src_pos, n);
2254         if (!qp->dim)
2255                 goto error;
2256
2257         return qp;
2258 error:
2259         isl_qpolynomial_free(qp);
2260         return NULL;
2261 }
2262
2263 __isl_give struct isl_upoly *isl_upoly_from_affine(isl_ctx *ctx, isl_int *f,
2264         isl_int denom, unsigned len)
2265 {
2266         int i;
2267         struct isl_upoly *up;
2268
2269         isl_assert(ctx, len >= 1, return NULL);
2270
2271         up = isl_upoly_rat_cst(ctx, f[0], denom);
2272         for (i = 0; i < len - 1; ++i) {
2273                 struct isl_upoly *t;
2274                 struct isl_upoly *c;
2275
2276                 if (isl_int_is_zero(f[1 + i]))
2277                         continue;
2278
2279                 c = isl_upoly_rat_cst(ctx, f[1 + i], denom);
2280                 t = isl_upoly_pow(ctx, i, 1);
2281                 t = isl_upoly_mul(c, t);
2282                 up = isl_upoly_sum(up, t);
2283         }
2284
2285         return up;
2286 }
2287
2288 __isl_give isl_qpolynomial *isl_qpolynomial_from_affine(__isl_take isl_dim *dim,
2289         isl_int *f, isl_int denom)
2290 {
2291         struct isl_upoly *up;
2292
2293         if (!dim)
2294                 return NULL;
2295
2296         up = isl_upoly_from_affine(dim->ctx, f, denom, 1 + isl_dim_total(dim));
2297
2298         return isl_qpolynomial_alloc(dim, 0, up);
2299 }
2300
2301 __isl_give isl_qpolynomial *isl_qpolynomial_from_constraint(
2302         __isl_take isl_constraint *c, enum isl_dim_type type, unsigned pos)
2303 {
2304         isl_int denom;
2305         isl_dim *dim;
2306         struct isl_upoly *up;
2307         isl_qpolynomial *qp;
2308         int sgn;
2309
2310         if (!c)
2311                 return NULL;
2312
2313         isl_int_init(denom);
2314
2315         isl_constraint_get_coefficient(c, type, pos, &denom);
2316         isl_constraint_set_coefficient(c, type, pos, c->ctx->zero);
2317         sgn = isl_int_sgn(denom);
2318         isl_int_abs(denom, denom);
2319         up = isl_upoly_from_affine(c->ctx, c->line[0], denom,
2320                                         1 + isl_constraint_dim(c, isl_dim_all));
2321         if (sgn < 0)
2322                 isl_int_neg(denom, denom);
2323         isl_constraint_set_coefficient(c, type, pos, denom);
2324
2325         dim = isl_dim_copy(c->bmap->dim);
2326
2327         isl_int_clear(denom);
2328         isl_constraint_free(c);
2329
2330         qp = isl_qpolynomial_alloc(dim, 0, up);
2331         if (sgn > 0)
2332                 qp = isl_qpolynomial_neg(qp);
2333         return qp;
2334 }
2335
2336 __isl_give struct isl_upoly *isl_upoly_subs(__isl_take struct isl_upoly *up,
2337         unsigned first, unsigned n, __isl_keep struct isl_upoly **subs)
2338 {
2339         int i;
2340         struct isl_upoly_rec *rec;
2341         struct isl_upoly *base, *res;
2342
2343         if (!up)
2344                 return NULL;
2345
2346         if (isl_upoly_is_cst(up))
2347                 return up;
2348
2349         if (up->var < first)
2350                 return up;
2351
2352         rec = isl_upoly_as_rec(up);
2353         if (!rec)
2354                 goto error;
2355
2356         isl_assert(up->ctx, rec->n >= 1, goto error);
2357
2358         if (up->var >= first + n)
2359                 base = isl_upoly_pow(up->ctx, up->var, 1);
2360         else
2361                 base = isl_upoly_copy(subs[up->var - first]);
2362
2363         res = isl_upoly_subs(isl_upoly_copy(rec->p[rec->n - 1]), first, n, subs);
2364         for (i = rec->n - 2; i >= 0; --i) {
2365                 struct isl_upoly *t;
2366                 t = isl_upoly_subs(isl_upoly_copy(rec->p[i]), first, n, subs);
2367                 res = isl_upoly_mul(res, isl_upoly_copy(base));
2368                 res = isl_upoly_sum(res, t);
2369         }
2370
2371         isl_upoly_free(base);
2372         isl_upoly_free(up);
2373                                 
2374         return res;
2375 error:
2376         isl_upoly_free(up);
2377         return NULL;
2378 }       
2379
2380 /* For each 0 <= i < "n", replace variable "first" + i of type "type"
2381  * in "qp" by subs[i].
2382  */
2383 __isl_give isl_qpolynomial *isl_qpolynomial_substitute(
2384         __isl_take isl_qpolynomial *qp,
2385         enum isl_dim_type type, unsigned first, unsigned n,
2386         __isl_keep isl_qpolynomial **subs)
2387 {
2388         int i;
2389         struct isl_upoly **ups;
2390
2391         if (n == 0)
2392                 return qp;
2393
2394         qp = isl_qpolynomial_cow(qp);
2395         if (!qp)
2396                 return NULL;
2397         for (i = 0; i < n; ++i)
2398                 if (!subs[i])
2399                         goto error;
2400
2401         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
2402                         goto error);
2403
2404         for (i = 0; i < n; ++i)
2405                 isl_assert(qp->dim->ctx, isl_dim_equal(qp->dim, subs[i]->dim),
2406                                 goto error);
2407
2408         isl_assert(qp->dim->ctx, qp->div->n_row == 0, goto error);
2409         for (i = 0; i < n; ++i)
2410                 isl_assert(qp->dim->ctx, subs[i]->div->n_row == 0, goto error);
2411
2412         first += pos(qp->dim, type);
2413
2414         ups = isl_alloc_array(qp->dim->ctx, struct isl_upoly *, n);
2415         if (!ups)
2416                 goto error;
2417         for (i = 0; i < n; ++i)
2418                 ups[i] = subs[i]->upoly;
2419
2420         qp->upoly = isl_upoly_subs(qp->upoly, first, n, ups);
2421
2422         free(ups);
2423
2424         if (!qp->upoly)
2425                 goto error;
2426
2427         return qp;
2428 error:
2429         isl_qpolynomial_free(qp);
2430         return NULL;
2431 }
2432
2433 __isl_give isl_basic_set *add_div_constraints(__isl_take isl_basic_set *bset,
2434         __isl_take isl_mat *div)
2435 {
2436         int i;
2437         unsigned total;
2438
2439         if (!bset || !div)
2440                 goto error;
2441
2442         bset = isl_basic_set_extend_constraints(bset, 0, 2 * div->n_row);
2443         if (!bset)
2444                 goto error;
2445         total = isl_basic_set_total_dim(bset);
2446         for (i = 0; i < div->n_row; ++i)
2447                 if (isl_basic_set_add_div_constraints_var(bset,
2448                                     total - div->n_row + i, div->row[i]) < 0)
2449                         goto error;
2450
2451         isl_mat_free(div);
2452         return bset;
2453 error:
2454         isl_mat_free(div);
2455         isl_basic_set_free(bset);
2456         return NULL;
2457 }
2458
2459 /* Extend "bset" with extra set dimensions for each integer division
2460  * in "qp" and then call "fn" with the extended bset and the polynomial
2461  * that results from replacing each of the integer divisions by the
2462  * corresponding extra set dimension.
2463  */
2464 int isl_qpolynomial_as_polynomial_on_domain(__isl_keep isl_qpolynomial *qp,
2465         __isl_keep isl_basic_set *bset,
2466         int (*fn)(__isl_take isl_basic_set *bset,
2467                   __isl_take isl_qpolynomial *poly, void *user), void *user)
2468 {
2469         isl_dim *dim;
2470         isl_mat *div;
2471         isl_qpolynomial *poly;
2472
2473         if (!qp || !bset)
2474                 goto error;
2475         if (qp->div->n_row == 0)
2476                 return fn(isl_basic_set_copy(bset), isl_qpolynomial_copy(qp),
2477                           user);
2478
2479         div = isl_mat_copy(qp->div);
2480         dim = isl_dim_copy(qp->dim);
2481         dim = isl_dim_add(dim, isl_dim_set, qp->div->n_row);
2482         poly = isl_qpolynomial_alloc(dim, 0, isl_upoly_copy(qp->upoly));
2483         bset = isl_basic_set_copy(bset);
2484         bset = isl_basic_set_add(bset, isl_dim_set, qp->div->n_row);
2485         bset = add_div_constraints(bset, div);
2486
2487         return fn(bset, poly, user);
2488 error:
2489         return -1;
2490 }
2491
2492 /* Return total degree in variables first (inclusive) up to last (exclusive).
2493  */
2494 int isl_upoly_degree(__isl_keep struct isl_upoly *up, int first, int last)
2495 {
2496         int deg = -1;
2497         int i;
2498         struct isl_upoly_rec *rec;
2499
2500         if (!up)
2501                 return -2;
2502         if (isl_upoly_is_zero(up))
2503                 return -1;
2504         if (isl_upoly_is_cst(up) || up->var < first)
2505                 return 0;
2506
2507         rec = isl_upoly_as_rec(up);
2508         if (!rec)
2509                 return -2;
2510
2511         for (i = 0; i < rec->n; ++i) {
2512                 int d;
2513
2514                 if (isl_upoly_is_zero(rec->p[i]))
2515                         continue;
2516                 d = isl_upoly_degree(rec->p[i], first, last);
2517                 if (up->var < last)
2518                         d += i;
2519                 if (d > deg)
2520                         deg = d;
2521         }
2522
2523         return deg;
2524 }
2525
2526 /* Return total degree in set variables.
2527  */
2528 int isl_qpolynomial_degree(__isl_keep isl_qpolynomial *poly)
2529 {
2530         unsigned ovar;
2531         unsigned nvar;
2532
2533         if (!poly)
2534                 return -2;
2535
2536         ovar = isl_dim_offset(poly->dim, isl_dim_set);
2537         nvar = isl_dim_size(poly->dim, isl_dim_set);
2538         return isl_upoly_degree(poly->upoly, ovar, ovar + nvar);
2539 }
2540
2541 __isl_give struct isl_upoly *isl_upoly_coeff(__isl_keep struct isl_upoly *up,
2542         unsigned pos, int deg)
2543 {
2544         int i;
2545         struct isl_upoly_rec *rec;
2546
2547         if (!up)
2548                 return NULL;
2549
2550         if (isl_upoly_is_cst(up) || up->var < pos) {
2551                 if (deg == 0)
2552                         return isl_upoly_copy(up);
2553                 else
2554                         return isl_upoly_zero(up->ctx);
2555         }
2556
2557         rec = isl_upoly_as_rec(up);
2558         if (!rec)
2559                 return NULL;
2560
2561         if (up->var == pos) {
2562                 if (deg < rec->n)
2563                         return isl_upoly_copy(rec->p[deg]);
2564                 else
2565                         return isl_upoly_zero(up->ctx);
2566         }
2567
2568         up = isl_upoly_copy(up);
2569         up = isl_upoly_cow(up);
2570         rec = isl_upoly_as_rec(up);
2571         if (!rec)
2572                 goto error;
2573
2574         for (i = 0; i < rec->n; ++i) {
2575                 struct isl_upoly *t;
2576                 t = isl_upoly_coeff(rec->p[i], pos, deg);
2577                 if (!t)
2578                         goto error;
2579                 isl_upoly_free(rec->p[i]);
2580                 rec->p[i] = t;
2581         }
2582
2583         return up;
2584 error:
2585         isl_upoly_free(up);
2586         return NULL;
2587 }
2588
2589 /* Return coefficient of power "deg" of variable "t_pos" of type "type".
2590  */
2591 __isl_give isl_qpolynomial *isl_qpolynomial_coeff(
2592         __isl_keep isl_qpolynomial *qp,
2593         enum isl_dim_type type, unsigned t_pos, int deg)
2594 {
2595         unsigned g_pos;
2596         struct isl_upoly *up;
2597         isl_qpolynomial *c;
2598
2599         if (!qp)
2600                 return NULL;
2601
2602         isl_assert(qp->div->ctx, t_pos < isl_dim_size(qp->dim, type),
2603                         return NULL);
2604
2605         g_pos = pos(qp->dim, type) + t_pos;
2606         up = isl_upoly_coeff(qp->upoly, g_pos, deg);
2607
2608         c = isl_qpolynomial_alloc(isl_dim_copy(qp->dim), qp->div->n_row, up);
2609         if (!c)
2610                 return NULL;
2611         isl_mat_free(c->div);
2612         c->div = isl_mat_copy(qp->div);
2613         if (!c->div)
2614                 goto error;
2615         return c;
2616 error:
2617         isl_qpolynomial_free(c);
2618         return NULL;
2619 }
2620
2621 /* Homogenize the polynomial in the variables first (inclusive) up to
2622  * last (exclusive) by inserting powers of variable first.
2623  * Variable first is assumed not to appear in the input.
2624  */
2625 __isl_give struct isl_upoly *isl_upoly_homogenize(
2626         __isl_take struct isl_upoly *up, int deg, int target,
2627         int first, int last)
2628 {
2629         int i;
2630         struct isl_upoly_rec *rec;
2631
2632         if (!up)
2633                 return NULL;
2634         if (isl_upoly_is_zero(up))
2635                 return up;
2636         if (deg == target)
2637                 return up;
2638         if (isl_upoly_is_cst(up) || up->var < first) {
2639                 struct isl_upoly *hom;
2640
2641                 hom = isl_upoly_pow(up->ctx, first, target - deg);
2642                 if (!hom)
2643                         goto error;
2644                 rec = isl_upoly_as_rec(hom);
2645                 rec->p[target - deg] = isl_upoly_mul(rec->p[target - deg], up);
2646
2647                 return hom;
2648         }
2649
2650         up = isl_upoly_cow(up);
2651         rec = isl_upoly_as_rec(up);
2652         if (!rec)
2653                 goto error;
2654
2655         for (i = 0; i < rec->n; ++i) {
2656                 if (isl_upoly_is_zero(rec->p[i]))
2657                         continue;
2658                 rec->p[i] = isl_upoly_homogenize(rec->p[i],
2659                                 up->var < last ? deg + i : i, target,
2660                                 first, last);
2661                 if (!rec->p[i])
2662                         goto error;
2663         }
2664
2665         return up;
2666 error:
2667         isl_upoly_free(up);
2668         return NULL;
2669 }
2670
2671 /* Homogenize the polynomial in the set variables by introducing
2672  * powers of an extra set variable at position 0.
2673  */
2674 __isl_give isl_qpolynomial *isl_qpolynomial_homogenize(
2675         __isl_take isl_qpolynomial *poly)
2676 {
2677         unsigned ovar;
2678         unsigned nvar;
2679         int deg = isl_qpolynomial_degree(poly);
2680
2681         if (deg < -1)
2682                 goto error;
2683
2684         poly = isl_qpolynomial_insert_dims(poly, isl_dim_set, 0, 1);
2685         poly = isl_qpolynomial_cow(poly);
2686         if (!poly)
2687                 goto error;
2688
2689         ovar = isl_dim_offset(poly->dim, isl_dim_set);
2690         nvar = isl_dim_size(poly->dim, isl_dim_set);
2691         poly->upoly = isl_upoly_homogenize(poly->upoly, 0, deg,
2692                                                 ovar, ovar + nvar);
2693         if (!poly->upoly)
2694                 goto error;
2695
2696         return poly;
2697 error:
2698         isl_qpolynomial_free(poly);
2699         return NULL;
2700 }
2701
2702 __isl_give isl_term *isl_term_alloc(__isl_take isl_dim *dim,
2703         __isl_take isl_mat *div)
2704 {
2705         isl_term *term;
2706         int n;
2707
2708         if (!dim || !div)
2709                 goto error;
2710
2711         n = isl_dim_total(dim) + div->n_row;
2712
2713         term = isl_calloc(dim->ctx, struct isl_term,
2714                         sizeof(struct isl_term) + (n - 1) * sizeof(int));
2715         if (!term)
2716                 goto error;
2717
2718         term->ref = 1;
2719         term->dim = dim;
2720         term->div = div;
2721         isl_int_init(term->n);
2722         isl_int_init(term->d);
2723         
2724         return term;
2725 error:
2726         isl_dim_free(dim);
2727         isl_mat_free(div);
2728         return NULL;
2729 }
2730
2731 __isl_give isl_term *isl_term_copy(__isl_keep isl_term *term)
2732 {
2733         if (!term)
2734                 return NULL;
2735
2736         term->ref++;
2737         return term;
2738 }
2739
2740 __isl_give isl_term *isl_term_dup(__isl_keep isl_term *term)
2741 {
2742         int i;
2743         isl_term *dup;
2744         unsigned total;
2745
2746         if (term)
2747                 return NULL;
2748
2749         total = isl_dim_total(term->dim) + term->div->n_row;
2750
2751         dup = isl_term_alloc(isl_dim_copy(term->dim), isl_mat_copy(term->div));
2752         if (!dup)
2753                 return NULL;
2754
2755         isl_int_set(dup->n, term->n);
2756         isl_int_set(dup->d, term->d);
2757
2758         for (i = 0; i < total; ++i)
2759                 dup->pow[i] = term->pow[i];
2760
2761         return dup;
2762 }
2763
2764 __isl_give isl_term *isl_term_cow(__isl_take isl_term *term)
2765 {
2766         if (!term)
2767                 return NULL;
2768
2769         if (term->ref == 1)
2770                 return term;
2771         term->ref--;
2772         return isl_term_dup(term);
2773 }
2774
2775 void isl_term_free(__isl_take isl_term *term)
2776 {
2777         if (!term)
2778                 return;
2779
2780         if (--term->ref > 0)
2781                 return;
2782
2783         isl_dim_free(term->dim);
2784         isl_mat_free(term->div);
2785         isl_int_clear(term->n);
2786         isl_int_clear(term->d);
2787         free(term);
2788 }
2789
2790 unsigned isl_term_dim(__isl_keep isl_term *term, enum isl_dim_type type)
2791 {
2792         if (!term)
2793                 return 0;
2794
2795         switch (type) {
2796         case isl_dim_param:
2797         case isl_dim_in:
2798         case isl_dim_out:       return isl_dim_size(term->dim, type);
2799         case isl_dim_div:       return term->div->n_row;
2800         case isl_dim_all:       return isl_dim_total(term->dim) + term->div->n_row;
2801         default:                return 0;
2802         }
2803 }
2804
2805 isl_ctx *isl_term_get_ctx(__isl_keep isl_term *term)
2806 {
2807         return term ? term->dim->ctx : NULL;
2808 }
2809
2810 void isl_term_get_num(__isl_keep isl_term *term, isl_int *n)
2811 {
2812         if (!term)
2813                 return;
2814         isl_int_set(*n, term->n);
2815 }
2816
2817 void isl_term_get_den(__isl_keep isl_term *term, isl_int *d)
2818 {
2819         if (!term)
2820                 return;
2821         isl_int_set(*d, term->d);
2822 }
2823
2824 int isl_term_get_exp(__isl_keep isl_term *term,
2825         enum isl_dim_type type, unsigned pos)
2826 {
2827         if (!term)
2828                 return -1;
2829
2830         isl_assert(term->dim->ctx, pos < isl_term_dim(term, type), return -1);
2831
2832         if (type >= isl_dim_set)
2833                 pos += isl_dim_size(term->dim, isl_dim_param);
2834         if (type >= isl_dim_div)
2835                 pos += isl_dim_size(term->dim, isl_dim_set);
2836
2837         return term->pow[pos];
2838 }
2839
2840 __isl_give isl_div *isl_term_get_div(__isl_keep isl_term *term, unsigned pos)
2841 {
2842         isl_basic_map *bmap;
2843         unsigned total;
2844         int k;
2845
2846         if (!term)
2847                 return NULL;
2848
2849         isl_assert(term->dim->ctx, pos < isl_term_dim(term, isl_dim_div),
2850                         return NULL);
2851
2852         total = term->div->n_col - term->div->n_row - 2;
2853         /* No nested divs for now */
2854         isl_assert(term->dim->ctx,
2855                 isl_seq_first_non_zero(term->div->row[pos] + 2 + total,
2856                                         term->div->n_row) == -1,
2857                 return NULL);
2858
2859         bmap = isl_basic_map_alloc_dim(isl_dim_copy(term->dim), 1, 0, 0);
2860         if ((k = isl_basic_map_alloc_div(bmap)) < 0)
2861                 goto error;
2862
2863         isl_seq_cpy(bmap->div[k], term->div->row[pos], 2 + total);
2864
2865         return isl_basic_map_div(bmap, k);
2866 error:
2867         isl_basic_map_free(bmap);
2868         return NULL;
2869 }
2870
2871 __isl_give isl_term *isl_upoly_foreach_term(__isl_keep struct isl_upoly *up,
2872         int (*fn)(__isl_take isl_term *term, void *user),
2873         __isl_take isl_term *term, void *user)
2874 {
2875         int i;
2876         struct isl_upoly_rec *rec;
2877
2878         if (!up || !term)
2879                 goto error;
2880
2881         if (isl_upoly_is_zero(up))
2882                 return term;
2883
2884         isl_assert(up->ctx, !isl_upoly_is_nan(up), goto error);
2885         isl_assert(up->ctx, !isl_upoly_is_infty(up), goto error);
2886         isl_assert(up->ctx, !isl_upoly_is_neginfty(up), goto error);
2887
2888         if (isl_upoly_is_cst(up)) {
2889                 struct isl_upoly_cst *cst;
2890                 cst = isl_upoly_as_cst(up);
2891                 if (!cst)
2892                         goto error;
2893                 term = isl_term_cow(term);
2894                 if (!term)
2895                         goto error;
2896                 isl_int_set(term->n, cst->n);
2897                 isl_int_set(term->d, cst->d);
2898                 if (fn(isl_term_copy(term), user) < 0)
2899                         goto error;
2900                 return term;
2901         }
2902
2903         rec = isl_upoly_as_rec(up);
2904         if (!rec)
2905                 goto error;
2906
2907         for (i = 0; i < rec->n; ++i) {
2908                 term = isl_term_cow(term);
2909                 if (!term)
2910                         goto error;
2911                 term->pow[up->var] = i;
2912                 term = isl_upoly_foreach_term(rec->p[i], fn, term, user);
2913                 if (!term)
2914                         goto error;
2915         }
2916         term->pow[up->var] = 0;
2917
2918         return term;
2919 error:
2920         isl_term_free(term);
2921         return NULL;
2922 }
2923
2924 int isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp,
2925         int (*fn)(__isl_take isl_term *term, void *user), void *user)
2926 {
2927         isl_term *term;
2928
2929         if (!qp)
2930                 return -1;
2931
2932         term = isl_term_alloc(isl_dim_copy(qp->dim), isl_mat_copy(qp->div));
2933         if (!term)
2934                 return -1;
2935
2936         term = isl_upoly_foreach_term(qp->upoly, fn, term, user);
2937
2938         isl_term_free(term);
2939
2940         return term ? 0 : -1;
2941 }
2942
2943 __isl_give isl_qpolynomial *isl_qpolynomial_from_term(__isl_take isl_term *term)
2944 {
2945         struct isl_upoly *up;
2946         isl_qpolynomial *qp;
2947         int i, n;
2948
2949         if (!term)
2950                 return NULL;
2951
2952         n = isl_dim_total(term->dim) + term->div->n_row;
2953
2954         up = isl_upoly_rat_cst(term->dim->ctx, term->n, term->d);
2955         for (i = 0; i < n; ++i) {
2956                 if (!term->pow[i])
2957                         continue;
2958                 up = isl_upoly_mul(up,
2959                         isl_upoly_pow(term->dim->ctx, i, term->pow[i]));
2960         }
2961
2962         qp = isl_qpolynomial_alloc(isl_dim_copy(term->dim), term->div->n_row, up);
2963         if (!qp)
2964                 goto error;
2965         isl_mat_free(qp->div);
2966         qp->div = isl_mat_copy(term->div);
2967         if (!qp->div)
2968                 goto error;
2969
2970         isl_term_free(term);
2971         return qp;
2972 error:
2973         isl_qpolynomial_free(qp);
2974         isl_term_free(term);
2975         return NULL;
2976 }
2977
2978 __isl_give isl_qpolynomial *isl_qpolynomial_lift(__isl_take isl_qpolynomial *qp,
2979         __isl_take isl_dim *dim)
2980 {
2981         int i;
2982         int extra;
2983         unsigned total;
2984
2985         if (!qp || !dim)
2986                 goto error;
2987
2988         if (isl_dim_equal(qp->dim, dim)) {
2989                 isl_dim_free(dim);
2990                 return qp;
2991         }
2992
2993         qp = isl_qpolynomial_cow(qp);
2994         if (!qp)
2995                 goto error;
2996
2997         extra = isl_dim_size(dim, isl_dim_set) -
2998                         isl_dim_size(qp->dim, isl_dim_set);
2999         total = isl_dim_total(qp->dim);
3000         if (qp->div->n_row) {
3001                 int *exp;
3002
3003                 exp = isl_alloc_array(qp->div->ctx, int, qp->div->n_row);
3004                 if (!exp)
3005                         goto error;
3006                 for (i = 0; i < qp->div->n_row; ++i)
3007                         exp[i] = extra + i;
3008                 qp->upoly = expand(qp->upoly, exp, total);
3009                 free(exp);
3010                 if (!qp->upoly)
3011                         goto error;
3012         }
3013         qp->div = isl_mat_insert_cols(qp->div, 2 + total, extra);
3014         if (!qp->div)
3015                 goto error;
3016         for (i = 0; i < qp->div->n_row; ++i)
3017                 isl_seq_clr(qp->div->row[i] + 2 + total, extra);
3018
3019         isl_dim_free(qp->dim);
3020         qp->dim = dim;
3021
3022         return qp;
3023 error:
3024         isl_dim_free(dim);
3025         isl_qpolynomial_free(qp);
3026         return NULL;
3027 }
3028
3029 /* For each parameter or variable that does not appear in qp,
3030  * first eliminate the variable from all constraints and then set it to zero.
3031  */
3032 static __isl_give isl_set *fix_inactive(__isl_take isl_set *set,
3033         __isl_keep isl_qpolynomial *qp)
3034 {
3035         int *active = NULL;
3036         int i;
3037         int d;
3038         unsigned nparam;
3039         unsigned nvar;
3040
3041         if (!set || !qp)
3042                 goto error;
3043
3044         d = isl_dim_total(set->dim);
3045         active = isl_calloc_array(set->ctx, int, d);
3046         if (set_active(qp, active) < 0)
3047                 goto error;
3048
3049         for (i = 0; i < d; ++i)
3050                 if (!active[i])
3051                         break;
3052
3053         if (i == d) {
3054                 free(active);
3055                 return set;
3056         }
3057
3058         nparam = isl_dim_size(set->dim, isl_dim_param);
3059         nvar = isl_dim_size(set->dim, isl_dim_set);
3060         for (i = 0; i < nparam; ++i) {
3061                 if (active[i])
3062                         continue;
3063                 set = isl_set_eliminate(set, isl_dim_param, i, 1);
3064                 set = isl_set_fix_si(set, isl_dim_param, i, 0);
3065         }
3066         for (i = 0; i < nvar; ++i) {
3067                 if (active[nparam + i])
3068                         continue;
3069                 set = isl_set_eliminate(set, isl_dim_set, i, 1);
3070                 set = isl_set_fix_si(set, isl_dim_set, i, 0);
3071         }
3072
3073         free(active);
3074
3075         return set;
3076 error:
3077         free(active);
3078         isl_set_free(set);
3079         return NULL;
3080 }
3081
3082 struct isl_opt_data {
3083         isl_qpolynomial *qp;
3084         int first;
3085         isl_qpolynomial *opt;
3086         int max;
3087 };
3088
3089 static int opt_fn(__isl_take isl_point *pnt, void *user)
3090 {
3091         struct isl_opt_data *data = (struct isl_opt_data *)user;
3092         isl_qpolynomial *val;
3093
3094         val = isl_qpolynomial_eval(isl_qpolynomial_copy(data->qp), pnt);
3095         if (data->first) {
3096                 data->first = 0;
3097                 data->opt = val;
3098         } else if (data->max) {
3099                 data->opt = isl_qpolynomial_max_cst(data->opt, val);
3100         } else {
3101                 data->opt = isl_qpolynomial_min_cst(data->opt, val);
3102         }
3103
3104         return 0;
3105 }
3106
3107 __isl_give isl_qpolynomial *isl_qpolynomial_opt_on_domain(
3108         __isl_take isl_qpolynomial *qp, __isl_take isl_set *set, int max)
3109 {
3110         struct isl_opt_data data = { NULL, 1, NULL, max };
3111
3112         if (!set || !qp)
3113                 goto error;
3114
3115         if (isl_upoly_is_cst(qp->upoly)) {
3116                 isl_set_free(set);
3117                 return qp;
3118         }
3119
3120         set = fix_inactive(set, qp);
3121
3122         data.qp = qp;
3123         if (isl_set_foreach_point(set, opt_fn, &data) < 0)
3124                 goto error;
3125
3126         if (data.first)
3127                 data.opt = isl_qpolynomial_zero(isl_qpolynomial_get_dim(qp));
3128
3129         isl_set_free(set);
3130         isl_qpolynomial_free(qp);
3131         return data.opt;
3132 error:
3133         isl_set_free(set);
3134         isl_qpolynomial_free(qp);
3135         isl_qpolynomial_free(data.opt);
3136         return NULL;
3137 }
3138
3139 __isl_give isl_qpolynomial *isl_qpolynomial_morph(__isl_take isl_qpolynomial *qp,
3140         __isl_take isl_morph *morph)
3141 {
3142         int i;
3143         isl_ctx *ctx;
3144         struct isl_upoly *up;
3145         unsigned n_div;
3146         struct isl_upoly **subs;
3147         isl_mat *mat;
3148
3149         qp = isl_qpolynomial_cow(qp);
3150         if (!qp || !morph)
3151                 goto error;
3152
3153         ctx = qp->dim->ctx;
3154         isl_assert(ctx, isl_dim_equal(qp->dim, morph->dom->dim), goto error);
3155
3156         subs = isl_calloc_array(ctx, struct isl_upoly *, morph->inv->n_row - 1);
3157         if (!subs)
3158                 goto error;
3159
3160         for (i = 0; 1 + i < morph->inv->n_row; ++i)
3161                 subs[i] = isl_upoly_from_affine(ctx, morph->inv->row[1 + i],
3162                                         morph->inv->row[0][0], morph->inv->n_col);
3163
3164         qp->upoly = isl_upoly_subs(qp->upoly, 0, morph->inv->n_row - 1, subs);
3165
3166         for (i = 0; 1 + i < morph->inv->n_row; ++i)
3167                 isl_upoly_free(subs[i]);
3168         free(subs);
3169
3170         mat = isl_mat_diagonal(isl_mat_identity(ctx, 1), isl_mat_copy(morph->inv));
3171         mat = isl_mat_diagonal(mat, isl_mat_identity(ctx, qp->div->n_row));
3172         qp->div = isl_mat_product(qp->div, mat);
3173         isl_dim_free(qp->dim);
3174         qp->dim = isl_dim_copy(morph->ran->dim);
3175
3176         if (!qp->upoly || !qp->div || !qp->dim)
3177                 goto error;
3178
3179         isl_morph_free(morph);
3180
3181         return qp;
3182 error:
3183         isl_qpolynomial_free(qp);
3184         isl_morph_free(morph);
3185         return NULL;
3186 }
3187
3188 static int neg_entry(void **entry, void *user)
3189 {
3190         isl_pw_qpolynomial **pwqp = (isl_pw_qpolynomial **)entry;
3191
3192         *pwqp = isl_pw_qpolynomial_neg(*pwqp);
3193
3194         return *pwqp ? 0 : -1;
3195 }
3196
3197 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_neg(
3198         __isl_take isl_union_pw_qpolynomial *upwqp)
3199 {
3200         upwqp = isl_union_pw_qpolynomial_cow(upwqp);
3201         if (!upwqp)
3202                 return NULL;
3203
3204         if (isl_hash_table_foreach(upwqp->dim->ctx, &upwqp->table,
3205                                    &neg_entry, NULL) < 0)
3206                 goto error;
3207
3208         return upwqp;
3209 error:
3210         isl_union_pw_qpolynomial_free(upwqp);
3211         return NULL;
3212 }
3213
3214 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub(
3215         __isl_take isl_union_pw_qpolynomial *upwqp1,
3216         __isl_take isl_union_pw_qpolynomial *upwqp2)
3217 {
3218         return isl_union_pw_qpolynomial_add(upwqp1,
3219                                         isl_union_pw_qpolynomial_neg(upwqp2));
3220 }
3221
3222 static int mul_entry(void **entry, void *user)
3223 {
3224         struct isl_union_pw_qpolynomial_match_bin_data *data = user;
3225         uint32_t hash;
3226         struct isl_hash_table_entry *entry2;
3227         isl_pw_qpolynomial *pwpq = *entry;
3228         int empty;
3229
3230         hash = isl_dim_get_hash(pwpq->dim);
3231         entry2 = isl_hash_table_find(data->upwqp2->dim->ctx,
3232                                      &data->upwqp2->table,
3233                                      hash, &has_dim, pwpq->dim, 0);
3234         if (!entry2)
3235                 return 0;
3236
3237         pwpq = isl_pw_qpolynomial_copy(pwpq);
3238         pwpq = isl_pw_qpolynomial_mul(pwpq,
3239                                       isl_pw_qpolynomial_copy(entry2->data));
3240
3241         empty = isl_pw_qpolynomial_is_zero(pwpq);
3242         if (empty < 0) {
3243                 isl_pw_qpolynomial_free(pwpq);
3244                 return -1;
3245         }
3246         if (empty) {
3247                 isl_pw_qpolynomial_free(pwpq);
3248                 return 0;
3249         }
3250
3251         data->res = isl_union_pw_qpolynomial_add_pw_qpolynomial(data->res, pwpq);
3252
3253         return 0;
3254 }
3255
3256 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul(
3257         __isl_take isl_union_pw_qpolynomial *upwqp1,
3258         __isl_take isl_union_pw_qpolynomial *upwqp2)
3259 {
3260         return match_bin_op(upwqp1, upwqp2, &mul_entry);
3261 }