Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
RobustMdpPrctlModelCheckerTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
8#include "storm/api/builder.h"
18
19std::unique_ptr<storm::modelchecker::QualitativeCheckResult> getInitialStateFilter(
20 std::shared_ptr<storm::models::sparse::Model<storm::Interval>> const& model) {
21 return std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(model->getInitialStates());
22}
23
24std::unique_ptr<storm::modelchecker::QualitativeCheckResult> getInitialStateFilter(std::shared_ptr<storm::models::sparse::Model<double>> const& model) {
25 return std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(model->getInitialStates());
26}
27
29 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
30 auto filter = getInitialStateFilter(model);
31 result->filter(*filter);
32 return result->asQuantitativeCheckResult<double>().getMin();
33}
34
36 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
37 auto filter = getInitialStateFilter(model);
38 result->filter(*filter);
39 return result->asQuantitativeCheckResult<double>().getMin();
40}
41
42void expectThrow(std::string const& path, std::string const& formulaString) {
43 std::shared_ptr<storm::models::sparse::Model<storm::Interval>> modelPtr = storm::parser::parseDirectEncodingModel<storm::Interval>(path);
44 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::api::extractFormulasFromProperties(storm::api::parseProperties(formulaString));
45
47 env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration);
48
49 std::shared_ptr<storm::models::sparse::Mdp<storm::Interval>> mdp = modelPtr->as<storm::models::sparse::Mdp<storm::Interval>>();
50 ASSERT_EQ(storm::models::ModelType::Mdp, modelPtr->getType());
52
54 STORM_SILENT_EXPECT_THROW(checker.check(env, task), storm::exceptions::InvalidArgumentException);
55}
56
57void checkModel(std::string const& path, std::string const& formulaString, double maxmin, double maxmax, double minmax, double minmin, bool produceScheduler) {
58 std::shared_ptr<storm::models::sparse::Model<storm::Interval>> modelPtr = storm::parser::parseDirectEncodingModel<storm::Interval>(path);
59 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::api::extractFormulasFromProperties(storm::api::parseProperties(formulaString));
61 env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration);
62
63 std::shared_ptr<storm::models::sparse::Mdp<storm::Interval>> mdp = modelPtr->as<storm::models::sparse::Mdp<storm::Interval>>();
64 ASSERT_EQ(storm::models::ModelType::Mdp, modelPtr->getType());
66 taskMax.setUncertaintyResolutionMode(storm::UncertaintyResolutionMode::Robust);
67 taskMax.setProduceSchedulers(produceScheduler);
68
70 auto resultMax = checker.check(env, taskMax);
71 EXPECT_NEAR(maxmin, getQuantitativeResultAtInitialState(mdp, resultMax), 0.0001);
72 taskMax.setUncertaintyResolutionMode(storm::UncertaintyResolutionMode::Cooperative);
73 auto resultMaxNonRobust = checker.check(env, taskMax);
74 EXPECT_NEAR(maxmax, getQuantitativeResultAtInitialState(mdp, resultMaxNonRobust), 0.0001);
75
77 taskMin.setUncertaintyResolutionMode(storm::UncertaintyResolutionMode::Robust);
78 taskMin.setProduceSchedulers(produceScheduler);
79
80 auto resultMin = checker.check(env, taskMin);
81 EXPECT_NEAR(minmax, getQuantitativeResultAtInitialState(mdp, resultMin), 0.0001);
82 taskMin.setUncertaintyResolutionMode(storm::UncertaintyResolutionMode::Cooperative);
83 auto resultMinNonRobust = checker.check(env, taskMin);
84 EXPECT_NEAR(minmin, getQuantitativeResultAtInitialState(mdp, resultMinNonRobust), 0.0001);
85}
86
87void checkPrismModelForQuantitativeResult(std::string const& path, std::string const& formulaString, double minmin, double minmax, double maxmin, double maxmax,
88 std::string constantsString) {
90 program = storm::utility::prism::preprocess(program, constantsString);
91
92 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::api::extractFormulasFromProperties(storm::api::parseProperties(formulaString));
93 std::shared_ptr<storm::models::sparse::Model<storm::Interval>> modelPtr = storm::api::buildSparseModel<storm::Interval>(program, formulas);
94
96 env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration);
97
98 std::shared_ptr<storm::models::sparse::Mdp<storm::Interval>> mdp = modelPtr->as<storm::models::sparse::Mdp<storm::Interval>>();
99 ASSERT_EQ(storm::models::ModelType::Mdp, modelPtr->getType());
100
102 taskMinMin.setUncertaintyResolutionMode(storm::UncertaintyResolutionMode::Minimize);
103
105 auto resultMinMin = checker.check(env, taskMinMin);
106 EXPECT_NEAR(minmin, getQuantitativeResultAtInitialState(mdp, resultMinMin), 0.0001);
107
109 taskMinMax.setUncertaintyResolutionMode(storm::UncertaintyResolutionMode::Maximize);
110
111 auto resultMinMax = checker.check(env, taskMinMax);
112 EXPECT_NEAR(minmax, getQuantitativeResultAtInitialState(mdp, resultMinMax), 0.0001);
113
115 taskMaxMin.setUncertaintyResolutionMode(storm::UncertaintyResolutionMode::Minimize);
116
117 auto resultMaxMin = checker.check(env, taskMaxMin);
118 EXPECT_NEAR(maxmin, getQuantitativeResultAtInitialState(mdp, resultMaxMin), 0.0001);
119
121 taskMaxMin.setUncertaintyResolutionMode(storm::UncertaintyResolutionMode::Maximize);
122
123 auto resultMaxMax = checker.check(env, taskMaxMax);
124 EXPECT_NEAR(maxmax, getQuantitativeResultAtInitialState(mdp, resultMaxMax), 0.0001);
125}
126
127TEST(RobustMdpModelCheckerTest, RobotMinMaxTest) {
128#ifndef STORM_HAVE_Z3
129 GTEST_SKIP() << "Z3 not available.";
130#endif
131 // Maxima reachability rewards using PRISM format.
132 checkPrismModelForQuantitativeResult(STORM_TEST_RESOURCES_DIR "/imdp/robot.prism",
133 "Pmin=? [ F \"goal2\"];Pmin=? [ F \"goal2\"];Pmax=? [ F \"goal2\"];Pmax=? [ F \"goal2\"]", 0.4, 0.6, 1.0, 1.0,
134 "delta=0.1");
135}
136
137void makeUncertainAndCheck(std::string const& path, std::string const& formulaString, double amountOfUncertainty) {
139 program = storm::utility::prism::preprocess(program, "");
140 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
142 std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::api::buildSparseModel<double>(program, formulas);
143
144 auto mdp = modelPtr->as<storm::models::sparse::Mdp<double>>();
145
146 ASSERT_TRUE(formulas[0]->isProbabilityOperatorFormula());
147 // These tests cases where written with max in mind.
148 ASSERT_TRUE(formulas[0]->asProbabilityOperatorFormula().getOptimalityType() == storm::solver::OptimizationDirection::Maximize);
151
152 // First compute certain value
154 auto exresult = checker.check(env, task);
155 double certainValue = getQuantitativeResultAtInitialState(mdp, exresult);
156
157 storm::Environment envIntervals;
158 envIntervals.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration);
159 auto transformer = storm::transformer::AddUncertainty(modelPtr);
160 auto imdp = transformer.transform(amountOfUncertainty)->as<storm::models::sparse::Mdp<storm::Interval>>();
162 auto iresultMin = checker.check(env, task);
163 double minValue = getQuantitativeResultAtInitialState(mdp, iresultMin);
164 EXPECT_LE(minValue, certainValue);
165 task.setUncertaintyResolutionMode(storm::UncertaintyResolutionMode::Cooperative);
166 auto iresultMax = checker.check(env, task);
167 double maxValue = getQuantitativeResultAtInitialState(mdp, iresultMax);
168 EXPECT_LE(certainValue, maxValue);
169}
170
171TEST(RobustMDPModelCheckingTest, Tiny01maxmin) {
172 checkModel(STORM_TEST_RESOURCES_DIR "/imdp/tiny-01.drn", "Pmax=? [ F \"target\"];Pmin=? [ F \"target\"]", 0.4, 0.5, 0.5, 0.4, false);
173}
174
175TEST(RobustMDPModelCheckingTest, Tiny03maxmin) {
176 checkModel(STORM_TEST_RESOURCES_DIR "/imdp/tiny-03.drn", "Pmax=? [ F \"target\"];Pmin=? [ F \"target\"]", 0.4, 0.5, 0.5, 0.4, true);
177}
178
179TEST(RobustMDPModelCheckingTest, BoundedTiny03maxmin) {
180 expectThrow(STORM_TEST_RESOURCES_DIR "/imdp/tiny-03.drn", "Pmax=? [ F<=3 \"target\"]");
181}
182
183TEST(RobustMDPModelCheckingTest, Tiny04maxmin) {
184 checkModel(STORM_TEST_RESOURCES_DIR "/imdp/tiny-04.drn", "Pmax=? [ F \"target\"];Pmin=? [ F \"target\"]", 1, 1, 0.42857, 0.42, false);
185}
186
187TEST(RobustMDPModelCheckingTest, Tiny05maxmin) {
188 checkModel(STORM_TEST_RESOURCES_DIR "/imdp/tiny-05.drn", "Pmax=? [ F \"target\"];Pmin=? [ F \"target\"]", 0.3, 0.4, 0.4, 0.3, false);
189}
190
191TEST(RobustMDPModelCheckingTest, Tiny04maxmin_rewards) {
192 expectThrow(STORM_TEST_RESOURCES_DIR "/imdp/tiny-04.drn", "Rmin=? [ F \"target\"]");
193}
194
195TEST(RobustMDPModelCheckingTest, AddUncertaintyCoin22max) {
196#ifndef STORM_HAVE_Z3
197 GTEST_SKIP() << "Z3 not available.";
198#endif
199 makeUncertainAndCheck(STORM_TEST_RESOURCES_DIR "/mdp/coin2-2.nm", "Pmax=? [F \"all_coins_equal_1\"]", 0.1);
200 makeUncertainAndCheck(STORM_TEST_RESOURCES_DIR "/mdp/coin2-2.nm", "Pmax=? [F \"all_coins_equal_1\"]", 0.2);
201}
TEST(RobustMdpModelCheckerTest, RobotMinMaxTest)
std::unique_ptr< storm::modelchecker::QualitativeCheckResult > getInitialStateFilter(std::shared_ptr< storm::models::sparse::Model< storm::Interval > > const &model)
void checkPrismModelForQuantitativeResult(std::string const &path, std::string const &formulaString, double minmin, double minmax, double maxmin, double maxmax, std::string constantsString)
void expectThrow(std::string const &path, std::string const &formulaString)
void checkModel(std::string const &path, std::string const &formulaString, double maxmin, double maxmax, double minmax, double minmin, bool produceScheduler)
double getQuantitativeResultAtInitialState(std::shared_ptr< storm::models::sparse::Model< storm::Interval > > const &model, std::unique_ptr< storm::modelchecker::CheckResult > &result)
void makeUncertainAndCheck(std::string const &path, std::string const &formulaString, double amountOfUncertainty)
SolverEnvironment & solver()
void setMethod(storm::solver::MinMaxMethod value, bool isSetFromDefault=false)
MinMaxSolverEnvironment & minMax()
virtual std::unique_ptr< CheckResult > check(Environment const &env, CheckTask< storm::logic::Formula, SolutionType > const &checkTask)
Checks the provided formula.
This class represents a (discrete-time) Markov decision process.
Definition Mdp.h:13
Base class for all sparse models.
Definition Model.h:32
This class is a convenience transformer to add uncertainty.
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< storm::jani::Property > parseProperties(storm::parser::FormulaParser &formulaParser, std::string const &inputString, boost::optional< std::set< std::string > > const &propertyFilter)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
template std::shared_ptr< storm::models::sparse::Model< storm::Interval > > parseDirectEncodingModel< storm::Interval >(std::filesystem::path const &file, DirectEncodingParserOptions const &options)
storm::prism::Program preprocess(storm::prism::Program const &program, std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantDefinitions)
Definition prism.cpp:13
#define STORM_SILENT_EXPECT_THROW(statement, expected_exception)
Definition storm_gtest.h:31