isl_qpolynomial_drop_dims: properly handle nested spaces
[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         int equal;
1722
1723         if (!qp1 || !qp2)
1724                 return -1;
1725
1726         equal = isl_dim_equal(qp1->dim, qp2->dim);
1727         if (equal < 0 || !equal)
1728                 return equal;
1729
1730         equal = isl_mat_is_equal(qp1->div, qp2->div);
1731         if (equal < 0 || !equal)
1732                 return equal;
1733
1734         return isl_upoly_is_equal(qp1->upoly, qp2->upoly);
1735 }
1736
1737 static void upoly_update_den(__isl_keep struct isl_upoly *up, isl_int *d)
1738 {
1739         int i;
1740         struct isl_upoly_rec *rec;
1741
1742         if (isl_upoly_is_cst(up)) {
1743                 struct isl_upoly_cst *cst;
1744                 cst = isl_upoly_as_cst(up);
1745                 if (!cst)
1746                         return;
1747                 isl_int_lcm(*d, *d, cst->d);
1748                 return;
1749         }
1750
1751         rec = isl_upoly_as_rec(up);
1752         if (!rec)
1753                 return;
1754
1755         for (i = 0; i < rec->n; ++i)
1756                 upoly_update_den(rec->p[i], d);
1757 }
1758
1759 void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d)
1760 {
1761         isl_int_set_si(*d, 1);
1762         if (!qp)
1763                 return;
1764         upoly_update_den(qp->upoly, d);
1765 }
1766
1767 __isl_give isl_qpolynomial *isl_qpolynomial_var_pow(__isl_take isl_dim *dim,
1768         int pos, int power)
1769 {
1770         struct isl_ctx *ctx;
1771
1772         if (!dim)
1773                 return NULL;
1774
1775         ctx = dim->ctx;
1776
1777         return isl_qpolynomial_alloc(dim, 0, isl_upoly_var_pow(ctx, pos, power));
1778 }
1779
1780 __isl_give isl_qpolynomial *isl_qpolynomial_var(__isl_take isl_dim *dim,
1781         enum isl_dim_type type, unsigned pos)
1782 {
1783         if (!dim)
1784                 return NULL;
1785
1786         isl_assert(dim->ctx, isl_dim_size(dim, isl_dim_in) == 0, goto error);
1787         isl_assert(dim->ctx, pos < isl_dim_size(dim, type), goto error);
1788
1789         if (type == isl_dim_set)
1790                 pos += isl_dim_size(dim, isl_dim_param);
1791
1792         return isl_qpolynomial_var_pow(dim, pos, 1);
1793 error:
1794         isl_dim_free(dim);
1795         return NULL;
1796 }
1797
1798 __isl_give struct isl_upoly *isl_upoly_subs(__isl_take struct isl_upoly *up,
1799         unsigned first, unsigned n, __isl_keep struct isl_upoly **subs)
1800 {
1801         int i;
1802         struct isl_upoly_rec *rec;
1803         struct isl_upoly *base, *res;
1804
1805         if (!up)
1806                 return NULL;
1807
1808         if (isl_upoly_is_cst(up))
1809                 return up;
1810
1811         if (up->var < first)
1812                 return up;
1813
1814         rec = isl_upoly_as_rec(up);
1815         if (!rec)
1816                 goto error;
1817
1818         isl_assert(up->ctx, rec->n >= 1, goto error);
1819
1820         if (up->var >= first + n)
1821                 base = isl_upoly_var_pow(up->ctx, up->var, 1);
1822         else
1823                 base = isl_upoly_copy(subs[up->var - first]);
1824
1825         res = isl_upoly_subs(isl_upoly_copy(rec->p[rec->n - 1]), first, n, subs);
1826         for (i = rec->n - 2; i >= 0; --i) {
1827                 struct isl_upoly *t;
1828                 t = isl_upoly_subs(isl_upoly_copy(rec->p[i]), first, n, subs);
1829                 res = isl_upoly_mul(res, isl_upoly_copy(base));
1830                 res = isl_upoly_sum(res, t);
1831         }
1832
1833         isl_upoly_free(base);
1834         isl_upoly_free(up);
1835                                 
1836         return res;
1837 error:
1838         isl_upoly_free(up);
1839         return NULL;
1840 }       
1841
1842 __isl_give struct isl_upoly *isl_upoly_from_affine(isl_ctx *ctx, isl_int *f,
1843         isl_int denom, unsigned len)
1844 {
1845         int i;
1846         struct isl_upoly *up;
1847
1848         isl_assert(ctx, len >= 1, return NULL);
1849
1850         up = isl_upoly_rat_cst(ctx, f[0], denom);
1851         for (i = 0; i < len - 1; ++i) {
1852                 struct isl_upoly *t;
1853                 struct isl_upoly *c;
1854
1855                 if (isl_int_is_zero(f[1 + i]))
1856                         continue;
1857
1858                 c = isl_upoly_rat_cst(ctx, f[1 + i], denom);
1859                 t = isl_upoly_var_pow(ctx, i, 1);
1860                 t = isl_upoly_mul(c, t);
1861                 up = isl_upoly_sum(up, t);
1862         }
1863
1864         return up;
1865 }
1866
1867 /* Remove common factor of non-constant terms and denominator.
1868  */
1869 static void normalize_div(__isl_keep isl_qpolynomial *qp, int div)
1870 {
1871         isl_ctx *ctx = qp->div->ctx;
1872         unsigned total = qp->div->n_col - 2;
1873
1874         isl_seq_gcd(qp->div->row[div] + 2, total, &ctx->normalize_gcd);
1875         isl_int_gcd(ctx->normalize_gcd,
1876                     ctx->normalize_gcd, qp->div->row[div][0]);
1877         if (isl_int_is_one(ctx->normalize_gcd))
1878                 return;
1879
1880         isl_seq_scale_down(qp->div->row[div] + 2, qp->div->row[div] + 2,
1881                             ctx->normalize_gcd, total);
1882         isl_int_divexact(qp->div->row[div][0], qp->div->row[div][0],
1883                             ctx->normalize_gcd);
1884         isl_int_fdiv_q(qp->div->row[div][1], qp->div->row[div][1],
1885                             ctx->normalize_gcd);
1886 }
1887
1888 /* Replace the integer division identified by "div" by the polynomial "s".
1889  * The integer division is assumed not to appear in the definition
1890  * of any other integer divisions.
1891  */
1892 static __isl_give isl_qpolynomial *substitute_div(
1893         __isl_take isl_qpolynomial *qp,
1894         int div, __isl_take struct isl_upoly *s)
1895 {
1896         int i;
1897         int total;
1898         int *reordering;
1899
1900         if (!qp || !s)
1901                 goto error;
1902
1903         qp = isl_qpolynomial_cow(qp);
1904         if (!qp)
1905                 goto error;
1906
1907         total = isl_dim_total(qp->dim);
1908         qp->upoly = isl_upoly_subs(qp->upoly, total + div, 1, &s);
1909         if (!qp->upoly)
1910                 goto error;
1911
1912         reordering = isl_alloc_array(qp->dim->ctx, int, total + qp->div->n_row);
1913         if (!reordering)
1914                 goto error;
1915         for (i = 0; i < total + div; ++i)
1916                 reordering[i] = i;
1917         for (i = total + div + 1; i < total + qp->div->n_row; ++i)
1918                 reordering[i] = i - 1;
1919         qp->div = isl_mat_drop_rows(qp->div, div, 1);
1920         qp->div = isl_mat_drop_cols(qp->div, 2 + total + div, 1);
1921         qp->upoly = reorder(qp->upoly, reordering);
1922         free(reordering);
1923
1924         if (!qp->upoly || !qp->div)
1925                 goto error;
1926
1927         isl_upoly_free(s);
1928         return qp;
1929 error:
1930         isl_qpolynomial_free(qp);
1931         isl_upoly_free(s);
1932         return NULL;
1933 }
1934
1935 /* Replace all integer divisions [e/d] that turn out to not actually be integer
1936  * divisions because d is equal to 1 by their definition, i.e., e.
1937  */
1938 static __isl_give isl_qpolynomial *substitute_non_divs(
1939         __isl_take isl_qpolynomial *qp)
1940 {
1941         int i, j;
1942         int total;
1943         struct isl_upoly *s;
1944
1945         if (!qp)
1946                 return NULL;
1947
1948         total = isl_dim_total(qp->dim);
1949         for (i = 0; qp && i < qp->div->n_row; ++i) {
1950                 if (!isl_int_is_one(qp->div->row[i][0]))
1951                         continue;
1952                 for (j = i + 1; j < qp->div->n_row; ++j) {
1953                         if (isl_int_is_zero(qp->div->row[j][2 + total + i]))
1954                                 continue;
1955                         isl_seq_combine(qp->div->row[j] + 1,
1956                                 qp->div->ctx->one, qp->div->row[j] + 1,
1957                                 qp->div->row[j][2 + total + i],
1958                                 qp->div->row[i] + 1, 1 + total + i);
1959                         isl_int_set_si(qp->div->row[j][2 + total + i], 0);
1960                         normalize_div(qp, j);
1961                 }
1962                 s = isl_upoly_from_affine(qp->dim->ctx, qp->div->row[i] + 1,
1963                                         qp->div->row[i][0], qp->div->n_col - 1);
1964                 qp = substitute_div(qp, i, s);
1965                 --i;
1966         }
1967
1968         return qp;
1969 }
1970
1971 /* Reduce the coefficients of div "div" to lie in the interval [0, d-1],
1972  * with d the denominator.  When replacing the coefficient e of x by
1973  * d * frac(e/d) = e - d * floor(e/d), we are subtracting d * floor(e/d) * x
1974  * inside the division, so we need to add floor(e/d) * x outside.
1975  * That is, we replace q by q' + floor(e/d) * x and we therefore need
1976  * to adjust the coefficient of x in each later div that depends on the
1977  * current div "div" and also in the affine expression "aff"
1978  * (if it too depends on "div").
1979  */
1980 static void reduce_div(__isl_keep isl_qpolynomial *qp, int div,
1981         __isl_keep isl_vec *aff)
1982 {
1983         int i, j;
1984         isl_int v;
1985         unsigned total = qp->div->n_col - qp->div->n_row - 2;
1986
1987         isl_int_init(v);
1988         for (i = 0; i < 1 + total + div; ++i) {
1989                 if (isl_int_is_nonneg(qp->div->row[div][1 + i]) &&
1990                     isl_int_lt(qp->div->row[div][1 + i], qp->div->row[div][0]))
1991                         continue;
1992                 isl_int_fdiv_q(v, qp->div->row[div][1 + i], qp->div->row[div][0]);
1993                 isl_int_fdiv_r(qp->div->row[div][1 + i],
1994                                 qp->div->row[div][1 + i], qp->div->row[div][0]);
1995                 if (!isl_int_is_zero(aff->el[1 + total + div]))
1996                         isl_int_addmul(aff->el[i], v, aff->el[1 + total + div]);
1997                 for (j = div + 1; j < qp->div->n_row; ++j) {
1998                         if (isl_int_is_zero(qp->div->row[j][2 + total + div]))
1999                                 continue;
2000                         isl_int_addmul(qp->div->row[j][1 + i],
2001                                         v, qp->div->row[j][2 + total + div]);
2002                 }
2003         }
2004         isl_int_clear(v);
2005 }
2006
2007 /* Check if the last non-zero coefficient is bigger that half of the
2008  * denominator.  If so, we will invert the div to further reduce the number
2009  * of distinct divs that may appear.
2010  * If the last non-zero coefficient is exactly half the denominator,
2011  * then we continue looking for earlier coefficients that are bigger
2012  * than half the denominator.
2013  */
2014 static int needs_invert(__isl_keep isl_mat *div, int row)
2015 {
2016         int i;
2017         int cmp;
2018
2019         for (i = div->n_col - 1; i >= 1; --i) {
2020                 if (isl_int_is_zero(div->row[row][i]))
2021                         continue;
2022                 isl_int_mul_ui(div->row[row][i], div->row[row][i], 2);
2023                 cmp = isl_int_cmp(div->row[row][i], div->row[row][0]);
2024                 isl_int_divexact_ui(div->row[row][i], div->row[row][i], 2);
2025                 if (cmp)
2026                         return cmp > 0;
2027                 if (i == 1)
2028                         return 1;
2029         }
2030
2031         return 0;
2032 }
2033
2034 /* Replace div "div" q = [e/d] by -[(-e+(d-1))/d].
2035  * We only invert the coefficients of e (and the coefficient of q in
2036  * later divs and in "aff").  After calling this function, the
2037  * coefficients of e should be reduced again.
2038  */
2039 static void invert_div(__isl_keep isl_qpolynomial *qp, int div,
2040         __isl_keep isl_vec *aff)
2041 {
2042         unsigned total = qp->div->n_col - qp->div->n_row - 2;
2043
2044         isl_seq_neg(qp->div->row[div] + 1,
2045                     qp->div->row[div] + 1, qp->div->n_col - 1);
2046         isl_int_sub_ui(qp->div->row[div][1], qp->div->row[div][1], 1);
2047         isl_int_add(qp->div->row[div][1],
2048                     qp->div->row[div][1], qp->div->row[div][0]);
2049         if (!isl_int_is_zero(aff->el[1 + total + div]))
2050                 isl_int_neg(aff->el[1 + total + div], aff->el[1 + total + div]);
2051         isl_mat_col_mul(qp->div, 2 + total + div,
2052                         qp->div->ctx->negone, 2 + total + div);
2053 }
2054
2055 /* Assuming "qp" is a monomial, reduce all its divs to have coefficients
2056  * in the interval [0, d-1], with d the denominator and such that the
2057  * last non-zero coefficient that is not equal to d/2 is smaller than d/2.
2058  *
2059  * After the reduction, some divs may have become redundant or identical,
2060  * so we call substitute_non_divs and sort_divs.  If these functions
2061  * eliminate divs of merge * two or more divs into one, the coefficients
2062  * of the enclosing divs may have to be reduced again, so we call
2063  * ourselves recursively if the number of divs decreases.
2064  */
2065 static __isl_give isl_qpolynomial *reduce_divs(__isl_take isl_qpolynomial *qp)
2066 {
2067         int i, j;
2068         isl_vec *aff = NULL;
2069         struct isl_upoly *s;
2070         unsigned n_div;
2071
2072         if (!qp)
2073                 return NULL;
2074
2075         aff = isl_vec_alloc(qp->div->ctx, qp->div->n_col - 1);
2076         aff = isl_vec_clr(aff);
2077         if (!aff)
2078                 goto error;
2079
2080         isl_int_set_si(aff->el[1 + qp->upoly->var], 1);
2081
2082         for (i = 0; i < qp->div->n_row; ++i) {
2083                 normalize_div(qp, i);
2084                 reduce_div(qp, i, aff);
2085                 if (needs_invert(qp->div, i)) {
2086                         invert_div(qp, i, aff);
2087                         reduce_div(qp, i, aff);
2088                 }
2089         }
2090
2091         s = isl_upoly_from_affine(qp->div->ctx, aff->el,
2092                                   qp->div->ctx->one, aff->size);
2093         qp->upoly = isl_upoly_subs(qp->upoly, qp->upoly->var, 1, &s);
2094         isl_upoly_free(s);
2095         if (!qp->upoly)
2096                 goto error;
2097
2098         isl_vec_free(aff);
2099
2100         n_div = qp->div->n_row;
2101         qp = substitute_non_divs(qp);
2102         qp = sort_divs(qp);
2103         if (qp && qp->div->n_row < n_div)
2104                 return reduce_divs(qp);
2105
2106         return qp;
2107 error:
2108         isl_qpolynomial_free(qp);
2109         isl_vec_free(aff);
2110         return NULL;
2111 }
2112
2113 /* Assumes each div only depends on earlier divs.
2114  */
2115 __isl_give isl_qpolynomial *isl_qpolynomial_div_pow(__isl_take isl_div *div,
2116         int power)
2117 {
2118         struct isl_qpolynomial *qp = NULL;
2119         struct isl_upoly_rec *rec;
2120         struct isl_upoly_cst *cst;
2121         int i, d;
2122         int pos;
2123
2124         if (!div)
2125                 return NULL;
2126
2127         d = div->line - div->bmap->div;
2128
2129         pos = isl_dim_total(div->bmap->dim) + d;
2130         rec = isl_upoly_alloc_rec(div->ctx, pos, 1 + power);
2131         qp = isl_qpolynomial_alloc(isl_basic_map_get_dim(div->bmap),
2132                                    div->bmap->n_div, &rec->up);
2133         if (!qp)
2134                 goto error;
2135
2136         for (i = 0; i < div->bmap->n_div; ++i)
2137                 isl_seq_cpy(qp->div->row[i], div->bmap->div[i], qp->div->n_col);
2138
2139         for (i = 0; i < 1 + power; ++i) {
2140                 rec->p[i] = isl_upoly_zero(div->ctx);
2141                 if (!rec->p[i])
2142                         goto error;
2143                 rec->n++;
2144         }
2145         cst = isl_upoly_as_cst(rec->p[power]);
2146         isl_int_set_si(cst->n, 1);
2147
2148         isl_div_free(div);
2149
2150         qp = reduce_divs(qp);
2151
2152         return qp;
2153 error:
2154         isl_qpolynomial_free(qp);
2155         isl_div_free(div);
2156         return NULL;
2157 }
2158
2159 __isl_give isl_qpolynomial *isl_qpolynomial_div(__isl_take isl_div *div)
2160 {
2161         return isl_qpolynomial_div_pow(div, 1);
2162 }
2163
2164 __isl_give isl_qpolynomial *isl_qpolynomial_rat_cst(__isl_take isl_dim *dim,
2165         const isl_int n, const isl_int d)
2166 {
2167         struct isl_qpolynomial *qp;
2168         struct isl_upoly_cst *cst;
2169
2170         qp = isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
2171         if (!qp)
2172                 return NULL;
2173
2174         cst = isl_upoly_as_cst(qp->upoly);
2175         isl_int_set(cst->n, n);
2176         isl_int_set(cst->d, d);
2177
2178         return qp;
2179 }
2180
2181 static int up_set_active(__isl_keep struct isl_upoly *up, int *active, int d)
2182 {
2183         struct isl_upoly_rec *rec;
2184         int i;
2185
2186         if (!up)
2187                 return -1;
2188
2189         if (isl_upoly_is_cst(up))
2190                 return 0;
2191
2192         if (up->var < d)
2193                 active[up->var] = 1;
2194
2195         rec = isl_upoly_as_rec(up);
2196         for (i = 0; i < rec->n; ++i)
2197                 if (up_set_active(rec->p[i], active, d) < 0)
2198                         return -1;
2199
2200         return 0;
2201 }
2202
2203 static int set_active(__isl_keep isl_qpolynomial *qp, int *active)
2204 {
2205         int i, j;
2206         int d = isl_dim_total(qp->dim);
2207
2208         if (!qp || !active)
2209                 return -1;
2210
2211         for (i = 0; i < d; ++i)
2212                 for (j = 0; j < qp->div->n_row; ++j) {
2213                         if (isl_int_is_zero(qp->div->row[j][2 + i]))
2214                                 continue;
2215                         active[i] = 1;
2216                         break;
2217                 }
2218
2219         return up_set_active(qp->upoly, active, d);
2220 }
2221
2222 int isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp,
2223         enum isl_dim_type type, unsigned first, unsigned n)
2224 {
2225         int i;
2226         int *active = NULL;
2227         int involves = 0;
2228
2229         if (!qp)
2230                 return -1;
2231         if (n == 0)
2232                 return 0;
2233
2234         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
2235                         return -1);
2236         isl_assert(qp->dim->ctx, type == isl_dim_param ||
2237                                  type == isl_dim_set, return -1);
2238
2239         active = isl_calloc_array(set->ctx, int, isl_dim_total(qp->dim));
2240         if (set_active(qp, active) < 0)
2241                 goto error;
2242
2243         if (type == isl_dim_set)
2244                 first += isl_dim_size(qp->dim, isl_dim_param);
2245         for (i = 0; i < n; ++i)
2246                 if (active[first + i]) {
2247                         involves = 1;
2248                         break;
2249                 }
2250
2251         free(active);
2252
2253         return involves;
2254 error:
2255         free(active);
2256         return -1;
2257 }
2258
2259 __isl_give struct isl_upoly *isl_upoly_drop(__isl_take struct isl_upoly *up,
2260         unsigned first, unsigned n)
2261 {
2262         int i;
2263         struct isl_upoly_rec *rec;
2264
2265         if (!up)
2266                 return NULL;
2267         if (n == 0 || up->var < 0 || up->var < first)
2268                 return up;
2269         if (up->var < first + n) {
2270                 up = replace_by_constant_term(up);
2271                 return isl_upoly_drop(up, first, n);
2272         }
2273         up = isl_upoly_cow(up);
2274         if (!up)
2275                 return NULL;
2276         up->var -= n;
2277         rec = isl_upoly_as_rec(up);
2278         if (!rec)
2279                 goto error;
2280
2281         for (i = 0; i < rec->n; ++i) {
2282                 rec->p[i] = isl_upoly_drop(rec->p[i], first, n);
2283                 if (!rec->p[i])
2284                         goto error;
2285         }
2286
2287         return up;
2288 error:
2289         isl_upoly_free(up);
2290         return NULL;
2291 }
2292
2293 __isl_give isl_qpolynomial *isl_qpolynomial_set_dim_name(
2294         __isl_take isl_qpolynomial *qp,
2295         enum isl_dim_type type, unsigned pos, const char *s)
2296 {
2297         qp = isl_qpolynomial_cow(qp);
2298         if (!qp)
2299                 return NULL;
2300         qp->dim = isl_dim_set_name(qp->dim, type, pos, s);
2301         if (!qp->dim)
2302                 goto error;
2303         return qp;
2304 error:
2305         isl_qpolynomial_free(qp);
2306         return NULL;
2307 }
2308
2309 __isl_give isl_qpolynomial *isl_qpolynomial_drop_dims(
2310         __isl_take isl_qpolynomial *qp,
2311         enum isl_dim_type type, unsigned first, unsigned n)
2312 {
2313         if (!qp)
2314                 return NULL;
2315         if (n == 0 && !isl_dim_is_named_or_nested(qp->dim, type))
2316                 return qp;
2317
2318         qp = isl_qpolynomial_cow(qp);
2319         if (!qp)
2320                 return NULL;
2321
2322         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
2323                         goto error);
2324         isl_assert(qp->dim->ctx, type == isl_dim_param ||
2325                                  type == isl_dim_set, goto error);
2326
2327         qp->dim = isl_dim_drop(qp->dim, type, first, n);
2328         if (!qp->dim)
2329                 goto error;
2330
2331         if (type == isl_dim_set)
2332                 first += isl_dim_size(qp->dim, isl_dim_param);
2333
2334         qp->div = isl_mat_drop_cols(qp->div, 2 + first, n);
2335         if (!qp->div)
2336                 goto error;
2337
2338         qp->upoly = isl_upoly_drop(qp->upoly, first, n);
2339         if (!qp->upoly)
2340                 goto error;
2341
2342         return qp;
2343 error:
2344         isl_qpolynomial_free(qp);
2345         return NULL;
2346 }
2347
2348 __isl_give isl_qpolynomial *isl_qpolynomial_substitute_equalities(
2349         __isl_take isl_qpolynomial *qp, __isl_take isl_basic_set *eq)
2350 {
2351         int i, j, k;
2352         isl_int denom;
2353         unsigned total;
2354         unsigned n_div;
2355         struct isl_upoly *up;
2356
2357         if (!eq)
2358                 goto error;
2359         if (eq->n_eq == 0) {
2360                 isl_basic_set_free(eq);
2361                 return qp;
2362         }
2363
2364         qp = isl_qpolynomial_cow(qp);
2365         if (!qp)
2366                 goto error;
2367         qp->div = isl_mat_cow(qp->div);
2368         if (!qp->div)
2369                 goto error;
2370
2371         total = 1 + isl_dim_total(eq->dim);
2372         n_div = eq->n_div;
2373         isl_int_init(denom);
2374         for (i = 0; i < eq->n_eq; ++i) {
2375                 j = isl_seq_last_non_zero(eq->eq[i], total + n_div);
2376                 if (j < 0 || j == 0 || j >= total)
2377                         continue;
2378
2379                 for (k = 0; k < qp->div->n_row; ++k) {
2380                         if (isl_int_is_zero(qp->div->row[k][1 + j]))
2381                                 continue;
2382                         isl_seq_elim(qp->div->row[k] + 1, eq->eq[i], j, total,
2383                                         &qp->div->row[k][0]);
2384                         normalize_div(qp, k);
2385                 }
2386
2387                 if (isl_int_is_pos(eq->eq[i][j]))
2388                         isl_seq_neg(eq->eq[i], eq->eq[i], total);
2389                 isl_int_abs(denom, eq->eq[i][j]);
2390                 isl_int_set_si(eq->eq[i][j], 0);
2391
2392                 up = isl_upoly_from_affine(qp->dim->ctx,
2393                                                    eq->eq[i], denom, total);
2394                 qp->upoly = isl_upoly_subs(qp->upoly, j - 1, 1, &up);
2395                 isl_upoly_free(up);
2396         }
2397         isl_int_clear(denom);
2398
2399         if (!qp->upoly)
2400                 goto error;
2401
2402         isl_basic_set_free(eq);
2403
2404         qp = substitute_non_divs(qp);
2405         qp = sort_divs(qp);
2406
2407         return qp;
2408 error:
2409         isl_basic_set_free(eq);
2410         isl_qpolynomial_free(qp);
2411         return NULL;
2412 }
2413
2414 static __isl_give isl_basic_set *add_div_constraints(
2415         __isl_take isl_basic_set *bset, __isl_take isl_mat *div)
2416 {
2417         int i;
2418         unsigned total;
2419
2420         if (!bset || !div)
2421                 goto error;
2422
2423         bset = isl_basic_set_extend_constraints(bset, 0, 2 * div->n_row);
2424         if (!bset)
2425                 goto error;
2426         total = isl_basic_set_total_dim(bset);
2427         for (i = 0; i < div->n_row; ++i)
2428                 if (isl_basic_set_add_div_constraints_var(bset,
2429                                     total - div->n_row + i, div->row[i]) < 0)
2430                         goto error;
2431
2432         isl_mat_free(div);
2433         return bset;
2434 error:
2435         isl_mat_free(div);
2436         isl_basic_set_free(bset);
2437         return NULL;
2438 }
2439
2440 /* Look for equalities among the variables shared by context and qp
2441  * and the integer divisions of qp, if any.
2442  * The equalities are then used to eliminate variables and/or integer
2443  * divisions from qp.
2444  */
2445 __isl_give isl_qpolynomial *isl_qpolynomial_gist(
2446         __isl_take isl_qpolynomial *qp, __isl_take isl_set *context)
2447 {
2448         isl_basic_set *aff;
2449
2450         if (!qp)
2451                 goto error;
2452         if (qp->div->n_row > 0) {
2453                 isl_basic_set *bset;
2454                 context = isl_set_add_dims(context, isl_dim_set,
2455                                             qp->div->n_row);
2456                 bset = isl_basic_set_universe(isl_set_get_dim(context));
2457                 bset = add_div_constraints(bset, isl_mat_copy(qp->div));
2458                 context = isl_set_intersect(context,
2459                                             isl_set_from_basic_set(bset));
2460         }
2461
2462         aff = isl_set_affine_hull(context);
2463         return isl_qpolynomial_substitute_equalities(qp, aff);
2464 error:
2465         isl_qpolynomial_free(qp);
2466         isl_set_free(context);
2467         return NULL;
2468 }
2469
2470 #undef PW
2471 #define PW isl_pw_qpolynomial
2472 #undef EL
2473 #define EL isl_qpolynomial
2474 #undef IS_ZERO
2475 #define IS_ZERO is_zero
2476 #undef FIELD
2477 #define FIELD qp
2478
2479 #include <isl_pw_templ.c>
2480
2481 #undef UNION
2482 #define UNION isl_union_pw_qpolynomial
2483 #undef PART
2484 #define PART isl_pw_qpolynomial
2485 #undef PARTS
2486 #define PARTS pw_qpolynomial
2487
2488 #include <isl_union_templ.c>
2489
2490 int isl_pw_qpolynomial_is_one(__isl_keep isl_pw_qpolynomial *pwqp)
2491 {
2492         if (!pwqp)
2493                 return -1;
2494
2495         if (pwqp->n != -1)
2496                 return 0;
2497
2498         if (!isl_set_fast_is_universe(pwqp->p[0].set))
2499                 return 0;
2500
2501         return isl_qpolynomial_is_one(pwqp->p[0].qp);
2502 }
2503
2504 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul(
2505         __isl_take isl_pw_qpolynomial *pwqp1,
2506         __isl_take isl_pw_qpolynomial *pwqp2)
2507 {
2508         int i, j, n;
2509         struct isl_pw_qpolynomial *res;
2510         isl_set *set;
2511
2512         if (!pwqp1 || !pwqp2)
2513                 goto error;
2514
2515         isl_assert(pwqp1->dim->ctx, isl_dim_equal(pwqp1->dim, pwqp2->dim),
2516                         goto error);
2517
2518         if (isl_pw_qpolynomial_is_zero(pwqp1)) {
2519                 isl_pw_qpolynomial_free(pwqp2);
2520                 return pwqp1;
2521         }
2522
2523         if (isl_pw_qpolynomial_is_zero(pwqp2)) {
2524                 isl_pw_qpolynomial_free(pwqp1);
2525                 return pwqp2;
2526         }
2527
2528         if (isl_pw_qpolynomial_is_one(pwqp1)) {
2529                 isl_pw_qpolynomial_free(pwqp1);
2530                 return pwqp2;
2531         }
2532
2533         if (isl_pw_qpolynomial_is_one(pwqp2)) {
2534                 isl_pw_qpolynomial_free(pwqp2);
2535                 return pwqp1;
2536         }
2537
2538         n = pwqp1->n * pwqp2->n;
2539         res = isl_pw_qpolynomial_alloc_(isl_dim_copy(pwqp1->dim), n);
2540
2541         for (i = 0; i < pwqp1->n; ++i) {
2542                 for (j = 0; j < pwqp2->n; ++j) {
2543                         struct isl_set *common;
2544                         struct isl_qpolynomial *prod;
2545                         common = isl_set_intersect(isl_set_copy(pwqp1->p[i].set),
2546                                                 isl_set_copy(pwqp2->p[j].set));
2547                         if (isl_set_fast_is_empty(common)) {
2548                                 isl_set_free(common);
2549                                 continue;
2550                         }
2551
2552                         prod = isl_qpolynomial_mul(
2553                                 isl_qpolynomial_copy(pwqp1->p[i].qp),
2554                                 isl_qpolynomial_copy(pwqp2->p[j].qp));
2555
2556                         res = isl_pw_qpolynomial_add_piece(res, common, prod);
2557                 }
2558         }
2559
2560         isl_pw_qpolynomial_free(pwqp1);
2561         isl_pw_qpolynomial_free(pwqp2);
2562
2563         return res;
2564 error:
2565         isl_pw_qpolynomial_free(pwqp1);
2566         isl_pw_qpolynomial_free(pwqp2);
2567         return NULL;
2568 }
2569
2570 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg(
2571         __isl_take isl_pw_qpolynomial *pwqp)
2572 {
2573         int i;
2574
2575         if (!pwqp)
2576                 return NULL;
2577
2578         if (isl_pw_qpolynomial_is_zero(pwqp))
2579                 return pwqp;
2580
2581         pwqp = isl_pw_qpolynomial_cow(pwqp);
2582         if (!pwqp)
2583                 return NULL;
2584
2585         for (i = 0; i < pwqp->n; ++i) {
2586                 pwqp->p[i].qp = isl_qpolynomial_neg(pwqp->p[i].qp);
2587                 if (!pwqp->p[i].qp)
2588                         goto error;
2589         }
2590
2591         return pwqp;
2592 error:
2593         isl_pw_qpolynomial_free(pwqp);
2594         return NULL;
2595 }
2596
2597 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub(
2598         __isl_take isl_pw_qpolynomial *pwqp1,
2599         __isl_take isl_pw_qpolynomial *pwqp2)
2600 {
2601         return isl_pw_qpolynomial_add(pwqp1, isl_pw_qpolynomial_neg(pwqp2));
2602 }
2603
2604 __isl_give struct isl_upoly *isl_upoly_eval(
2605         __isl_take struct isl_upoly *up, __isl_take isl_vec *vec)
2606 {
2607         int i;
2608         struct isl_upoly_rec *rec;
2609         struct isl_upoly *res;
2610         struct isl_upoly *base;
2611
2612         if (isl_upoly_is_cst(up)) {
2613                 isl_vec_free(vec);
2614                 return up;
2615         }
2616
2617         rec = isl_upoly_as_rec(up);
2618         if (!rec)
2619                 goto error;
2620
2621         isl_assert(up->ctx, rec->n >= 1, goto error);
2622
2623         base = isl_upoly_rat_cst(up->ctx, vec->el[1 + up->var], vec->el[0]);
2624
2625         res = isl_upoly_eval(isl_upoly_copy(rec->p[rec->n - 1]),
2626                                 isl_vec_copy(vec));
2627
2628         for (i = rec->n - 2; i >= 0; --i) {
2629                 res = isl_upoly_mul(res, isl_upoly_copy(base));
2630                 res = isl_upoly_sum(res, 
2631                             isl_upoly_eval(isl_upoly_copy(rec->p[i]),
2632                                                             isl_vec_copy(vec)));
2633         }
2634
2635         isl_upoly_free(base);
2636         isl_upoly_free(up);
2637         isl_vec_free(vec);
2638         return res;
2639 error:
2640         isl_upoly_free(up);
2641         isl_vec_free(vec);
2642         return NULL;
2643 }
2644
2645 __isl_give isl_qpolynomial *isl_qpolynomial_eval(
2646         __isl_take isl_qpolynomial *qp, __isl_take isl_point *pnt)
2647 {
2648         isl_vec *ext;
2649         struct isl_upoly *up;
2650         isl_dim *dim;
2651
2652         if (!qp || !pnt)
2653                 goto error;
2654         isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, qp->dim), goto error);
2655
2656         if (qp->div->n_row == 0)
2657                 ext = isl_vec_copy(pnt->vec);
2658         else {
2659                 int i;
2660                 unsigned dim = isl_dim_total(qp->dim);
2661                 ext = isl_vec_alloc(qp->dim->ctx, 1 + dim + qp->div->n_row);
2662                 if (!ext)
2663                         goto error;
2664
2665                 isl_seq_cpy(ext->el, pnt->vec->el, pnt->vec->size);
2666                 for (i = 0; i < qp->div->n_row; ++i) {
2667                         isl_seq_inner_product(qp->div->row[i] + 1, ext->el,
2668                                                 1 + dim + i, &ext->el[1+dim+i]);
2669                         isl_int_fdiv_q(ext->el[1+dim+i], ext->el[1+dim+i],
2670                                         qp->div->row[i][0]);
2671                 }
2672         }
2673
2674         up = isl_upoly_eval(isl_upoly_copy(qp->upoly), ext);
2675         if (!up)
2676                 goto error;
2677
2678         dim = isl_dim_copy(qp->dim);
2679         isl_qpolynomial_free(qp);
2680         isl_point_free(pnt);
2681
2682         return isl_qpolynomial_alloc(dim, 0, up);
2683 error:
2684         isl_qpolynomial_free(qp);
2685         isl_point_free(pnt);
2686         return NULL;
2687 }
2688
2689 int isl_upoly_cmp(__isl_keep struct isl_upoly_cst *cst1,
2690         __isl_keep struct isl_upoly_cst *cst2)
2691 {
2692         int cmp;
2693         isl_int t;
2694         isl_int_init(t);
2695         isl_int_mul(t, cst1->n, cst2->d);
2696         isl_int_submul(t, cst2->n, cst1->d);
2697         cmp = isl_int_sgn(t);
2698         isl_int_clear(t);
2699         return cmp;
2700 }
2701
2702 int isl_qpolynomial_le_cst(__isl_keep isl_qpolynomial *qp1,
2703         __isl_keep isl_qpolynomial *qp2)
2704 {
2705         struct isl_upoly_cst *cst1, *cst2;
2706
2707         if (!qp1 || !qp2)
2708                 return -1;
2709         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), return -1);
2710         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), return -1);
2711         if (isl_qpolynomial_is_nan(qp1))
2712                 return -1;
2713         if (isl_qpolynomial_is_nan(qp2))
2714                 return -1;
2715         cst1 = isl_upoly_as_cst(qp1->upoly);
2716         cst2 = isl_upoly_as_cst(qp2->upoly);
2717
2718         return isl_upoly_cmp(cst1, cst2) <= 0;
2719 }
2720
2721 __isl_give isl_qpolynomial *isl_qpolynomial_min_cst(
2722         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
2723 {
2724         struct isl_upoly_cst *cst1, *cst2;
2725         int cmp;
2726
2727         if (!qp1 || !qp2)
2728                 goto error;
2729         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
2730         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
2731         cst1 = isl_upoly_as_cst(qp1->upoly);
2732         cst2 = isl_upoly_as_cst(qp2->upoly);
2733         cmp = isl_upoly_cmp(cst1, cst2);
2734
2735         if (cmp <= 0) {
2736                 isl_qpolynomial_free(qp2);
2737         } else {
2738                 isl_qpolynomial_free(qp1);
2739                 qp1 = qp2;
2740         }
2741         return qp1;
2742 error:
2743         isl_qpolynomial_free(qp1);
2744         isl_qpolynomial_free(qp2);
2745         return NULL;
2746 }
2747
2748 __isl_give isl_qpolynomial *isl_qpolynomial_max_cst(
2749         __isl_take isl_qpolynomial *qp1, __isl_take isl_qpolynomial *qp2)
2750 {
2751         struct isl_upoly_cst *cst1, *cst2;
2752         int cmp;
2753
2754         if (!qp1 || !qp2)
2755                 goto error;
2756         isl_assert(qp1->dim->ctx, isl_upoly_is_cst(qp1->upoly), goto error);
2757         isl_assert(qp2->dim->ctx, isl_upoly_is_cst(qp2->upoly), goto error);
2758         cst1 = isl_upoly_as_cst(qp1->upoly);
2759         cst2 = isl_upoly_as_cst(qp2->upoly);
2760         cmp = isl_upoly_cmp(cst1, cst2);
2761
2762         if (cmp >= 0) {
2763                 isl_qpolynomial_free(qp2);
2764         } else {
2765                 isl_qpolynomial_free(qp1);
2766                 qp1 = qp2;
2767         }
2768         return qp1;
2769 error:
2770         isl_qpolynomial_free(qp1);
2771         isl_qpolynomial_free(qp2);
2772         return NULL;
2773 }
2774
2775 __isl_give isl_qpolynomial *isl_qpolynomial_insert_dims(
2776         __isl_take isl_qpolynomial *qp, enum isl_dim_type type,
2777         unsigned first, unsigned n)
2778 {
2779         unsigned total;
2780         unsigned g_pos;
2781         int *exp;
2782
2783         if (n == 0)
2784                 return qp;
2785
2786         qp = isl_qpolynomial_cow(qp);
2787         if (!qp)
2788                 return NULL;
2789
2790         isl_assert(qp->div->ctx, first <= isl_dim_size(qp->dim, type),
2791                     goto error);
2792
2793         g_pos = pos(qp->dim, type) + first;
2794
2795         qp->div = isl_mat_insert_zero_cols(qp->div, 2 + g_pos, n);
2796         if (!qp->div)
2797                 goto error;
2798
2799         total = qp->div->n_col - 2;
2800         if (total > g_pos) {
2801                 int i;
2802                 exp = isl_alloc_array(qp->div->ctx, int, total - g_pos);
2803                 if (!exp)
2804                         goto error;
2805                 for (i = 0; i < total - g_pos; ++i)
2806                         exp[i] = i + n;
2807                 qp->upoly = expand(qp->upoly, exp, g_pos);
2808                 free(exp);
2809                 if (!qp->upoly)
2810                         goto error;
2811         }
2812
2813         qp->dim = isl_dim_insert(qp->dim, type, first, n);
2814         if (!qp->dim)
2815                 goto error;
2816
2817         return qp;
2818 error:
2819         isl_qpolynomial_free(qp);
2820         return NULL;
2821 }
2822
2823 __isl_give isl_qpolynomial *isl_qpolynomial_add_dims(
2824         __isl_take isl_qpolynomial *qp, enum isl_dim_type type, unsigned n)
2825 {
2826         unsigned pos;
2827
2828         pos = isl_qpolynomial_dim(qp, type);
2829
2830         return isl_qpolynomial_insert_dims(qp, type, pos, n);
2831 }
2832
2833 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_dims(
2834         __isl_take isl_pw_qpolynomial *pwqp,
2835         enum isl_dim_type type, unsigned n)
2836 {
2837         unsigned pos;
2838
2839         pos = isl_pw_qpolynomial_dim(pwqp, type);
2840
2841         return isl_pw_qpolynomial_insert_dims(pwqp, type, pos, n);
2842 }
2843
2844 static int *reordering_move(isl_ctx *ctx,
2845         unsigned len, unsigned dst, unsigned src, unsigned n)
2846 {
2847         int i;
2848         int *reordering;
2849
2850         reordering = isl_alloc_array(ctx, int, len);
2851         if (!reordering)
2852                 return NULL;
2853
2854         if (dst <= src) {
2855                 for (i = 0; i < dst; ++i)
2856                         reordering[i] = i;
2857                 for (i = 0; i < n; ++i)
2858                         reordering[src + i] = dst + i;
2859                 for (i = 0; i < src - dst; ++i)
2860                         reordering[dst + i] = dst + n + i;
2861                 for (i = 0; i < len - src - n; ++i)
2862                         reordering[src + n + i] = src + n + i;
2863         } else {
2864                 for (i = 0; i < src; ++i)
2865                         reordering[i] = i;
2866                 for (i = 0; i < n; ++i)
2867                         reordering[src + i] = dst + i;
2868                 for (i = 0; i < dst - src; ++i)
2869                         reordering[src + n + i] = src + i;
2870                 for (i = 0; i < len - dst - n; ++i)
2871                         reordering[dst + n + i] = dst + n + i;
2872         }
2873
2874         return reordering;
2875 }
2876
2877 __isl_give isl_qpolynomial *isl_qpolynomial_move_dims(
2878         __isl_take isl_qpolynomial *qp,
2879         enum isl_dim_type dst_type, unsigned dst_pos,
2880         enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2881 {
2882         unsigned g_dst_pos;
2883         unsigned g_src_pos;
2884         int *reordering;
2885
2886         qp = isl_qpolynomial_cow(qp);
2887         if (!qp)
2888                 return NULL;
2889
2890         isl_assert(qp->dim->ctx, src_pos + n <= isl_dim_size(qp->dim, src_type),
2891                 goto error);
2892
2893         g_dst_pos = pos(qp->dim, dst_type) + dst_pos;
2894         g_src_pos = pos(qp->dim, src_type) + src_pos;
2895         if (dst_type > src_type)
2896                 g_dst_pos -= n;
2897
2898         qp->div = isl_mat_move_cols(qp->div, 2 + g_dst_pos, 2 + g_src_pos, n);
2899         if (!qp->div)
2900                 goto error;
2901         qp = sort_divs(qp);
2902         if (!qp)
2903                 goto error;
2904
2905         reordering = reordering_move(qp->dim->ctx,
2906                                 qp->div->n_col - 2, g_dst_pos, g_src_pos, n);
2907         if (!reordering)
2908                 goto error;
2909
2910         qp->upoly = reorder(qp->upoly, reordering);
2911         free(reordering);
2912         if (!qp->upoly)
2913                 goto error;
2914
2915         qp->dim = isl_dim_move(qp->dim, dst_type, dst_pos, src_type, src_pos, n);
2916         if (!qp->dim)
2917                 goto error;
2918
2919         return qp;
2920 error:
2921         isl_qpolynomial_free(qp);
2922         return NULL;
2923 }
2924
2925 __isl_give isl_qpolynomial *isl_qpolynomial_from_affine(__isl_take isl_dim *dim,
2926         isl_int *f, isl_int denom)
2927 {
2928         struct isl_upoly *up;
2929
2930         if (!dim)
2931                 return NULL;
2932
2933         up = isl_upoly_from_affine(dim->ctx, f, denom, 1 + isl_dim_total(dim));
2934
2935         return isl_qpolynomial_alloc(dim, 0, up);
2936 }
2937
2938 __isl_give isl_qpolynomial *isl_qpolynomial_from_constraint(
2939         __isl_take isl_constraint *c, enum isl_dim_type type, unsigned pos)
2940 {
2941         isl_int denom;
2942         isl_dim *dim;
2943         struct isl_upoly *up;
2944         isl_qpolynomial *qp;
2945         int sgn;
2946
2947         if (!c)
2948                 return NULL;
2949
2950         isl_int_init(denom);
2951
2952         isl_constraint_get_coefficient(c, type, pos, &denom);
2953         isl_constraint_set_coefficient(c, type, pos, c->ctx->zero);
2954         sgn = isl_int_sgn(denom);
2955         isl_int_abs(denom, denom);
2956         up = isl_upoly_from_affine(c->ctx, c->line[0], denom,
2957                                         1 + isl_constraint_dim(c, isl_dim_all));
2958         if (sgn < 0)
2959                 isl_int_neg(denom, denom);
2960         isl_constraint_set_coefficient(c, type, pos, denom);
2961
2962         dim = isl_dim_copy(c->bmap->dim);
2963
2964         isl_int_clear(denom);
2965         isl_constraint_free(c);
2966
2967         qp = isl_qpolynomial_alloc(dim, 0, up);
2968         if (sgn > 0)
2969                 qp = isl_qpolynomial_neg(qp);
2970         return qp;
2971 }
2972
2973 /* For each 0 <= i < "n", replace variable "first" + i of type "type"
2974  * in "qp" by subs[i].
2975  */
2976 __isl_give isl_qpolynomial *isl_qpolynomial_substitute(
2977         __isl_take isl_qpolynomial *qp,
2978         enum isl_dim_type type, unsigned first, unsigned n,
2979         __isl_keep isl_qpolynomial **subs)
2980 {
2981         int i;
2982         struct isl_upoly **ups;
2983
2984         if (n == 0)
2985                 return qp;
2986
2987         qp = isl_qpolynomial_cow(qp);
2988         if (!qp)
2989                 return NULL;
2990         for (i = 0; i < n; ++i)
2991                 if (!subs[i])
2992                         goto error;
2993
2994         isl_assert(qp->dim->ctx, first + n <= isl_dim_size(qp->dim, type),
2995                         goto error);
2996
2997         for (i = 0; i < n; ++i)
2998                 isl_assert(qp->dim->ctx, isl_dim_equal(qp->dim, subs[i]->dim),
2999                                 goto error);
3000
3001         isl_assert(qp->dim->ctx, qp->div->n_row == 0, goto error);
3002         for (i = 0; i < n; ++i)
3003                 isl_assert(qp->dim->ctx, subs[i]->div->n_row == 0, goto error);
3004
3005         first += pos(qp->dim, type);
3006
3007         ups = isl_alloc_array(qp->dim->ctx, struct isl_upoly *, n);
3008         if (!ups)
3009                 goto error;
3010         for (i = 0; i < n; ++i)
3011                 ups[i] = subs[i]->upoly;
3012
3013         qp->upoly = isl_upoly_subs(qp->upoly, first, n, ups);
3014
3015         free(ups);
3016
3017         if (!qp->upoly)
3018                 goto error;
3019
3020         return qp;
3021 error:
3022         isl_qpolynomial_free(qp);
3023         return NULL;
3024 }
3025
3026 /* Extend "bset" with extra set dimensions for each integer division
3027  * in "qp" and then call "fn" with the extended bset and the polynomial
3028  * that results from replacing each of the integer divisions by the
3029  * corresponding extra set dimension.
3030  */
3031 int isl_qpolynomial_as_polynomial_on_domain(__isl_keep isl_qpolynomial *qp,
3032         __isl_keep isl_basic_set *bset,
3033         int (*fn)(__isl_take isl_basic_set *bset,
3034                   __isl_take isl_qpolynomial *poly, void *user), void *user)
3035 {
3036         isl_dim *dim;
3037         isl_mat *div;
3038         isl_qpolynomial *poly;
3039
3040         if (!qp || !bset)
3041                 goto error;
3042         if (qp->div->n_row == 0)
3043                 return fn(isl_basic_set_copy(bset), isl_qpolynomial_copy(qp),
3044                           user);
3045
3046         div = isl_mat_copy(qp->div);
3047         dim = isl_dim_copy(qp->dim);
3048         dim = isl_dim_add(dim, isl_dim_set, qp->div->n_row);
3049         poly = isl_qpolynomial_alloc(dim, 0, isl_upoly_copy(qp->upoly));
3050         bset = isl_basic_set_copy(bset);
3051         bset = isl_basic_set_add(bset, isl_dim_set, qp->div->n_row);
3052         bset = add_div_constraints(bset, div);
3053
3054         return fn(bset, poly, user);
3055 error:
3056         return -1;
3057 }
3058
3059 /* Return total degree in variables first (inclusive) up to last (exclusive).
3060  */
3061 int isl_upoly_degree(__isl_keep struct isl_upoly *up, int first, int last)
3062 {
3063         int deg = -1;
3064         int i;
3065         struct isl_upoly_rec *rec;
3066
3067         if (!up)
3068                 return -2;
3069         if (isl_upoly_is_zero(up))
3070                 return -1;
3071         if (isl_upoly_is_cst(up) || up->var < first)
3072                 return 0;
3073
3074         rec = isl_upoly_as_rec(up);
3075         if (!rec)
3076                 return -2;
3077
3078         for (i = 0; i < rec->n; ++i) {
3079                 int d;
3080
3081                 if (isl_upoly_is_zero(rec->p[i]))
3082                         continue;
3083                 d = isl_upoly_degree(rec->p[i], first, last);
3084                 if (up->var < last)
3085                         d += i;
3086                 if (d > deg)
3087                         deg = d;
3088         }
3089
3090         return deg;
3091 }
3092
3093 /* Return total degree in set variables.
3094  */
3095 int isl_qpolynomial_degree(__isl_keep isl_qpolynomial *poly)
3096 {
3097         unsigned ovar;
3098         unsigned nvar;
3099
3100         if (!poly)
3101                 return -2;
3102
3103         ovar = isl_dim_offset(poly->dim, isl_dim_set);
3104         nvar = isl_dim_size(poly->dim, isl_dim_set);
3105         return isl_upoly_degree(poly->upoly, ovar, ovar + nvar);
3106 }
3107
3108 __isl_give struct isl_upoly *isl_upoly_coeff(__isl_keep struct isl_upoly *up,
3109         unsigned pos, int deg)
3110 {
3111         int i;
3112         struct isl_upoly_rec *rec;
3113
3114         if (!up)
3115                 return NULL;
3116
3117         if (isl_upoly_is_cst(up) || up->var < pos) {
3118                 if (deg == 0)
3119                         return isl_upoly_copy(up);
3120                 else
3121                         return isl_upoly_zero(up->ctx);
3122         }
3123
3124         rec = isl_upoly_as_rec(up);
3125         if (!rec)
3126                 return NULL;
3127
3128         if (up->var == pos) {
3129                 if (deg < rec->n)
3130                         return isl_upoly_copy(rec->p[deg]);
3131                 else
3132                         return isl_upoly_zero(up->ctx);
3133         }
3134
3135         up = isl_upoly_copy(up);
3136         up = isl_upoly_cow(up);
3137         rec = isl_upoly_as_rec(up);
3138         if (!rec)
3139                 goto error;
3140
3141         for (i = 0; i < rec->n; ++i) {
3142                 struct isl_upoly *t;
3143                 t = isl_upoly_coeff(rec->p[i], pos, deg);
3144                 if (!t)
3145                         goto error;
3146                 isl_upoly_free(rec->p[i]);
3147                 rec->p[i] = t;
3148         }
3149
3150         return up;
3151 error:
3152         isl_upoly_free(up);
3153         return NULL;
3154 }
3155
3156 /* Return coefficient of power "deg" of variable "t_pos" of type "type".
3157  */
3158 __isl_give isl_qpolynomial *isl_qpolynomial_coeff(
3159         __isl_keep isl_qpolynomial *qp,
3160         enum isl_dim_type type, unsigned t_pos, int deg)
3161 {
3162         unsigned g_pos;
3163         struct isl_upoly *up;
3164         isl_qpolynomial *c;
3165
3166         if (!qp)
3167                 return NULL;
3168
3169         isl_assert(qp->div->ctx, t_pos < isl_dim_size(qp->dim, type),
3170                         return NULL);
3171
3172         g_pos = pos(qp->dim, type) + t_pos;
3173         up = isl_upoly_coeff(qp->upoly, g_pos, deg);
3174
3175         c = isl_qpolynomial_alloc(isl_dim_copy(qp->dim), qp->div->n_row, up);
3176         if (!c)
3177                 return NULL;
3178         isl_mat_free(c->div);
3179         c->div = isl_mat_copy(qp->div);
3180         if (!c->div)
3181                 goto error;
3182         return c;
3183 error:
3184         isl_qpolynomial_free(c);
3185         return NULL;
3186 }
3187
3188 /* Homogenize the polynomial in the variables first (inclusive) up to
3189  * last (exclusive) by inserting powers of variable first.
3190  * Variable first is assumed not to appear in the input.
3191  */
3192 __isl_give struct isl_upoly *isl_upoly_homogenize(
3193         __isl_take struct isl_upoly *up, int deg, int target,
3194         int first, int last)
3195 {
3196         int i;
3197         struct isl_upoly_rec *rec;
3198
3199         if (!up)
3200                 return NULL;
3201         if (isl_upoly_is_zero(up))
3202                 return up;
3203         if (deg == target)
3204                 return up;
3205         if (isl_upoly_is_cst(up) || up->var < first) {
3206                 struct isl_upoly *hom;
3207
3208                 hom = isl_upoly_var_pow(up->ctx, first, target - deg);
3209                 if (!hom)
3210                         goto error;
3211                 rec = isl_upoly_as_rec(hom);
3212                 rec->p[target - deg] = isl_upoly_mul(rec->p[target - deg], up);
3213
3214                 return hom;
3215         }
3216
3217         up = isl_upoly_cow(up);
3218         rec = isl_upoly_as_rec(up);
3219         if (!rec)
3220                 goto error;
3221
3222         for (i = 0; i < rec->n; ++i) {
3223                 if (isl_upoly_is_zero(rec->p[i]))
3224                         continue;
3225                 rec->p[i] = isl_upoly_homogenize(rec->p[i],
3226                                 up->var < last ? deg + i : i, target,
3227                                 first, last);
3228                 if (!rec->p[i])
3229                         goto error;
3230         }
3231
3232         return up;
3233 error:
3234         isl_upoly_free(up);
3235         return NULL;
3236 }
3237
3238 /* Homogenize the polynomial in the set variables by introducing
3239  * powers of an extra set variable at position 0.
3240  */
3241 __isl_give isl_qpolynomial *isl_qpolynomial_homogenize(
3242         __isl_take isl_qpolynomial *poly)
3243 {
3244         unsigned ovar;
3245         unsigned nvar;
3246         int deg = isl_qpolynomial_degree(poly);
3247
3248         if (deg < -1)
3249                 goto error;
3250
3251         poly = isl_qpolynomial_insert_dims(poly, isl_dim_set, 0, 1);
3252         poly = isl_qpolynomial_cow(poly);
3253         if (!poly)
3254                 goto error;
3255
3256         ovar = isl_dim_offset(poly->dim, isl_dim_set);
3257         nvar = isl_dim_size(poly->dim, isl_dim_set);
3258         poly->upoly = isl_upoly_homogenize(poly->upoly, 0, deg,
3259                                                 ovar, ovar + nvar);
3260         if (!poly->upoly)
3261                 goto error;
3262
3263         return poly;
3264 error:
3265         isl_qpolynomial_free(poly);
3266         return NULL;
3267 }
3268
3269 __isl_give isl_term *isl_term_alloc(__isl_take isl_dim *dim,
3270         __isl_take isl_mat *div)
3271 {
3272         isl_term *term;
3273         int n;
3274
3275         if (!dim || !div)
3276                 goto error;
3277
3278         n = isl_dim_total(dim) + div->n_row;
3279
3280         term = isl_calloc(dim->ctx, struct isl_term,
3281                         sizeof(struct isl_term) + (n - 1) * sizeof(int));
3282         if (!term)
3283                 goto error;
3284
3285         term->ref = 1;
3286         term->dim = dim;
3287         term->div = div;
3288         isl_int_init(term->n);
3289         isl_int_init(term->d);
3290         
3291         return term;
3292 error:
3293         isl_dim_free(dim);
3294         isl_mat_free(div);
3295         return NULL;
3296 }
3297
3298 __isl_give isl_term *isl_term_copy(__isl_keep isl_term *term)
3299 {
3300         if (!term)
3301                 return NULL;
3302
3303         term->ref++;
3304         return term;
3305 }
3306
3307 __isl_give isl_term *isl_term_dup(__isl_keep isl_term *term)
3308 {
3309         int i;
3310         isl_term *dup;
3311         unsigned total;
3312
3313         if (term)
3314                 return NULL;
3315
3316         total = isl_dim_total(term->dim) + term->div->n_row;
3317
3318         dup = isl_term_alloc(isl_dim_copy(term->dim), isl_mat_copy(term->div));
3319         if (!dup)
3320                 return NULL;
3321
3322         isl_int_set(dup->n, term->n);
3323         isl_int_set(dup->d, term->d);
3324
3325         for (i = 0; i < total; ++i)
3326                 dup->pow[i] = term->pow[i];
3327
3328         return dup;
3329 }
3330
3331 __isl_give isl_term *isl_term_cow(__isl_take isl_term *term)
3332 {
3333         if (!term)
3334                 return NULL;
3335
3336         if (term->ref == 1)
3337                 return term;
3338         term->ref--;
3339         return isl_term_dup(term);
3340 }
3341
3342 void isl_term_free(__isl_take isl_term *term)
3343 {
3344         if (!term)
3345                 return;
3346
3347         if (--term->ref > 0)
3348                 return;
3349
3350         isl_dim_free(term->dim);
3351         isl_mat_free(term->div);
3352         isl_int_clear(term->n);
3353         isl_int_clear(term->d);
3354         free(term);
3355 }
3356
3357 unsigned isl_term_dim(__isl_keep isl_term *term, enum isl_dim_type type)
3358 {
3359         if (!term)
3360                 return 0;
3361
3362         switch (type) {
3363         case isl_dim_param:
3364         case isl_dim_in:
3365         case isl_dim_out:       return isl_dim_size(term->dim, type);
3366         case isl_dim_div:       return term->div->n_row;
3367         case isl_dim_all:       return isl_dim_total(term->dim) + term->div->n_row;
3368         default:                return 0;
3369         }
3370 }
3371
3372 isl_ctx *isl_term_get_ctx(__isl_keep isl_term *term)
3373 {
3374         return term ? term->dim->ctx : NULL;
3375 }
3376
3377 void isl_term_get_num(__isl_keep isl_term *term, isl_int *n)
3378 {
3379         if (!term)
3380                 return;
3381         isl_int_set(*n, term->n);
3382 }
3383
3384 void isl_term_get_den(__isl_keep isl_term *term, isl_int *d)
3385 {
3386         if (!term)
3387                 return;
3388         isl_int_set(*d, term->d);
3389 }
3390
3391 int isl_term_get_exp(__isl_keep isl_term *term,
3392         enum isl_dim_type type, unsigned pos)
3393 {
3394         if (!term)
3395                 return -1;
3396
3397         isl_assert(term->dim->ctx, pos < isl_term_dim(term, type), return -1);
3398
3399         if (type >= isl_dim_set)
3400                 pos += isl_dim_size(term->dim, isl_dim_param);
3401         if (type >= isl_dim_div)
3402                 pos += isl_dim_size(term->dim, isl_dim_set);
3403
3404         return term->pow[pos];
3405 }
3406
3407 __isl_give isl_div *isl_term_get_div(__isl_keep isl_term *term, unsigned pos)
3408 {
3409         isl_basic_map *bmap;
3410         unsigned total;
3411         int k;
3412
3413         if (!term)
3414                 return NULL;
3415
3416         isl_assert(term->dim->ctx, pos < isl_term_dim(term, isl_dim_div),
3417                         return NULL);
3418
3419         total = term->div->n_col - term->div->n_row - 2;
3420         /* No nested divs for now */
3421         isl_assert(term->dim->ctx,
3422                 isl_seq_first_non_zero(term->div->row[pos] + 2 + total,
3423                                         term->div->n_row) == -1,
3424                 return NULL);
3425
3426         bmap = isl_basic_map_alloc_dim(isl_dim_copy(term->dim), 1, 0, 0);
3427         if ((k = isl_basic_map_alloc_div(bmap)) < 0)
3428                 goto error;
3429
3430         isl_seq_cpy(bmap->div[k], term->div->row[pos], 2 + total);
3431
3432         return isl_basic_map_div(bmap, k);
3433 error:
3434         isl_basic_map_free(bmap);
3435         return NULL;
3436 }
3437
3438 __isl_give isl_term *isl_upoly_foreach_term(__isl_keep struct isl_upoly *up,
3439         int (*fn)(__isl_take isl_term *term, void *user),
3440         __isl_take isl_term *term, void *user)
3441 {
3442         int i;
3443         struct isl_upoly_rec *rec;
3444
3445         if (!up || !term)
3446                 goto error;
3447
3448         if (isl_upoly_is_zero(up))
3449                 return term;
3450
3451         isl_assert(up->ctx, !isl_upoly_is_nan(up), goto error);
3452         isl_assert(up->ctx, !isl_upoly_is_infty(up), goto error);
3453         isl_assert(up->ctx, !isl_upoly_is_neginfty(up), goto error);
3454
3455         if (isl_upoly_is_cst(up)) {
3456                 struct isl_upoly_cst *cst;
3457                 cst = isl_upoly_as_cst(up);
3458                 if (!cst)
3459                         goto error;
3460                 term = isl_term_cow(term);
3461                 if (!term)
3462                         goto error;
3463                 isl_int_set(term->n, cst->n);
3464                 isl_int_set(term->d, cst->d);
3465                 if (fn(isl_term_copy(term), user) < 0)
3466                         goto error;
3467                 return term;
3468         }
3469
3470         rec = isl_upoly_as_rec(up);
3471         if (!rec)
3472                 goto error;
3473
3474         for (i = 0; i < rec->n; ++i) {
3475                 term = isl_term_cow(term);
3476                 if (!term)
3477                         goto error;
3478                 term->pow[up->var] = i;
3479                 term = isl_upoly_foreach_term(rec->p[i], fn, term, user);
3480                 if (!term)
3481                         goto error;
3482         }
3483         term->pow[up->var] = 0;
3484
3485         return term;
3486 error:
3487         isl_term_free(term);
3488         return NULL;
3489 }
3490
3491 int isl_qpolynomial_foreach_term(__isl_keep isl_qpolynomial *qp,
3492         int (*fn)(__isl_take isl_term *term, void *user), void *user)
3493 {
3494         isl_term *term;
3495
3496         if (!qp)
3497                 return -1;
3498
3499         term = isl_term_alloc(isl_dim_copy(qp->dim), isl_mat_copy(qp->div));
3500         if (!term)
3501                 return -1;
3502
3503         term = isl_upoly_foreach_term(qp->upoly, fn, term, user);
3504
3505         isl_term_free(term);
3506
3507         return term ? 0 : -1;
3508 }
3509
3510 __isl_give isl_qpolynomial *isl_qpolynomial_from_term(__isl_take isl_term *term)
3511 {
3512         struct isl_upoly *up;
3513         isl_qpolynomial *qp;
3514         int i, n;
3515
3516         if (!term)
3517                 return NULL;
3518
3519         n = isl_dim_total(term->dim) + term->div->n_row;
3520
3521         up = isl_upoly_rat_cst(term->dim->ctx, term->n, term->d);
3522         for (i = 0; i < n; ++i) {
3523                 if (!term->pow[i])
3524                         continue;
3525                 up = isl_upoly_mul(up,
3526                         isl_upoly_var_pow(term->dim->ctx, i, term->pow[i]));
3527         }
3528
3529         qp = isl_qpolynomial_alloc(isl_dim_copy(term->dim), term->div->n_row, up);
3530         if (!qp)
3531                 goto error;
3532         isl_mat_free(qp->div);
3533         qp->div = isl_mat_copy(term->div);
3534         if (!qp->div)
3535                 goto error;
3536
3537         isl_term_free(term);
3538         return qp;
3539 error:
3540         isl_qpolynomial_free(qp);
3541         isl_term_free(term);
3542         return NULL;
3543 }
3544
3545 __isl_give isl_qpolynomial *isl_qpolynomial_lift(__isl_take isl_qpolynomial *qp,
3546         __isl_take isl_dim *dim)
3547 {
3548         int i;
3549         int extra;
3550         unsigned total;
3551
3552         if (!qp || !dim)
3553                 goto error;
3554
3555         if (isl_dim_equal(qp->dim, dim)) {
3556                 isl_dim_free(dim);
3557                 return qp;
3558         }
3559
3560         qp = isl_qpolynomial_cow(qp);
3561         if (!qp)
3562                 goto error;
3563
3564         extra = isl_dim_size(dim, isl_dim_set) -
3565                         isl_dim_size(qp->dim, isl_dim_set);
3566         total = isl_dim_total(qp->dim);
3567         if (qp->div->n_row) {
3568                 int *exp;
3569
3570                 exp = isl_alloc_array(qp->div->ctx, int, qp->div->n_row);
3571                 if (!exp)
3572                         goto error;
3573                 for (i = 0; i < qp->div->n_row; ++i)
3574                         exp[i] = extra + i;
3575                 qp->upoly = expand(qp->upoly, exp, total);
3576                 free(exp);
3577                 if (!qp->upoly)
3578                         goto error;
3579         }
3580         qp->div = isl_mat_insert_cols(qp->div, 2 + total, extra);
3581         if (!qp->div)
3582                 goto error;
3583         for (i = 0; i < qp->div->n_row; ++i)
3584                 isl_seq_clr(qp->div->row[i] + 2 + total, extra);
3585
3586         isl_dim_free(qp->dim);
3587         qp->dim = dim;
3588
3589         return qp;
3590 error:
3591         isl_dim_free(dim);
3592         isl_qpolynomial_free(qp);
3593         return NULL;
3594 }
3595
3596 /* For each parameter or variable that does not appear in qp,
3597  * first eliminate the variable from all constraints and then set it to zero.
3598  */
3599 static __isl_give isl_set *fix_inactive(__isl_take isl_set *set,
3600         __isl_keep isl_qpolynomial *qp)
3601 {
3602         int *active = NULL;
3603         int i;
3604         int d;
3605         unsigned nparam;
3606         unsigned nvar;
3607
3608         if (!set || !qp)
3609                 goto error;
3610
3611         d = isl_dim_total(set->dim);
3612         active = isl_calloc_array(set->ctx, int, d);
3613         if (set_active(qp, active) < 0)
3614                 goto error;
3615
3616         for (i = 0; i < d; ++i)
3617                 if (!active[i])
3618                         break;
3619
3620         if (i == d) {
3621                 free(active);
3622                 return set;
3623         }
3624
3625         nparam = isl_dim_size(set->dim, isl_dim_param);
3626         nvar = isl_dim_size(set->dim, isl_dim_set);
3627         for (i = 0; i < nparam; ++i) {
3628                 if (active[i])
3629                         continue;
3630                 set = isl_set_eliminate(set, isl_dim_param, i, 1);
3631                 set = isl_set_fix_si(set, isl_dim_param, i, 0);
3632         }
3633         for (i = 0; i < nvar; ++i) {
3634                 if (active[nparam + i])
3635                         continue;
3636                 set = isl_set_eliminate(set, isl_dim_set, i, 1);
3637                 set = isl_set_fix_si(set, isl_dim_set, i, 0);
3638         }
3639
3640         free(active);
3641
3642         return set;
3643 error:
3644         free(active);
3645         isl_set_free(set);
3646         return NULL;
3647 }
3648
3649 struct isl_opt_data {
3650         isl_qpolynomial *qp;
3651         int first;
3652         isl_qpolynomial *opt;
3653         int max;
3654 };
3655
3656 static int opt_fn(__isl_take isl_point *pnt, void *user)
3657 {
3658         struct isl_opt_data *data = (struct isl_opt_data *)user;
3659         isl_qpolynomial *val;
3660
3661         val = isl_qpolynomial_eval(isl_qpolynomial_copy(data->qp), pnt);
3662         if (data->first) {
3663                 data->first = 0;
3664                 data->opt = val;
3665         } else if (data->max) {
3666                 data->opt = isl_qpolynomial_max_cst(data->opt, val);
3667         } else {
3668                 data->opt = isl_qpolynomial_min_cst(data->opt, val);
3669         }
3670
3671         return 0;
3672 }
3673
3674 __isl_give isl_qpolynomial *isl_qpolynomial_opt_on_domain(
3675         __isl_take isl_qpolynomial *qp, __isl_take isl_set *set, int max)
3676 {
3677         struct isl_opt_data data = { NULL, 1, NULL, max };
3678
3679         if (!set || !qp)
3680                 goto error;
3681
3682         if (isl_upoly_is_cst(qp->upoly)) {
3683                 isl_set_free(set);
3684                 return qp;
3685         }
3686
3687         set = fix_inactive(set, qp);
3688
3689         data.qp = qp;
3690         if (isl_set_foreach_point(set, opt_fn, &data) < 0)
3691                 goto error;
3692
3693         if (data.first)
3694                 data.opt = isl_qpolynomial_zero(isl_qpolynomial_get_dim(qp));
3695
3696         isl_set_free(set);
3697         isl_qpolynomial_free(qp);
3698         return data.opt;
3699 error:
3700         isl_set_free(set);
3701         isl_qpolynomial_free(qp);
3702         isl_qpolynomial_free(data.opt);
3703         return NULL;
3704 }
3705
3706 __isl_give isl_qpolynomial *isl_qpolynomial_morph(__isl_take isl_qpolynomial *qp,
3707         __isl_take isl_morph *morph)
3708 {
3709         int i;
3710         int n_sub;
3711         isl_ctx *ctx;
3712         struct isl_upoly *up;
3713         unsigned n_div;
3714         struct isl_upoly **subs;
3715         isl_mat *mat;
3716
3717         qp = isl_qpolynomial_cow(qp);
3718         if (!qp || !morph)
3719                 goto error;
3720
3721         ctx = qp->dim->ctx;
3722         isl_assert(ctx, isl_dim_equal(qp->dim, morph->dom->dim), goto error);
3723
3724         n_sub = morph->inv->n_row - 1;
3725         if (morph->inv->n_row != morph->inv->n_col)
3726                 n_sub += qp->div->n_row;
3727         subs = isl_calloc_array(ctx, struct isl_upoly *, n_sub);
3728         if (!subs)
3729                 goto error;
3730
3731         for (i = 0; 1 + i < morph->inv->n_row; ++i)
3732                 subs[i] = isl_upoly_from_affine(ctx, morph->inv->row[1 + i],
3733                                         morph->inv->row[0][0], morph->inv->n_col);
3734         if (morph->inv->n_row != morph->inv->n_col)
3735                 for (i = 0; i < qp->div->n_row; ++i)
3736                         subs[morph->inv->n_row - 1 + i] =
3737                             isl_upoly_var_pow(ctx, morph->inv->n_col - 1 + i, 1);
3738
3739         qp->upoly = isl_upoly_subs(qp->upoly, 0, n_sub, subs);
3740
3741         for (i = 0; i < n_sub; ++i)
3742                 isl_upoly_free(subs[i]);
3743         free(subs);
3744
3745         mat = isl_mat_diagonal(isl_mat_identity(ctx, 1), isl_mat_copy(morph->inv));
3746         mat = isl_mat_diagonal(mat, isl_mat_identity(ctx, qp->div->n_row));
3747         qp->div = isl_mat_product(qp->div, mat);
3748         isl_dim_free(qp->dim);
3749         qp->dim = isl_dim_copy(morph->ran->dim);
3750
3751         if (!qp->upoly || !qp->div || !qp->dim)
3752                 goto error;
3753
3754         isl_morph_free(morph);
3755
3756         return qp;
3757 error:
3758         isl_qpolynomial_free(qp);
3759         isl_morph_free(morph);
3760         return NULL;
3761 }
3762
3763 static int neg_entry(void **entry, void *user)
3764 {
3765         isl_pw_qpolynomial **pwqp = (isl_pw_qpolynomial **)entry;
3766
3767         *pwqp = isl_pw_qpolynomial_neg(*pwqp);
3768
3769         return *pwqp ? 0 : -1;
3770 }
3771
3772 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_neg(
3773         __isl_take isl_union_pw_qpolynomial *upwqp)
3774 {
3775         upwqp = isl_union_pw_qpolynomial_cow(upwqp);
3776         if (!upwqp)
3777                 return NULL;
3778
3779         if (isl_hash_table_foreach(upwqp->dim->ctx, &upwqp->table,
3780                                    &neg_entry, NULL) < 0)
3781                 goto error;
3782
3783         return upwqp;
3784 error:
3785         isl_union_pw_qpolynomial_free(upwqp);
3786         return NULL;
3787 }
3788
3789 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub(
3790         __isl_take isl_union_pw_qpolynomial *upwqp1,
3791         __isl_take isl_union_pw_qpolynomial *upwqp2)
3792 {
3793         return isl_union_pw_qpolynomial_add(upwqp1,
3794                                         isl_union_pw_qpolynomial_neg(upwqp2));
3795 }
3796
3797 static int mul_entry(void **entry, void *user)
3798 {
3799         struct isl_union_pw_qpolynomial_match_bin_data *data = user;
3800         uint32_t hash;
3801         struct isl_hash_table_entry *entry2;
3802         isl_pw_qpolynomial *pwpq = *entry;
3803         int empty;
3804
3805         hash = isl_dim_get_hash(pwpq->dim);
3806         entry2 = isl_hash_table_find(data->u2->dim->ctx, &data->u2->table,
3807                                      hash, &has_dim, pwpq->dim, 0);
3808         if (!entry2)
3809                 return 0;
3810
3811         pwpq = isl_pw_qpolynomial_copy(pwpq);
3812         pwpq = isl_pw_qpolynomial_mul(pwpq,
3813                                       isl_pw_qpolynomial_copy(entry2->data));
3814
3815         empty = isl_pw_qpolynomial_is_zero(pwpq);
3816         if (empty < 0) {
3817                 isl_pw_qpolynomial_free(pwpq);
3818                 return -1;
3819         }
3820         if (empty) {
3821                 isl_pw_qpolynomial_free(pwpq);
3822                 return 0;
3823         }
3824
3825         data->res = isl_union_pw_qpolynomial_add_pw_qpolynomial(data->res, pwpq);
3826
3827         return 0;
3828 }
3829
3830 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul(
3831         __isl_take isl_union_pw_qpolynomial *upwqp1,
3832         __isl_take isl_union_pw_qpolynomial *upwqp2)
3833 {
3834         return match_bin_op(upwqp1, upwqp2, &mul_entry);
3835 }
3836
3837 /* Reorder the columns of the given div definitions according to the
3838  * given reordering.
3839  */
3840 static __isl_give isl_mat *reorder_divs(__isl_take isl_mat *div,
3841         __isl_take isl_reordering *r)
3842 {
3843         int i, j;
3844         isl_mat *mat;
3845         int extra;
3846
3847         if (!div || !r)
3848                 goto error;
3849
3850         extra = isl_dim_total(r->dim) + div->n_row - r->len;
3851         mat = isl_mat_alloc(div->ctx, div->n_row, div->n_col + extra);
3852         if (!mat)
3853                 goto error;
3854
3855         for (i = 0; i < div->n_row; ++i) {
3856                 isl_seq_cpy(mat->row[i], div->row[i], 2);
3857                 isl_seq_clr(mat->row[i] + 2, mat->n_col - 2);
3858                 for (j = 0; j < r->len; ++j)
3859                         isl_int_set(mat->row[i][2 + r->pos[j]],
3860                                     div->row[i][2 + j]);
3861         }
3862
3863         isl_reordering_free(r);
3864         isl_mat_free(div);
3865         return mat;
3866 error:
3867         isl_reordering_free(r);
3868         isl_mat_free(div);
3869         return NULL;
3870 }
3871
3872 /* Reorder the dimension of "qp" according to the given reordering.
3873  */
3874 __isl_give isl_qpolynomial *isl_qpolynomial_realign(
3875         __isl_take isl_qpolynomial *qp, __isl_take isl_reordering *r)
3876 {
3877         qp = isl_qpolynomial_cow(qp);
3878         if (!qp)
3879                 goto error;
3880
3881         r = isl_reordering_extend(r, qp->div->n_row);
3882         if (!r)
3883                 goto error;
3884
3885         qp->div = reorder_divs(qp->div, isl_reordering_copy(r));
3886         if (!qp->div)
3887                 goto error;
3888
3889         qp->upoly = reorder(qp->upoly, r->pos);
3890         if (!qp->upoly)
3891                 goto error;
3892
3893         qp = isl_qpolynomial_reset_dim(qp, isl_dim_copy(r->dim));
3894
3895         isl_reordering_free(r);
3896         return qp;
3897 error:
3898         isl_qpolynomial_free(qp);
3899         isl_reordering_free(r);
3900         return NULL;
3901 }
3902
3903 struct isl_split_periods_data {
3904         int max_periods;
3905         isl_pw_qpolynomial *res;
3906 };
3907
3908 /* Create a slice where the integer division "div" has the fixed value "v".
3909  * In particular, if "div" refers to floor(f/m), then create a slice
3910  *
3911  *      m v <= f <= m v + (m - 1)
3912  *
3913  * or
3914  *
3915  *      f - m v >= 0
3916  *      -f + m v + (m - 1) >= 0
3917  */
3918 static __isl_give isl_set *set_div_slice(__isl_take isl_dim *dim,
3919         __isl_keep isl_qpolynomial *qp, int div, isl_int v)
3920 {
3921         int total;
3922         isl_basic_set *bset = NULL;
3923         int k;
3924
3925         if (!dim || !qp)
3926                 goto error;
3927
3928         total = isl_dim_total(dim);
3929         bset = isl_basic_set_alloc_dim(isl_dim_copy(dim), 0, 0, 2);
3930
3931         k = isl_basic_set_alloc_inequality(bset);
3932         if (k < 0)
3933                 goto error;
3934         isl_seq_cpy(bset->ineq[k], qp->div->row[div] + 1, 1 + total);
3935         isl_int_submul(bset->ineq[k][0], v, qp->div->row[div][0]);
3936
3937         k = isl_basic_set_alloc_inequality(bset);
3938         if (k < 0)
3939                 goto error;
3940         isl_seq_neg(bset->ineq[k], qp->div->row[div] + 1, 1 + total);
3941         isl_int_addmul(bset->ineq[k][0], v, qp->div->row[div][0]);
3942         isl_int_add(bset->ineq[k][0], bset->ineq[k][0], qp->div->row[div][0]);
3943         isl_int_sub_ui(bset->ineq[k][0], bset->ineq[k][0], 1);
3944
3945         isl_dim_free(dim);
3946         return isl_set_from_basic_set(bset);
3947 error:
3948         isl_basic_set_free(bset);
3949         isl_dim_free(dim);
3950         return NULL;
3951 }
3952
3953 static int split_periods(__isl_take isl_set *set,
3954         __isl_take isl_qpolynomial *qp, void *user);
3955
3956 /* Create a slice of the domain "set" such that integer division "div"
3957  * has the fixed value "v" and add the results to data->res,
3958  * replacing the integer division by "v" in "qp".
3959  */
3960 static int set_div(__isl_take isl_set *set,
3961         __isl_take isl_qpolynomial *qp, int div, isl_int v,
3962         struct isl_split_periods_data *data)
3963 {
3964         int i;
3965         int total;
3966         isl_set *slice;
3967         struct isl_upoly *cst;
3968
3969         slice = set_div_slice(isl_set_get_dim(set), qp, div, v);
3970         set = isl_set_intersect(set, slice);
3971
3972         if (!qp)
3973                 goto error;
3974
3975         total = isl_dim_total(qp->dim);
3976
3977         for (i = div + 1; i < qp->div->n_row; ++i) {
3978                 if (isl_int_is_zero(qp->div->row[i][2 + total + div]))
3979                         continue;
3980                 isl_int_addmul(qp->div->row[i][1],
3981                                 qp->div->row[i][2 + total + div], v);
3982                 isl_int_set_si(qp->div->row[i][2 + total + div], 0);
3983         }
3984
3985         cst = isl_upoly_rat_cst(qp->dim->ctx, v, qp->dim->ctx->one);
3986         qp = substitute_div(qp, div, cst);
3987
3988         return split_periods(set, qp, data);
3989 error:
3990         isl_set_free(set);
3991         isl_qpolynomial_free(qp);
3992         return -1;
3993 }
3994
3995 /* Split the domain "set" such that integer division "div"
3996  * has a fixed value (ranging from "min" to "max") on each slice
3997  * and add the results to data->res.
3998  */
3999 static int split_div(__isl_take isl_set *set,
4000         __isl_take isl_qpolynomial *qp, int div, isl_int min, isl_int max,
4001         struct isl_split_periods_data *data)
4002 {
4003         for (; isl_int_le(min, max); isl_int_add_ui(min, min, 1)) {
4004                 isl_set *set_i = isl_set_copy(set);
4005                 isl_qpolynomial *qp_i = isl_qpolynomial_copy(qp);
4006
4007                 if (set_div(set_i, qp_i, div, min, data) < 0)
4008                         goto error;
4009         }
4010         isl_set_free(set);
4011         isl_qpolynomial_free(qp);
4012         return 0;
4013 error:
4014         isl_set_free(set);
4015         isl_qpolynomial_free(qp);
4016         return -1;
4017 }
4018
4019 /* If "qp" refers to any integer division
4020  * that can only attain "max_periods" distinct values on "set"
4021  * then split the domain along those distinct values.
4022  * Add the results (or the original if no splitting occurs)
4023  * to data->res.
4024  */
4025 static int split_periods(__isl_take isl_set *set,
4026         __isl_take isl_qpolynomial *qp, void *user)
4027 {
4028         int i;
4029         isl_pw_qpolynomial *pwqp;
4030         struct isl_split_periods_data *data;
4031         isl_int min, max;
4032         int total;
4033         int r = 0;
4034
4035         data = (struct isl_split_periods_data *)user;
4036
4037         if (!set || !qp)
4038                 goto error;
4039
4040         if (qp->div->n_row == 0) {
4041                 pwqp = isl_pw_qpolynomial_alloc(set, qp);
4042                 data->res = isl_pw_qpolynomial_add_disjoint(data->res, pwqp);
4043                 return 0;
4044         }
4045
4046         isl_int_init(min);
4047         isl_int_init(max);
4048         total = isl_dim_total(qp->dim);
4049         for (i = 0; i < qp->div->n_row; ++i) {
4050                 enum isl_lp_result lp_res;
4051
4052                 if (isl_seq_first_non_zero(qp->div->row[i] + 2 + total,
4053                                                 qp->div->n_row) != -1)
4054                         continue;
4055
4056                 lp_res = isl_set_solve_lp(set, 0, qp->div->row[i] + 1,
4057                                           set->ctx->one, &min, NULL, NULL);
4058                 if (lp_res == isl_lp_error)
4059                         goto error2;
4060                 if (lp_res == isl_lp_unbounded || lp_res == isl_lp_empty)
4061                         continue;
4062                 isl_int_fdiv_q(min, min, qp->div->row[i][0]);
4063
4064                 lp_res = isl_set_solve_lp(set, 1, qp->div->row[i] + 1,
4065                                           set->ctx->one, &max, NULL, NULL);
4066                 if (lp_res == isl_lp_error)
4067                         goto error2;
4068                 if (lp_res == isl_lp_unbounded || lp_res == isl_lp_empty)
4069                         continue;
4070                 isl_int_fdiv_q(max, max, qp->div->row[i][0]);
4071
4072                 isl_int_sub(max, max, min);
4073                 if (isl_int_cmp_si(max, data->max_periods) < 0) {
4074                         isl_int_add(max, max, min);
4075                         break;
4076                 }
4077         }
4078
4079         if (i < qp->div->n_row) {
4080                 r = split_div(set, qp, i, min, max, data);
4081         } else {
4082                 pwqp = isl_pw_qpolynomial_alloc(set, qp);
4083                 data->res = isl_pw_qpolynomial_add_disjoint(data->res, pwqp);
4084         }
4085
4086         isl_int_clear(max);
4087         isl_int_clear(min);
4088
4089         return r;
4090 error2:
4091         isl_int_clear(max);
4092         isl_int_clear(min);
4093 error:
4094         isl_set_free(set);
4095         isl_qpolynomial_free(qp);
4096         return -1;
4097 }
4098
4099 /* If any quasi-polynomial in pwqp refers to any integer division
4100  * that can only attain "max_periods" distinct values on its domain
4101  * then split the domain along those distinct values.
4102  */
4103 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_split_periods(
4104         __isl_take isl_pw_qpolynomial *pwqp, int max_periods)
4105 {
4106         struct isl_split_periods_data data;
4107
4108         data.max_periods = max_periods;
4109         data.res = isl_pw_qpolynomial_zero(isl_pw_qpolynomial_get_dim(pwqp));
4110
4111         if (isl_pw_qpolynomial_foreach_piece(pwqp, &split_periods, &data) < 0)
4112                 goto error;
4113
4114         isl_pw_qpolynomial_free(pwqp);
4115
4116         return data.res;
4117 error:
4118         isl_pw_qpolynomial_free(data.res);
4119         isl_pw_qpolynomial_free(pwqp);
4120         return NULL;
4121 }
4122
4123 /* Construct a piecewise quasipolynomial that is constant on the given
4124  * domain.  In particular, it is
4125  *      0       if cst == 0
4126  *      1       if cst == 1
4127  *  infinity    if cst == -1
4128  */
4129 static __isl_give isl_pw_qpolynomial *constant_on_domain(
4130         __isl_take isl_basic_set *bset, int cst)
4131 {
4132         isl_dim *dim;
4133         isl_qpolynomial *qp;
4134
4135         if (!bset)
4136                 return NULL;
4137
4138         bset = isl_basic_map_domain(isl_basic_map_from_range(bset));
4139         dim = isl_basic_set_get_dim(bset);
4140         if (cst < 0)
4141                 qp = isl_qpolynomial_infty(dim);
4142         else if (cst == 0)
4143                 qp = isl_qpolynomial_zero(dim);
4144         else
4145                 qp = isl_qpolynomial_one(dim);
4146         return isl_pw_qpolynomial_alloc(isl_set_from_basic_set(bset), qp);
4147 }
4148
4149 /* Factor bset, call fn on each of the factors and return the product.
4150  *
4151  * If no factors can be found, simply call fn on the input.
4152  * Otherwise, construct the factors based on the factorizer,
4153  * call fn on each factor and compute the product.
4154  */
4155 static __isl_give isl_pw_qpolynomial *compressed_multiplicative_call(
4156         __isl_take isl_basic_set *bset,
4157         __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset))
4158 {
4159         int i, n;
4160         isl_dim *dim;
4161         isl_set *set;
4162         isl_factorizer *f;
4163         isl_qpolynomial *qp;
4164         isl_pw_qpolynomial *pwqp;
4165         unsigned nparam;
4166         unsigned nvar;
4167
4168         f = isl_basic_set_factorizer(bset);
4169         if (!f)
4170                 goto error;
4171         if (f->n_group == 0) {
4172                 isl_factorizer_free(f);
4173                 return fn(bset);
4174         }
4175
4176         nparam = isl_basic_set_dim(bset, isl_dim_param);
4177         nvar = isl_basic_set_dim(bset, isl_dim_set);
4178
4179         dim = isl_basic_set_get_dim(bset);
4180         dim = isl_dim_domain(dim);
4181         set = isl_set_universe(isl_dim_copy(dim));
4182         qp = isl_qpolynomial_one(dim);
4183         pwqp = isl_pw_qpolynomial_alloc(set, qp);
4184
4185         bset = isl_morph_basic_set(isl_morph_copy(f->morph), bset);
4186
4187         for (i = 0, n = 0; i < f->n_group; ++i) {
4188                 isl_basic_set *bset_i;
4189                 isl_pw_qpolynomial *pwqp_i;
4190
4191                 bset_i = isl_basic_set_copy(bset);
4192                 bset_i = isl_basic_set_drop_constraints_involving(bset_i,
4193                             nparam + n + f->len[i], nvar - n - f->len[i]);
4194                 bset_i = isl_basic_set_drop_constraints_involving(bset_i,
4195                             nparam, n);
4196                 bset_i = isl_basic_set_drop(bset_i, isl_dim_set,
4197                             n + f->len[i], nvar - n - f->len[i]);
4198                 bset_i = isl_basic_set_drop(bset_i, isl_dim_set, 0, n);
4199
4200                 pwqp_i = fn(bset_i);
4201                 pwqp = isl_pw_qpolynomial_mul(pwqp, pwqp_i);
4202
4203                 n += f->len[i];
4204         }
4205
4206         isl_basic_set_free(bset);
4207         isl_factorizer_free(f);
4208
4209         return pwqp;
4210 error:
4211         isl_basic_set_free(bset);
4212         return NULL;
4213 }
4214
4215 /* Factor bset, call fn on each of the factors and return the product.
4216  * The function is assumed to evaluate to zero on empty domains,
4217  * to one on zero-dimensional domains and to infinity on unbounded domains
4218  * and will not be called explicitly on zero-dimensional or unbounded domains.
4219  *
4220  * We first check for some special cases and remove all equalities.
4221  * Then we hand over control to compressed_multiplicative_call.
4222  */
4223 __isl_give isl_pw_qpolynomial *isl_basic_set_multiplicative_call(
4224         __isl_take isl_basic_set *bset,
4225         __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset))
4226 {
4227         int bounded;
4228         isl_morph *morph;
4229         isl_pw_qpolynomial *pwqp;
4230         unsigned orig_nvar, final_nvar;
4231
4232         if (!bset)
4233                 return NULL;
4234
4235         if (isl_basic_set_fast_is_empty(bset))
4236                 return constant_on_domain(bset, 0);
4237
4238         orig_nvar = isl_basic_set_dim(bset, isl_dim_set);
4239
4240         if (orig_nvar == 0)
4241                 return constant_on_domain(bset, 1);
4242
4243         bounded = isl_basic_set_is_bounded(bset);
4244         if (bounded < 0)
4245                 goto error;
4246         if (!bounded)
4247                 return constant_on_domain(bset, -1);
4248
4249         if (bset->n_eq == 0)
4250                 return compressed_multiplicative_call(bset, fn);
4251
4252         morph = isl_basic_set_full_compression(bset);
4253         bset = isl_morph_basic_set(isl_morph_copy(morph), bset);
4254
4255         final_nvar = isl_basic_set_dim(bset, isl_dim_set);
4256
4257         pwqp = compressed_multiplicative_call(bset, fn);
4258
4259         morph = isl_morph_remove_dom_dims(morph, isl_dim_set, 0, orig_nvar);
4260         morph = isl_morph_remove_ran_dims(morph, isl_dim_set, 0, final_nvar);
4261         morph = isl_morph_inverse(morph);
4262
4263         pwqp = isl_pw_qpolynomial_morph(pwqp, morph);
4264
4265         return pwqp;
4266 error:
4267         isl_basic_set_free(bset);
4268         return NULL;
4269 }
4270
4271 /* Drop all floors in "qp", turning each integer division [a/m] into
4272  * a rational division a/m.  If "down" is set, then the integer division
4273  * is replaces by (a-(m-1))/m instead.
4274  */
4275 static __isl_give isl_qpolynomial *qp_drop_floors(
4276         __isl_take isl_qpolynomial *qp, int down)
4277 {
4278         int i;
4279         struct isl_upoly *s;
4280
4281         if (!qp)
4282                 return NULL;
4283         if (qp->div->n_row == 0)
4284                 return qp;
4285
4286         qp = isl_qpolynomial_cow(qp);
4287         if (!qp)
4288                 return NULL;
4289
4290         for (i = qp->div->n_row - 1; i >= 0; --i) {
4291                 if (down) {
4292                         isl_int_sub(qp->div->row[i][1],
4293                                     qp->div->row[i][1], qp->div->row[i][0]);
4294                         isl_int_add_ui(qp->div->row[i][1],
4295                                        qp->div->row[i][1], 1);
4296                 }
4297                 s = isl_upoly_from_affine(qp->dim->ctx, qp->div->row[i] + 1,
4298                                         qp->div->row[i][0], qp->div->n_col - 1);
4299                 qp = substitute_div(qp, i, s);
4300                 if (!qp)
4301                         return NULL;
4302         }
4303
4304         return qp;
4305 }
4306
4307 /* Drop all floors in "pwqp", turning each integer division [a/m] into
4308  * a rational division a/m.
4309  */
4310 static __isl_give isl_pw_qpolynomial *pwqp_drop_floors(
4311         __isl_take isl_pw_qpolynomial *pwqp)
4312 {
4313         int i;
4314
4315         if (!pwqp)
4316                 return NULL;
4317
4318         if (isl_pw_qpolynomial_is_zero(pwqp))
4319                 return pwqp;
4320
4321         pwqp = isl_pw_qpolynomial_cow(pwqp);
4322         if (!pwqp)
4323                 return NULL;
4324
4325         for (i = 0; i < pwqp->n; ++i) {
4326                 pwqp->p[i].qp = qp_drop_floors(pwqp->p[i].qp, 0);
4327                 if (!pwqp->p[i].qp)
4328                         goto error;
4329         }
4330
4331         return pwqp;
4332 error:
4333         isl_pw_qpolynomial_free(pwqp);
4334         return NULL;
4335 }
4336
4337 /* Adjust all the integer divisions in "qp" such that they are at least
4338  * one over the given orthant (identified by "signs").  This ensures
4339  * that they will still be non-negative even after subtracting (m-1)/m.
4340  *
4341  * In particular, f is replaced by f' + v, changing f = [a/m]
4342  * to f' = [(a - m v)/m].
4343  * If the constant term k in a is smaller than m,
4344  * the constant term of v is set to floor(k/m) - 1.
4345  * For any other term, if the coefficient c and the variable x have
4346  * the same sign, then no changes are needed.
4347  * Otherwise, if the variable is positive (and c is negative),
4348  * then the coefficient of x in v is set to floor(c/m).
4349  * If the variable is negative (and c is positive),
4350  * then the coefficient of x in v is set to ceil(c/m).
4351  */
4352 static __isl_give isl_qpolynomial *make_divs_pos(__isl_take isl_qpolynomial *qp,
4353         int *signs)
4354 {
4355         int i, j;
4356         int total;
4357         isl_vec *v = NULL;
4358         struct isl_upoly *s;
4359
4360         qp = isl_qpolynomial_cow(qp);
4361         if (!qp)
4362                 return NULL;
4363         qp->div = isl_mat_cow(qp->div);
4364         if (!qp->div)
4365                 goto error;
4366
4367         total = isl_dim_total(qp->dim);
4368         v = isl_vec_alloc(qp->div->ctx, qp->div->n_col - 1);
4369
4370         for (i = 0; i < qp->div->n_row; ++i) {
4371                 isl_int *row = qp->div->row[i];
4372                 v = isl_vec_clr(v);
4373                 if (!v)
4374                         goto error;
4375                 if (isl_int_lt(row[1], row[0])) {
4376                         isl_int_fdiv_q(v->el[0], row[1], row[0]);
4377                         isl_int_sub_ui(v->el[0], v->el[0], 1);
4378                         isl_int_submul(row[1], row[0], v->el[0]);
4379                 }
4380                 for (j = 0; j < total; ++j) {
4381                         if (isl_int_sgn(row[2 + j]) * signs[j] >= 0)
4382                                 continue;
4383                         if (signs[j] < 0)
4384                                 isl_int_cdiv_q(v->el[1 + j], row[2 + j], row[0]);
4385                         else
4386                                 isl_int_fdiv_q(v->el[1 + j], row[2 + j], row[0]);
4387                         isl_int_submul(row[2 + j], row[0], v->el[1 + j]);
4388                 }
4389                 for (j = 0; j < i; ++j) {
4390                         if (isl_int_sgn(row[2 + total + j]) >= 0)
4391                                 continue;
4392                         isl_int_fdiv_q(v->el[1 + total + j],
4393                                         row[2 + total + j], row[0]);
4394                         isl_int_submul(row[2 + total + j],
4395                                         row[0], v->el[1 + total + j]);
4396                 }
4397                 for (j = i + 1; j < qp->div->n_row; ++j) {
4398                         if (isl_int_is_zero(qp->div->row[j][2 + total + i]))
4399                                 continue;
4400                         isl_seq_combine(qp->div->row[j] + 1,
4401                                 qp->div->ctx->one, qp->div->row[j] + 1,
4402                                 qp->div->row[j][2 + total + i], v->el, v->size);
4403                 }
4404                 isl_int_set_si(v->el[1 + total + i], 1);
4405                 s = isl_upoly_from_affine(qp->dim->ctx, v->el,
4406                                         qp->div->ctx->one, v->size);
4407                 qp->upoly = isl_upoly_subs(qp->upoly, total + i, 1, &s);
4408                 isl_upoly_free(s);
4409                 if (!qp->upoly)
4410                         goto error;
4411         }
4412
4413         isl_vec_free(v);
4414         return qp;
4415 error:
4416         isl_vec_free(v);
4417         isl_qpolynomial_free(qp);
4418         return NULL;
4419 }
4420
4421 struct isl_to_poly_data {
4422         int sign;
4423         isl_pw_qpolynomial *res;
4424         isl_qpolynomial *qp;
4425 };
4426
4427 /* Appoximate data->qp by a polynomial on the orthant identified by "signs".
4428  * We first make all integer divisions positive and then split the
4429  * quasipolynomials into terms with sign data->sign (the direction
4430  * of the requested approximation) and terms with the opposite sign.
4431  * In the first set of terms, each integer division [a/m] is
4432  * overapproximated by a/m, while in the second it is underapproximated
4433  * by (a-(m-1))/m.
4434  */
4435 static int to_polynomial_on_orthant(__isl_take isl_set *orthant, int *signs,
4436         void *user)
4437 {
4438         struct isl_to_poly_data *data = user;
4439         isl_pw_qpolynomial *t;
4440         isl_qpolynomial *qp, *up, *down;
4441
4442         qp = isl_qpolynomial_copy(data->qp);
4443         qp = make_divs_pos(qp, signs);
4444
4445         up = isl_qpolynomial_terms_of_sign(qp, signs, data->sign);
4446         up = qp_drop_floors(up, 0);
4447         down = isl_qpolynomial_terms_of_sign(qp, signs, -data->sign);
4448         down = qp_drop_floors(down, 1);
4449
4450         isl_qpolynomial_free(qp);
4451         qp = isl_qpolynomial_add(up, down);
4452
4453         t = isl_pw_qpolynomial_alloc(orthant, qp);
4454         data->res = isl_pw_qpolynomial_add_disjoint(data->res, t);
4455
4456         return 0;
4457 }
4458
4459 /* Approximate each quasipolynomial by a polynomial.  If "sign" is positive,
4460  * the polynomial will be an overapproximation.  If "sign" is negative,
4461  * it will be an underapproximation.  If "sign" is zero, the approximation
4462  * will lie somewhere in between.
4463  *
4464  * In particular, is sign == 0, we simply drop the floors, turning
4465  * the integer divisions into rational divisions.
4466  * Otherwise, we split the domains into orthants, make all integer divisions
4467  * positive and then approximate each [a/m] by either a/m or (a-(m-1))/m,
4468  * depending on the requested sign and the sign of the term in which
4469  * the integer division appears.
4470  */
4471 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_to_polynomial(
4472         __isl_take isl_pw_qpolynomial *pwqp, int sign)
4473 {
4474         int i;
4475         struct isl_to_poly_data data;
4476
4477         if (sign == 0)
4478                 return pwqp_drop_floors(pwqp);
4479
4480         if (!pwqp)
4481                 return NULL;
4482
4483         data.sign = sign;
4484         data.res = isl_pw_qpolynomial_zero(isl_pw_qpolynomial_get_dim(pwqp));
4485
4486         for (i = 0; i < pwqp->n; ++i) {
4487                 if (pwqp->p[i].qp->div->n_row == 0) {
4488                         isl_pw_qpolynomial *t;
4489                         t = isl_pw_qpolynomial_alloc(
4490                                         isl_set_copy(pwqp->p[i].set),
4491                                         isl_qpolynomial_copy(pwqp->p[i].qp));
4492                         data.res = isl_pw_qpolynomial_add_disjoint(data.res, t);
4493                         continue;
4494                 }
4495                 data.qp = pwqp->p[i].qp;
4496                 if (isl_set_foreach_orthant(pwqp->p[i].set,
4497                                         &to_polynomial_on_orthant, &data) < 0)
4498                         goto error;
4499         }
4500
4501         isl_pw_qpolynomial_free(pwqp);
4502
4503         return data.res;
4504 error:
4505         isl_pw_qpolynomial_free(pwqp);
4506         isl_pw_qpolynomial_free(data.res);
4507         return NULL;
4508 }
4509
4510 static int poly_entry(void **entry, void *user)
4511 {
4512         int *sign = user;
4513         isl_pw_qpolynomial **pwqp = (isl_pw_qpolynomial **)entry;
4514
4515         *pwqp = isl_pw_qpolynomial_to_polynomial(*pwqp, *sign);
4516
4517         return *pwqp ? 0 : -1;
4518 }
4519
4520 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_to_polynomial(
4521         __isl_take isl_union_pw_qpolynomial *upwqp, int sign)
4522 {
4523         upwqp = isl_union_pw_qpolynomial_cow(upwqp);
4524         if (!upwqp)
4525                 return NULL;
4526
4527         if (isl_hash_table_foreach(upwqp->dim->ctx, &upwqp->table,
4528                                    &poly_entry, &sign) < 0)
4529                 goto error;
4530
4531         return upwqp;
4532 error:
4533         isl_union_pw_qpolynomial_free(upwqp);
4534         return NULL;
4535 }
4536
4537 __isl_give isl_basic_map *isl_basic_map_from_qpolynomial(
4538         __isl_take isl_qpolynomial *qp)
4539 {
4540         int i, k;
4541         isl_dim *dim;
4542         isl_vec *aff = NULL;
4543         isl_basic_map *bmap = NULL;
4544         unsigned pos;
4545         unsigned n_div;
4546
4547         if (!qp)
4548                 return NULL;
4549         if (!isl_upoly_is_affine(qp->upoly))
4550                 isl_die(qp->dim->ctx, isl_error_invalid,
4551                         "input quasi-polynomial not affine", goto error);
4552         aff = isl_qpolynomial_extract_affine(qp);
4553         if (!aff)
4554                 goto error;
4555         dim = isl_qpolynomial_get_dim(qp);
4556         dim = isl_dim_from_domain(dim);
4557         pos = 1 + isl_dim_offset(dim, isl_dim_out);
4558         dim = isl_dim_add(dim, isl_dim_out, 1);
4559         n_div = qp->div->n_row;
4560         bmap = isl_basic_map_alloc_dim(dim, n_div, 1, 2 * n_div);
4561
4562         for (i = 0; i < n_div; ++i) {
4563                 k = isl_basic_map_alloc_div(bmap);
4564                 if (k < 0)
4565                         goto error;
4566                 isl_seq_cpy(bmap->div[k], qp->div->row[i], qp->div->n_col);
4567                 isl_int_set_si(bmap->div[k][qp->div->n_col], 0);
4568                 if (isl_basic_map_add_div_constraints(bmap, k) < 0)
4569                         goto error;
4570         }
4571         k = isl_basic_map_alloc_equality(bmap);
4572         if (k < 0)
4573                 goto error;
4574         isl_int_neg(bmap->eq[k][pos], aff->el[0]);
4575         isl_seq_cpy(bmap->eq[k], aff->el + 1, pos);
4576         isl_seq_cpy(bmap->eq[k] + pos + 1, aff->el + 1 + pos, n_div);
4577
4578         isl_vec_free(aff);
4579         isl_qpolynomial_free(qp);
4580         bmap = isl_basic_map_finalize(bmap);
4581         return bmap;
4582 error:
4583         isl_vec_free(aff);
4584         isl_qpolynomial_free(qp);
4585         isl_basic_map_free(bmap);
4586         return NULL;
4587 }