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