Storm 1.12.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseParametricDtmcSimplifier.cpp
Go to the documentation of this file.
2
11#include "storm/utility/graph.h"
12
13namespace storm {
14namespace transformer {
15
16template<typename SparseModelType>
18 : SparseParametricModelSimplifier<SparseModelType>(model) {
19 // intentionally left empty
20}
21
22template<typename SparseModelType>
24 // Get the prob0, prob1 and the maybeStates
25 storm::modelchecker::SparsePropositionalModelChecker<SparseModelType> propositionalChecker(this->originalModel);
26 if (!propositionalChecker.canHandle(formula.getSubformula().asUntilFormula().getLeftSubformula()) ||
27 !propositionalChecker.canHandle(formula.getSubformula().asUntilFormula().getRightSubformula())) {
28 STORM_LOG_DEBUG("Can not simplify when Until-formula has non-propositional subformula(s). Formula: " << formula);
29 return false;
30 }
31 storm::storage::BitVector phiStates = std::move(propositionalChecker.check(formula.getSubformula().asUntilFormula().getLeftSubformula())
32 ->template asExplicitQualitativeCheckResult<typename SparseModelType::ValueType>()
33 .getTruthValuesVector());
34 storm::storage::BitVector psiStates = std::move(propositionalChecker.check(formula.getSubformula().asUntilFormula().getRightSubformula())
35 ->template asExplicitQualitativeCheckResult<typename SparseModelType::ValueType>()
36 .getTruthValuesVector());
37 std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01 =
38 storm::utility::graph::performProb01(this->originalModel, phiStates, psiStates);
39 // Only consider the maybestates that are reachable from one initial state without hopping over a target (i.e., prob1) state
41 this->originalModel.getTransitionMatrix(), this->originalModel.getInitialStates() & ~statesWithProbability01.first, ~statesWithProbability01.first,
42 statesWithProbability01.second);
43 storm::storage::BitVector maybeStates = reachableGreater0States & ~statesWithProbability01.second;
44
45 // obtain the resulting subsystem
46 storm::transformer::GoalStateMerger<SparseModelType> goalStateMerger(this->originalModel);
48 goalStateMerger.mergeTargetAndSinkStates(maybeStates, statesWithProbability01.second, statesWithProbability01.first);
49 this->simplifiedModel = mergerResult.model;
50 statesWithProbability01.second = storm::storage::BitVector(this->simplifiedModel->getNumberOfStates(), false);
51 if (mergerResult.targetState) {
52 statesWithProbability01.second.set(mergerResult.targetState.get(), true);
53 }
54 std::string targetLabel = "target";
55 while (this->simplifiedModel->hasLabel(targetLabel)) {
56 targetLabel = "_" + targetLabel;
57 }
58 this->simplifiedModel->getStateLabeling().addLabel(targetLabel, std::move(statesWithProbability01.second));
59
60 // obtain the simplified formula for the simplified model
61 auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula const>(targetLabel);
62 auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula const>(labelFormula, storm::logic::FormulaContext::Probability);
63 this->simplifiedFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula const>(eventuallyFormula, formula.getOperatorInformation());
64
65 // Eliminate all states for which all outgoing transitions are constant
66 storm::storage::BitVector considerForElimination = ~this->simplifiedModel->getInitialStates();
67 if (mergerResult.targetState) {
68 considerForElimination.set(*mergerResult.targetState, false);
69 }
70 if (mergerResult.sinkState) {
71 considerForElimination.set(*mergerResult.sinkState, false);
72 }
73 this->simplifiedModel = this->eliminateConstantDeterministicStates(*this->simplifiedModel, considerForElimination);
74
75 return true;
76}
77
78template<typename SparseModelType>
80 STORM_LOG_THROW(!formula.getSubformula().asBoundedUntilFormula().hasLowerBound(), storm::exceptions::NotSupportedException,
81 "Lower step bounds are not supported.");
82 STORM_LOG_THROW(formula.getSubformula().asBoundedUntilFormula().hasUpperBound(), storm::exceptions::UnexpectedException,
83 "Expected a bounded until formula with an upper bound.");
85 storm::exceptions::UnexpectedException, "Expected a bounded until formula with integral bounds.");
86
87 uint_fast64_t upperStepBound = formula.getSubformula().asBoundedUntilFormula().getUpperBound().evaluateAsInt();
89 STORM_LOG_THROW(upperStepBound > 0, storm::exceptions::UnexpectedException, "Expected a strict upper bound that is greater than zero.");
90 --upperStepBound;
91 }
92
93 // Get the prob0, target, and the maybeStates
94 storm::modelchecker::SparsePropositionalModelChecker<SparseModelType> propositionalChecker(this->originalModel);
95 if (!propositionalChecker.canHandle(formula.getSubformula().asBoundedUntilFormula().getLeftSubformula()) ||
96 !propositionalChecker.canHandle(formula.getSubformula().asBoundedUntilFormula().getRightSubformula())) {
97 STORM_LOG_DEBUG("Can not simplify when Until-formula has non-propositional subformula(s). Formula: " << formula);
98 return false;
99 }
100 storm::storage::BitVector phiStates = std::move(propositionalChecker.check(formula.getSubformula().asBoundedUntilFormula().getLeftSubformula())
101 ->template asExplicitQualitativeCheckResult<typename SparseModelType::ValueType>()
102 .getTruthValuesVector());
103 storm::storage::BitVector psiStates = std::move(propositionalChecker.check(formula.getSubformula().asBoundedUntilFormula().getRightSubformula())
104 ->template asExplicitQualitativeCheckResult<typename SparseModelType::ValueType>()
105 .getTruthValuesVector());
106 storm::storage::BitVector probGreater0States =
107 storm::utility::graph::performProbGreater0(this->originalModel.getBackwardTransitions(), phiStates, psiStates, true, upperStepBound);
108
109 // Only consider the maybestates that are reachable from one initial probGreater0 state within the given amount of steps and without hopping over a target
110 // state
111 storm::storage::BitVector reachableGreater0States =
112 storm::utility::graph::getReachableStates(this->originalModel.getTransitionMatrix(), this->originalModel.getInitialStates() & probGreater0States,
113 probGreater0States, psiStates, true, upperStepBound);
114 storm::storage::BitVector maybeStates = reachableGreater0States & ~psiStates;
115 storm::storage::BitVector prob0States = ~reachableGreater0States & ~psiStates;
116
117 // obtain the resulting subsystem
118 storm::transformer::GoalStateMerger<SparseModelType> goalStateMerger(this->originalModel);
120 goalStateMerger.mergeTargetAndSinkStates(maybeStates, psiStates, prob0States);
121 this->simplifiedModel = mergerResult.model;
122 psiStates = storm::storage::BitVector(this->simplifiedModel->getNumberOfStates(), false);
123 if (mergerResult.targetState) {
124 psiStates.set(mergerResult.targetState.get(), true);
125 }
126 std::string targetLabel = "target";
127 while (this->simplifiedModel->hasLabel(targetLabel)) {
128 targetLabel = "_" + targetLabel;
129 }
130 this->simplifiedModel->getStateLabeling().addLabel(targetLabel, std::move(psiStates));
131
132 // obtain the simplified formula for the simplified model
133 auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula const>(targetLabel);
134 auto boundedUntilFormula =
135 std::make_shared<storm::logic::BoundedUntilFormula const>(storm::logic::Formula::getTrueFormula(), labelFormula, boost::none,
139 this->simplifiedFormula = std::make_shared<storm::logic::ProbabilityOperatorFormula const>(boundedUntilFormula, formula.getOperatorInformation());
140
141 return true;
142}
143
144template<typename SparseModelType>
146 typename SparseModelType::RewardModelType const& originalRewardModel =
147 formula.hasRewardModelName() ? this->originalModel.getRewardModel(formula.getRewardModelName()) : this->originalModel.getUniqueRewardModel();
148
149 // Get the prob1 and the maybeStates
150 storm::modelchecker::SparsePropositionalModelChecker<SparseModelType> propositionalChecker(this->originalModel);
151 if (!propositionalChecker.canHandle(formula.getSubformula().asEventuallyFormula().getSubformula())) {
152 STORM_LOG_DEBUG("Can not simplify when reachability reward formula has non-propositional subformula(s). Formula: " << formula);
153 return false;
154 }
155 storm::storage::BitVector targetStates = std::move(propositionalChecker.check(formula.getSubformula().asEventuallyFormula().getSubformula())
156 ->template asExplicitQualitativeCheckResult<typename SparseModelType::ValueType>()
157 .getTruthValuesVector());
158 // The set of target states can be extended by the states that reach target with probability 1 without collecting any reward
159 targetStates = storm::utility::graph::performProb1(this->originalModel.getBackwardTransitions(),
160 originalRewardModel.getStatesWithZeroReward(this->originalModel.getTransitionMatrix()), targetStates);
162 this->originalModel.getBackwardTransitions(), storm::storage::BitVector(this->originalModel.getNumberOfStates(), true), targetStates);
163 storm::storage::BitVector infinityStates = ~statesWithProb1;
164 // Only consider the states that are reachable from an initial state without hopping over a target state
166 this->originalModel.getTransitionMatrix(), this->originalModel.getInitialStates() & statesWithProb1, statesWithProb1, targetStates);
167 storm::storage::BitVector maybeStates = reachableStates & ~targetStates;
168
169 // obtain the resulting subsystem
170 std::vector<std::string> rewardModelNameAsVector(
171 1, formula.hasRewardModelName() ? formula.getRewardModelName() : this->originalModel.getRewardModels().begin()->first);
172 storm::transformer::GoalStateMerger<SparseModelType> goalStateMerger(this->originalModel);
174 goalStateMerger.mergeTargetAndSinkStates(maybeStates, targetStates, infinityStates, rewardModelNameAsVector);
175 this->simplifiedModel = mergerResult.model;
176 targetStates = storm::storage::BitVector(this->simplifiedModel->getNumberOfStates(), false);
177 if (mergerResult.targetState) {
178 targetStates.set(mergerResult.targetState.get(), true);
179 }
180 std::string targetLabel = "target";
181 while (this->simplifiedModel->hasLabel(targetLabel)) {
182 targetLabel = "_" + targetLabel;
183 }
184 this->simplifiedModel->getStateLabeling().addLabel(targetLabel, std::move(targetStates));
185
186 // obtain the simplified formula for the simplified model
187 auto labelFormula = std::make_shared<storm::logic::AtomicLabelFormula const>(targetLabel);
188 auto eventuallyFormula = std::make_shared<storm::logic::EventuallyFormula const>(labelFormula, storm::logic::FormulaContext::Reward);
189 this->simplifiedFormula =
190 std::make_shared<storm::logic::RewardOperatorFormula const>(eventuallyFormula, rewardModelNameAsVector.front(), formula.getOperatorInformation());
191
192 // Eliminate all states for which all outgoing transitions are constant
193 storm::storage::BitVector considerForElimination = ~this->simplifiedModel->getInitialStates();
194 if (mergerResult.targetState) {
195 considerForElimination.set(*mergerResult.targetState, false);
196 }
197 if (mergerResult.sinkState) {
198 considerForElimination.set(*mergerResult.sinkState, false);
199 }
200 this->simplifiedModel = this->eliminateConstantDeterministicStates(*this->simplifiedModel, considerForElimination, rewardModelNameAsVector.front());
201
202 return true;
203}
204
205template<typename SparseModelType>
208 storm::exceptions::UnexpectedException, "Expected a cumulative reward formula with integral bound.");
209
210 typename SparseModelType::RewardModelType const& originalRewardModel =
211 formula.hasRewardModelName() ? this->originalModel.getRewardModel(formula.getRewardModelName()) : this->originalModel.getUniqueRewardModel();
212
213 uint_fast64_t stepBound = formula.getSubformula().asCumulativeRewardFormula().getBound().evaluateAsInt();
215 STORM_LOG_THROW(stepBound > 0, storm::exceptions::UnexpectedException, "Expected a strict upper bound that is greater than zero.");
216 --stepBound;
217 }
218
219 // Get the states with non-zero reward
221 this->originalModel.getBackwardTransitions(), storm::storage::BitVector(this->originalModel.getNumberOfStates(), true),
222 ~originalRewardModel.getStatesWithZeroReward(this->originalModel.getTransitionMatrix()), true, stepBound);
223 storm::storage::BitVector zeroRewardStates = ~maybeStates;
224 storm::storage::BitVector noStates(this->originalModel.getNumberOfStates(), false);
225
226 // obtain the resulting subsystem
227 std::vector<std::string> rewardModelNameAsVector(
228 1, formula.hasRewardModelName() ? formula.getRewardModelName() : this->originalModel.getRewardModels().begin()->first);
229 storm::transformer::GoalStateMerger<SparseModelType> goalStateMerger(this->originalModel);
231 goalStateMerger.mergeTargetAndSinkStates(maybeStates, noStates, zeroRewardStates, rewardModelNameAsVector);
232 this->simplifiedModel = mergerResult.model;
233
234 // obtain the simplified formula for the simplified model
235 this->simplifiedFormula = storm::logic::CloneVisitor().clone(formula);
236
237 return true;
238}
239
241} // namespace transformer
242} // namespace storm
virtual bool isIntegerLiteralExpression() const
int_fast64_t evaluateAsInt(Valuation const *valuation=nullptr) const
Evaluates the expression under the valuation of variables given by the valuation and returns the resu...
BaseExpression const & getBaseExpression() const
Retrieves the base expression underlying this expression object.
Formula const & getRightSubformula() const
Formula const & getLeftSubformula() const
storm::expressions::Expression const & getUpperBound(unsigned i=0) const
bool isUpperBoundStrict(unsigned i=0) const
std::shared_ptr< Formula > clone(Formula const &f) const
storm::expressions::Expression const & getBound() const
UntilFormula & asUntilFormula()
Definition Formula.cpp:325
BoundedUntilFormula & asBoundedUntilFormula()
Definition Formula.cpp:333
static std::shared_ptr< Formula const > getTrueFormula()
Definition Formula.cpp:213
EventuallyFormula & asEventuallyFormula()
Definition Formula.cpp:341
CumulativeRewardFormula & asCumulativeRewardFormula()
Definition Formula.cpp:429
OperatorInformation const & getOperatorInformation() const
std::string const & getRewardModelName() const
Retrieves the name of the reward model this property refers to (if any).
bool hasRewardModelName() const
Retrieves whether the reward model refers to a specific reward model.
Formula const & getSubformula() const
Formula const & getSubformula() const
virtual std::unique_ptr< CheckResult > check(Environment const &env, CheckTask< storm::logic::Formula, SolutionType > const &checkTask)
Checks the provided formula.
virtual bool canHandle(CheckTask< storm::logic::Formula, SolutionType > const &checkTask) const override
Determines whether the model checker can handle the given verification task.
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
ReturnType mergeTargetAndSinkStates(storm::storage::BitVector const &maybeStates, storm::storage::BitVector const &targetStates, storm::storage::BitVector const &sinkStates, std::vector< std::string > const &selectedRewardModels=std::vector< std::string >(), boost::optional< storm::storage::BitVector > const &choiceFilter=boost::none) const
This class performs different steps to simplify the given (parametric) model.
virtual bool simplifyForReachabilityRewards(storm::logic::RewardOperatorFormula const &formula) override
virtual bool simplifyForCumulativeRewards(storm::logic::RewardOperatorFormula const &formula) override
virtual bool simplifyForUntilProbabilities(storm::logic::ProbabilityOperatorFormula const &formula) override
virtual bool simplifyForBoundedUntilProbabilities(storm::logic::ProbabilityOperatorFormula const &formula) override
This class performs different steps to simplify the given (parametric) model.
#define STORM_LOG_DEBUG(message)
Definition logging.h:18
#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:393
storm::storage::BitVector getReachableStates(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &constraintStates, storm::storage::BitVector const &targetStates, bool useStepBound, uint_fast64_t maximalSteps, boost::optional< storm::storage::BitVector > const &choiceFilter)
Performs a forward depth-first search through the underlying graph structure to identify the states t...
Definition graph.cpp:41
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:315
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:376
boost::optional< uint_fast64_t > sinkState
std::shared_ptr< SparseModelType > model
boost::optional< uint_fast64_t > targetState