Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
LraDtmcPrctlModelCheckerTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
19
20namespace {
21
22#ifdef STORM_HAVE_GMM
23class GBGmmxxDoubleGmresEnvironment {
24 public:
25 typedef double ValueType;
26 static const bool isExact = false;
27 static storm::Environment createEnvironment() {
29 env.solver().lra().setDetLraMethod(storm::solver::LraMethod::GainBiasEquations);
30 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Gmmxx);
31 env.solver().gmmxx().setMethod(storm::solver::GmmxxLinearEquationSolverMethod::Gmres);
32 env.solver().gmmxx().setPreconditioner(storm::solver::GmmxxLinearEquationSolverPreconditioner::Ilu);
33 env.solver().gmmxx().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
34 env.solver().lra().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
35 return env;
36 }
37};
38
39class GBEigenDoubleDGmresEnvironment {
40 public:
41 typedef double ValueType;
42 static const bool isExact = false;
43 static storm::Environment createEnvironment() {
45 env.solver().lra().setDetLraMethod(storm::solver::LraMethod::GainBiasEquations);
46 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Eigen);
47 env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::DGmres);
48 env.solver().eigen().setPreconditioner(storm::solver::EigenLinearEquationSolverPreconditioner::Ilu);
49 env.solver().lra().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
50 env.solver().eigen().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
51 return env;
52 }
53};
54#endif
55
56class GBEigenRationalLUEnvironment {
57 public:
58 typedef storm::RationalNumber ValueType;
59 static const bool isExact = true;
60 static storm::Environment createEnvironment() {
62 env.solver().lra().setDetLraMethod(storm::solver::LraMethod::GainBiasEquations);
63 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Eigen);
64 env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::SparseLU);
65 return env;
66 }
67};
68
69class GBNativeSorEnvironment {
70 public:
71 typedef double ValueType;
72 static const bool isExact = false;
73 static storm::Environment createEnvironment() {
75 env.solver().lra().setDetLraMethod(storm::solver::LraMethod::GainBiasEquations);
76 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native);
77 env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SOR);
78 env.solver().native().setSorOmega(storm::utility::convertNumber<storm::RationalNumber>(0.8)); // A test fails if this is set to 0.9...
79 env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
80 env.solver().lra().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
81 return env;
82 }
83};
84
85class GBNativeWalkerChaeEnvironment {
86 public:
87 typedef double ValueType;
88 static const bool isExact = false;
89 static storm::Environment createEnvironment() {
91 env.solver().lra().setDetLraMethod(storm::solver::LraMethod::GainBiasEquations);
92 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native);
93 env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::WalkerChae);
94 env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
95 env.solver().lra().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
97 return env;
98 }
99};
100
101#ifdef STORM_HAVE_GMM
102class DistrGmmxxDoubleGmresEnvironment {
103 public:
104 typedef double ValueType;
105 static const bool isExact = false;
106 static storm::Environment createEnvironment() {
108 env.solver().lra().setDetLraMethod(storm::solver::LraMethod::LraDistributionEquations);
109 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Gmmxx);
110 env.solver().gmmxx().setMethod(storm::solver::GmmxxLinearEquationSolverMethod::Gmres);
111 env.solver().gmmxx().setPreconditioner(storm::solver::GmmxxLinearEquationSolverPreconditioner::Ilu);
112 env.solver().gmmxx().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
113 env.solver().lra().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
114 return env;
115 }
116};
117#endif
118
119class DistrEigenRationalLUEnvironment {
120 public:
121 typedef storm::RationalNumber ValueType;
122 static const bool isExact = true;
123 static storm::Environment createEnvironment() {
125 env.solver().lra().setDetLraMethod(storm::solver::LraMethod::LraDistributionEquations);
126 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Eigen);
127 env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::SparseLU);
128 return env;
129 }
130};
131
132class DistrNativeWalkerChaeEnvironment {
133 public:
134 typedef double ValueType;
135 static const bool isExact = false;
136 static storm::Environment createEnvironment() {
138 env.solver().lra().setDetLraMethod(storm::solver::LraMethod::GainBiasEquations);
139 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native);
140 env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::WalkerChae);
141 env.solver().lra().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
142 env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
144 return env;
145 }
146};
147
148class ValueIterationEnvironment {
149 public:
150 typedef double ValueType;
151 static const bool isExact = false;
152 static storm::Environment createEnvironment() {
154 env.solver().lra().setDetLraMethod(storm::solver::LraMethod::ValueIteration);
155 env.solver().lra().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8));
156 return env;
157 }
158};
159
160template<typename TestType>
161class LraDtmcPrctlModelCheckerTest : public ::testing::Test {
162 public:
163 typedef typename TestType::ValueType ValueType;
164 LraDtmcPrctlModelCheckerTest() : _environment(TestType::createEnvironment()) {}
165 storm::Environment const& env() const {
166 return _environment;
167 }
168 ValueType parseNumber(std::string const& input) const {
169 return storm::utility::convertNumber<ValueType>(input);
170 }
171 ValueType precision() const {
172 return TestType::isExact ? parseNumber("0") : parseNumber("1e-6");
173 }
174
175 private:
176 storm::Environment _environment;
177};
178
179typedef ::testing::Types<
180#ifdef STORM_HAVE_GMM
181 GBGmmxxDoubleGmresEnvironment, GBEigenDoubleDGmresEnvironment, DistrGmmxxDoubleGmresEnvironment,
182#endif
183 GBEigenRationalLUEnvironment, GBNativeSorEnvironment, GBNativeWalkerChaeEnvironment, DistrEigenRationalLUEnvironment, DistrNativeWalkerChaeEnvironment,
184 ValueIterationEnvironment>
186
187TYPED_TEST_SUITE(LraDtmcPrctlModelCheckerTest, TestingTypes, );
188
189TYPED_TEST(LraDtmcPrctlModelCheckerTest, LRASingleBscc) {
190 typedef typename TestFixture::ValueType ValueType;
191
193 std::shared_ptr<storm::models::sparse::Dtmc<ValueType>> dtmc;
194
195 // A parser that we use for conveniently constructing the formulas.
196 storm::parser::FormulaParser formulaParser;
197
198 {
199 matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(2, 2, 2);
200 matrixBuilder.addNextValue(0, 1, this->parseNumber("1"));
201 matrixBuilder.addNextValue(1, 0, this->parseNumber("1"));
202 storm::storage::SparseMatrix<ValueType> transitionMatrix = matrixBuilder.build();
203
205 ap.addLabel("a");
206 ap.addLabelToState("a", 1);
207
208 dtmc.reset(new storm::models::sparse::Dtmc<ValueType>(transitionMatrix, ap));
209
211
212 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
213
214 std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
216
217 EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[0], this->precision());
218 EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[1], this->precision());
219 }
220 {
221 matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(2, 2, 4);
222 matrixBuilder.addNextValue(0, 0, this->parseNumber("0.5"));
223 matrixBuilder.addNextValue(0, 1, this->parseNumber("0.5"));
224 matrixBuilder.addNextValue(1, 0, this->parseNumber("0.5"));
225 matrixBuilder.addNextValue(1, 1, this->parseNumber("0.5"));
226 storm::storage::SparseMatrix<ValueType> transitionMatrix = matrixBuilder.build();
227
229 ap.addLabel("a");
230 ap.addLabelToState("a", 1);
231
232 dtmc.reset(new storm::models::sparse::Dtmc<ValueType>(transitionMatrix, ap));
233
235
236 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
237
238 std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
240
241 EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[0], this->precision());
242 EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[1], this->precision());
243 }
244
245 {
246 matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(3, 3, 3);
247 matrixBuilder.addNextValue(0, 1, this->parseNumber("1"));
248 matrixBuilder.addNextValue(1, 2, this->parseNumber("1"));
249 matrixBuilder.addNextValue(2, 0, this->parseNumber("1"));
250 storm::storage::SparseMatrix<ValueType> transitionMatrix = matrixBuilder.build();
251
253 ap.addLabel("a");
254 ap.addLabelToState("a", 2);
255
256 dtmc.reset(new storm::models::sparse::Dtmc<ValueType>(transitionMatrix, ap));
257
259
260 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
261
262 std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
264
265 EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult1[0], this->precision());
266 EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult1[1], this->precision());
267 EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult1[2], this->precision());
268 }
269}
270
271TYPED_TEST(LraDtmcPrctlModelCheckerTest, LRA) {
272 typedef typename TestFixture::ValueType ValueType;
273
275 std::shared_ptr<storm::models::sparse::Dtmc<ValueType>> dtmc;
276
277 // A parser that we use for conveniently constructing the formulas.
278 storm::parser::FormulaParser formulaParser;
279
280 {
281 matrixBuilder = storm::storage::SparseMatrixBuilder<ValueType>(15, 15, 20, true);
282 matrixBuilder.addNextValue(0, 1, this->parseNumber("1"));
283 matrixBuilder.addNextValue(1, 4, this->parseNumber("0.7"));
284 matrixBuilder.addNextValue(1, 6, this->parseNumber("0.3"));
285 matrixBuilder.addNextValue(2, 0, this->parseNumber("1"));
286
287 matrixBuilder.addNextValue(3, 5, this->parseNumber("0.8"));
288 matrixBuilder.addNextValue(3, 9, this->parseNumber("0.2"));
289 matrixBuilder.addNextValue(4, 3, this->parseNumber("1"));
290 matrixBuilder.addNextValue(5, 3, this->parseNumber("1"));
291
292 matrixBuilder.addNextValue(6, 7, this->parseNumber("1"));
293 matrixBuilder.addNextValue(7, 8, this->parseNumber("1"));
294 matrixBuilder.addNextValue(8, 6, this->parseNumber("1"));
295
296 matrixBuilder.addNextValue(9, 10, this->parseNumber("1"));
297 matrixBuilder.addNextValue(10, 9, this->parseNumber("1"));
298 matrixBuilder.addNextValue(11, 9, this->parseNumber("1"));
299
300 matrixBuilder.addNextValue(12, 5, this->parseNumber("0.4"));
301 matrixBuilder.addNextValue(12, 8, this->parseNumber("0.3"));
302 matrixBuilder.addNextValue(12, 11, this->parseNumber("0.3"));
303
304 matrixBuilder.addNextValue(13, 7, this->parseNumber("0.7"));
305 matrixBuilder.addNextValue(13, 12, this->parseNumber("0.3"));
306
307 matrixBuilder.addNextValue(14, 12, this->parseNumber("1"));
308
309 storm::storage::SparseMatrix<ValueType> transitionMatrix = matrixBuilder.build();
310
312 ap.addLabel("a");
313 ap.addLabelToState("a", 1);
314 ap.addLabelToState("a", 4);
315 ap.addLabelToState("a", 5);
316 ap.addLabelToState("a", 7);
317 ap.addLabelToState("a", 11);
318 ap.addLabelToState("a", 13);
319 ap.addLabelToState("a", 14);
320
321 dtmc.reset(new storm::models::sparse::Dtmc<ValueType>(transitionMatrix, ap));
322
324
325 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
326
327 std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
329
330 EXPECT_NEAR(this->parseNumber("1/10"), quantitativeResult1[0], this->precision());
331 EXPECT_NEAR(this->parseNumber("0"), quantitativeResult1[3], this->precision());
332 EXPECT_NEAR(this->parseNumber("1/3"), quantitativeResult1[6], this->precision());
333 EXPECT_NEAR(this->parseNumber("0"), quantitativeResult1[9], this->precision());
334 EXPECT_NEAR(this->parseNumber("1/10"), quantitativeResult1[12], this->precision());
335 EXPECT_NEAR(this->parseNumber("79/300"), quantitativeResult1[13], this->precision());
336 EXPECT_NEAR(this->parseNumber("1/10"), quantitativeResult1[14], this->precision());
337 }
338}
339} // namespace
void setPrecision(storm::RationalNumber value)
void setPreconditioner(storm::solver::EigenLinearEquationSolverPreconditioner value)
void setMethod(storm::solver::EigenLinearEquationSolverMethod value)
SolverEnvironment & solver()
void setMethod(storm::solver::GmmxxLinearEquationSolverMethod value)
void setPrecision(storm::RationalNumber value)
void setPreconditioner(storm::solver::GmmxxLinearEquationSolverPreconditioner value)
void setDetLraMethod(storm::solver::LraMethod value, bool isSetFromDefault=false)
void setSorOmega(storm::RationalNumber const &value)
void setMaximalNumberOfIterations(uint64_t value)
void setMethod(storm::solver::NativeLinearEquationSolverMethod value)
void setPrecision(storm::RationalNumber value)
void setLinearEquationSolverType(storm::solver::EquationSolverType const &value, bool isSetFromDefault=false)
EigenSolverEnvironment & eigen()
NativeSolverEnvironment & native()
GmmxxSolverEnvironment & gmmxx()
LongRunAverageSolverEnvironment & lra()
ExplicitQuantitativeCheckResult< ValueType > & asExplicitQuantitativeCheckResult()
This class represents a discrete-time Markov chain.
Definition Dtmc.h:13
This class manages the labeling of the state space with a number of (atomic) labels.
std::shared_ptr< storm::logic::Formula const > parseSingleFormulaFromString(std::string const &formulaString) const
Parses the formula given by the provided string.
A class that can be used to build a sparse matrix by adding value by value.
void addNextValue(index_type row, index_type column, value_type const &value)
Sets the matrix entry at the given row and column to the given value.
SparseMatrix< value_type > build(index_type overriddenRowCount=0, index_type overriddenColumnCount=0, index_type overriddenRowGroupCount=0)
A class that holds a possibly non-square matrix in the compressed row storage format.
SFTBDDChecker::ValueType ValueType
NumberType parseNumber(std::string const &value)
Parse number from string.
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
Definition GraphTest.cpp:62
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes
Definition GraphTest.cpp:59