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