Storm 1.13.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"
33#include "storm/utility/graph.h"
36
37namespace storm {
38namespace modelchecker {
39namespace helper {
40
41template<typename ValueType, typename SolutionType>
42std::map<storm::storage::sparse::state_type, SolutionType> SparseMdpPrctlHelper<ValueType, SolutionType>::computeRewardBoundedValues(
44 storm::storage::BitVector const& initialStates) {
46 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing reward bounded values with interval models.");
47 } else {
48 storm::utility::Stopwatch swAll(true), swBuild, swCheck;
49
50 // Get lower and upper bounds for the solution.
51 auto lowerBound = rewardUnfolding.getLowerObjectiveBound();
52 auto upperBound = rewardUnfolding.getUpperObjectiveBound();
53
54 // Initialize epoch models
55 auto initEpoch = rewardUnfolding.getStartEpoch();
56 auto epochOrder = rewardUnfolding.getEpochComputationOrder(initEpoch);
57
58 // initialize data that will be needed for each epoch
59 std::vector<ValueType> x, b;
60 std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> minMaxSolver;
61
62 ValueType precision = rewardUnfolding.getRequiredEpochModelPrecision(
64 Environment preciseEnv = env;
66
67 // In case of cdf export we store the necessary data.
68 std::vector<std::vector<ValueType>> cdfData;
69
70 storm::utility::ProgressMeasurement progress("epochs");
71 progress.setMaxCount(epochOrder.size());
72 progress.startNewMeasurement(0);
73 uint64_t numCheckedEpochs = 0;
74 for (auto const& epoch : epochOrder) {
75 swBuild.start();
76 auto& epochModel = rewardUnfolding.setCurrentEpoch(epoch);
77 swBuild.stop();
78 swCheck.start();
79 rewardUnfolding.setSolutionForCurrentEpoch(epochModel.analyzeSingleObjective(preciseEnv, dir, x, b, minMaxSolver, lowerBound, upperBound));
80 swCheck.stop();
82 !rewardUnfolding.getEpochManager().hasBottomDimension(epoch)) {
83 std::vector<ValueType> cdfEntry;
84 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
85 uint64_t offset = rewardUnfolding.getDimension(i).boundType == helper::rewardbounded::DimensionBoundType::LowerBound ? 1 : 0;
86 cdfEntry.push_back(storm::utility::convertNumber<ValueType>(rewardUnfolding.getEpochManager().getDimensionOfEpoch(epoch, i) + offset) *
87 rewardUnfolding.getDimension(i).scalingFactor);
88 }
89 cdfEntry.push_back(rewardUnfolding.getInitialStateResult(epoch));
90 cdfData.push_back(std::move(cdfEntry));
91 }
92 ++numCheckedEpochs;
93 progress.updateProgress(numCheckedEpochs);
95 break;
96 }
97 }
98
99 std::map<storm::storage::sparse::state_type, ValueType> result;
100 for (auto initState : initialStates) {
101 result[initState] = rewardUnfolding.getInitialStateResult(initEpoch, initState);
102 }
103
104 swAll.stop();
105
107 std::vector<std::string> headers;
108 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
109 headers.push_back(rewardUnfolding.getDimension(i).formula->toString());
110 }
111 headers.push_back("Result");
113 storm::settings::getModule<storm::settings::modules::IOSettings>().getExportCdfDirectory() + "cdf.csv", cdfData, headers);
114 }
115
117 STORM_PRINT_AND_LOG("---------------------------------\n");
118 STORM_PRINT_AND_LOG("Statistics:\n");
119 STORM_PRINT_AND_LOG("---------------------------------\n");
120 STORM_PRINT_AND_LOG(" #checked epochs: " << epochOrder.size() << ".\n");
121 STORM_PRINT_AND_LOG(" overall Time: " << swAll << ".\n");
122 STORM_PRINT_AND_LOG("Epoch Model building Time: " << swBuild << ".\n");
123 STORM_PRINT_AND_LOG("Epoch Model checking Time: " << swCheck << ".\n");
124 STORM_PRINT_AND_LOG("---------------------------------\n");
125 }
126
127 return result;
128 }
129}
130
131template<typename ValueType, typename SolutionType>
133 Environment const& env, OptimizationDirection dir, UncertaintyResolutionMode uncertaintyResolutionMode,
134 storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) {
135 // Create the vector with which to multiply and initialize it correctly.
136 std::vector<SolutionType> result(transitionMatrix.getRowGroupCount());
138
139 auto multiplier = storm::solver::MultiplierFactory<ValueType, SolutionType>().create(env, transitionMatrix);
140 multiplier->multiplyAndReduce(env, dir, result, nullptr, result, uncertaintyResolutionMode);
141
142 return result;
143}
144
145template<typename ValueType, typename SolutionType = ValueType>
146std::vector<uint_fast64_t> computeValidSchedulerHint(Environment const& env, SemanticSolutionType const& type,
147 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
148 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
149 storm::storage::BitVector const& maybeStates, storm::storage::BitVector const& filterStates,
150 storm::storage::BitVector const& targetStates,
151 boost::optional<storm::storage::BitVector> const& selectedChoices) {
152 storm::storage::Scheduler<SolutionType> validScheduler(maybeStates.size());
153
155 storm::utility::graph::computeSchedulerProbGreater0E(transitionMatrix, backwardTransitions, filterStates, targetStates, validScheduler,
156 selectedChoices);
157 } else if (type == SemanticSolutionType::ExpectedRewards) {
158 storm::utility::graph::computeSchedulerProb1E(maybeStates | targetStates, transitionMatrix, backwardTransitions, filterStates, targetStates,
159 validScheduler, selectedChoices);
160 } else {
161 STORM_LOG_ASSERT(false, "Unexpected equation system type.");
162 }
163
164 // Extract the relevant parts of the scheduler for the solver.
165 std::vector<uint64_t> schedulerHint;
166 schedulerHint.reserve(maybeStates.getNumberOfSetBits());
167 if (selectedChoices) {
168 // There might be unselected choices so the local choice indices from the scheduler need to be adapted
169 for (auto maybeState : maybeStates) {
170 auto choice = validScheduler.getChoice(maybeState).getDeterministicChoice();
171 auto const groupStart = transitionMatrix.getRowGroupIndices()[maybeState];
172 auto const origGlobalChoiceIndex = groupStart + choice;
173 STORM_LOG_ASSERT(selectedChoices->get(origGlobalChoiceIndex), "The computed scheduler selects an illegal choice.");
174 // Count the number of unselected choices in [groupStart, origGlobalChoiceIndex) and subtract that from choice
175 for (auto pos = selectedChoices->getNextUnsetIndex(groupStart); pos < origGlobalChoiceIndex; pos = selectedChoices->getNextUnsetIndex(pos + 1)) {
176 --choice;
177 }
178 schedulerHint.push_back(choice);
179 }
180 } else {
181 for (auto maybeState : maybeStates) {
182 schedulerHint.push_back(validScheduler.getChoice(maybeState).getDeterministicChoice());
183 }
184 }
185 return schedulerHint;
186}
187
188template<typename ValueType>
191 // Intentionally left empty.
192 }
193
194 bool hasSchedulerHint() const {
195 return static_cast<bool>(schedulerHint);
196 }
197
198 bool hasValueHint() const {
199 return static_cast<bool>(valueHint);
200 }
201
202 bool hasLowerResultBound() const {
203 return static_cast<bool>(lowerResultBound);
204 }
205
206 ValueType const& getLowerResultBound() const {
207 return lowerResultBound.get();
208 }
209
210 bool hasUpperResultBound() const {
211 return static_cast<bool>(upperResultBound);
212 }
213
214 bool hasUpperResultBounds() const {
215 return static_cast<bool>(upperResultBounds);
216 }
217
218 ValueType const& getUpperResultBound() const {
219 return upperResultBound.get();
220 }
221
222 std::vector<ValueType>& getUpperResultBounds() {
223 return upperResultBounds.get();
224 }
225
226 std::vector<ValueType> const& getUpperResultBounds() const {
227 return upperResultBounds.get();
228 }
229
230 std::vector<uint64_t>& getSchedulerHint() {
231 return schedulerHint.get();
232 }
233
234 std::vector<ValueType>& getValueHint() {
235 return valueHint.get();
236 }
237
240 }
241
243 return computeUpperBounds;
244 }
245
246 bool hasUniqueSolution() const {
247 return uniqueSolution;
248 }
249
250 bool hasNoEndComponents() const {
251 return noEndComponents;
252 }
253
254 boost::optional<std::vector<uint64_t>> schedulerHint;
255 boost::optional<std::vector<ValueType>> valueHint;
256 boost::optional<ValueType> lowerResultBound;
257 boost::optional<ValueType> upperResultBound;
258 boost::optional<std::vector<ValueType>> upperResultBounds;
263};
264
265template<typename ValueType, typename SolutionType>
267 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& maybeStates,
268 boost::optional<storm::storage::BitVector> const& selectedChoices, ModelCheckerHint const& hint,
269 bool skipECWithinMaybeStatesCheck) {
270 // Deal with scheduler hint.
271 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasSchedulerHint()) {
272 if (hintStorage.hasSchedulerHint()) {
273 STORM_LOG_WARN("A scheduler hint was provided, but the solver requires a specific one. The provided scheduler hint will be ignored.");
274 } else {
275 auto const& schedulerHint = hint.template asExplicitModelCheckerHint<ValueType>().getSchedulerHint();
276 std::vector<uint64_t> hintChoices;
277
278 // The scheduler hint is only applicable if it induces no BSCC consisting of maybe states.
279 bool hintApplicable;
280 if (!skipECWithinMaybeStatesCheck) {
281 hintChoices.reserve(maybeStates.size());
282 for (uint_fast64_t state = 0; state < maybeStates.size(); ++state) {
283 hintChoices.push_back(schedulerHint.getChoice(state).getDeterministicChoice());
284 }
285 hintApplicable =
286 storm::utility::graph::performProb1(transitionMatrix.transposeSelectedRowsFromRowGroups(hintChoices), maybeStates, ~maybeStates).full();
287 } else {
288 hintApplicable = true;
289 }
290
291 if (hintApplicable) {
292 // Compute the hint w.r.t. the given subsystem.
293 hintChoices.clear();
294 hintChoices.reserve(maybeStates.getNumberOfSetBits());
295 for (auto state : maybeStates) {
296 uint_fast64_t hintChoice = schedulerHint.getChoice(state).getDeterministicChoice();
297 if (selectedChoices) {
298 uint_fast64_t firstChoice = transitionMatrix.getRowGroupIndices()[state];
299 uint_fast64_t lastChoice = firstChoice + hintChoice;
300 hintChoice = 0;
301 for (uint_fast64_t choice = selectedChoices->getNextSetIndex(firstChoice); choice < lastChoice;
302 choice = selectedChoices->getNextSetIndex(choice + 1)) {
303 ++hintChoice;
304 }
305 }
306 hintChoices.push_back(hintChoice);
307 }
308 hintStorage.schedulerHint = std::move(hintChoices);
309 }
310 }
311 }
312
313 // Deal with solution value hint. Only applicable if there are no End Components consisting of maybe states.
314 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasResultHint() &&
315 (skipECWithinMaybeStatesCheck || hintStorage.hasSchedulerHint() ||
316 storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, maybeStates, ~maybeStates)
317 .full())) {
318 hintStorage.valueHint = storm::utility::vector::filterVector(hint.template asExplicitModelCheckerHint<SolutionType>().getResultHint(), maybeStates);
319 }
320}
321
322template<typename ValueType, typename SolutionType>
325 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& maybeStates,
326 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& targetStates, bool produceScheduler,
327 boost::optional<storm::storage::BitVector> const& selectedChoices = boost::none) {
329
330 // There are no end components if we minimize until probabilities or
331 // maximize reachability rewards or if the hint tells us so.
332 result.noEndComponents = (dir == storm::solver::OptimizationDirection::Minimize && type == SemanticSolutionType::UntilProbabilities) ||
333 (dir == storm::solver::OptimizationDirection::Maximize && type == SemanticSolutionType::ExpectedRewards) ||
334 (hint.isExplicitModelCheckerHint() && hint.asExplicitModelCheckerHint<ValueType>().getNoEndComponentsInMaybeStates());
335
336 // If there are no end components, the solution is unique. (Note that the other direction does not hold,
337 // e.g., end components in which infinite reward is collected.
338 result.uniqueSolution = result.hasNoEndComponents();
339
340 // Check for requirements of the solver.
341 bool hasSchedulerHint = hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasSchedulerHint();
344 minMaxLinearEquationSolverFactory.getRequirements(env, result.uniqueSolution, result.noEndComponents, dir, hasSchedulerHint, produceScheduler);
345 if (requirements.hasEnabledRequirement()) {
346 // If the solver still requires no end-components, we have to eliminate them later.
347 if (requirements.uniqueSolution()) {
349 "The solver requires to eliminate the end components although the solution is already assumed to be unique.");
350 STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires a unique solution.");
351 result.eliminateEndComponents = true;
352 // If end components have been eliminated we can assume a unique solution.
353 result.uniqueSolution = true;
354 requirements.clearUniqueSolution();
355 // If we compute until probabilities, we can even assume the absence of end components.
356 // Note that in the case of minimizing expected rewards there might still be end components in which reward is collected.
358 }
359
360 // If the solver requires an initial scheduler, compute one now. Note that any scheduler is valid if there are no end components.
361 if (requirements.validInitialScheduler() && !result.noEndComponents) {
362 STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it.");
363 result.schedulerHint = computeValidSchedulerHint<ValueType, SolutionType>(env, type, transitionMatrix, backwardTransitions, maybeStates, phiStates,
364 targetStates, selectedChoices);
365 requirements.clearValidInitialScheduler();
366 }
367
368 // Finally, we have information on the bounds depending on the problem type.
370 requirements.clearBounds();
371 } else if (type == SemanticSolutionType::ExpectedRewards) {
372 requirements.clearLowerBounds();
373 }
374 if (requirements.upperBounds()) {
375 result.computeUpperBounds = true;
376 requirements.clearUpperBounds();
377 }
378 STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
379 "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked.");
380 } else {
381 STORM_LOG_DEBUG("Solver has no requirements.");
382 }
383
384 // Only if there is no end component decomposition that we will need to do later, we use value and scheduler
385 // hints from the provided hint.
386 if (!result.eliminateEndComponents) {
387 extractValueAndSchedulerHint(result, transitionMatrix, backwardTransitions, maybeStates, selectedChoices, hint, result.uniqueSolution);
388 } else {
389 if (hint.isEmpty()) {
390 STORM_LOG_TRACE("Warn A non-empty hint was provided, but its information will be disregarded.");
391 }
392 }
393
394 // Only set bounds if we did not obtain them from the hint.
395 if (!result.hasLowerResultBound()) {
397 }
400 }
401
402 // If we received an upper bound, we can drop the requirement to compute one.
403 if (result.hasUpperResultBound()) {
404 result.computeUpperBounds = false;
405 }
406
407 return result;
408}
409
410template<typename ValueType>
412 MaybeStateResult(std::vector<ValueType>&& values) : values(std::move(values)) {
413 // Intentionally left empty.
414 }
415
416 bool hasScheduler() const {
417 return static_cast<bool>(scheduler);
418 }
419
420 std::vector<uint64_t> const& getScheduler() const {
421 return scheduler.get();
422 }
423
424 std::vector<ValueType> const& getValues() const {
425 return values;
426 }
427
428 std::vector<ValueType> values;
429 boost::optional<std::vector<uint64_t>> scheduler;
430};
431
432template<typename ValueType, typename SolutionType>
434 storm::storage::SparseMatrix<ValueType>&& submatrix, std::vector<ValueType> const& b,
435 bool produceScheduler, SparseMdpHintType<SolutionType>& hint) {
436 // Initialize the solution vector.
437 std::vector<SolutionType> x =
438 hint.hasValueHint() ? std::move(hint.getValueHint())
439 : std::vector<SolutionType>(submatrix.getRowGroupCount(),
441
442 // Set up the solver.
444 std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType, SolutionType>> solver =
445 storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, std::move(submatrix));
446 solver->setRequirementsChecked();
447 solver->setUncertaintyResolutionMode(goal.getUncertaintyResolutionMode());
448 solver->setHasUniqueSolution(hint.hasUniqueSolution());
449 solver->setHasNoEndComponents(hint.hasNoEndComponents());
450 if (hint.hasLowerResultBound()) {
451 solver->setLowerBound(hint.getLowerResultBound());
452 }
453 if (hint.hasUpperResultBound()) {
454 solver->setUpperBound(hint.getUpperResultBound());
455 }
456 if (hint.hasUpperResultBounds()) {
457 solver->setUpperBounds(std::move(hint.getUpperResultBounds()));
458 }
459 if (hint.hasSchedulerHint()) {
460 solver->setInitialScheduler(std::move(hint.getSchedulerHint()));
461 }
462 solver->setTrackScheduler(produceScheduler);
463
464 // Solve the corresponding system of equations.
465 solver->solveEquations(env, x, b);
466
467#ifndef NDEBUG
468 // As a sanity check, make sure our local upper bounds were in fact correct.
470 uint64_t relevantState = solver->hasRelevantValues() ? solver->getRelevantValues().getNextSetIndex(0ull) : 0ull;
471 std::function<void()> getNextRelevantStateIndex;
472 if (solver->hasRelevantValues()) {
473 storm::storage::BitVector const& relevantValues = solver->getRelevantValues();
474 getNextRelevantStateIndex = [&relevantState, &relevantValues]() { relevantState = relevantValues.getNextSetIndex(++relevantState); };
475 } else {
476 getNextRelevantStateIndex = [&relevantState]() { ++relevantState; };
477 }
478 for (; relevantState < solver->getUpperBounds().size(); getNextRelevantStateIndex()) {
479 STORM_LOG_ASSERT(x.at(relevantState) <=
480 solver->getUpperBounds().at(relevantState) + storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()),
481 "Expecting result value for state " << relevantState << " to be <= " << solver->getUpperBounds().at(relevantState) << ", but got "
482 << x.at(relevantState) << ".");
483 }
484 }
485#endif
486
487 // Create result.
488 MaybeStateResult<SolutionType> result(std::move(x));
489
490 // If requested, return the requested scheduler.
491 if (produceScheduler) {
492 result.scheduler = std::move(solver->getSchedulerChoices());
493 }
494 return result;
495}
496
502
503template<typename ValueType>
506 result.maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
507
508 // Treat the states with probability zero/one.
509 std::vector<ValueType> const& resultsForNonMaybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getResultHint();
512 storm::storage::BitVector nonMaybeStates = ~result.maybeStates;
513 for (auto state : nonMaybeStates) {
514 if (storm::utility::isOne(resultsForNonMaybeStates[state])) {
515 result.statesWithProbability1.set(state, true);
516 } else {
517 STORM_LOG_THROW(storm::utility::isZero(resultsForNonMaybeStates[state]), storm::exceptions::IllegalArgumentException,
518 "Expected that the result hint specifies probabilities in {0,1} for non-maybe states");
519 result.statesWithProbability0.set(state, true);
520 }
521 }
522
523 return result;
524}
525
526template<typename ValueType, typename SolutionType>
528 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
529 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
530 storm::storage::BitVector const& phiStates,
531 storm::storage::BitVector const& psiStates) {
533
534 // Get all states that have probability 0 and 1 of satisfying the until-formula.
535 std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01;
536 if (goal.minimize()) {
537 statesWithProbability01 =
538 storm::utility::graph::performProb01Min(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, phiStates, psiStates);
539 } else {
540 statesWithProbability01 =
541 storm::utility::graph::performProb01Max(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, phiStates, psiStates);
542 }
543 result.statesWithProbability0 = std::move(statesWithProbability01.first);
544 result.statesWithProbability1 = std::move(statesWithProbability01.second);
546
547 return result;
548}
549
550template<typename ValueType, typename SolutionType>
552 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
553 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
554 storm::storage::BitVector const& phiStates,
555 storm::storage::BitVector const& psiStates, ModelCheckerHint const& hint) {
556 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
558 } else {
559 return computeQualitativeStateSetsUntilProbabilities(goal, transitionMatrix, backwardTransitions, phiStates, psiStates);
560 }
561}
562
563template<typename SolutionType, bool subChoicesCoverOnlyMaybeStates = true>
564void extractSchedulerChoices(storm::storage::Scheduler<SolutionType>& scheduler, std::vector<uint64_t> const& subChoices,
565 storm::storage::BitVector const& maybeStates) {
566 if constexpr (subChoicesCoverOnlyMaybeStates) {
567 auto subChoiceIt = subChoices.begin();
568 for (auto maybeState : maybeStates) {
569 scheduler.setChoice(*subChoiceIt, maybeState);
570 ++subChoiceIt;
571 }
572 assert(subChoiceIt == subChoices.end());
573 } else {
574 // See computeFixedPointSystemUntilProbabilities, where we create a different equation system.
575 // Consequentially, we run a slightly different code here for interval-based models.
576 STORM_LOG_ASSERT(maybeStates.size() == subChoices.size(), "Sizes do not coincide.");
577 for (auto maybeState : maybeStates) {
578 scheduler.setChoice(subChoices[maybeState], maybeState);
579 }
580 }
581}
582
583template<typename ValueType, typename SolutionType>
585 QualitativeStateSetsUntilProbabilities const& qualitativeStateSets, storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
586 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates,
587 storm::storage::BitVector const& psiStates) {
588 // Finally, if we need to produce a scheduler, we also need to figure out the parts of the scheduler for
589 // the states with probability 1 or 0 (depending on whether we maximize or minimize).
590 // We also need to define some arbitrary choice for the remaining states to obtain a fully defined scheduler.
591 if (goal.minimize()) {
592 storm::utility::graph::computeSchedulerProb0E(qualitativeStateSets.statesWithProbability0, transitionMatrix, scheduler);
593 for (auto prob1State : qualitativeStateSets.statesWithProbability1) {
594 scheduler.setChoice(0, prob1State);
595 }
596 } else {
597 storm::utility::graph::computeSchedulerProb1E(qualitativeStateSets.statesWithProbability1, transitionMatrix, backwardTransitions, phiStates, psiStates,
598 scheduler);
599 for (auto prob0State : qualitativeStateSets.statesWithProbability0) {
600 scheduler.setChoice(0, prob0State);
601 }
602 }
603}
604
605template<typename ValueType, typename SolutionType>
607 storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
608 QualitativeStateSetsUntilProbabilities const& qualitativeStateSets,
609 storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b) {
610 if constexpr (storm::IsIntervalType<ValueType>) {
611 // For non-interval based models, we can eliminate the rows and columns from the original transition probability matrix for states
612 // whose probabilities are already known... However, there is information in the transition to those states.
613 // Thus, we cannot eliminate them all.
614 // We can however drop all the outgoing transitions from these states.
615 // 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),
616 // TODO ctned: however, there is quite some bookkeeping involved in projecting the right vectors.
617 // TODO ctned: Instead is likely easier to just do a pass and make a unique sink and a unique target state.
618 // TODO ctned: If this is ever changed, extractSchedulerChoices must also be updated.
619 submatrix = transitionMatrix.filterEntries(transitionMatrix.getRowFilter(qualitativeStateSets.maybeStates));
620
621 // Prepare the right-hand side of the equation system. For entry i this corresponds to
622 // the accumulated probability of going from state i to some state that has probability 1.
623 storm::utility::vector::setAllValues(b, transitionMatrix.getRowFilter(qualitativeStateSets.statesWithProbability1));
624 } else {
625 // First, we can eliminate the rows and columns from the original transition probability matrix for states
626 // whose probabilities are already known.
627 submatrix = transitionMatrix.getSubmatrix(true, qualitativeStateSets.maybeStates, qualitativeStateSets.maybeStates, false);
628
629 // Prepare the right-hand side of the equation system. For entry i this corresponds to
630 // the accumulated probability of going from state i to some state that has probability 1.
631 b = transitionMatrix.getConstrainedRowGroupSumVector(qualitativeStateSets.maybeStates, qualitativeStateSets.statesWithProbability1);
632 }
633 // If the solve goal has relevant values, we need to adjust them.
634 goal.restrictRelevantValues(qualitativeStateSets.maybeStates);
635}
636
637template<typename ValueType, typename SolutionType>
638boost::optional<SparseMdpEndComponentInformation<ValueType>> computeFixedPointSystemUntilProbabilitiesEliminateEndComponents(
640 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, QualitativeStateSetsUntilProbabilities const& qualitativeStateSets,
641 storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, bool produceScheduler) {
642 // Get the set of states that (under some scheduler) can stay in the set of maybestates forever
644 transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, qualitativeStateSets.maybeStates, ~qualitativeStateSets.maybeStates);
645
646 bool doDecomposition = !candidateStates.empty();
647
649 if (doDecomposition) {
650 // Compute the states that are in MECs.
651 endComponentDecomposition = storm::storage::MaximalEndComponentDecomposition<ValueType>(transitionMatrix, backwardTransitions, candidateStates);
652 STORM_LOG_INFO(endComponentDecomposition.statistics(transitionMatrix.getRowGroupCount()));
653 }
654
655 // Only do more work if there are actually end-components.
656 if (doDecomposition && !endComponentDecomposition.empty()) {
657 STORM_LOG_DEBUG("Eliminating " << endComponentDecomposition.size() << " EC(s).");
659 endComponentDecomposition, transitionMatrix, qualitativeStateSets.maybeStates, &qualitativeStateSets.statesWithProbability1, nullptr, nullptr,
660 submatrix, &b, nullptr, produceScheduler);
661
662 // If the solve goal has relevant values, we need to adjust them.
663 if (goal.hasRelevantValues()) {
664 storm::storage::BitVector newRelevantValues(submatrix.getRowGroupCount());
665 for (auto state : goal.relevantValues()) {
666 if (qualitativeStateSets.maybeStates.get(state)) {
667 newRelevantValues.set(result.getRowGroupAfterElimination(state));
668 }
669 }
670 if (!newRelevantValues.empty()) {
671 goal.setRelevantValues(std::move(newRelevantValues));
672 }
673 }
674
675 return result;
676 } else {
677 STORM_LOG_DEBUG("Not eliminating ECs as there are none.");
678 computeFixedPointSystemUntilProbabilities(goal, transitionMatrix, qualitativeStateSets, submatrix, b);
679
680 return boost::none;
681 }
682}
683
684template<typename ValueType, typename SolutionType>
687 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
688 bool qualitative, bool produceScheduler, ModelCheckerHint const& hint) {
689 STORM_LOG_THROW(!qualitative || !produceScheduler, storm::exceptions::InvalidSettingsException,
690 "Cannot produce scheduler when performing qualitative model checking only.");
691
692 // Prepare resulting vector.
693 std::vector<SolutionType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<SolutionType>());
694
695 // We need to identify the maybe states (states which have a probability for satisfying the until formula
696 // that is strictly between 0 and 1) and the states that satisfy the formula with probablity 1 and 0, respectively.
697 QualitativeStateSetsUntilProbabilities qualitativeStateSets =
698 getQualitativeStateSetsUntilProbabilities(goal, transitionMatrix, backwardTransitions, phiStates, psiStates, hint);
699
700 STORM_LOG_INFO("Preprocessing: " << qualitativeStateSets.statesWithProbability1.getNumberOfSetBits() << " states with probability 1, "
701 << qualitativeStateSets.statesWithProbability0.getNumberOfSetBits() << " with probability 0 ("
702 << qualitativeStateSets.maybeStates.getNumberOfSetBits() << " states remaining).");
703
704 // Set values of resulting vector that are known exactly.
706
707 // Check if the values of the maybe states are relevant for the SolveGoal
708 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(qualitativeStateSets.maybeStates);
709
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 (auto 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, goal, 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 (auto 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 (auto 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 (auto 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 QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
1169 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates,
1170 std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) {
1171 // Finally, if we need to produce a scheduler, we also need to figure out the parts of the scheduler for
1172 // the states with reward zero/infinity.
1173 if (goal.minimize()) {
1174 storm::utility::graph::computeSchedulerProb1E(qualitativeStateSets.rewardZeroStates, transitionMatrix, backwardTransitions,
1175 qualitativeStateSets.rewardZeroStates, targetStates, scheduler, zeroRewardChoicesGetter());
1176 for (auto state : qualitativeStateSets.infinityStates) {
1177 scheduler.setChoice(0, state);
1178 }
1179 } else {
1180 storm::utility::graph::computeSchedulerRewInf(qualitativeStateSets.infinityStates, transitionMatrix, backwardTransitions, scheduler);
1181 for (auto state : qualitativeStateSets.rewardZeroStates) {
1182 scheduler.setChoice(0, state);
1183 }
1184 }
1185}
1186
1187template<typename ValueType, typename SolutionType>
1189 std::vector<uint_fast64_t> const& subChoices, storm::storage::BitVector const& maybeStates,
1190 boost::optional<storm::storage::BitVector> const& selectedChoices) {
1191 auto subChoiceIt = subChoices.begin();
1192 if (selectedChoices) {
1193 for (auto maybeState : maybeStates) {
1194 // find the rowindex that corresponds to the selected row of the submodel
1195 uint_fast64_t firstRowIndex = transitionMatrix.getRowGroupIndices()[maybeState];
1196 uint_fast64_t selectedRowIndex = selectedChoices->getNextSetIndex(firstRowIndex);
1197 for (uint_fast64_t choice = 0; choice < *subChoiceIt; ++choice) {
1198 selectedRowIndex = selectedChoices->getNextSetIndex(selectedRowIndex + 1);
1199 }
1200 scheduler.setChoice(selectedRowIndex - firstRowIndex, maybeState);
1201 ++subChoiceIt;
1202 }
1203 } else {
1204 for (auto maybeState : maybeStates) {
1205 scheduler.setChoice(*subChoiceIt, maybeState);
1206 ++subChoiceIt;
1207 }
1208 }
1209 assert(subChoiceIt == subChoices.end());
1210}
1211
1212template<typename ValueType, typename SolutionType>
1215 QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, boost::optional<storm::storage::BitVector> const& selectedChoices,
1216 std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const&
1217 totalStateRewardVectorGetter,
1218 storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, std::vector<ValueType>* oneStepTargetProbabilities = nullptr) {
1219 // Remove rows and columns from the original transition probability matrix for states whose reward values are already known.
1220 // If there are infinity states, we additionally have to remove choices of maybeState that lead to infinity.
1221 if (qualitativeStateSets.infinityStates.empty()) {
1222 submatrix = transitionMatrix.getSubmatrix(true, qualitativeStateSets.maybeStates, qualitativeStateSets.maybeStates, false);
1223 b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, qualitativeStateSets.maybeStates);
1224 if (oneStepTargetProbabilities) {
1225 (*oneStepTargetProbabilities) =
1226 transitionMatrix.getConstrainedRowGroupSumVector(qualitativeStateSets.maybeStates, qualitativeStateSets.rewardZeroStates);
1227 }
1228 } else {
1229 submatrix = transitionMatrix.getSubmatrix(false, *selectedChoices, qualitativeStateSets.maybeStates, false);
1230 b = totalStateRewardVectorGetter(transitionMatrix.getRowCount(), transitionMatrix,
1231 storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true));
1233 if (oneStepTargetProbabilities) {
1234 (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowSumVector(*selectedChoices, qualitativeStateSets.rewardZeroStates);
1235 }
1236 }
1237
1238 // If the solve goal has relevant values, we need to adjust them.
1239 goal.restrictRelevantValues(qualitativeStateSets.maybeStates);
1240}
1241
1242template<typename ValueType, typename SolutionType>
1243boost::optional<SparseMdpEndComponentInformation<ValueType>> computeFixedPointSystemReachabilityRewardsEliminateEndComponents(
1245 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets,
1246 boost::optional<storm::storage::BitVector> const& selectedChoices,
1247 std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const&
1248 totalStateRewardVectorGetter,
1249 storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, boost::optional<std::vector<ValueType>>& oneStepTargetProbabilities,
1250 bool produceScheduler) {
1251 // Start by computing the choices with reward 0, as we only want ECs within this fragment.
1252 storm::storage::BitVector zeroRewardChoices(transitionMatrix.getRowCount());
1253
1254 // Get the rewards of all choices.
1255 std::vector<ValueType> rewardVector =
1256 totalStateRewardVectorGetter(transitionMatrix.getRowCount(), transitionMatrix, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true));
1257
1258 uint64_t index = 0;
1259 for (auto const& e : rewardVector) {
1260 if (storm::utility::isZero(e)) {
1261 zeroRewardChoices.set(index);
1262 }
1263 ++index;
1264 }
1265
1266 // Compute the states that have some zero reward choice.
1267 storm::storage::BitVector candidateStates(qualitativeStateSets.maybeStates);
1268 for (auto state : qualitativeStateSets.maybeStates) {
1269 bool keepState = false;
1270
1271 for (auto row = transitionMatrix.getRowGroupIndices()[state], rowEnd = transitionMatrix.getRowGroupIndices()[state + 1]; row < rowEnd; ++row) {
1272 if (zeroRewardChoices.get(row)) {
1273 keepState = true;
1274 break;
1275 }
1276 }
1277
1278 if (!keepState) {
1279 candidateStates.set(state, false);
1280 }
1281 }
1282
1283 // Only keep the candidate states that (under some scheduler) can stay in the set of candidates forever
1284 candidateStates =
1285 storm::utility::graph::performProb0E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, candidateStates, ~candidateStates);
1286
1287 bool doDecomposition = !candidateStates.empty();
1288
1290 if (doDecomposition) {
1291 // Then compute the states that are in MECs with zero reward.
1292 endComponentDecomposition =
1293 storm::storage::MaximalEndComponentDecomposition<ValueType>(transitionMatrix, backwardTransitions, candidateStates, zeroRewardChoices);
1294 STORM_LOG_INFO(endComponentDecomposition.statistics(transitionMatrix.getRowGroupCount()));
1295 }
1296
1297 // Only do more work if there are actually end-components.
1298 if (doDecomposition && !endComponentDecomposition.empty()) {
1299 STORM_LOG_DEBUG("Eliminating " << endComponentDecomposition.size() << " ECs.");
1301 endComponentDecomposition, transitionMatrix, qualitativeStateSets.maybeStates,
1302 oneStepTargetProbabilities ? &qualitativeStateSets.rewardZeroStates : nullptr, selectedChoices ? &selectedChoices.get() : nullptr, &rewardVector,
1303 submatrix, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr, &b, produceScheduler);
1304
1305 // If the solve goal has relevant values, we need to adjust them.
1306 if (goal.hasRelevantValues()) {
1307 storm::storage::BitVector newRelevantValues(submatrix.getRowGroupCount());
1308 for (auto state : goal.relevantValues()) {
1309 if (qualitativeStateSets.maybeStates.get(state)) {
1310 newRelevantValues.set(result.getRowGroupAfterElimination(state));
1311 }
1312 }
1313 if (!newRelevantValues.empty()) {
1314 goal.setRelevantValues(std::move(newRelevantValues));
1315 }
1316 }
1317
1318 return result;
1319 } else {
1320 STORM_LOG_DEBUG("Not eliminating ECs as there are none.");
1321 computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b,
1322 oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr);
1323 return boost::none;
1324 }
1325}
1326
1327template<typename ValueType, typename SolutionType>
1329 storm::storage::SparseMatrix<ValueType> const& submatrix, std::vector<ValueType> const& choiceRewards,
1330 std::vector<ValueType> const& oneStepTargetProbabilities) {
1331 if constexpr (storm::IsIntervalType<ValueType>) {
1332 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support computing upper reward bounds with interval models.");
1333 } else {
1334 // For the min-case, we use DS-MPI, for the max-case variant 2 of the Baier et al. paper (CAV'17).
1335 if (direction == storm::OptimizationDirection::Minimize) {
1336 DsMpiMdpUpperRewardBoundsComputer<ValueType> dsmpi(submatrix, choiceRewards, oneStepTargetProbabilities);
1337 hintInformation.upperResultBounds = dsmpi.computeUpperBounds();
1338 } else {
1339 BaierUpperRewardBoundsComputer<ValueType> baier(submatrix, oneStepTargetProbabilities);
1340 hintInformation.upperResultBound = baier.computeTotalRewardBounds(choiceRewards).upper;
1341 }
1342 }
1343}
1344
1345template<typename ValueType, typename SolutionType>
1346MDPSparseModelCheckingHelperReturnType<SolutionType> SparseMdpPrctlHelper<ValueType, SolutionType>::computeReachabilityRewardsHelper(
1348 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
1349 std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const&
1350 totalStateRewardVectorGetter,
1351 storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler,
1352 std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter,
1353 ModelCheckerHint const& hint) {
1354 // Prepare resulting vector.
1355 std::vector<SolutionType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<SolutionType>());
1356
1357 // Determine which states have a reward that is infinity or less than infinity.
1358 QualitativeStateSetsReachabilityRewards qualitativeStateSets = getQualitativeStateSetsReachabilityRewards(
1359 goal, transitionMatrix, backwardTransitions, targetStates, hint, zeroRewardStatesGetter, zeroRewardChoicesGetter);
1360
1361 STORM_LOG_INFO("Preprocessing: " << qualitativeStateSets.infinityStates.getNumberOfSetBits() << " states with reward infinity, "
1362 << qualitativeStateSets.rewardZeroStates.getNumberOfSetBits() << " states with reward zero ("
1363 << qualitativeStateSets.maybeStates.getNumberOfSetBits() << " states remaining).");
1364
1365 storm::utility::vector::setVectorValues(result, qualitativeStateSets.infinityStates, storm::utility::infinity<SolutionType>());
1366
1367 // If requested, we will produce a scheduler.
1368 std::unique_ptr<storm::storage::Scheduler<SolutionType>> scheduler;
1369 if (produceScheduler) {
1370 if constexpr (storm::IsIntervalType<ValueType>) {
1371 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support producing schedulers in this function with interval models.");
1372 } else {
1373 scheduler = std::make_unique<storm::storage::Scheduler<SolutionType>>(transitionMatrix.getRowGroupCount());
1374 }
1375 }
1376
1377 // Check if the values of the maybe states are relevant for the SolveGoal
1378 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(qualitativeStateSets.maybeStates);
1379
1380 // Check whether we need to compute exact rewards for some states.
1381 if (qualitative || maybeStatesNotRelevant) {
1382 STORM_LOG_INFO("The rewards for the initial states were determined in a preprocessing step. No exact rewards were computed.");
1383 // Set the values for all maybe-states to 1 to indicate that their reward values
1384 // are neither 0 nor infinity.
1386 } else {
1387 if (!qualitativeStateSets.maybeStates.empty()) {
1388 // In this case we have to compute the reward values for the remaining states.
1389
1390 // Store the choices that lead to non-infinity values. If none, all choices im maybe states can be selected.
1391 boost::optional<storm::storage::BitVector> selectedChoices;
1392 if (!qualitativeStateSets.infinityStates.empty()) {
1393 selectedChoices = transitionMatrix.getRowFilter(qualitativeStateSets.maybeStates, ~qualitativeStateSets.infinityStates);
1394 }
1395
1396 // Obtain proper hint information either from the provided hint or from requirements of the solver.
1397 SparseMdpHintType<SolutionType> hintInformation = computeHints<ValueType, SolutionType>(
1398 env, SemanticSolutionType::ExpectedRewards, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates,
1399 ~qualitativeStateSets.rewardZeroStates, qualitativeStateSets.rewardZeroStates, produceScheduler, selectedChoices);
1400
1401 // Declare the components of the equation system we will solve.
1402 storm::storage::SparseMatrix<ValueType> submatrix;
1403 std::vector<ValueType> b;
1404
1405 // If we need to compute upper bounds on the reward values, we need the one step probabilities
1406 // to a target state.
1407 boost::optional<std::vector<ValueType>> oneStepTargetProbabilities;
1408 if (hintInformation.getComputeUpperBounds()) {
1409 oneStepTargetProbabilities = std::vector<ValueType>();
1410 }
1411
1412 // If the hint information tells us that we have to eliminate MECs, we do so now.
1413 boost::optional<SparseMdpEndComponentInformation<ValueType>> ecInformation;
1414 if (hintInformation.getEliminateEndComponents()) {
1415 if constexpr (storm::IsIntervalType<ValueType>) {
1416 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support eliminating end components with interval models.");
1417 } else {
1419 goal, transitionMatrix, backwardTransitions, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b,
1420 oneStepTargetProbabilities, produceScheduler);
1421 }
1422 } else {
1423 // Otherwise, we compute the standard equations.
1424 computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter,
1425 submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr);
1426 }
1427
1428 // If we need to compute upper bounds, do so now.
1429 if (hintInformation.getComputeUpperBounds()) {
1430 STORM_LOG_ASSERT(oneStepTargetProbabilities, "Expecting one step target probability vector to be available.");
1431 computeUpperRewardBounds(hintInformation, goal.direction(), submatrix, b, oneStepTargetProbabilities.get());
1432 }
1433
1434 // Now compute the results for the maybe states.
1435 MaybeStateResult<SolutionType> resultForMaybeStates =
1436 computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, hintInformation);
1437
1438 // If we eliminated end components, we need to extract the result differently.
1439 if (ecInformation && ecInformation.get().getEliminatedEndComponents()) {
1440 if constexpr (storm::IsIntervalType<ValueType>) {
1441 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We do not support eliminating end components with interval models.");
1442 } else {
1443 ecInformation.get().setValues(result, qualitativeStateSets.maybeStates, resultForMaybeStates.getValues());
1444 if (produceScheduler) {
1445 ecInformation.get().setScheduler(*scheduler, qualitativeStateSets.maybeStates, transitionMatrix, backwardTransitions,
1446 resultForMaybeStates.getScheduler());
1447 }
1448 }
1449 } else {
1450 // Set values of resulting vector according to result.
1451 storm::utility::vector::setVectorValues<SolutionType>(result, qualitativeStateSets.maybeStates, resultForMaybeStates.getValues());
1452 if (produceScheduler) {
1453 extractSchedulerChoices(*scheduler, transitionMatrix, resultForMaybeStates.getScheduler(), qualitativeStateSets.maybeStates,
1454 selectedChoices);
1455 }
1456 }
1457 }
1458 }
1459
1460 // Extend scheduler with choices for the states in the qualitative state sets.
1461 if (produceScheduler) {
1462 extendScheduler(*scheduler, goal, qualitativeStateSets, transitionMatrix, backwardTransitions, targetStates, zeroRewardChoicesGetter);
1463 }
1464
1465 // Sanity check for created scheduler.
1466 STORM_LOG_ASSERT(!produceScheduler || scheduler, "Expected that a scheduler was obtained.");
1467 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || !scheduler->isPartialScheduler(), "Expected a fully defined scheduler");
1468 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isDeterministicScheduler(), "Expected a deterministic scheduler");
1469 STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isMemorylessScheduler(), "Expected a memoryless scheduler");
1470
1471 if constexpr (storm::IsIntervalType<ValueType>) {
1472 return MDPSparseModelCheckingHelperReturnType<SolutionType>(std::move(result));
1473 } else {
1474 return MDPSparseModelCheckingHelperReturnType<SolutionType>(std::move(result), std::move(scheduler));
1475 }
1476}
1477
1478template class SparseMdpPrctlHelper<double>;
1479template std::vector<double> SparseMdpPrctlHelper<double>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal,
1480 storm::storage::SparseMatrix<double> const& transitionMatrix,
1481 storm::models::sparse::StandardRewardModel<double> const& rewardModel,
1482 uint_fast64_t stepCount);
1483template std::vector<double> SparseMdpPrctlHelper<double>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal,
1484 storm::storage::SparseMatrix<double> const& transitionMatrix,
1485 storm::models::sparse::StandardRewardModel<double> const& rewardModel,
1486 uint_fast64_t stepBound);
1487template std::vector<double> SparseMdpPrctlHelper<double>::computeDiscountedCumulativeRewards(
1488 Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix,
1489 storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepBound, double discountFactor);
1490template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeReachabilityRewards(
1491 Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix,
1492 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel,
1493 storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint);
1494template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeTotalRewards(
1495 Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix,
1496 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, bool qualitative,
1497 bool produceScheduler, ModelCheckerHint const& hint);
1498template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeDiscountedTotalRewards(
1499 Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix,
1500 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, bool qualitative,
1501 bool produceScheduler, double discountFactor, ModelCheckerHint const& hint);
1502
1503template class SparseMdpPrctlHelper<storm::RationalNumber>;
1504template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeInstantaneousRewards(
1505 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1506 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepCount);
1507template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeCumulativeRewards(
1508 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1509 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepBound);
1510template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeDiscountedCumulativeRewards(
1511 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1512 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepBound, storm::RationalNumber discountFactor);
1513template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(
1514 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1515 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
1516 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative,
1517 bool produceScheduler, ModelCheckerHint const& hint);
1518template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeTotalRewards(
1519 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1520 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
1521 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, bool qualitative, bool produceScheduler,
1522 ModelCheckerHint const& hint);
1523template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeDiscountedTotalRewards(
1524 Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
1525 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
1526 storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, bool qualitative, bool produceScheduler,
1527 storm::RationalNumber discountFactor, ModelCheckerHint const& hint);
1528
1529template class SparseMdpPrctlHelper<storm::Interval, double>;
1530template std::vector<double> SparseMdpPrctlHelper<storm::Interval, double>::computeInstantaneousRewards(
1531 Environment const& env, storm::solver::SolveGoal<storm::Interval, double>&& goal, storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
1532 storm::models::sparse::StandardRewardModel<storm::Interval> const& rewardModel, uint_fast64_t stepCount);
1533template std::vector<double> SparseMdpPrctlHelper<storm::Interval, double>::computeCumulativeRewards(
1534 Environment const& env, storm::solver::SolveGoal<storm::Interval, double>&& goal, storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
1535 storm::models::sparse::StandardRewardModel<storm::Interval> const& rewardModel, uint_fast64_t stepBound);
1536template std::vector<double> SparseMdpPrctlHelper<storm::Interval, double>::computeReachabilityRewards<storm::Interval>(
1537 Environment const& env, storm::solver::SolveGoal<storm::Interval, double>&& goal, storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
1538 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& rewardModel,
1539 bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative);
1540template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<storm::Interval, double>::computeTotalRewards(
1541 Environment const& env, storm::solver::SolveGoal<storm::Interval, double>&& goal, storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
1542 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& rewardModel,
1543 bool qualitative, bool produceScheduler, ModelCheckerHint const& hint);
1544
1545template class SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>;
1546template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>::computeInstantaneousRewards(
1547 Environment const& env, storm::solver::SolveGoal<storm::RationalInterval, storm::RationalNumber>&& goal,
1548 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix,
1549 storm::models::sparse::StandardRewardModel<storm::RationalInterval> const& rewardModel, uint_fast64_t stepCount);
1550template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>::computeCumulativeRewards(
1551 Environment const& env, storm::solver::SolveGoal<storm::RationalInterval, storm::RationalNumber>&& goal,
1552 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix,
1553 storm::models::sparse::StandardRewardModel<storm::RationalInterval> const& rewardModel, uint_fast64_t stepBound);
1554template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>::computeReachabilityRewards<
1555 storm::RationalInterval>(Environment const& env, storm::solver::SolveGoal<storm::RationalInterval, storm::RationalNumber>&& goal,
1556 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix,
1557 storm::storage::SparseMatrix<storm::RationalInterval> const& backwardTransitions,
1558 storm::models::sparse::StandardRewardModel<storm::RationalInterval> const& rewardModel, bool lowerBoundOfIntervals,
1559 storm::storage::BitVector const& targetStates, bool qualitative);
1560template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber>
1561SparseMdpPrctlHelper<storm::RationalInterval, storm::RationalNumber>::computeTotalRewards(
1562 Environment const& env, storm::solver::SolveGoal<storm::RationalInterval, storm::RationalNumber>&& goal,
1563 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix,
1564 storm::storage::SparseMatrix<storm::RationalInterval> const& backwardTransitions,
1565 storm::models::sparse::StandardRewardModel<storm::RationalInterval> const& rewardModel, bool qualitative, bool produceScheduler,
1566 ModelCheckerHint const& hint);
1567
1568} // namespace helper
1569} // namespace modelchecker
1570} // 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 prints it if the delay passed.
void setMaxCount(uint64_t maxCount)
Sets the maximal possible count.
void startNewMeasurement(uint64_t startCount)
Starts a new measurement, dropping all progress information collected so far.
A class that provides convenience operations to display run times.
Definition Stopwatch.h:14
void start()
Start stopwatch (again) and start measuring time.
Definition Stopwatch.cpp:48
void stop()
Stop stopwatch and add measured time to total time.
Definition Stopwatch.cpp:42
#define STORM_LOG_INFO(message)
Definition logging.h:24
#define STORM_LOG_WARN(message)
Definition logging.h:25
#define STORM_LOG_DEBUG(message)
Definition logging.h:18
#define STORM_LOG_TRACE(message)
Definition logging.h:12
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_ERROR_COND(cond, message)
Definition macros.h:52
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
#define STORM_PRINT_AND_LOG(message)
Definition macros.h:68
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)
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)
void extendScheduler(storm::storage::Scheduler< SolutionType > &scheduler, storm::solver::SolveGoal< ValueType, SolutionType > const &goal, 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)
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
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:34
bool isZero(ValueType const &a)
Definition constants.cpp:39
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