Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseDtmcPrctlHelper.cpp
Go to the documentation of this file.
2
9#include "storm/io/export.h"
28#include "storm/utility/graph.h"
31
32namespace storm {
33namespace modelchecker {
34namespace helper {
35
36template<>
37std::map<storm::storage::sparse::state_type, storm::RationalFunction> SparseDtmcPrctlHelper<storm::RationalFunction>::computeRewardBoundedValues(
39 std::shared_ptr<storm::logic::OperatorFormula const> /*rewardBoundedFormula*/) {
40 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The specified property is not supported by this value type.");
41 return std::map<storm::storage::sparse::state_type, storm::RationalFunction>();
42}
43
44template<typename ValueType, typename RewardModelType>
45std::map<storm::storage::sparse::state_type, ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeRewardBoundedValues(
46 Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula) {
47 storm::utility::Stopwatch swAll(true), swBuild, swCheck;
48
50
51 // Get lower and upper bounds for the solution.
52 auto lowerBound = rewardUnfolding.getLowerObjectiveBound();
53 auto upperBound = rewardUnfolding.getUpperObjectiveBound();
54
55 // Initialize epoch models
56 auto initEpoch = rewardUnfolding.getStartEpoch();
57 auto epochOrder = rewardUnfolding.getEpochComputationOrder(initEpoch);
58
59 // initialize data that will be needed for each epoch
60 std::vector<ValueType> x, b;
61 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSolver;
62
63 Environment preciseEnv = env;
64 ValueType precision = rewardUnfolding.getRequiredEpochModelPrecision(
65 initEpoch, storm::utility::convertNumber<ValueType>(storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision()));
66 preciseEnv.solver().setLinearEquationSolverPrecision(storm::utility::convertNumber<storm::RationalNumber>(precision));
67
68 // In case of cdf export we store the necessary data.
69 std::vector<std::vector<ValueType>> cdfData;
70
71 // Set the correct equation problem format.
73 rewardUnfolding.setEquationSystemFormatForEpochModel(linearEquationSolverFactory.getEquationProblemFormat(preciseEnv));
74
75 storm::utility::ProgressMeasurement progress("epochs");
76 progress.setMaxCount(epochOrder.size());
77 progress.startNewMeasurement(0);
78 uint64_t numCheckedEpochs = 0;
79 for (auto const& epoch : epochOrder) {
80 swBuild.start();
81 auto& epochModel = rewardUnfolding.setCurrentEpoch(epoch);
82 swBuild.stop();
83 swCheck.start();
84 rewardUnfolding.setSolutionForCurrentEpoch(epochModel.analyzeSingleObjective(preciseEnv, x, b, linEqSolver, lowerBound, upperBound));
85 swCheck.stop();
86 if (storm::settings::getModule<storm::settings::modules::IOSettings>().isExportCdfSet() &&
87 !rewardUnfolding.getEpochManager().hasBottomDimension(epoch)) {
88 std::vector<ValueType> cdfEntry;
89 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
90 uint64_t offset = rewardUnfolding.getDimension(i).boundType == helper::rewardbounded::DimensionBoundType::LowerBound ? 1 : 0;
91 cdfEntry.push_back(storm::utility::convertNumber<ValueType>(rewardUnfolding.getEpochManager().getDimensionOfEpoch(epoch, i) + offset) *
92 rewardUnfolding.getDimension(i).scalingFactor);
93 }
94 cdfEntry.push_back(rewardUnfolding.getInitialStateResult(epoch));
95 cdfData.push_back(std::move(cdfEntry));
96 }
97 ++numCheckedEpochs;
98 progress.updateProgress(numCheckedEpochs);
100 break;
101 }
102 }
103
104 std::map<storm::storage::sparse::state_type, ValueType> result;
105 for (auto initState : model.getInitialStates()) {
106 result[initState] = rewardUnfolding.getInitialStateResult(initEpoch, initState);
107 }
108
109 swAll.stop();
110
111 if (storm::settings::getModule<storm::settings::modules::IOSettings>().isExportCdfSet()) {
112 std::vector<std::string> headers;
113 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
114 headers.push_back(rewardUnfolding.getDimension(i).formula->toString());
115 }
116 headers.push_back("Result");
117 storm::io::exportDataToCSVFile<ValueType, std::string, std::string>(
118 storm::settings::getModule<storm::settings::modules::IOSettings>().getExportCdfDirectory() + "cdf.csv", cdfData, headers);
119 }
120
121 if (storm::settings::getModule<storm::settings::modules::CoreSettings>().isShowStatisticsSet()) {
122 STORM_PRINT_AND_LOG("---------------------------------\n");
123 STORM_PRINT_AND_LOG("Statistics:\n");
124 STORM_PRINT_AND_LOG("---------------------------------\n");
125 STORM_PRINT_AND_LOG(" #checked epochs: " << epochOrder.size() << ".\n");
126 STORM_PRINT_AND_LOG(" overall Time: " << swAll << ".\n");
127 STORM_PRINT_AND_LOG("Epoch Model building Time: " << swBuild << ".\n");
128 STORM_PRINT_AND_LOG("Epoch Model checking Time: " << swCheck << ".\n");
129 STORM_PRINT_AND_LOG("---------------------------------\n");
130 }
131
132 return result;
133}
134
135template<typename ValueType, typename RewardModelType>
138 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
139 bool qualitative, ModelCheckerHint const& hint) {
140 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>());
141
142 // We need to identify the maybe states (states which have a probability for satisfying the until formula
143 // that is strictly between 0 and 1) and the states that satisfy the formula with probability 1.
144 storm::storage::BitVector maybeStates, statesWithProbability1;
145
146 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
147 maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
148
149 // Treat the states with probability one
150 std::vector<ValueType> const& resultsForNonMaybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getResultHint();
151 statesWithProbability1 = storm::storage::BitVector(maybeStates.size(), false);
152 storm::storage::BitVector nonMaybeStates = ~maybeStates;
153 for (auto state : nonMaybeStates) {
154 if (storm::utility::isOne(resultsForNonMaybeStates[state])) {
155 statesWithProbability1.set(state, true);
156 result[state] = storm::utility::one<ValueType>();
157 } else {
158 STORM_LOG_THROW(storm::utility::isZero(resultsForNonMaybeStates[state]), storm::exceptions::IllegalArgumentException,
159 "Expected that the result hint specifies probabilities in {0,1} for non-maybe states");
160 }
161 }
162
163 STORM_LOG_INFO("Preprocessing: " << statesWithProbability1.getNumberOfSetBits() << " states with probability 1 (" << maybeStates.getNumberOfSetBits()
164 << " states remaining).");
165 } else {
166 // Get all states that have probability 0 and 1 of satisfying the until-formula.
167 std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01 =
168 storm::utility::graph::performProb01(backwardTransitions, phiStates, psiStates);
169 storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first);
170 statesWithProbability1 = std::move(statesWithProbability01.second);
171 maybeStates = ~(statesWithProbability0 | statesWithProbability1);
172
173 STORM_LOG_INFO("Preprocessing: " << statesWithProbability1.getNumberOfSetBits() << " states with probability 1, "
174 << statesWithProbability0.getNumberOfSetBits() << " with probability 0 (" << maybeStates.getNumberOfSetBits()
175 << " states remaining).");
176
177 // Set values of resulting vector that are known exactly.
178 storm::utility::vector::setVectorValues<ValueType>(result, statesWithProbability0, storm::utility::zero<ValueType>());
179 storm::utility::vector::setVectorValues<ValueType>(result, statesWithProbability1, storm::utility::one<ValueType>());
180 }
181
182 // Check if the values of the maybe states are relevant for the SolveGoal
183 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(maybeStates);
184
185 // Check whether we need to compute exact probabilities for some states.
186 if (qualitative || maybeStatesNotRelevant) {
187 // Set the values for all maybe-states to 0.5 to indicate that their probability values are neither 0 nor 1.
188 storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, storm::utility::convertNumber<ValueType>(0.5));
189 } else {
190 if (!maybeStates.empty()) {
191 // In this case we have to compute the probabilities.
192
193 // Check whether we need to convert the input to equation system format.
195 bool convertToEquationSystem =
197
198 // We can eliminate the rows and columns from the original transition probability matrix.
199 storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, convertToEquationSystem);
200 if (convertToEquationSystem) {
201 // Converting the matrix from the fixpoint notation to the form needed for the equation
202 // system. That is, we go from x = A*x + b to (I-A)x = b.
203 submatrix.convertToEquationSystem();
204 }
205
206 // Initialize the x vector with the hint (if available) or with 0.5 for each element.
207 // This is the initial guess for the iterative solvers. It should be safe as for all
208 // 'maybe' states we know that the probability is strictly larger than 0.
209 std::vector<ValueType> x;
210 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasResultHint()) {
211 x = storm::utility::vector::filterVector(hint.template asExplicitModelCheckerHint<ValueType>().getResultHint(), maybeStates);
212 } else {
213 x = std::vector<ValueType>(maybeStates.getNumberOfSetBits(), storm::utility::convertNumber<ValueType>(0.5));
214 }
215
216 // Prepare the right-hand side of the equation system. For entry i this corresponds to
217 // the accumulated probability of going from state i to some 'yes' state.
218 std::vector<ValueType> b = transitionMatrix.getConstrainedRowSumVector(maybeStates, statesWithProbability1);
219
220 // Now solve the created system of linear equations.
221 goal.restrictRelevantValues(maybeStates);
222 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver =
223 storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix));
224 solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
225 solver->solveEquations(env, x, b);
226
227 // Set values of resulting vector according to result.
228 storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, x);
229 }
230 }
231 return result;
232}
233
234template<typename ValueType, typename RewardModelType>
237 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
238 uint_fast64_t numberOfStates = transitionMatrix.getRowCount();
239 std::vector<ValueType> result(numberOfStates, storm::utility::zero<ValueType>());
240
241 // All states are relevant
242 storm::storage::BitVector relevantStates(numberOfStates, true);
243
244 // Compute exact probabilities for some states.
245 if (!relevantStates.empty()) {
246 // Check whether we need to convert the input to equation system format.
248 bool convertToEquationSystem =
250
251 storm::storage::SparseMatrix<ValueType> submatrix(transitionMatrix);
252 submatrix.makeRowsAbsorbing(phiStates);
253 submatrix.makeRowsAbsorbing(psiStates);
254 // submatrix.deleteDiagonalEntries(psiStates);
255 // storm::storage::BitVector failState(numberOfStates, false);
256 // failState.set(0, true);
257 submatrix.deleteDiagonalEntries();
258 submatrix = submatrix.transpose();
259 submatrix = submatrix.getSubmatrix(true, relevantStates, relevantStates, convertToEquationSystem);
260
261 if (convertToEquationSystem) {
262 // Converting the matrix from the fixpoint notation to the form needed for the equation
263 // system. That is, we go from x = A*x + b to (I-A)x = b.
264 submatrix.convertToEquationSystem();
265 }
266
267 // Initialize the x vector with 0.5 for each element.
268 // This is the initial guess for the iterative solvers. It should be safe as for all
269 // 'maybe' states we know that the probability is strictly larger than 0.
270 std::vector<ValueType> x = std::vector<ValueType>(relevantStates.getNumberOfSetBits(), storm::utility::convertNumber<ValueType>(0.5));
271
272 // Prepare the right-hand side of the equation system.
273 std::vector<ValueType> b(relevantStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
274 // Set initial states
275 size_t i = 0;
276 ValueType initDist = storm::utility::one<ValueType>() / storm::utility::convertNumber<ValueType>(initialStates.getNumberOfSetBits());
277 for (auto state : relevantStates) {
278 if (initialStates.get(state)) {
279 b[i] = initDist;
280 }
281 ++i;
282 }
283
284 // Now solve the created system of linear equations.
285 goal.restrictRelevantValues(relevantStates);
286 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver =
287 storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix));
288 solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
289 solver->solveEquations(env, x, b);
290
291 // Set values of resulting vector according to result.
292 storm::utility::vector::setVectorValues<ValueType>(result, relevantStates, x);
293 }
294 return result;
295}
296
297template<typename ValueType, typename RewardModelType>
300 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative) {
301 goal.oneMinus();
302 std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions,
303 storm::storage::BitVector(transitionMatrix.getRowCount(), true), ~psiStates, qualitative);
304 for (auto& entry : result) {
305 entry = storm::utility::one<ValueType>() - entry;
306 }
307 return result;
308}
309
310template<typename ValueType, typename RewardModelType>
312 Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) {
313 // Create the vector with which to multiply and initialize it correctly.
314 std::vector<ValueType> result(transitionMatrix.getRowCount());
315 storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>());
316
317 // Perform one single matrix-vector multiplication.
318 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
319 multiplier->multiply(env, result, nullptr, result);
320 return result;
321}
322
323template<typename ValueType, typename RewardModelType>
326 RewardModelType const& rewardModel, uint_fast64_t stepBound) {
327 // Initialize result to the null vector.
328 std::vector<ValueType> result(transitionMatrix.getRowCount());
329
330 // Compute the reward vector to add in each step based on the available reward models.
331 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix);
332
333 // Perform the matrix vector multiplication as often as required by the formula bound.
334 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
335 multiplier->repeatedMultiply(env, result, &totalRewardVector, stepBound);
336
337 return result;
338}
339
340template<typename ValueType, typename RewardModelType>
343 RewardModelType const& rewardModel, uint_fast64_t stepCount) {
344 // Only compute the result if the model has a state-based reward this->getModel().
345 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
346 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
347
348 // Initialize result to state rewards of the model.
349 std::vector<ValueType> result = rewardModel.getStateRewardVector();
350
351 // Perform the matrix vector multiplication as often as required by the formula bound.
352 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
353 multiplier->repeatedMultiply(env, result, nullptr, stepCount);
354
355 return result;
356}
357
358template<typename ValueType, typename RewardModelType>
361 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, bool qualitative, ModelCheckerHint const& hint) {
362 // Identify the states from which only states with zero reward are reachable.
363 // We can then compute reachability rewards assuming these states as target set.
364 storm::storage::BitVector statesWithoutReward = rewardModel.getStatesWithZeroReward(transitionMatrix);
365 storm::storage::BitVector rew0States = storm::utility::graph::performProbGreater0(backwardTransitions, statesWithoutReward, ~statesWithoutReward);
366 rew0States.complement();
367 return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, rewardModel, rew0States, qualitative, hint);
368}
369
370template<>
374 storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, uint_fast64_t stepBound, storm::RationalFunction discountFactor) {
375 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The specified property is not supported by this value type.");
376 return {};
377}
378
379template<typename ValueType, typename RewardModelType>
382 RewardModelType const& rewardModel, uint_fast64_t stepBound, ValueType discountFactor) {
383 // Only compute the result if the model has at least one reward this->getModel().
384 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
385
386 // Compute the reward vector to add in each step based on the available reward models.
387 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix);
388
389 // Initialize result to the zero vector.
390 std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
391
392 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
393 multiplier->repeatedMultiplyWithFactor(env, result, &totalRewardVector, stepBound, discountFactor);
394
395 return result;
396}
397
398template<>
403 storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, bool qualitative, storm::RationalFunction discountFactor,
404 ModelCheckerHint const& hint) {
405 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The specified property is not supported by this value type.");
406 return {};
407}
408
409template<typename ValueType, typename RewardModelType>
412 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, bool qualitative, ValueType discountFactor,
413 ModelCheckerHint const& hint) {
414 // If the solver is set to force exact results, throw an error if the method is not explicitly set to a value iteration type.
415 STORM_LOG_THROW(!env.solver().isForceExact(), storm::exceptions::NotSupportedException,
416 "Exact solving of discounted total reward objectives is currently not supported.");
417
418 // Reduce to reachability rewards
419 std::vector<ValueType> b;
420
421 std::vector<ValueType> x = std::vector<ValueType>(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
422 b = rewardModel.getTotalRewardVector(transitionMatrix);
423 storm::modelchecker::helper::DiscountingHelper<ValueType, true> discountingHelper(transitionMatrix, discountFactor);
424 discountingHelper.solveWithDiscountedValueIteration(env, std::nullopt, x, b);
425 return std::vector<ValueType>(std::move(x));
426}
427
428template<typename ValueType, typename RewardModelType>
431 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates,
432 bool qualitative, ModelCheckerHint const& hint) {
433 return computeReachabilityRewards(
434 env, std::move(goal), transitionMatrix, backwardTransitions,
435 [&](uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) {
436 return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates);
437 },
438 targetStates, qualitative, [&]() { return rewardModel.getStatesWithZeroReward(transitionMatrix); }, hint);
439}
440
441template<typename ValueType, typename RewardModelType>
444 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector,
445 storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint) {
446 return computeReachabilityRewards(
447 env, std::move(goal), transitionMatrix, backwardTransitions,
448 [&](uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const& maybeStates) {
449 std::vector<ValueType> result(numberOfRows);
450 storm::utility::vector::selectVectorValues(result, maybeStates, totalStateRewardVector);
451 return result;
452 },
453 targetStates, qualitative, [&]() { return storm::utility::vector::filterZero(totalStateRewardVector); }, hint);
454}
455
456template<typename ValueType, typename RewardModelType>
459 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, bool qualitative,
460 ModelCheckerHint const& hint) {
461 return computeReachabilityRewards(
462 env, std::move(goal), transitionMatrix, backwardTransitions,
463 [&](uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&) {
464 return std::vector<ValueType>(numberOfRows, storm::utility::one<ValueType>());
465 },
466 targetStates, qualitative, [&]() { return storm::storage::BitVector(transitionMatrix.getRowGroupCount(), false); }, hint);
467}
468
469// This function computes an upper bound on the reachability rewards (see Baier et al, CAV'17).
470template<typename ValueType>
471std::vector<ValueType> computeUpperRewardBounds(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& rewards,
472 std::vector<ValueType> const& oneStepTargetProbabilities) {
473 DsMpiDtmcUpperRewardBoundsComputer<ValueType> dsmpi(transitionMatrix, rewards, oneStepTargetProbabilities);
474 std::vector<ValueType> bounds = dsmpi.computeUpperBounds();
475 return bounds;
476}
477
478template<>
479std::vector<storm::RationalFunction> computeUpperRewardBounds(storm::storage::SparseMatrix<storm::RationalFunction> const& /*transitionMatrix*/,
480 std::vector<storm::RationalFunction> const& /*rewards*/,
481 std::vector<storm::RationalFunction> const& /*oneStepTargetProbabilities*/) {
482 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Computing upper reward bounds is not supported for rational functions.");
483}
484
485template<typename ValueType, typename RewardModelType>
488 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
489 std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const&
490 totalStateRewardVectorGetter,
491 storm::storage::BitVector const& targetStates, bool qualitative, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter,
492 ModelCheckerHint const& hint) {
493 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>());
494
495 // Determine which states have reward zero
496 storm::storage::BitVector rew0States;
497 if (storm::settings::getModule<storm::settings::modules::ModelCheckerSettings>().isFilterRewZeroSet()) {
498 rew0States = storm::utility::graph::performProb1(backwardTransitions, zeroRewardStatesGetter(), targetStates);
499 } else {
500 rew0States = targetStates;
501 }
502
503 // Determine which states have a reward that is less than infinity.
504 storm::storage::BitVector maybeStates;
505 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
506 maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
507 storm::utility::vector::setVectorValues(result, ~(maybeStates | rew0States), storm::utility::infinity<ValueType>());
508
509 STORM_LOG_INFO("Preprocessing: " << rew0States.getNumberOfSetBits() << " States with reward zero (" << maybeStates.getNumberOfSetBits()
510 << " states remaining).");
511 } else {
512 storm::storage::BitVector trueStates(transitionMatrix.getRowCount(), true);
513 storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(backwardTransitions, trueStates, rew0States);
514 infinityStates.complement();
515 maybeStates = ~(rew0States | infinityStates);
516
517 STORM_LOG_INFO("Preprocessing: " << infinityStates.getNumberOfSetBits() << " states with reward infinity, " << rew0States.getNumberOfSetBits()
518 << " states with reward zero (" << maybeStates.getNumberOfSetBits() << " states remaining).");
519
520 storm::utility::vector::setVectorValues(result, infinityStates, storm::utility::infinity<ValueType>());
521 }
522
523 // Check if the values of the maybe states are relevant for the SolveGoal
524 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(maybeStates);
525
526 // Check whether we need to compute exact rewards for some states.
527 if (qualitative || maybeStatesNotRelevant) {
528 // Set the values for all maybe-states to 1 to indicate that their reward values
529 // are neither 0 nor infinity.
530 storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, storm::utility::one<ValueType>());
531 } else {
532 if (!maybeStates.empty()) {
533 // Check whether we need to convert the input to equation system format.
535 bool convertToEquationSystem =
537
538 // In this case we have to compute the reward values for the remaining states.
539 // We can eliminate the rows and columns from the original transition probability matrix.
540 storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, convertToEquationSystem);
541
542 // Initialize the x vector with the hint (if available) or with 1 for each element.
543 // This is the initial guess for the iterative solvers.
544 std::vector<ValueType> x;
545 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasResultHint()) {
546 x = storm::utility::vector::filterVector(hint.template asExplicitModelCheckerHint<ValueType>().getResultHint(), maybeStates);
547 } else {
548 x = std::vector<ValueType>(submatrix.getColumnCount(), storm::utility::one<ValueType>());
549 }
550
551 // Prepare the right-hand side of the equation system.
552 std::vector<ValueType> b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, maybeStates);
553
554 storm::solver::LinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env);
555 boost::optional<std::vector<ValueType>> upperRewardBounds;
556 requirements.clearLowerBounds();
557 if (requirements.upperBounds()) {
558 upperRewardBounds = computeUpperRewardBounds(submatrix, b, transitionMatrix.getConstrainedRowSumVector(maybeStates, rew0States));
559 requirements.clearUpperBounds();
560 }
561 STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
562 "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked.");
563
564 // If necessary, convert the matrix from the fixpoint notation to the form needed for the equation system.
565 if (convertToEquationSystem) {
566 // go from x = A*x + b to (I-A)x = b.
567 submatrix.convertToEquationSystem();
568 }
569
570 // Create the solver.
571 goal.restrictRelevantValues(maybeStates);
572 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver =
573 storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix));
574 solver->setLowerBound(storm::utility::zero<ValueType>());
575 if (upperRewardBounds) {
576 solver->setUpperBounds(std::move(upperRewardBounds.get()));
577 }
578
579 // Now solve the resulting equation system.
580 solver->solveEquations(env, x, b);
581
582 // Set values of resulting vector according to result.
583 storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, x);
584 }
585 }
586 return result;
587}
588
589template<typename ValueType, typename RewardModelType>
590typename SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeBaierTransformation(
591 Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
592 storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates,
593 boost::optional<std::vector<ValueType>> const& stateRewards) {
594 BaierTransformedModel result;
595
596 // Start by computing all 'before' states, i.e. the states for which the conditional probability is defined.
597 std::vector<ValueType> probabilitiesToReachConditionStates =
598 computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), transitionMatrix, backwardTransitions,
599 storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false);
600
601 result.beforeStates = storm::storage::BitVector(targetStates.size(), true);
602 uint_fast64_t state = 0;
603 uint_fast64_t beforeStateIndex = 0;
604 for (auto const& value : probabilitiesToReachConditionStates) {
605 if (value == storm::utility::zero<ValueType>()) {
606 result.beforeStates.set(state, false);
607 } else {
608 probabilitiesToReachConditionStates[beforeStateIndex] = value;
609 ++beforeStateIndex;
610 }
611 ++state;
612 }
613 probabilitiesToReachConditionStates.resize(beforeStateIndex);
614
615 if (targetStates.empty()) {
616 result.noTargetStates = true;
617 return result;
618 } else if (!result.beforeStates.empty()) {
619 // If there are some states for which the conditional probability is defined and there are some
620 // states that can reach the target states without visiting condition states first, we need to
621 // do more work.
622
623 // First, compute the relevant states and some offsets.
624 storm::storage::BitVector allStates(targetStates.size(), true);
625 std::vector<uint_fast64_t> numberOfBeforeStatesUpToState = result.beforeStates.getNumberOfSetBitsBeforeIndices();
626 storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(backwardTransitions, allStates, targetStates);
627 statesWithProbabilityGreater0 &= storm::utility::graph::getReachableStates(transitionMatrix, conditionStates, allStates, targetStates);
628 uint_fast64_t normalStatesOffset = result.beforeStates.getNumberOfSetBits();
629 std::vector<uint_fast64_t> numberOfNormalStatesUpToState = statesWithProbabilityGreater0.getNumberOfSetBitsBeforeIndices();
630
631 // All transitions going to states with probability zero, need to be redirected to a deadlock state.
632 bool addDeadlockState = false;
633 uint_fast64_t deadlockState = normalStatesOffset + statesWithProbabilityGreater0.getNumberOfSetBits();
634
635 // Now, we create the matrix of 'before' and 'normal' states.
637
638 // Start by creating the transitions of the 'before' states.
639 uint_fast64_t currentRow = 0;
640 for (auto beforeState : result.beforeStates) {
641 if (conditionStates.get(beforeState)) {
642 // For condition states, we move to the 'normal' states.
643 ValueType zeroProbability = storm::utility::zero<ValueType>();
644 for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) {
645 if (statesWithProbabilityGreater0.get(successorEntry.getColumn())) {
646 builder.addNextValue(currentRow, normalStatesOffset + numberOfNormalStatesUpToState[successorEntry.getColumn()],
647 successorEntry.getValue());
648 } else {
649 zeroProbability += successorEntry.getValue();
650 }
651 }
652 if (!storm::utility::isZero(zeroProbability)) {
653 builder.addNextValue(currentRow, deadlockState, zeroProbability);
654 }
655 } else {
656 // For non-condition states, we scale the probabilities going to other before states.
657 for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) {
658 if (result.beforeStates.get(successorEntry.getColumn())) {
659 builder.addNextValue(currentRow, numberOfBeforeStatesUpToState[successorEntry.getColumn()],
660 successorEntry.getValue() *
661 probabilitiesToReachConditionStates[numberOfBeforeStatesUpToState[successorEntry.getColumn()]] /
662 probabilitiesToReachConditionStates[currentRow]);
663 }
664 }
665 }
666 ++currentRow;
667 }
668
669 // Then, create the transitions of the 'normal' states.
670 for (auto state : statesWithProbabilityGreater0) {
671 ValueType zeroProbability = storm::utility::zero<ValueType>();
672 for (auto const& successorEntry : transitionMatrix.getRow(state)) {
673 if (statesWithProbabilityGreater0.get(successorEntry.getColumn())) {
674 builder.addNextValue(currentRow, normalStatesOffset + numberOfNormalStatesUpToState[successorEntry.getColumn()], successorEntry.getValue());
675 } else {
676 zeroProbability += successorEntry.getValue();
677 }
678 }
679 if (!storm::utility::isZero(zeroProbability)) {
680 addDeadlockState = true;
681 builder.addNextValue(currentRow, deadlockState, zeroProbability);
682 }
683 ++currentRow;
684 }
685 if (addDeadlockState) {
686 builder.addNextValue(deadlockState, deadlockState, storm::utility::one<ValueType>());
687 }
688
689 // Build the new transition matrix and the new targets.
690 result.transitionMatrix = builder.build(addDeadlockState ? (deadlockState + 1) : deadlockState);
691 storm::storage::BitVector newTargetStates = targetStates % result.beforeStates;
692 newTargetStates.resize(result.transitionMatrix.get().getRowCount());
693 for (auto state : targetStates % statesWithProbabilityGreater0) {
694 newTargetStates.set(normalStatesOffset + state, true);
695 }
696 result.targetStates = std::move(newTargetStates);
697
698 // If a reward model was given, we need to compute the rewards for the transformed model.
699 if (stateRewards) {
700 std::vector<ValueType> newStateRewards(result.beforeStates.getNumberOfSetBits());
701 storm::utility::vector::selectVectorValues(newStateRewards, result.beforeStates, stateRewards.get());
702
703 newStateRewards.reserve(result.transitionMatrix.get().getRowCount());
704 for (auto state : statesWithProbabilityGreater0) {
705 newStateRewards.push_back(stateRewards.get()[state]);
706 }
707 // Add a zero reward to the deadlock state.
708 if (addDeadlockState) {
709 newStateRewards.push_back(storm::utility::zero<ValueType>());
710 }
711 result.stateRewards = std::move(newStateRewards);
712 }
713 }
714
715 return result;
716}
717
718template<typename ValueType, typename RewardModelType>
719storm::storage::BitVector SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel::getNewRelevantStates() const {
720 storm::storage::BitVector newRelevantStates(transitionMatrix.get().getRowCount());
721 for (uint64_t i = 0; i < this->beforeStates.getNumberOfSetBits(); ++i) {
722 newRelevantStates.set(i);
723 }
724 return newRelevantStates;
725}
726
727template<typename ValueType, typename RewardModelType>
728storm::storage::BitVector SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel::getNewRelevantStates(
729 storm::storage::BitVector const& oldRelevantStates) const {
730 storm::storage::BitVector result = oldRelevantStates % this->beforeStates;
731 result.resize(transitionMatrix.get().getRowCount());
732 return result;
733}
734
735template<typename ValueType, typename RewardModelType>
738 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates,
739 storm::storage::BitVector const& conditionStates, bool qualitative) {
740 // Prepare result vector.
741 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
742
743 if (!conditionStates.empty()) {
744 BaierTransformedModel transformedModel =
745 computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none);
746
747 if (transformedModel.noTargetStates) {
748 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
749 } else {
750 // At this point, we do not need to check whether there are 'before' states, since the condition
751 // states were non-empty so there is at least one state with a positive probability of satisfying
752 // the condition.
753
754 // Now compute reachability probabilities in the transformed model.
755 storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
756 storm::storage::BitVector newRelevantValues;
757 if (goal.hasRelevantValues()) {
758 newRelevantValues = transformedModel.getNewRelevantStates(goal.relevantValues());
759 } else {
760 newRelevantValues = transformedModel.getNewRelevantStates();
761 }
762 goal.setRelevantValues(std::move(newRelevantValues));
763 std::vector<ValueType> conditionalProbabilities =
764 computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(),
765 storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative);
766
767 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities);
768 }
769 }
770
771 return result;
772}
773
774template<typename ValueType, typename RewardModelType>
777 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates,
778 storm::storage::BitVector const& conditionStates, bool qualitative) {
779 // Prepare result vector.
780 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
781
782 if (!conditionStates.empty()) {
783 BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates,
784 rewardModel.getTotalRewardVector(transitionMatrix));
785
786 if (transformedModel.noTargetStates) {
787 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
788 } else {
789 // At this point, we do not need to check whether there are 'before' states, since the condition
790 // states were non-empty so there is at least one state with a positive probability of satisfying
791 // the condition.
792
793 // Now compute reachability probabilities in the transformed model.
794 storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
795 storm::storage::BitVector newRelevantValues;
796 if (goal.hasRelevantValues()) {
797 newRelevantValues = transformedModel.getNewRelevantStates(goal.relevantValues());
798 } else {
799 newRelevantValues = transformedModel.getNewRelevantStates();
800 }
801 goal.setRelevantValues(std::move(newRelevantValues));
802 std::vector<ValueType> conditionalRewards =
803 computeReachabilityRewards(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(),
804 transformedModel.targetStates.get(), qualitative);
805 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalRewards);
806 }
807 }
808
809 return result;
810}
811
812template class SparseDtmcPrctlHelper<double>;
813
816} // namespace helper
817} // namespace modelchecker
818} // namespace storm
SolverEnvironment & solver()
void setLinearEquationSolverPrecision(boost::optional< storm::RationalNumber > const &newPrecision, boost::optional< bool > const &relativePrecision=boost::none)
This class contains information that might accelerate the model checking process.
bool solveWithDiscountedValueIteration(Environment const &env, std::optional< OptimizationDirection > dir, std::vector< ValueType > &x, std::vector< ValueType > const &b) const
static std::vector< ValueType > computeNextProbabilities(Environment const &env, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &nextStates)
static std::vector< ValueType > computeReachabilityTimes(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &targetStates, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::vector< ValueType > computeReachabilityRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, storm::storage::BitVector const &targetStates, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::vector< ValueType > computeUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::vector< ValueType > computeConditionalProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &targetStates, storm::storage::BitVector const &conditionStates, bool qualitative)
static std::vector< ValueType > computeAllUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
static std::vector< ValueType > computeTotalRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::map< storm::storage::sparse::state_type, ValueType > computeRewardBoundedValues(Environment const &env, storm::models::sparse::Dtmc< ValueType > const &model, std::shared_ptr< storm::logic::OperatorFormula const > rewardBoundedFormula)
static std::vector< ValueType > computeConditionalRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, storm::storage::BitVector const &targetStates, storm::storage::BitVector const &conditionStates, bool qualitative)
static std::vector< ValueType > computeInstantaneousRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepCount)
static std::vector< ValueType > computeDiscountedTotalRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, bool qualitative, ValueType discountFactor, ModelCheckerHint const &hint=ModelCheckerHint())
static std::vector< ValueType > computeGloballyProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &psiStates, bool qualitative)
static std::vector< ValueType > computeDiscountedCumulativeRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepBound, ValueType discountFactor)
static std::vector< ValueType > computeCumulativeRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepBound)
uint64_t getDimensionOfEpoch(Epoch const &epoch, uint64_t const &dimension) const
Epoch getStartEpoch(bool setUnknownDimsToBottom=false)
Retrieves the desired epoch that needs to be analyzed to compute the reward bounded values.
EpochModel< ValueType, SingleObjectiveMode > & setCurrentEpoch(Epoch const &epoch)
std::vector< Epoch > getEpochComputationOrder(Epoch const &startEpoch, bool stopAtComputedEpochs=false)
Computes a sequence of epochs that need to be analyzed to get a result at the start epoch.
ValueType getRequiredEpochModelPrecision(Epoch const &startEpoch, ValueType const &precision)
Returns the precision required for the analyzis of each epoch model in order to achieve the given ove...
boost::optional< ValueType > getUpperObjectiveBound(uint64_t objectiveIndex=0)
Returns an upper/lower bound for the objective result in every state (if this bound could be computed...
void setEquationSystemFormatForEpochModel(storm::solver::LinearEquationSolverProblemFormat eqSysFormat)
This class represents a discrete-time Markov chain.
Definition Dtmc.h:13
storm::storage::BitVector const & getInitialStates() const
Retrieves the initial states of the model.
Definition Model.cpp:179
LinearEquationSolverRequirements getRequirements(Environment const &env) const
Retrieves the requirements of the solver if it was created with the current settings.
virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const &env) const
Retrieves the problem format that the solver expects if it was created with the current settings.
std::string getEnabledRequirementsAsString() const
Checks whether there are no critical requirements left.
std::unique_ptr< Multiplier< ValueType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix)
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
void complement()
Negates all bits in the bit vector.
std::vector< uint64_t > getNumberOfSetBitsBeforeIndices() const
Retrieves a vector that holds at position i the number of bits set before index i.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
size_t size() const
Retrieves the number of bits this bit vector can store.
void resize(uint64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
A class that can be used to build a sparse matrix by adding value by value.
void addNextValue(index_type row, index_type column, value_type const &value)
Sets the matrix entry at the given row and column to the given value.
SparseMatrix< value_type > build(index_type overriddenRowCount=0, index_type overriddenColumnCount=0, index_type overriddenRowGroupCount=0)
A class that holds a possibly non-square matrix in the compressed row storage format.
void convertToEquationSystem()
Transforms the matrix into an equation system.
void makeRowsAbsorbing(storm::storage::BitVector const &rows, bool dropZeroEntries=false)
This function makes the given rows absorbing.
SparseMatrix getSubmatrix(bool useGroups, storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint, bool insertDiagonalEntries=false, storm::storage::BitVector const &makeZeroColumns=storm::storage::BitVector()) const
Creates a submatrix of the current matrix by dropping all rows and columns whose bits are not set to ...
std::vector< value_type > getConstrainedRowSumVector(storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint) const
Computes a vector whose i-th entry is the sum of the entries in the i-th selected row where only thos...
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
index_type getColumnCount() const
Returns the number of columns of the matrix.
void deleteDiagonalEntries(bool dropZeroEntries=false)
Sets all diagonal elements to zero.
storm::storage::SparseMatrix< value_type > transpose(bool joinGroups=false, bool keepZeros=false) const
Transposes the matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
A class that provides convenience operations to display run times.
bool updateProgress(uint64_t count)
Updates the progress to the current count and prints it if the delay passed.
void setMaxCount(uint64_t maxCount)
Sets the maximal possible count.
void startNewMeasurement(uint64_t startCount)
Starts a new measurement, dropping all progress information collected so far.
A class that provides convenience operations to display run times.
Definition Stopwatch.h:14
void start()
Start stopwatch (again) and start measuring time.
Definition Stopwatch.cpp:48
void stop()
Stop stopwatch and add measured time to total time.
Definition Stopwatch.cpp:42
#define STORM_LOG_INFO(message)
Definition logging.h:24
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
#define STORM_PRINT_AND_LOG(message)
Definition macros.h:68
SFTBDDChecker::ValueType ValueType
std::vector< ValueType > computeUpperRewardBounds(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< ValueType > const &rewards, std::vector< ValueType > const &oneStepTargetProbabilities)
std::unique_ptr< storm::solver::LinearEquationSolver< ValueType > > configureLinearEquationSolver(Environment const &env, SolveGoal< ValueType, SolutionType > &&goal, storm::solver::LinearEquationSolverFactory< ValueType > const &factory, MatrixType &&matrix)
Definition SolveGoal.h:128
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
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
void setVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Sets the provided values at the provided positions in the given vector.
Definition vector.h:78
void selectVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Selects the elements from a vector at the specified positions and writes them consecutively into anot...
Definition vector.h:184
storm::storage::BitVector filterZero(std::vector< T > const &values)
Retrieves a bit vector containing all the indices for which the value at this position is equal to ze...
Definition vector.h:519
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
Definition vector.h:1060
bool isOne(ValueType const &a)
Definition constants.cpp:34
bool isZero(ValueType const &a)
Definition constants.cpp:39