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