1#include "storm-config.h"
17void assertEquivalent(
storm::expressions::Expression const& expression, cvc5::Term
const& term, cvc5::TermManager& termManager, cvc5::Solver& solver,
18 storm::adapters::Cvc5ExpressionAdapter& adapter) {
21 cvc5::Term equivalence = termManager.mkTerm(cvc5::Kind::EQUAL, {adapter.translateExpression(expression), term});
22 solver.assertFormula(termManager.mkTerm(cvc5::Kind::NOT, {equivalence}));
23 ASSERT_TRUE(solver.checkSat().isUnsat()) <<
"Not equivalent: " << expression <<
" (" << adapter.translateExpression(expression) <<
") vs " << term;
24 solver.resetAssertions();
28TEST(Cvc5ExpressionAdapter, StormToCvc5Boolean) {
29 cvc5::TermManager termManager;
30 cvc5::Solver solver(termManager);
33 storm::adapters::Cvc5ExpressionAdapter adapter(*manager, solver);
38 cvc5::Term cvc5X = adapter.translateExpression(x);
39 cvc5::Term cvc5Y = adapter.translateExpression(y);
41 assertEquivalent(
manager->boolean(
true), termManager.mkBoolean(
true), termManager, solver, adapter);
42 assertEquivalent(
manager->boolean(
false), termManager.mkBoolean(
false), termManager, solver, adapter);
43 assertEquivalent(x && y, termManager.mkTerm(cvc5::Kind::AND, {cvc5X, cvc5Y}), termManager, solver, adapter);
44 assertEquivalent(x || y, termManager.mkTerm(cvc5::Kind::OR, {cvc5X, cvc5Y}), termManager, solver, adapter);
45 assertEquivalent(!(x && y), termManager.mkTerm(cvc5::Kind::NOT, {termManager.mkTerm(cvc5::Kind::AND, {cvc5X, cvc5Y})}), termManager, solver, adapter);
46 assertEquivalent(
storm::expressions::iff(x, y), termManager.mkTerm(cvc5::Kind::EQUAL, {cvc5X, cvc5Y}), termManager, solver, adapter);
47 assertEquivalent(
storm::expressions::implies(x, y), termManager.mkTerm(cvc5::Kind::IMPLIES, {cvc5X, cvc5Y}), termManager, solver, adapter);
50TEST(Cvc5ExpressionAdapter, StormToCvc5Integer) {
51 cvc5::TermManager termManager;
52 cvc5::Solver solver(termManager);
55 storm::adapters::Cvc5ExpressionAdapter adapter(*manager, solver);
60 cvc5::Term cvc5X = adapter.translateExpression(x);
61 cvc5::Term cvc5Y = adapter.translateExpression(y);
63 assertEquivalent(
manager->integer(0), termManager.mkInteger(0), termManager, solver, adapter);
64 assertEquivalent(
manager->integer(-13), termManager.mkInteger(-13), termManager, solver, adapter);
65 assertEquivalent(x + y, termManager.mkTerm(cvc5::Kind::ADD, {cvc5X, cvc5Y}), termManager, solver, adapter);
66 assertEquivalent(x - y, termManager.mkTerm(cvc5::Kind::SUB, {cvc5X, cvc5Y}), termManager, solver, adapter);
67 assertEquivalent(-x, termManager.mkTerm(cvc5::Kind::NEG, {cvc5X}), termManager, solver, adapter);
68 assertEquivalent(x * y, termManager.mkTerm(cvc5::Kind::MULT, {cvc5X, cvc5Y}), termManager, solver, adapter);
69 assertEquivalent(x + y < -y,
70 termManager.mkTerm(cvc5::Kind::LT, {termManager.mkTerm(cvc5::Kind::ADD, {cvc5X, cvc5Y}), termManager.mkTerm(cvc5::Kind::NEG, {cvc5Y})}),
71 termManager, solver, adapter);
72 assertEquivalent(
storm::expressions::pow(x,
manager->integer(2),
true), termManager.mkTerm(cvc5::Kind::POW, {cvc5X, termManager.mkInteger(2)}), termManager,
76TEST(Cvc5ExpressionAdapter, StormToCvc5Real) {
77 cvc5::TermManager termManager;
78 cvc5::Solver solver(termManager);
81 storm::adapters::Cvc5ExpressionAdapter adapter(*manager, solver);
86 cvc5::Term cvc5X = adapter.translateExpression(x);
87 cvc5::Term cvc5Y = adapter.translateExpression(y);
89 assertEquivalent(
manager->rational(storm::RationalNumber(1, 2)), termManager.mkReal(1, 2), termManager, solver, adapter);
90 assertEquivalent(
manager->rational(storm::RationalNumber(-3, 4)), termManager.mkReal(-3, 4), termManager, solver, adapter);
91 assertEquivalent(x + y, termManager.mkTerm(cvc5::Kind::ADD, {cvc5X, cvc5Y}), termManager, solver, adapter);
92 assertEquivalent(x - y, termManager.mkTerm(cvc5::Kind::SUB, {cvc5X, cvc5Y}), termManager, solver, adapter);
93 assertEquivalent(-x, termManager.mkTerm(cvc5::Kind::NEG, {cvc5X}), termManager, solver, adapter);
94 assertEquivalent(x * y, termManager.mkTerm(cvc5::Kind::MULT, {cvc5X, cvc5Y}), termManager, solver, adapter);
95 assertEquivalent(x / y, termManager.mkTerm(cvc5::Kind::DIVISION, {cvc5X, cvc5Y}), termManager, solver, adapter);
100TEST(Cvc5ExpressionAdapter, StormToCvc5MixedNumericalTypes) {
101 cvc5::TermManager termManager;
102 cvc5::Solver solver(termManager);
105 storm::adapters::Cvc5ExpressionAdapter adapter(*manager, solver);
110 cvc5::Term cvc5IntVar = adapter.translateExpression(intVar);
111 cvc5::Term cvc5RealVar = adapter.translateExpression(realVar);
112 cvc5::Term cvc5ToReal = termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar});
115 assertEquivalent(intVar / realVar, termManager.mkTerm(cvc5::Kind::DIVISION, {cvc5ToReal, cvc5RealVar}), termManager, solver, adapter);
119 cvc5::Term cvc5IntVar2 = adapter.translateExpression(intVar2);
120 assertEquivalent(intVar / intVar2, termManager.mkTerm(cvc5::Kind::DIVISION, {cvc5ToReal, termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar2})}),
121 termManager, solver, adapter);
126 cvc5::Term cvc5IntVar3 = adapter.translateExpression(intVar3);
127 assertEquivalent(intVar / intVar2 + intVar3 ==
manager->integer(0),
128 termManager.mkTerm(cvc5::Kind::EQUAL,
129 {termManager.mkTerm(cvc5::Kind::ADD,
130 {termManager.mkTerm(cvc5::Kind::DIVISION, {termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar}),
131 termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar2})}),
132 termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar3})}),
133 termManager.mkReal(0)}),
134 termManager, solver, adapter);
141 {termManager.mkTerm(cvc5::Kind::LEQ, {termManager.mkTerm(cvc5::Kind::DIVISION, {termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar}),
142 termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar2})}),
143 termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar3})}),
144 termManager.mkTerm(cvc5::Kind::DIVISION,
145 {termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar}), termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar2})}),
146 termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5IntVar3})}),
147 termManager, solver, adapter);
150TEST(Cvc5ExpressionAdapter, StormToCvc5FloorAndCeil) {
151 cvc5::TermManager termManager;
152 cvc5::Solver solver(termManager);
155 storm::adapters::Cvc5ExpressionAdapter adapter(*manager, solver);
158 cvc5::Term cvc5X = adapter.translateExpression(x);
164 solver.assertFormula(termManager.mkTerm(cvc5::Kind::EQUAL, {cvc5X, termManager.mkReal(7, 3)}));
165 solver.assertFormula(termManager.mkTerm(cvc5::Kind::EQUAL, {cvc5Floor, termManager.mkInteger(2)}));
166 solver.assertFormula(termManager.mkTerm(cvc5::Kind::EQUAL, {cvc5Ceil, termManager.mkInteger(3)}));
167 ASSERT_TRUE(solver.checkSat().isSat());
170 assertEquivalent(
storm::expressions::floor(x), termManager.mkTerm(cvc5::Kind::TO_INTEGER, {cvc5X}), termManager, solver, adapter);
172 termManager.mkTerm(cvc5::Kind::NEG, {termManager.mkTerm(cvc5::Kind::TO_INTEGER, {termManager.mkTerm(cvc5::Kind::NEG, {cvc5X})})}),
173 termManager, solver, adapter);
177 cvc5::Term cvc5IntVar = adapter.translateExpression(intVar);
182TEST(Cvc5ExpressionAdapter, StormToCvc5IfThenElse) {
183 cvc5::TermManager termManager;
184 cvc5::Solver solver(termManager);
187 storm::adapters::Cvc5ExpressionAdapter adapter(*manager, solver);
193 cvc5::Term cvc5X = adapter.translateExpression(x);
194 cvc5::Term cvc5Y = adapter.translateExpression(y);
195 cvc5::Term cvc5Z = adapter.translateExpression(z);
197 assertEquivalent(
storm::expressions::ite(x, y, z), termManager.mkTerm(cvc5::Kind::ITE, {cvc5X, cvc5Y, cvc5Z}), termManager, solver, adapter);
202 cvc5::Term cvc5R = adapter.translateExpression(r);
203 assertEquivalent(
storm::expressions::ite(x, y, r), termManager.mkTerm(cvc5::Kind::ITE, {cvc5X, termManager.mkTerm(cvc5::Kind::TO_REAL, {cvc5Y}), cvc5R}),
204 termManager, solver, adapter);
207TEST(Cvc5ExpressionAdapter, Cvc5ToStorm) {
208 cvc5::TermManager termManager;
209 cvc5::Solver solver(termManager);
212 storm::adapters::Cvc5ExpressionAdapter adapter(*manager, solver);
216 ASSERT_TRUE(translatedTrue.
isTrue());
217 ASSERT_TRUE(adapter.translateExpression(termManager.mkBoolean(
false)).isFalse());
220 auto const assertIntegerLiteral = [&adapter, &termManager](int64_t value) {
223 EXPECT_TRUE(integerLiteral !=
nullptr);
224 if (integerLiteral !=
nullptr) {
225 EXPECT_EQ(value, integerLiteral->getValue());
228 assertIntegerLiteral(-42);
229 assertIntegerLiteral(0);
230 assertIntegerLiteral(42);
237 EXPECT_TRUE(rationalLiteral !=
nullptr);
238 if (rationalLiteral !=
nullptr) {
239 EXPECT_EQ(storm::RationalNumber(numerator, denominator), rationalLiteral->getValue());
242 assertRationalLiteral(1, 2);
243 assertRationalLiteral(-3, 4);
244 assertRationalLiteral(7, 3);
245 assertRationalLiteral(2, 1);
250 cvc5::Term cvc5X = adapter.translateExpression(xVar);
251 cvc5::Term cvc5Y = adapter.translateExpression(yVar);
252 cvc5::Term cvc5Sum = termManager.mkTerm(cvc5::Kind::ADD, {cvc5X, cvc5Y});
253 cvc5::Term cvc5Less = termManager.mkTerm(cvc5::Kind::LT, {cvc5Sum, termManager.mkInteger(0)});
267 ASSERT_TRUE(zeroLiteral !=
nullptr);
268 ASSERT_EQ(0, zeroLiteral->getValue());
271 cvc5::Term cvc5ThreeWaySum = termManager.mkTerm(cvc5::Kind::ADD, {cvc5X, cvc5Y, adapter.translateExpression(
manager->integer(3))});
274 EXPECT_EQ((translatedSum +
manager->integer(3)).toString(), translatedThreeWaySum.
toString());
276 cvc5::Term cvc5ThreeWayProduct = termManager.mkTerm(cvc5::Kind::MULT, {cvc5X, cvc5Y, adapter.translateExpression(
manager->integer(3))});
286 cvc5::Term cvc5Equivalent = termManager.mkTerm(cvc5::Kind::EQUAL, {adapter.translateExpression(aVar), adapter.translateExpression(bVar)});
TEST(RegionConstraintCheckerTest, AffineConstraintHoldsThroughout)
bool isVariable() const
Retrieves whether the expression is a variable.
OperatorType getOperator() const
Retrieves the operator of a function application.
bool hasBooleanType() const
Retrieves whether the expression has a boolean return type.
Expression getOperand(uint_fast64_t operandIndex) const
Retrieves the given operand from the expression.
std::string const & getIdentifier() const
Retrieves the identifier associated with this expression.
BaseExpression const & getBaseExpression() const
Retrieves the base expression underlying this expression object.
std::string toString() const
Converts the expression into a string.
bool isTrue() const
Checks if the expression is equal to the boolean literal true.
This class is responsible for managing a set of typed variables and all expressions using these varia...
storm::expressions::Expression getExpression() const
Retrieves an expression that represents the variable.
Expression ceil(Expression const &first)
Expression ite(Expression const &condition, Expression const &thenExpression, Expression const &elseExpression)
Expression iff(Expression const &first, Expression const &second)
Expression pow(Expression const &base, Expression const &exponent, bool allowIntegerType)
The type of the resulting expression is.
Expression minimum(Expression const &first, Expression const &second)
Expression floor(Expression const &first)
Expression implies(Expression const &first, Expression const &second)
SettingsManager const & manager()
Retrieves the settings manager.
NumberTraits< RationalType >::IntegerType denominator(RationalType const &number)
NumberTraits< RationalType >::IntegerType numerator(RationalType const &number)