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