summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGereon Kremer <gereon.kremer@cs.rwth-aachen.de>2020-10-11 18:22:51 +0200
committerGitHub <noreply@github.com>2020-10-11 11:22:51 -0500
commit0f834b9622947ad1f6405c83a43df88c98c05c55 (patch)
tree654edff05fc2f486c72a45f015d0fe76aa784a84
parent9e481faf7dfce8f992ae6730ad49f6db335b6432 (diff)
Add conversion of poly polynomial to cvc node. (#5218)
This PR adds a new utility function to convert a poly::Polynomial back to a cvc4 Node.
-rw-r--r--src/theory/arith/nl/poly_conversion.cpp93
-rw-r--r--src/theory/arith/nl/poly_conversion.h11
2 files changed, 91 insertions, 13 deletions
diff --git a/src/theory/arith/nl/poly_conversion.cpp b/src/theory/arith/nl/poly_conversion.cpp
index 1280f9c8e..a76a781c4 100644
--- a/src/theory/arith/nl/poly_conversion.cpp
+++ b/src/theory/arith/nl/poly_conversion.cpp
@@ -211,6 +211,70 @@ poly::Polynomial as_poly_polynomial(const CVC4::Node& n,
return res;
}
+namespace {
+/**
+ * Utility class that collects the monomial terms (as nodes) from the polynomial
+ * we are converting.
+ */
+struct CollectMonomialData
+{
+ CollectMonomialData(VariableMapper& v) : d_vm(v) {}
+
+ /** Mapper from poly variables to CVC4 variables */
+ VariableMapper& d_vm;
+ /** Collections of the monomial terms */
+ std::vector<Node> d_terms;
+ /** Caches the current node manager */
+ NodeManager* d_nm = NodeManager::currentNM();
+};
+/**
+ * Callback for lp_polynomial_traverse. Assumes data is actually a
+ * CollectMonomialData object and puts the polynomial into it.
+ */
+void collect_monomials(const lp_polynomial_context_t* ctx,
+ lp_monomial_t* m,
+ void* data)
+{
+ CollectMonomialData* d = static_cast<CollectMonomialData*>(data);
+ // constant
+ Node term =
+ d->d_nm->mkConst<Rational>(poly_utils::toRational(poly::Integer(&m->a)));
+ for (std::size_t i = 0; i < m->n; ++i)
+ {
+ // variable exponent pair
+ Node var = d->d_vm(m->p[i].x);
+ if (m->p[i].d > 1)
+ {
+ Node exp = d->d_nm->mkConst<Rational>(m->p[i].d);
+ term = d->d_nm->mkNode(
+ Kind::NONLINEAR_MULT, term, d->d_nm->mkNode(Kind::POW, var, exp));
+ }
+ else
+ {
+ term = d->d_nm->mkNode(Kind::NONLINEAR_MULT, term, var);
+ }
+ }
+ d->d_terms.emplace_back(term);
+}
+} // namespace
+
+CVC4::Node as_cvc_polynomial(const poly::Polynomial& p, VariableMapper& vm)
+{
+ CollectMonomialData cmd(vm);
+ // Do the actual conversion
+ lp_polynomial_traverse(p.get_internal(), collect_monomials, &cmd);
+
+ if (cmd.d_terms.empty())
+ {
+ return cmd.d_nm->mkConst<Rational>(0);
+ }
+ if (cmd.d_terms.size() == 1)
+ {
+ return cmd.d_terms.front();
+ }
+ return cmd.d_nm->mkNode(Kind::PLUS, cmd.d_terms);
+}
+
poly::SignCondition normalize_kind(CVC4::Kind kind,
bool negated,
poly::Polynomial& lhs)
@@ -496,15 +560,15 @@ Node excluding_interval_to_lemma(const Node& variable,
if (allowNonlinearLemma)
{
Node poly = as_cvc_upolynomial(get_defining_polynomial(alg), variable);
- return nm->mkNode(
- Kind::OR,
+ return nm->mkNode(
+ Kind::OR,
nm->mkNode(Kind::DISTINCT, poly, nm->mkConst(Rational(0))),
nm->mkNode(Kind::LT,
variable,
nm->mkConst(poly_utils::toRationalBelow(lv))),
- nm->mkNode(Kind::GT,
- variable,
- nm->mkConst(poly_utils::toRationalAbove(lv))));
+ nm->mkNode(Kind::GT,
+ variable,
+ nm->mkConst(poly_utils::toRationalAbove(lv))));
}
return Node();
}
@@ -715,16 +779,19 @@ std::size_t bitsize(const poly::Value& v)
return 0;
}
-poly::IntervalAssignment getBounds(VariableMapper& vm, const BoundInference& bi) {
+poly::IntervalAssignment getBounds(VariableMapper& vm, const BoundInference& bi)
+{
poly::IntervalAssignment res;
- for (const auto& vb: bi.get()) {
+ for (const auto& vb : bi.get())
+ {
poly::Variable v = vm(vb.first);
- poly::Value l = vb.second.lower.isNull() ? poly::Value::minus_infty() : node_to_value(vb.second.lower, vb.first);
- poly::Value u = vb.second.upper.isNull() ? poly::Value::plus_infty() : node_to_value(vb.second.upper, vb.first);
- poly::Interval i(l,
- vb.second.lower_strict,
- u,
- vb.second.upper_strict);
+ poly::Value l = vb.second.lower.isNull()
+ ? poly::Value::minus_infty()
+ : node_to_value(vb.second.lower, vb.first);
+ poly::Value u = vb.second.upper.isNull()
+ ? poly::Value::plus_infty()
+ : node_to_value(vb.second.upper, vb.first);
+ poly::Interval i(l, vb.second.lower_strict, u, vb.second.upper_strict);
res.set(v, i);
}
return res;
diff --git a/src/theory/arith/nl/poly_conversion.h b/src/theory/arith/nl/poly_conversion.h
index b4d44c39d..37d816179 100644
--- a/src/theory/arith/nl/poly_conversion.h
+++ b/src/theory/arith/nl/poly_conversion.h
@@ -75,6 +75,17 @@ poly::Polynomial as_poly_polynomial(const CVC4::Node& n,
poly::Rational& denominator);
/**
+ * Constructs a node from the given polynomial.
+ *
+ * This methods does the straight-forward conversion from a polynomial into Node
+ * representation, using the given variable mapper.
+ * The resulting node is not minimized in any form (it may contain spurious
+ * multiplications with one or use NONLINEAR_MULT where regular MULT may be
+ * sufficient), so it may be sensible to rewrite it afterwards.
+ */
+CVC4::Node as_cvc_polynomial(const poly::Polynomial& p, VariableMapper& vm);
+
+/**
* Constructs a constraints (a polynomial and a sign condition) from the given
* node.
*/
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback