Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseMdpPrctlHelper.cpp
Go to the documentation of this file.
2
10#include "storm/io/export.h"
32#include "storm/utility/graph.h"
35
36namespace storm {
37namespace modelchecker {
38namespace helper {
39
40template<typename ValueType, typename SolutionType>
41std::map<storm::storage::sparse::state_type, SolutionType> SparseMdpPrctlHelper<ValueType, SolutionType>::computeRewardBoundedValues(
43 storm::storage::BitVector const& initialStates) {
45 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing reward bounded values with interval models.");
46 } else {
47 storm::utility::Stopwatch swAll(true), swBuild, swCheck;
48
49 // Get lower and upper bounds for the solution.
50 auto lowerBound = rewardUnfolding.getLowerObjectiveBound();
51 auto upperBound = rewardUnfolding.getUpperObjectiveBound();
52
53 // Initialize epoch models
54 auto initEpoch = rewardUnfolding.getStartEpoch();
55 auto epochOrder = rewardUnfolding.getEpochComputationOrder(initEpoch);
56
57 // initialize data that will be needed for each epoch
58 std::vector<ValueType> x, b;
59 std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> minMaxSolver;
60
61 ValueType precision = rewardUnfolding.getRequiredEpochModelPrecision(
63 Environment preciseEnv = env;
65
66 // In case of cdf export we store the necessary data.
67 std::vector<std::vector<ValueType>> cdfData;
68
69 storm::utility::ProgressMeasurement progress("epochs");
70 progress.setMaxCount(epochOrder.size());
71 progress.startNewMeasurement(0);
72 uint64_t numCheckedEpochs = 0;
73 for (auto const& epoch : epochOrder) {
74 swBuild.start();
75 auto& epochModel = rewardUnfolding.setCurrentEpoch(epoch);
76 swBuild.stop();
77 swCheck.start();
78 rewardUnfolding.setSolutionForCurrentEpoch(epochModel.analyzeSingleObjective(preciseEnv, dir, x, b, minMaxSolver, lowerBound, upperBound));
79 swCheck.stop();
81 !rewardUnfolding.getEpochManager().hasBottomDimension(epoch)) {
82 std::vector<ValueType> cdfEntry;
83 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
84 uint64_t offset = rewardUnfolding.getDimension(i).boundType == helper::rewardbounded::DimensionBoundType::LowerBound ? 1 : 0;
85 cdfEntry.push_back(storm::utility::convertNumber<ValueType>(rewardUnfolding.getEpochManager().getDimensionOfEpoch(epoch, i) + offset) *
86 rewardUnfolding.getDimension(i).scalingFactor);
87 }
88 cdfEntry.push_back(rewardUnfolding.getInitialStateResult(epoch));
89 cdfData.push_back(std::move(cdfEntry));
90 }
91 ++numCheckedEpochs;
92 progress.updateProgress(numCheckedEpochs);
94 break;
95 }
96 }
97
98 std::map<storm::storage::sparse::state_type, ValueType> result;
99 for (uint64_t initState : initialStates) {
100 result[initState] = rewardUnfolding.getInitialStateResult(initEpoch, initState);
101 }
102
103 swAll.stop();
104
106 std::vector<std::string> headers;
107 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
108 headers.push_back(rewardUnfolding.getDimension(i).formula->toString());
109 }
110 headers.push_back("Result");
112 storm::settings::getModule<storm::settings::modules::IOSettings>().getExportCdfDirectory() + "cdf.csv", cdfData, headers);
113 }
114
115 STORM_LOG_STATISTICS("---------------------------------\n");
116 STORM_LOG_STATISTICS("Statistics:\n");
117 STORM_LOG_STATISTICS("---------------------------------\n");
118 STORM_LOG_STATISTICS(" #checked epochs: " << epochOrder.size() << ".\n");
119 STORM_LOG_STATISTICS(" overall Time: " << swAll << ".\n");
120 STORM_LOG_STATISTICS("Epoch Model building Time: " << swBuild << ".\n");
121 STORM_LOG_STATISTICS("Epoch Model checking Time: " << swCheck << ".\n");
122 STORM_LOG_STATISTICS("---------------------------------\n");
123
124 return result;
125 }
126}
127
128template<typename ValueType, typename SolutionType>
130 Environment const& env, OptimizationDirection dir, UncertaintyResolutionMode uncertaintyResolutionMode,
131 storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) {
132 // Create the vector with which to multiply and initialize it correctly.
133 std::vector<SolutionType> result(transitionMatrix.getRowGroupCount());
135
136 auto multiplier = storm::solver::MultiplierFactory<ValueType, SolutionType>().create(env, transitionMatrix);
137 multiplier->multiplyAndReduce(env, dir, result, nullptr, result, uncertaintyResolutionMode);
138
139 return result;
140}
141
142template<typename ValueType, typename SolutionType = ValueType>
143std::vector<uint_fast64_t> computeValidSchedulerHint(Environment const& env, SemanticSolutionType const& type,
144 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
145 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
146 storm::storage::BitVector const& maybeStates, storm::storage::BitVector const& filterStates,
147 storm::storage::BitVector const& targetStates,
148 boost::optional<storm::storage::BitVector> const& selectedChoices) {
149 storm::storage::Scheduler<SolutionType> validScheduler(maybeStates.size());
150
152 storm::utility::graph::computeSchedulerProbGreater0E(transitionMatrix, backwardTransitions, filterStates, targetStates, validScheduler,
153 selectedChoices);
154 } else if (type == SemanticSolutionType::ExpectedRewards) {
155 storm::utility::graph::computeSchedulerProb1E(maybeStates | targetStates, transitionMatrix, backwardTransitions, filterStates, targetStates,
156 validScheduler, selectedChoices);
157 } else {
158 STORM_LOG_ASSERT(false, "Unexpected equation system type.");
159 }
160
161 // Extract the relevant parts of the scheduler for the solver.
162 std::vector<uint64_t> schedulerHint;
163 schedulerHint.reserve(maybeStates.getNumberOfSetBits());
164 if (selectedChoices) {
165 // There might be unselected choices so the local choice indices from the scheduler need to be adapted
166 for (uint64_t maybeState : maybeStates) {
167 auto choice = validScheduler.getChoice(maybeState).getDeterministicChoice();
168 auto const groupStart = transitionMatrix.getRowGroupIndices()[maybeState];
169 auto const origGlobalChoiceIndex = groupStart + choice;
170 STORM_LOG_ASSERT(selectedChoices->get(origGlobalChoiceIndex), "The computed scheduler selects an illegal choice.");
171 // Count the number of unselected choices in [groupStart, origGlobalChoiceIndex) and subtract that from choice
172 for (auto pos = selectedChoices->getNextUnsetIndex(groupStart); pos < origGlobalChoiceIndex; pos = selectedChoices->getNextUnsetIndex(pos + 1)) {
173 --choice;
174 }
175 schedulerHint.push_back(choice);
176 }
177 } else {
178 for (uint64_t maybeState : maybeStates) {
179 schedulerHint.push_back(validScheduler.getChoice(maybeState).getDeterministicChoice());
180 }
181 }
182 return schedulerHint;
183}
184
185template<typename ValueType>
188 // Intentionally left empty.
189 }
190
191 bool hasSchedulerHint() const {
192 return static_cast<bool>(schedulerHint);
193 }
194
195 bool hasValueHint() const {
196 return static_cast<bool>(valueHint);
197 }
198
199 bool hasLowerResultBound() const {
200 return static_cast<bool>(lowerResultBound);
201 }
202
203 ValueType const& getLowerResultBound() const {
204 return lowerResultBound.get();
205 }
206
207 bool hasUpperResultBound() const {
208 return static_cast<bool>(upperResultBound);
209 }
210
211 bool hasUpperResultBounds() const {
212 return static_cast<bool>(upperResultBounds);
213 }
214
215 ValueType const& getUpperResultBound() const {
216 return upperResultBound.get();
217 }
218
219 std::vector<ValueType>& getUpperResultBounds() {
220 return upperResultBounds.get();
221 }
222
223 std::vector<ValueType> const& getUpperResultBounds() const {
224 return upperResultBounds.get();
225 }
226
227 std::vector<uint64_t>& getSchedulerHint() {
228 return schedulerHint.get();
229 }
230
231 std::vector<ValueType>& getValueHint() {
232 return valueHint.get();
233 }
234
237 }
238
240 return computeUpperBounds;
241 }
242
243 bool hasUniqueSolution() const {
244 return uniqueSolution;
245 }
246
247 bool hasNoEndComponents() const {
248 return noEndComponents;
249 }
250
251 boost::optional<std::vector<uint64_t>> schedulerHint;
252 boost::optional<std::vector<ValueType>> valueHint;
253 boost::optional<ValueType> lowerResultBound;
254 boost::optional<ValueType> upperResultBound;
255 boost::optional<std::vector<ValueType>> upperResultBounds;
260};
261
262template<typename ValueType, typename SolutionType>
264 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& maybeStates,
265 boost::optional<storm::storage::BitVector> const& selectedChoices, ModelCheckerHint const& hint,
266 bool skipECWithinMaybeStatesCheck) {
267 // Deal with scheduler hint.
268 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasSchedulerHint()) {
269 if (hintStorage.hasSchedulerHint()) {
270 STORM_LOG_WARN("A scheduler hint was provided, but the solver requires a specific one. The provided scheduler hint will be ignored.");
271 } else {
272 auto const& schedulerHint = hint.template asExplicitModelCheckerHint<ValueType>().getSchedulerHint();
273 std::vector<uint64_t> hintChoices;
274
275 // The scheduler hint is only applicable if it induces no BSCC consisting of maybe states.
276 bool hintApplicable;
277 if (!skipECWithinMaybeStatesCheck) {
278 hintChoices.reserve(maybeStates.size());
279 for (uint_fast64_t state = 0; state < maybeStates.size(); ++state) {
280 hintChoices.push_back(schedulerHint.getChoice(state).getDeterministicChoice());
281 }
282 hintApplicable =
283 storm::utility::graph::performProb1(transitionMatrix.transposeSelectedRowsFromRowGroups(hintChoices), maybeStates, ~maybeStates).full();
284 } else {
285 hintApplicable = true;
286 }
287
288 if (hintApplicable) {
289 // Compute the hint w.r.t. the given subsystem.
290 hintChoices.clear();
291 hintChoices.reserve(maybeStates.getNumberOfSetBits());
292 for (uint64_t state : maybeStates) {
293 uint_fast64_t hintChoice = schedulerHint.getChoice(state).getDeterministicChoice();
294 if (selectedChoices) {
295 uint_fast64_t firstChoice = transitionMatrix.getRowGroupIndices()[state];
296 uint_fast64_t lastChoice = firstChoice + hintChoice;
297 hintChoice = 0;
298 for (uint_fast64_t choice = selectedChoices->getNextSetIndex(firstChoice); choice < lastChoice;
299 choice = selectedChoices->getNextSetIndex(choice + 1)) {
300 ++hintChoice;
301 }
302 }
303 hintChoices.push_back(hintChoice);
304 }
305 hintStorage.schedulerHint = std::move(hintChoices);
306 }
307 }
308 }
309
310 // Deal with solution value hint. Only applicable if there are no End Components consisting of maybe states.
311 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasResultHint() &&
312 (skipECWithinMaybeStatesCheck || hintStorage.hasSchedulerHint() ||
313 storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, maybeStates, ~maybeStates)
314 .full())) {
315 hintStorage.valueHint = storm::utility::vector::filterVector(hint.template asExplicitModelCheckerHint<SolutionType>().getResultHint(), maybeStates);
316 }
317}
318
319template<typename ValueType, typename SolutionType>
322 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& maybeStates,
323 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& targetStates, bool produceScheduler,
324 boost::optional<storm::storage::BitVector> const& selectedChoices = boost::none) {
326
327 // There are no end components if we minimize until probabilities or
328 // maximize reachability rewards or if the hint tells us so.
329 result.noEndComponents = (dir == storm::solver::OptimizationDirection::Minimize && type == SemanticSolutionType::UntilProbabilities) ||
330 (dir == storm::solver::OptimizationDirection::Maximize && type == SemanticSolutionType::ExpectedRewards) ||
331 (hint.isExplicitModelCheckerHint() && hint.asExplicitModelCheckerHint<ValueType>().getNoEndComponentsInMaybeStates());
332
333 // If there are no end components, the solution is unique. (Note that the other direction does not hold,
334 // e.g., end components in which infinite reward is collected.
335 result.uniqueSolution = result.hasNoEndComponents();
336
337 // Check for requirements of the solver.
338 bool hasSchedulerHint = hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasSchedulerHint();
341 minMaxLinearEquationSolverFactory.getRequirements(env, result.uniqueSolution, result.noEndComponents, dir, hasSchedulerHint, produceScheduler);
342 if (requirements.hasEnabledRequirement()) {
343 // If the solver still requires no end-components, we have to eliminate them later.
344 if (requirements.uniqueSolution()) {
346 "The solver requires to eliminate the end components although the solution is already assumed to be unique.");
347 STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires a unique solution.");
348 result.eliminateEndComponents = true;
349 // If end components have been eliminated we can assume a unique solution.
350 result.uniqueSolution = true;
351 requirements.clearUniqueSolution();
352 // If we compute until probabilities, we can even assume the absence of end components.
353 // Note that in the case of minimizing expected rewards there might still be end components in which reward is collected.
355 }
356
357 // If the solver requires an initial scheduler, compute one now. Note that any scheduler is valid if there are no end components.
358 if (requirements.validInitialScheduler() && !result.noEndComponents) {
359 STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it.");
360 result.schedulerHint = computeValidSchedulerHint<ValueType, SolutionType>(env, type, transitionMatrix, backwardTransitions, maybeStates, phiStates,
361 targetStates, selectedChoices);
362 requirements.clearValidInitialScheduler();
363 }
364
365 // Finally, we have information on the bounds depending on the problem type.
367 requirements.clearBounds();
368 } else if (type == SemanticSolutionType::ExpectedRewards) {
369 requirements.clearLowerBounds();
370 }
371 if (requirements.upperBounds()) {
372 result.computeUpperBounds = true;
373 requirements.clearUpperBounds();
374 }
375 STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
376 "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked.");
377 } else {
378 STORM_LOG_DEBUG("Solver has no requirements.");
379 }
380
381 // Only if there is no end component decomposition that we will need to do later, we use value and scheduler
382 // hints from the provided hint.
383 if (!result.eliminateEndComponents) {
384 extractValueAndSchedulerHint(result, transitionMatrix, backwardTransitions, maybeStates, selectedChoices, hint, result.uniqueSolution);
385 } else {
386 if (hint.isEmpty()) {
387 STORM_LOG_TRACE("Warn A non-empty hint was provided, but its information will be disregarded.");
388 }
389 }
390
391 // Only set bounds if we did not obtain them from the hint.
392 if (!result.hasLowerResultBound()) {
394 }
397 }
398
399 // If we received an upper bound, we can drop the requirement to compute one.
400 if (result.hasUpperResultBound()) {
401 result.computeUpperBounds = false;
402 }
403
404 return result;
405}
406
407template<typename ValueType>
409 MaybeStateResult(std::vector<ValueType>&& values) : values(std::move(values)) {
410 // Intentionally left empty.
411 }
412
413 bool hasScheduler() const {
414 return static_cast<bool>(scheduler);
415 }
416
417 std::vector<uint64_t> const& getScheduler() const {
418 return scheduler.get();
419 }
420
421 std::vector<ValueType> const& getValues() const {
422 return values;
423 }
424
425 std::vector<ValueType> values;
426 boost::optional<std::vector<uint64_t>> scheduler;
427};
428
429template<typename ValueType, typename SolutionType>
431 storm::storage::SparseMatrix<ValueType>&& submatrix, std::vector<ValueType> const& b,
432 bool produceScheduler, SparseMdpHintType<SolutionType>& hint) {
433 // Initialize the solution vector.
434 std::vector<SolutionType> x =
435 hint.hasValueHint() ? std::move(hint.getValueHint())
436 : std::vector<SolutionType>(submatrix.getRowGroupCount(),
438
439 // Capture the uncertainty resolution mode before the goal is consumed by the solver configuration.
440 auto const uncertaintyResolutionMode = goal.getUncertaintyResolutionMode();
441 // Set up the solver.
443 std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType, SolutionType>> solver =
444 storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, std::move(submatrix));
445 solver->setRequirementsChecked();
446 solver->setUncertaintyResolutionMode(uncertaintyResolutionMode);
447 solver->setHasUniqueSolution(hint.hasUniqueSolution());
448 solver->setHasNoEndComponents(hint.hasNoEndComponents());
449 if (hint.hasLowerResultBound()) {
450 solver->setLowerBound(hint.getLowerResultBound());
451 }
452 if (hint.hasUpperResultBound()) {
453 solver->setUpperBound(hint.getUpperResultBound());
454 }
455 if (hint.hasUpperResultBounds()) {
456 solver->setUpperBounds(std::move(hint.getUpperResultBounds()));
457 }
458 if (hint.hasSchedulerHint()) {
459 solver->setInitialScheduler(std::move(hint.getSchedulerHint()));
460 }
461 solver->setTrackScheduler(produceScheduler);
462
463 // Solve the corresponding system of equations.
464 solver->solveEquations(env, x, b);
465
466#ifndef NDEBUG
467 // As a sanity check, make sure our local upper bounds were in fact correct.
469 uint64_t relevantState = solver->hasRelevantValues() ? solver->getRelevantValues().getNextSetIndex(0ull) : 0ull;
470 std::function<void()> getNextRelevantStateIndex;
471 if (solver->hasRelevantValues()) {
472 storm::storage::BitVector const& relevantValues = solver->getRelevantValues();
473 getNextRelevantStateIndex = [&relevantState, &relevantValues]() { relevantState = relevantValues.getNextSetIndex(++relevantState); };
474 } else {
475 getNextRelevantStateIndex = [&relevantState]() { ++relevantState; };
476 }
477 for (; relevantState < solver->getUpperBounds().size(); getNextRelevantStateIndex()) {
478 STORM_LOG_ASSERT(x.at(relevantState) <=
479 solver->getUpperBounds().at(relevantState) + storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()),
480 "Expecting result value for state " << relevantState << " to be <= " << solver->getUpperBounds().at(relevantState) << ", but got "
481 << x.at(relevantState) << ".");
482 }
483 }
484#endif
485
486 // Create result.
487 MaybeStateResult<SolutionType> result(std::move(x));
488
489 // If requested, return the requested scheduler.
490 if (produceScheduler) {
491 result.scheduler = std::move(solver->getSchedulerChoices());
492 }
493 return result;
494}
495
501
502template<typename ValueType>
505 result.maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
506
507 // Treat the states with probability zero/one.
508 std::vector<ValueType> const& resultsForNonMaybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getResultHint();
511 storm::storage::BitVector nonMaybeStates = ~result.maybeStates;
512 for (uint64_t state : nonMaybeStates) {
513 if (storm::utility::isOne(resultsForNonMaybeStates[state])) {
514 result.statesWithProbability1.set(state, true);
515 } else {
516 STORM_LOG_THROW(storm::utility::isZero(resultsForNonMaybeStates[state]), storm::exceptions::IllegalArgumentException,
517 "Expected that the result hint specifies probabilities in {0,1} for non-maybe states.");
518 result.statesWithProbability0.set(state, true);
519 }
520 }
521
522 return result;
523}
524
525template<typename ValueType, typename SolutionType>
527 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
528 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
529 storm::storage::BitVector const& phiStates,
530 storm::storage::BitVector const& psiStates) {
532
533 // Get all states that have probability 0 and 1 of satisfying the until-formula.
534 std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01;
535 if (goal.minimize()) {
536 statesWithProbability01 =
537 storm::utility::graph::performProb01Min(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, phiStates, psiStates);
538 } else {
539 statesWithProbability01 =
540 storm::utility::graph::performProb01Max(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, phiStates, psiStates);
541 }
542 result.statesWithProbability0 = std::move(statesWithProbability01.first);
543 result.statesWithProbability1 = std::move(statesWithProbability01.second);
545
546 return result;
547}
548
549template<typename ValueType, typename SolutionType>
551 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
552 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
553 storm::storage::BitVector const& phiStates,
554 storm::storage::BitVector const& psiStates, ModelCheckerHint const& hint) {
555 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
557 } else {
558 return computeQualitativeStateSetsUntilProbabilities(goal, transitionMatrix, backwardTransitions, phiStates, psiStates);
559 }
560}
561
562template<typename SolutionType, bool subChoicesCoverOnlyMaybeStates = true>
563void extractSchedulerChoices(storm::storage::Scheduler<SolutionType>& scheduler, std::vector<uint64_t> const& subChoices,
564 storm::storage::BitVector const& maybeStates) {
565 if constexpr (subChoicesCoverOnlyMaybeStates) {
566 auto subChoiceIt = subChoices.begin();
567 for (uint64_t maybeState : maybeStates) {
568 scheduler.setChoice(*subChoiceIt, maybeState);
569 ++subChoiceIt;
570 }
571 STORM_LOG_ASSERT(subChoiceIt == subChoices.end(), "Subchoice iterator not at end.");
572 } else {
573 // See computeFixedPointSystemUntilProbabilities, where we create a different equation system.
574 // Consequentially, we run a slightly different code here for interval-based models.
575 STORM_LOG_ASSERT(maybeStates.size() == subChoices.size(), "Sizes do not coincide.");
576 for (uint64_t maybeState : maybeStates) {
577 scheduler.setChoice(subChoices[maybeState], maybeState);
578 }
579 }
580}
581
582template<typename ValueType, typename SolutionType>
584 storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
585 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
586 // Finally, if we need to produce a scheduler, we also need to figure out the parts of the scheduler for
587 // the states with probability 1 or 0 (depending on whether we maximize or minimize).
588 // We also need to define some arbitrary choice for the remaining states to obtain a fully defined scheduler.
589 if (minimize) {
590 storm::utility::graph::computeSchedulerProb0E(qualitativeStateSets.statesWithProbability0, transitionMatrix, scheduler);
591 for (uint64_t prob1State : qualitativeStateSets.statesWithProbability1) {
592 scheduler.setChoice(0, prob1State);
593 }
594 } else {
595 storm::utility::graph::computeSchedulerProb1E(qualitativeStateSets.statesWithProbability1, transitionMatrix, backwardTransitions, phiStates, psiStates,
596 scheduler);
597 for (uint64_t prob0State : qualitativeStateSets.statesWithProbability0) {
598 scheduler.setChoice(0, prob0State);
599 }
600 }
601}
602
603template<typename ValueType, typename SolutionType>
605 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
606 QualitativeStateSetsUntilProbabilities const& qualitativeStateSets,
607 storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b) {
608 if constexpr (storm::IsIntervalType<ValueType>) {
609 // For non-interval based models, we can eliminate the rows and columns from the original transition probability matrix for states
610 // whose probabilities are already known... However, there is information in the transition to those states.
611 // Thus, we cannot eliminate them all.
612 // We can however drop all the outgoing transitions from these states.
613 // TODO: we can drop more than those entries and actually remove many states (all but the ones reachable in one step from the maybe states),
614 // TODO ctned: however, there is quite some bookkeeping involved in projecting the right vectors.
615 // TODO ctned: Instead is likely easier to just do a pass and make a unique sink and a unique target state.
616 // TODO ctned: If this is ever changed, extractSchedulerChoices must also be updated.
617 submatrix = transitionMatrix.filterEntries(transitionMatrix.getRowFilter(qualitativeStateSets.maybeStates));
618
619 // Prepare the right-hand side of the equation system. For entry i this corresponds to
620 // the accumulated probability of going from state i to some state that has probability 1.
621 storm::utility::vector::setAllValues(b, transitionMatrix.getRowFilter(qualitativeStateSets.statesWithProbability1));
622 } else {
623 // First, we can eliminate the rows and columns from the original transition probability matrix for states
624 // whose probabilities are already known.
625 submatrix = transitionMatrix.getSubmatrix(true, qualitativeStateSets.maybeStates, qualitativeStateSets.maybeStates, false);
626
627 // Prepare the right-hand side of the equation system. For entry i this corresponds to
628 // the accumulated probability of going from state i to some state that has probability 1.
629 b = transitionMatrix.getConstrainedRowGroupSumVector(qualitativeStateSets.maybeStates, qualitativeStateSets.statesWithProbability1);
630 }
631 // If the solve goal has relevant values, we need to adjust them.
632 goal.restrictRelevantValues(qualitativeStateSets.maybeStates);
633}
634
635template<typename ValueType, typename SolutionType>
636boost::optional<SparseMdpEndComponentInformation<ValueType>> computeFixedPointSystemUntilProbabilitiesEliminateEndComponents(
638 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, QualitativeStateSetsUntilProbabilities const& qualitativeStateSets,
639 storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, bool produceScheduler) {
640 // Get the set of states that (under some scheduler) can stay in the set of maybestates forever
642 transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, qualitativeStateSets.maybeStates, ~qualitativeStateSets.maybeStates);
643
644 bool doDecomposition = !candidateStates.empty();
645
647 if (doDecomposition) {
648 // Compute the states that are in MECs.
649 endComponentDecomposition = storm::storage::MaximalEndComponentDecomposition<ValueType>(transitionMatrix, backwardTransitions, candidateStates);
650 STORM_LOG_INFO(endComponentDecomposition.statistics(transitionMatrix.getRowGroupCount()));
651 }
652
653 // Only do more work if there are actually end-components.
654 if (doDecomposition && !endComponentDecomposition.empty()) {
655 STORM_LOG_DEBUG("Eliminating " << endComponentDecomposition.size() << " EC(s).");
657 endComponentDecomposition, transitionMatrix, qualitativeStateSets.maybeStates, &qualitativeStateSets.statesWithProbability1, nullptr, nullptr,
658 submatrix, &b, nullptr, produceScheduler);
659
660 // If the solve goal has relevant values, we need to adjust them.
661 if (goal.hasRelevantValues()) {
662 storm::storage::BitVector newRelevantValues(submatrix.getRowGroupCount());
663 for (auto state : goal.relevantValues()) {
664 if (qualitativeStateSets.maybeStates.get(state)) {
665 newRelevantValues.set(result.getRowGroupAfterElimination(state));
666 }
667 }
668 if (!newRelevantValues.empty()) {
669 goal.setRelevantValues(std::move(newRelevantValues));
670 }
671 }
672
673 return result;
674 } else {
675 STORM_LOG_DEBUG("Not eliminating ECs as there are none.");
676 computeFixedPointSystemUntilProbabilities(goal, transitionMatrix, qualitativeStateSets, submatrix, b);
677
678 return boost::none;
679 }
680}
681
682template<typename ValueType, typename SolutionType>
685 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
686 bool qualitative, bool produceScheduler, ModelCheckerHint const& hint) {
687 STORM_LOG_THROW(!qualitative || !produceScheduler, storm::exceptions::InvalidSettingsException,
688 "Cannot produce scheduler when performing qualitative model checking only.");
689
690 // Prepare resulting vector.
691 std::vector<SolutionType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<SolutionType>());
692
693 // We need to identify the maybe states (states which have a probability for satisfying the until formula
694 // that is strictly between 0 and 1) and the states that satisfy the formula with probablity 1 and 0, respectively.
695 QualitativeStateSetsUntilProbabilities qualitativeStateSets =
696 getQualitativeStateSetsUntilProbabilities(goal, transitionMatrix, backwardTransitions, phiStates, psiStates, hint);
697
698 STORM_LOG_INFO("Preprocessing: " << qualitativeStateSets.statesWithProbability1.getNumberOfSetBits() << " states with probability 1, "
699 << qualitativeStateSets.statesWithProbability0.getNumberOfSetBits() << " with probability 0 ("
700 << qualitativeStateSets.maybeStates.getNumberOfSetBits() << " states remaining).");
701
702 // Set values of resulting vector that are known exactly.
704
705 // Check if the values of the maybe states are relevant for the SolveGoal
706 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(qualitativeStateSets.maybeStates);
707
708 // Capture the goal direction before the goal is consumed by the solver configuration.
709 bool const minimize = goal.minimize();
710 // If requested, we will produce a scheduler.
711 std::unique_ptr<storm::storage::Scheduler<SolutionType>> scheduler;
712 if (produceScheduler) {
713 scheduler = std::make_unique<storm::storage::Scheduler<SolutionType>>(transitionMatrix.getRowGroupCount());
714 // If maybeStatesNotRelevant is true, we have to set the scheduler for maybe states as "dontCare"
715 if (maybeStatesNotRelevant) {
716 for (uint64_t state : qualitativeStateSets.maybeStates) {
717 scheduler->setDontCare(state);
718 }
719 }
720 }
721
722 // Check whether we need to compute exact probabilities for some states.
723 if (qualitative || maybeStatesNotRelevant) {
724 // Set the values for all maybe-states to 0.5 to indicate that their probability values are neither 0 nor 1.
726 } else {
727 if (!qualitativeStateSets.maybeStates.empty()) {
728 // In this case we have have to compute the remaining probabilities.
729
730 // Obtain proper hint information either from the provided hint or from requirements of the solver.
732 env, SemanticSolutionType::UntilProbabilities, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates,
733 phiStates, qualitativeStateSets.statesWithProbability1, produceScheduler);
734
735 // Declare the components of the equation system we will solve.
737 std::vector<ValueType> b;
738
739 // If the hint information tells us that we have to eliminate MECs, we do so now.
740 boost::optional<SparseMdpEndComponentInformation<ValueType>> ecInformation;
741 if (hintInformation.getEliminateEndComponents()) {
742 ecInformation = computeFixedPointSystemUntilProbabilitiesEliminateEndComponents(goal, transitionMatrix, backwardTransitions,
743 qualitativeStateSets, submatrix, b, produceScheduler);
744 } else {
745 // Otherwise, we compute the standard equations.
746 computeFixedPointSystemUntilProbabilities(goal, transitionMatrix, qualitativeStateSets, submatrix, b);
747 }
748
749 // Now compute the results for the maybe states.
750 MaybeStateResult<SolutionType> resultForMaybeStates =
751 computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, hintInformation);
752
753 // If we eliminated end components, we need to extract the result differently.
754 if (ecInformation && ecInformation.get().getEliminatedEndComponents()) {
755 if constexpr (storm::IsIntervalType<ValueType>) {
756 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support this end component with interval models.");
757 } else {
758 ecInformation.get().setValues(result, qualitativeStateSets.maybeStates, resultForMaybeStates.getValues());
759 if (produceScheduler) {
760 ecInformation.get().setScheduler(*scheduler, qualitativeStateSets.maybeStates, transitionMatrix, backwardTransitions,
761 resultForMaybeStates.getScheduler());
762 }
763 }
764 } else {
765 // Set values of resulting vector according to result.
766 if constexpr (!storm::IsIntervalType<ValueType>) {
767 // For non-interval models, we only operated on the maybe states, and we must recover the qualitative values for the other state.
768 storm::utility::vector::setVectorValues<SolutionType>(result, qualitativeStateSets.maybeStates, resultForMaybeStates.getValues());
769 } else {
770 // For interval models, the result for maybe states indeed also holds values for all qualitative states.
771 STORM_LOG_ASSERT(resultForMaybeStates.getValues().size() == transitionMatrix.getColumnCount(), "Dimensions do not match.");
772 result = resultForMaybeStates.getValues();
773 }
774 if (produceScheduler) {
776 qualitativeStateSets.maybeStates);
777 }
778 }
779 }
780 }
781
782 // Extend scheduler with choices for the states in the qualitative state sets.
783 if (produceScheduler) {
784 extendScheduler(*scheduler, minimize, qualitativeStateSets, transitionMatrix, backwardTransitions, phiStates, psiStates);
785 }
786
787 // Sanity check for created scheduler.
788 STORM_LOG_ASSERT(!produceScheduler || scheduler, "Expected that a scheduler was obtained.");
789 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || !scheduler->isPartialScheduler(), "Expected a fully defined scheduler.");
790 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isDeterministicScheduler(), "Expected a deterministic scheduler.");
791 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isMemorylessScheduler(), "Expected a memoryless scheduler.");
792
793 // Return result.
794 return MDPSparseModelCheckingHelperReturnType<SolutionType>(std::move(result), std::move(scheduler));
795}
796
797template<typename ValueType, typename SolutionType>
800 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, bool produceScheduler,
801 bool useMecBasedTechnique) {
802 if (useMecBasedTechnique) {
803 // TODO: does this really work for minimizing objectives?
804 storm::storage::MaximalEndComponentDecomposition<ValueType> mecDecomposition(transitionMatrix, backwardTransitions, psiStates);
805 storm::storage::BitVector statesInPsiMecs(transitionMatrix.getRowGroupCount());
806 for (auto const& mec : mecDecomposition) {
807 for (auto const& stateActionsPair : mec) {
808 statesInPsiMecs.set(stateActionsPair.first, true);
809 }
810 }
811
812 return computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, psiStates, statesInPsiMecs, qualitative,
813 produceScheduler);
814 } else {
815 goal.oneMinus();
816 auto result =
817 computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions,
818 storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), ~psiStates, qualitative, produceScheduler);
819 for (auto& element : result.values) {
820 element = storm::utility::one<SolutionType>() - element;
821 }
822 return result;
823 }
824}
825
826template<typename ValueType, typename SolutionType>
827template<typename RewardModelType>
830 RewardModelType const& rewardModel, uint_fast64_t stepCount) {
831 if constexpr (storm::IsIntervalType<ValueType>) {
832 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support instantenous rewards with interval models.");
833 } else {
834 // Only compute the result if the model has a state-based reward this->getModel().
835 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
836 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
837 // Initialize result to state rewards of the this->getModel().
838 std::vector<SolutionType> result(rewardModel.getStateRewardVector());
839
840 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
841 multiplier->repeatedMultiplyAndReduce(env, goal.direction(), result, nullptr, stepCount, goal.getUncertaintyResolutionMode());
842
843 return result;
844 }
845}
846
847template<typename ValueType, typename SolutionType>
848template<typename RewardModelType>
851 RewardModelType const& rewardModel, uint_fast64_t stepBound) {
852 if constexpr (storm::IsIntervalType<ValueType>) {
853 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support cumulative rewards with interval models.");
854 } else {
855 // Only compute the result if the model has at least one reward this->getModel().
856 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
857
858 // Compute the reward vector to add in each step based on the available reward models.
859 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix);
860
861 // Initialize result to the zero vector.
862 std::vector<SolutionType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<SolutionType>());
863
864 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
865 multiplier->repeatedMultiplyAndReduce(env, goal.direction(), result, &totalRewardVector, stepBound, goal.getUncertaintyResolutionMode());
866
867 return result;
868 }
869}
870
871template<typename ValueType, typename SolutionType>
872template<typename RewardModelType>
875 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, bool qualitative, bool produceScheduler,
876 ModelCheckerHint const& hint) {
877 STORM_LOG_THROW(!rewardModel.hasNegativeRewards(), storm::exceptions::NotImplementedException,
878 "The reward model contains negative rewards. This is not implemented by the total rewards computation.");
879 // Reduce to reachability rewards
880 if (goal.minimize()) {
881 // Identify the states from which no reward can be collected under some scheduler
882 storm::storage::BitVector choicesWithoutReward = rewardModel.getChoicesWithZeroReward(transitionMatrix);
883 storm::storage::BitVector statesWithZeroRewardChoice(transitionMatrix.getRowGroupCount(), false);
884 for (uint64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) {
885 if (choicesWithoutReward.getNextSetIndex(transitionMatrix.getRowGroupIndices()[state]) < transitionMatrix.getRowGroupIndices()[state + 1]) {
886 statesWithZeroRewardChoice.set(state);
887 }
888 }
889 storm::storage::BitVector rew0EStates =
890 storm::utility::graph::performProbGreater0A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions,
891 statesWithZeroRewardChoice, ~statesWithZeroRewardChoice, false, 0, choicesWithoutReward);
892 rew0EStates.complement();
893 auto result = computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, rewardModel, rew0EStates, qualitative,
894 produceScheduler, hint);
895 if (result.scheduler) {
896 storm::utility::graph::computeSchedulerStayingInStates(rew0EStates, transitionMatrix, *result.scheduler, choicesWithoutReward);
897 }
898 return result;
899 } else {
900 // Identify the states from which only states with zero reward are reachable.
901 storm::storage::BitVector statesWithoutReward = rewardModel.getStatesWithZeroReward(transitionMatrix);
902 storm::storage::BitVector rew0AStates = storm::utility::graph::performProbGreater0E(backwardTransitions, statesWithoutReward, ~statesWithoutReward);
903 rew0AStates.complement();
904
905 // There might be end components that consists only of states/choices with zero rewards. The reachability reward semantics would assign such
906 // end components reward infinity. To avoid this, we potentially need to eliminate such end components
907 storm::storage::BitVector trueStates(transitionMatrix.getRowGroupCount(), true);
908 if (storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, trueStates, rew0AStates)
909 .full()) {
910 return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, rewardModel, rew0AStates, qualitative,
911 produceScheduler, hint);
912 } else {
913 // The transformation of schedulers for the ec-eliminated system back to the original one is not implemented.
914 STORM_LOG_ERROR_COND(!produceScheduler, "Can not produce scheduler for this property (functionality not implemented");
915 storm::storage::BitVector choicesWithoutReward = rewardModel.getChoicesWithZeroReward(transitionMatrix);
917 transitionMatrix, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), choicesWithoutReward, rew0AStates, true);
918 storm::storage::BitVector newRew0AStates(ecElimResult.matrix.getRowGroupCount(), false);
919 for (uint64_t oldRew0AState : rew0AStates) {
920 newRew0AStates.set(ecElimResult.oldToNewStateMapping[oldRew0AState]);
921 }
922
923 if (goal.hasRelevantValues()) {
924 storm::storage::BitVector newRelevantValues(ecElimResult.matrix.getRowGroupCount(), false);
925 for (auto oldRelevantState : goal.relevantValues()) {
926 newRelevantValues.set(ecElimResult.oldToNewStateMapping[oldRelevantState]);
927 }
928 goal.relevantValues() = std::move(newRelevantValues);
929 }
930
931 MDPSparseModelCheckingHelperReturnType<SolutionType> result = computeReachabilityRewardsHelper(
932 env, std::move(goal), ecElimResult.matrix, ecElimResult.matrix.transpose(true),
933 [&](uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix, storm::storage::BitVector const& maybeStates) {
934 std::vector<ValueType> result;
935 std::vector<ValueType> oldChoiceRewards = rewardModel.getTotalRewardVector(transitionMatrix);
936 result.reserve(rowCount);
937 for (uint64_t newState : maybeStates) {
938 for (auto newChoice : newTransitionMatrix.getRowGroupIndices(newState)) {
939 uint64_t oldChoice = ecElimResult.newToOldRowMapping[newChoice];
940 result.push_back(oldChoiceRewards[oldChoice]);
941 }
942 }
943 STORM_LOG_ASSERT(result.size() == rowCount, "Unexpected size of reward vector.");
944 return result;
945 },
946 newRew0AStates, qualitative, false,
947 [&]() {
948 storm::storage::BitVector newStatesWithoutReward(ecElimResult.matrix.getRowGroupCount(), false);
949 for (uint64_t oldStateWithoutRew : statesWithoutReward) {
950 newStatesWithoutReward.set(ecElimResult.oldToNewStateMapping[oldStateWithoutRew]);
951 }
952 return newStatesWithoutReward;
953 },
954 [&]() {
955 storm::storage::BitVector newChoicesWithoutReward(ecElimResult.matrix.getRowGroupCount(), false);
956 for (uint64_t newChoice = 0; newChoice < ecElimResult.matrix.getRowCount(); ++newChoice) {
957 if (choicesWithoutReward.get(ecElimResult.newToOldRowMapping[newChoice])) {
958 newChoicesWithoutReward.set(newChoice);
959 }
960 }
961 return newChoicesWithoutReward;
962 });
963
964 std::vector<SolutionType> resultInEcQuotient = std::move(result.values);
965 result.values.resize(ecElimResult.oldToNewStateMapping.size());
966 storm::utility::vector::selectVectorValues(result.values, ecElimResult.oldToNewStateMapping, resultInEcQuotient);
967 return result;
968 }
969 }
970}
971
972template<typename ValueType, typename SolutionType>
973template<typename RewardModelType>
976 RewardModelType const& rewardModel, uint_fast64_t stepBound, ValueType discountFactor) {
977 // Only compute the result if the model has at least one reward this->getModel().
978 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
979
980 // Compute the reward vector to add in each step based on the available reward models.
981 std::vector<SolutionType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix);
982
983 // Initialize result to the zero vector.
984 std::vector<SolutionType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
985
986 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
987 multiplier->repeatedMultiplyAndReduceWithFactor(env, goal.direction(), result, &totalRewardVector, stepBound, discountFactor,
988 goal.getUncertaintyResolutionMode());
989
990 return result;
991}
992
993template<typename ValueType, typename SolutionType>
994template<typename RewardModelType>
997 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, bool qualitative, bool produceScheduler,
998 ValueType discountFactor, ModelCheckerHint const& hint) {
999 // If the solver is set to force exact results, throw an error
1000 STORM_LOG_THROW(!env.solver().isForceExact(), storm::exceptions::NotSupportedException,
1001 "Exact solving of discounted total reward objectives is currently not supported.");
1002
1003 std::vector<ValueType> b;
1004
1005 std::vector<SolutionType> x = std::vector<SolutionType>(transitionMatrix.getRowGroupCount(), storm::utility::zero<SolutionType>());
1006 b = rewardModel.getTotalRewardVector(transitionMatrix);
1007 storm::modelchecker::helper::DiscountingHelper<ValueType> discountingHelper(transitionMatrix, discountFactor, produceScheduler);
1008
1009 discountingHelper.solveWithDiscountedValueIteration(env, goal.direction(), x, b);
1010
1011 std::unique_ptr<storm::storage::Scheduler<SolutionType>> scheduler;
1012 if (produceScheduler) {
1013 scheduler = std::make_unique<storm::storage::Scheduler<ValueType>>(discountingHelper.computeScheduler());
1014 }
1015 STORM_LOG_ASSERT(!produceScheduler || scheduler, "Expected that a scheduler was obtained.");
1016 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || !scheduler->isPartialScheduler(), "Expected a fully defined scheduler.");
1017 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isDeterministicScheduler(), "Expected a deterministic scheduler.");
1018 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isMemorylessScheduler(), "Expected a memoryless scheduler.");
1019 return MDPSparseModelCheckingHelperReturnType<SolutionType>(std::move(x), std::move(scheduler));
1020}
1021
1022template<typename ValueType, typename SolutionType>
1023template<typename RewardModelType>
1026 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates,
1027 bool qualitative, bool produceScheduler, ModelCheckerHint const& hint) {
1028 // Only compute the result if the model has at least one reward this->getModel().
1029 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Reward model for formula is empty. Skipping formula.");
1030 return computeReachabilityRewardsHelper(
1031 env, std::move(goal), transitionMatrix, backwardTransitions,
1032 [&rewardModel](uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const& transMatrix, storm::storage::BitVector const& maybeStates) {
1033 return rewardModel.getTotalRewardVector(rowCount, transMatrix, maybeStates);
1034 },
1035 targetStates, qualitative, produceScheduler, [&]() { return rewardModel.getStatesWithZeroReward(transitionMatrix); },
1036 [&]() { return rewardModel.getChoicesWithZeroReward(transitionMatrix); }, hint);
1037}
1038
1039template<typename ValueType, typename SolutionType>
1042 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler,
1043 ModelCheckerHint const& hint) {
1044 return computeReachabilityRewardsHelper(
1045 env, std::move(goal), transitionMatrix, backwardTransitions,
1046 [](uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&) {
1047 return std::vector<ValueType>(rowCount, storm::utility::one<ValueType>());
1048 },
1049 targetStates, qualitative, produceScheduler, [&]() { return storm::storage::BitVector(transitionMatrix.getRowGroupCount(), false); },
1050 [&]() { return storm::storage::BitVector(transitionMatrix.getRowCount(), false); }, hint);
1051}
1052
1053template<typename ValueType, typename SolutionType>
1054template<typename IntervalRewardType>
1057 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
1058 storm::models::sparse::StandardRewardModel<IntervalRewardType> const& intervalRewardModel, bool lowerBoundOfIntervals,
1059 storm::storage::BitVector const& targetStates, bool qualitative) {
1060 // Only compute the result if the reward model is not empty.
1061 STORM_LOG_THROW(!intervalRewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
1062 if constexpr (!std::is_same_v<IntervalBaseType<ValueType>, IntervalBaseType<IntervalRewardType>>) {
1063 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support a valuetype and reward type having different base types.");
1064 } else {
1065 return computeReachabilityRewardsHelper(
1066 env, std::move(goal), transitionMatrix, backwardTransitions,
1067 [&](uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) {
1068 std::vector<ValueType> result;
1069 result.reserve(rowCount);
1070 std::vector<IntervalRewardType> subIntervalVector = intervalRewardModel.getTotalRewardVector(rowCount, transitionMatrix, maybeStates);
1071 for (auto const& interval : subIntervalVector) {
1072 result.push_back(lowerBoundOfIntervals ? interval.lower() : interval.upper());
1073 }
1074 return result;
1075 },
1076 targetStates, qualitative, false,
1077 [&]() {
1078 return intervalRewardModel.getStatesWithFilter(transitionMatrix, [&](IntervalRewardType const& i) {
1079 return storm::utility::isZero(lowerBoundOfIntervals ? i.lower() : i.upper());
1080 });
1081 },
1082 [&]() {
1083 return intervalRewardModel.getChoicesWithFilter(transitionMatrix, [&](IntervalRewardType const& i) {
1084 return storm::utility::isZero(lowerBoundOfIntervals ? i.lower() : i.upper());
1085 });
1086 })
1087 .values;
1088 }
1089}
1090
1096
1097template<typename ValueType>
1099 storm::storage::BitVector const& targetStates) {
1101 result.maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
1102
1103 // Treat the states with reward zero/infinity.
1104 std::vector<ValueType> const& resultsForNonMaybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getResultHint();
1107 storm::storage::BitVector nonMaybeStates = ~result.maybeStates;
1108 for (uint64_t state : nonMaybeStates) {
1109 if (storm::utility::isZero(resultsForNonMaybeStates[state])) {
1110 result.rewardZeroStates.set(state, true);
1111 } else {
1112 STORM_LOG_THROW(storm::utility::isInfinity(resultsForNonMaybeStates[state]), storm::exceptions::IllegalArgumentException,
1113 "Expected that the result hint specifies probabilities in {0,infinity} for non-maybe states.");
1114 result.infinityStates.set(state, true);
1115 }
1116 }
1117 return result;
1118}
1119
1120template<typename ValueType, typename SolutionType>
1123 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates,
1124 std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) {
1126 storm::storage::BitVector trueStates(transitionMatrix.getRowGroupCount(), true);
1127 if (goal.minimize()) {
1128 result.infinityStates =
1129 storm::utility::graph::performProb1E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, trueStates, targetStates);
1130 } else {
1131 result.infinityStates =
1132 storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, trueStates, targetStates);
1133 }
1134 result.infinityStates.complement();
1135
1137 if (goal.minimize()) {
1138 result.rewardZeroStates = storm::utility::graph::performProb1E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions,
1139 trueStates, targetStates, zeroRewardChoicesGetter());
1140 } else {
1141 result.rewardZeroStates = storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions,
1142 zeroRewardStatesGetter(), targetStates);
1143 }
1144 } else {
1145 result.rewardZeroStates = targetStates;
1146 }
1147 result.maybeStates = ~(result.rewardZeroStates | result.infinityStates);
1148 return result;
1149}
1150
1151template<typename ValueType, typename SolutionType>
1153 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
1154 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
1155 storm::storage::BitVector const& targetStates, ModelCheckerHint const& hint,
1156 std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter,
1157 std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) {
1158 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
1160 } else {
1161 return computeQualitativeStateSetsReachabilityRewards(goal, transitionMatrix, backwardTransitions, targetStates, zeroRewardStatesGetter,
1162 zeroRewardChoicesGetter);
1163 }
1164}
1165
1166template<typename ValueType, typename SolutionType>
1168 storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
1169 storm::storage::BitVector const& targetStates, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) {
1170 // Finally, if we need to produce a scheduler, we also need to figure out the parts of the scheduler for
1171 // the states with reward zero/infinity.
1172 if (minimize) {
1173 storm::utility::graph::computeSchedulerProb1E(qualitativeStateSets.rewardZeroStates, transitionMatrix, backwardTransitions,
1174 qualitativeStateSets.rewardZeroStates, targetStates, scheduler, zeroRewardChoicesGetter());
1175 for (uint64_t state : qualitativeStateSets.infinityStates) {
1176 scheduler.setChoice(0, state);
1177 }
1178 } else {
1179 storm::utility::graph::computeSchedulerRewInf(qualitativeStateSets.infinityStates, transitionMatrix, backwardTransitions, scheduler);
1180 for (uint64_t state : qualitativeStateSets.rewardZeroStates) {
1181 scheduler.setChoice(0, state);
1182 }
1183 }
1184}
1185
1186template<typename ValueType, typename SolutionType>
1188 std::vector<uint_fast64_t> const& subChoices, storm::storage::BitVector const& maybeStates,
1189 boost::optional<storm::storage::BitVector> const& selectedChoices) {
1190 auto subChoiceIt = subChoices.begin();
1191 if (selectedChoices) {
1192 for (uint64_t maybeState : maybeStates) {
1193 // find the rowindex that corresponds to the selected row of the submodel
1194 uint_fast64_t firstRowIndex = transitionMatrix.getRowGroupIndices()[maybeState];
1195 uint_fast64_t selectedRowIndex = selectedChoices->getNextSetIndex(firstRowIndex);
1196 for (uint_fast64_t choice = 0; choice < *subChoiceIt; ++choice) {
1197 selectedRowIndex = selectedChoices->getNextSetIndex(selectedRowIndex + 1);
1198 }
1199 scheduler.setChoice(selectedRowIndex - firstRowIndex, maybeState);
1200 ++subChoiceIt;
1201 }
1202 } else {
1203 for (uint64_t maybeState : maybeStates) {
1204 scheduler.setChoice(*subChoiceIt, maybeState);
1205 ++subChoiceIt;
1206 }
1207 }
1208 STORM_LOG_ASSERT(subChoiceIt == subChoices.end(), "Subchoice iterator not at end.");
1209}
1210
1211template<typename ValueType, typename SolutionType>
1214 QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, boost::optional<storm::storage::BitVector> const& selectedChoices,
1215 std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const&
1216 totalStateRewardVectorGetter,
1217 storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, std::vector<ValueType>* oneStepTargetProbabilities = nullptr) {
1218 // Remove rows and columns from the original transition probability matrix for states whose reward values are already known.
1219 // If there are infinity states, we additionally have to remove choices of maybeState that lead to infinity.
1220 if (qualitativeStateSets.infinityStates.empty()) {
1221 submatrix = transitionMatrix.getSubmatrix(true, qualitativeStateSets.maybeStates, qualitativeStateSets.maybeStates, false);
1222 b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, qualitativeStateSets.maybeStates);
1223 if (oneStepTargetProbabilities) {
1224 (*oneStepTargetProbabilities) =
1225 transitionMatrix.getConstrainedRowGroupSumVector(qualitativeStateSets.maybeStates, qualitativeStateSets.rewardZeroStates);
1226 }
1227 } else {
1228 submatrix = transitionMatrix.getSubmatrix(false, *selectedChoices, qualitativeStateSets.maybeStates, false);
1229 b = totalStateRewardVectorGetter(transitionMatrix.getRowCount(), transitionMatrix,
1230 storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true));
1232 if (oneStepTargetProbabilities) {
1233 (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowSumVector(*selectedChoices, qualitativeStateSets.rewardZeroStates);
1234 }
1235 }
1236
1237 // If the solve goal has relevant values, we need to adjust them.
1238 goal.restrictRelevantValues(qualitativeStateSets.maybeStates);
1239}
1240
1241template<typename ValueType, typename SolutionType>
1242boost::optional<SparseMdpEndComponentInformation<ValueType>> computeFixedPointSystemReachabilityRewardsEliminateEndComponents(
1244 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets,
1245 boost::optional<storm::storage::BitVector> const& selectedChoices,
1246 std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const&
1247 totalStateRewardVectorGetter,
1248 storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, boost::optional<std::vector<ValueType>>& oneStepTargetProbabilities,
1249 bool produceScheduler) {
1250 // Start by computing the choices with reward 0, as we only want ECs within this fragment.
1251 storm::storage::BitVector zeroRewardChoices(transitionMatrix.getRowCount());
1252
1253 // Get the rewards of all choices.
1254 std::vector<ValueType> rewardVector =
1255 totalStateRewardVectorGetter(transitionMatrix.getRowCount(), transitionMatrix, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true));
1256
1257 uint64_t index = 0;
1258 for (auto const& e : rewardVector) {
1259 if (storm::utility::isZero(e)) {
1260 zeroRewardChoices.set(index);
1261 }
1262 ++index;
1263 }
1264
1265 // Compute the states that have some zero reward choice.
1266 storm::storage::BitVector candidateStates(qualitativeStateSets.maybeStates);
1267 for (uint64_t state : qualitativeStateSets.maybeStates) {
1268 bool keepState = false;
1269
1270 for (auto row = transitionMatrix.getRowGroupIndices()[state], rowEnd = transitionMatrix.getRowGroupIndices()[state + 1]; row < rowEnd; ++row) {
1271 if (zeroRewardChoices.get(row)) {
1272 keepState = true;
1273 break;
1274 }
1275 }
1276
1277 if (!keepState) {
1278 candidateStates.set(state, false);
1279 }
1280 }
1281
1282 // Only keep the candidate states that (under some scheduler) can stay in the set of candidates forever
1283 candidateStates =
1284 storm::utility::graph::performProb0E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, candidateStates, ~candidateStates);
1285
1286 bool doDecomposition = !candidateStates.empty();
1287
1289 if (doDecomposition) {
1290 // Then compute the states that are in MECs with zero reward.
1291 endComponentDecomposition =
1292 storm::storage::MaximalEndComponentDecomposition<ValueType>(transitionMatrix, backwardTransitions, candidateStates, zeroRewardChoices);
1293 STORM_LOG_INFO(endComponentDecomposition.statistics(transitionMatrix.getRowGroupCount()));
1294 }
1295
1296 // Only do more work if there are actually end-components.
1297 if (doDecomposition && !endComponentDecomposition.empty()) {
1298 STORM_LOG_DEBUG("Eliminating " << endComponentDecomposition.size() << " ECs.");
1300 endComponentDecomposition, transitionMatrix, qualitativeStateSets.maybeStates,
1301 oneStepTargetProbabilities ? &qualitativeStateSets.rewardZeroStates : nullptr, selectedChoices ? &selectedChoices.get() : nullptr, &rewardVector,
1302 submatrix, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr, &b, produceScheduler);
1303
1304 // If the solve goal has relevant values, we need to adjust them.
1305 if (goal.hasRelevantValues()) {
1306 storm::storage::BitVector newRelevantValues(submatrix.getRowGroupCount());
1307 for (auto state : goal.relevantValues()) {
1308 if (qualitativeStateSets.maybeStates.get(state)) {
1309 newRelevantValues.set(result.getRowGroupAfterElimination(state));
1310 }
1311 }
1312 if (!newRelevantValues.empty()) {
1313 goal.setRelevantValues(std::move(newRelevantValues));
1314 }
1315 }
1316
1317 return result;
1318 } else {
1319 STORM_LOG_DEBUG("Not eliminating ECs as there are none.");
1320 computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b,
1321 oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr);
1322 return boost::none;
1323 }
1324}
1325
1326template<typename ValueType, typename SolutionType>
1328 storm::storage::SparseMatrix<ValueType> const& submatrix, std::vector<ValueType> const& choiceRewards,
1329 std::vector<ValueType> const& oneStepTargetProbabilities) {
1330 if constexpr (storm::IsIntervalType<ValueType>) {
1331 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing upper reward bounds with interval models.");
1332 } else {
1333 // For the min-case, we use DS-MPI, for the max-case variant 2 of the Baier et al. paper (CAV'17).
1334 if (direction == storm::OptimizationDirection::Minimize) {
1335 DsMpiMdpUpperRewardBoundsComputer<ValueType> dsmpi(submatrix, choiceRewards, oneStepTargetProbabilities);
1336 hintInformation.upperResultBounds = dsmpi.computeUpperBounds();
1337 } else {
1338 BaierUpperRewardBoundsComputer<ValueType> baier(submatrix, oneStepTargetProbabilities);
1339 hintInformation.upperResultBound = baier.computeTotalRewardBounds(choiceRewards).upper;
1340 }
1341 }
1342}
1343
1344template<typename ValueType, typename SolutionType>
1345MDPSparseModelCheckingHelperReturnType<SolutionType> SparseMdpPrctlHelper<ValueType, SolutionType>::computeReachabilityRewardsHelper(
1347 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
1348 std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const&
1349 totalStateRewardVectorGetter,
1350 storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler,
1351 std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter,
1352 ModelCheckerHint const& hint) {
1353 // Prepare resulting vector.
1354 std::vector<SolutionType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<SolutionType>());
1355
1356 // Determine which states have a reward that is infinity or less than infinity.
1357 QualitativeStateSetsReachabilityRewards qualitativeStateSets = getQualitativeStateSetsReachabilityRewards(
1358 goal, transitionMatrix, backwardTransitions, targetStates, hint, zeroRewardStatesGetter, zeroRewardChoicesGetter);
1359
1360 STORM_LOG_INFO("Preprocessing: " << qualitativeStateSets.infinityStates.getNumberOfSetBits() << " states with reward infinity, "
1361 << qualitativeStateSets.rewardZeroStates.getNumberOfSetBits() << " states with reward zero ("
1362 << qualitativeStateSets.maybeStates.getNumberOfSetBits() << " states remaining).");
1363
1364 storm::utility::vector::setVectorValues(result, qualitativeStateSets.infinityStates, storm::utility::infinity<SolutionType>());
1365
1366 // If requested, we will produce a scheduler.
1367 std::unique_ptr<storm::storage::Scheduler<SolutionType>> scheduler;
1368 if (produceScheduler) {
1369 if constexpr (storm::IsIntervalType<ValueType>) {
1370 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support producing schedulers in this function with interval models.");
1371 } else {
1372 scheduler = std::make_unique<storm::storage::Scheduler<SolutionType>>(transitionMatrix.getRowGroupCount());
1373 }
1374 }
1375
1376 // Check if the values of the maybe states are relevant for the SolveGoal
1377 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(qualitativeStateSets.maybeStates);
1378
1379 // Capture the goal direction before the goal is consumed by the solver configuration.
1380 bool const minimize = goal.minimize();
1381 // Check whether we need to compute exact rewards for some states.
1382 if (qualitative || maybeStatesNotRelevant) {
1383 STORM_LOG_INFO("The rewards for the initial states were determined in a preprocessing step. No exact rewards were computed.");
1384 // Set the values for all maybe-states to 1 to indicate that their reward values
1385 // are neither 0 nor infinity.
1387 } else {
1388 if (!qualitativeStateSets.maybeStates.empty()) {
1389 // In this case we have to compute the reward values for the remaining states.
1390
1391 // Store the choices that lead to non-infinity values. If none, all choices im maybe states can be selected.
1392 boost::optional<storm::storage::BitVector> selectedChoices;
1393 if (!qualitativeStateSets.infinityStates.empty()) {
1394 selectedChoices = transitionMatrix.getRowFilter(qualitativeStateSets.maybeStates, ~qualitativeStateSets.infinityStates);
1395 }
1396
1397 // Obtain proper hint information either from the provided hint or from requirements of the solver.
1398 SparseMdpHintType<SolutionType> hintInformation = computeHints<ValueType, SolutionType>(
1399 env, SemanticSolutionType::ExpectedRewards, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates,
1400 ~qualitativeStateSets.rewardZeroStates, qualitativeStateSets.rewardZeroStates, produceScheduler, selectedChoices);
1401
1402 // Declare the components of the equation system we will solve.
1403 storm::storage::SparseMatrix<ValueType> submatrix;
1404 std::vector<ValueType> b;
1405
1406 // If we need to compute upper bounds on the reward values, we need the one step probabilities
1407 // to a target state.
1408 boost::optional<std::vector<ValueType>> oneStepTargetProbabilities;
1409 if (hintInformation.getComputeUpperBounds()) {
1410 oneStepTargetProbabilities = std::vector<ValueType>();
1411 }
1412
1413 // If the hint information tells us that we have to eliminate MECs, we do so now.
1414 boost::optional<SparseMdpEndComponentInformation<ValueType>> ecInformation;
1415 if (hintInformation.getEliminateEndComponents()) {
1416 if constexpr (storm::IsIntervalType<ValueType>) {
1417 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support eliminating end components with interval models.");
1418 } else {
1420 goal, transitionMatrix, backwardTransitions, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b,
1421 oneStepTargetProbabilities, produceScheduler);
1422 }
1423 } else {
1424 // Otherwise, we compute the standard equations.
1425 computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter,
1426 submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr);
1427 }
1428
1429 // If we need to compute upper bounds, do so now.
1430 if (hintInformation.getComputeUpperBounds()) {
1431 STORM_LOG_ASSERT(oneStepTargetProbabilities, "Expecting one step target probability vector to be available.");
1432 computeUpperRewardBounds(hintInformation, goal.direction(), submatrix, b, oneStepTargetProbabilities.get());
1433 }
1434
1435 // Now compute the results for the maybe states.
1436 MaybeStateResult<SolutionType> resultForMaybeStates =
1437 computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, hintInformation);
1438
1439 // If we eliminated end components, we need to extract the result differently.
1440 if (ecInformation && ecInformation.get().getEliminatedEndComponents()) {
1441 if constexpr (storm::IsIntervalType<ValueType>) {
1442 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support eliminating end components with interval models.");
1443 } else {
1444 ecInformation.get().setValues(result, qualitativeStateSets.maybeStates, resultForMaybeStates.getValues());
1445 if (produceScheduler) {
1446 ecInformation.get().setScheduler(*scheduler, qualitativeStateSets.maybeStates, transitionMatrix, backwardTransitions,
1447 resultForMaybeStates.getScheduler());
1448 }
1449 }
1450 } else {
1451 // Set values of resulting vector according to result.
1452 storm::utility::vector::setVectorValues<SolutionType>(result, qualitativeStateSets.maybeStates, resultForMaybeStates.getValues());
1453 if (produceScheduler) {
1454 extractSchedulerChoices(*scheduler, transitionMatrix, resultForMaybeStates.getScheduler(), qualitativeStateSets.maybeStates,
1455 selectedChoices);
1456 }
1457 }
1458 }
1459 }
1460
1461 // Extend scheduler with choices for the states in the qualitative state sets.
1462 if (produceScheduler) {
1463 extendScheduler(*scheduler, minimize, qualitativeStateSets, transitionMatrix, backwardTransitions, targetStates, zeroRewardChoicesGetter);
1464 }
1465
1466 // Sanity check for created scheduler.
1467 STORM_LOG_ASSERT(!produceScheduler || scheduler, "Expected that a scheduler was obtained.");
1468 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || !scheduler->isPartialScheduler(), "Expected a fully defined scheduler.");
1469 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isDeterministicScheduler(), "Expected a deterministic scheduler.");
1470 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isMemorylessScheduler(), "Expected a memoryless scheduler.");
1471
1472 if constexpr (storm::IsIntervalType<ValueType>) {
1473 return MDPSparseModelCheckingHelperReturnType<SolutionType>(std::move(result));
1474 } else {
1475 return MDPSparseModelCheckingHelperReturnType<SolutionType>(std::move(result), std::move(scheduler));
1476 }
1477}
1478
1479template class SparseMdpPrctlHelper<double>;
1480template std::vector<double> SparseMdpPrctlHelper<double>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal,
1481 storm::storage::SparseMatrix<double> const& transitionMatrix,
1482 storm::models::sparse::StandardRewardModel<double> const& rewardModel,
1483 uint_fast64_t stepCount);
1484template std::vector<double> SparseMdpPrctlHelper<double>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal,
1485 storm::storage::SparseMatrix<double> const& transitionMatrix,
1486 storm::models::sparse::StandardRewardModel<double> const& rewardModel,
1487 uint_fast64_t stepBound);
1488template std::vector<double> SparseMdpPrctlHelper<double>::computeDiscountedCumulativeRewards(
1489 Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix,
1490 storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepBound, double discountFactor);
1491template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeReachabilityRewards(
1492 Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix,
1493 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel,
1494 storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint);
1495template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeTotalRewards(
1496 Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix,
1497 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, bool qualitative,
1498 bool produceScheduler, ModelCheckerHint const& hint);
1499template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeDiscountedTotalRewards(
1500 Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix,
1501 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, bool qualitative,
1502 bool produceScheduler, double discountFactor, ModelCheckerHint const& hint);
1503
1504template class SparseMdpPrctlHelper<storm::RationalNumber>;
1505template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeInstantaneousRewards(
1506 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1507 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepCount);
1508template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeCumulativeRewards(
1509 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1510 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepBound);
1511template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeDiscountedCumulativeRewards(
1512 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1513 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepBound, storm::RationalNumber discountFactor);
1514template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(
1515 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1516 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
1517 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative,
1518 bool produceScheduler, ModelCheckerHint const& hint);
1519template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeTotalRewards(
1520 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1521 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
1522 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, bool qualitative, bool produceScheduler,
1523 ModelCheckerHint const& hint);
1524template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeDiscountedTotalRewards(
1525 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1526 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
1527 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, bool qualitative, bool produceScheduler,
1528 storm::RationalNumber discountFactor, ModelCheckerHint const& hint);
1529
1530template class SparseMdpPrctlHelper<storm::Interval, double>;
1531template std::vector<double> SparseMdpPrctlHelper<storm::Interval, double>::computeInstantaneousRewards(
1532 Environment const& env, storm::solver::SolveGoal<storm::Interval, double>&& goal, storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
1533 storm::models::sparse::StandardRewardModel<storm::Interval> const& rewardModel, uint_fast64_t stepCount);
1534template std::vector<double> SparseMdpPrctlHelper<storm::Interval, double>::computeCumulativeRewards(
1535 Environment const& env, storm::solver::SolveGoal<storm::Interval, double>&& goal, storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
1536 storm::models::sparse::StandardRewardModel<storm::Interval> const& rewardModel, uint_fast64_t stepBound);
1537template std::vector<double> SparseMdpPrctlHelper<storm::Interval, double>::computeReachabilityRewards<storm::Interval>(
1538 Environment const& env, storm::solver::SolveGoal<storm::Interval, double>&& goal, storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
1539 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& rewardModel,
1540 bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative);
1541template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<storm::Interval, double>::computeTotalRewards(
1542 Environment const& env, storm::solver::SolveGoal<storm::Interval, double>&& goal, storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
1543 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& rewardModel,
1544 bool qualitative, bool produceScheduler, ModelCheckerHint const& hint);
1545
1546template class SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>;
1547template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>::computeInstantaneousRewards(
1548 Environment const& env, storm::solver::SolveGoal<storm::RationalInterval, storm::RationalNumber>&& goal,
1549 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix,
1550 storm::models::sparse::StandardRewardModel<storm::RationalInterval> const& rewardModel, uint_fast64_t stepCount);
1551template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>::computeCumulativeRewards(
1552 Environment const& env, storm::solver::SolveGoal<storm::RationalInterval, storm::RationalNumber>&& goal,
1553 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix,
1554 storm::models::sparse::StandardRewardModel<storm::RationalInterval> const& rewardModel, uint_fast64_t stepBound);
1555template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>::computeReachabilityRewards<
1556 storm::RationalInterval>(Environment const& env, storm::solver::SolveGoal<storm::RationalInterval, storm::RationalNumber>&& goal,
1557 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix,
1558 storm::storage::SparseMatrix<storm::RationalInterval> const& backwardTransitions,
1559 storm::models::sparse::StandardRewardModel<storm::RationalInterval> const& rewardModel, bool lowerBoundOfIntervals,
1560 storm::storage::BitVector const& targetStates, bool qualitative);
1561template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber>
1562SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>::computeTotalRewards(
1563 Environment const& env, storm::solver::SolveGoal<storm::RationalInterval, storm::RationalNumber>&& goal,
1564 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix,
1565 storm::storage::SparseMatrix<storm::RationalInterval> const& backwardTransitions,
1566 storm::models::sparse::StandardRewardModel<storm::RationalInterval> const& rewardModel, bool qualitative, bool produceScheduler,
1567 ModelCheckerHint const& hint);
1568
1569} // namespace helper
1570} // namespace modelchecker
1571} // namespace storm
SolverEnvironment & solver()
storm::RationalNumber const & getPrecision() const
void setPrecision(storm::RationalNumber value)
MinMaxSolverEnvironment & minMax()
This class contains information that might accelerate the model checking process.
ExplicitModelCheckerHint< ValueType > & asExplicitModelCheckerHint()
Bounds computeTotalRewardBounds(std::vector< ValueType > const &rewards)
Computes a lower and an upper bound on the expected total rewards.
storm::storage::Scheduler< ValueType > computeScheduler() const
Retrieves the generated scheduler.
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.
uint64_t getRowGroupAfterElimination(uint64_t state) const
Retrieves the row group of the state after end component elimination.
static SparseMdpEndComponentInformation< ValueType > eliminateEndComponents(storm::storage::MaximalEndComponentDecomposition< ValueType > const &endComponentDecomposition, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &maybeStates, storm::storage::BitVector const *sumColumns, storm::storage::BitVector const *selectedChoices, std::vector< ValueType > const *summand, storm::storage::SparseMatrix< ValueType > &submatrix, std::vector< ValueType > *columnSumVector, std::vector< ValueType > *summandResultVector, bool gatherExitChoices=false)
static MDPSparseModelCheckingHelperReturnType< 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, bool produceScheduler, ModelCheckerHint const &hint=ModelCheckerHint())
static MDPSparseModelCheckingHelperReturnType< 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, bool produceScheduler, ModelCheckerHint const &hint=ModelCheckerHint())
static MDPSparseModelCheckingHelperReturnType< 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, bool produceScheduler, bool useMecBasedTechnique=false)
static std::vector< SolutionType > computeNextProbabilities(Environment const &env, OptimizationDirection dir, UncertaintyResolutionMode uncertaintyResolutionMode, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &nextStates)
static std::map< storm::storage::sparse::state_type, SolutionType > computeRewardBoundedValues(Environment const &env, OptimizationDirection dir, rewardbounded::MultiDimensionalRewardUnfolding< ValueType, true > &rewardUnfolding, storm::storage::BitVector const &initialStates)
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 MDPSparseModelCheckingHelperReturnType< 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, bool produceScheduler, ModelCheckerHint const &hint=ModelCheckerHint())
static MDPSparseModelCheckingHelperReturnType< 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, bool produceScheduler, ValueType discountFactor, 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 > 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 MDPSparseModelCheckingHelperReturnType< 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, bool produceScheduler, ModelCheckerHint const &hint=ModelCheckerHint())
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...
bool empty() const
Retrieves whether the reward model is empty, i.e.
std::vector< ValueType > getTotalRewardVector(storm::storage::SparseMatrix< MatrixValueType > const &transitionMatrix) const
Creates a vector representing the complete reward vector based on the state-, state-action- and trans...
storm::storage::BitVector getChoicesWithFilter(storm::storage::SparseMatrix< MatrixValueType > const &transitionMatrix, std::function< bool(ValueType const &)> const &filter) const
Returns the set of choices for which all associated rewards (state, action or transition rewards) sat...
storm::storage::BitVector getStatesWithFilter(storm::storage::SparseMatrix< MatrixValueType > const &transitionMatrix, std::function< bool(ValueType const &)> const &filter) const
Returns the set of states for which all associated rewards (state, action or transition rewards) sati...
MinMaxLinearEquationSolverRequirements getRequirements(Environment const &env, bool hasUniqueSolution=false, bool hasNoEndComponents=false, boost::optional< storm::solver::OptimizationDirection > const &direction=boost::none, bool hasInitialScheduler=false, bool trackScheduler=false) const
Retrieves the requirements of the solver that would be created when calling create() right now.
std::string getEnabledRequirementsAsString() const
Returns a string that enumerates the enabled requirements.
std::unique_ptr< Multiplier< ValueType, SolutionType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix)
bool hasRelevantValues() const
void restrictRelevantValues(storm::storage::BitVector const &filter)
storm::storage::BitVector & relevantValues()
void setRelevantValues(storm::storage::BitVector &&values)
OptimizationDirection direction() const
Definition SolveGoal.cpp:89
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.
uint64_t getNextSetIndex(uint64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to true 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 ...
bool full() const
Retrieves whether all bits are set in this bit vector.
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.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
bool empty() const
Checks if the decomposition is empty.
std::size_t size() const
Retrieves the number of blocks of this decomposition.
This class represents the decomposition of a nondeterministic model into its maximal end components.
std::string statistics(uint64_t totalNumberOfStates) const
Returns a string containing statistics about the MEC decomposition, e.g., the number of (trivial/non-...
This class defines which action is chosen in a particular state of a non-deterministic model.
Definition Scheduler.h:18
SchedulerChoice< ValueType > const & getChoice(uint_fast64_t modelState, uint_fast64_t memoryState=0) const
Gets the choice defined by the scheduler for the given model and memory state.
Definition Scheduler.cpp:94
void setChoice(SchedulerChoice< ValueType > const &choice, uint_fast64_t modelState, uint_fast64_t memoryState=0)
Sets the choice defined by the scheduler for the given state.
Definition Scheduler.cpp:38
A class that holds a possibly non-square matrix in the compressed row storage format.
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...
SparseMatrix< ValueType > transposeSelectedRowsFromRowGroups(std::vector< uint64_t > const &rowGroupChoices, bool keepZeros=false) const
Transposes the matrix w.r.t.
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.
std::vector< index_type > const & getRowGroupIndices() const
Returns the grouping of rows of this matrix.
std::vector< value_type > getConstrainedRowGroupSumVector(storm::storage::BitVector const &rowGroupConstraint, storm::storage::BitVector const &columnConstraint) const
Computes a vector whose entries represent the sums of selected columns for all rows in selected row g...
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.
static EndComponentEliminatorReturnType transform(storm::storage::SparseMatrix< ValueType > const &originalMatrix, storm::storage::MaximalEndComponentDecomposition< ValueType > ecs, storm::storage::BitVector const &subsystemStates, storm::storage::BitVector const &addSinkRowStates, bool addSelfLoopAtSinkStates=false)
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_WARN(message)
Definition logging.h:28
#define STORM_LOG_DEBUG(message)
Definition logging.h:21
#define STORM_LOG_STATISTICS(message)
Definition logging.h:41
#define STORM_LOG_TRACE(message)
Definition logging.h:15
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_ERROR_COND(cond, message)
Definition macros.h:50
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
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
void extractSchedulerChoices(storm::storage::Scheduler< SolutionType > &scheduler, std::vector< uint64_t > const &subChoices, storm::storage::BitVector const &maybeStates)
boost::optional< SparseMdpEndComponentInformation< ValueType > > computeFixedPointSystemUntilProbabilitiesEliminateEndComponents(storm::solver::SolveGoal< ValueType, SolutionType > &goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, QualitativeStateSetsUntilProbabilities const &qualitativeStateSets, storm::storage::SparseMatrix< ValueType > &submatrix, std::vector< ValueType > &b, bool produceScheduler)
QualitativeStateSetsReachabilityRewards computeQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal< ValueType, SolutionType > const &goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &targetStates, std::function< storm::storage::BitVector()> const &zeroRewardStatesGetter, std::function< storm::storage::BitVector()> const &zeroRewardChoicesGetter)
QualitativeStateSetsUntilProbabilities computeQualitativeStateSetsUntilProbabilities(storm::solver::SolveGoal< ValueType, SolutionType > const &goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
void extractValueAndSchedulerHint(SparseMdpHintType< SolutionType > &hintStorage, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &maybeStates, boost::optional< storm::storage::BitVector > const &selectedChoices, ModelCheckerHint const &hint, bool skipECWithinMaybeStatesCheck)
void extendScheduler(storm::storage::Scheduler< SolutionType > &scheduler, bool minimize, QualitativeStateSetsUntilProbabilities const &qualitativeStateSets, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
std::vector< uint_fast64_t > computeValidSchedulerHint(Environment const &env, SemanticSolutionType const &type, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &maybeStates, storm::storage::BitVector const &filterStates, storm::storage::BitVector const &targetStates, boost::optional< storm::storage::BitVector > const &selectedChoices)
SparseMdpHintType< SolutionType > computeHints(Environment const &env, SemanticSolutionType const &type, ModelCheckerHint const &hint, storm::OptimizationDirection const &dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &maybeStates, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &targetStates, bool produceScheduler, boost::optional< storm::storage::BitVector > const &selectedChoices=boost::none)
QualitativeStateSetsUntilProbabilities getQualitativeStateSetsUntilProbabilitiesFromHint(ModelCheckerHint const &hint)
std::vector< ValueType > computeUpperRewardBounds(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< ValueType > const &rewards, std::vector< ValueType > const &oneStepTargetProbabilities)
QualitativeStateSetsReachabilityRewards getQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal< ValueType, SolutionType > const &goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &targetStates, ModelCheckerHint const &hint, std::function< storm::storage::BitVector()> const &zeroRewardStatesGetter, std::function< storm::storage::BitVector()> const &zeroRewardChoicesGetter)
void computeFixedPointSystemUntilProbabilities(storm::solver::SolveGoal< ValueType, SolutionType > &goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, QualitativeStateSetsUntilProbabilities const &qualitativeStateSets, storm::storage::SparseMatrix< ValueType > &submatrix, std::vector< ValueType > &b)
MaybeStateResult< SolutionType > computeValuesForMaybeStates(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > &&submatrix, std::vector< ValueType > const &b, bool produceScheduler, SparseMdpHintType< SolutionType > &hint)
QualitativeStateSetsReachabilityRewards getQualitativeStateSetsReachabilityRewardsFromHint(ModelCheckerHint const &hint, storm::storage::BitVector const &targetStates)
boost::optional< SparseMdpEndComponentInformation< ValueType > > computeFixedPointSystemReachabilityRewardsEliminateEndComponents(storm::solver::SolveGoal< ValueType, SolutionType > &goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, QualitativeStateSetsReachabilityRewards const &qualitativeStateSets, boost::optional< storm::storage::BitVector > const &selectedChoices, std::function< std::vector< ValueType >(uint_fast64_t, storm::storage::SparseMatrix< ValueType > const &, storm::storage::BitVector const &)> const &totalStateRewardVectorGetter, storm::storage::SparseMatrix< ValueType > &submatrix, std::vector< ValueType > &b, boost::optional< std::vector< ValueType > > &oneStepTargetProbabilities, bool produceScheduler)
QualitativeStateSetsUntilProbabilities getQualitativeStateSetsUntilProbabilities(storm::solver::SolveGoal< ValueType, SolutionType > const &goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, ModelCheckerHint const &hint)
void computeFixedPointSystemReachabilityRewards(storm::solver::SolveGoal< ValueType, SolutionType > &goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, QualitativeStateSetsReachabilityRewards const &qualitativeStateSets, boost::optional< storm::storage::BitVector > const &selectedChoices, std::function< std::vector< ValueType >(uint_fast64_t, storm::storage::SparseMatrix< ValueType > const &, storm::storage::BitVector const &)> const &totalStateRewardVectorGetter, storm::storage::SparseMatrix< ValueType > &submatrix, std::vector< ValueType > &b, std::vector< ValueType > *oneStepTargetProbabilities=nullptr)
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
bool constexpr minimize(OptimizationDirection d)
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01Max(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Definition graph.cpp:819
void computeSchedulerStayingInStates(storm::storage::BitVector const &states, storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::Scheduler< SchedulerValueType > &scheduler, boost::optional< storm::storage::BitVector > const &rowFilter)
Computes a scheduler for the given states that chooses an action that stays completely in the very sa...
Definition graph.cpp:483
void computeSchedulerProbGreater0E(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, storm::storage::Scheduler< SchedulerValueType > &scheduler, boost::optional< storm::storage::BitVector > const &rowFilter)
Computes a scheduler for the ProbGreater0E-States such that in the induced system the given psiStates...
Definition graph.cpp:535
storm::storage::BitVector performProbGreater0A(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps, boost::optional< storm::storage::BitVector > const &choiceConstraint)
Computes the sets of states that have probability greater 0 of satisfying phi until psi under any pos...
Definition graph.cpp:841
void computeSchedulerProb1E(storm::storage::BitVector const &prob1EStates, storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, storm::storage::Scheduler< SchedulerValueType > &scheduler, boost::optional< storm::storage::BitVector > const &rowFilter)
Computes a scheduler for the given prob1EStates such that in the induced system the given psiStates a...
Definition graph.cpp:608
storm::storage::BitVector performProb1A(storm::models::sparse::NondeterministicModel< T, RM > const &model, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 1 of satisfying phi until psi under all possible re...
Definition graph.cpp:981
storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps)
Computes the sets of states that have probability greater 0 of satisfying phi until psi under at leas...
Definition graph.cpp:673
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
storm::storage::BitVector performProb0E(storm::models::sparse::NondeterministicModel< T, RM > const &model, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 0 of satisfying phi until psi under at least one po...
Definition graph.cpp:960
void computeSchedulerProb0E(storm::storage::BitVector const &prob0EStates, storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::Scheduler< SchedulerValueType > &scheduler)
Computes a scheduler for the given states that have a scheduler that has a probability 0.
Definition graph.cpp:586
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01Min(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Definition graph.cpp:1063
storm::storage::BitVector performProb1E(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, boost::optional< storm::storage::BitVector > const &choiceConstraint)
Computes the sets of states that have probability 1 of satisfying phi until psi under at least one po...
Definition graph.cpp:741
void computeSchedulerRewInf(storm::storage::BitVector const &rewInfStates, storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::Scheduler< SchedulerValueType > &scheduler)
Computes a scheduler for the given states that have a scheduler that has a reward infinity.
Definition graph.cpp:592
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
void filterVectorInPlace(std::vector< Type > &v, storm::storage::BitVector const &filter)
Definition vector.h:1071
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
bool isInfinity(ValueType const &a)
TargetType convertNumber(SourceType const &number)
carl::Interval< storm::RationalNumber > RationalInterval
solver::UncertaintyResolutionMode UncertaintyResolutionMode
solver::OptimizationDirection OptimizationDirection
constexpr bool IsIntervalType
Helper to check if a type is an interval.
typename detail::IntervalMetaProgrammingHelper< ValueType >::BaseType IntervalBaseType
Helper to access the type in which interval boundaries are stored.
boost::optional< std::vector< uint64_t > > scheduler
MaybeStateResult(std::vector< ValueType > &&values)
std::vector< uint64_t > const & getScheduler() const
std::vector< ValueType > const & getValues() const
boost::optional< std::vector< uint64_t > > schedulerHint
boost::optional< std::vector< ValueType > > valueHint
std::vector< ValueType > const & getUpperResultBounds() const
boost::optional< std::vector< ValueType > > upperResultBounds