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