Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SymbolicBisimulationDecompositionTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
22
23class Cudd {
24 public:
25 static void checkLibraryAvailable() {
26#ifndef STORM_HAVE_CUDD
27 GTEST_SKIP() << "Library CUDD not available.";
28#endif
29 }
30
32};
33
34class Sylvan {
35 public:
36 static void checkLibraryAvailable() {
37#ifndef STORM_HAVE_SYLVAN
38 GTEST_SKIP() << "Library Sylvan not available.";
39#endif
40 }
41
43};
44
45template<typename TestType>
46class SymbolicModelBisimulationDecomposition : public ::testing::Test {
47 public:
48 void SetUp() override {
49 TestType::checkLibraryAvailable();
50 }
51
52 static const storm::dd::DdType DdType = TestType::DdType;
53};
54
55typedef ::testing::Types<Cudd, Sylvan> TestingTypes;
57
59 const storm::dd::DdType DdType = TestFixture::DdType;
60 storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/die.pm");
61
62 std::shared_ptr<storm::models::symbolic::Model<DdType, double>> model = storm::builder::DdPrismModelBuilder<DdType, double>().build(program);
63 model->getManager().execute([&]() {
65 decomposition.compute();
66 std::shared_ptr<storm::models::Model<double>> quotient = decomposition.getQuotient(storm::dd::bisimulation::QuotientFormat::Dd);
67
68 EXPECT_EQ(11ul, quotient->getNumberOfStates());
69 EXPECT_EQ(17ul, quotient->getNumberOfTransitions());
70 EXPECT_EQ(storm::models::ModelType::Dtmc, quotient->getType());
71 EXPECT_TRUE(quotient->isSymbolicModel());
72
73 storm::parser::FormulaParser formulaParser;
74 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"two\"]");
75
76 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas;
77 formulas.push_back(formula);
78
80 decomposition2.compute();
82
83 EXPECT_EQ(5ul, quotient->getNumberOfStates());
84 EXPECT_EQ(8ul, quotient->getNumberOfTransitions());
85 EXPECT_EQ(storm::models::ModelType::Dtmc, quotient->getType());
86 EXPECT_TRUE(quotient->isSymbolicModel());
87 });
88}
89
91 const storm::dd::DdType DdType = TestFixture::DdType;
92 storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/die.pm");
93
94 std::shared_ptr<storm::models::symbolic::Model<DdType, double>> model = storm::builder::DdPrismModelBuilder<DdType, double>().build(program);
95
96 model->getManager().execute([&]() {
98
99 std::shared_ptr<storm::models::Model<double>> quotient = decomposition.getQuotient(storm::dd::bisimulation::QuotientFormat::Dd);
100 ASSERT_EQ(storm::models::ModelType::Mdp, quotient->getType());
101 ASSERT_TRUE(quotient->isSymbolicModel());
102
103 std::shared_ptr<storm::models::symbolic::Mdp<DdType, double>> quotientMdp = quotient->as<storm::models::symbolic::Mdp<DdType, double>>();
104
106
107 storm::parser::FormulaParser formulaParser;
108 std::shared_ptr<storm::logic::Formula const> minFormula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"one\"]");
109 std::shared_ptr<storm::logic::Formula const> maxFormula = formulaParser.parseSingleFormulaFromString("Pmax=? [F \"one\"]");
110
111 std::pair<double, double> resultBounds;
112
113 std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*minFormula);
114 result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<DdType>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates()));
115 resultBounds.first = result->asQuantitativeCheckResult<double>().sum();
116 result = checker.check(*maxFormula);
117 result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<DdType>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates()));
118 resultBounds.second = result->asQuantitativeCheckResult<double>().sum();
119
120 EXPECT_EQ(resultBounds.first, storm::utility::zero<double>());
121 EXPECT_EQ(resultBounds.second, storm::utility::one<double>());
122
123 // Perform only one step.
124 decomposition.compute(1);
125
127 ASSERT_EQ(storm::models::ModelType::Mdp, quotient->getType());
128 ASSERT_TRUE(quotient->isSymbolicModel());
129 quotientMdp = quotient->as<storm::models::symbolic::Mdp<DdType, double>>();
130
132
133 result = checker2.check(*minFormula);
134 result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<DdType>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates()));
135 resultBounds.first = result->asQuantitativeCheckResult<double>().sum();
136 result = checker2.check(*maxFormula);
137 result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<DdType>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates()));
138 resultBounds.second = result->asQuantitativeCheckResult<double>().sum();
139
140 EXPECT_EQ(resultBounds.first, storm::utility::zero<double>());
141 EXPECT_NEAR(resultBounds.second, static_cast<double>(1) / 3, 1e-6);
142
143 // Perform only one step.
144 decomposition.compute(1);
145
147 ASSERT_EQ(storm::models::ModelType::Mdp, quotient->getType());
148 ASSERT_TRUE(quotient->isSymbolicModel());
149 quotientMdp = quotient->as<storm::models::symbolic::Mdp<DdType, double>>();
150
152
153 result = checker3.check(*minFormula);
154 result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<DdType>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates()));
155 resultBounds.first = result->asQuantitativeCheckResult<double>().sum();
156 result = checker3.check(*maxFormula);
157 result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<DdType>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates()));
158 resultBounds.second = result->asQuantitativeCheckResult<double>().sum();
159
160 EXPECT_NEAR(resultBounds.first, static_cast<double>(1) / 6, 1e-6);
161 EXPECT_NEAR(resultBounds.second, static_cast<double>(1) / 6, 1e-6);
162 EXPECT_NEAR(resultBounds.first, resultBounds.second, 1e-6);
163
164 decomposition.compute(1);
165
167 ASSERT_EQ(storm::models::ModelType::Dtmc, quotient->getType());
168 ASSERT_TRUE(quotient->isSymbolicModel());
169 std::shared_ptr<storm::models::symbolic::Dtmc<DdType, double>> quotientDtmc = quotient->as<storm::models::symbolic::Dtmc<DdType, double>>();
170
172
173 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"one\"]");
174
175 result = checker4.check(*formula);
176 result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<DdType>(quotientDtmc->getReachableStates(), quotientDtmc->getInitialStates()));
177 resultBounds.first = resultBounds.second = result->asQuantitativeCheckResult<double>().sum();
178
179 EXPECT_NEAR(resultBounds.first, static_cast<double>(1) / 6, 1e-6);
180 });
181}
182
184 const storm::dd::DdType DdType = TestFixture::DdType;
185 storm::storage::SymbolicModelDescription smd = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/crowds5_5.pm");
186
187 // Preprocess model to substitute all constants.
188 smd = smd.preprocess();
189
190 std::shared_ptr<storm::models::symbolic::Model<DdType, double>> model = storm::builder::DdPrismModelBuilder<DdType, double>().build(smd.asPrismProgram());
191
192 model->getManager().execute([&]() {
194 decomposition.compute();
195 std::shared_ptr<storm::models::Model<double>> quotient = decomposition.getQuotient(storm::dd::bisimulation::QuotientFormat::Dd);
196
197 EXPECT_EQ(2007ul, quotient->getNumberOfStates());
198 EXPECT_EQ(3738ul, quotient->getNumberOfTransitions());
199 EXPECT_EQ(storm::models::ModelType::Dtmc, quotient->getType());
200 EXPECT_TRUE(quotient->isSymbolicModel());
201
202 storm::parser::FormulaParser formulaParser;
203 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"observe0Greater1\"]");
204
205 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas;
206 formulas.push_back(formula);
207
209 decomposition2.compute();
211
212 EXPECT_EQ(65ul, quotient->getNumberOfStates());
213 EXPECT_EQ(105ul, quotient->getNumberOfTransitions());
214 EXPECT_EQ(storm::models::ModelType::Dtmc, quotient->getType());
215 EXPECT_TRUE(quotient->isSymbolicModel());
216 });
217}
218
220 const storm::dd::DdType DdType = TestFixture::DdType;
221 storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/mdp/two_dice.nm");
222
223 std::shared_ptr<storm::models::symbolic::Model<DdType, double>> model = storm::builder::DdPrismModelBuilder<DdType, double>().build(program);
224
225 model->getManager().execute([&]() {
227 decomposition.compute();
228 std::shared_ptr<storm::models::Model<double>> quotient = decomposition.getQuotient(storm::dd::bisimulation::QuotientFormat::Dd);
229
230 EXPECT_EQ(77ul, quotient->getNumberOfStates());
231 EXPECT_EQ(210ul, quotient->getNumberOfTransitions());
232 EXPECT_EQ(storm::models::ModelType::Mdp, quotient->getType());
233 EXPECT_TRUE(quotient->isSymbolicModel());
234 EXPECT_EQ(116ul, (quotient->as<storm::models::symbolic::Mdp<DdType, double>>()->getNumberOfChoices()));
235
236 storm::parser::FormulaParser formulaParser;
237 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"two\"]");
238
239 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas;
240 formulas.push_back(formula);
241
243 decomposition2.compute();
245
246 EXPECT_EQ(11ul, quotient->getNumberOfStates());
247 EXPECT_EQ(34ul, quotient->getNumberOfTransitions());
248 EXPECT_EQ(storm::models::ModelType::Mdp, quotient->getType());
249 EXPECT_TRUE(quotient->isSymbolicModel());
250 EXPECT_EQ(19ul, (quotient->as<storm::models::symbolic::Mdp<DdType, double>>()->getNumberOfChoices()));
251 });
252}
253
255 const storm::dd::DdType DdType = TestFixture::DdType;
256 storm::storage::SymbolicModelDescription smd = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/mdp/leader4.nm");
257
258 // Preprocess model to substitute all constants.
259 smd = smd.preprocess();
260
261 storm::parser::FormulaParser formulaParser;
262 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("Rmax=? [F \"elected\"]");
263
264 std::shared_ptr<storm::models::symbolic::Model<DdType, double>> model =
266
267 model->getManager().execute([&]() {
269 decomposition.compute();
270 std::shared_ptr<storm::models::Model<double>> quotient = decomposition.getQuotient(storm::dd::bisimulation::QuotientFormat::Dd);
271
272 EXPECT_EQ(252ul, quotient->getNumberOfStates());
273 EXPECT_EQ(624ul, quotient->getNumberOfTransitions());
274 EXPECT_EQ(storm::models::ModelType::Mdp, quotient->getType());
275 EXPECT_TRUE(quotient->isSymbolicModel());
276 EXPECT_EQ(500ul, (quotient->as<storm::models::symbolic::Mdp<DdType, double>>()->getNumberOfChoices()));
277
278 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas;
279 formulas.push_back(formula);
280
282 decomposition2.compute();
284
285 EXPECT_EQ(1107ul, quotient->getNumberOfStates());
286 EXPECT_EQ(2684ul, quotient->getNumberOfTransitions());
287 EXPECT_EQ(storm::models::ModelType::Mdp, quotient->getType());
288 EXPECT_TRUE(quotient->isSymbolicModel());
289 EXPECT_EQ(2152ul, (quotient->as<storm::models::symbolic::Mdp<DdType, double>>()->getNumberOfChoices()));
290 });
291}
TYPED_TEST_SUITE(SymbolicModelBisimulationDecomposition, TestingTypes,)
TYPED_TEST(SymbolicModelBisimulationDecomposition, Die)
::testing::Types< Cudd, Sylvan > TestingTypes
static const storm::dd::DdType DdType
Definition GraphTest.cpp:31
static const storm::dd::DdType DdType
Definition GraphTest.cpp:42
std::shared_ptr< storm::models::symbolic::Model< Type, ValueType > > build(storm::prism::Program const &program, Options const &options=Options())
Translates the given program into a symbolic model (i.e.
void compute(bisimulation::SignatureMode const &mode=bisimulation::SignatureMode::Eager)
Performs partition refinement until a fixpoint has been reached.
std::shared_ptr< storm::models::Model< ExportValueType > > getQuotient(storm::dd::bisimulation::QuotientFormat const &quotientFormat) const
Retrieves the quotient model after the bisimulation decomposition was computed.
This class represents a discrete-time Markov chain.
Definition Dtmc.h:13
This class represents a discrete-time Markov decision process.
Definition Mdp.h:13
virtual uint_fast64_t getNumberOfChoices() const override
Retrieves the number of nondeterministic choices in the model.
std::shared_ptr< storm::logic::Formula const > parseSingleFormulaFromString(std::string const &formulaString) const
Parses the formula given by the provided string.
static storm::prism::Program parse(std::string const &filename, bool prismCompatability=false)
Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
storm::prism::Program const & asPrismProgram() const
SymbolicModelDescription preprocess(std::string const &constantDefinitionString="") const
::testing::Types< Cudd, Sylvan > TestingTypes
Definition GraphTest.cpp:59