case kind::INTS_MODULUS: return rewriteIntsDivMod(t, true);
case kind::INTS_DIVISION_TOTAL:
case kind::INTS_MODULUS_TOTAL: return rewriteIntsDivModTotal(t, true);
- case kind::ABS:
- if (t[0].isConst())
- {
- const Rational& rat = t[0].getConst<Rational>();
- if (rat >= 0)
- {
- return RewriteResponse(REWRITE_DONE, t[0]);
- }
- else
- {
- return RewriteResponse(REWRITE_DONE,
- NodeManager::currentNM()->mkConstRealOrInt(
- t[0].getType(), -rat));
- }
- }
- return RewriteResponse(REWRITE_DONE, t);
+ case kind::ABS: return rewriteAbs(t);
case kind::IS_INTEGER:
case kind::TO_INTEGER: return RewriteResponse(REWRITE_DONE, t);
case kind::TO_REAL:
case kind::INTS_MODULUS: return rewriteIntsDivMod(t, false);
case kind::INTS_DIVISION_TOTAL:
case kind::INTS_MODULUS_TOTAL: return rewriteIntsDivModTotal(t, false);
- case kind::ABS:
- if (t[0].isConst())
- {
- const Rational& rat = t[0].getConst<Rational>();
- if (rat >= 0)
- {
- return RewriteResponse(REWRITE_DONE, t[0]);
- }
- else
- {
- return RewriteResponse(REWRITE_DONE,
- NodeManager::currentNM()->mkConstRealOrInt(
- t[0].getType(), -rat));
- }
- }
- return RewriteResponse(REWRITE_DONE, t);
+ case kind::ABS: return rewriteAbs(t);
case kind::TO_REAL:
case kind::CAST_TO_REAL: return RewriteResponse(REWRITE_DONE, t[0]);
case kind::TO_INTEGER: return rewriteExtIntegerOp(t);
return RewriteResponse(REWRITE_DONE, t);
}
+RewriteResponse ArithRewriter::rewriteAbs(TNode t)
+{
+ Assert(t.getKind() == Kind::ABS);
+ Assert(t.getNumChildren() == 1);
+
+ if (t[0].isConst())
+ {
+ const Rational& rat = t[0].getConst<Rational>();
+ if (rat >= 0)
+ {
+ return RewriteResponse(REWRITE_DONE, t[0]);
+ }
+ return RewriteResponse(
+ REWRITE_DONE,
+ NodeManager::currentNM()->mkConstRealOrInt(t[0].getType(), -rat));
+ }
+ if (t[0].getKind() == Kind::REAL_ALGEBRAIC_NUMBER)
+ {
+ const RealAlgebraicNumber& ran =
+ t[0].getOperator().getConst<RealAlgebraicNumber>();
+ if (ran >= RealAlgebraicNumber())
+ {
+ return RewriteResponse(REWRITE_DONE, t[0]);
+ }
+ return RewriteResponse(
+ REWRITE_DONE, NodeManager::currentNM()->mkRealAlgebraicNumber(-ran));
+ }
+ return RewriteResponse(REWRITE_DONE, t);
+}
+
RewriteResponse ArithRewriter::rewriteIntsDivMod(TNode t, bool pre)
{
NodeManager* nm = NodeManager::currentNM();
typerule TO_INTEGER ::cvc5::theory::arith::ArithOperatorTypeRule
typerule IS_INTEGER "SimpleTypeRule<RBool, AReal>"
-typerule ABS "SimpleTypeRule<RInteger, AInteger>"
+typerule ABS ::cvc5::theory::arith::ArithOperatorTypeRule
typerule INTS_DIVISION "SimpleTypeRule<RInteger, AInteger, AInteger>"
typerule INTS_MODULUS "SimpleTypeRule<RInteger, AInteger, AInteger>"
typerule DIVISIBLE "SimpleTypeRule<RBool, AInteger>"
}
}
+TEST_F(TestTheoryArithRewriterBlack, Abs)
+{
+ {
+ Node a = d_nodeManager->mkConstReal(10);
+ Node b = d_nodeManager->mkConstReal(-10);
+ Node m = d_nodeManager->mkNode(Kind::ABS, a);
+ Node n = d_nodeManager->mkNode(Kind::ABS, b);
+ m = d_slvEngine->getRewriter()->rewrite(m);
+ n = d_slvEngine->getRewriter()->rewrite(n);
+ EXPECT_EQ(m, a);
+ EXPECT_EQ(n, a);
+ }
+ {
+ Node a = d_nodeManager->mkConstReal(Rational(3,2));
+ Node b = d_nodeManager->mkConstReal(Rational(-3,2));
+ Node m = d_nodeManager->mkNode(Kind::ABS, a);
+ Node n = d_nodeManager->mkNode(Kind::ABS, b);
+ m = d_slvEngine->getRewriter()->rewrite(m);
+ n = d_slvEngine->getRewriter()->rewrite(n);
+ EXPECT_EQ(m, a);
+ EXPECT_EQ(n, a);
+ }
+ {
+ RealAlgebraicNumber msqrt2({-2, 0, 1}, -2, -1);
+ RealAlgebraicNumber sqrt2({-2, 0, 1}, 1, 2);
+ Node a = d_nodeManager->mkRealAlgebraicNumber(msqrt2);
+ Node b = d_nodeManager->mkRealAlgebraicNumber(sqrt2);
+ Node m = d_nodeManager->mkNode(Kind::ABS, a);
+ Node n = d_nodeManager->mkNode(Kind::ABS, b);
+ m = d_slvEngine->getRewriter()->rewrite(m);
+ n = d_slvEngine->getRewriter()->rewrite(n);
+ EXPECT_EQ(m, b);
+ EXPECT_EQ(n, b);
+ }
+}
+
} // namespace test
} // namespace cvc5