Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
BinaryDtmcTransformerTest.cpp
Go to the documentation of this file.
1#include <carl/formula/Constraint.h>
2#include <memory>
3#include <string>
4#include "storm-config.h"
15#include "storm/api/builder.h"
25#include "storm/utility/prism.h"
26#include "test/storm_gtest.h"
27
32
33void testModelB(std::string programFile, std::string formulaAsString, std::string constantsAsString) {
35 program = storm::utility::prism::preprocess(program, constantsAsString);
36 std::vector<std::shared_ptr<const storm::logic::Formula>> formulas =
38 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model =
39 storm::api::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
41 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = model->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
42 uint64_t initialStateModel = dtmc->getStates("init").getNextSetIndex(0);
43
44 dtmc = storm::api::performBisimulationMinimization<storm::RationalFunction>(dtmc, formulas, storm::storage::BisimulationType::Weak)
46
48 auto simpleDtmc = binaryDtmcTransformer.transform(*dtmc, true);
49
51 modelChecker.specifyFormula(checkTask);
53 modelCheckerSimple.specifyFormula(checkTask);
54
55 auto parameters = storm::models::sparse::getAllParameters(*dtmc);
56
57 // Check if both DTMCs are equivalent just by sampling.
58 std::vector<std::map<storm::RationalFunctionVariable, storm::RationalFunctionCoefficient>> testInstantiations;
59 std::map<storm::RationalFunctionVariable, storm::RationalFunctionCoefficient> emptyInstantiation;
60 testInstantiations.push_back(emptyInstantiation);
61 for (auto const& param : parameters) {
62 std::vector<std::map<storm::RationalFunctionVariable, storm::RationalFunctionCoefficient>> newInstantiations;
63 for (auto point : testInstantiations) {
64 for (storm::RationalNumber x = storm::utility::convertNumber<storm::RationalNumber>(1e-6); x <= 1;
65 x += (1 - storm::utility::convertNumber<storm::RationalNumber>(1e-6)) / 10) {
66 std::map<storm::RationalFunctionVariable, storm::RationalFunctionCoefficient> newMap(point);
67 newMap[param] = storm::utility::convertNumber<storm::RationalFunctionCoefficient>(x);
68 newInstantiations.push_back(newMap);
69 }
70 }
71 testInstantiations = newInstantiations;
72 }
73
75 for (auto const& instantiation : testInstantiations) {
76 auto result = modelChecker.check(env, instantiation)->asExplicitQuantitativeCheckResult<double>()[initialStateModel];
77 auto resultSimple = modelCheckerSimple.check(env, instantiation)->asExplicitQuantitativeCheckResult<double>()[initialStateModel];
78 ASSERT_TRUE(storm::utility::isAlmostZero(result - resultSimple))
79 << "Results " << result << " and " << resultSimple << " are not the same but should be.";
80 }
81
82 auto region = storm::api::createRegion<storm::RationalFunction>("0.4", *dtmc);
83
85 pla.specify(env, dtmc, checkTask);
86 auto resultPLA = pla.getBoundAtInitState(env, region[0], storm::OptimizationDirection::Minimize);
87
89 plaSimple.specify(env, simpleDtmc, checkTask);
90 auto resultPLASimple = plaSimple.getBoundAtInitState(env, region[0], storm::OptimizationDirection::Minimize);
91
92 // no <= defined for RationalFunctions I suppose
93 ASSERT_TRUE(resultPLA < resultPLASimple || resultPLA == resultPLASimple) << "Worse PLA result with simplified DTMC";
94
95 // Check that simpleDtmc is in fact simple
96 for (uint64_t state = 0; state < simpleDtmc->getTransitionMatrix().getRowCount(); ++state) {
97 auto row = simpleDtmc->getTransitionMatrix().getRow(state);
98
99 std::set<storm::RationalFunctionVariable> variables;
100
101 for (auto const& entry : row) {
102 for (auto const& variable : entry.getValue().gatherVariables()) {
103 variables.emplace(variable);
104 }
105 }
106
107 if (variables.size() != 0) {
108 ASSERT_TRUE(variables.size() == 1);
109 auto parameter = *variables.begin();
110
111 auto parameterPol = storm::RawPolynomial(parameter);
112 auto parameterRational = storm::RationalFunction(carl::makePolynomial<storm::Polynomial>(parameterPol));
113 auto oneMinusParameter = storm::RawPolynomial(1) - parameterPol;
114 auto oneMinusParameterRational = storm::RationalFunction(carl::makePolynomial<storm::Polynomial>(oneMinusParameter));
115
116 uint64_t seenP = 0;
117 uint64_t seenOneMinusP = 0;
118
119 for (auto const& entry : row) {
120 if (!storm::utility::isZero(entry.getValue())) {
121 if (entry.getValue() == parameterRational) {
122 seenP++;
123 } else if (entry.getValue() == oneMinusParameterRational) {
124 seenOneMinusP++;
125 } else {
126 ASSERT_TRUE(false) << "Value " << entry.getValue() << " is not simple";
127 }
128 }
129 }
130
131 ASSERT_TRUE(seenP == 1 && seenOneMinusP == 1) << "State " << state << " not simple";
132 }
133 }
134}
135
136class BinaryDtmcTransformer : public ::testing::Test {
137 protected:
138 void SetUp() override {
139#ifndef STORM_HAVE_Z3
140 GTEST_SKIP() << "Z3 not available.";
141#endif
142 }
143};
144
146 std::string programFile = STORM_TEST_RESOURCES_DIR "/pdtmc/crowds3_5.pm";
147 std::string formulaAsString = "P=? [F \"observeIGreater1\"]";
148 std::string constantsAsString = ""; // e.g. pL=0.9,TOACK=0.5
149 testModelB(programFile, formulaAsString, constantsAsString);
150}
152 std::string programFile = STORM_TEST_RESOURCES_DIR "/pdtmc/nand-5-2.pm";
153 std::string formulaAsString = "P=? [F \"target\"]";
154 std::string constantsAsString = ""; // e.g. pL=0.9,TOACK=0.5
155 testModelB(programFile, formulaAsString, constantsAsString);
156}
158 std::string programFile = STORM_TEST_RESOURCES_DIR "/pdtmc/brp16_2.pm";
159 std::string formulaAsString = "P=? [F \"error\"]";
160 std::string constantsAsString = ""; // e.g. pL=0.9,TOACK=0.5
161 testModelB(programFile, formulaAsString, constantsAsString);
162}
TEST_F(BinaryDtmcTransformer, Crowds)
void testModelB(std::string programFile, std::string formulaAsString, std::string constantsAsString)
Class to efficiently check a formula on a parametric model with different parameter instantiations.
virtual std::unique_ptr< CheckResult > check(Environment const &env, storm::utility::parametric::Valuation< typename SparseModelType::ValueType > const &valuation) override
virtual void specify(Environment const &env, std::shared_ptr< storm::models::ModelBase > parametricModel, CheckTask< storm::logic::Formula, ValueType > const &checkTask, bool generateRegionSplitEstimates=false, bool allowModelSimplification=true) override
void specifyFormula(CheckTask< storm::logic::Formula, typename SparseModelType::ValueType > const &checkTask)
virtual SparseModelType::ValueType getBoundAtInitState(Environment const &env, storm::storage::ParameterRegion< typename SparseModelType::ValueType > const &region, storm::solver::OptimizationDirection const &dirForParameters) override
This class represents a discrete-time Markov chain.
Definition Dtmc.h:14
storm::storage::BitVector const & getStates(std::string const &label) const
Returns the sets of states labeled with the given label.
Definition Model.cpp:187
uint_fast64_t getNextSetIndex(uint_fast64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to true in the bit vector.
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)
std::set< storm::RationalFunctionVariable > getAllParameters(Model< storm::RationalFunction > const &model)
Get all parameters (probability, rewards, and rates) occurring in the model.
Definition Model.cpp:728
storm::prism::Program preprocess(storm::prism::Program const &program, std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantDefinitions)
Definition prism.cpp:19
bool isAlmostZero(ValueType const &a)
Definition constants.cpp:56
bool isZero(ValueType const &a)
Definition constants.cpp:41
carl::RationalFunction< Polynomial, true > RationalFunction
carl::MultivariatePolynomial< RationalFunctionCoefficient > RawPolynomial