Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SymbolicDtmcPrctlHelper.cpp
Go to the documentation of this file.
2
7
9
11
13#include "storm/utility/graph.h"
14
16
17namespace storm {
18namespace modelchecker {
19namespace helper {
20
21template<storm::dd::DdType DdType, typename ValueType>
24 storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative,
25 boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
26 // We need to identify the states which have to be taken out of the matrix, i.e. all states that have
27 // probability 0 and 1 of satisfying the until-formula.
28 STORM_LOG_TRACE("Found " << phiStates.getNonZeroCount() << " phi states and " << psiStates.getNonZeroCount() << " psi states.");
29 std::pair<storm::dd::Bdd<DdType>, storm::dd::Bdd<DdType>> statesWithProbability01 =
30 storm::utility::graph::performProb01(model, transitionMatrix.notZero(), phiStates, psiStates);
31 storm::dd::Bdd<DdType> maybeStates = !statesWithProbability01.first && !statesWithProbability01.second && model.getReachableStates();
32
33 STORM_LOG_INFO("Preprocessing: " << statesWithProbability01.first.getNonZeroCount() << " states with probability 0, "
34 << statesWithProbability01.second.getNonZeroCount() << " with probability 1 (" << maybeStates.getNonZeroCount()
35 << " states remaining).");
36
37 // Check whether we need to compute exact probabilities for some states.
38 if (qualitative) {
39 // Set the values for all maybe-states to 0.5 to indicate that their probability values are neither 0 nor 1.
40 return statesWithProbability01.second.template toAdd<ValueType>() +
41 maybeStates.template toAdd<ValueType>() * model.getManager().getConstant(storm::utility::convertNumber<ValueType>(0.5));
42 } else {
43 // If there are maybe states, we need to solve an equation system.
44 if (!maybeStates.isZero()) {
45 return computeUntilProbabilities(env, model, transitionMatrix, maybeStates, statesWithProbability01.second,
46 startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>())
47 : model.getManager().template getAddZero<ValueType>());
48 } else {
49 return statesWithProbability01.second.template toAdd<ValueType>();
50 }
51 }
52}
53
54template<storm::dd::DdType DdType, typename ValueType>
57 storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1,
58 boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
59 // Create the matrix and the vector for the equation system.
60 storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>();
61
62 // Start by cutting away all rows that do not belong to maybe states. Note that this leaves columns targeting
63 // non-maybe states in the matrix.
64 storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd;
65
66 // Then compute the vector that contains the one-step probabilities to a state with probability 1 for all
67 // maybe states.
68 storm::dd::Add<DdType, ValueType> prob1StatesAsColumn =
69 statesWithProbability1.template toAdd<ValueType>().swapVariables(model.getRowColumnMetaVariablePairs());
70 storm::dd::Add<DdType, ValueType> subvector = submatrix * prob1StatesAsColumn;
71 subvector = subvector.sumAbstract(model.getColumnVariables());
72
73 // Finally cut away all columns targeting non-maybe states and convert the matrix into the matrix needed
74 // for solving the equation system (i.e. compute (I-A)).
75 submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
78 submatrix = (model.getRowColumnIdentity() * maybeStatesAdd) - submatrix;
79 }
80
81 // Solve the equation system.
82 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
83 env, submatrix, maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
84 solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
85 storm::dd::Add<DdType, ValueType> result = solver->solveEquations(env, model.getManager().template getAddZero<ValueType>(), subvector);
86
87 return statesWithProbability1.template toAdd<ValueType>() + result;
88}
89
90template<storm::dd::DdType DdType, typename ValueType>
93 storm::dd::Bdd<DdType> const& psiStates, bool qualitative) {
95 computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative);
96 result = result.getDdManager().template getAddOne<ValueType>() - result;
97 return result;
98}
99
100template<storm::dd::DdType DdType, typename ValueType>
107
108template<storm::dd::DdType DdType, typename ValueType>
111 storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) {
112 // We need to identify the states which have to be taken out of the matrix, i.e. all states that have
113 // probability 0 or 1 of satisfying the until-formula.
114 storm::dd::Bdd<DdType> statesWithProbabilityGreater0 =
115 storm::utility::graph::performProbGreater0(model, transitionMatrix.notZero(), phiStates, psiStates, stepBound);
116 storm::dd::Bdd<DdType> maybeStates = statesWithProbabilityGreater0 && !psiStates && model.getReachableStates();
117
118 // If there are maybe states, we need to perform matrix-vector multiplications.
119 if (!maybeStates.isZero()) {
120 // Create the matrix and the vector for the equation system.
121 storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>();
122
123 // Start by cutting away all rows that do not belong to maybe states. Note that this leaves columns targeting
124 // non-maybe states in the matrix.
125 storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd;
126
127 // Then compute the vector that contains the one-step probabilities to a state with probability 1 for all
128 // maybe states.
129 storm::dd::Add<DdType, ValueType> prob1StatesAsColumn = psiStates.template toAdd<ValueType>().swapVariables(model.getRowColumnMetaVariablePairs());
130 storm::dd::Add<DdType, ValueType> subvector = (submatrix * prob1StatesAsColumn).sumAbstract(model.getColumnVariables());
131
132 // Finally cut away all columns targeting non-maybe states.
133 submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
134
135 // Perform the matrix-vector multiplication.
137 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
138 env, submatrix, maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
139 storm::dd::Add<DdType, ValueType> result = solver->multiply(model.getManager().template getAddZero<ValueType>(), &subvector, stepBound);
140
141 return psiStates.template toAdd<ValueType>() + result;
142 } else {
143 return psiStates.template toAdd<ValueType>();
144 }
145}
146
147template<storm::dd::DdType DdType, typename ValueType>
150 RewardModelType const& rewardModel, uint_fast64_t stepBound) {
151 // Only compute the result if the model has at least one reward this->getModel().
152 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
153
154 // Compute the reward vector to add in each step based on the available reward models.
155 storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables());
156
157 // Perform the matrix-vector multiplication.
159 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
160 env, transitionMatrix, model.getReachableStates(), model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
161 return solver->multiply(model.getManager().template getAddZero<ValueType>(), &totalRewardVector, stepBound);
162}
163
164template<storm::dd::DdType DdType, typename ValueType>
167 RewardModelType const& rewardModel, uint_fast64_t stepBound) {
168 // Only compute the result if the model has at least one reward this->getModel().
169 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
170 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
171
172 // Perform the matrix-vector multiplication.
174 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
175 env, transitionMatrix, model.getReachableStates(), model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
176 return solver->multiply(rewardModel.getStateRewardVector(), nullptr, stepBound);
177}
178
179template<storm::dd::DdType DdType, typename ValueType>
182 RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative,
183 boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
184 // Only compute the result if there is at least one reward model.
185 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
186
187 // Determine which states have a reward of infinity by definition.
188 storm::dd::Bdd<DdType> infinityStates = storm::utility::graph::performProb1(model, transitionMatrix.notZero(), model.getReachableStates(), targetStates);
189 infinityStates = !infinityStates && model.getReachableStates();
190 storm::dd::Bdd<DdType> maybeStates = (!targetStates && !infinityStates) && model.getReachableStates();
191
192 STORM_LOG_INFO("Preprocessing: " << infinityStates.getNonZeroCount() << " states with reward infinity, " << targetStates.getNonZeroCount()
193 << " target states (" << maybeStates.getNonZeroCount() << " states remaining).");
194
195 // Check whether we need to compute exact rewards for some states.
196 if (qualitative) {
197 // Set the values for all maybe-states to 1 to indicate that their reward values
198 // are neither 0 nor infinity.
199 return infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), model.getManager().template getAddZero<ValueType>()) +
200 maybeStates.template toAdd<ValueType>() * model.getManager().getConstant(storm::utility::one<ValueType>());
201 } else {
202 // If there are maybe states, we need to solve an equation system.
203 if (!maybeStates.isZero()) {
204 return computeReachabilityRewards(env, model, transitionMatrix, rewardModel, maybeStates, targetStates, infinityStates,
205 startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>())
206 : model.getManager().template getAddZero<ValueType>());
207 } else {
208 return infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()),
209 model.getManager().getConstant(storm::utility::zero<ValueType>()));
210 }
211 }
212}
213
214template<storm::dd::DdType DdType, typename ValueType>
217 RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates,
218 storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
219 // Create the matrix and the vector for the equation system.
220 storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>();
221
222 // Start by cutting away all rows that do not belong to maybe states. Note that this leaves columns targeting
223 // non-maybe states in the matrix.
224 storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd;
225
226 // Then compute the state reward vector to use in the computation.
227 storm::dd::Add<DdType, ValueType> subvector = rewardModel.getTotalRewardVector(maybeStatesAdd, submatrix, model.getColumnVariables());
228
229 // Finally cut away all columns targeting non-maybe states and convert the matrix into the matrix needed
230 // for solving the equation system (i.e. compute (I-A)).
231 submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
234 submatrix = (model.getRowColumnIdentity() * maybeStatesAdd) - submatrix;
235 }
236
237 // Solve the equation system.
238 std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(
239 env, submatrix, maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs());
240 solver->setLowerBound(storm::utility::zero<ValueType>());
242 solver->solveEquations(env, startValues ? startValues.get() : maybeStatesAdd.getDdManager().template getAddZero<ValueType>(), subvector);
243
244 return infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), result);
245}
246
247template<storm::dd::DdType DdType, typename ValueType>
250 storm::dd::Bdd<DdType> const& targetStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) {
251 RewardModelType rewardModel(model.getManager().getConstant(storm::utility::one<ValueType>()), boost::none, boost::none);
252 return computeReachabilityRewards(env, model, transitionMatrix, rewardModel, targetStates, qualitative, startValues);
253}
254
257
260} // namespace helper
261} // namespace modelchecker
262} // 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:292
Add< LibraryType, ValueType > sumAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Sum-abstracts from the given meta variables.
Definition Add.cpp:178
Bdd< LibraryType > notZero() const
Computes a BDD that represents the function in which all assignments with a function value unequal to...
Definition Add.cpp:431
bool isZero() const
Retrieves whether this DD represents the constant zero function.
Definition Bdd.cpp:547
virtual uint_fast64_t getNonZeroCount() const override
Retrieves the number of encodings that are mapped to a non-zero value.
Definition Bdd.cpp:513
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:302
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:113
DdManager< LibraryType > & getDdManager() const
Retrieves the manager that is responsible for this DD.
Definition Dd.cpp:39
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:46
storm::dd::DdManager< Type > & getManager() const
Retrieves the manager responsible for the DDs that represent this model.
Definition Model.cpp:92
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:197
storm::dd::Add< Type, ValueType > getRowColumnIdentity() const
Retrieves an ADD that represents the diagonal of the transition matrix.
Definition Model.cpp:243
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:223
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:192
storm::dd::Bdd< Type > const & getReachableStates() const
Retrieves the reachable states of the model.
Definition Model.cpp:102
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:29
#define STORM_LOG_TRACE(message)
Definition logging.h:17
#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:400
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:322
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:383
LabParser.cpp.
Definition cli.cpp:18