Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
BinaryDtmcTransformerTest.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
4#include <memory>
5#include <string>
6
14#include "storm/api/builder.h"
24
25void testModelB(std::string programFile, std::string formulaAsString, std::string constantsAsString) {
27 program = program.preprocess(constantsAsString);
28 std::vector<std::shared_ptr<const storm::logic::Formula>> formulas =
30 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model =
33 std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = model->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
34 uint64_t initialStateModel = dtmc->getStates("init").getNextSetIndex(0);
35
36 dtmc =
39
41 auto simpleDtmc = binaryDtmcTransformer.transform(*dtmc, true);
42
44 storm::Environment(), *dtmc);
45 modelChecker.specifyFormula(checkTask);
47 storm::Environment(), *simpleDtmc);
48 modelCheckerSimple.specifyFormula(checkTask);
49
50 auto parameters = storm::models::sparse::getAllParameters(*dtmc);
51
52 // Check if both DTMCs are equivalent just by sampling.
53 std::vector<std::map<storm::RationalFunctionVariable, storm::RationalFunctionCoefficient>> testInstantiations;
54 std::map<storm::RationalFunctionVariable, storm::RationalFunctionCoefficient> emptyInstantiation;
55 testInstantiations.push_back(emptyInstantiation);
56 for (auto const& param : parameters) {
57 std::vector<std::map<storm::RationalFunctionVariable, storm::RationalFunctionCoefficient>> newInstantiations;
58 for (auto point : testInstantiations) {
59 for (storm::RationalNumber x = storm::utility::convertNumber<storm::RationalNumber>(1e-6); x <= 1;
61 std::map<storm::RationalFunctionVariable, storm::RationalFunctionCoefficient> newMap(point);
63 newInstantiations.push_back(newMap);
64 }
65 }
66 testInstantiations = newInstantiations;
67 }
68
70 for (auto const& instantiation : testInstantiations) {
71 auto result = modelChecker.check(env, instantiation)->asExplicitQuantitativeCheckResult<storm::RationalNumber>()[initialStateModel];
72 auto resultSimple = modelCheckerSimple.check(env, instantiation)->asExplicitQuantitativeCheckResult<storm::RationalNumber>()[initialStateModel];
73 // The results are exact rationals, but we print their rounded double approximations for readability.
74 EXPECT_EQ(result, resultSimple) << "Results " << storm::utility::convertNumber<double>(result) << " and "
75 << storm::utility::convertNumber<double>(resultSimple) << " (both rounded) are not the same but should be.";
76 }
77
78 auto region = storm::api::createRegion<storm::RationalFunction>("0.4", *dtmc);
79
80 auto pla =
82 auto resultPLA = pla->getBoundAtInitState(env, region[0], storm::OptimizationDirection::Minimize);
83
84 auto plaSimple = storm::api::initializeRegionModelChecker<storm::RationalFunction>(env, simpleDtmc, checkTask,
86 auto resultPLASimple = plaSimple->getBoundAtInitState(env, region[0], storm::OptimizationDirection::Minimize);
87
88 ASSERT_TRUE(resultPLA == resultPLASimple) << "Different PLA result with simplified DTMC";
89
90 // Check that simpleDtmc is in fact simple
91 for (uint64_t state = 0; state < simpleDtmc->getTransitionMatrix().getRowCount(); ++state) {
92 auto row = simpleDtmc->getTransitionMatrix().getRow(state);
93
94 std::set<storm::RationalFunctionVariable> variables;
95
96 for (auto const& entry : row) {
97 for (auto const& variable : entry.getValue().gatherVariables()) {
98 variables.emplace(variable);
99 }
100 }
101
102 if (variables.size() != 0) {
103 ASSERT_TRUE(variables.size() == 1);
104 auto parameter = *variables.begin();
105
106 // Build the expected values with the cache of the model, just like the transformer does.
107 std::shared_ptr<storm::RawPolynomialCache> cache;
108 for (auto const& entry : row) {
109 if (!entry.getValue().isConstant()) {
110 cache = entry.getValue().nominator().pCache();
111 break;
112 }
113 }
114 ASSERT_TRUE(cache != nullptr);
115
116 auto parameterPol = storm::RawPolynomial(parameter);
117 auto parameterRational = storm::RationalFunction(storm::Polynomial(parameterPol, cache));
118 auto oneMinusParameter = storm::RawPolynomial(1) - parameterPol;
119 auto oneMinusParameterRational = storm::RationalFunction(storm::Polynomial(oneMinusParameter, cache));
120
121 uint64_t seenP = 0;
122 uint64_t seenOneMinusP = 0;
123
124 for (auto const& entry : row) {
125 if (!storm::utility::isZero(entry.getValue())) {
126 if (entry.getValue() == parameterRational) {
127 seenP++;
128 } else if (entry.getValue() == oneMinusParameterRational) {
129 seenOneMinusP++;
130 } else {
131 ASSERT_TRUE(false) << "Value " << entry.getValue() << " is not simple";
132 }
133 }
134 }
135
136 ASSERT_TRUE(seenP == 1 && seenOneMinusP == 1) << "State " << state << " not simple";
137 }
138 }
139}
140
141class BinaryDtmcTransformerTest : public ::testing::Test {
142 protected:
143 void SetUp() override {
144#ifndef STORM_HAVE_Z3
145 GTEST_SKIP() << "Z3 not available.";
146#endif
147 }
148};
149
151 std::string programFile = STORM_TEST_RESOURCES_DIR "/pdtmc/crowds3_5.pm";
152 std::string formulaAsString = "P=? [F \"observeIGreater1\"]";
153 std::string constantsAsString = ""; // e.g. pL=0.9,TOACK=0.5
154 testModelB(programFile, formulaAsString, constantsAsString);
155}
157 std::string programFile = STORM_TEST_RESOURCES_DIR "/pdtmc/nand-5-2.pm";
158 std::string formulaAsString = "P=? [F \"target\"]";
159 std::string constantsAsString = ""; // e.g. pL=0.9,TOACK=0.5
160 testModelB(programFile, formulaAsString, constantsAsString);
161}
163 std::string programFile = STORM_TEST_RESOURCES_DIR "/pdtmc/brp16_2.pm";
164 std::string formulaAsString = "P=? [F \"error\"]";
165 std::string constantsAsString = ""; // e.g. pL=0.9,TOACK=0.5
166 testModelB(programFile, formulaAsString, constantsAsString);
167}
TEST_F(BinaryDtmcTransformerTest, 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
void specifyFormula(CheckTask< storm::logic::Formula, typename SparseModelType::ValueType > const &checkTask)
This class represents a discrete-time Markov chain.
Definition Dtmc.h:16
storm::storage::BitVector const & getStates(std::string const &label) const
Returns the sets of states labeled with the given label.
Definition Model.cpp:216
Program preprocess(std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantDefinitions) const
Preprocesses the program by defining the given constant definitions, substituting constants and formu...
Definition Program.cpp:1170
uint64_t getNextSetIndex(uint64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to true in the bit vector.
std::shared_ptr< storm::models::sparse::Dtmc< RationalFunction > > transform(storm::models::sparse::Dtmc< RationalFunction > const &dtmc, bool keepStateValuations=false) const
Transforms a pDTMC that has linear transitions (e.g.
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::shared_ptr< storm::models::sparse::Model< ValueType > > buildSparseModel(storm::storage::SymbolicModelDescription const &model, storm::builder::BuilderOptions const &options, typename storm::builder::ExplicitModelBuilder< ValueType >::Options const &explorationOptions=typename storm::builder::ExplicitModelBuilder< ValueType >::Options())
Definition builder.h:117
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
storm::storage::ParameterRegion< ValueType > createRegion(std::string const &inputString, std::set< typename storm::storage::ParameterRegion< ValueType >::VariableType > const &consideredVariables)
Definition region.h:114
std::unique_ptr< storm::modelchecker::RegionModelChecker< ValueType > > initializeRegionModelChecker(Environment const &env, std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const &task, storm::modelchecker::RegionCheckEngine engine, bool allowModelSimplification=true, storm::pars::analysis::GraphPreservationStatus graphPreservationStatus=storm::pars::analysis::GraphPreservationStatus::GraphPreserving, bool preconditionsValidated=false, MonotonicitySetting monotonicitySetting=MonotonicitySetting(), std::optional< std::pair< std::set< typename storm::storage::ParameterRegion< ValueType >::VariableType >, std::set< typename storm::storage::ParameterRegion< ValueType >::VariableType > > > monotoneParameters=std::nullopt)
Definition region.h:238
std::shared_ptr< storm::models::sparse::Model< ValueType > > performBisimulationMinimization(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas={}, storm::bisimulation::Options const &options={})
@ ExactParameterLifting
Parameter lifting approach with exact arithmethics.
std::set< storm::RationalFunctionVariable > getAllParameters(Model< storm::RationalFunction > const &model)
Get all parameters (probability, rewards, and rates) occurring in the model.
Definition Model.cpp:757
bool isZero(ValueType const &a)
Definition constants.cpp:44
TargetType convertNumber(SourceType const &number)
carl::FactorizedPolynomial< RawPolynomial > Polynomial
carl::RationalFunction< Polynomial, true > RationalFunction
carl::MultivariatePolynomial< RationalFunctionCoefficient > RawPolynomial