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