Storm
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
7#include "storm/api/builder.h"
17
18std::unique_ptr<storm::modelchecker::QualitativeCheckResult> getInitialStateFilter(
19 std::shared_ptr<storm::models::sparse::Model<storm::Interval>> const& model) {
20 return std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(model->getInitialStates());
21}
22
23std::unique_ptr<storm::modelchecker::QualitativeCheckResult> getInitialStateFilter(std::shared_ptr<storm::models::sparse::Model<double>> const& model) {
24 return std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(model->getInitialStates());
25}
26
28 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
29 auto filter = getInitialStateFilter(model);
30 result->filter(*filter);
31 return result->asQuantitativeCheckResult<double>().getMin();
32}
33
35 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
36 auto filter = getInitialStateFilter(model);
37 result->filter(*filter);
38 return result->asQuantitativeCheckResult<double>().getMin();
39}
40
41void expectThrow(std::string const& path, std::string const& formulaString) {
42 std::shared_ptr<storm::models::sparse::Model<storm::Interval>> modelPtr = storm::parser::DirectEncodingParser<storm::Interval>::parseModel(path);
43 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::api::extractFormulasFromProperties(storm::api::parseProperties(formulaString));
44
46 env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration);
47
48 std::shared_ptr<storm::models::sparse::Mdp<storm::Interval>> mdp = modelPtr->as<storm::models::sparse::Mdp<storm::Interval>>();
49 ASSERT_EQ(storm::models::ModelType::Mdp, modelPtr->getType());
51
53 STORM_SILENT_EXPECT_THROW(checker.check(env, task), storm::exceptions::InvalidArgumentException);
54}
55
56void checkModel(std::string const& path, std::string const& formulaString, double maxmin, double maxmax, double minmax, double minmin, bool produceScheduler) {
57 std::shared_ptr<storm::models::sparse::Model<storm::Interval>> modelPtr = storm::parser::DirectEncodingParser<storm::Interval>::parseModel(path);
58 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::api::extractFormulasFromProperties(storm::api::parseProperties(formulaString));
60 env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration);
61
62 std::shared_ptr<storm::models::sparse::Mdp<storm::Interval>> mdp = modelPtr->as<storm::models::sparse::Mdp<storm::Interval>>();
63 ASSERT_EQ(storm::models::ModelType::Mdp, modelPtr->getType());
65 taskMax.setProduceSchedulers(produceScheduler);
66
68 auto resultMax = checker.check(env, taskMax);
69 EXPECT_NEAR(maxmin, getQuantitativeResultAtInitialState(mdp, resultMax), 0.0001);
70 taskMax.setRobustUncertainty(false);
71 auto resultMaxNonRobust = checker.check(env, taskMax);
72 EXPECT_NEAR(maxmax, getQuantitativeResultAtInitialState(mdp, resultMaxNonRobust), 0.0001);
73
75 taskMin.setProduceSchedulers(produceScheduler);
76
77 auto resultMin = checker.check(env, taskMin);
78 EXPECT_NEAR(minmax, getQuantitativeResultAtInitialState(mdp, resultMin), 0.0001);
79 taskMin.setRobustUncertainty(false);
80 auto resultMinNonRobust = checker.check(env, taskMin);
81 EXPECT_NEAR(minmin, getQuantitativeResultAtInitialState(mdp, resultMinNonRobust), 0.0001);
82}
83
84void makeUncertainAndCheck(std::string const& path, std::string const& formulaString, double amountOfUncertainty) {
86 program = storm::utility::prism::preprocess(program, "");
87 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas =
89 std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::api::buildSparseModel<double>(program, formulas);
90
91 auto mdp = modelPtr->as<storm::models::sparse::Mdp<double>>();
92
93 ASSERT_TRUE(formulas[0]->isProbabilityOperatorFormula());
94 // These tests cases where written with max in mind.
95 ASSERT_TRUE(formulas[0]->asProbabilityOperatorFormula().getOptimalityType() == storm::solver::OptimizationDirection::Maximize);
98
99 // First compute certain value
101 auto exresult = checker.check(env, task);
102 double certainValue = getQuantitativeResultAtInitialState(mdp, exresult);
103
104 storm::Environment envIntervals;
105 envIntervals.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration);
106 auto transformer = storm::transformer::AddUncertainty(modelPtr);
107 auto imdp = transformer.transform(amountOfUncertainty)->as<storm::models::sparse::Mdp<storm::Interval>>();
109 auto iresultMin = checker.check(env, task);
110 double minValue = getQuantitativeResultAtInitialState(mdp, iresultMin);
111 EXPECT_LE(minValue, certainValue);
112 task.setRobustUncertainty(false);
113 auto iresultMax = checker.check(env, task);
114 double maxValue = getQuantitativeResultAtInitialState(mdp, iresultMax);
115 EXPECT_LE(certainValue, maxValue);
116}
117
118TEST(RobustMDPModelCheckingTest, Tiny01maxmin) {
119 checkModel(STORM_TEST_RESOURCES_DIR "/imdp/tiny-01.drn", "Pmax=? [ F \"target\"];Pmin=? [ F \"target\"]", 0.4, 0.5, 0.5, 0.4, false);
120}
121
122TEST(RobustMDPModelCheckingTest, Tiny03maxmin) {
123 checkModel(STORM_TEST_RESOURCES_DIR "/imdp/tiny-03.drn", "Pmax=? [ F \"target\"];Pmin=? [ F \"target\"]", 0.4, 0.5, 0.5, 0.4, true);
124}
125
126TEST(RobustMDPModelCheckingTest, BoundedTiny03maxmin) {
127 expectThrow(STORM_TEST_RESOURCES_DIR "/imdp/tiny-03.drn", "Pmax=? [ F<=3 \"target\"]");
128}
129
130TEST(RobustMDPModelCheckingTest, Tiny04maxmin) {
131 checkModel(STORM_TEST_RESOURCES_DIR "/imdp/tiny-04.drn", "Pmax=? [ F \"target\"];Pmin=? [ F \"target\"]", 1, 1, 0.42857, 0.42, false);
132}
133
134TEST(RobustMDPModelCheckingTest, Tiny05maxmin) {
135 checkModel(STORM_TEST_RESOURCES_DIR "/imdp/tiny-05.drn", "Pmax=? [ F \"target\"];Pmin=? [ F \"target\"]", 0.3, 0.4, 0.4, 0.3, false);
136}
137
138TEST(RobustMDPModelCheckingTest, Tiny04maxmin_rewards) {
139 expectThrow(STORM_TEST_RESOURCES_DIR "/imdp/tiny-04.drn", "Rmin=? [ F \"target\"]");
140}
141
142TEST(RobustMDPModelCheckingTest, AddUncertaintyCoin22max) {
143#ifndef STORM_HAVE_Z3
144 GTEST_SKIP() << "Z3 not available.";
145#endif
146 makeUncertainAndCheck(STORM_TEST_RESOURCES_DIR "/mdp/coin2-2.nm", "Pmax=? [F \"all_coins_equal_1\"]", 0.1);
147 makeUncertainAndCheck(STORM_TEST_RESOURCES_DIR "/mdp/coin2-2.nm", "Pmax=? [F \"all_coins_equal_1\"]", 0.2);
148}
std::unique_ptr< storm::modelchecker::QualitativeCheckResult > getInitialStateFilter(std::shared_ptr< storm::models::sparse::Model< storm::Interval > > const &model)
void expectThrow(std::string const &path, std::string const &formulaString)
TEST(RobustMDPModelCheckingTest, Tiny01maxmin)
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:14
Base class for all sparse models.
Definition Model.h:33
static std::shared_ptr< storm::models::sparse::Model< ValueType, RewardModelType > > parseModel(std::string const &fil, DirectEncodingParserOptions const &options=DirectEncodingParserOptions())
Load a model in DRN format from a file and create the model.
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)
storm::prism::Program preprocess(storm::prism::Program const &program, std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantDefinitions)
Definition prism.cpp:19
#define STORM_SILENT_EXPECT_THROW(statement, expected_exception)