Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
Z3ExpressionAdapterTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
4#include <memory>
5
6#ifdef STORM_HAVE_Z3
11
12TEST(Z3ExpressionAdapter, StormToZ3Basic) {
13 z3::context ctx;
14 z3::solver s(ctx);
15 z3::expr conjecture = ctx.bool_val(false);
16
17 std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
18 storm::adapters::Z3ExpressionAdapter adapter(*manager, ctx);
19
20 storm::expressions::Expression exprTrue = manager->boolean(true);
21 z3::expr z3True = ctx.bool_val(true);
22 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprTrue), z3True)));
23 s.add(conjecture);
24 ASSERT_TRUE(s.check() == z3::unsat);
25 s.reset();
26
27 storm::expressions::Expression exprFalse = manager->boolean(false);
28 z3::expr z3False = ctx.bool_val(false);
29 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprFalse), z3False)));
30 s.add(conjecture);
31 ASSERT_TRUE(s.check() == z3::unsat);
32 s.reset();
33
34 storm::expressions::Variable x = manager->declareBooleanVariable("x");
35 storm::expressions::Variable y = manager->declareBooleanVariable("y");
36 storm::expressions::Expression exprConjunction = x && y;
37 z3::expr z3Conjunction = (ctx.bool_const("x") && ctx.bool_const("y"));
38
39 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprConjunction), z3Conjunction)));
40 s.add(conjecture);
41 ASSERT_TRUE(s.check() == z3::unsat);
42 s.reset();
43
44 storm::expressions::Expression exprNor = !(x || y);
45 z3::expr z3Nor = !(ctx.bool_const("x") || ctx.bool_const("y"));
46 ASSERT_NO_THROW(adapter.translateExpression(exprNor)); // Variables already created in adapter.
47 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprNor), z3Nor)));
48 s.add(conjecture);
49 ASSERT_TRUE(s.check() == z3::unsat);
50 s.reset();
51}
52
53TEST(Z3ExpressionAdapter, StormToZ3Integer) {
54 z3::context ctx;
55 z3::solver s(ctx);
56 z3::expr conjecture = ctx.bool_val(false);
57
58 std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
59 storm::adapters::Z3ExpressionAdapter adapter(*manager, ctx);
60
61 storm::expressions::Variable x = manager->declareIntegerVariable("x");
62 storm::expressions::Variable y = manager->declareIntegerVariable("y");
63
64 storm::expressions::Expression exprAdd = x + y < -y;
65 z3::expr z3Add = (ctx.int_const("x") + ctx.int_const("y") < -ctx.int_const("y"));
66 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprAdd), z3Add)));
67 s.add(conjecture);
68 ASSERT_TRUE(s.check() == z3::unsat);
69 s.reset();
70
71 storm::expressions::Expression exprMult = !(x * y == y);
72 z3::expr z3Mult = !(ctx.int_const("x") * ctx.int_const("y") == ctx.int_const("y"));
73 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprMult), z3Mult)));
74 s.add(conjecture);
75 ASSERT_TRUE(s.check() == z3::unsat);
76 s.reset();
77}
78
79TEST(Z3ExpressionAdapter, StormToZ3Real) {
80 z3::context ctx;
81 z3::solver s(ctx);
82 z3::expr conjecture = ctx.bool_val(false);
83
84 std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
85 storm::adapters::Z3ExpressionAdapter adapter(*manager, ctx);
86
87 storm::expressions::Variable x = manager->declareRationalVariable("x");
88 storm::expressions::Variable y = manager->declareRationalVariable("y");
89
90 storm::expressions::Expression exprAdd = x + y < -y;
91 z3::expr z3Add = (ctx.real_const("x") + ctx.real_const("y") < -ctx.real_const("y"));
92 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprAdd), z3Add)));
93 s.add(conjecture);
94 ASSERT_TRUE(s.check() == z3::unsat);
95 s.reset();
96
97 storm::expressions::Expression exprMult = !(x * y == y);
98 z3::expr z3Mult = !(ctx.real_const("x") * ctx.real_const("y") == ctx.real_const("y"));
99 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprMult), z3Mult)));
100 s.add(conjecture);
101 ASSERT_TRUE(s.check() == z3::unsat);
102 s.reset();
103}
104
105TEST(Z3ExpressionAdapter, StormToZ3FloorCeil) {
106 z3::context ctx;
107 z3::solver s(ctx);
108 z3::expr conjecture = ctx.bool_val(false);
109
110 std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
111 storm::adapters::Z3ExpressionAdapter adapter(*manager, ctx);
112
113 storm::expressions::Variable d = manager->declareRationalVariable("d");
114 storm::expressions::Variable i = manager->declareIntegerVariable("i");
115
116 storm::expressions::Expression exprFloor = storm::expressions::floor(d) == i && d > manager->rational(4.1) && d < manager->rational(4.991);
117 z3::expr z3Floor = ctx.int_val(4) == ctx.int_const("i");
118
119 conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprFloor), z3Floor));
120 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprFloor), z3Floor)));
121 s.add(conjecture);
122
123 // It is not logically equivalent, so this should be satisfiable.
124 ASSERT_TRUE(s.check() == z3::sat);
125 s.reset();
126 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_implies(ctx, adapter.translateExpression(exprFloor), z3Floor)));
127 s.add(conjecture);
128
129 // However, the left part implies the right one, which is why this should be unsatisfiable.
130 ASSERT_TRUE(s.check() == z3::unsat);
131 s.reset();
132
133 storm::expressions::Expression exprCeil = storm::expressions::ceil(d) == i && d > manager->rational(4.1) && d < manager->rational(4.991);
134 z3::expr z3Ceil = ctx.int_val(5) == ctx.int_const("i");
135
136 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_iff(ctx, adapter.translateExpression(exprCeil), z3Ceil)));
137 s.add(conjecture);
138 // It is not logically equivalent, so this should be satisfiable.
139 ASSERT_TRUE(s.check() == z3::sat);
140 s.reset();
141 ASSERT_NO_THROW(conjecture = !z3::expr(ctx, Z3_mk_implies(ctx, adapter.translateExpression(exprCeil), z3Ceil)));
142 s.add(conjecture);
143
144 // However, the left part implies the right one, which is why this should be unsatisfiable.
145 ASSERT_TRUE(s.check() == z3::unsat);
146 s.reset();
147}
148
149TEST(Z3ExpressionAdapter, Z3ToStormBasic) {
150 z3::context ctx;
151
152 std::shared_ptr<storm::expressions::ExpressionManager> manager(new storm::expressions::ExpressionManager());
153 manager->declareBooleanVariable("x");
154 manager->declareBooleanVariable("y");
155 storm::adapters::Z3ExpressionAdapter adapter(*manager, ctx);
156
157 z3::expr z3True = ctx.bool_val(true);
159 exprTrue = adapter.translateExpression(z3True);
160 ASSERT_TRUE(exprTrue.isTrue());
161
162 z3::expr z3False = ctx.bool_val(false);
164 exprFalse = adapter.translateExpression(z3False);
165 ASSERT_TRUE(exprFalse.isFalse());
166
167 z3::expr z3Conjunction = (ctx.bool_const("x") && ctx.bool_const("y"));
168 storm::expressions::Expression exprConjunction;
169 (exprConjunction = adapter.translateExpression(z3Conjunction));
170 ASSERT_EQ(storm::expressions::OperatorType::And, exprConjunction.getOperator());
171 ASSERT_TRUE(exprConjunction.getOperand(0).isVariable());
172 ASSERT_EQ("x", exprConjunction.getOperand(0).getIdentifier());
173 ASSERT_TRUE(exprConjunction.getOperand(1).isVariable());
174 ASSERT_EQ("y", exprConjunction.getOperand(1).getIdentifier());
175
176 z3::expr z3Nor = !(ctx.bool_const("x") || ctx.bool_const("y"));
178 (exprNor = adapter.translateExpression(z3Nor));
181 ASSERT_TRUE(exprNor.getOperand(0).getOperand(0).isVariable());
182 ASSERT_EQ("x", exprNor.getOperand(0).getOperand(0).getIdentifier());
183 ASSERT_TRUE(exprNor.getOperand(0).getOperand(1).isVariable());
184 ASSERT_EQ("y", exprNor.getOperand(0).getOperand(1).getIdentifier());
185}
186#endif
TEST(OrderTest, Simple)
Definition OrderTest.cpp:15
bool isVariable() const
Retrieves whether the expression is a variable.
OperatorType getOperator() const
Retrieves the operator of a function application.
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.
bool isFalse() const
Checks if the expression is equal to the boolean literal false.
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...
Expression ceil(Expression const &first)
Expression floor(Expression const &first)
SettingsManager const & manager()
Retrieves the settings manager.