2 * Copyright 2010 INRIA Saclay
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
11 #include <isl_union_map_private.h>
12 #include <isl_polynomial_private.h>
13 #include <isl_point_private.h>
14 #include <isl_dim_private.h>
15 #include <isl_map_private.h>
19 static __isl_give isl_qpolynomial_fold *qpolynomial_fold_alloc(
20 enum isl_fold type, __isl_take isl_dim *dim, int n)
22 isl_qpolynomial_fold *fold;
27 isl_assert(dim->ctx, n >= 0, goto error);
28 fold = isl_calloc(dim->ctx, struct isl_qpolynomial_fold,
29 sizeof(struct isl_qpolynomial_fold) +
30 (n - 1) * sizeof(struct isl_qpolynomial *));
46 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_dim(
47 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_dim *dim)
51 fold = isl_qpolynomial_fold_cow(fold);
55 for (i = 0; i < fold->n; ++i) {
56 fold->qp[i] = isl_qpolynomial_reset_dim(fold->qp[i],
62 isl_dim_free(fold->dim);
67 isl_qpolynomial_fold_free(fold);
72 int isl_qpolynomial_fold_involves_dims(__isl_keep isl_qpolynomial_fold *fold,
73 enum isl_dim_type type, unsigned first, unsigned n)
79 if (fold->n == 0 || n == 0)
82 for (i = 0; i < fold->n; ++i) {
83 int involves = isl_qpolynomial_involves_dims(fold->qp[i],
85 if (involves < 0 || involves)
91 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_drop_dims(
92 __isl_take isl_qpolynomial_fold *fold,
93 enum isl_dim_type type, unsigned first, unsigned n)
102 fold = isl_qpolynomial_fold_cow(fold);
105 fold->dim = isl_dim_drop(fold->dim, type, first, n);
109 for (i = 0; i < fold->n; ++i) {
110 fold->qp[i] = isl_qpolynomial_drop_dims(fold->qp[i],
118 isl_qpolynomial_fold_free(fold);
122 static int isl_qpolynomial_cst_sign(__isl_keep isl_qpolynomial *qp)
124 struct isl_upoly_cst *cst;
126 cst = isl_upoly_as_cst(qp->upoly);
130 return isl_int_sgn(cst->n) < 0 ? -1 : 1;
133 static int isl_qpolynomial_aff_sign(__isl_keep isl_set *set,
134 __isl_keep isl_qpolynomial *qp)
136 enum isl_lp_result res;
141 aff = isl_qpolynomial_extract_affine(qp);
147 res = isl_set_solve_lp(set, 0, aff->el + 1, aff->el[0],
149 if (res == isl_lp_error)
151 if (res == isl_lp_empty ||
152 (res == isl_lp_ok && !isl_int_is_neg(opt))) {
157 res = isl_set_solve_lp(set, 1, aff->el + 1, aff->el[0],
159 if (res == isl_lp_ok && !isl_int_is_pos(opt))
168 /* Determine, if possible, the sign of the quasipolynomial "qp" on
171 * If qp is a constant, then the problem is trivial.
172 * If qp is linear, then we check if the minimum of the corresponding
173 * affine constraint is non-negative or if the maximum is non-positive.
175 * Otherwise, we check if the outermost variable "v" has a lower bound "l"
176 * in "set". If so, we write qp(v,v') as
178 * q(v,v') * (v - l) + r(v')
180 * if q(v,v') and r(v') have the same known sign, then the original
181 * quasipolynomial has the same sign as well.
188 static int isl_qpolynomial_sign(__isl_keep isl_set *set,
189 __isl_keep isl_qpolynomial *qp)
194 struct isl_upoly_rec *rec;
197 enum isl_lp_result res;
200 is = isl_qpolynomial_is_cst(qp, NULL, NULL);
204 return isl_qpolynomial_cst_sign(qp);
206 is = isl_qpolynomial_is_affine(qp);
210 return isl_qpolynomial_aff_sign(set, qp);
212 if (qp->div->n_row > 0)
215 rec = isl_upoly_as_rec(qp->upoly);
219 d = isl_dim_total(qp->dim);
220 v = isl_vec_alloc(set->ctx, 2 + d);
224 isl_seq_clr(v->el + 1, 1 + d);
225 isl_int_set_si(v->el[0], 1);
226 isl_int_set_si(v->el[2 + qp->upoly->var], 1);
230 res = isl_set_solve_lp(set, 0, v->el + 1, v->el[0], &l, NULL, NULL);
231 if (res == isl_lp_ok) {
232 isl_qpolynomial *min;
233 isl_qpolynomial *base;
234 isl_qpolynomial *r, *q;
237 min = isl_qpolynomial_cst(isl_dim_copy(qp->dim), l);
238 base = isl_qpolynomial_pow(isl_dim_copy(qp->dim),
241 r = isl_qpolynomial_alloc(isl_dim_copy(qp->dim), 0,
242 isl_upoly_copy(rec->p[rec->n - 1]));
243 q = isl_qpolynomial_copy(r);
245 for (i = rec->n - 2; i >= 0; --i) {
246 r = isl_qpolynomial_mul(r, isl_qpolynomial_copy(min));
247 t = isl_qpolynomial_alloc(isl_dim_copy(qp->dim), 0,
248 isl_upoly_copy(rec->p[i]));
249 r = isl_qpolynomial_add(r, t);
252 q = isl_qpolynomial_mul(q, isl_qpolynomial_copy(base));
253 q = isl_qpolynomial_add(q, isl_qpolynomial_copy(r));
256 if (isl_qpolynomial_is_zero(q))
257 sgn = isl_qpolynomial_sign(set, r);
258 else if (isl_qpolynomial_is_zero(r))
259 sgn = isl_qpolynomial_sign(set, q);
262 sgn_r = isl_qpolynomial_sign(set, r);
263 sgn_q = isl_qpolynomial_sign(set, q);
268 isl_qpolynomial_free(min);
269 isl_qpolynomial_free(base);
270 isl_qpolynomial_free(q);
271 isl_qpolynomial_free(r);
281 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold_on_domain(
282 __isl_keep isl_set *set,
283 __isl_take isl_qpolynomial_fold *fold1,
284 __isl_take isl_qpolynomial_fold *fold2)
288 struct isl_qpolynomial_fold *res = NULL;
291 if (!fold1 || !fold2)
294 isl_assert(fold1->dim->ctx, fold1->type == fold2->type, goto error);
295 isl_assert(fold1->dim->ctx, isl_dim_equal(fold1->dim, fold2->dim),
298 better = fold1->type == isl_fold_max ? -1 : 1;
300 if (isl_qpolynomial_fold_is_empty(fold1)) {
301 isl_qpolynomial_fold_free(fold1);
305 if (isl_qpolynomial_fold_is_empty(fold2)) {
306 isl_qpolynomial_fold_free(fold2);
310 res = qpolynomial_fold_alloc(fold1->type, isl_dim_copy(fold1->dim),
311 fold1->n + fold2->n);
315 for (i = 0; i < fold1->n; ++i) {
316 res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]);
317 if (!res->qp[res->n])
323 for (i = 0; i < fold2->n; ++i) {
324 for (j = n1 - 1; j >= 0; --j) {
327 d = isl_qpolynomial_sub(
328 isl_qpolynomial_copy(res->qp[j]),
329 isl_qpolynomial_copy(fold2->qp[i]));
330 sgn = isl_qpolynomial_sign(set, d);
331 isl_qpolynomial_free(d);
336 isl_qpolynomial_free(res->qp[j]);
338 res->qp[j] = res->qp[n1 - 1];
340 if (n1 != res->n - 1)
341 res->qp[n1] = res->qp[res->n - 1];
346 res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]);
347 if (!res->qp[res->n])
352 isl_qpolynomial_fold_free(fold1);
353 isl_qpolynomial_fold_free(fold2);
357 isl_qpolynomial_fold_free(res);
358 isl_qpolynomial_fold_free(fold1);
359 isl_qpolynomial_fold_free(fold2);
363 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_qpolynomial(
364 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_qpolynomial *qp)
371 if (isl_qpolynomial_is_zero(qp)) {
372 isl_qpolynomial_free(qp);
376 fold = isl_qpolynomial_fold_cow(fold);
380 for (i = 0; i < fold->n; ++i) {
381 fold->qp[i] = isl_qpolynomial_add(fold->qp[i],
382 isl_qpolynomial_copy(qp));
387 isl_qpolynomial_free(qp);
390 isl_qpolynomial_fold_free(fold);
391 isl_qpolynomial_free(qp);
395 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_add_on_domain(
396 __isl_keep isl_set *dom,
397 __isl_take isl_qpolynomial_fold *fold1,
398 __isl_take isl_qpolynomial_fold *fold2)
401 isl_qpolynomial_fold *res = NULL;
403 if (!fold1 || !fold2)
406 if (isl_qpolynomial_fold_is_empty(fold1)) {
407 isl_qpolynomial_fold_free(fold1);
411 if (isl_qpolynomial_fold_is_empty(fold2)) {
412 isl_qpolynomial_fold_free(fold2);
416 if (fold1->n == 1 && fold2->n != 1)
417 return isl_qpolynomial_fold_add_on_domain(dom, fold2, fold1);
420 res = isl_qpolynomial_fold_add_qpolynomial(fold1,
421 isl_qpolynomial_copy(fold2->qp[0]));
422 isl_qpolynomial_fold_free(fold2);
426 res = isl_qpolynomial_fold_add_qpolynomial(
427 isl_qpolynomial_fold_copy(fold1),
428 isl_qpolynomial_copy(fold2->qp[0]));
430 for (i = 1; i < fold2->n; ++i) {
431 isl_qpolynomial_fold *res_i;
432 res_i = isl_qpolynomial_fold_add_qpolynomial(
433 isl_qpolynomial_fold_copy(fold1),
434 isl_qpolynomial_copy(fold2->qp[i]));
435 res = isl_qpolynomial_fold_fold_on_domain(dom, res, res_i);
438 isl_qpolynomial_fold_free(fold1);
439 isl_qpolynomial_fold_free(fold2);
442 isl_qpolynomial_fold_free(res);
443 isl_qpolynomial_fold_free(fold1);
444 isl_qpolynomial_fold_free(fold2);
448 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute_equalities(
449 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_basic_set *eq)
456 fold = isl_qpolynomial_fold_cow(fold);
460 for (i = 0; i < fold->n; ++i) {
461 fold->qp[i] = isl_qpolynomial_substitute_equalities(fold->qp[i],
462 isl_basic_set_copy(eq));
467 isl_basic_set_free(eq);
470 isl_basic_set_free(eq);
471 isl_qpolynomial_fold_free(fold);
478 #define PW isl_pw_qpolynomial_fold
480 #define EL isl_qpolynomial_fold
482 #define IS_ZERO is_empty
486 #include <isl_pw_templ.c>
489 #define UNION isl_union_pw_qpolynomial_fold
491 #define PART isl_pw_qpolynomial_fold
493 #define PARTS pw_qpolynomial_fold
495 #include <isl_union_templ.c>
497 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type,
498 __isl_take isl_dim *dim)
500 return qpolynomial_fold_alloc(type, dim, 0);
503 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_alloc(
504 enum isl_fold type, __isl_take isl_qpolynomial *qp)
506 isl_qpolynomial_fold *fold;
511 fold = qpolynomial_fold_alloc(type, isl_dim_copy(qp->dim), 1);
520 isl_qpolynomial_fold_free(fold);
521 isl_qpolynomial_free(qp);
525 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_copy(
526 __isl_keep isl_qpolynomial_fold *fold)
535 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_dup(
536 __isl_keep isl_qpolynomial_fold *fold)
539 isl_qpolynomial_fold *dup;
543 dup = qpolynomial_fold_alloc(fold->type,
544 isl_dim_copy(fold->dim), fold->n);
549 for (i = 0; i < fold->n; ++i) {
550 dup->qp[i] = isl_qpolynomial_copy(fold->qp[i]);
557 isl_qpolynomial_fold_free(dup);
561 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_cow(
562 __isl_take isl_qpolynomial_fold *fold)
570 return isl_qpolynomial_fold_dup(fold);
573 void isl_qpolynomial_fold_free(__isl_take isl_qpolynomial_fold *fold)
582 for (i = 0; i < fold->n; ++i)
583 isl_qpolynomial_free(fold->qp[i]);
584 isl_dim_free(fold->dim);
588 int isl_qpolynomial_fold_is_empty(__isl_keep isl_qpolynomial_fold *fold)
596 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_fold(
597 __isl_take isl_qpolynomial_fold *fold1,
598 __isl_take isl_qpolynomial_fold *fold2)
601 struct isl_qpolynomial_fold *res = NULL;
603 if (!fold1 || !fold2)
606 isl_assert(fold1->dim->ctx, fold1->type == fold2->type, goto error);
607 isl_assert(fold1->dim->ctx, isl_dim_equal(fold1->dim, fold2->dim),
610 if (isl_qpolynomial_fold_is_empty(fold1)) {
611 isl_qpolynomial_fold_free(fold1);
615 if (isl_qpolynomial_fold_is_empty(fold2)) {
616 isl_qpolynomial_fold_free(fold2);
620 res = qpolynomial_fold_alloc(fold1->type, isl_dim_copy(fold1->dim),
621 fold1->n + fold2->n);
625 for (i = 0; i < fold1->n; ++i) {
626 res->qp[res->n] = isl_qpolynomial_copy(fold1->qp[i]);
627 if (!res->qp[res->n])
632 for (i = 0; i < fold2->n; ++i) {
633 res->qp[res->n] = isl_qpolynomial_copy(fold2->qp[i]);
634 if (!res->qp[res->n])
639 isl_qpolynomial_fold_free(fold1);
640 isl_qpolynomial_fold_free(fold2);
644 isl_qpolynomial_fold_free(res);
645 isl_qpolynomial_fold_free(fold1);
646 isl_qpolynomial_fold_free(fold2);
650 __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fold(
651 __isl_take isl_pw_qpolynomial_fold *pw1,
652 __isl_take isl_pw_qpolynomial_fold *pw2)
655 struct isl_pw_qpolynomial_fold *res;
661 isl_assert(pw1->dim->ctx, isl_dim_equal(pw1->dim, pw2->dim), goto error);
663 if (isl_pw_qpolynomial_fold_is_zero(pw1)) {
664 isl_pw_qpolynomial_fold_free(pw1);
668 if (isl_pw_qpolynomial_fold_is_zero(pw2)) {
669 isl_pw_qpolynomial_fold_free(pw2);
673 if (pw1->type != pw2->type)
674 isl_die(set->ctx, isl_error_invalid, "fold types don't match",
677 n = (pw1->n + 1) * (pw2->n + 1);
678 res = isl_pw_qpolynomial_fold_alloc_(isl_dim_copy(pw1->dim),
681 for (i = 0; i < pw1->n; ++i) {
682 set = isl_set_copy(pw1->p[i].set);
683 for (j = 0; j < pw2->n; ++j) {
684 struct isl_set *common;
685 isl_qpolynomial_fold *sum;
686 set = isl_set_subtract(set,
687 isl_set_copy(pw2->p[j].set));
688 common = isl_set_intersect(isl_set_copy(pw1->p[i].set),
689 isl_set_copy(pw2->p[j].set));
690 if (isl_set_fast_is_empty(common)) {
691 isl_set_free(common);
695 sum = isl_qpolynomial_fold_fold_on_domain(common,
696 isl_qpolynomial_fold_copy(pw1->p[i].fold),
697 isl_qpolynomial_fold_copy(pw2->p[j].fold));
699 res = isl_pw_qpolynomial_fold_add_piece(res, common, sum);
701 res = isl_pw_qpolynomial_fold_add_piece(res, set,
702 isl_qpolynomial_fold_copy(pw1->p[i].fold));
705 for (j = 0; j < pw2->n; ++j) {
706 set = isl_set_copy(pw2->p[j].set);
707 for (i = 0; i < pw1->n; ++i)
708 set = isl_set_subtract(set, isl_set_copy(pw1->p[i].set));
709 res = isl_pw_qpolynomial_fold_add_piece(res, set,
710 isl_qpolynomial_fold_copy(pw2->p[j].fold));
713 isl_pw_qpolynomial_fold_free(pw1);
714 isl_pw_qpolynomial_fold_free(pw2);
718 isl_pw_qpolynomial_fold_free(pw1);
719 isl_pw_qpolynomial_fold_free(pw2);
723 __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold(
724 __isl_take isl_union_pw_qpolynomial_fold *u,
725 __isl_take isl_pw_qpolynomial_fold *part)
728 struct isl_hash_table_entry *entry;
730 u = isl_union_pw_qpolynomial_fold_cow(u);
735 isl_assert(u->dim->ctx, isl_dim_match(part->dim, isl_dim_param, u->dim,
736 isl_dim_param), goto error);
738 hash = isl_dim_get_hash(part->dim);
739 entry = isl_hash_table_find(u->dim->ctx, &u->table, hash,
740 &has_dim, part->dim, 1);
747 entry->data = isl_pw_qpolynomial_fold_fold(entry->data,
748 isl_pw_qpolynomial_fold_copy(part));
751 isl_pw_qpolynomial_fold_free(part);
756 isl_pw_qpolynomial_fold_free(part);
757 isl_union_pw_qpolynomial_fold_free(u);
761 static int fold_part(__isl_take isl_pw_qpolynomial_fold *part, void *user)
763 isl_union_pw_qpolynomial_fold **u;
764 u = (isl_union_pw_qpolynomial_fold **)user;
766 *u = isl_union_pw_qpolynomial_fold_fold_pw_qpolynomial_fold(*u, part);
771 __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold(
772 __isl_take isl_union_pw_qpolynomial_fold *u1,
773 __isl_take isl_union_pw_qpolynomial_fold *u2)
775 u1 = isl_union_pw_qpolynomial_fold_cow(u1);
780 if (isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(u2,
781 &fold_part, &u1) < 0)
784 isl_union_pw_qpolynomial_fold_free(u2);
788 isl_union_pw_qpolynomial_fold_free(u1);
789 isl_union_pw_qpolynomial_fold_free(u2);
793 __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_from_pw_qpolynomial(
794 enum isl_fold type, __isl_take isl_pw_qpolynomial *pwqp)
797 isl_pw_qpolynomial_fold *pwf;
802 pwf = isl_pw_qpolynomial_fold_alloc_(isl_dim_copy(pwqp->dim), type,
805 for (i = 0; i < pwqp->n; ++i)
806 pwf = isl_pw_qpolynomial_fold_add_piece(pwf,
807 isl_set_copy(pwqp->p[i].set),
808 isl_qpolynomial_fold_alloc(type,
809 isl_qpolynomial_copy(pwqp->p[i].qp)));
811 isl_pw_qpolynomial_free(pwqp);
816 int isl_qpolynomial_fold_is_equal(__isl_keep isl_qpolynomial_fold *fold1,
817 __isl_keep isl_qpolynomial_fold *fold2)
821 if (!fold1 || !fold2)
824 if (fold1->n != fold2->n)
827 /* We probably want to sort the qps first... */
828 for (i = 0; i < fold1->n; ++i) {
829 int eq = isl_qpolynomial_is_equal(fold1->qp[i], fold2->qp[i]);
837 __isl_give isl_qpolynomial *isl_qpolynomial_fold_eval(
838 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt)
844 isl_assert(pnt->dim->ctx, isl_dim_equal(pnt->dim, fold->dim), goto error);
845 isl_assert(pnt->dim->ctx,
846 fold->type == isl_fold_max || fold->type == isl_fold_min,
850 qp = isl_qpolynomial_zero(isl_dim_copy(fold->dim));
853 qp = isl_qpolynomial_eval(isl_qpolynomial_copy(fold->qp[0]),
854 isl_point_copy(pnt));
855 for (i = 1; i < fold->n; ++i) {
856 isl_qpolynomial *qp_i;
857 qp_i = isl_qpolynomial_eval(
858 isl_qpolynomial_copy(fold->qp[i]),
859 isl_point_copy(pnt));
860 if (fold->type == isl_fold_max)
861 qp = isl_qpolynomial_max_cst(qp, qp_i);
863 qp = isl_qpolynomial_min_cst(qp, qp_i);
866 isl_qpolynomial_fold_free(fold);
871 isl_qpolynomial_fold_free(fold);
876 size_t isl_pw_qpolynomial_fold_size(__isl_keep isl_pw_qpolynomial_fold *pwf)
881 for (i = 0; i < pwf->n; ++i)
882 n += pwf->p[i].fold->n;
887 __isl_give isl_qpolynomial *isl_qpolynomial_fold_opt_on_domain(
888 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_set *set, int max)
891 isl_qpolynomial *opt;
897 isl_dim *dim = isl_dim_copy(fold->dim);
899 isl_qpolynomial_fold_free(fold);
900 return isl_qpolynomial_zero(dim);
903 opt = isl_qpolynomial_opt_on_domain(isl_qpolynomial_copy(fold->qp[0]),
904 isl_set_copy(set), max);
905 for (i = 1; i < fold->n; ++i) {
906 isl_qpolynomial *opt_i;
907 opt_i = isl_qpolynomial_opt_on_domain(
908 isl_qpolynomial_copy(fold->qp[i]),
909 isl_set_copy(set), max);
911 opt = isl_qpolynomial_max_cst(opt, opt_i);
913 opt = isl_qpolynomial_min_cst(opt, opt_i);
917 isl_qpolynomial_fold_free(fold);
922 isl_qpolynomial_fold_free(fold);
926 /* Check whether for each quasi-polynomial in "fold2" there is
927 * a quasi-polynomial in "fold1" that dominates it on "set".
929 static int qpolynomial_fold_covers_on_domain(__isl_keep isl_set *set,
930 __isl_keep isl_qpolynomial_fold *fold1,
931 __isl_keep isl_qpolynomial_fold *fold2)
936 if (!set || !fold1 || !fold2)
939 covers = fold1->type == isl_fold_max ? 1 : -1;
941 for (i = 0; i < fold2->n; ++i) {
942 for (j = 0; j < fold1->n; ++j) {
946 d = isl_qpolynomial_sub(
947 isl_qpolynomial_copy(fold1->qp[j]),
948 isl_qpolynomial_copy(fold2->qp[i]));
949 sgn = isl_qpolynomial_sign(set, d);
950 isl_qpolynomial_free(d);
961 /* Check whether "pwf1" dominated "pwf2", i.e., the domain of "pwf1" contains
962 * that of "pwf2" and on each cell, the corresponding fold from pwf1 dominates
965 int isl_pw_qpolynomial_fold_covers(__isl_keep isl_pw_qpolynomial_fold *pwf1,
966 __isl_keep isl_pw_qpolynomial_fold *pwf2)
969 isl_set *dom1, *dom2;
980 dom1 = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf1));
981 dom2 = isl_pw_qpolynomial_fold_domain(isl_pw_qpolynomial_fold_copy(pwf2));
982 is_subset = isl_set_is_subset(dom2, dom1);
986 if (is_subset < 0 || !is_subset)
989 for (i = 0; i < pwf2->n; ++i) {
990 for (j = 0; j < pwf1->n; ++j) {
995 common = isl_set_intersect(isl_set_copy(pwf1->p[j].set),
996 isl_set_copy(pwf2->p[i].set));
997 is_empty = isl_set_is_empty(common);
998 if (is_empty < 0 || is_empty) {
999 isl_set_free(common);
1004 covers = qpolynomial_fold_covers_on_domain(common,
1005 pwf1->p[j].fold, pwf2->p[i].fold);
1006 isl_set_free(common);
1007 if (covers < 0 || !covers)
1015 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_morph(
1016 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_morph *morph)
1021 if (!fold || !morph)
1024 ctx = fold->dim->ctx;
1025 isl_assert(ctx, isl_dim_equal(fold->dim, morph->dom->dim), goto error);
1027 fold = isl_qpolynomial_fold_cow(fold);
1031 isl_dim_free(fold->dim);
1032 fold->dim = isl_dim_copy(morph->ran->dim);
1036 for (i = 0; i < fold->n; ++i) {
1037 fold->qp[i] = isl_qpolynomial_morph(fold->qp[i],
1038 isl_morph_copy(morph));
1043 isl_morph_free(morph);
1047 isl_qpolynomial_fold_free(fold);
1048 isl_morph_free(morph);
1052 enum isl_fold isl_qpolynomial_fold_get_type(__isl_keep isl_qpolynomial_fold *fold)
1055 return isl_fold_list;
1059 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_lift(
1060 __isl_take isl_qpolynomial_fold *fold, __isl_take isl_dim *dim)
1068 if (isl_dim_equal(fold->dim, dim)) {
1073 fold = isl_qpolynomial_fold_cow(fold);
1077 isl_dim_free(fold->dim);
1078 fold->dim = isl_dim_copy(dim);
1082 for (i = 0; i < fold->n; ++i) {
1083 fold->qp[i] = isl_qpolynomial_lift(fold->qp[i],
1093 isl_qpolynomial_fold_free(fold);
1098 int isl_qpolynomial_fold_foreach_qpolynomial(
1099 __isl_keep isl_qpolynomial_fold *fold,
1100 int (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user)
1107 for (i = 0; i < fold->n; ++i)
1108 if (fn(isl_qpolynomial_copy(fold->qp[i]), user) < 0)
1114 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_move_dims(
1115 __isl_take isl_qpolynomial_fold *fold,
1116 enum isl_dim_type dst_type, unsigned dst_pos,
1117 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
1124 fold = isl_qpolynomial_fold_cow(fold);
1128 fold->dim = isl_dim_move(fold->dim, dst_type, dst_pos,
1129 src_type, src_pos, n);
1133 for (i = 0; i < fold->n; ++i) {
1134 fold->qp[i] = isl_qpolynomial_move_dims(fold->qp[i],
1135 dst_type, dst_pos, src_type, src_pos, n);
1142 isl_qpolynomial_fold_free(fold);
1146 /* For each 0 <= i < "n", replace variable "first" + i of type "type"
1147 * in fold->qp[k] by subs[i].
1149 __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute(
1150 __isl_take isl_qpolynomial_fold *fold,
1151 enum isl_dim_type type, unsigned first, unsigned n,
1152 __isl_keep isl_qpolynomial **subs)
1159 fold = isl_qpolynomial_fold_cow(fold);
1163 for (i = 0; i < fold->n; ++i) {
1164 fold->qp[i] = isl_qpolynomial_substitute(fold->qp[i],
1165 type, first, n, subs);
1172 isl_qpolynomial_fold_free(fold);