Storm 1.14.0.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"
26#include "storm/utility/graph.h"
29
30namespace storm {
31namespace modelchecker {
32namespace helper {
33
34template<>
35std::map<storm::storage::sparse::state_type, storm::RationalFunction> SparseDtmcPrctlHelper<storm::RationalFunction>::computeRewardBoundedValues(
37 std::shared_ptr<storm::logic::OperatorFormula const> /*rewardBoundedFormula*/) {
38 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The specified property is not supported by this value type.");
39 return std::map<storm::storage::sparse::state_type, storm::RationalFunction>();
40}
41
42template<typename ValueType, typename RewardModelType, typename SolutionType>
44 Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula) {
46 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing reward bounded values with interval models.");
47 } else {
48 storm::utility::Stopwatch swAll(true), swBuild, swCheck;
49
51
52 // Get lower and upper bounds for the solution.
53 auto lowerBound = rewardUnfolding.getLowerObjectiveBound();
54 auto upperBound = rewardUnfolding.getUpperObjectiveBound();
55
56 // Initialize epoch models
57 auto initEpoch = rewardUnfolding.getStartEpoch();
58 auto epochOrder = rewardUnfolding.getEpochComputationOrder(initEpoch);
59
60 // initialize data that will be needed for each epoch
61 std::vector<ValueType> x, b;
62 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSolver;
63
64 Environment preciseEnv = env;
65 ValueType precision = rewardUnfolding.getRequiredEpochModelPrecision(
68
69 // In case of cdf export we store the necessary data.
70 std::vector<std::vector<ValueType>> cdfData;
71
72 // Set the correct equation problem format.
74 rewardUnfolding.setEquationSystemFormatForEpochModel(linearEquationSolverFactory.getEquationProblemFormat(preciseEnv));
75
76 storm::utility::ProgressMeasurement progress("epochs");
77 progress.setMaxCount(epochOrder.size());
78 progress.startNewMeasurement(0);
79 uint64_t numCheckedEpochs = 0;
80 for (auto const& epoch : epochOrder) {
81 swBuild.start();
82 auto& epochModel = rewardUnfolding.setCurrentEpoch(epoch);
83 swBuild.stop();
84 swCheck.start();
85 rewardUnfolding.setSolutionForCurrentEpoch(epochModel.analyzeSingleObjective(preciseEnv, x, b, linEqSolver, lowerBound, upperBound));
86 swCheck.stop();
88 !rewardUnfolding.getEpochManager().hasBottomDimension(epoch)) {
89 std::vector<ValueType> cdfEntry;
90 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
91 uint64_t offset = rewardUnfolding.getDimension(i).boundType == helper::rewardbounded::DimensionBoundType::LowerBound ? 1 : 0;
92 cdfEntry.push_back(storm::utility::convertNumber<ValueType>(rewardUnfolding.getEpochManager().getDimensionOfEpoch(epoch, i) + offset) *
93 rewardUnfolding.getDimension(i).scalingFactor);
94 }
95 cdfEntry.push_back(rewardUnfolding.getInitialStateResult(epoch));
96 cdfData.push_back(std::move(cdfEntry));
97 }
98 ++numCheckedEpochs;
99 progress.updateProgress(numCheckedEpochs);
101 break;
102 }
103 }
104
105 std::map<storm::storage::sparse::state_type, ValueType> result;
106 for (auto initState : model.getInitialStates()) {
107 result[initState] = rewardUnfolding.getInitialStateResult(initEpoch, initState);
108 }
109
110 swAll.stop();
111
113 std::vector<std::string> headers;
114 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
115 headers.push_back(rewardUnfolding.getDimension(i).formula->toString());
116 }
117 headers.push_back("Result");
119 storm::settings::getModule<storm::settings::modules::IOSettings>().getExportCdfDirectory() + "cdf.csv", cdfData, headers);
120 }
121
122 STORM_LOG_STATISTICS("---------------------------------\n");
123 STORM_LOG_STATISTICS("Statistics:\n");
124 STORM_LOG_STATISTICS("---------------------------------\n");
125 STORM_LOG_STATISTICS(" #checked epochs: " << epochOrder.size() << ".\n");
126 STORM_LOG_STATISTICS(" overall Time: " << swAll << ".\n");
127 STORM_LOG_STATISTICS("Epoch Model building Time: " << swBuild << ".\n");
128 STORM_LOG_STATISTICS("Epoch Model checking Time: " << swCheck << ".\n");
129 STORM_LOG_STATISTICS("---------------------------------\n");
130
131 return result;
132 }
133}
134
135template<typename ValueType, typename SolutionType>
137 storm::storage::SparseMatrix<ValueType>&& submatrix, std::vector<ValueType> const& b,
138 bool computeReward) {
139 // Initialize the solution vector.
140 std::vector<SolutionType> x = std::vector<SolutionType>(submatrix.getRowGroupCount(), storm::utility::zero<SolutionType>());
141
142 // Set up the solver.
144 // The goal is consumed by the solver configuration, so capture what is needed first.
145 auto const uncertaintyResolutionMode = goal.getUncertaintyResolutionMode();
146 std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType, SolutionType>> solver = storm::solver::configureMinMaxLinearEquationSolver(
147 env, std::move(goal), minMaxLinearEquationSolverFactory, std::move(submatrix),
148 convert(OptimizationDirection::Maximize)); // default to maximize for IDTMCs; does not affect the result
149 solver->setUncertaintyResolutionMode(uncertaintyResolutionMode);
150 solver->setHasUniqueSolution(computeReward); // As we check for graph-preservation, in case of rewards on IDTMCs, we have a unique solution
151 solver->setHasNoEndComponents(false);
152
153 // check requirements of solver
154 auto req = solver->getRequirements(env);
155 if (!computeReward) {
158 req.clearBounds();
159 }
160 STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
161 "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked.");
162
163 solver->setRequirementsChecked();
164
165 // Solve the corresponding system of equations.
166 solver->solveEquations(env, x, b);
167
168 return x;
169}
170
171template<typename ValueType, typename RewardModelType, typename SolutionType>
174 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
175 bool qualitative, ModelCheckerHint const& hint) {
176 std::vector<SolutionType> result(transitionMatrix.getRowCount(), storm::utility::zero<SolutionType>());
177
178 // We need to identify the maybe states (states which have a probability for satisfying the until formula
179 // that is strictly between 0 and 1) and the states that satisfy the formula with probability 1.
180 storm::storage::BitVector maybeStates, statesWithProbability1;
181
182 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
183 maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
184
185 // Treat the states with probability one
186 std::vector<SolutionType> const& resultsForNonMaybeStates = hint.template asExplicitModelCheckerHint<SolutionType>().getResultHint();
187 statesWithProbability1 = storm::storage::BitVector(maybeStates.size(), false);
188 storm::storage::BitVector nonMaybeStates = ~maybeStates;
189 for (uint64_t state : nonMaybeStates) {
190 if (storm::utility::isOne(resultsForNonMaybeStates[state])) {
191 statesWithProbability1.set(state, true);
192 result[state] = storm::utility::one<SolutionType>();
193 } else {
194 STORM_LOG_THROW(storm::utility::isZero(resultsForNonMaybeStates[state]), storm::exceptions::IllegalArgumentException,
195 "Expected that the result hint specifies probabilities in {0,1} for non-maybe states.");
196 }
197 }
198
199 STORM_LOG_INFO("Preprocessing: " << statesWithProbability1.getNumberOfSetBits() << " states with probability 1 (" << maybeStates.getNumberOfSetBits()
200 << " states remaining).");
201 } else {
202 // Get all states that have probability 0 and 1 of satisfying the until-formula.
203 std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01 =
204 storm::utility::graph::performProb01(backwardTransitions, phiStates, psiStates);
205 storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first);
206 statesWithProbability1 = std::move(statesWithProbability01.second);
207 maybeStates = ~(statesWithProbability0 | statesWithProbability1);
208
209 STORM_LOG_INFO("Preprocessing: " << statesWithProbability1.getNumberOfSetBits() << " states with probability 1, "
210 << statesWithProbability0.getNumberOfSetBits() << " with probability 0 (" << maybeStates.getNumberOfSetBits()
211 << " states remaining).");
212
213 // Set values of resulting vector that are known exactly.
216 }
217
218 // Check if the values of the maybe states are relevant for the SolveGoal
219 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(maybeStates);
220
221 // Check whether we need to compute exact probabilities for some states.
222 if (qualitative || maybeStatesNotRelevant) {
223 // Set the values for all maybe-states to 0.5 to indicate that their probability values are neither 0 nor 1.
225 } else {
226 if (!maybeStates.empty()) {
227 // In this case we have to compute the probabilities.
228 if constexpr (storm::IsIntervalType<ValueType>) {
229 // Compute probabilities in a robust fashion by using the logic as for MDPs
231 std::vector<ValueType> b;
232
233 submatrix = transitionMatrix.filterEntries(transitionMatrix.getRowFilter(maybeStates));
234
235 // Prepare the right-hand side of the equation system. For entry i this corresponds to
236 // the accumulated probability of going from state i to some state that has probability 1.
237 storm::utility::vector::setAllValues(b, transitionMatrix.getRowFilter(statesWithProbability1));
238
239 std::vector<SolutionType> resultForMaybeStates = computeRobustValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, false);
240
241 // For interval models, the result for maybe states indeed also holds values for all qualitative states.
242 STORM_LOG_ASSERT(resultForMaybeStates.size() == transitionMatrix.getColumnCount(), "Dimensions do not match.");
243 result = std::move(resultForMaybeStates);
244 } else {
245 // Check whether we need to convert the input to equation system format.
247 bool convertToEquationSystem =
249
250 // We can eliminate the rows and columns from the original transition probability matrix.
251 storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, convertToEquationSystem);
252 if (convertToEquationSystem) {
253 // Converting the matrix from the fixpoint notation to the form needed for the equation
254 // system. That is, we go from x = A*x + b to (I-A)x = b.
255 submatrix.convertToEquationSystem();
256 }
257
258 // Initialize the x vector with the hint (if available) or with 0.5 for each element.
259 // This is the initial guess for the iterative solvers. It should be safe as for all
260 // 'maybe' states we know that the probability is strictly larger than 0.
261 std::vector<SolutionType> x;
262 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasResultHint()) {
263 x = storm::utility::vector::filterVector(hint.template asExplicitModelCheckerHint<SolutionType>().getResultHint(), maybeStates);
264 } else {
265 x = std::vector<SolutionType>(maybeStates.getNumberOfSetBits(), storm::utility::convertNumber<SolutionType>(0.5));
266 }
267
268 // Prepare the right-hand side of the equation system. For entry i this corresponds to
269 // the accumulated probability of going from state i to some 'yes' state.
270 std::vector<SolutionType> b = transitionMatrix.getConstrainedRowSumVector(maybeStates, statesWithProbability1);
271
272 // Now solve the created system of linear equations.
273 goal.restrictRelevantValues(maybeStates);
274 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver =
275 storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix));
277 solver->solveEquations(env, x, b);
278
279 // Set values of resulting vector according to result.
281 }
282 }
283 }
284 return result;
285}
286
287template<typename ValueType, typename RewardModelType, typename SolutionType>
290 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
291 if constexpr (storm::IsIntervalType<ValueType>) {
292 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing all until probabilities with interval models.");
293 } else {
294 uint_fast64_t numberOfStates = transitionMatrix.getRowCount();
295 std::vector<SolutionType> result(numberOfStates, storm::utility::zero<SolutionType>());
296
297 // All states are relevant
298 storm::storage::BitVector relevantStates(numberOfStates, true);
299
300 // Compute exact probabilities for some states.
301 if (!relevantStates.empty()) {
302 // Check whether we need to convert the input to equation system format.
304 bool convertToEquationSystem =
306
307 storm::storage::SparseMatrix<ValueType> submatrix(transitionMatrix);
308 submatrix.makeRowsAbsorbing(phiStates);
309 submatrix.makeRowsAbsorbing(psiStates);
310 // submatrix.deleteDiagonalEntries(psiStates);
311 // storm::storage::BitVector failState(numberOfStates, false);
312 // failState.set(0, true);
313 submatrix.deleteDiagonalEntries();
314 submatrix = submatrix.transpose();
315 submatrix = submatrix.getSubmatrix(true, relevantStates, relevantStates, convertToEquationSystem);
316
317 if (convertToEquationSystem) {
318 // Converting the matrix from the fixpoint notation to the form needed for the equation
319 // system. That is, we go from x = A*x + b to (I-A)x = b.
320 submatrix.convertToEquationSystem();
321 }
322
323 // Initialize the x vector with 0.5 for each element.
324 // This is the initial guess for the iterative solvers. It should be safe as for all
325 // 'maybe' states we know that the probability is strictly larger than 0.
326 std::vector<SolutionType> x = std::vector<SolutionType>(relevantStates.getNumberOfSetBits(), storm::utility::convertNumber<SolutionType>(0.5));
327
328 // Prepare the right-hand side of the equation system.
329 std::vector<SolutionType> b(relevantStates.getNumberOfSetBits(), storm::utility::zero<SolutionType>());
330 // Set initial states
331 size_t i = 0;
333 for (uint64_t state : relevantStates) {
334 if (initialStates.get(state)) {
335 b[i] = initDist;
336 }
337 ++i;
338 }
339
340 // Now solve the created system of linear equations.
341 goal.restrictRelevantValues(relevantStates);
342 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver =
343 storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix));
345 solver->solveEquations(env, x, b);
346
347 // Set values of resulting vector according to result.
349 }
350 return result;
351 }
352}
353
354template<typename ValueType, typename RewardModelType, typename SolutionType>
357 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative) {
358 if constexpr (storm::IsIntervalType<ValueType>) {
359 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing globally probabilities with interval models.");
360 } else {
361 goal.oneMinus();
362 std::vector<SolutionType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions,
363 storm::storage::BitVector(transitionMatrix.getRowCount(), true), ~psiStates, qualitative);
364 for (auto& entry : result) {
365 entry = storm::utility::one<SolutionType>() - entry;
366 }
367 return result;
368 }
369}
370
371template<typename ValueType, typename RewardModelType, typename SolutionType>
373 Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) {
374 if constexpr (storm::IsIntervalType<ValueType>) {
375 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support next probabilities with interval models.");
376 } else {
377 // Create the vector with which to multiply and initialize it correctly.
378 std::vector<ValueType> result(transitionMatrix.getRowCount());
380
381 // Perform one single matrix-vector multiplication.
382 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
383 multiplier->multiply(env, result, nullptr, result);
384 return result;
385 }
386}
387
388template<typename ValueType, typename RewardModelType, typename SolutionType>
391 RewardModelType const& rewardModel, uint_fast64_t stepBound) {
392 if constexpr (storm::IsIntervalType<ValueType>) {
393 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support cumulative rewards with interval models.");
394 } else {
395 // Initialize result to the null vector.
396 std::vector<ValueType> result(transitionMatrix.getRowCount());
397
398 // Compute the reward vector to add in each step based on the available reward models.
399 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix);
400
401 // Perform the matrix vector multiplication as often as required by the formula bound.
402 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
403 multiplier->repeatedMultiply(env, result, &totalRewardVector, stepBound);
404
405 return result;
406 }
407}
408
409template<typename ValueType, typename RewardModelType, typename SolutionType>
412 RewardModelType const& rewardModel, uint_fast64_t stepCount) {
413 if constexpr (storm::IsIntervalType<ValueType>) {
414 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support instantaneous rewards with interval models.");
415 } else {
416 // Only compute the result if the model has a state-based reward this->getModel().
417 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
418 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
419
420 // Initialize result to state rewards of the model.
421 std::vector<ValueType> result = rewardModel.getStateRewardVector();
422
423 // Perform the matrix vector multiplication as often as required by the formula bound.
424 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
425 multiplier->repeatedMultiply(env, result, nullptr, stepCount);
426
427 return result;
428 }
429}
430
431template<typename ValueType, typename RewardModelType, typename SolutionType>
434 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, bool qualitative, ModelCheckerHint const& hint) {
435 if constexpr (storm::IsIntervalType<ValueType>) {
436 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing total rewards with interval models.");
437 } else {
438 // Identify the states from which only states with zero reward are reachable.
439 // We can then compute reachability rewards assuming these states as target set.
440 storm::storage::BitVector statesWithoutReward = rewardModel.getStatesWithZeroReward(transitionMatrix);
441 storm::storage::BitVector rew0States = storm::utility::graph::performProbGreater0(backwardTransitions, statesWithoutReward, ~statesWithoutReward);
442 rew0States.complement();
443 return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, rewardModel, rew0States, qualitative, hint);
444 }
445}
446
447template<>
451 storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, uint_fast64_t stepBound, storm::RationalFunction discountFactor) {
452 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The specified property is not supported by this value type.");
453 return {};
454}
455
456template<typename ValueType, typename RewardModelType, typename SolutionType>
459 RewardModelType const& rewardModel, uint_fast64_t stepBound, ValueType discountFactor) {
460 if constexpr (storm::IsIntervalType<ValueType>) {
461 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support discounted cumulative rewards with interval models.");
462 } else {
463 // Only compute the result if the model has at least one reward this->getModel().
464 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
465
466 // Compute the reward vector to add in each step based on the available reward models.
467 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix);
468
469 // Initialize result to the zero vector.
470 std::vector<SolutionType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<SolutionType>());
471
472 auto multiplier = storm::solver::MultiplierFactory<SolutionType>().create(env, transitionMatrix);
473 multiplier->repeatedMultiplyWithFactor(env, result, &totalRewardVector, stepBound, discountFactor);
474
475 return result;
476 }
477}
478
479template<>
484 storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, bool qualitative, storm::RationalFunction discountFactor,
485 ModelCheckerHint const& hint) {
486 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The specified property is not supported by this value type.");
487 return {};
488}
489
490template<typename ValueType, typename RewardModelType, typename SolutionType>
493 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, bool qualitative, ValueType discountFactor,
494 ModelCheckerHint const& hint) {
495 if constexpr (storm::IsIntervalType<ValueType>) {
496 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support discounted total rewards with interval models.");
497 } else {
498 // If the solver is set to force exact results, throw an error if the method is not explicitly set to a value iteration type.
499 STORM_LOG_THROW(!env.solver().isForceExact(), storm::exceptions::NotSupportedException,
500 "Exact solving of discounted total reward objectives is currently not supported.");
501
502 // Reduce to reachability rewards
503 std::vector<ValueType> b;
504
505 std::vector<ValueType> x = std::vector<ValueType>(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
506 b = rewardModel.getTotalRewardVector(transitionMatrix);
507 storm::modelchecker::helper::DiscountingHelper<SolutionType, true> discountingHelper(transitionMatrix, discountFactor);
508 discountingHelper.solveWithDiscountedValueIteration(env, std::nullopt, x, b);
509 return std::vector<SolutionType>(std::move(x));
510 }
511}
512
513template<typename ValueType, typename RewardModelType, typename SolutionType>
516 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates,
517 bool qualitative, ModelCheckerHint const& hint) {
519 env, std::move(goal), transitionMatrix, backwardTransitions,
520 [&](uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) {
521 return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates);
522 },
523 targetStates, qualitative, [&]() { return rewardModel.getStatesWithZeroReward(transitionMatrix); }, hint);
524}
525
526template<typename ValueType, typename RewardModelType, typename SolutionType>
529 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector,
530 storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint) {
532 env, std::move(goal), transitionMatrix, backwardTransitions,
533 [&](uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const& maybeStates) {
534 std::vector<ValueType> result(numberOfRows, storm::utility::zero<ValueType>());
535 storm::utility::vector::selectVectorValues(result, maybeStates, totalStateRewardVector);
536 return result;
537 },
538 targetStates, qualitative, [&]() { return storm::utility::vector::filterZero(totalStateRewardVector); }, hint);
539}
540
541template<typename ValueType, typename RewardModelType, typename SolutionType>
544 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, bool qualitative,
545 ModelCheckerHint const& hint) {
546 if constexpr (storm::IsIntervalType<ValueType>) {
547 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing reachability times with interval models.");
548 } else {
550 env, std::move(goal), transitionMatrix, backwardTransitions,
551 [&](uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&) {
552 return std::vector<ValueType>(numberOfRows, storm::utility::one<ValueType>());
553 },
554 targetStates, qualitative, [&]() { return storm::storage::BitVector(transitionMatrix.getRowGroupCount(), false); }, hint);
555 }
556}
557
558// This function computes an upper bound on the reachability rewards (see Baier et al, CAV'17).
559template<typename ValueType, typename SolutionType>
560std::vector<SolutionType> computeUpperRewardBounds(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& rewards,
561 std::vector<SolutionType> const& oneStepTargetProbabilities) {
562 if constexpr (storm::IsIntervalType<ValueType>) {
563 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing upper reward bounds with interval models.");
564 } else {
565 DsMpiDtmcUpperRewardBoundsComputer<ValueType> dsmpi(transitionMatrix, rewards, oneStepTargetProbabilities);
566 std::vector<ValueType> bounds = dsmpi.computeUpperBounds();
567 return bounds;
568 }
569}
570
571template<>
572std::vector<storm::RationalFunction> computeUpperRewardBounds(storm::storage::SparseMatrix<storm::RationalFunction> const& /*transitionMatrix*/,
573 std::vector<storm::RationalFunction> const& /*rewards*/,
574 std::vector<storm::RationalFunction> const& /*oneStepTargetProbabilities*/) {
575 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Computing upper reward bounds is not supported for rational functions.");
576}
577
578template<typename ValueType, typename RewardModelType, typename SolutionType>
581 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
582 std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const&
583 totalStateRewardVectorGetter,
584 storm::storage::BitVector const& targetStates, bool qualitative, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter,
585 ModelCheckerHint const& hint) {
586 std::vector<SolutionType> result(transitionMatrix.getRowCount(), storm::utility::zero<SolutionType>());
587
588 // Determine which states have reward zero
589 storm::storage::BitVector rew0States;
591 rew0States = storm::utility::graph::performProb1(backwardTransitions, zeroRewardStatesGetter(), targetStates);
592 } else {
593 rew0States = targetStates;
594 }
595
596 // Determine which states have a reward that is less than infinity.
597 storm::storage::BitVector maybeStates;
598 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
599 maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
601
602 STORM_LOG_INFO("Preprocessing: " << rew0States.getNumberOfSetBits() << " States with reward zero (" << maybeStates.getNumberOfSetBits()
603 << " states remaining).");
604 } else {
605 storm::storage::BitVector trueStates(transitionMatrix.getRowCount(), true);
606 storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(backwardTransitions, trueStates, rew0States);
607 infinityStates.complement();
608 maybeStates = ~(rew0States | infinityStates);
609
610 STORM_LOG_INFO("Preprocessing: " << infinityStates.getNumberOfSetBits() << " states with reward infinity, " << rew0States.getNumberOfSetBits()
611 << " states with reward zero (" << maybeStates.getNumberOfSetBits() << " states remaining).");
612
614 }
615
616 // Check if the values of the maybe states are relevant for the SolveGoal
617 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(maybeStates);
618
619 // Check whether we need to compute exact rewards for some states.
620 if (qualitative || maybeStatesNotRelevant) {
621 // Set the values for all maybe-states to 1 to indicate that their reward values
622 // are neither 0 nor infinity.
624 } else {
625 if (!maybeStates.empty()) {
626 if constexpr (storm::IsIntervalType<ValueType>) {
627 // In this case we have to compute the reward values for the remaining states.
628 // We can eliminate the rows and columns from the original transition probability matrix.
629 storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.filterEntries(transitionMatrix.getRowFilter(maybeStates));
630
631 // Prepare the right-hand side of the equation system.
632 std::vector<ValueType> b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, maybeStates);
633
634 // Compute values for maybe states.
635 std::vector<SolutionType> x = computeRobustValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, true);
636
637 // Set values of resulting vector according to result.
639 } else {
640 // Check whether we need to convert the input to equation system format.
641 storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory;
642 bool convertToEquationSystem =
644
645 // In this case we have to compute the reward values for the remaining states.
646 // We can eliminate the rows and columns from the original transition probability matrix.
647 storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, convertToEquationSystem);
648
649 // Initialize the x vector with the hint (if available) or with 1 for each element.
650 // This is the initial guess for the iterative solvers.
651 std::vector<ValueType> x;
652 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasResultHint()) {
653 x = storm::utility::vector::filterVector(hint.template asExplicitModelCheckerHint<ValueType>().getResultHint(), maybeStates);
654 } else {
655 x = std::vector<ValueType>(submatrix.getColumnCount(), storm::utility::one<ValueType>());
656 }
657
658 // Prepare the right-hand side of the equation system.
659 std::vector<ValueType> b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, maybeStates);
660
661 storm::solver::LinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env);
662 boost::optional<std::vector<ValueType>> upperRewardBounds;
663 requirements.clearLowerBounds();
664 if (requirements.upperBounds()) {
665 upperRewardBounds = computeUpperRewardBounds(submatrix, b, transitionMatrix.getConstrainedRowSumVector(maybeStates, rew0States));
666 requirements.clearUpperBounds();
667 }
668 STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
669 "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked.");
670
671 // If necessary, convert the matrix from the fixpoint notation to the form needed for the equation system.
672 if (convertToEquationSystem) {
673 // go from x = A*x + b to (I-A)x = b.
674 submatrix.convertToEquationSystem();
675 }
676
677 // Create the solver.
678 goal.restrictRelevantValues(maybeStates);
679 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver =
680 storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix));
681 solver->setLowerBound(storm::utility::zero<ValueType>());
682 if (upperRewardBounds) {
683 solver->setUpperBounds(std::move(upperRewardBounds.get()));
684 }
685
686 // Now solve the resulting equation system.
687 solver->solveEquations(env, x, b);
688
689 // Set values of resulting vector according to result.
691 }
692 }
693 }
694 return result;
695}
696
697template<typename ValueType, typename RewardModelType, typename SolutionType>
698typename SparseDtmcPrctlHelper<ValueType, RewardModelType, SolutionType>::BaierTransformedModel
699SparseDtmcPrctlHelper<ValueType, RewardModelType, SolutionType>::computeBaierTransformation(Environment const& env,
700 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
701 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
702 storm::storage::BitVector const& targetStates,
703 storm::storage::BitVector const& conditionStates,
704 boost::optional<std::vector<ValueType>> const& stateRewards) {
705 if constexpr (storm::IsIntervalType<ValueType>) {
706 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support baier transformation with interval models.");
707 } else {
708 BaierTransformedModel result;
709
710 // Start by computing all 'before' states, i.e. the states for which the conditional probability is defined.
711 std::vector<ValueType> probabilitiesToReachConditionStates =
712 computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), transitionMatrix, backwardTransitions,
713 storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false);
714
715 result.beforeStates = storm::storage::BitVector(targetStates.size(), true);
716 uint_fast64_t state = 0;
717 uint_fast64_t beforeStateIndex = 0;
718 for (auto const& value : probabilitiesToReachConditionStates) {
719 if (value == storm::utility::zero<ValueType>()) {
720 result.beforeStates.set(state, false);
721 } else {
722 probabilitiesToReachConditionStates[beforeStateIndex] = value;
723 ++beforeStateIndex;
724 }
725 ++state;
726 }
727 probabilitiesToReachConditionStates.resize(beforeStateIndex);
728
729 if (targetStates.empty()) {
730 result.noTargetStates = true;
731 return result;
732 } else if (!result.beforeStates.empty()) {
733 // If there are some states for which the conditional probability is defined and there are some
734 // states that can reach the target states without visiting condition states first, we need to
735 // do more work.
736
737 // First, compute the relevant states and some offsets.
738 storm::storage::BitVector allStates(targetStates.size(), true);
739 std::vector<uint_fast64_t> numberOfBeforeStatesUpToState = result.beforeStates.getNumberOfSetBitsBeforeIndices();
740 storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(backwardTransitions, allStates, targetStates);
741 statesWithProbabilityGreater0 &= storm::utility::graph::getReachableStates(transitionMatrix, conditionStates, allStates, targetStates);
742 uint_fast64_t normalStatesOffset = result.beforeStates.getNumberOfSetBits();
743 std::vector<uint_fast64_t> numberOfNormalStatesUpToState = statesWithProbabilityGreater0.getNumberOfSetBitsBeforeIndices();
744
745 // All transitions going to states with probability zero, need to be redirected to a deadlock state.
746 bool addDeadlockState = false;
747 uint_fast64_t deadlockState = normalStatesOffset + statesWithProbabilityGreater0.getNumberOfSetBits();
748
749 // Now, we create the matrix of 'before' and 'normal' states.
750 storm::storage::SparseMatrixBuilder<ValueType> builder;
751
752 // Start by creating the transitions of the 'before' states.
753 uint_fast64_t currentRow = 0;
754 for (auto beforeState : result.beforeStates) {
755 if (conditionStates.get(beforeState)) {
756 // For condition states, we move to the 'normal' states.
757 ValueType zeroProbability = storm::utility::zero<ValueType>();
758 for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) {
759 if (statesWithProbabilityGreater0.get(successorEntry.getColumn())) {
760 builder.addNextValue(currentRow, normalStatesOffset + numberOfNormalStatesUpToState[successorEntry.getColumn()],
761 successorEntry.getValue());
762 } else {
763 zeroProbability += successorEntry.getValue();
764 }
765 }
766 if (!storm::utility::isZero(zeroProbability)) {
767 builder.addNextValue(currentRow, deadlockState, zeroProbability);
768 }
769 } else {
770 // For non-condition states, we scale the probabilities going to other before states.
771 for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) {
772 if (result.beforeStates.get(successorEntry.getColumn())) {
773 builder.addNextValue(currentRow, numberOfBeforeStatesUpToState[successorEntry.getColumn()],
774 successorEntry.getValue() *
775 probabilitiesToReachConditionStates[numberOfBeforeStatesUpToState[successorEntry.getColumn()]] /
776 probabilitiesToReachConditionStates[currentRow]);
777 }
778 }
779 }
780 ++currentRow;
781 }
782
783 // Then, create the transitions of the 'normal' states.
784 for (uint64_t state : statesWithProbabilityGreater0) {
785 ValueType zeroProbability = storm::utility::zero<ValueType>();
786 for (auto const& successorEntry : transitionMatrix.getRow(state)) {
787 if (statesWithProbabilityGreater0.get(successorEntry.getColumn())) {
788 builder.addNextValue(currentRow, normalStatesOffset + numberOfNormalStatesUpToState[successorEntry.getColumn()],
789 successorEntry.getValue());
790 } else {
791 zeroProbability += successorEntry.getValue();
792 }
793 }
794 if (!storm::utility::isZero(zeroProbability)) {
795 addDeadlockState = true;
796 builder.addNextValue(currentRow, deadlockState, zeroProbability);
797 }
798 ++currentRow;
799 }
800 if (addDeadlockState) {
801 builder.addNextValue(deadlockState, deadlockState, storm::utility::one<ValueType>());
802 }
803
804 // Build the new transition matrix and the new targets.
805 result.transitionMatrix = builder.build(addDeadlockState ? (deadlockState + 1) : deadlockState);
806 storm::storage::BitVector newTargetStates = targetStates % result.beforeStates;
807 newTargetStates.resize(result.transitionMatrix.get().getRowCount());
808 for (uint64_t state : targetStates % statesWithProbabilityGreater0) {
809 newTargetStates.set(normalStatesOffset + state, true);
810 }
811 result.targetStates = std::move(newTargetStates);
812
813 // If a reward model was given, we need to compute the rewards for the transformed model.
814 if (stateRewards) {
815 std::vector<ValueType> newStateRewards(result.beforeStates.getNumberOfSetBits());
816 storm::utility::vector::selectVectorValues(newStateRewards, result.beforeStates, stateRewards.get());
817
818 newStateRewards.reserve(result.transitionMatrix.get().getRowCount());
819 for (uint64_t state : statesWithProbabilityGreater0) {
820 newStateRewards.push_back(stateRewards.get()[state]);
821 }
822 // Add a zero reward to the deadlock state.
823 if (addDeadlockState) {
824 newStateRewards.push_back(storm::utility::zero<ValueType>());
825 }
826 result.stateRewards = std::move(newStateRewards);
827 }
828 }
829
830 return result;
831 }
832}
833
834template<typename ValueType, typename RewardModelType, typename SolutionType>
835storm::storage::BitVector SparseDtmcPrctlHelper<ValueType, RewardModelType, SolutionType>::BaierTransformedModel::getNewRelevantStates() const {
836 storm::storage::BitVector newRelevantStates(transitionMatrix.get().getRowCount());
837 for (uint64_t i = 0; i < this->beforeStates.getNumberOfSetBits(); ++i) {
838 newRelevantStates.set(i);
839 }
840 return newRelevantStates;
841}
842
843template<typename ValueType, typename RewardModelType, typename SolutionType>
844storm::storage::BitVector SparseDtmcPrctlHelper<ValueType, RewardModelType, SolutionType>::BaierTransformedModel::getNewRelevantStates(
845 storm::storage::BitVector const& oldRelevantStates) const {
846 storm::storage::BitVector result = oldRelevantStates % this->beforeStates;
847 result.resize(transitionMatrix.get().getRowCount());
848 return result;
849}
850
851template<typename ValueType, typename RewardModelType, typename SolutionType>
854 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates,
855 storm::storage::BitVector const& conditionStates, bool qualitative) {
856 if constexpr (storm::IsIntervalType<ValueType>) {
857 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing conditional probabilities with interval models.");
858 } else {
859 // Prepare result vector.
860 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
861
862 if (!conditionStates.empty()) {
863 BaierTransformedModel transformedModel =
864 computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none);
865
866 if (transformedModel.noTargetStates) {
867 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
868 } else {
869 // At this point, we do not need to check whether there are 'before' states, since the condition
870 // states were non-empty so there is at least one state with a positive probability of satisfying
871 // the condition.
872
873 // Now compute reachability probabilities in the transformed model.
874 storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
875 storm::storage::BitVector newRelevantValues;
876 if (goal.hasRelevantValues()) {
877 newRelevantValues = transformedModel.getNewRelevantStates(goal.relevantValues());
878 } else {
879 newRelevantValues = transformedModel.getNewRelevantStates();
880 }
881 goal.setRelevantValues(std::move(newRelevantValues));
882 std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(
883 env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(),
884 storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative);
885
886 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities);
887 }
888 }
889
890 return result;
891 }
892}
893
894template<typename ValueType, typename RewardModelType, typename SolutionType>
897 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates,
898 storm::storage::BitVector const& conditionStates, bool qualitative) {
899 if constexpr (storm::IsIntervalType<ValueType>) {
900 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing conditional rewards with interval models.");
901 } else {
902 // Prepare result vector.
903 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
904
905 if (!conditionStates.empty()) {
906 BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates,
907 rewardModel.getTotalRewardVector(transitionMatrix));
908
909 if (transformedModel.noTargetStates) {
910 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
911 } else {
912 // At this point, we do not need to check whether there are 'before' states, since the condition
913 // states were non-empty so there is at least one state with a positive probability of satisfying
914 // the condition.
915
916 // Now compute reachability probabilities in the transformed model.
917 storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
918 storm::storage::BitVector newRelevantValues;
919 if (goal.hasRelevantValues()) {
920 newRelevantValues = transformedModel.getNewRelevantStates(goal.relevantValues());
921 } else {
922 newRelevantValues = transformedModel.getNewRelevantStates();
923 }
924 goal.setRelevantValues(std::move(newRelevantValues));
925 std::vector<ValueType> conditionalRewards =
926 computeReachabilityRewards(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(),
927 transformedModel.targetStates.get(), qualitative);
928 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalRewards);
929 }
930 }
931
932 return result;
933 }
934}
935
936template class SparseDtmcPrctlHelper<double>;
937
942} // namespace helper
943} // namespace modelchecker
944} // 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
std::vector< ValueType > computeUpperBounds()
Computes upper bounds on the expected rewards.
static std::vector< SolutionType > computeUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&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< SolutionType > computeConditionalProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&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< SolutionType > computeReachabilityTimes(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&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< SolutionType > computeReachabilityRewards(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&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< SolutionType > computeDiscountedCumulativeRewards(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepBound, ValueType discountFactor)
static std::vector< SolutionType > computeConditionalRewards(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&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< SolutionType > computeDiscountedTotalRewards(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&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::map< storm::storage::sparse::state_type, SolutionType > computeRewardBoundedValues(Environment const &env, storm::models::sparse::Dtmc< ValueType > const &model, std::shared_ptr< storm::logic::OperatorFormula const > rewardBoundedFormula)
static std::vector< SolutionType > computeAllUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&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< SolutionType > computeGloballyProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &psiStates, bool qualitative)
static std::vector< SolutionType > computeTotalRewards(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::vector< SolutionType > computeCumulativeRewards(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepBound)
static std::vector< SolutionType > computeInstantaneousRewards(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepCount)
static std::vector< SolutionType > computeNextProbabilities(Environment const &env, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &nextStates)
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:178
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, SolutionType > > 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.
bool isDisjointFrom(BitVector const &other) const
Checks whether none of the bits that are set in the current bit vector are also set in the given bit ...
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.
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.
const_rows getRow(index_type row) const
Returns an object representing the given row.
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.
storm::storage::BitVector getRowFilter(storm::storage::BitVector const &groupConstraint) const
Returns a bitvector representing the set of rows, with all indices set that correspond to one of the ...
SparseMatrix filterEntries(storm::storage::BitVector const &rowFilter) const
Returns a copy of this matrix that only considers entries in the selected rows.
A class that provides convenience operations to display run times.
bool updateProgress(uint64_t count)
Updates the progress to the current count and logs it (on the progress log channel) if the delay pass...
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:13
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:27
#define STORM_LOG_STATISTICS(message)
Definition logging.h:41
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
SFTBDDChecker::ValueType ValueType
void exportDataToCSVFile(std::string filepath, std::vector< std::vector< DataType > > const &data, boost::optional< std::vector< Header1Type > > const &header1=boost::none, boost::optional< std::vector< Header2Type > > const &header2=boost::none)
Definition export.h:13
std::vector< SolutionType > computeRobustValuesForMaybeStates(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > &&submatrix, std::vector< ValueType > const &b, bool computeReward)
std::vector< ValueType > computeUpperRewardBounds(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< ValueType > const &rewards, std::vector< ValueType > const &oneStepTargetProbabilities)
SettingsType const & getModule()
Get module.
std::unique_ptr< storm::solver::MinMaxLinearEquationSolver< ValueType, SolutionType > > configureMinMaxLinearEquationSolver(Environment const &env, SolveGoal< ValueType, SolutionType > &&goal, storm::solver::MinMaxLinearEquationSolverFactory< ValueType, SolutionType > const &factory, MatrixType &&matrix, OptimizationDirectionSetting optimizationDirectionSetting=OptimizationDirectionSetting::Unset)
Definition SolveGoal.h:110
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:132
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 setAllValues(std::vector< T > &vec, storm::storage::BitVector const &positions, T const &positiveValue=storm::utility::one< T >(), T const &negativeValue=storm::utility::zero< T >())
Definition vector.h:53
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:37
bool isZero(ValueType const &a)
Definition constants.cpp:42
ValueType zero()
Definition constants.cpp:24
ValueType infinity()
Definition constants.cpp:29
ValueType one()
Definition constants.cpp:19
TargetType convertNumber(SourceType const &number)
constexpr bool IsIntervalType
Helper to check if a type is an interval.
carl::RationalFunction< Polynomial, true > RationalFunction