Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SymbolicDtmcPrctlHelper.cpp
Go to the documentation of this file.
2
12#include "storm/utility/graph.h"
13
14namespace storm {
15namespace modelchecker {
16namespace helper {
17
18template<storm::dd::DdType DdType, typename ValueType>
21 storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative,
22 boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
23 // We need to identify the states which have to be taken out of the matrix, i.e. all states that have
24 // probability 0 and 1 of satisfying the until-formula.
25 STORM_LOG_TRACE("Found " << phiStates.getNonZeroCount() << " phi states and " << psiStates.getNonZeroCount() << " psi states.");
26 std::pair<storm::dd::Bdd<DdType>, storm::dd::Bdd<DdType>> statesWithProbability01 =
27 storm::utility::graph::performProb01(model, transitionMatrix.notZero(), phiStates, psiStates);
28 storm::dd::Bdd<DdType> maybeStates = !statesWithProbability01.first && !statesWithProbability01.second && model.getReachableStates();
29
30 STORM_LOG_INFO("Preprocessing: " << statesWithProbability01.first.getNonZeroCount() << " states with probability 0, "
31 << statesWithProbability01.second.getNonZeroCount() << " with probability 1 (" << maybeStates.getNonZeroCount()
32 << " states remaining).");
33
34 // Check whether we need to compute exact probabilities for some states.
35 if (qualitative) {
36 // Set the values for all maybe-states to 0.5 to indicate that their probability values are neither 0 nor 1.
37 return statesWithProbability01.second.template toAdd<ValueType>() +
38 maybeStates.template toAdd<ValueType>() * model.getManager().getConstant(storm::utility::convertNumber<ValueType>(0.5));
39 } else {
40 // If there are maybe states, we need to solve an equation system.
41 if (!maybeStates.isZero()) {
42 return computeUntilProbabilities(env, model, transitionMatrix, maybeStates, statesWithProbability01.second,
43 startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>())
44 : model.getManager().template getAddZero<ValueType>());
45 } else {
46 return statesWithProbability01.second.template toAdd<ValueType>();
47 }
48 }
49}
50
51template<storm::dd::DdType DdType, typename ValueType>
54 storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1,
55 boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
56 // Create the matrix and the vector for the equation system.
57 storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>();
58
59 // Start by cutting away all rows that do not belong to maybe states. Note that this leaves columns targeting
60 // non-maybe states in the matrix.
61 storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd;
62
63 // Then compute the vector that contains the one-step probabilities to a state with probability 1 for all
64 // maybe states.
65 storm::dd::Add<DdType, ValueType> prob1StatesAsColumn =
66 statesWithProbability1.template toAdd<ValueType>().swapVariables(model.getRowColumnMetaVariablePairs());
67 storm::dd::Add<DdType, ValueType> subvector = submatrix * prob1StatesAsColumn;
68 subvector = subvector.sumAbstract(model.getColumnVariables());
69
70 // Finally cut away all columns targeting non-maybe states and convert the matrix into the matrix needed
71 // for solving the equation system (i.e. compute (I-A)).
72 submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
75 submatrix = (model.getRowColumnIdentity() * maybeStatesAdd) - submatrix;
76 }
77
78 // Solve the equation system.
79 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
80 env, submatrix, maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
81 solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
82 storm::dd::Add<DdType, ValueType> result = solver->solveEquations(env, model.getManager().template getAddZero<ValueType>(), subvector);
83
84 return statesWithProbability1.template toAdd<ValueType>() + result;
85}
86
87template<storm::dd::DdType DdType, typename ValueType>
90 storm::dd::Bdd<DdType> const& psiStates, bool qualitative) {
92 computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative);
93 result = result.getDdManager().template getAddOne<ValueType>() - result;
94 return result;
95}
96
97template<storm::dd::DdType DdType, typename ValueType>
104
105template<storm::dd::DdType DdType, typename ValueType>
108 storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) {
109 // We need to identify the states which have to be taken out of the matrix, i.e. all states that have
110 // probability 0 or 1 of satisfying the until-formula.
111 storm::dd::Bdd<DdType> statesWithProbabilityGreater0 =
112 storm::utility::graph::performProbGreater0(model, transitionMatrix.notZero(), phiStates, psiStates, stepBound);
113 storm::dd::Bdd<DdType> maybeStates = statesWithProbabilityGreater0 && !psiStates && model.getReachableStates();
114
115 // If there are maybe states, we need to perform matrix-vector multiplications.
116 if (!maybeStates.isZero()) {
117 // Create the matrix and the vector for the equation system.
118 storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>();
119
120 // Start by cutting away all rows that do not belong to maybe states. Note that this leaves columns targeting
121 // non-maybe states in the matrix.
122 storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd;
123
124 // Then compute the vector that contains the one-step probabilities to a state with probability 1 for all
125 // maybe states.
126 storm::dd::Add<DdType, ValueType> prob1StatesAsColumn = psiStates.template toAdd<ValueType>().swapVariables(model.getRowColumnMetaVariablePairs());
127 storm::dd::Add<DdType, ValueType> subvector = (submatrix * prob1StatesAsColumn).sumAbstract(model.getColumnVariables());
128
129 // Finally cut away all columns targeting non-maybe states.
130 submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
131
132 // Perform the matrix-vector multiplication.
134 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
135 env, submatrix, maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
136 storm::dd::Add<DdType, ValueType> result = solver->multiply(model.getManager().template getAddZero<ValueType>(), &subvector, stepBound);
137
138 return psiStates.template toAdd<ValueType>() + result;
139 } else {
140 return psiStates.template toAdd<ValueType>();
141 }
142}
143
144template<storm::dd::DdType DdType, typename ValueType>
147 RewardModelType const& rewardModel, uint_fast64_t stepBound) {
148 // Only compute the result if the model has at least one reward this->getModel().
149 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
150
151 // Compute the reward vector to add in each step based on the available reward models.
152 storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables());
153
154 // Perform the matrix-vector multiplication.
156 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
157 env, transitionMatrix, model.getReachableStates(), model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
158 return solver->multiply(model.getManager().template getAddZero<ValueType>(), &totalRewardVector, stepBound);
159}
160
161template<storm::dd::DdType DdType, typename ValueType>
164 RewardModelType const& rewardModel, uint_fast64_t stepBound) {
165 // Only compute the result if the model has at least one reward this->getModel().
166 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
167 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
168
169 // Perform the matrix-vector multiplication.
171 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
172 env, transitionMatrix, model.getReachableStates(), model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
173 return solver->multiply(rewardModel.getStateRewardVector(), nullptr, stepBound);
174}
175
176template<storm::dd::DdType DdType, typename ValueType>
179 RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative,
180 boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
181 // Only compute the result if there is at least one reward model.
182 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
183
184 // Determine which states have a reward of infinity by definition.
185 storm::dd::Bdd<DdType> infinityStates = storm::utility::graph::performProb1(model, transitionMatrix.notZero(), model.getReachableStates(), targetStates);
186 infinityStates = !infinityStates && model.getReachableStates();
187 storm::dd::Bdd<DdType> maybeStates = (!targetStates && !infinityStates) && model.getReachableStates();
188
189 STORM_LOG_INFO("Preprocessing: " << infinityStates.getNonZeroCount() << " states with reward infinity, " << targetStates.getNonZeroCount()
190 << " target states (" << maybeStates.getNonZeroCount() << " states remaining).");
191
192 // Check whether we need to compute exact rewards for some states.
193 if (qualitative) {
194 // Set the values for all maybe-states to 1 to indicate that their reward values
195 // are neither 0 nor infinity.
196 return infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), model.getManager().template getAddZero<ValueType>()) +
197 maybeStates.template toAdd<ValueType>() * model.getManager().getConstant(storm::utility::one<ValueType>());
198 } else {
199 // If there are maybe states, we need to solve an equation system.
200 if (!maybeStates.isZero()) {
201 return computeReachabilityRewards(env, model, transitionMatrix, rewardModel, maybeStates, targetStates, infinityStates,
202 startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>())
203 : model.getManager().template getAddZero<ValueType>());
204 } else {
205 return infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()),
206 model.getManager().getConstant(storm::utility::zero<ValueType>()));
207 }
208 }
209}
210
211template<storm::dd::DdType DdType, typename ValueType>
214 RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates,
215 storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
216 // Create the matrix and the vector for the equation system.
217 storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>();
218
219 // Start by cutting away all rows that do not belong to maybe states. Note that this leaves columns targeting
220 // non-maybe states in the matrix.
221 storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd;
222
223 // Then compute the state reward vector to use in the computation.
224 storm::dd::Add<DdType, ValueType> subvector = rewardModel.getTotalRewardVector(maybeStatesAdd, submatrix, model.getColumnVariables());
225
226 // Finally cut away all columns targeting non-maybe states and convert the matrix into the matrix needed
227 // for solving the equation system (i.e. compute (I-A)).
228 submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
231 submatrix = (model.getRowColumnIdentity() * maybeStatesAdd) - submatrix;
232 }
233
234 // Solve the equation system.
235 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
236 env, submatrix, maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
237 solver->setLowerBound(storm::utility::zero<ValueType>());
239 solver->solveEquations(env, startValues ? startValues.get() : maybeStatesAdd.getDdManager().template getAddZero<ValueType>(), subvector);
240
241 return infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), result);
242}
243
244template<storm::dd::DdType DdType, typename ValueType>
247 storm::dd::Bdd<DdType> const& targetStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
248 RewardModelType rewardModel(model.getManager().getConstant(storm::utility::one<ValueType>()), boost::none, boost::none);
249 return computeReachabilityRewards(env, model, transitionMatrix, rewardModel, targetStates, qualitative, startValues);
250}
251
254
257} // namespace helper
258} // namespace modelchecker
259} // namespace storm
Add< LibraryType, ValueType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the ADD.
Definition Add.cpp:288
Add< LibraryType, ValueType > sumAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Sum-abstracts from the given meta variables.
Definition Add.cpp:174
Bdd< LibraryType > notZero() const
Computes a BDD that represents the function in which all assignments with a function value unequal to...
Definition Add.cpp:427
bool isZero() const
Retrieves whether this DD represents the constant zero function.
Definition Bdd.cpp:541
virtual uint_fast64_t getNonZeroCount() const override
Retrieves the number of encodings that are mapped to a non-zero value.
Definition Bdd.cpp:507
Bdd< LibraryType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the BDD.
Definition Bdd.cpp:296
Bdd< LibraryType > ite(Bdd< LibraryType > const &thenBdd, Bdd< LibraryType > const &elseBdd) const
Performs an if-then-else with the given operands, i.e.
Definition Bdd.cpp:107
DdManager< LibraryType > & getDdManager() const
Retrieves the manager that is responsible for this DD.
Definition Dd.cpp:38
static storm::dd::Add< DdType, ValueType > computeUntilProbabilities(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &phiStates, storm::dd::Bdd< DdType > const &psiStates, bool qualitative, boost::optional< storm::dd::Add< DdType, ValueType > > const &startValues=boost::none)
static storm::dd::Add< DdType, ValueType > computeCumulativeRewards(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepBound)
static storm::dd::Add< DdType, ValueType > computeNextProbabilities(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &nextStates)
static storm::dd::Add< DdType, ValueType > computeBoundedUntilProbabilities(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &phiStates, storm::dd::Bdd< DdType > const &psiStates, uint_fast64_t stepBound)
static storm::dd::Add< DdType, ValueType > computeReachabilityTimes(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &targetStates, bool qualitative, boost::optional< storm::dd::Add< DdType, ValueType > > const &startValues=boost::none)
static storm::dd::Add< DdType, ValueType > computeReachabilityRewards(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, RewardModelType const &rewardModel, storm::dd::Bdd< DdType > const &targetStates, bool qualitative, boost::optional< storm::dd::Add< DdType, ValueType > > const &startValues=boost::none)
static storm::dd::Add< DdType, ValueType > computeGloballyProbabilities(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &psiStates, bool qualitative)
static storm::dd::Add< DdType, ValueType > computeInstantaneousRewards(Environment const &env, storm::models::symbolic::Model< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepBound)
Base class for all symbolic models.
Definition Model.h:42
storm::dd::DdManager< Type > & getManager() const
Retrieves the manager responsible for the DDs that represent this model.
Definition Model.cpp:87
std::set< storm::expressions::Variable > const & getColumnVariables() const
Retrieves the meta variables used to encode the columns of the transition matrix and the vector indic...
Definition Model.cpp:192
storm::dd::Add< Type, ValueType > getRowColumnIdentity() const
Retrieves an ADD that represents the diagonal of the transition matrix.
Definition Model.cpp:233
std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const & getRowColumnMetaVariablePairs() const
Retrieves the pairs of row and column meta variables.
Definition Model.cpp:218
std::set< storm::expressions::Variable > const & getRowVariables() const
Retrieves the meta variables used to encode the rows of the transition matrix and the vector indices.
Definition Model.cpp:187
storm::dd::Bdd< Type > const & getReachableStates() const
Retrieves the reachable states of the model.
Definition Model.cpp:97
bool hasStateRewards() const
Retrieves whether the reward model has state rewards.
storm::dd::Add< Type, ValueType > getTotalRewardVector(storm::dd::Add< Type, ValueType > const &transitionMatrix, std::set< storm::expressions::Variable > const &columnVariables) const
Creates a vector representing the complete reward vector based on the state-, state-action- and trans...
bool empty() const
Retrieves whether the reward model is empty.
storm::dd::Add< Type, ValueType > const & getStateRewardVector() const
Retrieves the state rewards of the reward model.
virtual std::unique_ptr< storm::solver::SymbolicLinearEquationSolver< DdType, ValueType > > create(Environment const &env) const override
LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const &env) const
#define STORM_LOG_INFO(message)
Definition logging.h:24
#define STORM_LOG_TRACE(message)
Definition logging.h:12
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01(storm::models::sparse::DeterministicModel< T > const &model, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi i...
Definition graph.cpp:399
storm::storage::BitVector performProbGreater0(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps)
Performs a backward depth-first search trough the underlying graph structure of the given model to de...
Definition graph.cpp:321
storm::storage::BitVector performProb1(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &, storm::storage::BitVector const &psiStates, storm::storage::BitVector const &statesWithProbabilityGreater0)
Computes the set of states of the given model for which all paths lead to the given set of target sta...
Definition graph.cpp:382