Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseMdpInstantiationModelChecker.cpp
Go to the documentation of this file.
2
11#include "storm/utility/graph.h"
13
14namespace storm {
15namespace modelchecker {
16
17template<typename SparseModelType, typename ConstantType>
19 bool produceScheduler)
20 : SparseInstantiationModelChecker<SparseModelType, ConstantType>(parametricModel), modelInstantiator(parametricModel), produceScheduler(produceScheduler) {
21 // Intentionally left empty
22}
23
24template<typename SparseModelType, typename ConstantType>
27 STORM_LOG_THROW(this->currentCheckTask, storm::exceptions::InvalidStateException, "Checking has been invoked but no property has been specified before.");
28 auto const& instantiatedModel = modelInstantiator.instantiate(valuation);
29 STORM_LOG_THROW(instantiatedModel.getTransitionMatrix().isProbabilistic(), storm::exceptions::InvalidArgumentException,
30 "Instantiation point is invalid as the transition matrix becomes non-stochastic.");
32
33 // Check if there are some optimizations implemented for the specified property
34 if (this->currentCheckTask->getFormula().isInFragment(storm::logic::reachability())) {
35 return checkReachabilityProbabilityFormula(env, modelChecker, instantiatedModel);
36 } else if (this->currentCheckTask->getFormula().isInFragment(storm::logic::propositional()
41 return checkReachabilityRewardFormula(env, modelChecker, instantiatedModel);
42 } else if (this->currentCheckTask->getFormula().isInFragment(storm::logic::propositional()
49 return checkBoundedUntilFormula(env, modelChecker);
50 } else {
51 return modelChecker.check(env, *this->currentCheckTask);
52 }
53}
54
55template<typename SparseModelType, typename ConstantType>
58 storm::models::sparse::Mdp<ConstantType> const& instantiatedModel) {
59 if (produceScheduler) {
60 this->currentCheckTask->setProduceSchedulers(true);
61 }
62
63 if (!this->currentCheckTask->getHint().isExplicitModelCheckerHint()) {
64 this->currentCheckTask->setHint(std::make_shared<ExplicitModelCheckerHint<ConstantType>>());
65 }
66 ExplicitModelCheckerHint<ConstantType>& hint = this->currentCheckTask->getHint().template asExplicitModelCheckerHint<ConstantType>();
67
68 if (this->getInstantiationsAreGraphPreserving() && !hint.hasMaybeStates()) {
69 // Perform purely qualitative analysis once
70 std::vector<ConstantType> qualitativeResult;
71 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
72 auto newCheckTask = *this->currentCheckTask;
73 newCheckTask.setQualitative(true);
74 newCheckTask.setOnlyInitialStatesRelevant(false);
75 newCheckTask.setProduceSchedulers(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 newCheckTask.setProduceSchedulers(false);
82 qualitativeResult =
83 modelChecker.computeProbabilities(env, newCheckTask)->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector();
84 }
85 storm::storage::BitVector maybeStates = storm::utility::vector::filter<ConstantType>(qualitativeResult, [](ConstantType const& value) -> bool {
86 return !(storm::utility::isZero<ConstantType>(value) || storm::utility::isOne<ConstantType>(value));
87 });
88 hint.setMaybeStates(std::move(maybeStates));
89 hint.setResultHint(std::move(qualitativeResult));
91
92 // Check if there can be end components within the maybestates
93 if (storm::solver::minimize(this->currentCheckTask->getOptimizationDirection()) ||
94 storm::utility::graph::performProb1A(instantiatedModel.getTransitionMatrix(), instantiatedModel.getTransitionMatrix().getRowGroupIndices(),
95 instantiatedModel.getBackwardTransitions(), hint.getMaybeStates(), ~hint.getMaybeStates())
96 .full()) {
98 }
99 }
100
101 std::unique_ptr<CheckResult> result;
102 // Check the formula and store the result as a hint for the next call.
103 // For qualitative properties, we still want a quantitative result hint. Hence we perform the check on the subformula
104 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
105 result = modelChecker.check(env, *this->currentCheckTask);
106 hint.setResultHint(result->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector());
107 if (produceScheduler) {
108 storm::storage::Scheduler<ConstantType> const& scheduler = result->template asExplicitQuantitativeCheckResult<ConstantType>().getScheduler();
109 hint.setSchedulerHint(dynamic_cast<storm::storage::Scheduler<ConstantType> const&>(scheduler));
110 }
111 } else {
112 auto newCheckTask = this->currentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula())
113 .setOnlyInitialStatesRelevant(false);
114 std::unique_ptr<storm::modelchecker::CheckResult> quantitativeResult = modelChecker.computeProbabilities(env, newCheckTask);
115 result = quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().compareAgainstBound(
116 this->currentCheckTask->getFormula().asOperatorFormula().getComparisonType(),
117 this->currentCheckTask->getFormula().asOperatorFormula().template getThresholdAs<ConstantType>());
118 hint.setResultHint(std::move(quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector()));
119 if (produceScheduler) {
120 storm::storage::Scheduler<ConstantType>& scheduler = quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().getScheduler();
121 hint.setSchedulerHint(std::move(dynamic_cast<storm::storage::Scheduler<ConstantType>&>(scheduler)));
122 }
123 }
124
125 return result;
126}
127
128template<typename SparseModelType, typename ConstantType>
131 storm::models::sparse::Mdp<ConstantType> const& instantiatedModel) {
132 this->currentCheckTask->setProduceSchedulers(true);
133
134 if (!this->currentCheckTask->getHint().isExplicitModelCheckerHint()) {
135 this->currentCheckTask->setHint(std::make_shared<ExplicitModelCheckerHint<ConstantType>>());
136 }
137 ExplicitModelCheckerHint<ConstantType>& hint = this->currentCheckTask->getHint().template asExplicitModelCheckerHint<ConstantType>();
138
139 if (this->getInstantiationsAreGraphPreserving() && !hint.hasMaybeStates()) {
140 // Perform purely qualitative analysis once
141 std::vector<ConstantType> qualitativeResult;
142 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
143 auto newCheckTask = *this->currentCheckTask;
144 newCheckTask.setQualitative(true);
145 newCheckTask.setOnlyInitialStatesRelevant(false);
146 newCheckTask.setProduceSchedulers(false);
147 qualitativeResult = modelChecker.check(env, newCheckTask)->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector();
148 } else {
149 auto newCheckTask = this->currentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula());
150 newCheckTask.setQualitative(true);
151 newCheckTask.setOnlyInitialStatesRelevant(false);
152 newCheckTask.setProduceSchedulers(false);
153 qualitativeResult = modelChecker.computeRewards(env, newCheckTask)->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector();
154 }
155 storm::storage::BitVector maybeStates = storm::utility::vector::filter<ConstantType>(qualitativeResult, [](ConstantType const& value) -> bool {
156 return !(storm::utility::isZero<ConstantType>(value) || storm::utility::isInfinity<ConstantType>(value));
157 });
158 hint.setMaybeStates(std::move(maybeStates));
159 hint.setResultHint(std::move(qualitativeResult));
160 hint.setComputeOnlyMaybeStates(true);
161
162 // Check if there can be end components within the maybestates
163 if (storm::solver::maximize(this->currentCheckTask->getOptimizationDirection()) ||
164 storm::utility::graph::performProb1A(instantiatedModel.getTransitionMatrix(), instantiatedModel.getTransitionMatrix().getRowGroupIndices(),
165 instantiatedModel.getBackwardTransitions(), hint.getMaybeStates(), ~hint.getMaybeStates())
166 .full()) {
168 }
169 }
170
171 std::unique_ptr<CheckResult> result;
172 // Check the formula and store the result as a hint for the next call.
173 // For qualitative properties, we still want a quantitative result hint. Hence we perform the check on the subformula
174 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
175 result = modelChecker.check(env, *this->currentCheckTask);
176 storm::storage::Scheduler<ConstantType> const& scheduler = result->template asExplicitQuantitativeCheckResult<ConstantType>().getScheduler();
177 hint.setResultHint(result->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector());
178 hint.setSchedulerHint(dynamic_cast<storm::storage::Scheduler<ConstantType> const&>(scheduler));
179 } else {
180 auto newCheckTask = this->currentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula())
181 .setOnlyInitialStatesRelevant(false);
182 std::unique_ptr<storm::modelchecker::CheckResult> quantitativeResult = modelChecker.computeRewards(env, newCheckTask);
183 result = quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().compareAgainstBound(
184 this->currentCheckTask->getFormula().asOperatorFormula().getComparisonType(),
185 this->currentCheckTask->getFormula().asOperatorFormula().template getThresholdAs<ConstantType>());
186 storm::storage::Scheduler<ConstantType>& scheduler = quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().getScheduler();
187 hint.setResultHint(std::move(quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector()));
188 hint.setSchedulerHint(std::move(dynamic_cast<storm::storage::Scheduler<ConstantType>&>(scheduler)));
189 }
190
191 return result;
192}
193
194template<typename SparseModelType, typename ConstantType>
197 if (!this->currentCheckTask->getHint().isExplicitModelCheckerHint()) {
198 this->currentCheckTask->setHint(std::make_shared<ExplicitModelCheckerHint<ConstantType>>());
199 }
200 std::unique_ptr<CheckResult> result;
201 ExplicitModelCheckerHint<ConstantType>& hint = this->currentCheckTask->getHint().template asExplicitModelCheckerHint<ConstantType>();
202
203 if (this->getInstantiationsAreGraphPreserving() && !hint.hasMaybeStates()) {
204 // We extract the maybestates from the quantitative result
205 // For qualitative properties, we still need a quantitative result. Hence we perform the check on the subformula
206 if (this->currentCheckTask->getFormula().asOperatorFormula().hasQuantitativeResult()) {
207 result = modelChecker.check(env, *this->currentCheckTask);
208 hint.setResultHint(result->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector());
209 } else {
210 auto newCheckTask = this->currentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula())
211 .setOnlyInitialStatesRelevant(false);
212 std::unique_ptr<CheckResult> quantitativeResult = modelChecker.computeProbabilities(env, newCheckTask);
213 result = quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().compareAgainstBound(
214 this->currentCheckTask->getFormula().asOperatorFormula().getComparisonType(),
215 this->currentCheckTask->getFormula().asOperatorFormula().template getThresholdAs<ConstantType>());
216 hint.setResultHint(std::move(quantitativeResult->template asExplicitQuantitativeCheckResult<ConstantType>().getValueVector()));
217 }
219 // We need to exclude the target states from the maybe states.
220 // 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
221 std::unique_ptr<CheckResult> subFormulaResult =
222 modelChecker.check(env, this->currentCheckTask->getFormula().asOperatorFormula().getSubformula().asBoundedUntilFormula().getRightSubformula());
223 maybeStates = maybeStates & ~(subFormulaResult->asExplicitQualitativeCheckResult().getTruthValuesVector());
224 hint.setMaybeStates(std::move(maybeStates));
225 hint.setComputeOnlyMaybeStates(true);
226 } else {
227 result = modelChecker.check(env, *this->currentCheckTask);
228 }
229 return result;
230}
231
234
235} // namespace modelchecker
236} // 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 setSchedulerHint(boost::optional< storage::Scheduler< ValueType > > const &schedulerHint)
void setResultHint(boost::optional< std::vector< ValueType > > const &resultHint)
storm::storage::BitVector const & getMaybeStates() const
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.
Class to efficiently check a formula on a parametric model with different parameter instantiations.
std::unique_ptr< CheckResult > checkReachabilityProbabilityFormula(Environment const &env, storm::modelchecker::SparseMdpPrctlModelChecker< storm::models::sparse::Mdp< ConstantType > > &modelChecker, storm::models::sparse::Mdp< ConstantType > const &instantiatedModel)
virtual std::unique_ptr< CheckResult > check(Environment const &env, storm::utility::parametric::Valuation< typename SparseModelType::ValueType > const &valuation) override
std::unique_ptr< CheckResult > checkBoundedUntilFormula(Environment const &env, storm::modelchecker::SparseMdpPrctlModelChecker< storm::models::sparse::Mdp< ConstantType > > &modelChecker)
std::unique_ptr< CheckResult > checkReachabilityRewardFormula(Environment const &env, storm::modelchecker::SparseMdpPrctlModelChecker< storm::models::sparse::Mdp< ConstantType > > &modelChecker, storm::models::sparse::Mdp< ConstantType > const &instantiatedModel)
SparseMdpInstantiationModelChecker(SparseModelType const &parametricModel, bool produceScheduler=true)
This class represents a (discrete-time) Markov decision process.
Definition Mdp.h:14
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Definition Model.cpp:197
storm::storage::SparseMatrix< ValueType > getBackwardTransitions() const
Retrieves the backward transition relation of the model, i.e.
Definition Model.cpp:152
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:18
This class defines which action is chosen in a particular state of a non-deterministic model.
Definition Scheduler.h:18
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
FragmentSpecification propositional()
FragmentSpecification reachability()
bool constexpr maximize(OptimizationDirection d)
bool constexpr minimize(OptimizationDirection d)
storm::storage::BitVector performProb1A(storm::models::sparse::NondeterministicModel< T, RM > const &model, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 1 of satisfying phi until psi under all possible re...
Definition graph.cpp:997
std::map< typename VariableType< FunctionType >::type, typename CoefficientType< FunctionType >::type > Valuation
Definition parametric.h:41
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:552
LabParser.cpp.
Definition cli.cpp:18