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