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