Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseDtmcInstantiationModelChecker.cpp
Go to the documentation of this file.
2
13
14namespace storm {
15namespace modelchecker {
16
17template<typename SparseModelType, typename ConstantType>
19 : SparseInstantiationModelChecker<SparseModelType, ConstantType>(parametricModel), modelInstantiator(parametricModel) {
20 // Intentionally left empty
21}
22
23template<typename SparseModelType, typename ConstantType>
26 STORM_LOG_THROW(this->currentCheckTask, storm::exceptions::InvalidStateException, "Checking has been invoked but no property has been specified before.");
27 auto const& instantiatedModel = modelInstantiator.instantiate(valuation);
28 if (instantiatedModel.isExact()) {
29 STORM_LOG_THROW(instantiatedModel.getTransitionMatrix().isProbabilistic(storm::utility::zero<ConstantType>()),
30 storm::exceptions::InvalidArgumentException, "Instantiation point is invalid as the transition matrix becomes non-stochastic.");
31 } else {
32 auto const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
33 STORM_LOG_THROW(instantiatedModel.getTransitionMatrix().isProbabilistic(storm::utility::convertNumber<ConstantType>(generalSettings.getPrecision())),
34 storm::exceptions::InvalidArgumentException, "Instantiation point is invalid as the transition matrix becomes non-stochastic.");
35 }
36
38
39 // Check if there are some optimizations implemented for the specified property
40 if (this->currentCheckTask->getFormula().isInFragment(storm::logic::reachability())) {
41 return checkReachabilityProbabilityFormula(env, modelChecker);
42 } else if (this->currentCheckTask->getFormula().isInFragment(storm::logic::propositional()
47 return checkReachabilityRewardFormula(env, modelChecker);
48 } else if (this->currentCheckTask->getFormula().isInFragment(storm::logic::propositional()
55 return checkBoundedUntilFormula(env, modelChecker);
56 } else {
57 return modelChecker.check(env, *this->currentCheckTask);
58 }
59}
60
61template<typename SparseModelType, typename ConstantType>
64 if (!this->currentCheckTask->getHint().isExplicitModelCheckerHint()) {
65 this->currentCheckTask->setHint(std::make_shared<ExplicitModelCheckerHint<ConstantType>>());
66 }
67 ExplicitModelCheckerHint<ConstantType>& hint = this->currentCheckTask->getHint().template asExplicitModelCheckerHint<ConstantType>();
68
69 if (this->getInstantiationsAreGraphPreserving() && !hint.hasMaybeStates()) {
70 // Perform purely qualitative analysis once
71 std::vector<ConstantType> qualitativeResult;
72 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
73 auto newCheckTask = *this->currentCheckTask;
74 newCheckTask.setQualitative(true);
75 newCheckTask.setOnlyInitialStatesRelevant(false);
76 qualitativeResult = modelChecker.check(env, newCheckTask)->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector();
77 } else {
78 auto newCheckTask = this->currentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula());
79 newCheckTask.setQualitative(true);
80 newCheckTask.setOnlyInitialStatesRelevant(false);
81 qualitativeResult =
82 modelChecker.computeProbabilities(env, newCheckTask)->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector();
83 }
84 storm::storage::BitVector maybeStates = storm::utility::vector::filter<ConstantType>(qualitativeResult, [](ConstantType const& value) -> bool {
85 return !(storm::utility::isZero<ConstantType>(value) || storm::utility::isOne<ConstantType>(value));
86 });
87 hint.setMaybeStates(std::move(maybeStates));
88 hint.setResultHint(std::move(qualitativeResult));
90 }
91
92 std::unique_ptr<CheckResult> result;
93 // Check the formula and store the result as a hint for the next call.
94 // For qualitative properties, we still want a quantitative result hint. Hence we perform the check on the subformula
95 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
96 result = modelChecker.check(env, *this->currentCheckTask);
97 hint.setResultHint(result->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector());
98 } else {
99 auto newCheckTask = this->currentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula())
100 .setOnlyInitialStatesRelevant(false);
101 std::unique_ptr<CheckResult> quantitativeResult = modelChecker.computeProbabilities(env, newCheckTask);
102 result = quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().compareAgainstBound(
103 this->currentCheckTask->getFormula().asOperatorFormula().getComparisonType(),
104 this->currentCheckTask->getFormula().asOperatorFormula().template getThresholdAs<ConstantType>());
105 hint.setResultHint(std::move(quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector()));
106 }
107
108 return result;
109}
110
111template<typename SparseModelType, typename ConstantType>
114 if (!this->currentCheckTask->getHint().isExplicitModelCheckerHint()) {
115 this->currentCheckTask->setHint(std::make_shared<ExplicitModelCheckerHint<ConstantType>>());
116 }
117 ExplicitModelCheckerHint<ConstantType>& hint = this->currentCheckTask->getHint().template asExplicitModelCheckerHint<ConstantType>();
118
119 if (this->getInstantiationsAreGraphPreserving() && !hint.hasMaybeStates()) {
120 // Perform purely qualitative analysis once
121 std::vector<ConstantType> qualitativeResult;
122 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
123 auto newCheckTask = *this->currentCheckTask;
124 newCheckTask.setQualitative(true);
125 newCheckTask.setOnlyInitialStatesRelevant(false);
126 qualitativeResult = modelChecker.check(env, newCheckTask)->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector();
127 } else {
128 auto newCheckTask = this->currentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula());
129 newCheckTask.setQualitative(true);
130 newCheckTask.setOnlyInitialStatesRelevant(false);
131 qualitativeResult = modelChecker.computeRewards(env, newCheckTask)->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector();
132 }
133 storm::storage::BitVector maybeStates = storm::utility::vector::filter<ConstantType>(qualitativeResult, [](ConstantType const& value) -> bool {
134 return !(storm::utility::isZero<ConstantType>(value) || storm::utility::isInfinity<ConstantType>(value));
135 });
136 hint.setMaybeStates(std::move(maybeStates));
137 hint.setResultHint(std::move(qualitativeResult));
138 hint.setComputeOnlyMaybeStates(true);
139 }
140
141 std::unique_ptr<CheckResult> result;
142
143 // Check the formula and store the result as a hint for the next call.
144 // For qualitative properties, we still want a quantitative result hint. Hence we perform the check on the subformula
145 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
146 result = modelChecker.check(env, *this->currentCheckTask);
147 this->currentCheckTask->getHint().template asExplicitModelCheckerHint<ConstantType>().setResultHint(
148 result->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector());
149 } else {
150 auto newCheckTask = this->currentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula())
151 .setOnlyInitialStatesRelevant(false);
152 std::unique_ptr<CheckResult> quantitativeResult = modelChecker.computeRewards(env, newCheckTask);
153 result = quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().compareAgainstBound(
154 this->currentCheckTask->getFormula().asOperatorFormula().getComparisonType(),
155 this->currentCheckTask->getFormula().asOperatorFormula().template getThresholdAs<ConstantType>());
156 this->currentCheckTask->getHint().template asExplicitModelCheckerHint<ConstantType>().setResultHint(
157 std::move(quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector()));
158 }
159
160 return result;
161}
162
163template<typename SparseModelType, typename ConstantType>
166 if (!this->currentCheckTask->getHint().isExplicitModelCheckerHint()) {
167 this->currentCheckTask->setHint(std::make_shared<ExplicitModelCheckerHint<ConstantType>>());
168 }
169 std::unique_ptr<CheckResult> result;
170 ExplicitModelCheckerHint<ConstantType>& hint = this->currentCheckTask->getHint().template asExplicitModelCheckerHint<ConstantType>();
171
172 if (this->getInstantiationsAreGraphPreserving() && !hint.hasMaybeStates()) {
173 // We extract the maybestates from the quantitative result
174 // For qualitative properties, we still need a quantitative result. Hence we perform the check on the subformula
175 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
176 result = modelChecker.check(env, *this->currentCheckTask);
177 hint.setResultHint(result->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector());
178 } else {
179 auto newCheckTask = this->currentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula())
180 .setOnlyInitialStatesRelevant(false);
181 std::unique_ptr<CheckResult> quantitativeResult = modelChecker.computeProbabilities(env, newCheckTask);
182 result = quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().compareAgainstBound(
183 this->currentCheckTask->getFormula().asOperatorFormula().getComparisonType(),
184 this->currentCheckTask->getFormula().asOperatorFormula().template getThresholdAs<ConstantType>());
185 hint.setResultHint(std::move(quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector()));
186 }
187
189 // We need to exclude the target states from the maybe states.
190 // Note that we can not consider the states with probability one since a state might reach a target state with prob 1 within >0 steps
191 std::unique_ptr<CheckResult> subFormulaResult =
192 modelChecker.check(env, this->currentCheckTask->getFormula().asOperatorFormula().getSubformula().asBoundedUntilFormula().getRightSubformula());
193 maybeStates = maybeStates & ~(subFormulaResult->asExplicitQualitativeCheckResult().getTruthValuesVector());
194 hint.setMaybeStates(std::move(maybeStates));
195 hint.setComputeOnlyMaybeStates(true);
196 } else {
197 result = modelChecker.check(env, *this->currentCheckTask);
198 }
199
200 return result;
201}
202
203template<typename SparseModelType, typename ConstantType>
206 auto const& instantiatedModel = modelInstantiator.instantiate(valuation);
207 // Should be moved further outside.
208 if (instantiatedModel.isExact()) {
209 return instantiatedModel.getTransitionMatrix().isProbabilistic(storm::utility::zero<ConstantType>());
210 } else {
211 auto const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
212 return instantiatedModel.getTransitionMatrix().isProbabilistic(storm::utility::convertNumber<ConstantType>(generalSettings.getPrecision()));
213 }
214}
215
218
219} // namespace modelchecker
220} // namespace storm
FragmentSpecification & setStepBoundedUntilFormulasAllowed(bool newValue)
FragmentSpecification & setOperatorAtTopLevelRequired(bool newValue)
FragmentSpecification & setTimeBoundedUntilFormulasAllowed(bool newValue)
FragmentSpecification & setReachabilityRewardFormulasAllowed(bool newValue)
FragmentSpecification & setRewardOperatorsAllowed(bool newValue)
FragmentSpecification & setBoundedUntilFormulasAllowed(bool newValue)
FragmentSpecification & setNestedOperatorsAllowed(bool newValue)
FragmentSpecification & setProbabilityOperatorsAllowed(bool newValue)
virtual std::unique_ptr< CheckResult > check(Environment const &env, CheckTask< storm::logic::Formula, SolutionType > const &checkTask)
Checks the provided formula.
This class contains information that might accelerate the model checking process.
void setResultHint(boost::optional< std::vector< ValueType > > const &resultHint)
void setMaybeStates(storm::storage::BitVector const &maybeStates)
std::vector< ValueType > const & getResultHint() const
Class to efficiently check a formula on a parametric model with different parameter instantiations.
std::unique_ptr< CheckResult > checkReachabilityRewardFormula(Environment const &env, storm::modelchecker::SparseDtmcPrctlModelChecker< storm::models::sparse::Dtmc< ConstantType > > &modelChecker)
virtual std::unique_ptr< CheckResult > check(Environment const &env, storm::utility::parametric::Valuation< typename SparseModelType::ValueType > const &valuation) override
virtual bool isWellDefined(storm::utility::parametric::Valuation< typename SparseModelType::ValueType > const &valuation) override
Checks if the given valuation is valid for the current model.
std::unique_ptr< CheckResult > checkBoundedUntilFormula(Environment const &env, storm::modelchecker::SparseDtmcPrctlModelChecker< storm::models::sparse::Dtmc< ConstantType > > &modelChecker)
std::unique_ptr< CheckResult > checkReachabilityProbabilityFormula(Environment const &env, storm::modelchecker::SparseDtmcPrctlModelChecker< storm::models::sparse::Dtmc< ConstantType > > &modelChecker)
Class to efficiently check a formula on a parametric model with different parameter instantiations.
This class represents a discrete-time Markov chain.
Definition Dtmc.h:13
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
FragmentSpecification propositional()
FragmentSpecification reachability()
std::map< typename VariableType< FunctionType >::type, typename CoefficientType< FunctionType >::type > Valuation
Definition parametric.h:43
storm::storage::BitVector filterGreaterZero(std::vector< T > const &values)
Retrieves a bit vector containing all the indices for which the value at this position is greater tha...
Definition vector.h:512