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