add isl_aff_mod_val
[platform/upstream/isl.git] / isl_polynomial.c
index c865789..2dfdd0f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010      INRIA Saclay
  *
- * Use of this software is governed by the GNU LGPLv2.1 license
+ * Use of this software is governed by the MIT license
  *
  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
@@ -20,7 +20,6 @@
 #include <isl_polynomial_private.h>
 #include <isl_point_private.h>
 #include <isl_space_private.h>
-#include <isl_div_private.h>
 #include <isl_mat_private.h>
 #include <isl_range.h>
 #include <isl_local_space_private.h>
@@ -344,7 +343,7 @@ __isl_give struct isl_upoly_rec *isl_upoly_alloc_rec(struct isl_ctx *ctx,
        return rec;
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_reset_space(
+__isl_give isl_qpolynomial *isl_qpolynomial_reset_domain_space(
        __isl_take isl_qpolynomial *qp, __isl_take isl_space *dim)
 {
        qp = isl_qpolynomial_cow(qp);
@@ -361,20 +360,53 @@ error:
        return NULL;
 }
 
+/* Reset the space of "qp".  This function is called from isl_pw_templ.c
+ * and doesn't know if the space of an element object is represented
+ * directly or through its domain.  It therefore passes along both.
+ */
+__isl_give isl_qpolynomial *isl_qpolynomial_reset_space_and_domain(
+       __isl_take isl_qpolynomial *qp, __isl_take isl_space *space,
+       __isl_take isl_space *domain)
+{
+       isl_space_free(space);
+       return isl_qpolynomial_reset_domain_space(qp, domain);
+}
+
 isl_ctx *isl_qpolynomial_get_ctx(__isl_keep isl_qpolynomial *qp)
 {
        return qp ? qp->dim->ctx : NULL;
 }
 
-__isl_give isl_space *isl_qpolynomial_get_space(__isl_keep isl_qpolynomial *qp)
+__isl_give isl_space *isl_qpolynomial_get_domain_space(
+       __isl_keep isl_qpolynomial *qp)
 {
        return qp ? isl_space_copy(qp->dim) : NULL;
 }
 
+__isl_give isl_space *isl_qpolynomial_get_space(__isl_keep isl_qpolynomial *qp)
+{
+       isl_space *space;
+       if (!qp)
+               return NULL;
+       space = isl_space_copy(qp->dim);
+       space = isl_space_from_domain(space);
+       space = isl_space_add_dims(space, isl_dim_out, 1);
+       return space;
+}
+
+/* Externally, an isl_qpolynomial has a map space, but internally, the
+ * ls field corresponds to the domain of that space.
+ */
 unsigned isl_qpolynomial_dim(__isl_keep isl_qpolynomial *qp,
        enum isl_dim_type type)
 {
-       return qp ? isl_space_dim(qp->dim, type) : 0;
+       if (!qp)
+               return 0;
+       if (type == isl_dim_out)
+               return 1;
+       if (type == isl_dim_in)
+               type = isl_dim_set;
+       return isl_space_dim(qp->dim, type);
 }
 
 int isl_qpolynomial_is_zero(__isl_keep isl_qpolynomial *qp)
@@ -955,6 +987,10 @@ __isl_give isl_qpolynomial *isl_qpolynomial_alloc(__isl_take isl_space *dim,
        if (!dim || !up)
                goto error;
 
+       if (!isl_space_is_set(dim))
+               isl_die(isl_space_get_ctx(dim), isl_error_invalid,
+                       "domain of polynomial should be a set", goto error);
+
        total = isl_space_dim(dim, isl_dim_all);
 
        qp = isl_calloc_type(dim->ctx, struct isl_qpolynomial);
@@ -1402,7 +1438,7 @@ __isl_give isl_qpolynomial *isl_qpolynomial_mul_isl_int(
 
        if (qp && isl_int_is_zero(v)) {
                isl_qpolynomial *zero;
-               zero = isl_qpolynomial_zero(isl_space_copy(qp->dim));
+               zero = isl_qpolynomial_zero_on_domain(isl_space_copy(qp->dim));
                isl_qpolynomial_free(qp);
                return zero;
        }
@@ -1494,42 +1530,48 @@ __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_pow(
        return pwqp;
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_zero(__isl_take isl_space *dim)
+__isl_give isl_qpolynomial *isl_qpolynomial_zero_on_domain(
+       __isl_take isl_space *dim)
 {
        if (!dim)
                return NULL;
        return isl_qpolynomial_alloc(dim, 0, isl_upoly_zero(dim->ctx));
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_one(__isl_take isl_space *dim)
+__isl_give isl_qpolynomial *isl_qpolynomial_one_on_domain(
+       __isl_take isl_space *dim)
 {
        if (!dim)
                return NULL;
        return isl_qpolynomial_alloc(dim, 0, isl_upoly_one(dim->ctx));
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_infty(__isl_take isl_space *dim)
+__isl_give isl_qpolynomial *isl_qpolynomial_infty_on_domain(
+       __isl_take isl_space *dim)
 {
        if (!dim)
                return NULL;
        return isl_qpolynomial_alloc(dim, 0, isl_upoly_infty(dim->ctx));
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_neginfty(__isl_take isl_space *dim)
+__isl_give isl_qpolynomial *isl_qpolynomial_neginfty_on_domain(
+       __isl_take isl_space *dim)
 {
        if (!dim)
                return NULL;
        return isl_qpolynomial_alloc(dim, 0, isl_upoly_neginfty(dim->ctx));
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_nan(__isl_take isl_space *dim)
+__isl_give isl_qpolynomial *isl_qpolynomial_nan_on_domain(
+       __isl_take isl_space *dim)
 {
        if (!dim)
                return NULL;
        return isl_qpolynomial_alloc(dim, 0, isl_upoly_nan(dim->ctx));
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_cst(__isl_take isl_space *dim,
+__isl_give isl_qpolynomial *isl_qpolynomial_cst_on_domain(
+       __isl_take isl_space *dim,
        isl_int v)
 {
        struct isl_qpolynomial *qp;
@@ -1738,8 +1780,8 @@ void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d)
        upoly_update_den(qp->upoly, d);
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_var_pow(__isl_take isl_space *dim,
-       int pos, int power)
+__isl_give isl_qpolynomial *isl_qpolynomial_var_pow_on_domain(
+       __isl_take isl_space *dim, int pos, int power)
 {
        struct isl_ctx *ctx;
 
@@ -1751,7 +1793,7 @@ __isl_give isl_qpolynomial *isl_qpolynomial_var_pow(__isl_take isl_space *dim,
        return isl_qpolynomial_alloc(dim, 0, isl_upoly_var_pow(ctx, pos, power));
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_var(__isl_take isl_space *dim,
+__isl_give isl_qpolynomial *isl_qpolynomial_var_on_domain(__isl_take isl_space *dim,
        enum isl_dim_type type, unsigned pos)
 {
        if (!dim)
@@ -1763,7 +1805,7 @@ __isl_give isl_qpolynomial *isl_qpolynomial_var(__isl_take isl_space *dim,
        if (type == isl_dim_set)
                pos += isl_space_dim(dim, isl_dim_param);
 
-       return isl_qpolynomial_var_pow(dim, pos, 1);
+       return isl_qpolynomial_var_pow_on_domain(dim, pos, 1);
 error:
        isl_space_free(dim);
        return NULL;
@@ -2084,59 +2126,8 @@ error:
        return NULL;
 }
 
-/* Assumes each div only depends on earlier divs.
- */
-__isl_give isl_qpolynomial *isl_qpolynomial_div_pow(__isl_take isl_div *div,
-       int power)
-{
-       struct isl_qpolynomial *qp = NULL;
-       struct isl_upoly_rec *rec;
-       struct isl_upoly_cst *cst;
-       int i, d;
-       int pos;
-
-       if (!div)
-               return NULL;
-
-       d = div->line - div->bmap->div;
-
-       pos = isl_space_dim(div->bmap->dim, isl_dim_all) + d;
-       rec = isl_upoly_alloc_rec(div->ctx, pos, 1 + power);
-       qp = isl_qpolynomial_alloc(isl_basic_map_get_space(div->bmap),
-                                  div->bmap->n_div, &rec->up);
-       if (!qp)
-               goto error;
-
-       for (i = 0; i < div->bmap->n_div; ++i)
-               isl_seq_cpy(qp->div->row[i], div->bmap->div[i], qp->div->n_col);
-
-       for (i = 0; i < 1 + power; ++i) {
-               rec->p[i] = isl_upoly_zero(div->ctx);
-               if (!rec->p[i])
-                       goto error;
-               rec->n++;
-       }
-       cst = isl_upoly_as_cst(rec->p[power]);
-       isl_int_set_si(cst->n, 1);
-
-       isl_div_free(div);
-
-       qp = reduce_divs(qp);
-
-       return qp;
-error:
-       isl_qpolynomial_free(qp);
-       isl_div_free(div);
-       return NULL;
-}
-
-__isl_give isl_qpolynomial *isl_qpolynomial_div(__isl_take isl_div *div)
-{
-       return isl_qpolynomial_div_pow(div, 1);
-}
-
-__isl_give isl_qpolynomial *isl_qpolynomial_rat_cst(__isl_take isl_space *dim,
-       const isl_int n, const isl_int d)
+__isl_give isl_qpolynomial *isl_qpolynomial_rat_cst_on_domain(
+       __isl_take isl_space *dim, const isl_int n, const isl_int d)
 {
        struct isl_qpolynomial *qp;
        struct isl_upoly_cst *cst;
@@ -2208,17 +2199,17 @@ int isl_qpolynomial_involves_dims(__isl_keep isl_qpolynomial *qp,
        if (n == 0)
                return 0;
 
-       isl_assert(qp->dim->ctx, first + n <= isl_space_dim(qp->dim, type),
-                       return -1);
+       isl_assert(qp->dim->ctx,
+                   first + n <= isl_qpolynomial_dim(qp, type), return -1);
        isl_assert(qp->dim->ctx, type == isl_dim_param ||
-                                type == isl_dim_set, return -1);
+                                type == isl_dim_in, return -1);
 
        active = isl_calloc_array(qp->dim->ctx, int,
                                        isl_space_dim(qp->dim, isl_dim_all));
        if (set_active(qp, active) < 0)
                goto error;
 
-       if (type == isl_dim_set)
+       if (type == isl_dim_in)
                first += isl_space_dim(qp->dim, isl_dim_param);
        for (i = 0; i < n; ++i)
                if (active[first + i]) {
@@ -2374,6 +2365,12 @@ __isl_give isl_qpolynomial *isl_qpolynomial_drop_dims(
 {
        if (!qp)
                return NULL;
+       if (type == isl_dim_out)
+               isl_die(qp->dim->ctx, isl_error_invalid,
+                       "cannot drop output/set dimension",
+                       goto error);
+       if (type == isl_dim_in)
+               type = isl_dim_set;
        if (n == 0 && !isl_space_is_named_or_nested(qp->dim, type))
                return qp;
 
@@ -2417,18 +2414,18 @@ __isl_give isl_qpolynomial *isl_qpolynomial_project_domain_on_params(
        unsigned n;
        int involves;
 
-       n = isl_qpolynomial_dim(qp, isl_dim_set);
-       involves = isl_qpolynomial_involves_dims(qp, isl_dim_set, 0, n);
+       n = isl_qpolynomial_dim(qp, isl_dim_in);
+       involves = isl_qpolynomial_involves_dims(qp, isl_dim_in, 0, n);
        if (involves < 0)
                return isl_qpolynomial_free(qp);
        if (involves)
                isl_die(isl_qpolynomial_get_ctx(qp), isl_error_invalid,
                        "polynomial involves some of the domain dimensions",
                        return isl_qpolynomial_free(qp));
-       qp = isl_qpolynomial_drop_dims(qp, isl_dim_set, 0, n);
-       space = isl_qpolynomial_get_space(qp);
+       qp = isl_qpolynomial_drop_dims(qp, isl_dim_in, 0, n);
+       space = isl_qpolynomial_get_domain_space(qp);
        space = isl_space_params(space);
-       qp = isl_qpolynomial_reset_space(qp, space);
+       qp = isl_qpolynomial_reset_domain_space(qp, space);
        return qp;
 }
 
@@ -2506,7 +2503,7 @@ __isl_give isl_qpolynomial *isl_qpolynomial_substitute_equalities(
        if (!qp || !eq)
                goto error;
        if (qp->div->n_row > 0)
-               eq = isl_basic_set_add(eq, isl_dim_set, qp->div->n_row);
+               eq = isl_basic_set_add_dims(eq, isl_dim_set, qp->div->n_row);
        return isl_qpolynomial_substitute_equalities_lifted(qp, eq);
 error:
        isl_basic_set_free(eq);
@@ -2570,6 +2567,15 @@ error:
        return NULL;
 }
 
+__isl_give isl_qpolynomial *isl_qpolynomial_gist_params(
+       __isl_take isl_qpolynomial *qp, __isl_take isl_set *context)
+{
+       isl_space *space = isl_qpolynomial_get_domain_space(qp);
+       isl_set *dom_context = isl_set_universe(space);
+       dom_context = isl_set_intersect_params(dom_context, context);
+       return isl_qpolynomial_gist(qp, dom_context);
+}
+
 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_qpolynomial(
        __isl_take isl_qpolynomial *qp)
 {
@@ -2583,7 +2589,7 @@ __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_qpolynomial(
                return isl_pw_qpolynomial_zero(dim);
        }
 
-       dom = isl_set_universe(isl_qpolynomial_get_space(qp));
+       dom = isl_set_universe(isl_qpolynomial_get_domain_space(qp));
        return isl_pw_qpolynomial_alloc(dom, qp);
 }
 
@@ -2599,6 +2605,10 @@ __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_qpolynomial(
 #define IS_ZERO is_zero
 #undef FIELD
 #define FIELD qp
+#undef DEFAULT_IS_ZERO
+#define DEFAULT_IS_ZERO 1
+
+#define NO_PULLBACK
 
 #include <isl_pw_templ.c>
 
@@ -2608,6 +2618,7 @@ __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_qpolynomial(
 #define PART isl_pw_qpolynomial
 #undef PARTS
 #define PARTS pw_qpolynomial
+#define ALIGN_DOMAIN
 
 #include <isl_union_templ.c>
 
@@ -2625,6 +2636,13 @@ int isl_pw_qpolynomial_is_one(__isl_keep isl_pw_qpolynomial *pwqp)
        return isl_qpolynomial_is_one(pwqp->p[0].qp);
 }
 
+__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add(
+       __isl_take isl_pw_qpolynomial *pwqp1,
+       __isl_take isl_pw_qpolynomial *pwqp2)
+{
+       return isl_pw_qpolynomial_union_add_(pwqp1, pwqp2);
+}
+
 __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul(
        __isl_take isl_pw_qpolynomial *pwqp1,
        __isl_take isl_pw_qpolynomial *pwqp2)
@@ -2869,6 +2887,14 @@ __isl_give isl_qpolynomial *isl_qpolynomial_insert_dims(
        unsigned g_pos;
        int *exp;
 
+       if (!qp)
+               return NULL;
+       if (type == isl_dim_out)
+               isl_die(qp->div->ctx, isl_error_invalid,
+                       "cannot insert output/set dimensions",
+                       goto error);
+       if (type == isl_dim_in)
+               type = isl_dim_set;
        if (n == 0 && !isl_space_is_named_or_nested(qp->dim, type))
                return qp;
 
@@ -2976,6 +3002,15 @@ __isl_give isl_qpolynomial *isl_qpolynomial_move_dims(
        if (!qp)
                return NULL;
 
+       if (dst_type == isl_dim_out || src_type == isl_dim_out)
+               isl_die(qp->dim->ctx, isl_error_invalid,
+                       "cannot move output/set dimension",
+                       goto error);
+       if (dst_type == isl_dim_in)
+               dst_type = isl_dim_set;
+       if (src_type == isl_dim_in)
+               src_type = isl_dim_set;
+
        isl_assert(qp->dim->ctx, src_pos + n <= isl_space_dim(qp->dim, src_type),
                goto error);
 
@@ -3016,6 +3051,7 @@ __isl_give isl_qpolynomial *isl_qpolynomial_from_affine(__isl_take isl_space *di
 {
        struct isl_upoly *up;
 
+       dim = isl_space_domain(dim);
        if (!dim)
                return NULL;
 
@@ -3038,7 +3074,7 @@ __isl_give isl_qpolynomial *isl_qpolynomial_from_aff(__isl_take isl_aff *aff)
        up = isl_upoly_from_affine(ctx, aff->v->el + 1, aff->v->el[0],
                                    aff->v->size - 1);
 
-       qp = isl_qpolynomial_alloc(isl_aff_get_space(aff),
+       qp = isl_qpolynomial_alloc(isl_aff_get_domain_space(aff),
                                    aff->ls->div->n_row, up);
        if (!qp)
                goto error;
@@ -3110,6 +3146,14 @@ __isl_give isl_qpolynomial *isl_qpolynomial_substitute(
        qp = isl_qpolynomial_cow(qp);
        if (!qp)
                return NULL;
+
+       if (type == isl_dim_out)
+               isl_die(qp->dim->ctx, isl_error_invalid,
+                       "cannot substitute output/set dimension",
+                       goto error);
+       if (type == isl_dim_in)
+               type = isl_dim_set;
+
        for (i = 0; i < n; ++i)
                if (!subs[i])
                        goto error;
@@ -3171,7 +3215,7 @@ int isl_qpolynomial_as_polynomial_on_domain(__isl_keep isl_qpolynomial *qp,
        dim = isl_space_add_dims(dim, isl_dim_set, qp->div->n_row);
        poly = isl_qpolynomial_alloc(dim, 0, isl_upoly_copy(qp->upoly));
        bset = isl_basic_set_copy(bset);
-       bset = isl_basic_set_add(bset, isl_dim_set, qp->div->n_row);
+       bset = isl_basic_set_add_dims(bset, isl_dim_set, qp->div->n_row);
        bset = add_div_constraints(bset, div);
 
        return fn(bset, poly, user);
@@ -3289,6 +3333,13 @@ __isl_give isl_qpolynomial *isl_qpolynomial_coeff(
        if (!qp)
                return NULL;
 
+       if (type == isl_dim_out)
+               isl_die(qp->div->ctx, isl_error_invalid,
+                       "output/set dimension does not have a coefficient",
+                       return NULL);
+       if (type == isl_dim_in)
+               type = isl_dim_set;
+
        isl_assert(qp->div->ctx, t_pos < isl_space_dim(qp->dim, type),
                        return NULL);
 
@@ -3371,7 +3422,7 @@ __isl_give isl_qpolynomial *isl_qpolynomial_homogenize(
        if (deg < -1)
                goto error;
 
-       poly = isl_qpolynomial_insert_dims(poly, isl_dim_set, 0, 1);
+       poly = isl_qpolynomial_insert_dims(poly, isl_dim_in, 0, 1);
        poly = isl_qpolynomial_cow(poly);
        if (!poly)
                goto error;
@@ -3433,7 +3484,7 @@ __isl_give isl_term *isl_term_dup(__isl_keep isl_term *term)
        isl_term *dup;
        unsigned total;
 
-       if (term)
+       if (!term)
                return NULL;
 
        total = isl_space_dim(term->dim, isl_dim_all) + term->div->n_row;
@@ -3528,11 +3579,10 @@ int isl_term_get_exp(__isl_keep isl_term *term,
        return term->pow[pos];
 }
 
-__isl_give isl_div *isl_term_get_div(__isl_keep isl_term *term, unsigned pos)
+__isl_give isl_aff *isl_term_get_div(__isl_keep isl_term *term, unsigned pos)
 {
-       isl_basic_map *bmap;
-       unsigned total;
-       int k;
+       isl_local_space *ls;
+       isl_aff *aff;
 
        if (!term)
                return NULL;
@@ -3540,23 +3590,17 @@ __isl_give isl_div *isl_term_get_div(__isl_keep isl_term *term, unsigned pos)
        isl_assert(term->dim->ctx, pos < isl_term_dim(term, isl_dim_div),
                        return NULL);
 
-       total = term->div->n_col - term->div->n_row - 2;
-       /* No nested divs for now */
-       isl_assert(term->dim->ctx,
-               isl_seq_first_non_zero(term->div->row[pos] + 2 + total,
-                                       term->div->n_row) == -1,
-               return NULL);
+       ls = isl_local_space_alloc_div(isl_space_copy(term->dim),
+                                       isl_mat_copy(term->div));
+       aff = isl_aff_alloc(ls);
+       if (!aff)
+               return NULL;
 
-       bmap = isl_basic_map_alloc_space(isl_space_copy(term->dim), 1, 0, 0);
-       if ((k = isl_basic_map_alloc_div(bmap)) < 0)
-               goto error;
+       isl_seq_cpy(aff->v->el, term->div->row[pos], aff->v->size);
 
-       isl_seq_cpy(bmap->div[k], term->div->row[pos], 2 + total);
+       aff = isl_aff_normalize(aff);
 
-       return isl_basic_map_div(bmap, k);
-error:
-       isl_basic_map_free(bmap);
-       return NULL;
+       return aff;
 }
 
 __isl_give isl_term *isl_upoly_foreach_term(__isl_keep struct isl_upoly *up,
@@ -3814,8 +3858,10 @@ __isl_give isl_qpolynomial *isl_qpolynomial_opt_on_domain(
        if (isl_set_foreach_point(set, opt_fn, &data) < 0)
                goto error;
 
-       if (data.first)
-               data.opt = isl_qpolynomial_zero(isl_qpolynomial_get_space(qp));
+       if (data.first) {
+               isl_space *space = isl_qpolynomial_get_domain_space(qp);
+               data.opt = isl_qpolynomial_zero_on_domain(space);
+       }
 
        isl_set_free(set);
        isl_qpolynomial_free(qp);
@@ -3827,14 +3873,14 @@ error:
        return NULL;
 }
 
-__isl_give isl_qpolynomial *isl_qpolynomial_morph(__isl_take isl_qpolynomial *qp,
-       __isl_take isl_morph *morph)
+__isl_give isl_qpolynomial *isl_qpolynomial_morph_domain(
+       __isl_take isl_qpolynomial *qp, __isl_take isl_morph *morph)
 {
        int i;
        int n_sub;
        isl_ctx *ctx;
        struct isl_upoly **subs;
-       isl_mat *mat;
+       isl_mat *mat, *diag;
 
        qp = isl_qpolynomial_cow(qp);
        if (!qp || !morph)
@@ -3864,8 +3910,10 @@ __isl_give isl_qpolynomial *isl_qpolynomial_morph(__isl_take isl_qpolynomial *qp
                isl_upoly_free(subs[i]);
        free(subs);
 
-       mat = isl_mat_diagonal(isl_mat_identity(ctx, 1), isl_mat_copy(morph->inv));
-       mat = isl_mat_diagonal(mat, isl_mat_identity(ctx, qp->div->n_row));
+       diag = isl_mat_diag(ctx, 1, morph->inv->row[0][0]);
+       mat = isl_mat_diagonal(diag, isl_mat_copy(morph->inv));
+       diag = isl_mat_diag(ctx, qp->div->n_row, morph->inv->row[0][0]);
+       mat = isl_mat_diagonal(mat, diag);
        qp->div = isl_mat_product(qp->div, mat);
        isl_space_free(qp->dim);
        qp->dim = isl_space_copy(morph->ran->dim);
@@ -3908,52 +3956,11 @@ error:
        return NULL;
 }
 
-__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub(
-       __isl_take isl_union_pw_qpolynomial *upwqp1,
-       __isl_take isl_union_pw_qpolynomial *upwqp2)
-{
-       return isl_union_pw_qpolynomial_add(upwqp1,
-                                       isl_union_pw_qpolynomial_neg(upwqp2));
-}
-
-static int mul_entry(void **entry, void *user)
-{
-       struct isl_union_pw_qpolynomial_match_bin_data *data = user;
-       uint32_t hash;
-       struct isl_hash_table_entry *entry2;
-       isl_pw_qpolynomial *pwpq = *entry;
-       int empty;
-
-       hash = isl_space_get_hash(pwpq->dim);
-       entry2 = isl_hash_table_find(data->u2->dim->ctx, &data->u2->table,
-                                    hash, &has_dim, pwpq->dim, 0);
-       if (!entry2)
-               return 0;
-
-       pwpq = isl_pw_qpolynomial_copy(pwpq);
-       pwpq = isl_pw_qpolynomial_mul(pwpq,
-                                     isl_pw_qpolynomial_copy(entry2->data));
-
-       empty = isl_pw_qpolynomial_is_zero(pwpq);
-       if (empty < 0) {
-               isl_pw_qpolynomial_free(pwpq);
-               return -1;
-       }
-       if (empty) {
-               isl_pw_qpolynomial_free(pwpq);
-               return 0;
-       }
-
-       data->res = isl_union_pw_qpolynomial_add_pw_qpolynomial(data->res, pwpq);
-
-       return 0;
-}
-
 __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul(
        __isl_take isl_union_pw_qpolynomial *upwqp1,
        __isl_take isl_union_pw_qpolynomial *upwqp2)
 {
-       return match_bin_op(upwqp1, upwqp2, &mul_entry);
+       return match_bin_op(upwqp1, upwqp2, &isl_pw_qpolynomial_mul);
 }
 
 /* Reorder the columns of the given div definitions according to the
@@ -3993,7 +4000,7 @@ error:
 
 /* Reorder the dimension of "qp" according to the given reordering.
  */
-__isl_give isl_qpolynomial *isl_qpolynomial_realign(
+__isl_give isl_qpolynomial *isl_qpolynomial_realign_domain(
        __isl_take isl_qpolynomial *qp, __isl_take isl_reordering *r)
 {
        qp = isl_qpolynomial_cow(qp);
@@ -4012,7 +4019,7 @@ __isl_give isl_qpolynomial *isl_qpolynomial_realign(
        if (!qp->upoly)
                goto error;
 
-       qp = isl_qpolynomial_reset_space(qp, isl_space_copy(r->dim));
+       qp = isl_qpolynomial_reset_domain_space(qp, isl_space_copy(r->dim));
 
        isl_reordering_free(r);
        return qp;
@@ -4037,8 +4044,8 @@ __isl_give isl_qpolynomial *isl_qpolynomial_align_params(
                                        0, isl_space_dim(model, isl_dim_out));
                exp = isl_parameter_alignment_reordering(qp->dim, model);
                exp = isl_reordering_extend_space(exp,
-                                               isl_qpolynomial_get_space(qp));
-               qp = isl_qpolynomial_realign(qp, exp);
+                                       isl_qpolynomial_get_domain_space(qp));
+               qp = isl_qpolynomial_realign_domain(qp, exp);
        }
 
        isl_space_free(model);
@@ -4287,11 +4294,11 @@ static __isl_give isl_pw_qpolynomial *constant_on_domain(
        bset = isl_basic_set_params(bset);
        dim = isl_basic_set_get_space(bset);
        if (cst < 0)
-               qp = isl_qpolynomial_infty(dim);
+               qp = isl_qpolynomial_infty_on_domain(dim);
        else if (cst == 0)
-               qp = isl_qpolynomial_zero(dim);
+               qp = isl_qpolynomial_zero_on_domain(dim);
        else
-               qp = isl_qpolynomial_one(dim);
+               qp = isl_qpolynomial_one_on_domain(dim);
        return isl_pw_qpolynomial_alloc(isl_set_from_basic_set(bset), qp);
 }
 
@@ -4328,7 +4335,7 @@ static __isl_give isl_pw_qpolynomial *compressed_multiplicative_call(
        dim = isl_basic_set_get_space(bset);
        dim = isl_space_domain(dim);
        set = isl_set_universe(isl_space_copy(dim));
-       qp = isl_qpolynomial_one(dim);
+       qp = isl_qpolynomial_one_on_domain(dim);
        pwqp = isl_pw_qpolynomial_alloc(set, qp);
 
        bset = isl_morph_basic_set(isl_morph_copy(f->morph), bset);
@@ -4376,7 +4383,6 @@ __isl_give isl_pw_qpolynomial *isl_basic_set_multiplicative_call(
        int bounded;
        isl_morph *morph;
        isl_pw_qpolynomial *pwqp;
-       unsigned orig_nvar, final_nvar;
 
        if (!bset)
                return NULL;
@@ -4384,9 +4390,7 @@ __isl_give isl_pw_qpolynomial *isl_basic_set_multiplicative_call(
        if (isl_basic_set_plain_is_empty(bset))
                return constant_on_domain(bset, 0);
 
-       orig_nvar = isl_basic_set_dim(bset, isl_dim_set);
-
-       if (orig_nvar == 0)
+       if (isl_basic_set_dim(bset, isl_dim_set) == 0)
                return constant_on_domain(bset, 1);
 
        bounded = isl_basic_set_is_bounded(bset);
@@ -4401,15 +4405,13 @@ __isl_give isl_pw_qpolynomial *isl_basic_set_multiplicative_call(
        morph = isl_basic_set_full_compression(bset);
        bset = isl_morph_basic_set(isl_morph_copy(morph), bset);
 
-       final_nvar = isl_basic_set_dim(bset, isl_dim_set);
-
        pwqp = compressed_multiplicative_call(bset, fn);
 
-       morph = isl_morph_remove_dom_dims(morph, isl_dim_set, 0, orig_nvar);
-       morph = isl_morph_remove_ran_dims(morph, isl_dim_set, 0, final_nvar);
+       morph = isl_morph_dom_params(morph);
+       morph = isl_morph_ran_params(morph);
        morph = isl_morph_inverse(morph);
 
-       pwqp = isl_pw_qpolynomial_morph(pwqp, morph);
+       pwqp = isl_pw_qpolynomial_morph_domain(pwqp, morph);
 
        return pwqp;
 error:
@@ -4702,9 +4704,7 @@ __isl_give isl_basic_map *isl_basic_map_from_qpolynomial(
        if (!aff)
                goto error;
        dim = isl_qpolynomial_get_space(qp);
-       dim = isl_space_from_domain(dim);
        pos = 1 + isl_space_offset(dim, isl_dim_out);
-       dim = isl_space_add_dims(dim, isl_dim_out, 1);
        n_div = qp->div->n_row;
        bmap = isl_basic_map_alloc_space(dim, n_div, 1, 2 * n_div);