Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseDerivativeInstantiationModelCheckerTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
9#include "storm/api/builder.h"
10#include "storm/api/storm.h"
14
15namespace {
16class RationalGmmxxEnvironment {
17 public:
19 typedef storm::RationalNumber ConstantType;
20 static storm::Environment createEnvironment() {
22 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Gmmxx);
23 return env;
24 }
25};
26class DoubleGmmxxEnvironment {
27 public:
29 typedef double ConstantType;
30 static storm::Environment createEnvironment() {
32 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Gmmxx);
33 return env;
34 }
35};
36class RationalEigenEnvironment {
37 public:
39 typedef storm::RationalNumber ConstantType;
40 static storm::Environment createEnvironment() {
42 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Eigen);
43 return env;
44 }
45};
46class DoubleEigenEnvironment {
47 public:
49 typedef double ConstantType;
50 static storm::Environment createEnvironment() {
52 env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Eigen);
53 return env;
54 }
55};
56template<typename TestType>
57class SparseDerivativeInstantiationModelCheckerTest : public ::testing::Test {
58 public:
59 typedef typename TestType::ValueType ValueType;
60 typedef typename TestType::ConstantType ConstantType;
61 template<typename ValueType>
63 template<typename ValueType>
65 template<typename ValueType>
66 using Instantiation = std::map<VariableType<storm::RationalFunction>, CoefficientType<storm::RationalFunction>>;
67 template<typename ValueType>
68 using ResultMap = std::map<VariableType<storm::RationalFunction>, ConstantType>;
69 SparseDerivativeInstantiationModelCheckerTest() : _environment(TestType::createEnvironment()) {}
70 storm::Environment const& env() const {
71 return _environment;
72 }
73 virtual void SetUp() {
74#ifndef STORM_HAVE_Z3
75 GTEST_SKIP() << "Z3 not available.";
76#endif
77 carl::VariablePool::getInstance().clear();
78 }
79 virtual void TearDown() {
80 carl::VariablePool::getInstance().clear();
81 }
83 std::vector<std::shared_ptr<const storm::logic::Formula>> formulas, storm::RationalFunction reachabilityFunction);
84
85 private:
86 storm::Environment _environment;
87};
88
89typedef ::testing::Types<
90#ifdef STORM_HAVE_GMM
91 RationalGmmxxEnvironment, DoubleGmmxxEnvironment,
92#endif
93 RationalEigenEnvironment, DoubleEigenEnvironment>
95} // namespace
96
97TYPED_TEST_SUITE(SparseDerivativeInstantiationModelCheckerTest, TestingTypes, );
98
99template<typename TestType>
100void SparseDerivativeInstantiationModelCheckerTest<TestType>::testModel(std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc,
101 std::vector<std::shared_ptr<const storm::logic::Formula>> formulas,
102 storm::RationalFunction reachabilityFunction) {
103 auto formulaWithoutBound = std::make_shared<storm::logic::ProbabilityOperatorFormula>(
104 formulas[0]->asProbabilityOperatorFormula().getSubformula().asSharedPointer(), storm::logic::OperatorInformation(boost::none, boost::none));
105
108
109 std::map<VariableType<storm::RationalFunction>, storm::RationalFunction> derivatives;
110 for (auto const& parameter : parameters) {
111 derivatives[parameter] = reachabilityFunction.derivative(parameter);
112 }
113
114 // Generate test cases.
115 std::vector<Instantiation<storm::RationalFunction>> testInstantiations;
116 Instantiation<storm::RationalFunction> emptyInstantiation;
117 testInstantiations.push_back(emptyInstantiation);
118 for (auto const& param : parameters) {
119 std::vector<Instantiation<storm::RationalFunction>> newInstantiations;
120 for (auto point : testInstantiations) {
121 for (typename TestType::ConstantType x = storm::utility::convertNumber<ConstantType>(1e-6); x <= 1;
122 x += (1 - storm::utility::convertNumber<ConstantType>(1e-6)) / 10) {
123 std::map<VariableType<storm::RationalFunction>, CoefficientType<storm::RationalFunction>> newMap(point);
124 newMap[param] = storm::utility::convertNumber<CoefficientType<storm::RationalFunction>>(x);
125 newInstantiations.push_back(newMap);
126 }
127 }
128 testInstantiations = newInstantiations;
129 }
130
131 // The test cases we are going to study. Left are the actual instantiations, right are the maps
132 // for the results (which happen to share the same type).
133 std::map<Instantiation<storm::RationalFunction>, ResultMap<storm::RationalFunction>> testCases;
134 for (auto const& instantiation : testInstantiations) {
135 ResultMap<storm::RationalFunction> resultMap;
136 for (auto const& entry : instantiation) {
137 auto parameter = entry.first;
138 auto derivativeWrtParameter = derivatives[parameter];
139 resultMap[parameter] = storm::utility::parametric::evaluate<typename TestType::ConstantType>(derivativeWrtParameter, instantiation);
140 }
141 testCases[instantiation] = resultMap;
142 }
143
144 auto checkTask = storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>(*formulaWithoutBound);
145 derivativeModelChecker.specifyFormula(env(), checkTask);
146
147 for (auto const& testCase : testCases) {
148 Instantiation<ValueType> instantiation = testCase.first;
149 for (auto const& position : instantiation) {
150 auto parameter = position.first;
151 auto parameterValue = position.second;
152 auto expectedResult = testCase.second.at(parameter);
153
154 auto derivative = derivativeModelChecker.check(env(), instantiation, parameter);
155 ASSERT_NEAR(storm::utility::convertNumber<double>(derivative->getValueVector()[0]), storm::utility::convertNumber<double>(expectedResult), 1e-6)
156 << instantiation;
157 }
158 }
159}
160
161// A very simple DTMC
162TYPED_TEST(SparseDerivativeInstantiationModelCheckerTest, Simple) {
163 std::string programFile = STORM_TEST_RESOURCES_DIR "/pdtmc/gradient1.pm";
164 std::string formulaAsString = "Pmax=? [F s=2]";
165 std::string constantsAsString = ""; // e.g. pL=0.9,TOACK=0.5
166
167 // We have to create the dtmc and formulas here, because we need its parameters to create the polynomial
168 storm::prism::Program program = storm::api::parseProgram(programFile);
169 program = storm::utility::prism::preprocess(program, constantsAsString);
170 std::vector<std::shared_ptr<const storm::logic::Formula>> formulas =
172 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model =
173 storm::api::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
174 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = model->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
176 ASSERT_TRUE(simplifier.simplify(*(formulas[0])));
177 model = simplifier.getSimplifiedModel();
179
180 // The associated polynomial. In this case, it's p * (1 - p).
181 carl::Variable varP = carl::VariablePool::getInstance().findVariableWithName("p");
182 std::shared_ptr<storm::RawPolynomialCache> cache = std::make_shared<storm::RawPolynomialCache>();
184 storm::RationalFunction reachabilityFunction = p * (storm::RationalFunction(1) - p);
185
186 this->testModel(dtmc, formulas, reachabilityFunction);
187}
188
189// A very simple DTMC with two parameters
190TYPED_TEST(SparseDerivativeInstantiationModelCheckerTest, Simple2) {
191 std::string programFile = STORM_TEST_RESOURCES_DIR "/pdtmc/gradient2.pm";
192 std::string formulaAsString = "Pmax=? [F s=2]";
193 std::string constantsAsString = ""; // e.g. pL=0.9,TOACK=0.5
194
195 // We have to create the dtmc and formulas here, because we need its parameters to create the polynomial
196 storm::prism::Program program = storm::api::parseProgram(programFile);
197 program = storm::utility::prism::preprocess(program, constantsAsString);
198 std::vector<std::shared_ptr<const storm::logic::Formula>> formulas =
200 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model =
201 storm::api::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
202 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = model->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
204 ASSERT_TRUE(simplifier.simplify(*(formulas[0])));
205 model = simplifier.getSimplifiedModel();
207
208 // The associated polynomial. In this case, it's p * (1 - q).
209 carl::Variable varP = carl::VariablePool::getInstance().findVariableWithName("p");
210 carl::Variable varQ = carl::VariablePool::getInstance().findVariableWithName("q");
211 std::shared_ptr<storm::RawPolynomialCache> cache = std::make_shared<storm::RawPolynomialCache>();
214 storm::RationalFunction reachabilityFunction = p * (storm::RationalFunction(1) - q);
215
216 this->testModel(dtmc, formulas, reachabilityFunction);
217}
218
219// The bounded retransmission protocol
220TYPED_TEST(SparseDerivativeInstantiationModelCheckerTest, Brp162) {
221 std::string programFile = STORM_TEST_RESOURCES_DIR "/pdtmc/brp16_2.pm";
222 std::string formulaAsString = "Pmax=? [F s=4 & i=N ]";
223 std::string constantsAsString = ""; // e.g. pL=0.9,TOACK=0.5
224
225 // We have to create the dtmc and formulas here, because we need its parameters to create the polynomial
226 storm::prism::Program program = storm::api::parseProgram(programFile);
227 program = storm::utility::prism::preprocess(program, constantsAsString);
228 std::vector<std::shared_ptr<const storm::logic::Formula>> formulas =
230 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model =
231 storm::api::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
232 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = model->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
234 ASSERT_TRUE(simplifier.simplify(*(formulas[0])));
235 model = simplifier.getSimplifiedModel();
237
238 carl::Variable pLVar = carl::VariablePool::getInstance().findVariableWithName("pL");
239 carl::Variable pKVar = carl::VariablePool::getInstance().findVariableWithName("pK");
240 std::shared_ptr<storm::RawPolynomialCache> cache = std::make_shared<storm::RawPolynomialCache>();
243
244 // The term is ((pK)^16 * (pL)^16 * (pK^2*pL^2+(-3)*pK*pL+3)^16)/(1), so we're just going to create this here.
245 auto firstTerm = pK * pK * pK * pK * pK * pK * pK * pK * pK * pK * pK * pK * pK * pK * pK * pK;
246 auto secondTerm = pL * pL * pL * pL * pL * pL * pL * pL * pL * pL * pL * pL * pL * pL * pL * pL;
247 auto thirdTermUnpowed = pK * pK * pL * pL + (-3) * pK * pL + 3;
248 auto thirdTerm = thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed *
249 thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed * thirdTermUnpowed *
250 thirdTermUnpowed * thirdTermUnpowed;
251 storm::RationalFunction reachabilityFunction = firstTerm * secondTerm * thirdTerm;
252
253 this->testModel(dtmc, formulas, reachabilityFunction);
254}
void testModel(std::string programFile, std::string formulaAsString, std::string constantsAsString)
TYPED_TEST(SparseDerivativeInstantiationModelCheckerTest, Simple)
TYPED_TEST_SUITE(SparseDerivativeInstantiationModelCheckerTest, TestingTypes,)
SolverEnvironment & solver()
void setLinearEquationSolverType(storm::solver::EquationSolverType const &value, bool isSetFromDefault=false)
std::shared_ptr< ModelType > as()
Casts the model into the model type given by the template parameter.
Definition ModelBase.h:37
This class represents a discrete-time Markov chain.
Definition Dtmc.h:13
This class performs different steps to simplify the given (parametric) model.
std::vector< storm::jani::Property > parsePropertiesForPrismProgram(std::string const &inputString, storm::prism::Program const &program, boost::optional< std::set< std::string > > const &propertyFilter)
storm::prism::Program parseProgram(std::string const &filename, bool prismCompatibility, bool simplify)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
typename utility::parametric::VariableType< FunctionType >::type VariableType
typename utility::parametric::CoefficientType< FunctionType >::type CoefficientType
SFTBDDChecker::ValueType ValueType
std::set< storm::RationalFunctionVariable > getProbabilityParameters(Model< storm::RationalFunction > const &model)
Get all probability parameters occurring on transitions.
Definition Model.cpp:695
storm::prism::Program preprocess(storm::prism::Program const &program, std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantDefinitions)
Definition prism.cpp:13
carl::RationalFunction< Polynomial, true > RationalFunction
carl::MultivariatePolynomial< RationalFunctionCoefficient > RawPolynomial
::testing::Types< Cudd, Sylvan > TestingTypes
Definition GraphTest.cpp:59