Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ConditionalDtmcPrctlModelCheckerTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
6#include "storm/api/builder.h"
16
17namespace {
18
19#ifdef STORM_HAVE_GMM
20class GmmxxDoubleGmresEnvironment {
21 public:
22 typedef double ValueType;
23 static const bool isExact = false;
24 static storm::Environment createEnvironment() {
25 storm::Environment env;
26 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Gmmxx);
27 env.solver().gmmxx().setMethod(storm::solver::GmmxxLinearEquationSolverMethod::Gmres);
28 env.solver().gmmxx().setPreconditioner(storm::solver::GmmxxLinearEquationSolverPreconditioner::Ilu);
30 return env;
31 }
32};
33
34class EigenDoubleDGmresEnvironment {
35 public:
36 typedef double ValueType;
37 static const bool isExact = false;
38 static storm::Environment createEnvironment() {
39 storm::Environment env;
40 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Eigen);
41 env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::DGmres);
42 env.solver().eigen().setPreconditioner(storm::solver::EigenLinearEquationSolverPreconditioner::Ilu);
44 return env;
45 }
46};
47#endif
48
49class EigenRationalLUEnvironment {
50 public:
51 typedef storm::RationalNumber ValueType;
52 static const bool isExact = true;
53 static storm::Environment createEnvironment() {
54 storm::Environment env;
55 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Eigen);
56 env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::SparseLU);
57 return env;
58 }
59};
60
61class NativeSorEnvironment {
62 public:
63 typedef double ValueType;
64 static const bool isExact = false;
65 static storm::Environment createEnvironment() {
66 storm::Environment env;
67 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native);
68 env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SOR);
71 return env;
72 }
73};
74
75class NativePowerEnvironment {
76 public:
77 typedef double ValueType;
78 static const bool isExact = false;
79 static storm::Environment createEnvironment() {
80 storm::Environment env;
81 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native);
82 env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::Power);
84 return env;
85 }
86};
87
88class NativeWalkerChaeEnvironment {
89 public:
90 typedef double ValueType;
91 static const bool isExact = false;
92 static storm::Environment createEnvironment() {
93 storm::Environment env;
94 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native);
95 env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::WalkerChae);
98 return env;
99 }
100};
101
102template<typename TestType>
103class ConditionalDtmcPrctlModelCheckerTest : public ::testing::Test {
104 public:
105 typedef typename TestType::ValueType ValueType;
106 ConditionalDtmcPrctlModelCheckerTest() : _environment(TestType::createEnvironment()) {}
107
108 void SetUp() override {
109#ifndef STORM_HAVE_Z3
110 GTEST_SKIP() << "Z3 not available.";
111#endif
112 }
113
114 storm::Environment const& env() const {
115 return _environment;
116 }
117 ValueType parseNumber(std::string const& input) const {
119 }
120 ValueType precision() const {
121 return TestType::isExact ? parseNumber("0") : parseNumber("1e-6");
122 }
123
124 private:
125 storm::Environment _environment;
126};
127
128typedef ::testing::Types<
129#ifdef STORM_HAVE_GMM
130 GmmxxDoubleGmresEnvironment, EigenDoubleDGmresEnvironment,
131#endif
132 EigenRationalLUEnvironment, NativeSorEnvironment, NativePowerEnvironment, NativeWalkerChaeEnvironment>
134
135TYPED_TEST_SUITE(ConditionalDtmcPrctlModelCheckerTest, TestingTypes, );
136
137TYPED_TEST(ConditionalDtmcPrctlModelCheckerTest, Conditional) {
138 typedef typename TestFixture::ValueType ValueType;
139
140 storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/test_conditional.pm");
141
144 std::shared_ptr<storm::models::sparse::Model<ValueType>> model = storm::builder::ExplicitModelBuilder<ValueType>(program, options).build();
145 ASSERT_TRUE(model->getType() == storm::models::ModelType::Dtmc);
146 ASSERT_EQ(4ul, model->getNumberOfStates());
147 ASSERT_EQ(5ul, model->getNumberOfTransitions());
148
149 std::shared_ptr<storm::models::sparse::Dtmc<ValueType>> dtmc = model->template as<storm::models::sparse::Dtmc<ValueType>>();
150
152
153 // A parser that we use for conveniently constructing the formulas.
154
155 auto expManager = std::make_shared<storm::expressions::ExpressionManager>();
156 storm::parser::FormulaParser formulaParser(expManager);
157 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\"]");
158
159 std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
161 EXPECT_NEAR(this->parseNumber("0.5"), quantitativeResult1[0], this->precision());
162
163 formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\" || F \"condition\"]");
164
165 result = checker.check(this->env(), *formula);
167 EXPECT_NEAR(storm::utility::one<ValueType>(), quantitativeResult2[0], this->precision());
168
169 formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\" || F \"unreachable\"]");
170
171 STORM_SILENT_EXPECT_THROW(checker.check(this->env(), *formula), storm::exceptions::InvalidPropertyException);
172
173 formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\"]");
174
175 result = checker.check(this->env(), *formula);
177 EXPECT_EQ(storm::utility::positiveInfinity<ValueType>(), quantitativeResult3[0]);
178
179 formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\" || F \"condition\"]");
180
181 result = checker.check(this->env(), *formula);
183 EXPECT_NEAR(storm::utility::one<ValueType>(), quantitativeResult4[0], this->precision());
184
185 formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\" || F \"unreachable\"]");
186
187 STORM_SILENT_EXPECT_THROW(checker.check(this->env(), *formula), storm::exceptions::InvalidPropertyException);
188}
189
190TYPED_TEST(ConditionalDtmcPrctlModelCheckerTest, ConditionalUnreachableFromInitialState) {
191 typedef typename TestFixture::ValueType ValueType;
192
193 // In this model, the condition is reachable from one of the two initial states only.
194 storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/test_conditional_multiple_initial.pm");
195
198 std::shared_ptr<storm::models::sparse::Model<ValueType>> model = storm::builder::ExplicitModelBuilder<ValueType>(program, options).build();
199 ASSERT_TRUE(model->getType() == storm::models::ModelType::Dtmc);
200 ASSERT_EQ(4ul, model->getNumberOfStates());
201
202 std::shared_ptr<storm::models::sparse::Dtmc<ValueType>> dtmc = model->template as<storm::models::sparse::Dtmc<ValueType>>();
203 ASSERT_EQ(2ul, dtmc->getInitialStates().getNumberOfSetBits());
204 storm::storage::BitVector initialStatesWithoutCondition = dtmc->getInitialStates() & ~dtmc->getStates("start");
205 ASSERT_EQ(1ul, initialStatesWithoutCondition.getNumberOfSetBits());
206
208
209 auto expManager = std::make_shared<storm::expressions::ExpressionManager>();
210 storm::parser::FormulaParser formulaParser(expManager);
211
212 std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"target\" || F \"condition\"]");
213
214 // If we are only interested in the initial states, the value is undefined for the initial state that cannot reach the condition.
216 storm::exceptions::InvalidPropertyException);
217
218 // If all states are relevant, the undefined values are reported as infinity.
219 std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(this->env(), *formula);
221 EXPECT_NEAR(storm::utility::one<ValueType>(), quantitativeResult1[*dtmc->getStates("start").begin()], this->precision());
222 EXPECT_EQ(storm::utility::positiveInfinity<ValueType>(), quantitativeResult1[*initialStatesWithoutCondition.begin()]);
223
224 formula = formulaParser.parseSingleFormulaFromString("R=? [F \"target\" || F \"condition\"]");
225
227 storm::exceptions::InvalidPropertyException);
228
229 result = checker.check(this->env(), *formula);
231 EXPECT_NEAR(storm::utility::one<ValueType>(), quantitativeResult2[*dtmc->getStates("start").begin()], this->precision());
232 EXPECT_EQ(storm::utility::positiveInfinity<ValueType>(), quantitativeResult2[*initialStatesWithoutCondition.begin()]);
233}
234} // namespace
void setPrecision(storm::RationalNumber value)
void setMethod(storm::solver::EigenLinearEquationSolverMethod value, bool isSetFromDefault=false)
void setPreconditioner(storm::solver::EigenLinearEquationSolverPreconditioner value)
SolverEnvironment & solver()
void setMethod(storm::solver::GmmxxLinearEquationSolverMethod value)
void setPrecision(storm::RationalNumber value)
void setPreconditioner(storm::solver::GmmxxLinearEquationSolverPreconditioner value)
void setSorOmega(storm::RationalNumber const &value)
void setMaximalNumberOfIterations(uint64_t value)
void setPrecision(storm::RationalNumber value)
void setMethod(storm::solver::NativeLinearEquationSolverMethod value, bool isSetFromDefault=false)
void setLinearEquationSolverType(storm::solver::EquationSolverType const &value, bool isSetFromDefault=false)
EigenSolverEnvironment & eigen()
NativeSolverEnvironment & native()
GmmxxSolverEnvironment & gmmxx()
BuilderOptions & setBuildAllLabels(bool newValue=true)
Should all reward models be built?
BuilderOptions & setBuildAllRewardModels(bool newValue=true)
Should all reward models be built?
std::shared_ptr< storm::models::sparse::Model< ValueType, RewardModelType > > build()
Convert the program given at construction time to an abstract model.
ExplicitQuantitativeCheckResult< ValueType > & asExplicitQuantitativeCheckResult()
A quantitative check result over the states of a sparse model.
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.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
SFTBDDChecker::ValueType ValueType
storm::builder::BuilderOptions NextStateGeneratorOptions
NumberType parseNumber(std::string const &value)
Parse number from string.
ExtendedValueType< ValueType > positiveInfinity()
ValueType one()
Definition constants.cpp:21
TargetType convertNumber(SourceType const &number)
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
Definition GraphTest.cpp:64
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes
Definition GraphTest.cpp:61
#define STORM_SILENT_EXPECT_THROW(statement, expected_exception)
Definition storm_gtest.h:21