add isl_union_pw_qpolynomial_to_polynomial
[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_factorization.h>
13 #include <isl_lp.h>
14 #include <isl_seq.h>
15 #include <isl_union_map_private.h>
16 #include <isl_polynomial_private.h>
17 #include <isl_point_private.h>
18 #include <isl_dim_private.h>
19 #include <isl_map_private.h>
20 #include <isl_mat_private.h>
21 #include <isl_range.h>
22
23 static unsigned pos(__isl_keep isl_dim *dim, enum isl_dim_type type)
24 {
25         switch (type) {
26         case isl_dim_param:     return 0;
27         case isl_dim_in:        return dim->nparam;
28         case isl_dim_out:       return dim->nparam + dim->n_in;
29         default:                return 0;
30         }
31 }
32
33 int isl_upoly_is_cst(__isl_keep struct isl_upoly *up)
34 {
35         if (!up)
36                 return -1;
37
38         return up->var < 0;
39 }
40
41 __isl_keep struct isl_upoly_cst *isl_upoly_as_cst(__isl_keep struct isl_upoly *up)
42 {
43         if (!up)
44                 return NULL;
45
46         isl_assert(up->ctx, up->var < 0, return NULL);
47
48         return (struct isl_upoly_cst *)up;
49 }
50
51 __isl_keep struct isl_upoly_rec *isl_upoly_as_rec(__isl_keep struct isl_upoly *up)
52 {
53         if (!up)
54                 return NULL;
55
56         isl_assert(up->ctx, up->var >= 0, return NULL);
57
58         return (struct isl_upoly_rec *)up;
59 }
60
61 int isl_upoly_is_equal(__isl_keep struct isl_upoly *up1,
62         __isl_keep struct isl_upoly *up2)
63 {
64         int i;
65         struct isl_upoly_rec *rec1, *rec2;
66
67         if (!up1 || !up2)
68                 return -1;
69         if (up1 == up2)
70                 return 1;
71         if (up1->var != up2->var)
72                 return 0;
73         if (isl_upoly_is_cst(up1)) {
74                 struct isl_upoly_cst *cst1, *cst2;
75                 cst1 = isl_upoly_as_cst(up1);
76                 cst2 = isl_upoly_as_cst(up2);
77                 if (!cst1 || !cst2)
78                         return -1;
79                 return isl_int_eq(cst1->n, cst2->n) &&
80                        isl_int_eq(cst1->d, cst2->d);
81         }
82
83         rec1 = isl_upoly_as_rec(up1);
84         rec2 = isl_upoly_as_rec(up2);
85         if (!rec1 || !rec2)
86                 return -1;
87
88         if (rec1->n != rec2->n)
89                 return 0;
90
91         for (i = 0; i < rec1->n; ++i) {
92                 int eq = isl_upoly_is_equal(rec1->p[i], rec2->p[i]);
93                 if (eq < 0 || !eq)
94                         return eq;
95         }
96
97         return 1;
98 }
99
100 int isl_upoly_is_zero(__isl_keep struct isl_upoly *up)
101 {
102         struct isl_upoly_cst *cst;
103
104         if (!up)
105                 return -1;
106         if (!isl_upoly_is_cst(up))
107                 return 0;
108
109         cst = isl_upoly_as_cst(up);
110         if (!cst)
111                 return -1;
112
113         return isl_int_is_zero(cst->n) && isl_int_is_pos(cst->d);
114 }
115
116 int isl_upoly_sgn(__isl_keep struct isl_upoly *up)
117 {
118         struct isl_upoly_cst *cst;
119
120         if (!up)
121                 return 0;
122         if (!isl_upoly_is_cst(up))
123                 return 0;
124
125         cst = isl_upoly_as_cst(up);
126         if (!cst)
127                 return 0;
128
129         return isl_int_sgn(cst->n);
130 }
131
132 int isl_upoly_is_nan(__isl_keep struct isl_upoly *up)
133 {
134         struct isl_upoly_cst *cst;
135
136         if (!up)
137                 return -1;
138         if (!isl_upoly_is_cst(up))
139                 return 0;
140
141         cst = isl_upoly_as_cst(up);
142         if (!cst)
143                 return -1;
144
145         return isl_int_is_zero(cst->n) && isl_int_is_zero(cst->d);
146 }
147
148 int isl_upoly_is_infty(__isl_keep struct isl_upoly *up)
149 {
150         struct isl_upoly_cst *cst;
151
152         if (!up)
153                 return -1;
154         if (!isl_upoly_is_cst(up))
155                 return 0;
156
157         cst = isl_upoly_as_cst(up);
158         if (!cst)
159                 return -1;
160
161         return isl_int_is_pos(cst->n) && isl_int_is_zero(cst->d);
162 }
163
164 int isl_upoly_is_neginfty(__isl_keep struct isl_upoly *up)
165 {
166         struct isl_upoly_cst *cst;
167
168         if (!up)
169                 return -1;
170         if (!isl_upoly_is_cst(up))
171                 return 0;
172
173         cst = isl_upoly_as_cst(up);
174         if (!cst)
175                 return -1;
176
177         return isl_int_is_neg(cst->n) && isl_int_is_zero(cst->d);
178 }
179
180 int isl_upoly_is_one(__isl_keep struct isl_upoly *up)
181 {
182         struct isl_upoly_cst *cst;
183
184         if (!up)
185                 return -1;
186         if (!isl_upoly_is_cst(up))
187                 return 0;
188
189         cst = isl_upoly_as_cst(up);
190         if (!cst)
191                 return -1;
192
193         return isl_int_eq(cst->n, cst->d) && isl_int_is_pos(cst->d);
194 }
195
196 int isl_upoly_is_negone(__isl_keep struct isl_upoly *up)
197 {
198         struct isl_upoly_cst *cst;
199
200         if (!up)
201                 return -1;
202         if (!isl_upoly_is_cst(up))
203                 return 0;
204
205         cst = isl_upoly_as_cst(up);
206         if (!cst)
207                 return -1;
208
209         return isl_int_is_negone(cst->n) && isl_int_is_one(cst->d);
210 }
211
212 __isl_give struct isl_upoly_cst *isl_upoly_cst_alloc(struct isl_ctx *ctx)
213 {
214         struct isl_upoly_cst *cst;
215
216         cst = isl_alloc_type(ctx, struct isl_upoly_cst);
217         if (!cst)
218                 return NULL;
219
220         cst->up.ref = 1;
221         cst->up.ctx = ctx;
222         isl_ctx_ref(ctx);
223         cst->up.var = -1;
224
225         isl_int_init(cst->n);
226         isl_int_init(cst->d);
227
228         return cst;
229 }
230
231 __isl_give struct isl_upoly *isl_upoly_zero(struct isl_ctx *ctx)
232 {
233         struct isl_upoly_cst *cst;
234
235         cst = isl_upoly_cst_alloc(ctx);
236         if (!cst)
237                 return NULL;
238
239         isl_int_set_si(cst->n, 0);
240         isl_int_set_si(cst->d, 1);
241
242         return &cst->up;
243 }
244
245 __isl_give struct isl_upoly *isl_upoly_one(struct isl_ctx *ctx)
246 {
247         struct isl_upoly_cst *cst;
248
249         cst = isl_upoly_cst_alloc(ctx);
250         if (!cst)
251                 return NULL;
252
253         isl_int_set_si(cst->n, 1);
254         isl_int_set_si(cst->d, 1);
255
256         return &cst->up;
257 }
258
259 __isl_give struct isl_upoly *isl_upoly_infty(struct isl_ctx *ctx)
260 {
261         struct isl_upoly_cst *cst;
262
263         cst = isl_upoly_cst_alloc(ctx);
264         if (!cst)
265                 return NULL;
266
267         isl_int_set_si(cst->n, 1);
268         isl_int_set_si(cst->d, 0);
269
270         return &cst->up;
271 }
272
273 __isl_give struct isl_upoly *isl_upoly_neginfty(struct isl_ctx *ctx)
274 {
275         struct isl_upoly_cst *cst;
276
277         cst = isl_upoly_cst_alloc(ctx);
278         if (!cst)
279                 return NULL;
280
281         isl_int_set_si(cst->n, -1);
282         isl_int_set_si(cst->d, 0);
283
284         return &cst->up;
285 }
286
287 __isl_give struct isl_upoly *isl_upoly_nan(struct isl_ctx *ctx)
288 {
289         struct isl_upoly_cst *cst;
290
291         cst = isl_upoly_cst_alloc(ctx);
292         if (!cst)
293                 return NULL;
294
295         isl_int_set_si(cst->n, 0);
296         isl_int_set_si(cst->d, 0);
297
298         return &cst->up;
299 }
300
301 __isl_give struct isl_upoly *isl_upoly_rat_cst(struct isl_ctx *ctx,
302         isl_int n, isl_int d)
303 {
304         struct isl_upoly_cst *cst;
305
306         cst = isl_upoly_cst_alloc(ctx);
307         if (!cst)
308                 return NULL;
309
310         isl_int_set(cst->n, n);
311         isl_int_set(cst->d, d);
312
313         return &cst->up;
314 }
315
316 __isl_give struct isl_upoly_rec *isl_upoly_alloc_rec(struct isl_ctx *ctx,
317         int var, int size)
318 {
319         struct isl_upoly_rec *rec;
320
321         isl_assert(ctx, var >= 0, return NULL);
322         isl_assert(ctx, size >= 0, return NULL);
323         rec = isl_calloc(ctx, struct isl_upoly_rec,
324                         sizeof(struct isl_upoly_rec) +
325                         (size - 1) * sizeof(struct isl_upoly *));
326         if (!rec)
327                 return NULL;
328
329         rec->up.ref = 1;
330         rec->up.ctx = ctx;
331         isl_ctx_ref(ctx);
332         rec->up.var = var;
333
334         rec->n = 0;
335         rec->size = size;
336
337         return rec;
338 }
339
340 __isl_give isl_qpolynomial *isl_qpolynomial_reset_dim(
341         __isl_take isl_qpolynomial *qp, __isl_take isl_dim *dim)
342 {
343         qp = isl_qpolynomial_cow(qp);
344         if (!qp || !dim)
345                 goto error;
346
347         isl_dim_free(qp->dim);
348         qp->dim = dim;
349
350         return qp;
351 error:
352         isl_qpolynomial_free(qp);
353         isl_dim_free(dim);
354         return NULL;
355 }
356
357 isl_ctx *isl_qpolynomial_get_ctx(__isl_keep isl_qpolynomial *qp)
358 {
359         return qp ? qp->dim->ctx : NULL;
360 }
361
362 __isl_give isl_dim *isl_qpolynomial_get_dim(__isl_keep isl_qpolynomial *qp)
363 {
364         return qp ? isl_dim_copy(qp->dim) : NULL;
365 }
366
367 unsigned isl_qpolynomial_dim(__isl_keep isl_qpolynomial *qp,
368         enum isl_dim_type type)
369 {
370         return qp ? isl_dim_size(qp->dim, type) : 0;
371 }
372
373 int isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp)
374 {
375         return qp ? isl_upoly_is_zero(qp->upoly) : -1;
376 }
377
378 int isl_qpolynomial_is_one(__isl_keep isl_qpolynomial *qp)
379 {
380         return qp ? isl_upoly_is_one(qp->upoly) : -1;
381 }
382
383 int isl_qpolynomial_is_nan(__isl_keep isl_qpolynomial *qp)
384 {
385         return qp ? isl_upoly_is_nan(qp->upoly) : -1;
386 }
387
388 int isl_qpolynomial_is_infty(__isl_keep isl_qpolynomial *qp)
389 {
390         return qp ? isl_upoly_is_infty(qp->upoly) : -1;
391 }
392
393 int isl_qpolynomial_is_neginfty(__isl_keep isl_qpolynomial *qp)
394 {
395         return qp ? isl_upoly_is_neginfty(qp->upoly) : -1;
396 }
397
398 int isl_qpolynomial_sgn(__isl_keep isl_qpolynomial *qp)
399 {
400         return qp ? isl_upoly_sgn(qp->upoly) : 0;
401 }
402
403 static void upoly_free_cst(__isl_take struct isl_upoly_cst *cst)
404 {
405         isl_int_clear(cst->n);
406         isl_int_clear(cst->d);
407 }
408
409 static void upoly_free_rec(__isl_take struct isl_upoly_rec *rec)
410 {
411         int i;
412
413         for (i = 0; i < rec->n; ++i)
414                 isl_upoly_free(rec->p[i]);
415 }
416
417 __isl_give struct isl_upoly *isl_upoly_copy(__isl_keep struct isl_upoly *up)
418 {
419         if (!up)
420                 return NULL;
421
422         up->ref++;
423         return up;
424 }
425
426 __isl_give struct isl_upoly *isl_upoly_dup_cst(__isl_keep struct isl_upoly *up)
427 {
428         struct isl_upoly_cst *cst;
429         struct isl_upoly_cst *dup;
430
431         cst = isl_upoly_as_cst(up);
432         if (!cst)
433                 return NULL;
434
435         dup = isl_upoly_as_cst(isl_upoly_zero(up->ctx));
436         if (!dup)
437                 return NULL;
438         isl_int_set(dup->n, cst->n);
439         isl_int_set(dup->d, cst->d);
440
441         return &dup->up;
442 }
443
444 __isl_give struct isl_upoly *isl_upoly_dup_rec(__isl_keep struct isl_upoly *up)
445 {
446         int i;
447         struct isl_upoly_rec *rec;
448         struct isl_upoly_rec *dup;
449
450         rec = isl_upoly_as_rec(up);
451         if (!rec)
452                 return NULL;
453
454         dup = isl_upoly_alloc_rec(up->ctx, up->var, rec->n);
455         if (!dup)
456                 return NULL;
457
458         for (i = 0; i < rec->n; ++i) {
459                 dup->p[i] = isl_upoly_copy(rec->p[i]);
460                 if (!dup->p[i])
461                         goto error;
462                 dup->n++;
463         }
464
465         return &dup->up;
466 error:
467         isl_upoly_free(&dup->up);
468         return NULL;
469 }
470
471 __isl_give struct isl_upoly *isl_upoly_dup(__isl_keep struct isl_upoly *up)
472 {
473         struct isl_upoly *dup;
474
475         if (!up)
476                 return NULL;
477
478         if (isl_upoly_is_cst(up))
479                 return isl_upoly_dup_cst(up);
480         else
481                 return isl_upoly_dup_rec(up);
482 }
483
484 __isl_give struct isl_upoly *isl_upoly_cow(__isl_take struct isl_upoly *up)
485 {
486         if (!up)
487                 return NULL;
488
489         if (up->ref == 1)
490                 return up;
491         up->ref--;
492         return isl_upoly_dup(up);
493 }
494
495 void isl_upoly_free(__isl_take struct isl_upoly *up)
496 {
497         if (!up)
498                 return;
499
500         if (--up->ref > 0)
501                 return;
502
503         if (up->var < 0)
504                 upoly_free_cst((struct isl_upoly_cst *)up);
505         else
506                 upoly_free_rec((struct isl_upoly_rec *)up);
507
508         isl_ctx_deref(up->ctx);
509         free(up);
510 }
511
512 static void isl_upoly_cst_reduce(__isl_keep struct isl_upoly_cst *cst)
513 {
514         isl_int gcd;
515
516         isl_int_init(gcd);
517         isl_int_gcd(gcd, cst->n, cst->d);
518         if (!isl_int_is_zero(gcd) && !isl_int_is_one(gcd)) {
519                 isl_int_divexact(cst->n, cst->n, gcd);
520                 isl_int_divexact(cst->d, cst->d, gcd);
521         }
522         isl_int_clear(gcd);
523 }
524
525 __isl_give struct isl_upoly *isl_upoly_sum_cst(__isl_take struct isl_upoly *up1,
526         __isl_take struct isl_upoly *up2)
527 {
528         struct isl_upoly_cst *cst1;
529         struct isl_upoly_cst *cst2;
530
531         up1 = isl_upoly_cow(up1);
532         if (!up1 || !up2)
533                 goto error;
534
535         cst1 = isl_upoly_as_cst(up1);
536         cst2 = isl_upoly_as_cst(up2);
537
538         if (isl_int_eq(cst1->d, cst2->d))
539                 isl_int_add(cst1->n, cst1->n, cst2->n);
540         else {
541                 isl_int_mul(cst1->n, cst1->n, cst2->d);
542                 isl_int_addmul(cst1->n, cst2->n, cst1->d);
543                 isl_int_mul(cst1->d, cst1->d, cst2->d);
544         }
545
546         isl_upoly_cst_reduce(cst1);
547
548         isl_upoly_free(up2);
549         return up1;
550 error:
551         isl_upoly_free(up1);
552         isl_upoly_free(up2);
553         return NULL;
554 }
555
556 static __isl_give struct isl_upoly *replace_by_zero(
557         __isl_take struct isl_upoly *up)
558 {
559         struct isl_ctx *ctx;
560
561         if (!up)
562                 return NULL;
563         ctx = up->ctx;
564         isl_upoly_free(up);
565         return isl_upoly_zero(ctx);
566 }
567
568 static __isl_give struct isl_upoly *replace_by_constant_term(
569         __isl_take struct isl_upoly *up)
570 {
571         struct isl_upoly_rec *rec;
572         struct isl_upoly *cst;
573
574         if (!up)
575                 return NULL;
576
577         rec = isl_upoly_as_rec(up);
578         if (!rec)
579                 goto error;
580         cst = isl_upoly_copy(rec->p[0]);
581         isl_upoly_free(up);
582         return cst;
583 error:
584         isl_upoly_free(up);
585         return NULL;
586 }
587
588 __isl_give struct isl_upoly *isl_upoly_sum(__isl_take struct isl_upoly *up1,
589         __isl_take struct isl_upoly *up2)
590 {
591         int i;
592         struct isl_upoly_rec *rec1, *rec2;
593
594         if (!up1 || !up2)
595                 goto error;
596
597         if (isl_upoly_is_nan(up1)) {
598                 isl_upoly_free(up2);
599                 return up1;
600         }
601
602         if (isl_upoly_is_nan(up2)) {
603                 isl_upoly_free(up1);
604                 return up2;
605         }
606
607         if (isl_upoly_is_zero(up1)) {
608                 isl_upoly_free(up1);
609                 return up2;
610         }
611
612         if (isl_upoly_is_zero(up2)) {
613                 isl_upoly_free(up2);
614                 return up1;
615         }
616
617         if (up1->var < up2->var)
618                 return isl_upoly_sum(up2, up1);
619
620         if (up2->var < up1->var) {
621                 struct isl_upoly_rec *rec;
622                 if (isl_upoly_is_infty(up2) || isl_upoly_is_neginfty(up2)) {
623                         isl_upoly_free(up1);
624                         return up2;
625                 }
626                 up1 = isl_upoly_cow(up1);
627                 rec = isl_upoly_as_rec(up1);
628                 if (!rec)
629                         goto error;
630                 rec->p[0] = isl_upoly_sum(rec->p[0], up2);
631                 if (rec->n == 1)
632                         up1 = replace_by_constant_term(up1);
633                 return up1;
634         }
635
636         if (isl_upoly_is_cst(up1))
637                 return isl_upoly_sum_cst(up1, up2);
638
639         rec1 = isl_upoly_as_rec(up1);
640         rec2 = isl_upoly_as_rec(up2);
641         if (!rec1 || !rec2)
642                 goto error;
643
644         if (rec1->n < rec2->n)
645                 return isl_upoly_sum(up2, up1);
646
647         up1 = isl_upoly_cow(up1);
648         rec1 = isl_upoly_as_rec(up1);
649         if (!rec1)
650                 goto error;
651
652         for (i = rec2->n - 1; i >= 0; --i) {
653                 rec1->p[i] = isl_upoly_sum(rec1->p[i],
654                                             isl_upoly_copy(rec2->p[i]));
655                 if (!rec1->p[i])
656                         goto error;
657                 if (i == rec1->n - 1 && isl_upoly_is_zero(rec1->p[i])) {
658                         isl_upoly_free(rec1->p[i]);
659                         rec1->n--;
660                 }
661         }
662
663         if (rec1->n == 0)
664                 up1 = replace_by_zero(up1);
665         else if (rec1->n == 1)
666                 up1 = replace_by_constant_term(up1);
667
668         isl_upoly_free(up2);
669
670         return up1;
671 error:
672         isl_upoly_free(up1);
673         isl_upoly_free(up2);
674         return NULL;
675 }
676
677 __isl_give struct isl_upoly *isl_upoly_neg_cst(__isl_take struct isl_upoly *up)
678 {
679         struct isl_upoly_cst *cst;
680
681         if (isl_upoly_is_zero(up))
682                 return up;
683
684         up = isl_upoly_cow(up);
685         if (!up)
686                 return NULL;
687
688         cst = isl_upoly_as_cst(up);
689
690         isl_int_neg(cst->n, cst->n);
691
692         return up;
693 }
694
695 __isl_give struct isl_upoly *isl_upoly_neg(__isl_take struct isl_upoly *up)
696 {
697         int i;
698         struct isl_upoly_rec *rec;
699
700         if (!up)
701                 return NULL;
702
703         if (isl_upoly_is_cst(up))
704                 return isl_upoly_neg_cst(up);
705
706         up = isl_upoly_cow(up);
707         rec = isl_upoly_as_rec(up);
708         if (!rec)
709                 goto error;
710
711         for (i = 0; i < rec->n; ++i) {
712                 rec->p[i] = isl_upoly_neg(rec->p[i]);
713                 if (!rec->p[i])
714                         goto error;
715         }
716
717         return up;
718 error:
719         isl_upoly_free(up);
720         return NULL;
721 }
722
723 __isl_give struct isl_upoly *isl_upoly_mul_cst(__isl_take struct isl_upoly *up1,
724         __isl_take struct isl_upoly *up2)
725 {
726         struct isl_upoly_cst *cst1;
727         struct isl_upoly_cst *cst2;
728
729         up1 = isl_upoly_cow(up1);
730         if (!up1 || !up2)
731                 goto error;
732
733         cst1 = isl_upoly_as_cst(up1);
734         cst2 = isl_upoly_as_cst(up2);
735
736         isl_int_mul(cst1->n, cst1->n, cst2->n);
737         isl_int_mul(cst1->d, cst1->d, cst2->d);
738
739         isl_upoly_cst_reduce(cst1);
740
741         isl_upoly_free(up2);
742         return up1;
743 error:
744         isl_upoly_free(up1);
745         isl_upoly_free(up2);
746         return NULL;
747 }
748
749 __isl_give struct isl_upoly *isl_upoly_mul_rec(__isl_take struct isl_upoly *up1,
750         __isl_take struct isl_upoly *up2)
751 {
752         struct isl_upoly_rec *rec1;
753         struct isl_upoly_rec *rec2;
754         struct isl_upoly_rec *res;
755         int i, j;
756         int size;
757
758         rec1 = isl_upoly_as_rec(up1);
759         rec2 = isl_upoly_as_rec(up2);
760         if (!rec1 || !rec2)
761                 goto error;
762         size = rec1->n + rec2->n - 1;
763         res = isl_upoly_alloc_rec(up1->ctx, up1->var, size);
764         if (!res)
765                 goto error;
766
767         for (i = 0; i < rec1->n; ++i) {
768                 res->p[i] = isl_upoly_mul(isl_upoly_copy(rec2->p[0]),
769                                             isl_upoly_copy(rec1->p[i]));
770                 if (!res->p[i])
771                         goto error;
772                 res->n++;
773         }
774         for (; i < size; ++i) {
775                 res->p[i] = isl_upoly_zero(up1->ctx);
776                 if (!res->p[i])
777                         goto error;
778                 res->n++;
779         }
780         for (i = 0; i < rec1->n; ++i) {
781                 for (j = 1; j < rec2->n; ++j) {
782                         struct isl_upoly *up;
783                         up = isl_upoly_mul(isl_upoly_copy(rec2->p[j]),
784                                             isl_upoly_copy(rec1->p[i]));
785                         res->p[i + j] = isl_upoly_sum(res->p[i + j], up);
786                         if (!res->p[i + j])
787                                 goto error;
788                 }
789         }
790
791         isl_upoly_free(up1);
792         isl_upoly_free(up2);
793
794         return &res->up;
795 error:
796         isl_upoly_free(up1);
797         isl_upoly_free(up2);
798         isl_upoly_free(&res->up);
799         return NULL;
800 }
801
802 __isl_give struct isl_upoly *isl_upoly_mul(__isl_take struct isl_upoly *up1,
803         __isl_take struct isl_upoly *up2)
804 {
805         if (!up1 || !up2)
806                 goto error;
807
808         if (isl_upoly_is_nan(up1)) {
809                 isl_upoly_free(up2);
810                 return up1;
811         }
812
813         if (isl_upoly_is_nan(up2)) {
814                 isl_upoly_free(up1);
815                 return up2;
816         }
817
818         if (isl_upoly_is_zero(up1)) {
819                 isl_upoly_free(up2);
820                 return up1;
821         }
822
823         if (isl_upoly_is_zero(up2)) {
824                 isl_upoly_free(up1);
825                 return up2;
826         }
827
828         if (isl_upoly_is_one(up1)) {
829                 isl_upoly_free(up1);
830                 return up2;
831         }
832
833         if (isl_upoly_is_one(up2)) {
834                 isl_upoly_free(up2);
835                 return up1;
836         }
837
838         if (up1->var < up2->var)
839                 return isl_upoly_mul(up2, up1);
840
841         if (up2->var < up1->var) {
842                 int i;
843                 struct isl_upoly_rec *rec;
844                 if (isl_upoly_is_infty(up2) || isl_upoly_is_neginfty(up2)) {
845                         isl_ctx *ctx = up1->ctx;
846                         isl_upoly_free(up1);
847                         isl_upoly_free(up2);
848                         return isl_upoly_nan(ctx);
849                 }
850                 up1 = isl_upoly_cow(up1);
851                 rec = isl_upoly_as_rec(up1);
852                 if (!rec)
853                         goto error;
854
855                 for (i = 0; i < rec->n; ++i) {
856                         rec->p[i] = isl_upoly_mul(rec->p[i],
857                                                     isl_upoly_copy(up2));
858                         if (!rec->p[i])
859                                 goto error;
860                 }
861                 isl_upoly_free(up2);
862                 return up1;
863         }
864
865         if (isl_upoly_is_cst(up1))
866                 return isl_upoly_mul_cst(up1, up2);
867
868         return isl_upoly_mul_rec(up1, up2);
869 error:
870         isl_upoly_free(up1);
871         isl_upoly_free(up2);
872         return NULL;
873 }
874
875 __isl_give isl_qpolynomial *isl_qpolynomial_alloc(__isl_take isl_dim *dim,
876         unsigned n_div, __isl_take struct isl_upoly *up)
877 {
878         struct isl_qpolynomial *qp = NULL;
879         unsigned total;
880
881         if (!dim || !up)
882                 goto error;
883
884         total = isl_dim_total(dim);
885
886         qp = isl_calloc_type(dim->ctx, struct isl_qpolynomial);
887         if (!qp)
888                 goto error;
889
890         qp->ref = 1;
891         qp->div = isl_mat_alloc(dim->ctx, n_div, 1 + 1 + total + n_div);
892         if (!qp->div)
893                 goto error;
894
895         qp->dim = dim;
896         qp->upoly = up;
897
898         return qp;
899 error:
900         isl_dim_free(dim);
901         isl_upoly_free(up);
902         isl_qpolynomial_free(qp);
903         return NULL;
904 }
905
906 __isl_give isl_qpolynomial *isl_qpolynomial_copy(__isl_keep isl_qpolynomial *qp)
907 {
908         if (!qp)
909                 return NULL;
910
911         qp->ref++;
912         return qp;
913 }
914
915 __isl_give isl_qpolynomial *isl_qpolynomial_dup(__isl_keep isl_qpolynomial *qp)
916 {
917         struct isl_qpolynomial *dup;
918
919         if (!qp)
920                 return NULL;
921
922         dup = isl_qpolynomial_alloc(isl_dim_copy(qp->dim), qp->div->n_row,
923                                     isl_upoly_copy(qp->upoly));
924         if (!dup)
925                 return NULL;
926         isl_mat_free(dup->div);
927         dup->div = isl_mat_copy(qp->div);
928         if (!dup->div)
929                 goto error;
930
931         return dup;
932 error:
933         isl_qpolynomial_free(dup);
934         return NULL;
935 }
936
937 __isl_give isl_qpolynomial *isl_qpolynomial_cow(__isl_take isl_qpolynomial *qp)
938 {
939         if (!qp)
940                 return NULL;
941
942         if (qp->ref == 1)
943                 return qp;
944         qp->ref--;
945         return isl_qpolynomial_dup(qp);
946 }
947
948 void isl_qpolynomial_free(__isl_take isl_qpolynomial *qp)
949 {
950         if (!qp)
951                 return;
952
953         if (--qp->ref > 0)
954                 return;
955
956         isl_dim_free(qp->dim);
957         isl_mat_free(qp->div);
958         isl_upoly_free(qp->upoly);
959
960         free(qp);
961 }
962
963 __isl_give struct isl_upoly *isl_upoly_pow(isl_ctx *ctx, int pos, int power)
964 {
965         int i;
966         struct isl_upoly *up;
967         struct isl_upoly_rec *rec;
968         struct isl_upoly_cst *cst;
969
970         rec = isl_upoly_alloc_rec(ctx, pos, 1 + power);
971         if (!rec)
972                 return NULL;
973         for (i = 0; i < 1 + power; ++i) {
974                 rec->p[i] = isl_upoly_zero(ctx);
975                 if (!rec->p[i])
976                         goto error;
977                 rec->n++;
978         }
979         cst = isl_upoly_as_cst(rec->p[power]);
980         isl_int_set_si(cst->n, 1);
981
982         return &rec->up;
983 error:
984         isl_upoly_free(&rec->up);
985         return NULL;
986 }
987
988 /* r array maps original positions to new positions.
989  */
990 static __isl_give struct isl_upoly *reorder(__isl_take struct isl_upoly *up,
991         int *r)
992 {
993         int i;
994         struct isl_upoly_rec *rec;
995         struct isl_upoly *base;
996         struct isl_upoly *res;
997
998         if (isl_upoly_is_cst(up))
999                 return up;
1000
1001         rec = isl_upoly_as_rec(up);
1002         if (!rec)
1003                 goto error;
1004
1005         isl_assert(up->ctx, rec->n >= 1, goto error);
1006
1007         base = isl_upoly_pow(up->ctx, r[up->var], 1);
1008         res = reorder(isl_upoly_copy(rec->p[rec->n - 1]), r);
1009
1010         for (i = rec->n - 2; i >= 0; --i) {
1011                 res = isl_upoly_mul(res, isl_upoly_copy(base));
1012                 res = isl_upoly_sum(res, reorder(isl_upoly_copy(rec->p[i]), r));
1013         }
1014
1015         isl_upoly_free(base);
1016         isl_upoly_free(up);
1017
1018         return res;
1019 error:
1020         isl_upoly_free(up);
1021         return NULL;
1022 }
1023
1024 static int compatible_divs(__isl_keep isl_mat *div1, __isl_keep isl_mat *div2)
1025 {
1026         int n_row, n_col;
1027         int equal;
1028
1029         isl_assert(div1->ctx, div1->n_row >= div2->n_row &&
1030                                 div1->n_col >= div2->n_col, return -1);
1031
1032         if (div1->n_row == div2->n_row)
1033                 return isl_mat_is_equal(div1, div2);
1034
1035         n_row = div1->n_row;
1036         n_col = div1->n_col;
1037         div1->n_row = div2->n_row;
1038         div1->n_col = div2->n_col;
1039
1040         equal = isl_mat_is_equal(div1, div2);
1041
1042         div1->n_row = n_row;
1043         div1->n_col = n_col;
1044
1045         return equal;
1046 }
1047
1048 static void expand_row(__isl_keep isl_mat *dst, int d,
1049         __isl_keep isl_mat *src, int s, int *exp)
1050 {
1051         int i;
1052         unsigned c = src->n_col - src->n_row;
1053
1054         isl_seq_cpy(dst->row[d], src->row[s], c);
1055         isl_seq_clr(dst->row[d] + c, dst->n_col - c);
1056
1057         for (i = 0; i < s; ++i)
1058                 isl_int_set(dst->row[d][c + exp[i]], src->row[s][c + i]);
1059 }
1060
1061 static int cmp_row(__isl_keep isl_mat *div, int i, int j)
1062 {
1063         int li, lj;
1064
1065         li = isl_seq_last_non_zero(div->row[i], div->n_col);
1066         lj = isl_seq_last_non_zero(div->row[j], div->n_col);
1067
1068         if (li != lj)
1069                 return li - lj;
1070
1071         return isl_seq_cmp(div->row[i], div->row[j], div->n_col);
1072 }
1073
1074 struct isl_div_sort_info {
1075         isl_mat *div;
1076         int      row;
1077 };
1078
1079 static int div_sort_cmp(const void *p1, const void *p2)
1080 {
1081         const struct isl_div_sort_info *i1, *i2;
1082         i1 = (const struct isl_div_sort_info *) p1;
1083         i2 = (const struct isl_div_sort_info *) p2;
1084
1085         return cmp_row(i1->div, i1->row, i2->row);
1086 }
1087
1088 /* Sort divs and remove duplicates.
1089  */
1090 static __isl_give isl_qpolynomial *sort_divs(__isl_take isl_qpolynomial *qp)
1091 {
1092         int i;
1093         int skip;
1094         int len;
1095         struct isl_div_sort_info *array = NULL;
1096         int *pos = NULL, *at = NULL;
1097         int *reordering = NULL;
1098         unsigned div_pos;
1099
1100         if (!qp)
1101                 return NULL;
1102         if (qp->div->n_row <= 1)
1103                 return qp;
1104
1105         div_pos = isl_dim_total(qp->dim);
1106
1107         array = isl_alloc_array(qp->div->ctx, struct isl_div_sort_info,
1108                                 qp->div->n_row);
1109         pos = isl_alloc_array(qp->div->ctx, int, qp->div->n_row);
1110         at = isl_alloc_array(qp->div->ctx, int, qp->div->n_row);
1111         len = qp->div->n_col - 2;
1112         reordering = isl_alloc_array(qp->div->ctx, int, len);
1113         if (!array || !pos || !at || !reordering)
1114                 goto error;
1115
1116         for (i = 0; i < qp->div->n_row; ++i) {
1117                 array[i].div = qp->div;
1118                 array[i].row = i;
1119                 pos[i] = i;
1120                 at[i] = i;
1121         }
1122
1123         qsort(array, qp->div->n_row, sizeof(struct isl_div_sort_info),
1124                 div_sort_cmp);
1125
1126         for (i = 0; i < div_pos; ++i)
1127                 reordering[i] = i;
1128
1129         for (i = 0; i < qp->div->n_row; ++i) {
1130                 if (pos[array[i].row] == i)
1131                         continue;
1132                 qp->div = isl_mat_swap_rows(qp->div, i, pos[array[i].row]);
1133                 pos[at[i]] = pos[array[i].row];
1134                 at[pos[array[i].row]] = at[i];
1135                 at[i] = array[i].row;
1136                 pos[array[i].row] = i;
1137         }
1138
1139         skip = 0;
1140         for (i = 0; i < len - div_pos; ++i) {
1141                 if (i > 0 &&
1142                     isl_seq_eq(qp->div->row[i - skip - 1],
1143                                qp->div->row[i - skip], qp->div->n_col)) {
1144                         qp->div = isl_mat_drop_rows(qp->div, i - skip, 1);
1145                         qp->div = isl_mat_drop_cols(qp->div,
1146                                                     2 + div_pos + i - skip, 1);
1147                         skip++;
1148                 }
1149                 reordering[div_pos + array[i].row] = div_pos + i - skip;
1150         }
1151
1152         qp->upoly = reorder(qp->upoly, reordering);
1153
1154         if (!qp->upoly || !qp->div)
1155                 goto error;
1156
1157         free(at);
1158         free(pos);
1159         free(array);
1160         free(reordering);
1161
1162         return qp;
1163 error:
1164         free(at);
1165         free(pos);
1166         free(array);
1167         free(reordering);
1168         isl_qpolynomial_free(qp);
1169         return NULL;
1170 }
1171
1172 static __isl_give isl_mat *merge_divs(__isl_keep isl_mat *div1,
1173         __isl_keep isl_mat *div2, int *exp1, int *exp2)
1174 {
1175         int i, j, k;
1176         isl_mat *div = NULL;
1177         unsigned d = div1->n_col - div1->n_row;
1178
1179         div = isl_mat_alloc(div1->ctx, 1 + div1->n_row + div2->n_row,
1180                                 d + div1->n_row + div2->n_row);
1181         if (!div)
1182                 return NULL;
1183
1184         for (i = 0, j = 0, k = 0; i < div1->n_row && j < div2->n_row; ++k) {
1185                 int cmp;
1186
1187                 expand_row(div, k, div1, i, exp1);
1188                 expand_row(div, k + 1, div2, j, exp2);
1189
1190                 cmp = cmp_row(div, k, k + 1);
1191                 if (cmp == 0) {
1192                         exp1[i++] = k;
1193                         exp2[j++] = k;
1194                 } else if (cmp < 0) {
1195                         exp1[i++] = k;
1196                 } else {
1197                         exp2[j++] = k;
1198                         isl_seq_cpy(div->row[k], div->row[k + 1], div->n_col);
1199                 }
1200         }
1201         for (; i < div1->n_row; ++i, ++k) {
1202                 expand_row(div, k, div1, i, exp1);
1203                 exp1[i] = k;
1204         }
1205         for (; j < div2->n_row; ++j, ++k) {
1206                 expand_row(div, k, div2, j, exp2);
1207                 exp2[j] = k;
1208         }
1209
1210         div->n_row = k;
1211         div->n_col = d + k;
1212
1213         return div;
1214 }
1215
1216 static __isl_give struct isl_upoly *expand(__isl_take struct isl_upoly *up,
1217         int *exp, int first)
1218 {
1219         int i;
1220         struct isl_upoly_rec *rec;
1221
1222         if (isl_upoly_is_cst(up))
1223                 return up;
1224
1225         if (up->var < first)
1226                 return up;
1227
1228         if (exp[up->var - first] == up->var - first)
1229                 return up;
1230
1231         up = isl_upoly_cow(up);
1232         if (!up)
1233                 goto error;
1234
1235         up->var = exp[up->var - first] + first;
1236
1237         rec = isl_upoly_as_rec(up);
1238         if (!rec)
1239                 goto error;
1240
1241         for (i = 0; i < rec->n; ++i) {
1242                 rec->p[i] = expand(rec->p[i], exp, first);
1243                 if (!rec->p[i])
1244                         goto error;
1245         }
1246
1247         return up;
1248 error:
1249         isl_upoly_free(up);
1250         return NULL;
1251 }
1252
1253 static __isl_give isl_qpolynomial *with_merged_divs(
1254         __isl_give isl_qpolynomial *(*fn)(__isl_take isl_qpolynomial *qp1,
1255                                           __isl_take isl_qpolynomial *qp2),
1256         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
1257 {
1258         int *exp1 = NULL;
1259         int *exp2 = NULL;
1260         isl_mat *div = NULL;
1261
1262         qp1 = isl_qpolynomial_cow(qp1);
1263         qp2 = isl_qpolynomial_cow(qp2);
1264
1265         if (!qp1 || !qp2)
1266                 goto error;
1267
1268         isl_assert(qp1->div->ctx, qp1->div->n_row >= qp2->div->n_row &&
1269                                 qp1->div->n_col >= qp2->div->n_col, goto error);
1270
1271         exp1 = isl_alloc_array(qp1->div->ctx, int, qp1->div->n_row);
1272         exp2 = isl_alloc_array(qp2->div->ctx, int, qp2->div->n_row);
1273         if (!exp1 || !exp2)
1274                 goto error;
1275
1276         div = merge_divs(qp1->div, qp2->div, exp1, exp2);
1277         if (!div)
1278                 goto error;
1279
1280         isl_mat_free(qp1->div);
1281         qp1->div = isl_mat_copy(div);
1282         isl_mat_free(qp2->div);
1283         qp2->div = isl_mat_copy(div);
1284
1285         qp1->upoly = expand(qp1->upoly, exp1, div->n_col - div->n_row - 2);
1286         qp2->upoly = expand(qp2->upoly, exp2, div->n_col - div->n_row - 2);
1287
1288         if (!qp1->upoly || !qp2->upoly)
1289                 goto error;
1290
1291         isl_mat_free(div);
1292         free(exp1);
1293         free(exp2);
1294
1295         return fn(qp1, qp2);
1296 error:
1297         isl_mat_free(div);
1298         free(exp1);
1299         free(exp2);
1300         isl_qpolynomial_free(qp1);
1301         isl_qpolynomial_free(qp2);
1302         return NULL;
1303 }
1304
1305 __isl_give isl_qpolynomial *isl_qpolynomial_add(__isl_take isl_qpolynomial *qp1,
1306         __isl_take isl_qpolynomial *qp2)
1307 {
1308         qp1 = isl_qpolynomial_cow(qp1);
1309
1310         if (!qp1 || !qp2)
1311                 goto error;
1312
1313         if (qp1->div->n_row < qp2->div->n_row)
1314                 return isl_qpolynomial_add(qp2, qp1);
1315
1316         isl_assert(qp1->dim->ctx, isl_dim_equal(qp1->dim, qp2->dim), goto error);
1317         if (!compatible_divs(qp1->div, qp2->div))
1318                 return with_merged_divs(isl_qpolynomial_add, qp1, qp2);
1319
1320         qp1->upoly = isl_upoly_sum(qp1->upoly, isl_upoly_copy(qp2->upoly));
1321         if (!qp1->upoly)
1322                 goto error;
1323
1324         isl_qpolynomial_free(qp2);
1325
1326         return qp1;
1327 error:
1328         isl_qpolynomial_free(qp1);
1329         isl_qpolynomial_free(qp2);
1330         return NULL;
1331 }
1332
1333 __isl_give isl_qpolynomial *isl_qpolynomial_add_on_domain(
1334         __isl_keep isl_set *dom,
1335         __isl_take isl_qpolynomial *qp1,
1336         __isl_take isl_qpolynomial *qp2)
1337 {
1338         return isl_qpolynomial_add(qp1, qp2);
1339 }
1340
1341 __isl_give isl_qpolynomial *isl_qpolynomial_sub(__isl_take isl_qpolynomial *qp1,
1342         __isl_take isl_qpolynomial *qp2)
1343 {
1344         return isl_qpolynomial_add(qp1, isl_qpolynomial_neg(qp2));
1345 }
1346
1347 __isl_give isl_qpolynomial *isl_qpolynomial_neg(__isl_take isl_qpolynomial *qp)
1348 {
1349         qp = isl_qpolynomial_cow(qp);
1350
1351         if (!qp)
1352                 return NULL;
1353
1354         qp->upoly = isl_upoly_neg(qp->upoly);
1355         if (!qp->upoly)
1356                 goto error;
1357
1358         return qp;
1359 error:
1360         isl_qpolynomial_free(qp);
1361         return NULL;
1362 }
1363
1364 __isl_give isl_qpolynomial *isl_qpolynomial_mul(__isl_take isl_qpolynomial *qp1,
1365         __isl_take isl_qpolynomial *qp2)
1366 {
1367         qp1 = isl_qpolynomial_cow(qp1);
1368
1369         if (!qp1 || !qp2)
1370                 goto error;
1371
1372         if (qp1->div->n_row < qp2->div->n_row)
1373                 return isl_qpolynomial_mul(qp2, qp1);
1374
1375         isl_assert(qp1->dim->ctx, isl_dim_equal(qp1->dim, qp2->dim), goto error);
1376         if (!compatible_divs(qp1->div, qp2->div))
1377                 return with_merged_divs(isl_qpolynomial_mul, qp1, qp2);
1378
1379         qp1->upoly = isl_upoly_mul(qp1->upoly, isl_upoly_copy(qp2->upoly));
1380         if (!qp1->upoly)
1381                 goto error;
1382
1383         isl_qpolynomial_free(qp2);
1384
1385         return qp1;
1386 error:
1387         isl_qpolynomial_free(qp1);
1388         isl_qpolynomial_free(qp2);
1389         return NULL;
1390 }
1391
1392 __isl_give isl_qpolynomial *isl_qpolynomial_zero(__isl_take isl_dim *dim)
1393 {
1394         return isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
1395 }
1396
1397 __isl_give isl_qpolynomial *isl_qpolynomial_one(__isl_take isl_dim *dim)
1398 {
1399         return isl_qpolynomial_alloc(dim, 0, isl_upoly_one(dim->ctx));
1400 }
1401
1402 __isl_give isl_qpolynomial *isl_qpolynomial_infty(__isl_take isl_dim *dim)
1403 {
1404         return isl_qpolynomial_alloc(dim, 0, isl_upoly_infty(dim->ctx));
1405 }
1406
1407 __isl_give isl_qpolynomial *isl_qpolynomial_neginfty(__isl_take isl_dim *dim)
1408 {
1409         return isl_qpolynomial_alloc(dim, 0, isl_upoly_neginfty(dim->ctx));
1410 }
1411
1412 __isl_give isl_qpolynomial *isl_qpolynomial_nan(__isl_take isl_dim *dim)
1413 {
1414         return isl_qpolynomial_alloc(dim, 0, isl_upoly_nan(dim->ctx));
1415 }
1416
1417 __isl_give isl_qpolynomial *isl_qpolynomial_cst(__isl_take isl_dim *dim,
1418         isl_int v)
1419 {
1420         struct isl_qpolynomial *qp;
1421         struct isl_upoly_cst *cst;
1422
1423         qp = isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
1424         if (!qp)
1425                 return NULL;
1426
1427         cst = isl_upoly_as_cst(qp->upoly);
1428         isl_int_set(cst->n, v);
1429
1430         return qp;
1431 }
1432
1433 int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp,
1434         isl_int *n, isl_int *d)
1435 {
1436         struct isl_upoly_cst *cst;
1437
1438         if (!qp)
1439                 return -1;
1440
1441         if (!isl_upoly_is_cst(qp->upoly))
1442                 return 0;
1443
1444         cst = isl_upoly_as_cst(qp->upoly);
1445         if (!cst)
1446                 return -1;
1447
1448         if (n)
1449                 isl_int_set(*n, cst->n);
1450         if (d)
1451                 isl_int_set(*d, cst->d);
1452
1453         return 1;
1454 }
1455
1456 int isl_upoly_is_affine(__isl_keep struct isl_upoly *up)
1457 {
1458         int is_cst;
1459         struct isl_upoly_rec *rec;
1460
1461         if (!up)
1462                 return -1;
1463
1464         if (up->var < 0)
1465                 return 1;
1466
1467         rec = isl_upoly_as_rec(up);
1468         if (!rec)
1469                 return -1;
1470
1471         if (rec->n > 2)
1472                 return 0;
1473
1474         isl_assert(up->ctx, rec->n > 1, return -1);
1475
1476         is_cst = isl_upoly_is_cst(rec->p[1]);
1477         if (is_cst < 0)
1478                 return -1;
1479         if (!is_cst)
1480                 return 0;
1481
1482         return isl_upoly_is_affine(rec->p[0]);
1483 }
1484
1485 int isl_qpolynomial_is_affine(__isl_keep isl_qpolynomial *qp)
1486 {
1487         if (!qp)
1488                 return -1;
1489
1490         if (qp->div->n_row > 0)
1491                 return 0;
1492
1493         return isl_upoly_is_affine(qp->upoly);
1494 }
1495
1496 static void update_coeff(__isl_keep isl_vec *aff,
1497         __isl_keep struct isl_upoly_cst *cst, int pos)
1498 {
1499         isl_int gcd;
1500         isl_int f;
1501
1502         if (isl_int_is_zero(cst->n))
1503                 return;
1504
1505         isl_int_init(gcd);
1506         isl_int_init(f);
1507         isl_int_gcd(gcd, cst->d, aff->el[0]);
1508         isl_int_divexact(f, cst->d, gcd);
1509         isl_int_divexact(gcd, aff->el[0], gcd);
1510         isl_seq_scale(aff->el, aff->el, f, aff->size);
1511         isl_int_mul(aff->el[1 + pos], gcd, cst->n);
1512         isl_int_clear(gcd);
1513         isl_int_clear(f);
1514 }
1515
1516 int isl_upoly_update_affine(__isl_keep struct isl_upoly *up,
1517         __isl_keep isl_vec *aff)
1518 {
1519         struct isl_upoly_cst *cst;
1520         struct isl_upoly_rec *rec;
1521
1522         if (!up || !aff)
1523                 return -1;
1524
1525         if (up->var < 0) {
1526                 struct isl_upoly_cst *cst;
1527
1528                 cst = isl_upoly_as_cst(up);
1529                 if (!cst)
1530                         return -1;
1531                 update_coeff(aff, cst, 0);
1532                 return 0;
1533         }
1534
1535         rec = isl_upoly_as_rec(up);
1536         if (!rec)
1537                 return -1;
1538         isl_assert(up->ctx, rec->n == 2, return -1);
1539
1540         cst = isl_upoly_as_cst(rec->p[1]);
1541         if (!cst)
1542                 return -1;
1543         update_coeff(aff, cst, 1 + up->var);
1544
1545         return isl_upoly_update_affine(rec->p[0], aff);
1546 }
1547
1548 __isl_give isl_vec *isl_qpolynomial_extract_affine(
1549         __isl_keep isl_qpolynomial *qp)
1550 {
1551         isl_vec *aff;
1552         unsigned d;
1553
1554         if (!qp)
1555                 return NULL;
1556
1557         isl_assert(qp->div->ctx, qp->div->n_row == 0, return NULL);
1558         d = isl_dim_total(qp->dim);
1559         aff = isl_vec_alloc(qp->div->ctx, 2 + d);
1560         if (!aff)
1561                 return NULL;
1562
1563         isl_seq_clr(aff->el + 1, 1 + d);
1564         isl_int_set_si(aff->el[0], 1);
1565
1566         if (isl_upoly_update_affine(qp->upoly, aff) < 0)
1567                 goto error;
1568
1569         return aff;
1570 error:
1571         isl_vec_free(aff);
1572         return NULL;
1573 }
1574
1575 int isl_qpolynomial_is_equal(__isl_keep isl_qpolynomial *qp1,
1576         __isl_keep isl_qpolynomial *qp2)
1577 {
1578         if (!qp1 || !qp2)
1579                 return -1;
1580
1581         return isl_upoly_is_equal(qp1->upoly, qp2->upoly);
1582 }
1583
1584 static void upoly_update_den(__isl_keep struct isl_upoly *up, isl_int *d)
1585 {
1586         int i;
1587         struct isl_upoly_rec *rec;
1588
1589         if (isl_upoly_is_cst(up)) {
1590                 struct isl_upoly_cst *cst;
1591                 cst = isl_upoly_as_cst(up);
1592                 if (!cst)
1593                         return;
1594                 isl_int_lcm(*d, *d, cst->d);
1595                 return;
1596         }
1597
1598         rec = isl_upoly_as_rec(up);
1599         if (!rec)
1600                 return;
1601
1602         for (i = 0; i < rec->n; ++i)
1603                 upoly_update_den(rec->p[i], d);
1604 }
1605
1606 void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d)
1607 {
1608         isl_int_set_si(*d, 1);
1609         if (!qp)
1610                 return;
1611         upoly_update_den(qp->upoly, d);
1612 }
1613
1614 __isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_dim *dim,
1615         int pos, int power)
1616 {
1617         struct isl_ctx *ctx;
1618
1619         if (!dim)
1620                 return NULL;
1621
1622         ctx = dim->ctx;
1623
1624         return isl_qpolynomial_alloc(dim, 0, isl_upoly_pow(ctx, pos, power));
1625 }
1626
1627 __isl_give isl_qpolynomial *isl_qpolynomial_var(__isl_take isl_dim *dim,
1628         enum isl_dim_type type, unsigned pos)
1629 {
1630         if (!dim)
1631                 return NULL;
1632
1633         isl_assert(dim->ctx, isl_dim_size(dim, isl_dim_in) == 0, goto error);
1634         isl_assert(dim->ctx, pos < isl_dim_size(dim, type), goto error);
1635
1636         if (type == isl_dim_set)
1637                 pos += isl_dim_size(dim, isl_dim_param);
1638
1639         return isl_qpolynomial_pow(dim, pos, 1);
1640 error:
1641         isl_dim_free(dim);
1642         return NULL;
1643 }
1644
1645 /* Remove common factor of non-constant terms and denominator.
1646  */
1647 static void normalize_div(__isl_keep isl_qpolynomial *qp, int div)
1648 {
1649         isl_ctx *ctx = qp->div->ctx;
1650         unsigned total = qp->div->n_col - 2;
1651
1652         isl_seq_gcd(qp->div->row[div] + 2, total, &ctx->normalize_gcd);
1653         isl_int_gcd(ctx->normalize_gcd,
1654                     ctx->normalize_gcd, qp->div->row[div][0]);
1655         if (isl_int_is_one(ctx->normalize_gcd))
1656                 return;
1657
1658         isl_seq_scale_down(qp->div->row[div] + 2, qp->div->row[div] + 2,
1659                             ctx->normalize_gcd, total);
1660         isl_int_divexact(qp->div->row[div][0], qp->div->row[div][0],
1661                             ctx->normalize_gcd);
1662         isl_int_fdiv_q(qp->div->row[div][1], qp->div->row[div][1],
1663                             ctx->normalize_gcd);
1664 }
1665
1666 __isl_give isl_qpolynomial *isl_qpolynomial_div_pow(__isl_take isl_div *div,
1667         int power)
1668 {
1669         struct isl_qpolynomial *qp = NULL;
1670         struct isl_upoly_rec *rec;
1671         struct isl_upoly_cst *cst;
1672         int i, d;
1673         int pos;
1674
1675         if (!div)
1676                 return NULL;
1677
1678         d = div->line - div->bmap->div;
1679
1680         pos = isl_dim_total(div->bmap->dim) + d;
1681         rec = isl_upoly_alloc_rec(div->ctx, pos, 1 + power);
1682         qp = isl_qpolynomial_alloc(isl_basic_map_get_dim(div->bmap),
1683                                    div->bmap->n_div, &rec->up);
1684         if (!qp)
1685                 goto error;
1686
1687         for (i = 0; i < div->bmap->n_div; ++i) {
1688                 isl_seq_cpy(qp->div->row[i], div->bmap->div[i], qp->div->n_col);
1689                 normalize_div(qp, i);
1690         }
1691
1692         for (i = 0; i < 1 + power; ++i) {
1693                 rec->p[i] = isl_upoly_zero(div->ctx);
1694                 if (!rec->p[i])
1695                         goto error;
1696                 rec->n++;
1697         }
1698         cst = isl_upoly_as_cst(rec->p[power]);
1699         isl_int_set_si(cst->n, 1);
1700
1701         isl_div_free(div);
1702
1703         return qp;
1704 error:
1705         isl_qpolynomial_free(qp);
1706         isl_div_free(div);
1707         return NULL;
1708 }
1709
1710 __isl_give isl_qpolynomial *isl_qpolynomial_div(__isl_take isl_div *div)
1711 {
1712         return isl_qpolynomial_div_pow(div, 1);
1713 }
1714
1715 __isl_give isl_qpolynomial *isl_qpolynomial_rat_cst(__isl_take isl_dim *dim,
1716         const isl_int n, const isl_int d)
1717 {
1718         struct isl_qpolynomial *qp;
1719         struct isl_upoly_cst *cst;
1720
1721         qp = isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
1722         if (!qp)
1723                 return NULL;
1724
1725         cst = isl_upoly_as_cst(qp->upoly);
1726         isl_int_set(cst->n, n);
1727         isl_int_set(cst->d, d);
1728
1729         return qp;
1730 }
1731
1732 static int up_set_active(__isl_keep struct isl_upoly *up, int *active, int d)
1733 {
1734         struct isl_upoly_rec *rec;
1735         int i;
1736
1737         if (!up)
1738                 return -1;
1739
1740         if (isl_upoly_is_cst(up))
1741                 return 0;
1742
1743         if (up->var < d)
1744                 active[up->var] = 1;
1745
1746         rec = isl_upoly_as_rec(up);
1747         for (i = 0; i < rec->n; ++i)
1748                 if (up_set_active(rec->p[i], active, d) < 0)
1749                         return -1;
1750
1751         return 0;
1752 }
1753
1754 static int set_active(__isl_keep isl_qpolynomial *qp, int *active)
1755 {
1756         int i, j;
1757         int d = isl_dim_total(qp->dim);
1758
1759         if (!qp || !active)
1760                 return -1;
1761
1762         for (i = 0; i < d; ++i)
1763                 for (j = 0; j < qp->div->n_row; ++j) {
1764                         if (isl_int_is_zero(qp->div->row[j][2 + i]))
1765                                 continue;
1766                         active[i] = 1;
1767                         break;
1768                 }
1769
1770         return up_set_active(qp->upoly, active, d);
1771 }
1772
1773 int isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp,
1774         enum isl_dim_type type, unsigned first, unsigned n)
1775 {
1776         int i;
1777         int *active = NULL;
1778         int involves = 0;
1779
1780         if (!qp)
1781                 return -1;
1782         if (n == 0)
1783                 return 0;
1784
1785         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
1786                         return -1);
1787         isl_assert(qp->dim->ctx, type == isl_dim_param ||
1788                                  type == isl_dim_set, return -1);
1789
1790         active = isl_calloc_array(set->ctx, int, isl_dim_total(qp->dim));
1791         if (set_active(qp, active) < 0)
1792                 goto error;
1793
1794         if (type == isl_dim_set)
1795                 first += isl_dim_size(qp->dim, isl_dim_param);
1796         for (i = 0; i < n; ++i)
1797                 if (active[first + i]) {
1798                         involves = 1;
1799                         break;
1800                 }
1801
1802         free(active);
1803
1804         return involves;
1805 error:
1806         free(active);
1807         return -1;
1808 }
1809
1810 __isl_give struct isl_upoly *isl_upoly_drop(__isl_take struct isl_upoly *up,
1811         unsigned first, unsigned n)
1812 {
1813         int i;
1814         struct isl_upoly_rec *rec;
1815
1816         if (!up)
1817                 return NULL;
1818         if (n == 0 || up->var < 0 || up->var < first)
1819                 return up;
1820         if (up->var < first + n) {
1821                 up = replace_by_constant_term(up);
1822                 return isl_upoly_drop(up, first, n);
1823         }
1824         up = isl_upoly_cow(up);
1825         if (!up)
1826                 return NULL;
1827         up->var -= n;
1828         rec = isl_upoly_as_rec(up);
1829         if (!rec)
1830                 goto error;
1831
1832         for (i = 0; i < rec->n; ++i) {
1833                 rec->p[i] = isl_upoly_drop(rec->p[i], first, n);
1834                 if (!rec->p[i])
1835                         goto error;
1836         }
1837
1838         return up;
1839 error:
1840         isl_upoly_free(up);
1841         return NULL;
1842 }
1843
1844 __isl_give isl_qpolynomial *isl_qpolynomial_set_dim_name(
1845         __isl_take isl_qpolynomial *qp,
1846         enum isl_dim_type type, unsigned pos, const char *s)
1847 {
1848         qp = isl_qpolynomial_cow(qp);
1849         if (!qp)
1850                 return NULL;
1851         qp->dim = isl_dim_set_name(qp->dim, type, pos, s);
1852         if (!qp->dim)
1853                 goto error;
1854         return qp;
1855 error:
1856         isl_qpolynomial_free(qp);
1857         return NULL;
1858 }
1859
1860 __isl_give isl_qpolynomial *isl_qpolynomial_drop_dims(
1861         __isl_take isl_qpolynomial *qp,
1862         enum isl_dim_type type, unsigned first, unsigned n)
1863 {
1864         if (!qp)
1865                 return NULL;
1866         if (n == 0 && !isl_dim_get_tuple_name(qp->dim, type))
1867                 return qp;
1868
1869         qp = isl_qpolynomial_cow(qp);
1870         if (!qp)
1871                 return NULL;
1872
1873         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
1874                         goto error);
1875         isl_assert(qp->dim->ctx, type == isl_dim_param ||
1876                                  type == isl_dim_set, goto error);
1877
1878         qp->dim = isl_dim_drop(qp->dim, type, first, n);
1879         if (!qp->dim)
1880                 goto error;
1881
1882         if (type == isl_dim_set)
1883                 first += isl_dim_size(qp->dim, isl_dim_param);
1884
1885         qp->div = isl_mat_drop_cols(qp->div, 2 + first, n);
1886         if (!qp->div)
1887                 goto error;
1888
1889         qp->upoly = isl_upoly_drop(qp->upoly, first, n);
1890         if (!qp->upoly)
1891                 goto error;
1892
1893         return qp;
1894 error:
1895         isl_qpolynomial_free(qp);
1896         return NULL;
1897 }
1898
1899 __isl_give struct isl_upoly *isl_upoly_subs(__isl_take struct isl_upoly *up,
1900         unsigned first, unsigned n, __isl_keep struct isl_upoly **subs)
1901 {
1902         int i;
1903         struct isl_upoly_rec *rec;
1904         struct isl_upoly *base, *res;
1905
1906         if (!up)
1907                 return NULL;
1908
1909         if (isl_upoly_is_cst(up))
1910                 return up;
1911
1912         if (up->var < first)
1913                 return up;
1914
1915         rec = isl_upoly_as_rec(up);
1916         if (!rec)
1917                 goto error;
1918
1919         isl_assert(up->ctx, rec->n >= 1, goto error);
1920
1921         if (up->var >= first + n)
1922                 base = isl_upoly_pow(up->ctx, up->var, 1);
1923         else
1924                 base = isl_upoly_copy(subs[up->var - first]);
1925
1926         res = isl_upoly_subs(isl_upoly_copy(rec->p[rec->n - 1]), first, n, subs);
1927         for (i = rec->n - 2; i >= 0; --i) {
1928                 struct isl_upoly *t;
1929                 t = isl_upoly_subs(isl_upoly_copy(rec->p[i]), first, n, subs);
1930                 res = isl_upoly_mul(res, isl_upoly_copy(base));
1931                 res = isl_upoly_sum(res, t);
1932         }
1933
1934         isl_upoly_free(base);
1935         isl_upoly_free(up);
1936                                 
1937         return res;
1938 error:
1939         isl_upoly_free(up);
1940         return NULL;
1941 }       
1942
1943 __isl_give struct isl_upoly *isl_upoly_from_affine(isl_ctx *ctx, isl_int *f,
1944         isl_int denom, unsigned len)
1945 {
1946         int i;
1947         struct isl_upoly *up;
1948
1949         isl_assert(ctx, len >= 1, return NULL);
1950
1951         up = isl_upoly_rat_cst(ctx, f[0], denom);
1952         for (i = 0; i < len - 1; ++i) {
1953                 struct isl_upoly *t;
1954                 struct isl_upoly *c;
1955
1956                 if (isl_int_is_zero(f[1 + i]))
1957                         continue;
1958
1959                 c = isl_upoly_rat_cst(ctx, f[1 + i], denom);
1960                 t = isl_upoly_pow(ctx, i, 1);
1961                 t = isl_upoly_mul(c, t);
1962                 up = isl_upoly_sum(up, t);
1963         }
1964
1965         return up;
1966 }
1967
1968 /* Replace the integer division identified by "div" by the polynomial "s".
1969  * The integer division is assumed not to appear in the definition
1970  * of any other integer divisions.
1971  */
1972 static __isl_give isl_qpolynomial *substitute_div(
1973         __isl_take isl_qpolynomial *qp,
1974         int div, __isl_take struct isl_upoly *s)
1975 {
1976         int i;
1977         int total;
1978         int *reordering;
1979
1980         if (!qp || !s)
1981                 goto error;
1982
1983         qp = isl_qpolynomial_cow(qp);
1984         if (!qp)
1985                 goto error;
1986
1987         total = isl_dim_total(qp->dim);
1988         qp->upoly = isl_upoly_subs(qp->upoly, total + div, 1, &s);
1989         if (!qp->upoly)
1990                 goto error;
1991
1992         reordering = isl_alloc_array(qp->dim->ctx, int, total + qp->div->n_row);
1993         if (!reordering)
1994                 goto error;
1995         for (i = 0; i < total + div; ++i)
1996                 reordering[i] = i;
1997         for (i = total + div + 1; i < total + qp->div->n_row; ++i)
1998                 reordering[i] = i - 1;
1999         qp->div = isl_mat_drop_rows(qp->div, div, 1);
2000         qp->div = isl_mat_drop_cols(qp->div, 2 + total + div, 1);
2001         qp->upoly = reorder(qp->upoly, reordering);
2002         free(reordering);
2003
2004         if (!qp->upoly || !qp->div)
2005                 goto error;
2006
2007         isl_upoly_free(s);
2008         return qp;
2009 error:
2010         isl_qpolynomial_free(qp);
2011         isl_upoly_free(s);
2012         return NULL;
2013 }
2014
2015 /* Replace all integer divisions [e/d] that turn out to not actually be integer
2016  * divisions because d is equal to 1 by their definition, i.e., e.
2017  */
2018 static __isl_give isl_qpolynomial *substitute_non_divs(
2019         __isl_take isl_qpolynomial *qp)
2020 {
2021         int i, j;
2022         int total;
2023         struct isl_upoly *s;
2024
2025         if (!qp)
2026                 return NULL;
2027
2028         total = isl_dim_total(qp->dim);
2029         for (i = 0; qp && i < qp->div->n_row; ++i) {
2030                 if (!isl_int_is_one(qp->div->row[i][0]))
2031                         continue;
2032                 for (j = i + 1; j < qp->div->n_row; ++j) {
2033                         if (isl_int_is_zero(qp->div->row[j][2 + total + i]))
2034                                 continue;
2035                         isl_seq_combine(qp->div->row[j] + 1,
2036                                 qp->div->ctx->one, qp->div->row[j] + 1,
2037                                 qp->div->row[j][2 + total + i],
2038                                 qp->div->row[i] + 1, 1 + total + i);
2039                         isl_int_set_si(qp->div->row[j][2 + total + i], 0);
2040                         normalize_div(qp, j);
2041                 }
2042                 s = isl_upoly_from_affine(qp->dim->ctx, qp->div->row[i] + 1,
2043                                         qp->div->row[i][0], qp->div->n_col - 1);
2044                 qp = substitute_div(qp, i, s);
2045                 --i;
2046         }
2047
2048         return qp;
2049 }
2050
2051 __isl_give isl_qpolynomial *isl_qpolynomial_substitute_equalities(
2052         __isl_take isl_qpolynomial *qp, __isl_take isl_basic_set *eq)
2053 {
2054         int i, j, k;
2055         isl_int denom;
2056         unsigned total;
2057         unsigned n_div;
2058         struct isl_upoly *up;
2059
2060         if (!eq)
2061                 goto error;
2062         if (eq->n_eq == 0) {
2063                 isl_basic_set_free(eq);
2064                 return qp;
2065         }
2066
2067         qp = isl_qpolynomial_cow(qp);
2068         if (!qp)
2069                 goto error;
2070         qp->div = isl_mat_cow(qp->div);
2071         if (!qp->div)
2072                 goto error;
2073
2074         total = 1 + isl_dim_total(eq->dim);
2075         n_div = eq->n_div;
2076         isl_int_init(denom);
2077         for (i = 0; i < eq->n_eq; ++i) {
2078                 j = isl_seq_last_non_zero(eq->eq[i], total + n_div);
2079                 if (j < 0 || j == 0 || j >= total)
2080                         continue;
2081
2082                 for (k = 0; k < qp->div->n_row; ++k) {
2083                         if (isl_int_is_zero(qp->div->row[k][1 + j]))
2084                                 continue;
2085                         isl_seq_elim(qp->div->row[k] + 1, eq->eq[i], j, total,
2086                                         &qp->div->row[k][0]);
2087                         normalize_div(qp, k);
2088                 }
2089
2090                 if (isl_int_is_pos(eq->eq[i][j]))
2091                         isl_seq_neg(eq->eq[i], eq->eq[i], total);
2092                 isl_int_abs(denom, eq->eq[i][j]);
2093                 isl_int_set_si(eq->eq[i][j], 0);
2094
2095                 up = isl_upoly_from_affine(qp->dim->ctx,
2096                                                    eq->eq[i], denom, total);
2097                 qp->upoly = isl_upoly_subs(qp->upoly, j - 1, 1, &up);
2098                 isl_upoly_free(up);
2099         }
2100         isl_int_clear(denom);
2101
2102         if (!qp->upoly)
2103                 goto error;
2104
2105         isl_basic_set_free(eq);
2106
2107         qp = substitute_non_divs(qp);
2108         qp = sort_divs(qp);
2109
2110         return qp;
2111 error:
2112         isl_basic_set_free(eq);
2113         isl_qpolynomial_free(qp);
2114         return NULL;
2115 }
2116
2117 static __isl_give isl_basic_set *add_div_constraints(
2118         __isl_take isl_basic_set *bset, __isl_take isl_mat *div)
2119 {
2120         int i;
2121         unsigned total;
2122
2123         if (!bset || !div)
2124                 goto error;
2125
2126         bset = isl_basic_set_extend_constraints(bset, 0, 2 * div->n_row);
2127         if (!bset)
2128                 goto error;
2129         total = isl_basic_set_total_dim(bset);
2130         for (i = 0; i < div->n_row; ++i)
2131                 if (isl_basic_set_add_div_constraints_var(bset,
2132                                     total - div->n_row + i, div->row[i]) < 0)
2133                         goto error;
2134
2135         isl_mat_free(div);
2136         return bset;
2137 error:
2138         isl_mat_free(div);
2139         isl_basic_set_free(bset);
2140         return NULL;
2141 }
2142
2143 /* Look for equalities among the variables shared by context and qp
2144  * and the integer divisions of qp, if any.
2145  * The equalities are then used to eliminate variables and/or integer
2146  * divisions from qp.
2147  */
2148 __isl_give isl_qpolynomial *isl_qpolynomial_gist(
2149         __isl_take isl_qpolynomial *qp, __isl_take isl_set *context)
2150 {
2151         isl_basic_set *aff;
2152
2153         if (!qp)
2154                 goto error;
2155         if (qp->div->n_row > 0) {
2156                 isl_basic_set *bset;
2157                 context = isl_set_add_dims(context, isl_dim_set,
2158                                             qp->div->n_row);
2159                 bset = isl_basic_set_universe(isl_set_get_dim(context));
2160                 bset = add_div_constraints(bset, isl_mat_copy(qp->div));
2161                 context = isl_set_intersect(context,
2162                                             isl_set_from_basic_set(bset));
2163         }
2164
2165         aff = isl_set_affine_hull(context);
2166         return isl_qpolynomial_substitute_equalities(qp, aff);
2167 error:
2168         isl_qpolynomial_free(qp);
2169         isl_set_free(context);
2170         return NULL;
2171 }
2172
2173 #undef PW
2174 #define PW isl_pw_qpolynomial
2175 #undef EL
2176 #define EL isl_qpolynomial
2177 #undef IS_ZERO
2178 #define IS_ZERO is_zero
2179 #undef FIELD
2180 #define FIELD qp
2181
2182 #include <isl_pw_templ.c>
2183
2184 #undef UNION
2185 #define UNION isl_union_pw_qpolynomial
2186 #undef PART
2187 #define PART isl_pw_qpolynomial
2188 #undef PARTS
2189 #define PARTS pw_qpolynomial
2190
2191 #include <isl_union_templ.c>
2192
2193 int isl_pw_qpolynomial_is_one(__isl_keep isl_pw_qpolynomial *pwqp)
2194 {
2195         if (!pwqp)
2196                 return -1;
2197
2198         if (pwqp->n != -1)
2199                 return 0;
2200
2201         if (!isl_set_fast_is_universe(pwqp->p[0].set))
2202                 return 0;
2203
2204         return isl_qpolynomial_is_one(pwqp->p[0].qp);
2205 }
2206
2207 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul(
2208         __isl_take isl_pw_qpolynomial *pwqp1,
2209         __isl_take isl_pw_qpolynomial *pwqp2)
2210 {
2211         int i, j, n;
2212         struct isl_pw_qpolynomial *res;
2213         isl_set *set;
2214
2215         if (!pwqp1 || !pwqp2)
2216                 goto error;
2217
2218         isl_assert(pwqp1->dim->ctx, isl_dim_equal(pwqp1->dim, pwqp2->dim),
2219                         goto error);
2220
2221         if (isl_pw_qpolynomial_is_zero(pwqp1)) {
2222                 isl_pw_qpolynomial_free(pwqp2);
2223                 return pwqp1;
2224         }
2225
2226         if (isl_pw_qpolynomial_is_zero(pwqp2)) {
2227                 isl_pw_qpolynomial_free(pwqp1);
2228                 return pwqp2;
2229         }
2230
2231         if (isl_pw_qpolynomial_is_one(pwqp1)) {
2232                 isl_pw_qpolynomial_free(pwqp1);
2233                 return pwqp2;
2234         }
2235
2236         if (isl_pw_qpolynomial_is_one(pwqp2)) {
2237                 isl_pw_qpolynomial_free(pwqp2);
2238                 return pwqp1;
2239         }
2240
2241         n = pwqp1->n * pwqp2->n;
2242         res = isl_pw_qpolynomial_alloc_(isl_dim_copy(pwqp1->dim), n);
2243
2244         for (i = 0; i < pwqp1->n; ++i) {
2245                 for (j = 0; j < pwqp2->n; ++j) {
2246                         struct isl_set *common;
2247                         struct isl_qpolynomial *prod;
2248                         common = isl_set_intersect(isl_set_copy(pwqp1->p[i].set),
2249                                                 isl_set_copy(pwqp2->p[j].set));
2250                         if (isl_set_fast_is_empty(common)) {
2251                                 isl_set_free(common);
2252                                 continue;
2253                         }
2254
2255                         prod = isl_qpolynomial_mul(
2256                                 isl_qpolynomial_copy(pwqp1->p[i].qp),
2257                                 isl_qpolynomial_copy(pwqp2->p[j].qp));
2258
2259                         res = isl_pw_qpolynomial_add_piece(res, common, prod);
2260                 }
2261         }
2262
2263         isl_pw_qpolynomial_free(pwqp1);
2264         isl_pw_qpolynomial_free(pwqp2);
2265
2266         return res;
2267 error:
2268         isl_pw_qpolynomial_free(pwqp1);
2269         isl_pw_qpolynomial_free(pwqp2);
2270         return NULL;
2271 }
2272
2273 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg(
2274         __isl_take isl_pw_qpolynomial *pwqp)
2275 {
2276         int i;
2277
2278         if (!pwqp)
2279                 return NULL;
2280
2281         if (isl_pw_qpolynomial_is_zero(pwqp))
2282                 return pwqp;
2283
2284         pwqp = isl_pw_qpolynomial_cow(pwqp);
2285         if (!pwqp)
2286                 return NULL;
2287
2288         for (i = 0; i < pwqp->n; ++i) {
2289                 pwqp->p[i].qp = isl_qpolynomial_neg(pwqp->p[i].qp);
2290                 if (!pwqp->p[i].qp)
2291                         goto error;
2292         }
2293
2294         return pwqp;
2295 error:
2296         isl_pw_qpolynomial_free(pwqp);
2297         return NULL;
2298 }
2299
2300 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub(
2301         __isl_take isl_pw_qpolynomial *pwqp1,
2302         __isl_take isl_pw_qpolynomial *pwqp2)
2303 {
2304         return isl_pw_qpolynomial_add(pwqp1, isl_pw_qpolynomial_neg(pwqp2));
2305 }
2306
2307 __isl_give struct isl_upoly *isl_upoly_eval(
2308         __isl_take struct isl_upoly *up, __isl_take isl_vec *vec)
2309 {
2310         int i;
2311         struct isl_upoly_rec *rec;
2312         struct isl_upoly *res;
2313         struct isl_upoly *base;
2314
2315         if (isl_upoly_is_cst(up)) {
2316                 isl_vec_free(vec);
2317                 return up;
2318         }
2319
2320         rec = isl_upoly_as_rec(up);
2321         if (!rec)
2322                 goto error;
2323
2324         isl_assert(up->ctx, rec->n >= 1, goto error);
2325
2326         base = isl_upoly_rat_cst(up->ctx, vec->el[1 + up->var], vec->el[0]);
2327
2328         res = isl_upoly_eval(isl_upoly_copy(rec->p[rec->n - 1]),
2329                                 isl_vec_copy(vec));
2330
2331         for (i = rec->n - 2; i >= 0; --i) {
2332                 res = isl_upoly_mul(res, isl_upoly_copy(base));
2333                 res = isl_upoly_sum(res, 
2334                             isl_upoly_eval(isl_upoly_copy(rec->p[i]),
2335                                                             isl_vec_copy(vec)));
2336         }
2337
2338         isl_upoly_free(base);
2339         isl_upoly_free(up);
2340         isl_vec_free(vec);
2341         return res;
2342 error:
2343         isl_upoly_free(up);
2344         isl_vec_free(vec);
2345         return NULL;
2346 }
2347
2348 __isl_give isl_qpolynomial *isl_qpolynomial_eval(
2349         __isl_take isl_qpolynomial *qp, __isl_take isl_point *pnt)
2350 {
2351         isl_vec *ext;
2352         struct isl_upoly *up;
2353         isl_dim *dim;
2354
2355         if (!qp || !pnt)
2356                 goto error;
2357         isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, qp->dim), goto error);
2358
2359         if (qp->div->n_row == 0)
2360                 ext = isl_vec_copy(pnt->vec);
2361         else {
2362                 int i;
2363                 unsigned dim = isl_dim_total(qp->dim);
2364                 ext = isl_vec_alloc(qp->dim->ctx, 1 + dim + qp->div->n_row);
2365                 if (!ext)
2366                         goto error;
2367
2368                 isl_seq_cpy(ext->el, pnt->vec->el, pnt->vec->size);
2369                 for (i = 0; i < qp->div->n_row; ++i) {
2370                         isl_seq_inner_product(qp->div->row[i] + 1, ext->el,
2371                                                 1 + dim + i, &ext->el[1+dim+i]);
2372                         isl_int_fdiv_q(ext->el[1+dim+i], ext->el[1+dim+i],
2373                                         qp->div->row[i][0]);
2374                 }
2375         }
2376
2377         up = isl_upoly_eval(isl_upoly_copy(qp->upoly), ext);
2378         if (!up)
2379                 goto error;
2380
2381         dim = isl_dim_copy(qp->dim);
2382         isl_qpolynomial_free(qp);
2383         isl_point_free(pnt);
2384
2385         return isl_qpolynomial_alloc(dim, 0, up);
2386 error:
2387         isl_qpolynomial_free(qp);
2388         isl_point_free(pnt);
2389         return NULL;
2390 }
2391
2392 int isl_upoly_cmp(__isl_keep struct isl_upoly_cst *cst1,
2393         __isl_keep struct isl_upoly_cst *cst2)
2394 {
2395         int cmp;
2396         isl_int t;
2397         isl_int_init(t);
2398         isl_int_mul(t, cst1->n, cst2->d);
2399         isl_int_submul(t, cst2->n, cst1->d);
2400         cmp = isl_int_sgn(t);
2401         isl_int_clear(t);
2402         return cmp;
2403 }
2404
2405 int isl_qpolynomial_le_cst(__isl_keep isl_qpolynomial *qp1,
2406         __isl_keep isl_qpolynomial *qp2)
2407 {
2408         struct isl_upoly_cst *cst1, *cst2;
2409
2410         if (!qp1 || !qp2)
2411                 return -1;
2412         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), return -1);
2413         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), return -1);
2414         if (isl_qpolynomial_is_nan(qp1))
2415                 return -1;
2416         if (isl_qpolynomial_is_nan(qp2))
2417                 return -1;
2418         cst1 = isl_upoly_as_cst(qp1->upoly);
2419         cst2 = isl_upoly_as_cst(qp2->upoly);
2420
2421         return isl_upoly_cmp(cst1, cst2) <= 0;
2422 }
2423
2424 __isl_give isl_qpolynomial *isl_qpolynomial_min_cst(
2425         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
2426 {
2427         struct isl_upoly_cst *cst1, *cst2;
2428         int cmp;
2429
2430         if (!qp1 || !qp2)
2431                 goto error;
2432         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
2433         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
2434         cst1 = isl_upoly_as_cst(qp1->upoly);
2435         cst2 = isl_upoly_as_cst(qp2->upoly);
2436         cmp = isl_upoly_cmp(cst1, cst2);
2437
2438         if (cmp <= 0) {
2439                 isl_qpolynomial_free(qp2);
2440         } else {
2441                 isl_qpolynomial_free(qp1);
2442                 qp1 = qp2;
2443         }
2444         return qp1;
2445 error:
2446         isl_qpolynomial_free(qp1);
2447         isl_qpolynomial_free(qp2);
2448         return NULL;
2449 }
2450
2451 __isl_give isl_qpolynomial *isl_qpolynomial_max_cst(
2452         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
2453 {
2454         struct isl_upoly_cst *cst1, *cst2;
2455         int cmp;
2456
2457         if (!qp1 || !qp2)
2458                 goto error;
2459         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
2460         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
2461         cst1 = isl_upoly_as_cst(qp1->upoly);
2462         cst2 = isl_upoly_as_cst(qp2->upoly);
2463         cmp = isl_upoly_cmp(cst1, cst2);
2464
2465         if (cmp >= 0) {
2466                 isl_qpolynomial_free(qp2);
2467         } else {
2468                 isl_qpolynomial_free(qp1);
2469                 qp1 = qp2;
2470         }
2471         return qp1;
2472 error:
2473         isl_qpolynomial_free(qp1);
2474         isl_qpolynomial_free(qp2);
2475         return NULL;
2476 }
2477
2478 __isl_give isl_qpolynomial *isl_qpolynomial_insert_dims(
2479         __isl_take isl_qpolynomial *qp, enum isl_dim_type type,
2480         unsigned first, unsigned n)
2481 {
2482         unsigned total;
2483         unsigned g_pos;
2484         int *exp;
2485
2486         if (n == 0)
2487                 return qp;
2488
2489         qp = isl_qpolynomial_cow(qp);
2490         if (!qp)
2491                 return NULL;
2492
2493         isl_assert(qp->div->ctx, first <= isl_dim_size(qp->dim, type),
2494                     goto error);
2495
2496         g_pos = pos(qp->dim, type) + first;
2497
2498         qp->div = isl_mat_insert_cols(qp->div, 2 + g_pos, n);
2499         if (!qp->div)
2500                 goto error;
2501
2502         total = qp->div->n_col - 2;
2503         if (total > g_pos) {
2504                 int i;
2505                 exp = isl_alloc_array(qp->div->ctx, int, total - g_pos);
2506                 if (!exp)
2507                         goto error;
2508                 for (i = 0; i < total - g_pos; ++i)
2509                         exp[i] = i + n;
2510                 qp->upoly = expand(qp->upoly, exp, g_pos);
2511                 free(exp);
2512                 if (!qp->upoly)
2513                         goto error;
2514         }
2515
2516         qp->dim = isl_dim_insert(qp->dim, type, first, n);
2517         if (!qp->dim)
2518                 goto error;
2519
2520         return qp;
2521 error:
2522         isl_qpolynomial_free(qp);
2523         return NULL;
2524 }
2525
2526 __isl_give isl_qpolynomial *isl_qpolynomial_add_dims(
2527         __isl_take isl_qpolynomial *qp, enum isl_dim_type type, unsigned n)
2528 {
2529         unsigned pos;
2530
2531         pos = isl_qpolynomial_dim(qp, type);
2532
2533         return isl_qpolynomial_insert_dims(qp, type, pos, n);
2534 }
2535
2536 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_dims(
2537         __isl_take isl_pw_qpolynomial *pwqp,
2538         enum isl_dim_type type, unsigned n)
2539 {
2540         unsigned pos;
2541
2542         pos = isl_pw_qpolynomial_dim(pwqp, type);
2543
2544         return isl_pw_qpolynomial_insert_dims(pwqp, type, pos, n);
2545 }
2546
2547 static int *reordering_move(isl_ctx *ctx,
2548         unsigned len, unsigned dst, unsigned src, unsigned n)
2549 {
2550         int i;
2551         int *reordering;
2552
2553         reordering = isl_alloc_array(ctx, int, len);
2554         if (!reordering)
2555                 return NULL;
2556
2557         if (dst <= src) {
2558                 for (i = 0; i < dst; ++i)
2559                         reordering[i] = i;
2560                 for (i = 0; i < n; ++i)
2561                         reordering[src + i] = dst + i;
2562                 for (i = 0; i < src - dst; ++i)
2563                         reordering[dst + i] = dst + n + i;
2564                 for (i = 0; i < len - src - n; ++i)
2565                         reordering[src + n + i] = src + n + i;
2566         } else {
2567                 for (i = 0; i < src; ++i)
2568                         reordering[i] = i;
2569                 for (i = 0; i < n; ++i)
2570                         reordering[src + i] = dst + i;
2571                 for (i = 0; i < dst - src; ++i)
2572                         reordering[src + n + i] = src + i;
2573                 for (i = 0; i < len - dst - n; ++i)
2574                         reordering[dst + n + i] = dst + n + i;
2575         }
2576
2577         return reordering;
2578 }
2579
2580 __isl_give isl_qpolynomial *isl_qpolynomial_move_dims(
2581         __isl_take isl_qpolynomial *qp,
2582         enum isl_dim_type dst_type, unsigned dst_pos,
2583         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2584 {
2585         unsigned g_dst_pos;
2586         unsigned g_src_pos;
2587         int *reordering;
2588
2589         qp = isl_qpolynomial_cow(qp);
2590         if (!qp)
2591                 return NULL;
2592
2593         isl_assert(qp->dim->ctx, src_pos + n <= isl_dim_size(qp->dim, src_type),
2594                 goto error);
2595
2596         g_dst_pos = pos(qp->dim, dst_type) + dst_pos;
2597         g_src_pos = pos(qp->dim, src_type) + src_pos;
2598         if (dst_type > src_type)
2599                 g_dst_pos -= n;
2600
2601         qp->div = isl_mat_move_cols(qp->div, 2 + g_dst_pos, 2 + g_src_pos, n);
2602         if (!qp->div)
2603                 goto error;
2604         qp = sort_divs(qp);
2605         if (!qp)
2606                 goto error;
2607
2608         reordering = reordering_move(qp->dim->ctx,
2609                                 qp->div->n_col - 2, g_dst_pos, g_src_pos, n);
2610         if (!reordering)
2611                 goto error;
2612
2613         qp->upoly = reorder(qp->upoly, reordering);
2614         free(reordering);
2615         if (!qp->upoly)
2616                 goto error;
2617
2618         qp->dim = isl_dim_move(qp->dim, dst_type, dst_pos, src_type, src_pos, n);
2619         if (!qp->dim)
2620                 goto error;
2621
2622         return qp;
2623 error:
2624         isl_qpolynomial_free(qp);
2625         return NULL;
2626 }
2627
2628 __isl_give isl_qpolynomial *isl_qpolynomial_from_affine(__isl_take isl_dim *dim,
2629         isl_int *f, isl_int denom)
2630 {
2631         struct isl_upoly *up;
2632
2633         if (!dim)
2634                 return NULL;
2635
2636         up = isl_upoly_from_affine(dim->ctx, f, denom, 1 + isl_dim_total(dim));
2637
2638         return isl_qpolynomial_alloc(dim, 0, up);
2639 }
2640
2641 __isl_give isl_qpolynomial *isl_qpolynomial_from_constraint(
2642         __isl_take isl_constraint *c, enum isl_dim_type type, unsigned pos)
2643 {
2644         isl_int denom;
2645         isl_dim *dim;
2646         struct isl_upoly *up;
2647         isl_qpolynomial *qp;
2648         int sgn;
2649
2650         if (!c)
2651                 return NULL;
2652
2653         isl_int_init(denom);
2654
2655         isl_constraint_get_coefficient(c, type, pos, &denom);
2656         isl_constraint_set_coefficient(c, type, pos, c->ctx->zero);
2657         sgn = isl_int_sgn(denom);
2658         isl_int_abs(denom, denom);
2659         up = isl_upoly_from_affine(c->ctx, c->line[0], denom,
2660                                         1 + isl_constraint_dim(c, isl_dim_all));
2661         if (sgn < 0)
2662                 isl_int_neg(denom, denom);
2663         isl_constraint_set_coefficient(c, type, pos, denom);
2664
2665         dim = isl_dim_copy(c->bmap->dim);
2666
2667         isl_int_clear(denom);
2668         isl_constraint_free(c);
2669
2670         qp = isl_qpolynomial_alloc(dim, 0, up);
2671         if (sgn > 0)
2672                 qp = isl_qpolynomial_neg(qp);
2673         return qp;
2674 }
2675
2676 /* For each 0 <= i < "n", replace variable "first" + i of type "type"
2677  * in "qp" by subs[i].
2678  */
2679 __isl_give isl_qpolynomial *isl_qpolynomial_substitute(
2680         __isl_take isl_qpolynomial *qp,
2681         enum isl_dim_type type, unsigned first, unsigned n,
2682         __isl_keep isl_qpolynomial **subs)
2683 {
2684         int i;
2685         struct isl_upoly **ups;
2686
2687         if (n == 0)
2688                 return qp;
2689
2690         qp = isl_qpolynomial_cow(qp);
2691         if (!qp)
2692                 return NULL;
2693         for (i = 0; i < n; ++i)
2694                 if (!subs[i])
2695                         goto error;
2696
2697         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
2698                         goto error);
2699
2700         for (i = 0; i < n; ++i)
2701                 isl_assert(qp->dim->ctx, isl_dim_equal(qp->dim, subs[i]->dim),
2702                                 goto error);
2703
2704         isl_assert(qp->dim->ctx, qp->div->n_row == 0, goto error);
2705         for (i = 0; i < n; ++i)
2706                 isl_assert(qp->dim->ctx, subs[i]->div->n_row == 0, goto error);
2707
2708         first += pos(qp->dim, type);
2709
2710         ups = isl_alloc_array(qp->dim->ctx, struct isl_upoly *, n);
2711         if (!ups)
2712                 goto error;
2713         for (i = 0; i < n; ++i)
2714                 ups[i] = subs[i]->upoly;
2715
2716         qp->upoly = isl_upoly_subs(qp->upoly, first, n, ups);
2717
2718         free(ups);
2719
2720         if (!qp->upoly)
2721                 goto error;
2722
2723         return qp;
2724 error:
2725         isl_qpolynomial_free(qp);
2726         return NULL;
2727 }
2728
2729 /* Extend "bset" with extra set dimensions for each integer division
2730  * in "qp" and then call "fn" with the extended bset and the polynomial
2731  * that results from replacing each of the integer divisions by the
2732  * corresponding extra set dimension.
2733  */
2734 int isl_qpolynomial_as_polynomial_on_domain(__isl_keep isl_qpolynomial *qp,
2735         __isl_keep isl_basic_set *bset,
2736         int (*fn)(__isl_take isl_basic_set *bset,
2737                   __isl_take isl_qpolynomial *poly, void *user), void *user)
2738 {
2739         isl_dim *dim;
2740         isl_mat *div;
2741         isl_qpolynomial *poly;
2742
2743         if (!qp || !bset)
2744                 goto error;
2745         if (qp->div->n_row == 0)
2746                 return fn(isl_basic_set_copy(bset), isl_qpolynomial_copy(qp),
2747                           user);
2748
2749         div = isl_mat_copy(qp->div);
2750         dim = isl_dim_copy(qp->dim);
2751         dim = isl_dim_add(dim, isl_dim_set, qp->div->n_row);
2752         poly = isl_qpolynomial_alloc(dim, 0, isl_upoly_copy(qp->upoly));
2753         bset = isl_basic_set_copy(bset);
2754         bset = isl_basic_set_add(bset, isl_dim_set, qp->div->n_row);
2755         bset = add_div_constraints(bset, div);
2756
2757         return fn(bset, poly, user);
2758 error:
2759         return -1;
2760 }
2761
2762 /* Return total degree in variables first (inclusive) up to last (exclusive).
2763  */
2764 int isl_upoly_degree(__isl_keep struct isl_upoly *up, int first, int last)
2765 {
2766         int deg = -1;
2767         int i;
2768         struct isl_upoly_rec *rec;
2769
2770         if (!up)
2771                 return -2;
2772         if (isl_upoly_is_zero(up))
2773                 return -1;
2774         if (isl_upoly_is_cst(up) || up->var < first)
2775                 return 0;
2776
2777         rec = isl_upoly_as_rec(up);
2778         if (!rec)
2779                 return -2;
2780
2781         for (i = 0; i < rec->n; ++i) {
2782                 int d;
2783
2784                 if (isl_upoly_is_zero(rec->p[i]))
2785                         continue;
2786                 d = isl_upoly_degree(rec->p[i], first, last);
2787                 if (up->var < last)
2788                         d += i;
2789                 if (d > deg)
2790                         deg = d;
2791         }
2792
2793         return deg;
2794 }
2795
2796 /* Return total degree in set variables.
2797  */
2798 int isl_qpolynomial_degree(__isl_keep isl_qpolynomial *poly)
2799 {
2800         unsigned ovar;
2801         unsigned nvar;
2802
2803         if (!poly)
2804                 return -2;
2805
2806         ovar = isl_dim_offset(poly->dim, isl_dim_set);
2807         nvar = isl_dim_size(poly->dim, isl_dim_set);
2808         return isl_upoly_degree(poly->upoly, ovar, ovar + nvar);
2809 }
2810
2811 __isl_give struct isl_upoly *isl_upoly_coeff(__isl_keep struct isl_upoly *up,
2812         unsigned pos, int deg)
2813 {
2814         int i;
2815         struct isl_upoly_rec *rec;
2816
2817         if (!up)
2818                 return NULL;
2819
2820         if (isl_upoly_is_cst(up) || up->var < pos) {
2821                 if (deg == 0)
2822                         return isl_upoly_copy(up);
2823                 else
2824                         return isl_upoly_zero(up->ctx);
2825         }
2826
2827         rec = isl_upoly_as_rec(up);
2828         if (!rec)
2829                 return NULL;
2830
2831         if (up->var == pos) {
2832                 if (deg < rec->n)
2833                         return isl_upoly_copy(rec->p[deg]);
2834                 else
2835                         return isl_upoly_zero(up->ctx);
2836         }
2837
2838         up = isl_upoly_copy(up);
2839         up = isl_upoly_cow(up);
2840         rec = isl_upoly_as_rec(up);
2841         if (!rec)
2842                 goto error;
2843
2844         for (i = 0; i < rec->n; ++i) {
2845                 struct isl_upoly *t;
2846                 t = isl_upoly_coeff(rec->p[i], pos, deg);
2847                 if (!t)
2848                         goto error;
2849                 isl_upoly_free(rec->p[i]);
2850                 rec->p[i] = t;
2851         }
2852
2853         return up;
2854 error:
2855         isl_upoly_free(up);
2856         return NULL;
2857 }
2858
2859 /* Return coefficient of power "deg" of variable "t_pos" of type "type".
2860  */
2861 __isl_give isl_qpolynomial *isl_qpolynomial_coeff(
2862         __isl_keep isl_qpolynomial *qp,
2863         enum isl_dim_type type, unsigned t_pos, int deg)
2864 {
2865         unsigned g_pos;
2866         struct isl_upoly *up;
2867         isl_qpolynomial *c;
2868
2869         if (!qp)
2870                 return NULL;
2871
2872         isl_assert(qp->div->ctx, t_pos < isl_dim_size(qp->dim, type),
2873                         return NULL);
2874
2875         g_pos = pos(qp->dim, type) + t_pos;
2876         up = isl_upoly_coeff(qp->upoly, g_pos, deg);
2877
2878         c = isl_qpolynomial_alloc(isl_dim_copy(qp->dim), qp->div->n_row, up);
2879         if (!c)
2880                 return NULL;
2881         isl_mat_free(c->div);
2882         c->div = isl_mat_copy(qp->div);
2883         if (!c->div)
2884                 goto error;
2885         return c;
2886 error:
2887         isl_qpolynomial_free(c);
2888         return NULL;
2889 }
2890
2891 /* Homogenize the polynomial in the variables first (inclusive) up to
2892  * last (exclusive) by inserting powers of variable first.
2893  * Variable first is assumed not to appear in the input.
2894  */
2895 __isl_give struct isl_upoly *isl_upoly_homogenize(
2896         __isl_take struct isl_upoly *up, int deg, int target,
2897         int first, int last)
2898 {
2899         int i;
2900         struct isl_upoly_rec *rec;
2901
2902         if (!up)
2903                 return NULL;
2904         if (isl_upoly_is_zero(up))
2905                 return up;
2906         if (deg == target)
2907                 return up;
2908         if (isl_upoly_is_cst(up) || up->var < first) {
2909                 struct isl_upoly *hom;
2910
2911                 hom = isl_upoly_pow(up->ctx, first, target - deg);
2912                 if (!hom)
2913                         goto error;
2914                 rec = isl_upoly_as_rec(hom);
2915                 rec->p[target - deg] = isl_upoly_mul(rec->p[target - deg], up);
2916
2917                 return hom;
2918         }
2919
2920         up = isl_upoly_cow(up);
2921         rec = isl_upoly_as_rec(up);
2922         if (!rec)
2923                 goto error;
2924
2925         for (i = 0; i < rec->n; ++i) {
2926                 if (isl_upoly_is_zero(rec->p[i]))
2927                         continue;
2928                 rec->p[i] = isl_upoly_homogenize(rec->p[i],
2929                                 up->var < last ? deg + i : i, target,
2930                                 first, last);
2931                 if (!rec->p[i])
2932                         goto error;
2933         }
2934
2935         return up;
2936 error:
2937         isl_upoly_free(up);
2938         return NULL;
2939 }
2940
2941 /* Homogenize the polynomial in the set variables by introducing
2942  * powers of an extra set variable at position 0.
2943  */
2944 __isl_give isl_qpolynomial *isl_qpolynomial_homogenize(
2945         __isl_take isl_qpolynomial *poly)
2946 {
2947         unsigned ovar;
2948         unsigned nvar;
2949         int deg = isl_qpolynomial_degree(poly);
2950
2951         if (deg < -1)
2952                 goto error;
2953
2954         poly = isl_qpolynomial_insert_dims(poly, isl_dim_set, 0, 1);
2955         poly = isl_qpolynomial_cow(poly);
2956         if (!poly)
2957                 goto error;
2958
2959         ovar = isl_dim_offset(poly->dim, isl_dim_set);
2960         nvar = isl_dim_size(poly->dim, isl_dim_set);
2961         poly->upoly = isl_upoly_homogenize(poly->upoly, 0, deg,
2962                                                 ovar, ovar + nvar);
2963         if (!poly->upoly)
2964                 goto error;
2965
2966         return poly;
2967 error:
2968         isl_qpolynomial_free(poly);
2969         return NULL;
2970 }
2971
2972 __isl_give isl_term *isl_term_alloc(__isl_take isl_dim *dim,
2973         __isl_take isl_mat *div)
2974 {
2975         isl_term *term;
2976         int n;
2977
2978         if (!dim || !div)
2979                 goto error;
2980
2981         n = isl_dim_total(dim) + div->n_row;
2982
2983         term = isl_calloc(dim->ctx, struct isl_term,
2984                         sizeof(struct isl_term) + (n - 1) * sizeof(int));
2985         if (!term)
2986                 goto error;
2987
2988         term->ref = 1;
2989         term->dim = dim;
2990         term->div = div;
2991         isl_int_init(term->n);
2992         isl_int_init(term->d);
2993         
2994         return term;
2995 error:
2996         isl_dim_free(dim);
2997         isl_mat_free(div);
2998         return NULL;
2999 }
3000
3001 __isl_give isl_term *isl_term_copy(__isl_keep isl_term *term)
3002 {
3003         if (!term)
3004                 return NULL;
3005
3006         term->ref++;
3007         return term;
3008 }
3009
3010 __isl_give isl_term *isl_term_dup(__isl_keep isl_term *term)
3011 {
3012         int i;
3013         isl_term *dup;
3014         unsigned total;
3015
3016         if (term)
3017                 return NULL;
3018
3019         total = isl_dim_total(term->dim) + term->div->n_row;
3020
3021         dup = isl_term_alloc(isl_dim_copy(term->dim), isl_mat_copy(term->div));
3022         if (!dup)
3023                 return NULL;
3024
3025         isl_int_set(dup->n, term->n);
3026         isl_int_set(dup->d, term->d);
3027
3028         for (i = 0; i < total; ++i)
3029                 dup->pow[i] = term->pow[i];
3030
3031         return dup;
3032 }
3033
3034 __isl_give isl_term *isl_term_cow(__isl_take isl_term *term)
3035 {
3036         if (!term)
3037                 return NULL;
3038
3039         if (term->ref == 1)
3040                 return term;
3041         term->ref--;
3042         return isl_term_dup(term);
3043 }
3044
3045 void isl_term_free(__isl_take isl_term *term)
3046 {
3047         if (!term)
3048                 return;
3049
3050         if (--term->ref > 0)
3051                 return;
3052
3053         isl_dim_free(term->dim);
3054         isl_mat_free(term->div);
3055         isl_int_clear(term->n);
3056         isl_int_clear(term->d);
3057         free(term);
3058 }
3059
3060 unsigned isl_term_dim(__isl_keep isl_term *term, enum isl_dim_type type)
3061 {
3062         if (!term)
3063                 return 0;
3064
3065         switch (type) {
3066         case isl_dim_param:
3067         case isl_dim_in:
3068         case isl_dim_out:       return isl_dim_size(term->dim, type);
3069         case isl_dim_div:       return term->div->n_row;
3070         case isl_dim_all:       return isl_dim_total(term->dim) + term->div->n_row;
3071         default:                return 0;
3072         }
3073 }
3074
3075 isl_ctx *isl_term_get_ctx(__isl_keep isl_term *term)
3076 {
3077         return term ? term->dim->ctx : NULL;
3078 }
3079
3080 void isl_term_get_num(__isl_keep isl_term *term, isl_int *n)
3081 {
3082         if (!term)
3083                 return;
3084         isl_int_set(*n, term->n);
3085 }
3086
3087 void isl_term_get_den(__isl_keep isl_term *term, isl_int *d)
3088 {
3089         if (!term)
3090                 return;
3091         isl_int_set(*d, term->d);
3092 }
3093
3094 int isl_term_get_exp(__isl_keep isl_term *term,
3095         enum isl_dim_type type, unsigned pos)
3096 {
3097         if (!term)
3098                 return -1;
3099
3100         isl_assert(term->dim->ctx, pos < isl_term_dim(term, type), return -1);
3101
3102         if (type >= isl_dim_set)
3103                 pos += isl_dim_size(term->dim, isl_dim_param);
3104         if (type >= isl_dim_div)
3105                 pos += isl_dim_size(term->dim, isl_dim_set);
3106
3107         return term->pow[pos];
3108 }
3109
3110 __isl_give isl_div *isl_term_get_div(__isl_keep isl_term *term, unsigned pos)
3111 {
3112         isl_basic_map *bmap;
3113         unsigned total;
3114         int k;
3115
3116         if (!term)
3117                 return NULL;
3118
3119         isl_assert(term->dim->ctx, pos < isl_term_dim(term, isl_dim_div),
3120                         return NULL);
3121
3122         total = term->div->n_col - term->div->n_row - 2;
3123         /* No nested divs for now */
3124         isl_assert(term->dim->ctx,
3125                 isl_seq_first_non_zero(term->div->row[pos] + 2 + total,
3126                                         term->div->n_row) == -1,
3127                 return NULL);
3128
3129         bmap = isl_basic_map_alloc_dim(isl_dim_copy(term->dim), 1, 0, 0);
3130         if ((k = isl_basic_map_alloc_div(bmap)) < 0)
3131                 goto error;
3132
3133         isl_seq_cpy(bmap->div[k], term->div->row[pos], 2 + total);
3134
3135         return isl_basic_map_div(bmap, k);
3136 error:
3137         isl_basic_map_free(bmap);
3138         return NULL;
3139 }
3140
3141 __isl_give isl_term *isl_upoly_foreach_term(__isl_keep struct isl_upoly *up,
3142         int (*fn)(__isl_take isl_term *term, void *user),
3143         __isl_take isl_term *term, void *user)
3144 {
3145         int i;
3146         struct isl_upoly_rec *rec;
3147
3148         if (!up || !term)
3149                 goto error;
3150
3151         if (isl_upoly_is_zero(up))
3152                 return term;
3153
3154         isl_assert(up->ctx, !isl_upoly_is_nan(up), goto error);
3155         isl_assert(up->ctx, !isl_upoly_is_infty(up), goto error);
3156         isl_assert(up->ctx, !isl_upoly_is_neginfty(up), goto error);
3157
3158         if (isl_upoly_is_cst(up)) {
3159                 struct isl_upoly_cst *cst;
3160                 cst = isl_upoly_as_cst(up);
3161                 if (!cst)
3162                         goto error;
3163                 term = isl_term_cow(term);
3164                 if (!term)
3165                         goto error;
3166                 isl_int_set(term->n, cst->n);
3167                 isl_int_set(term->d, cst->d);
3168                 if (fn(isl_term_copy(term), user) < 0)
3169                         goto error;
3170                 return term;
3171         }
3172
3173         rec = isl_upoly_as_rec(up);
3174         if (!rec)
3175                 goto error;
3176
3177         for (i = 0; i < rec->n; ++i) {
3178                 term = isl_term_cow(term);
3179                 if (!term)
3180                         goto error;
3181                 term->pow[up->var] = i;
3182                 term = isl_upoly_foreach_term(rec->p[i], fn, term, user);
3183                 if (!term)
3184                         goto error;
3185         }
3186         term->pow[up->var] = 0;
3187
3188         return term;
3189 error:
3190         isl_term_free(term);
3191         return NULL;
3192 }
3193
3194 int isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp,
3195         int (*fn)(__isl_take isl_term *term, void *user), void *user)
3196 {
3197         isl_term *term;
3198
3199         if (!qp)
3200                 return -1;
3201
3202         term = isl_term_alloc(isl_dim_copy(qp->dim), isl_mat_copy(qp->div));
3203         if (!term)
3204                 return -1;
3205
3206         term = isl_upoly_foreach_term(qp->upoly, fn, term, user);
3207
3208         isl_term_free(term);
3209
3210         return term ? 0 : -1;
3211 }
3212
3213 __isl_give isl_qpolynomial *isl_qpolynomial_from_term(__isl_take isl_term *term)
3214 {
3215         struct isl_upoly *up;
3216         isl_qpolynomial *qp;
3217         int i, n;
3218
3219         if (!term)
3220                 return NULL;
3221
3222         n = isl_dim_total(term->dim) + term->div->n_row;
3223
3224         up = isl_upoly_rat_cst(term->dim->ctx, term->n, term->d);
3225         for (i = 0; i < n; ++i) {
3226                 if (!term->pow[i])
3227                         continue;
3228                 up = isl_upoly_mul(up,
3229                         isl_upoly_pow(term->dim->ctx, i, term->pow[i]));
3230         }
3231
3232         qp = isl_qpolynomial_alloc(isl_dim_copy(term->dim), term->div->n_row, up);
3233         if (!qp)
3234                 goto error;
3235         isl_mat_free(qp->div);
3236         qp->div = isl_mat_copy(term->div);
3237         if (!qp->div)
3238                 goto error;
3239
3240         isl_term_free(term);
3241         return qp;
3242 error:
3243         isl_qpolynomial_free(qp);
3244         isl_term_free(term);
3245         return NULL;
3246 }
3247
3248 __isl_give isl_qpolynomial *isl_qpolynomial_lift(__isl_take isl_qpolynomial *qp,
3249         __isl_take isl_dim *dim)
3250 {
3251         int i;
3252         int extra;
3253         unsigned total;
3254
3255         if (!qp || !dim)
3256                 goto error;
3257
3258         if (isl_dim_equal(qp->dim, dim)) {
3259                 isl_dim_free(dim);
3260                 return qp;
3261         }
3262
3263         qp = isl_qpolynomial_cow(qp);
3264         if (!qp)
3265                 goto error;
3266
3267         extra = isl_dim_size(dim, isl_dim_set) -
3268                         isl_dim_size(qp->dim, isl_dim_set);
3269         total = isl_dim_total(qp->dim);
3270         if (qp->div->n_row) {
3271                 int *exp;
3272
3273                 exp = isl_alloc_array(qp->div->ctx, int, qp->div->n_row);
3274                 if (!exp)
3275                         goto error;
3276                 for (i = 0; i < qp->div->n_row; ++i)
3277                         exp[i] = extra + i;
3278                 qp->upoly = expand(qp->upoly, exp, total);
3279                 free(exp);
3280                 if (!qp->upoly)
3281                         goto error;
3282         }
3283         qp->div = isl_mat_insert_cols(qp->div, 2 + total, extra);
3284         if (!qp->div)
3285                 goto error;
3286         for (i = 0; i < qp->div->n_row; ++i)
3287                 isl_seq_clr(qp->div->row[i] + 2 + total, extra);
3288
3289         isl_dim_free(qp->dim);
3290         qp->dim = dim;
3291
3292         return qp;
3293 error:
3294         isl_dim_free(dim);
3295         isl_qpolynomial_free(qp);
3296         return NULL;
3297 }
3298
3299 /* For each parameter or variable that does not appear in qp,
3300  * first eliminate the variable from all constraints and then set it to zero.
3301  */
3302 static __isl_give isl_set *fix_inactive(__isl_take isl_set *set,
3303         __isl_keep isl_qpolynomial *qp)
3304 {
3305         int *active = NULL;
3306         int i;
3307         int d;
3308         unsigned nparam;
3309         unsigned nvar;
3310
3311         if (!set || !qp)
3312                 goto error;
3313
3314         d = isl_dim_total(set->dim);
3315         active = isl_calloc_array(set->ctx, int, d);
3316         if (set_active(qp, active) < 0)
3317                 goto error;
3318
3319         for (i = 0; i < d; ++i)
3320                 if (!active[i])
3321                         break;
3322
3323         if (i == d) {
3324                 free(active);
3325                 return set;
3326         }
3327
3328         nparam = isl_dim_size(set->dim, isl_dim_param);
3329         nvar = isl_dim_size(set->dim, isl_dim_set);
3330         for (i = 0; i < nparam; ++i) {
3331                 if (active[i])
3332                         continue;
3333                 set = isl_set_eliminate(set, isl_dim_param, i, 1);
3334                 set = isl_set_fix_si(set, isl_dim_param, i, 0);
3335         }
3336         for (i = 0; i < nvar; ++i) {
3337                 if (active[nparam + i])
3338                         continue;
3339                 set = isl_set_eliminate(set, isl_dim_set, i, 1);
3340                 set = isl_set_fix_si(set, isl_dim_set, i, 0);
3341         }
3342
3343         free(active);
3344
3345         return set;
3346 error:
3347         free(active);
3348         isl_set_free(set);
3349         return NULL;
3350 }
3351
3352 struct isl_opt_data {
3353         isl_qpolynomial *qp;
3354         int first;
3355         isl_qpolynomial *opt;
3356         int max;
3357 };
3358
3359 static int opt_fn(__isl_take isl_point *pnt, void *user)
3360 {
3361         struct isl_opt_data *data = (struct isl_opt_data *)user;
3362         isl_qpolynomial *val;
3363
3364         val = isl_qpolynomial_eval(isl_qpolynomial_copy(data->qp), pnt);
3365         if (data->first) {
3366                 data->first = 0;
3367                 data->opt = val;
3368         } else if (data->max) {
3369                 data->opt = isl_qpolynomial_max_cst(data->opt, val);
3370         } else {
3371                 data->opt = isl_qpolynomial_min_cst(data->opt, val);
3372         }
3373
3374         return 0;
3375 }
3376
3377 __isl_give isl_qpolynomial *isl_qpolynomial_opt_on_domain(
3378         __isl_take isl_qpolynomial *qp, __isl_take isl_set *set, int max)
3379 {
3380         struct isl_opt_data data = { NULL, 1, NULL, max };
3381
3382         if (!set || !qp)
3383                 goto error;
3384
3385         if (isl_upoly_is_cst(qp->upoly)) {
3386                 isl_set_free(set);
3387                 return qp;
3388         }
3389
3390         set = fix_inactive(set, qp);
3391
3392         data.qp = qp;
3393         if (isl_set_foreach_point(set, opt_fn, &data) < 0)
3394                 goto error;
3395
3396         if (data.first)
3397                 data.opt = isl_qpolynomial_zero(isl_qpolynomial_get_dim(qp));
3398
3399         isl_set_free(set);
3400         isl_qpolynomial_free(qp);
3401         return data.opt;
3402 error:
3403         isl_set_free(set);
3404         isl_qpolynomial_free(qp);
3405         isl_qpolynomial_free(data.opt);
3406         return NULL;
3407 }
3408
3409 __isl_give isl_qpolynomial *isl_qpolynomial_morph(__isl_take isl_qpolynomial *qp,
3410         __isl_take isl_morph *morph)
3411 {
3412         int i;
3413         int n_sub;
3414         isl_ctx *ctx;
3415         struct isl_upoly *up;
3416         unsigned n_div;
3417         struct isl_upoly **subs;
3418         isl_mat *mat;
3419
3420         qp = isl_qpolynomial_cow(qp);
3421         if (!qp || !morph)
3422                 goto error;
3423
3424         ctx = qp->dim->ctx;
3425         isl_assert(ctx, isl_dim_equal(qp->dim, morph->dom->dim), goto error);
3426
3427         n_sub = morph->inv->n_row - 1;
3428         if (morph->inv->n_row != morph->inv->n_col)
3429                 n_sub += qp->div->n_row;
3430         subs = isl_calloc_array(ctx, struct isl_upoly *, n_sub);
3431         if (!subs)
3432                 goto error;
3433
3434         for (i = 0; 1 + i < morph->inv->n_row; ++i)
3435                 subs[i] = isl_upoly_from_affine(ctx, morph->inv->row[1 + i],
3436                                         morph->inv->row[0][0], morph->inv->n_col);
3437         if (morph->inv->n_row != morph->inv->n_col)
3438                 for (i = 0; i < qp->div->n_row; ++i)
3439                         subs[morph->inv->n_row - 1 + i] =
3440                                 isl_upoly_pow(ctx, morph->inv->n_col - 1 + i, 1);
3441
3442         qp->upoly = isl_upoly_subs(qp->upoly, 0, n_sub, subs);
3443
3444         for (i = 0; i < n_sub; ++i)
3445                 isl_upoly_free(subs[i]);
3446         free(subs);
3447
3448         mat = isl_mat_diagonal(isl_mat_identity(ctx, 1), isl_mat_copy(morph->inv));
3449         mat = isl_mat_diagonal(mat, isl_mat_identity(ctx, qp->div->n_row));
3450         qp->div = isl_mat_product(qp->div, mat);
3451         isl_dim_free(qp->dim);
3452         qp->dim = isl_dim_copy(morph->ran->dim);
3453
3454         if (!qp->upoly || !qp->div || !qp->dim)
3455                 goto error;
3456
3457         isl_morph_free(morph);
3458
3459         return qp;
3460 error:
3461         isl_qpolynomial_free(qp);
3462         isl_morph_free(morph);
3463         return NULL;
3464 }
3465
3466 static int neg_entry(void **entry, void *user)
3467 {
3468         isl_pw_qpolynomial **pwqp = (isl_pw_qpolynomial **)entry;
3469
3470         *pwqp = isl_pw_qpolynomial_neg(*pwqp);
3471
3472         return *pwqp ? 0 : -1;
3473 }
3474
3475 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_neg(
3476         __isl_take isl_union_pw_qpolynomial *upwqp)
3477 {
3478         upwqp = isl_union_pw_qpolynomial_cow(upwqp);
3479         if (!upwqp)
3480                 return NULL;
3481
3482         if (isl_hash_table_foreach(upwqp->dim->ctx, &upwqp->table,
3483                                    &neg_entry, NULL) < 0)
3484                 goto error;
3485
3486         return upwqp;
3487 error:
3488         isl_union_pw_qpolynomial_free(upwqp);
3489         return NULL;
3490 }
3491
3492 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub(
3493         __isl_take isl_union_pw_qpolynomial *upwqp1,
3494         __isl_take isl_union_pw_qpolynomial *upwqp2)
3495 {
3496         return isl_union_pw_qpolynomial_add(upwqp1,
3497                                         isl_union_pw_qpolynomial_neg(upwqp2));
3498 }
3499
3500 static int mul_entry(void **entry, void *user)
3501 {
3502         struct isl_union_pw_qpolynomial_match_bin_data *data = user;
3503         uint32_t hash;
3504         struct isl_hash_table_entry *entry2;
3505         isl_pw_qpolynomial *pwpq = *entry;
3506         int empty;
3507
3508         hash = isl_dim_get_hash(pwpq->dim);
3509         entry2 = isl_hash_table_find(data->u2->dim->ctx, &data->u2->table,
3510                                      hash, &has_dim, pwpq->dim, 0);
3511         if (!entry2)
3512                 return 0;
3513
3514         pwpq = isl_pw_qpolynomial_copy(pwpq);
3515         pwpq = isl_pw_qpolynomial_mul(pwpq,
3516                                       isl_pw_qpolynomial_copy(entry2->data));
3517
3518         empty = isl_pw_qpolynomial_is_zero(pwpq);
3519         if (empty < 0) {
3520                 isl_pw_qpolynomial_free(pwpq);
3521                 return -1;
3522         }
3523         if (empty) {
3524                 isl_pw_qpolynomial_free(pwpq);
3525                 return 0;
3526         }
3527
3528         data->res = isl_union_pw_qpolynomial_add_pw_qpolynomial(data->res, pwpq);
3529
3530         return 0;
3531 }
3532
3533 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul(
3534         __isl_take isl_union_pw_qpolynomial *upwqp1,
3535         __isl_take isl_union_pw_qpolynomial *upwqp2)
3536 {
3537         return match_bin_op(upwqp1, upwqp2, &mul_entry);
3538 }
3539
3540 /* Reorder the columns of the given div definitions according to the
3541  * given reordering.
3542  */
3543 static __isl_give isl_mat *reorder_divs(__isl_take isl_mat *div,
3544         __isl_take isl_reordering *r)
3545 {
3546         int i, j;
3547         isl_mat *mat;
3548         int extra;
3549
3550         if (!div || !r)
3551                 goto error;
3552
3553         extra = isl_dim_total(r->dim) + div->n_row - r->len;
3554         mat = isl_mat_alloc(div->ctx, div->n_row, div->n_col + extra);
3555         if (!mat)
3556                 goto error;
3557
3558         for (i = 0; i < div->n_row; ++i) {
3559                 isl_seq_cpy(mat->row[i], div->row[i], 2);
3560                 isl_seq_clr(mat->row[i] + 2, mat->n_col - 2);
3561                 for (j = 0; j < r->len; ++j)
3562                         isl_int_set(mat->row[i][2 + r->pos[j]],
3563                                     div->row[i][2 + j]);
3564         }
3565
3566         isl_reordering_free(r);
3567         isl_mat_free(div);
3568         return mat;
3569 error:
3570         isl_reordering_free(r);
3571         isl_mat_free(div);
3572         return NULL;
3573 }
3574
3575 /* Reorder the dimension of "qp" according to the given reordering.
3576  */
3577 __isl_give isl_qpolynomial *isl_qpolynomial_realign(
3578         __isl_take isl_qpolynomial *qp, __isl_take isl_reordering *r)
3579 {
3580         qp = isl_qpolynomial_cow(qp);
3581         if (!qp)
3582                 goto error;
3583
3584         r = isl_reordering_extend(r, qp->div->n_row);
3585         if (!r)
3586                 goto error;
3587
3588         qp->div = reorder_divs(qp->div, isl_reordering_copy(r));
3589         if (!qp->div)
3590                 goto error;
3591
3592         qp->upoly = reorder(qp->upoly, r->pos);
3593         if (!qp->upoly)
3594                 goto error;
3595
3596         qp = isl_qpolynomial_reset_dim(qp, isl_dim_copy(r->dim));
3597
3598         isl_reordering_free(r);
3599         return qp;
3600 error:
3601         isl_qpolynomial_free(qp);
3602         isl_reordering_free(r);
3603         return NULL;
3604 }
3605
3606 struct isl_split_periods_data {
3607         int max_periods;
3608         isl_pw_qpolynomial *res;
3609 };
3610
3611 /* Create a slice where the integer division "div" has the fixed value "v".
3612  * In particular, if "div" refers to floor(f/m), then create a slice
3613  *
3614  *      m v <= f <= m v + (m - 1)
3615  *
3616  * or
3617  *
3618  *      f - m v >= 0
3619  *      -f + m v + (m - 1) >= 0
3620  */
3621 static __isl_give isl_set *set_div_slice(__isl_take isl_dim *dim,
3622         __isl_keep isl_qpolynomial *qp, int div, isl_int v)
3623 {
3624         int total;
3625         isl_basic_set *bset = NULL;
3626         int k;
3627
3628         if (!dim || !qp)
3629                 goto error;
3630
3631         total = isl_dim_total(dim);
3632         bset = isl_basic_set_alloc_dim(isl_dim_copy(dim), 0, 0, 2);
3633
3634         k = isl_basic_set_alloc_inequality(bset);
3635         if (k < 0)
3636                 goto error;
3637         isl_seq_cpy(bset->ineq[k], qp->div->row[div] + 1, 1 + total);
3638         isl_int_submul(bset->ineq[k][0], v, qp->div->row[div][0]);
3639
3640         k = isl_basic_set_alloc_inequality(bset);
3641         if (k < 0)
3642                 goto error;
3643         isl_seq_neg(bset->ineq[k], qp->div->row[div] + 1, 1 + total);
3644         isl_int_addmul(bset->ineq[k][0], v, qp->div->row[div][0]);
3645         isl_int_add(bset->ineq[k][0], bset->ineq[k][0], qp->div->row[div][0]);
3646         isl_int_sub_ui(bset->ineq[k][0], bset->ineq[k][0], 1);
3647
3648         isl_dim_free(dim);
3649         return isl_set_from_basic_set(bset);
3650 error:
3651         isl_basic_set_free(bset);
3652         isl_dim_free(dim);
3653         return NULL;
3654 }
3655
3656 static int split_periods(__isl_take isl_set *set,
3657         __isl_take isl_qpolynomial *qp, void *user);
3658
3659 /* Create a slice of the domain "set" such that integer division "div"
3660  * has the fixed value "v" and add the results to data->res,
3661  * replacing the integer division by "v" in "qp".
3662  */
3663 static int set_div(__isl_take isl_set *set,
3664         __isl_take isl_qpolynomial *qp, int div, isl_int v,
3665         struct isl_split_periods_data *data)
3666 {
3667         int i;
3668         int total;
3669         isl_set *slice;
3670         struct isl_upoly *cst;
3671
3672         slice = set_div_slice(isl_set_get_dim(set), qp, div, v);
3673         set = isl_set_intersect(set, slice);
3674
3675         if (!qp)
3676                 goto error;
3677
3678         total = isl_dim_total(qp->dim);
3679
3680         for (i = div + 1; i < qp->div->n_row; ++i) {
3681                 if (isl_int_is_zero(qp->div->row[i][2 + total + div]))
3682                         continue;
3683                 isl_int_addmul(qp->div->row[i][1],
3684                                 qp->div->row[i][2 + total + div], v);
3685                 isl_int_set_si(qp->div->row[i][2 + total + div], 0);
3686         }
3687
3688         cst = isl_upoly_rat_cst(qp->dim->ctx, v, qp->dim->ctx->one);
3689         qp = substitute_div(qp, div, cst);
3690
3691         return split_periods(set, qp, data);
3692 error:
3693         isl_set_free(set);
3694         isl_qpolynomial_free(qp);
3695         return -1;
3696 }
3697
3698 /* Split the domain "set" such that integer division "div"
3699  * has a fixed value (ranging from "min" to "max") on each slice
3700  * and add the results to data->res.
3701  */
3702 static int split_div(__isl_take isl_set *set,
3703         __isl_take isl_qpolynomial *qp, int div, isl_int min, isl_int max,
3704         struct isl_split_periods_data *data)
3705 {
3706         for (; isl_int_le(min, max); isl_int_add_ui(min, min, 1)) {
3707                 isl_set *set_i = isl_set_copy(set);
3708                 isl_qpolynomial *qp_i = isl_qpolynomial_copy(qp);
3709
3710                 if (set_div(set_i, qp_i, div, min, data) < 0)
3711                         goto error;
3712         }
3713         isl_set_free(set);
3714         isl_qpolynomial_free(qp);
3715         return 0;
3716 error:
3717         isl_set_free(set);
3718         isl_qpolynomial_free(qp);
3719         return -1;
3720 }
3721
3722 /* If "qp" refers to any integer division
3723  * that can only attain "max_periods" distinct values on "set"
3724  * then split the domain along those distinct values.
3725  * Add the results (or the original if no splitting occurs)
3726  * to data->res.
3727  */
3728 static int split_periods(__isl_take isl_set *set,
3729         __isl_take isl_qpolynomial *qp, void *user)
3730 {
3731         int i;
3732         isl_pw_qpolynomial *pwqp;
3733         struct isl_split_periods_data *data;
3734         isl_int min, max;
3735         int total;
3736         int r = 0;
3737
3738         data = (struct isl_split_periods_data *)user;
3739
3740         if (!set || !qp)
3741                 goto error;
3742
3743         if (qp->div->n_row == 0) {
3744                 pwqp = isl_pw_qpolynomial_alloc(set, qp);
3745                 data->res = isl_pw_qpolynomial_add_disjoint(data->res, pwqp);
3746                 return 0;
3747         }
3748
3749         isl_int_init(min);
3750         isl_int_init(max);
3751         total = isl_dim_total(qp->dim);
3752         for (i = 0; i < qp->div->n_row; ++i) {
3753                 enum isl_lp_result lp_res;
3754
3755                 if (isl_seq_first_non_zero(qp->div->row[i] + 2 + total,
3756                                                 qp->div->n_row) != -1)
3757                         continue;
3758
3759                 lp_res = isl_set_solve_lp(set, 0, qp->div->row[i] + 1,
3760                                           set->ctx->one, &min, NULL, NULL);
3761                 if (lp_res == isl_lp_error)
3762                         goto error2;
3763                 if (lp_res == isl_lp_unbounded || lp_res == isl_lp_empty)
3764                         continue;
3765                 isl_int_fdiv_q(min, min, qp->div->row[i][0]);
3766
3767                 lp_res = isl_set_solve_lp(set, 1, qp->div->row[i] + 1,
3768                                           set->ctx->one, &max, NULL, NULL);
3769                 if (lp_res == isl_lp_error)
3770                         goto error2;
3771                 if (lp_res == isl_lp_unbounded || lp_res == isl_lp_empty)
3772                         continue;
3773                 isl_int_fdiv_q(max, max, qp->div->row[i][0]);
3774
3775                 isl_int_sub(max, max, min);
3776                 if (isl_int_cmp_si(max, data->max_periods) < 0) {
3777                         isl_int_add(max, max, min);
3778                         break;
3779                 }
3780         }
3781
3782         if (i < qp->div->n_row) {
3783                 r = split_div(set, qp, i, min, max, data);
3784         } else {
3785                 pwqp = isl_pw_qpolynomial_alloc(set, qp);
3786                 data->res = isl_pw_qpolynomial_add_disjoint(data->res, pwqp);
3787         }
3788
3789         isl_int_clear(max);
3790         isl_int_clear(min);
3791
3792         return r;
3793 error2:
3794         isl_int_clear(max);
3795         isl_int_clear(min);
3796 error:
3797         isl_set_free(set);
3798         isl_qpolynomial_free(qp);
3799         return -1;
3800 }
3801
3802 /* If any quasi-polynomial in pwqp refers to any integer division
3803  * that can only attain "max_periods" distinct values on its domain
3804  * then split the domain along those distinct values.
3805  */
3806 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_split_periods(
3807         __isl_take isl_pw_qpolynomial *pwqp, int max_periods)
3808 {
3809         struct isl_split_periods_data data;
3810
3811         data.max_periods = max_periods;
3812         data.res = isl_pw_qpolynomial_zero(isl_pw_qpolynomial_get_dim(pwqp));
3813
3814         if (isl_pw_qpolynomial_foreach_piece(pwqp, &split_periods, &data) < 0)
3815                 goto error;
3816
3817         isl_pw_qpolynomial_free(pwqp);
3818
3819         return data.res;
3820 error:
3821         isl_pw_qpolynomial_free(data.res);
3822         isl_pw_qpolynomial_free(pwqp);
3823         return NULL;
3824 }
3825
3826 /* Construct a piecewise quasipolynomial that is constant on the given
3827  * domain.  In particular, it is
3828  *      0       if cst == 0
3829  *      1       if cst == 1
3830  *  infinity    if cst == -1
3831  */
3832 static __isl_give isl_pw_qpolynomial *constant_on_domain(
3833         __isl_take isl_basic_set *bset, int cst)
3834 {
3835         isl_dim *dim;
3836         isl_qpolynomial *qp;
3837
3838         if (!bset)
3839                 return NULL;
3840
3841         bset = isl_basic_map_domain(isl_basic_map_from_range(bset));
3842         dim = isl_basic_set_get_dim(bset);
3843         if (cst < 0)
3844                 qp = isl_qpolynomial_infty(dim);
3845         else if (cst == 0)
3846                 qp = isl_qpolynomial_zero(dim);
3847         else
3848                 qp = isl_qpolynomial_one(dim);
3849         return isl_pw_qpolynomial_alloc(isl_set_from_basic_set(bset), qp);
3850 }
3851
3852 /* Factor bset, call fn on each of the factors and return the product.
3853  *
3854  * If no factors can be found, simply call fn on the input.
3855  * Otherwise, construct the factors based on the factorizer,
3856  * call fn on each factor and compute the product.
3857  */
3858 static __isl_give isl_pw_qpolynomial *compressed_multiplicative_call(
3859         __isl_take isl_basic_set *bset,
3860         __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset))
3861 {
3862         int i, n;
3863         isl_dim *dim;
3864         isl_set *set;
3865         isl_factorizer *f;
3866         isl_qpolynomial *qp;
3867         isl_pw_qpolynomial *pwqp;
3868         unsigned nparam;
3869         unsigned nvar;
3870
3871         f = isl_basic_set_factorizer(bset);
3872         if (!f)
3873                 goto error;
3874         if (f->n_group == 0) {
3875                 isl_factorizer_free(f);
3876                 return fn(bset);
3877         }
3878
3879         nparam = isl_basic_set_dim(bset, isl_dim_param);
3880         nvar = isl_basic_set_dim(bset, isl_dim_set);
3881
3882         dim = isl_basic_set_get_dim(bset);
3883         dim = isl_dim_domain(dim);
3884         set = isl_set_universe(isl_dim_copy(dim));
3885         qp = isl_qpolynomial_one(dim);
3886         pwqp = isl_pw_qpolynomial_alloc(set, qp);
3887
3888         bset = isl_morph_basic_set(isl_morph_copy(f->morph), bset);
3889
3890         for (i = 0, n = 0; i < f->n_group; ++i) {
3891                 isl_basic_set *bset_i;
3892                 isl_pw_qpolynomial *pwqp_i;
3893
3894                 bset_i = isl_basic_set_copy(bset);
3895                 bset_i = isl_basic_set_drop_constraints_involving(bset_i,
3896                             nparam + n + f->len[i], nvar - n - f->len[i]);
3897                 bset_i = isl_basic_set_drop_constraints_involving(bset_i,
3898                             nparam, n);
3899                 bset_i = isl_basic_set_drop(bset_i, isl_dim_set,
3900                             n + f->len[i], nvar - n - f->len[i]);
3901                 bset_i = isl_basic_set_drop(bset_i, isl_dim_set, 0, n);
3902
3903                 pwqp_i = fn(bset_i);
3904                 pwqp = isl_pw_qpolynomial_mul(pwqp, pwqp_i);
3905
3906                 n += f->len[i];
3907         }
3908
3909         isl_basic_set_free(bset);
3910         isl_factorizer_free(f);
3911
3912         return pwqp;
3913 error:
3914         isl_basic_set_free(bset);
3915         return NULL;
3916 }
3917
3918 /* Factor bset, call fn on each of the factors and return the product.
3919  * The function is assumed to evaluate to zero on empty domains,
3920  * to one on zero-dimensional domains and to infinity on unbounded domains
3921  * and will not be called explicitly on zero-dimensional or unbounded domains.
3922  *
3923  * We first check for some special cases and remove all equalities.
3924  * Then we hand over control to compressed_multiplicative_call.
3925  */
3926 __isl_give isl_pw_qpolynomial *isl_basic_set_multiplicative_call(
3927         __isl_take isl_basic_set *bset,
3928         __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset))
3929 {
3930         int bounded;
3931         isl_morph *morph;
3932         isl_pw_qpolynomial *pwqp;
3933         unsigned orig_nvar, final_nvar;
3934
3935         if (!bset)
3936                 return NULL;
3937
3938         if (isl_basic_set_fast_is_empty(bset))
3939                 return constant_on_domain(bset, 0);
3940
3941         orig_nvar = isl_basic_set_dim(bset, isl_dim_set);
3942
3943         if (orig_nvar == 0)
3944                 return constant_on_domain(bset, 1);
3945
3946         bounded = isl_basic_set_is_bounded(bset);
3947         if (bounded < 0)
3948                 goto error;
3949         if (!bounded)
3950                 return constant_on_domain(bset, -1);
3951
3952         if (bset->n_eq == 0)
3953                 return compressed_multiplicative_call(bset, fn);
3954
3955         morph = isl_basic_set_full_compression(bset);
3956         bset = isl_morph_basic_set(isl_morph_copy(morph), bset);
3957
3958         final_nvar = isl_basic_set_dim(bset, isl_dim_set);
3959
3960         pwqp = compressed_multiplicative_call(bset, fn);
3961
3962         morph = isl_morph_remove_dom_dims(morph, isl_dim_set, 0, orig_nvar);
3963         morph = isl_morph_remove_ran_dims(morph, isl_dim_set, 0, final_nvar);
3964         morph = isl_morph_inverse(morph);
3965
3966         pwqp = isl_pw_qpolynomial_morph(pwqp, morph);
3967
3968         return pwqp;
3969 error:
3970         isl_basic_set_free(bset);
3971         return NULL;
3972 }
3973
3974 /* Drop all floors in "qp", turning each integer division [a/m] into
3975  * a rational division a/m.  If "down" is set, then the integer division
3976  * is replaces by (a-(m-1))/m instead.
3977  */
3978 static __isl_give isl_qpolynomial *qp_drop_floors(
3979         __isl_take isl_qpolynomial *qp, int down)
3980 {
3981         int i;
3982         struct isl_upoly *s;
3983
3984         if (!qp)
3985                 return NULL;
3986         if (qp->div->n_row == 0)
3987                 return qp;
3988
3989         qp = isl_qpolynomial_cow(qp);
3990         if (!qp)
3991                 return NULL;
3992
3993         for (i = qp->div->n_row - 1; i >= 0; --i) {
3994                 if (down) {
3995                         isl_int_sub(qp->div->row[i][1],
3996                                     qp->div->row[i][1], qp->div->row[i][0]);
3997                         isl_int_add_ui(qp->div->row[i][1],
3998                                        qp->div->row[i][1], 1);
3999                 }
4000                 s = isl_upoly_from_affine(qp->dim->ctx, qp->div->row[i] + 1,
4001                                         qp->div->row[i][0], qp->div->n_col - 1);
4002                 qp = substitute_div(qp, i, s);
4003                 if (!qp)
4004                         return NULL;
4005         }
4006
4007         return qp;
4008 }
4009
4010 /* Drop all floors in "pwqp", turning each integer division [a/m] into
4011  * a rational division a/m.
4012  */
4013 static __isl_give isl_pw_qpolynomial *pwqp_drop_floors(
4014         __isl_take isl_pw_qpolynomial *pwqp)
4015 {
4016         int i;
4017
4018         if (!pwqp)
4019                 return NULL;
4020
4021         if (isl_pw_qpolynomial_is_zero(pwqp))
4022                 return pwqp;
4023
4024         pwqp = isl_pw_qpolynomial_cow(pwqp);
4025         if (!pwqp)
4026                 return NULL;
4027
4028         for (i = 0; i < pwqp->n; ++i) {
4029                 pwqp->p[i].qp = qp_drop_floors(pwqp->p[i].qp, 0);
4030                 if (!pwqp->p[i].qp)
4031                         goto error;
4032         }
4033
4034         return pwqp;
4035 error:
4036         isl_pw_qpolynomial_free(pwqp);
4037         return NULL;
4038 }
4039
4040 /* Adjust all the integer divisions in "qp" such that they are at least
4041  * one over the given orthant (identified by "signs").  This ensures
4042  * that they will still be non-negative even after subtracting (m-1)/m.
4043  *
4044  * In particular, f is replaced by f' + v, changing f = [a/m]
4045  * to f' = [(a - m v)/m].
4046  * If the constant term k in a is smaller than m,
4047  * the constant term of v is set to floor(k/m) - 1.
4048  * For any other term, if the coefficient c and the variable x have
4049  * the same sign, then no changes are needed.
4050  * Otherwise, if the variable is positive (and c is negative),
4051  * then the coefficient of x in v is set to floor(c/m).
4052  * If the variable is negative (and c is positive),
4053  * then the coefficient of x in v is set to ceil(c/m).
4054  */
4055 static __isl_give isl_qpolynomial *make_divs_pos(__isl_take isl_qpolynomial *qp,
4056         int *signs)
4057 {
4058         int i, j;
4059         int total;
4060         isl_vec *v = NULL;
4061         struct isl_upoly *s;
4062
4063         qp = isl_qpolynomial_cow(qp);
4064         if (!qp)
4065                 return NULL;
4066         qp->div = isl_mat_cow(qp->div);
4067         if (!qp->div)
4068                 goto error;
4069
4070         total = isl_dim_total(qp->dim);
4071         v = isl_vec_alloc(qp->div->ctx, qp->div->n_col - 1);
4072
4073         for (i = 0; i < qp->div->n_row; ++i) {
4074                 isl_int *row = qp->div->row[i];
4075                 v = isl_vec_clr(v);
4076                 if (!v)
4077                         goto error;
4078                 if (isl_int_lt(row[1], row[0])) {
4079                         isl_int_fdiv_q(v->el[0], row[1], row[0]);
4080                         isl_int_sub_ui(v->el[0], v->el[0], 1);
4081                         isl_int_submul(row[1], row[0], v->el[0]);
4082                 }
4083                 for (j = 0; j < total; ++j) {
4084                         if (isl_int_sgn(row[2 + j]) * signs[j] >= 0)
4085                                 continue;
4086                         if (signs[j] < 0)
4087                                 isl_int_cdiv_q(v->el[1 + j], row[2 + j], row[0]);
4088                         else
4089                                 isl_int_fdiv_q(v->el[1 + j], row[2 + j], row[0]);
4090                         isl_int_submul(row[2 + j], row[0], v->el[1 + j]);
4091                 }
4092                 for (j = 0; j < i; ++j) {
4093                         if (isl_int_sgn(row[2 + total + j]) >= 0)
4094                                 continue;
4095                         isl_int_fdiv_q(v->el[1 + total + j],
4096                                         row[2 + total + j], row[0]);
4097                         isl_int_submul(row[2 + total + j],
4098                                         row[0], v->el[1 + total + j]);
4099                 }
4100                 for (j = i + 1; j < qp->div->n_row; ++j) {
4101                         if (isl_int_is_zero(qp->div->row[j][2 + total + i]))
4102                                 continue;
4103                         isl_seq_combine(qp->div->row[j] + 1,
4104                                 qp->div->ctx->one, qp->div->row[j] + 1,
4105                                 qp->div->row[j][2 + total + i], v->el, v->size);
4106                 }
4107                 isl_int_set_si(v->el[1 + total + i], 1);
4108                 s = isl_upoly_from_affine(qp->dim->ctx, v->el,
4109                                         qp->div->ctx->one, v->size);
4110                 qp->upoly = isl_upoly_subs(qp->upoly, total + i, 1, &s);
4111                 isl_upoly_free(s);
4112                 if (!qp->upoly)
4113                         goto error;
4114         }
4115
4116         isl_vec_free(v);
4117         return qp;
4118 error:
4119         isl_vec_free(v);
4120         isl_qpolynomial_free(qp);
4121         return NULL;
4122 }
4123
4124 struct isl_to_poly_data {
4125         int sign;
4126         isl_pw_qpolynomial *res;
4127         isl_qpolynomial *qp;
4128 };
4129
4130 /* Appoximate data->qp by a polynomial on the orthant identified by "signs".
4131  * We first make all integer divisions positive and then split the
4132  * quasipolynomials into terms with sign data->sign (the direction
4133  * of the requested approximation) and terms with the opposite sign.
4134  * In the first set of terms, each integer division [a/m] is
4135  * overapproximated by a/m, while in the second it is underapproximated
4136  * by (a-(m-1))/m.
4137  */
4138 static int to_polynomial_on_orthant(__isl_take isl_set *orthant, int *signs,
4139         void *user)
4140 {
4141         struct isl_to_poly_data *data = user;
4142         isl_pw_qpolynomial *t;
4143         isl_qpolynomial *qp, *up, *down;
4144
4145         qp = isl_qpolynomial_copy(data->qp);
4146         qp = make_divs_pos(qp, signs);
4147
4148         up = isl_qpolynomial_terms_of_sign(qp, signs, data->sign);
4149         up = qp_drop_floors(up, 0);
4150         down = isl_qpolynomial_terms_of_sign(qp, signs, -data->sign);
4151         down = qp_drop_floors(down, 1);
4152
4153         isl_qpolynomial_free(qp);
4154         qp = isl_qpolynomial_add(up, down);
4155
4156         t = isl_pw_qpolynomial_alloc(orthant, qp);
4157         data->res = isl_pw_qpolynomial_add_disjoint(data->res, t);
4158
4159         return 0;
4160 }
4161
4162 /* Approximate each quasipolynomial by a polynomial.  If "sign" is positive,
4163  * the polynomial will be an overapproximation.  If "sign" is negative,
4164  * it will be an underapproximation.  If "sign" is zero, the approximation
4165  * will lie somewhere in between.
4166  *
4167  * In particular, is sign == 0, we simply drop the floors, turning
4168  * the integer divisions into rational divisions.
4169  * Otherwise, we split the domains into orthants, make all integer divisions
4170  * positive and then approximate each [a/m] by either a/m or (a-(m-1))/m,
4171  * depending on the requested sign and the sign of the term in which
4172  * the integer division appears.
4173  */
4174 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_to_polynomial(
4175         __isl_take isl_pw_qpolynomial *pwqp, int sign)
4176 {
4177         int i;
4178         struct isl_to_poly_data data;
4179
4180         if (sign == 0)
4181                 return pwqp_drop_floors(pwqp);
4182
4183         if (!pwqp)
4184                 return NULL;
4185
4186         data.sign = sign;
4187         data.res = isl_pw_qpolynomial_zero(isl_pw_qpolynomial_get_dim(pwqp));
4188
4189         for (i = 0; i < pwqp->n; ++i) {
4190                 if (pwqp->p[i].qp->div->n_row == 0) {
4191                         isl_pw_qpolynomial *t;
4192                         t = isl_pw_qpolynomial_alloc(
4193                                         isl_set_copy(pwqp->p[i].set),
4194                                         isl_qpolynomial_copy(pwqp->p[i].qp));
4195                         data.res = isl_pw_qpolynomial_add_disjoint(data.res, t);
4196                         continue;
4197                 }
4198                 data.qp = pwqp->p[i].qp;
4199                 if (isl_set_foreach_orthant(pwqp->p[i].set,
4200                                         &to_polynomial_on_orthant, &data) < 0)
4201                         goto error;
4202         }
4203
4204         isl_pw_qpolynomial_free(pwqp);
4205
4206         return data.res;
4207 error:
4208         isl_pw_qpolynomial_free(pwqp);
4209         isl_pw_qpolynomial_free(data.res);
4210         return NULL;
4211 }
4212
4213 static int poly_entry(void **entry, void *user)
4214 {
4215         int *sign = user;
4216         isl_pw_qpolynomial **pwqp = (isl_pw_qpolynomial **)entry;
4217
4218         *pwqp = isl_pw_qpolynomial_to_polynomial(*pwqp, *sign);
4219
4220         return *pwqp ? 0 : -1;
4221 }
4222
4223 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_to_polynomial(
4224         __isl_take isl_union_pw_qpolynomial *upwqp, int sign)
4225 {
4226         upwqp = isl_union_pw_qpolynomial_cow(upwqp);
4227         if (!upwqp)
4228                 return NULL;
4229
4230         if (isl_hash_table_foreach(upwqp->dim->ctx, &upwqp->table,
4231                                    &poly_entry, &sign) < 0)
4232                 goto error;
4233
4234         return upwqp;
4235 error:
4236         isl_union_pw_qpolynomial_free(upwqp);
4237         return NULL;
4238 }