return NULL;
}
+/* Remove common factor of non-constant terms and denominator.
+ */
+static void normalize_div(__isl_keep isl_qpolynomial *qp, int div)
+{
+ isl_ctx *ctx = qp->div->ctx;
+ unsigned total = qp->div->n_col - 2;
+
+ isl_seq_gcd(qp->div->row[div] + 2, total, &ctx->normalize_gcd);
+ isl_int_gcd(ctx->normalize_gcd,
+ ctx->normalize_gcd, qp->div->row[div][0]);
+ if (isl_int_is_one(ctx->normalize_gcd))
+ return;
+
+ isl_seq_scale_down(qp->div->row[div] + 2, qp->div->row[div] + 2,
+ ctx->normalize_gcd, total);
+ isl_int_divexact(qp->div->row[div][0], qp->div->row[div][0],
+ ctx->normalize_gcd);
+ isl_int_fdiv_q(qp->div->row[div][1], qp->div->row[div][1],
+ ctx->normalize_gcd);
+}
+
__isl_give isl_qpolynomial *isl_qpolynomial_div_pow(__isl_take isl_div *div,
int power)
{
if (!qp)
goto error;
- for (i = 0; i < div->bmap->n_div; ++i)
+ for (i = 0; i < div->bmap->n_div; ++i) {
isl_seq_cpy(qp->div->row[i], div->bmap->div[i], qp->div->n_col);
+ normalize_div(qp, i);
+ }
for (i = 0; i < 1 + power; ++i) {
rec->p[i] = isl_upoly_zero(div->ctx);
return up;
}
-/* Remove common factor of non-constant terms and denominator.
- */
-static void normalize_div(__isl_keep isl_qpolynomial *qp, int div)
-{
- isl_ctx *ctx = qp->div->ctx;
- unsigned total = qp->div->n_col - 2;
-
- isl_seq_gcd(qp->div->row[div] + 2, total, &ctx->normalize_gcd);
- isl_int_gcd(ctx->normalize_gcd,
- ctx->normalize_gcd, qp->div->row[div][0]);
- if (isl_int_is_one(ctx->normalize_gcd))
- return;
-
- isl_seq_scale_down(qp->div->row[div] + 2, qp->div->row[div] + 2,
- ctx->normalize_gcd, total);
- isl_int_divexact(qp->div->row[div][0], qp->div->row[div][0],
- ctx->normalize_gcd);
- isl_int_fdiv_q(qp->div->row[div][1], qp->div->row[div][1],
- ctx->normalize_gcd);
-}
-
/* Replace the integer division identified by "div" by the polynomial "s".
* The integer division is assumed not to appear in the definition
* of any other integer divisions.
return NULL;
}
+static __isl_give isl_basic_set *add_div_constraints(
+ __isl_take isl_basic_set *bset, __isl_take isl_mat *div)
+{
+ int i;
+ unsigned total;
+
+ if (!bset || !div)
+ goto error;
+
+ bset = isl_basic_set_extend_constraints(bset, 0, 2 * div->n_row);
+ if (!bset)
+ goto error;
+ total = isl_basic_set_total_dim(bset);
+ for (i = 0; i < div->n_row; ++i)
+ if (isl_basic_set_add_div_constraints_var(bset,
+ total - div->n_row + i, div->row[i]) < 0)
+ goto error;
+
+ isl_mat_free(div);
+ return bset;
+error:
+ isl_mat_free(div);
+ isl_basic_set_free(bset);
+ return NULL;
+}
+
+/* Look for equalities among the variables shared by context and qp
+ * and the integer divisions of qp, if any.
+ * The equalities are then used to eliminate variables and/or integer
+ * divisions from qp.
+ */
+__isl_give isl_qpolynomial *isl_qpolynomial_gist(
+ __isl_take isl_qpolynomial *qp, __isl_take isl_set *context)
+{
+ isl_basic_set *aff;
+
+ if (!qp)
+ goto error;
+ if (qp->div->n_row > 0) {
+ isl_basic_set *bset;
+ context = isl_set_add_dims(context, isl_dim_set,
+ qp->div->n_row);
+ bset = isl_basic_set_universe(isl_set_get_dim(context));
+ bset = add_div_constraints(bset, isl_mat_copy(qp->div));
+ context = isl_set_intersect(context,
+ isl_set_from_basic_set(bset));
+ }
+
+ aff = isl_set_affine_hull(context);
+ return isl_qpolynomial_substitute_equalities(qp, aff);
+error:
+ isl_qpolynomial_free(qp);
+ isl_set_free(context);
+ return NULL;
+}
+
#undef PW
#define PW isl_pw_qpolynomial
#undef EL
return NULL;
}
-__isl_give isl_basic_set *add_div_constraints(__isl_take isl_basic_set *bset,
- __isl_take isl_mat *div)
-{
- int i;
- unsigned total;
-
- if (!bset || !div)
- goto error;
-
- bset = isl_basic_set_extend_constraints(bset, 0, 2 * div->n_row);
- if (!bset)
- goto error;
- total = isl_basic_set_total_dim(bset);
- for (i = 0; i < div->n_row; ++i)
- if (isl_basic_set_add_div_constraints_var(bset,
- total - div->n_row + i, div->row[i]) < 0)
- goto error;
-
- isl_mat_free(div);
- return bset;
-error:
- isl_mat_free(div);
- isl_basic_set_free(bset);
- return NULL;
-}
-
/* Extend "bset" with extra set dimensions for each integer division
* in "qp" and then call "fn" with the extended bset and the polynomial
* that results from replacing each of the integer divisions by the