RewriteResponse ArithRewriter::postRewritePlus(TNode t){
Assert(t.getKind() == kind::PLUS);
+ Assert(t.getNumChildren() > 1);
+ Rational rational;
+ RealAlgebraicNumber ran;
std::vector<Monomial> monomials;
std::vector<Polynomial> polynomials;
- for(TNode::iterator i = t.begin(), end = t.end(); i != end; ++i){
- TNode curr = *i;
- if(Monomial::isMember(curr)){
- monomials.push_back(Monomial::parseMonomial(curr));
- }else{
- polynomials.push_back(Polynomial::parsePolynomial(curr));
+ for (const auto& child : t)
+ {
+ if (child.isConst())
+ {
+ if (child.getConst<Rational>().isZero())
+ {
+ continue;
+ }
+ rational += child.getConst<Rational>();
+ }
+ else if (child.getKind() == Kind::REAL_ALGEBRAIC_NUMBER)
+ {
+ ran += child.getOperator().getConst<RealAlgebraicNumber>();
+ }
+ else if (Monomial::isMember(child))
+ {
+ monomials.emplace_back(Monomial::parseMonomial(child));
+ }
+ else
+ {
+ polynomials.emplace_back(Polynomial::parsePolynomial(child));
}
}
if(!monomials.empty()){
Monomial::sort(monomials);
Monomial::combineAdjacentMonomials(monomials);
- polynomials.push_back(Polynomial::mkPolynomial(monomials));
+ polynomials.emplace_back(Polynomial::mkPolynomial(monomials));
+ }
+ if (!rational.isZero())
+ {
+ polynomials.emplace_back(
+ Polynomial::mkPolynomial(Constant::mkConstant(rational)));
}
- Polynomial res = Polynomial::sumPolynomials(polynomials);
+ Polynomial poly = Polynomial::sumPolynomials(polynomials);
- return RewriteResponse(REWRITE_DONE, res.getNode());
+ if (isZero(ran))
+ {
+ return RewriteResponse(REWRITE_DONE, poly.getNode());
+ }
+ if (poly.containsConstant())
+ {
+ ran += RealAlgebraicNumber(poly.getHead().getConstant().getValue());
+ poly = poly.getTail();
+ }
+
+ auto* nm = NodeManager::currentNM();
+ if (poly.isConstant())
+ {
+ return RewriteResponse(REWRITE_DONE, nm->mkRealAlgebraicNumber(ran));
+ }
+ return RewriteResponse(
+ REWRITE_DONE,
+ nm->mkNode(Kind::PLUS, nm->mkRealAlgebraicNumber(ran), poly.getNode()));
}
RewriteResponse ArithRewriter::postRewriteMult(TNode t){
cvc5_add_unit_test_white(theory_arith_pow2_white theory)
cvc5_add_unit_test_white(theory_arith_white theory)
cvc5_add_unit_test_white(theory_arith_cad_white theory)
+cvc5_add_unit_test_black(theory_arith_rewriter_black theory)
cvc5_add_unit_test_white(theory_bags_normal_form_white theory)
cvc5_add_unit_test_white(theory_bags_rewriter_white theory)
cvc5_add_unit_test_white(theory_bags_type_rules_white theory)
--- /dev/null
+/******************************************************************************
+ * Top contributors (to current version):
+ * Aina Niemetz
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved. See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Black box testing of rewriter for arithmetic.
+ */
+
+#include "test_smt.h"
+#include "util/rational.h"
+#include "util/real_algebraic_number.h"
+
+namespace cvc5 {
+
+using namespace kind;
+using namespace context;
+using namespace theory;
+
+namespace test {
+
+class TestTheoryArithRewriterBlack : public TestSmt
+{
+};
+
+TEST_F(TestTheoryArithRewriterBlack, RealAlgebraicNumber)
+{
+ Trace.on("arith-rewriter");
+ {
+ RealAlgebraicNumber two({-8, 0, 0, 1}, 1, 3);
+ Node n = d_nodeManager->mkRealAlgebraicNumber(two);
+ EXPECT_EQ(n.getKind(), Kind::CONST_RATIONAL);
+ EXPECT_EQ(n.getConst<Rational>(), Rational(2));
+ }
+ {
+ RealAlgebraicNumber sqrt2({-2, 0, 1}, 1, 3);
+ Node n = d_nodeManager->mkRealAlgebraicNumber(sqrt2);
+ n = d_nodeManager->mkNode(Kind::MINUS, n, n);
+ n = d_slvEngine->getRewriter()->rewrite(n);
+ EXPECT_EQ(n.getKind(), Kind::CONST_RATIONAL);
+ EXPECT_EQ(n.getConst<Rational>(), Rational(0));
+ }
+}
+
+} // namespace test
+} // namespace cvc5