Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
HybridMdpPrctlHelper.cpp
Go to the documentation of this file.
2
4
10
12#include "storm/utility/graph.h"
14
16
23
26
28
31
32namespace storm {
33namespace modelchecker {
34namespace helper {
35
36template<typename ValueType>
38 boost::optional<SparseMdpEndComponentInformation<ValueType>> ecInformation;
39 boost::optional<std::vector<uint64_t>> initialScheduler;
41 boost::optional<std::vector<ValueType>> oneStepTargetProbabilities;
42};
43
48template<typename ValueType>
49void expandSolutionAfterEndComponentElimination(SolverRequirementsData<ValueType>& solverRequirementsData, std::vector<ValueType>& x) {
50 // The EC information refers to the state indices of the extended state space (properMaybeStates is a subset thereof).
51 std::vector<ValueType> extendedVector(solverRequirementsData.properMaybeStates.size());
52 solverRequirementsData.ecInformation.get().setValues(extendedVector, solverRequirementsData.properMaybeStates, x);
53 x = storm::utility::vector::filterVector(extendedVector, solverRequirementsData.properMaybeStates);
54}
55
56template<typename ValueType>
58 std::vector<ValueType> const& b) {
59 uint64_t numberOfMaybeStates = transitionMatrix.getRowGroupCount();
60 std::vector<uint64_t> result(numberOfMaybeStates);
61 storm::storage::BitVector targetStates(numberOfMaybeStates);
62
63 for (uint64_t state = 0; state < numberOfMaybeStates; ++state) {
64 // Record all states with non-zero probability of moving directly to the target states.
65 for (uint64_t row = transitionMatrix.getRowGroupIndices()[state]; row < transitionMatrix.getRowGroupIndices()[state + 1]; ++row) {
66 if (!storm::utility::isZero(b[row])) {
67 targetStates.set(state);
68 result[state] = row - transitionMatrix.getRowGroupIndices()[state];
69 }
70 }
71 }
72
73 if (!targetStates.full()) {
74 storm::storage::Scheduler<ValueType> validScheduler(numberOfMaybeStates);
75 storm::storage::SparseMatrix<ValueType> backwardTransitions = transitionMatrix.transpose(true);
76 storm::utility::graph::computeSchedulerProbGreater0E(transitionMatrix, backwardTransitions, storm::storage::BitVector(numberOfMaybeStates, true),
77 targetStates, validScheduler, boost::none);
78
79 for (uint64_t state = 0; state < numberOfMaybeStates; ++state) {
80 if (!targetStates.get(state)) {
81 result[state] = validScheduler.getChoice(state).getDeterministicChoice();
82 }
83 }
84 }
85
86 return result;
87}
88
89template<typename ValueType>
90void eliminateExtendedStatesFromExplicitRepresentation(std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>>& explicitRepresentation,
91 boost::optional<std::vector<uint64_t>>& scheduler, storm::storage::BitVector const& properMaybeStates) {
92 if (scheduler) {
93 // Eliminate superfluous entries from the scheduler.
94 uint64_t position = 0;
95 for (uint64_t state : properMaybeStates) {
96 scheduler.get()[position] = scheduler.get()[state];
97 position++;
98 }
99 scheduler.get().resize(properMaybeStates.getNumberOfSetBits());
100 scheduler.get().shrink_to_fit();
101 }
102
103 // Treat the matrix.
104 explicitRepresentation.first = explicitRepresentation.first.getSubmatrix(true, properMaybeStates, properMaybeStates);
105}
106
107template<typename ValueType>
109 std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>>& explicitRepresentation,
110 SolverRequirementsData<ValueType>& solverRequirementsData, storm::storage::BitVector const& targetStates) {
111 // Get easier handles to the data.
112 auto& transitionMatrix = explicitRepresentation.first;
113 auto& oneStepProbabilities = explicitRepresentation.second;
114
115 bool doDecomposition = !solverRequirementsData.properMaybeStates.empty();
116
118 if (doDecomposition) {
119 auto backwardTransitions = transitionMatrix.transpose(true);
120 // Get the set of states that (under some scheduler) can stay in the set of maybestates forever
121 storm::storage::BitVector candidateStates =
122 storm::utility::graph::performProb0E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions,
123 solverRequirementsData.properMaybeStates, ~solverRequirementsData.properMaybeStates);
124
125 doDecomposition = !candidateStates.empty();
126
127 if (doDecomposition) {
128 // If there are candidates, compute the states that are in MECs with zero reward.
129 endComponentDecomposition = storm::storage::MaximalEndComponentDecomposition<ValueType>(transitionMatrix, backwardTransitions, candidateStates);
130 }
131 }
132
133 // Only do more work if there are actually end-components.
134 if (doDecomposition && !endComponentDecomposition.empty()) {
135 STORM_LOG_DEBUG("Eliminating " << endComponentDecomposition.size() << " EC(s).");
136 std::vector<ValueType> subvector;
138 endComponentDecomposition, transitionMatrix, solverRequirementsData.properMaybeStates, &targetStates, nullptr, nullptr,
139 explicitRepresentation.first, &subvector, nullptr);
140 oneStepProbabilities = std::move(subvector);
141 } else {
142 STORM_LOG_DEBUG("Not eliminating ECs as there are none.");
143 oneStepProbabilities = explicitRepresentation.first.getConstrainedRowGroupSumVector(solverRequirementsData.properMaybeStates, targetStates);
144 eliminateExtendedStatesFromExplicitRepresentation(explicitRepresentation, solverRequirementsData.initialScheduler,
145 solverRequirementsData.properMaybeStates);
146 }
147}
148
149template<storm::dd::DdType DdType, typename ValueType>
152 storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates,
153 bool qualitative) {
154 // We need to identify the states which have to be taken out of the matrix, i.e. all states that have
155 // probability 0 and 1 of satisfying the until-formula.
156 storm::dd::Bdd<DdType> transitionMatrixBdd = transitionMatrix.notZero();
157 std::pair<storm::dd::Bdd<DdType>, storm::dd::Bdd<DdType>> statesWithProbability01;
158 if (dir == OptimizationDirection::Minimize) {
159 statesWithProbability01 = storm::utility::graph::performProb01Min(model, transitionMatrixBdd, phiStates, psiStates);
160 } else {
161 statesWithProbability01 = storm::utility::graph::performProb01Max(model, transitionMatrixBdd, phiStates, psiStates);
162 }
163 storm::dd::Bdd<DdType> maybeStates = !statesWithProbability01.first && !statesWithProbability01.second && model.getReachableStates();
164
165 STORM_LOG_INFO("Preprocessing: " << statesWithProbability01.first.getNonZeroCount() << " states with probability 1, "
166 << statesWithProbability01.second.getNonZeroCount() << " with probability 0 (" << maybeStates.getNonZeroCount()
167 << " states remaining).");
168
169 // Check whether we need to compute exact probabilities for some states.
170 if (qualitative) {
171 // Set the values for all maybe-states to 0.5 to indicate that their probability values are neither 0 nor 1.
173 model.getReachableStates(),
174 statesWithProbability01.second.template toAdd<ValueType>() +
175 maybeStates.template toAdd<ValueType>() * model.getManager().getConstant(storm::utility::convertNumber<ValueType>(0.5))));
176 } else {
177 // If there are maybe states, we need to solve an equation system.
178 if (!maybeStates.isZero()) {
179 // If we minimize, we know that the solution to the equation system has no end components
180 bool hasNoEndComponents = dir == storm::solver::OptimizationDirection::Minimize;
181 // Check for requirements of the solver early so we can adjust the maybe state computation accordingly.
184 linearEquationSolverFactory.getRequirements(env, hasNoEndComponents, hasNoEndComponents, dir);
185 storm::solver::MinMaxLinearEquationSolverRequirements clearedRequirements = requirements;
186 SolverRequirementsData<ValueType> solverRequirementsData;
187 bool extendMaybeStates = false;
188
189 if (clearedRequirements.hasEnabledRequirement()) {
190 if (clearedRequirements.uniqueSolution()) {
191 STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires a unique solution.");
192 extendMaybeStates = true;
193 clearedRequirements.clearUniqueSolution();
194 hasNoEndComponents = true;
195 }
196 if (clearedRequirements.validInitialScheduler() && !hasNoEndComponents) {
197 STORM_LOG_DEBUG("Scheduling valid scheduler computation, because the solver requires it.");
198 clearedRequirements.clearValidInitialScheduler();
199 }
200 clearedRequirements.clearBounds();
201 STORM_LOG_THROW(!clearedRequirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
202 "Solver requirements " + clearedRequirements.getEnabledRequirementsAsString() + " not checked.");
203 }
204
205 storm::dd::Bdd<DdType> extendedMaybeStates = maybeStates;
206 if (extendMaybeStates) {
207 // Extend the maybe states by all non-maybe states that can be reached from a maybe state within one step (they
208 // either are states with probability 0 or 1).
209 extendedMaybeStates |= maybeStates.relationalProduct(transitionMatrixBdd.existsAbstract(model.getNondeterminismVariables()),
210 model.getRowVariables(), model.getColumnVariables());
211 }
212
213 storm::utility::Stopwatch conversionWatch;
214
215 // Create the ODD for the translation between symbolic and explicit storage.
216 conversionWatch.start();
217 storm::dd::Odd odd = extendedMaybeStates.createOdd();
218 conversionWatch.stop();
219
220 // Convert the maybe states BDD to an ADD.
221 storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>();
222
223 // Start by cutting away all rows that do not belong to maybe states. Note that this leaves columns targeting
224 // non-maybe states in the matrix.
225 storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd;
226
227 // If the maybe states were extended, we generate the explicit representation slightly differently.
228 std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation;
229 if (extendMaybeStates) {
230 // Eliminate all transitions to non-extended-maybe states.
231 submatrix *= extendedMaybeStates.template toAdd<ValueType>().swapVariables(model.getRowColumnMetaVariablePairs());
232
233 // Only translate the matrix for now.
234 conversionWatch.start();
235 explicitRepresentation.first = submatrix.toMatrix(model.getNondeterminismVariables(), odd, odd);
236
237 // Get all original maybe states in the extended matrix.
238 solverRequirementsData.properMaybeStates = maybeStates.toVector(odd);
239
240 // Compute the target states within the set of extended maybe states.
241 storm::storage::BitVector targetStates = (extendedMaybeStates && statesWithProbability01.second).toVector(odd);
242 conversionWatch.stop();
243
244 // Eliminate the end components and remove the states that are not interesting (target or non-filter).
245 eliminateEndComponentsAndExtendedStatesUntilProbabilities(explicitRepresentation, solverRequirementsData, targetStates);
246
247 } else {
248 // Then compute the vector that contains the one-step probabilities to a state with probability 1 for all
249 // maybe states.
250 storm::dd::Add<DdType, ValueType> prob1StatesAsColumn = statesWithProbability01.second.template toAdd<ValueType>();
251 prob1StatesAsColumn = prob1StatesAsColumn.swapVariables(model.getRowColumnMetaVariablePairs());
252 storm::dd::Add<DdType, ValueType> subvector = submatrix * prob1StatesAsColumn;
253 subvector = subvector.sumAbstract(model.getColumnVariables());
254
255 // Finally cut away all columns targeting non-maybe states.
256 submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
257
258 // Translate the symbolic matrix/vector to their explicit representations and solve the equation system.
259 conversionWatch.start();
260 explicitRepresentation = submatrix.toMatrixVector(subvector, model.getNondeterminismVariables(), odd, odd);
261 conversionWatch.stop();
262
263 if (requirements.validInitialScheduler()) {
264 solverRequirementsData.initialScheduler =
265 computeValidInitialSchedulerForUntilProbabilities<ValueType>(explicitRepresentation.first, explicitRepresentation.second);
266 }
267 }
268
269 STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms.");
270
271 // Create the solution vector.
272 std::vector<ValueType> x(explicitRepresentation.first.getRowGroupCount(), storm::utility::zero<ValueType>());
273
274 std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver =
275 linearEquationSolverFactory.create(env, std::move(explicitRepresentation.first));
276
277 // Set whether the equation system will have a unique solution / no end components
278 solver->setHasUniqueSolution(hasNoEndComponents);
279 solver->setHasNoEndComponents(hasNoEndComponents);
280
281 if (solverRequirementsData.initialScheduler) {
282 solver->setInitialScheduler(std::move(solverRequirementsData.initialScheduler.get()));
283 }
285 solver->setRequirementsChecked();
286 solver->solveEquations(env, dir, x, explicitRepresentation.second);
287
288 // If we eliminated end components, we need to expand the result from the solver.
289 if (requirements.uniqueSolution() && solverRequirementsData.ecInformation) {
290 expandSolutionAfterEndComponentElimination(solverRequirementsData, x);
291 }
292
293 // If we extended the maybe states, we create a new ODD containing only the propery maybe states.
294 if (extendMaybeStates) {
295 odd = maybeStates.createOdd();
296 }
297
298 // Return a hybrid check result that stores the numerical values explicitly.
299 return std::unique_ptr<CheckResult>(new storm::modelchecker::HybridQuantitativeCheckResult<DdType, ValueType>(
300 model.getReachableStates(), model.getReachableStates() && !maybeStates, statesWithProbability01.second.template toAdd<ValueType>(), maybeStates,
301 odd, x));
302 } else {
304 model.getReachableStates(), statesWithProbability01.second.template toAdd<ValueType>()));
305 }
306 }
307}
308
309template<storm::dd::DdType DdType, typename ValueType>
312 storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) {
313 std::unique_ptr<CheckResult> result =
314 computeUntilProbabilities(env, dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Minimize, model,
315 transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative);
316 result->asQuantitativeCheckResult<ValueType>().oneMinus();
317 return result;
318}
319
320template<storm::dd::DdType DdType, typename ValueType>
326
327template<storm::dd::DdType DdType, typename ValueType>
330 storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates,
331 uint_fast64_t stepBound) {
332 // We need to identify the states which have to be taken out of the matrix, i.e. all states that have
333 // probability 0 or 1 of satisfying the until-formula.
334 storm::dd::Bdd<DdType> statesWithProbabilityGreater0;
335 if (dir == OptimizationDirection::Minimize) {
336 statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0A(model, transitionMatrix.notZero(), phiStates, psiStates);
337 } else {
338 statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0E(model, transitionMatrix.notZero(), phiStates, psiStates);
339 }
340 storm::dd::Bdd<DdType> maybeStates = statesWithProbabilityGreater0 && !psiStates && model.getReachableStates();
341
342 STORM_LOG_INFO("Preprocessing: " << statesWithProbabilityGreater0.getNonZeroCount() << " states with probability greater 0.");
343
344 // If there are maybe states, we need to perform matrix-vector multiplications.
345 if (!maybeStates.isZero()) {
346 storm::utility::Stopwatch conversionWatch;
347
348 // Create the ODD for the translation between symbolic and explicit storage.
349 conversionWatch.start();
350 storm::dd::Odd odd = maybeStates.createOdd();
351 conversionWatch.stop();
352
353 // Create the matrix and the vector for the equation system.
354 storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>();
355
356 // Start by cutting away all rows that do not belong to maybe states. Note that this leaves columns targeting
357 // non-maybe states in the matrix.
358 storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * maybeStatesAdd;
359
360 // Then compute the vector that contains the one-step probabilities to a state with probability 1 for all
361 // maybe states.
362 storm::dd::Add<DdType, ValueType> prob1StatesAsColumn = psiStates.template toAdd<ValueType>().swapVariables(model.getRowColumnMetaVariablePairs());
363 storm::dd::Add<DdType, ValueType> subvector = (submatrix * prob1StatesAsColumn).sumAbstract(model.getColumnVariables());
364
365 // Finally cut away all columns targeting non-maybe states.
366 submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
367
368 // Create the solution vector.
369 std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::zero<ValueType>());
370
371 // Translate the symbolic matrix/vector to their explicit representations.
372 conversionWatch.start();
373 std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation =
374 submatrix.toMatrixVector(subvector, model.getNondeterminismVariables(), odd, odd);
375 conversionWatch.stop();
376 STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms.");
377
378 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitRepresentation.first);
379 multiplier->repeatedMultiplyAndReduce(env, dir, x, &explicitRepresentation.second, stepBound);
380
381 // Return a hybrid check result that stores the numerical values explicitly.
382 return std::unique_ptr<CheckResult>(new storm::modelchecker::HybridQuantitativeCheckResult<DdType, ValueType>(
383 model.getReachableStates(), model.getReachableStates() && !maybeStates, psiStates.template toAdd<ValueType>(), maybeStates, odd, x));
384 } else {
385 return std::unique_ptr<CheckResult>(
386 new storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), psiStates.template toAdd<ValueType>()));
387 }
388}
389
390template<storm::dd::DdType DdType, typename ValueType>
393 storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) {
394 // Only compute the result if the model has at least one reward this->getModel().
395 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
396 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
397
398 storm::utility::Stopwatch conversionWatch;
399
400 // Create the ODD for the translation between symbolic and explicit storage.
402
403 // Translate the symbolic matrix to its explicit representations.
404 storm::storage::SparseMatrix<ValueType> explicitMatrix = transitionMatrix.toMatrix(model.getNondeterminismVariables(), odd, odd);
405
406 // Create the solution vector (and initialize it to the state rewards of the model).
407 std::vector<ValueType> x = rewardModel.getStateRewardVector().toVector(odd);
408 conversionWatch.stop();
409 STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms.");
410
411 // Perform the matrix-vector multiplication.
412 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix);
413 multiplier->repeatedMultiplyAndReduce(env, dir, x, nullptr, stepBound);
414
415 // Return a hybrid check result that stores the numerical values explicitly.
416 return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(
417 model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x));
418}
419
420template<storm::dd::DdType DdType, typename ValueType>
423 storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) {
424 // Only compute the result if the model has at least one reward this->getModel().
425 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
426
427 // Compute the reward vector to add in each step based on the available reward models.
428 storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables());
429
430 // Create the solution vector.
431 std::vector<ValueType> x(model.getNumberOfStates(), storm::utility::zero<ValueType>());
432
433 storm::utility::Stopwatch conversionWatch(true);
434
435 // Create the ODD for the translation between symbolic and explicit storage.
437
438 // Translate the symbolic matrix/vector to their explicit representations.
439 std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation =
440 transitionMatrix.toMatrixVector(totalRewardVector, model.getNondeterminismVariables(), odd, odd);
441 conversionWatch.stop();
442 STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms.");
443
444 // Perform the matrix-vector multiplication.
445 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitRepresentation.first);
446 multiplier->repeatedMultiplyAndReduce(env, dir, x, &explicitRepresentation.second, stepBound);
447
448 // Return a hybrid check result that stores the numerical values explicitly.
449 return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(
450 model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x));
451}
452
453template<typename ValueType>
455 storm::storage::BitVector targetStates(transitionMatrix.getRowGroupCount());
456
457 // A state is a target state iff its row group is empty.
458 for (uint64_t rowGroup = 0; rowGroup < transitionMatrix.getRowGroupCount(); ++rowGroup) {
459 if (transitionMatrix.getRowGroupIndices()[rowGroup] == transitionMatrix.getRowGroupIndices()[rowGroup + 1]) {
460 targetStates.set(rowGroup);
461 }
462 }
463
464 return targetStates;
465}
466
467template<typename ValueType>
469 storm::storage::BitVector const& properMaybeStates,
470 storm::storage::BitVector const& targetStates) {
471 uint64_t numberOfMaybeStates = transitionMatrix.getRowGroupCount();
472 std::vector<uint64_t> result(numberOfMaybeStates);
473
474 storm::storage::Scheduler<ValueType> validScheduler(numberOfMaybeStates);
475 storm::storage::SparseMatrix<ValueType> backwardTransitions = transitionMatrix.transpose(true);
476 storm::utility::graph::computeSchedulerProb1E(storm::storage::BitVector(numberOfMaybeStates, true), transitionMatrix, backwardTransitions,
477 properMaybeStates, targetStates, validScheduler);
478
479 for (uint64_t state = 0; state < numberOfMaybeStates; ++state) {
480 if (!targetStates.get(state)) {
481 result[state] = validScheduler.getChoice(state).getDeterministicChoice();
482 }
483 }
484
485 return result;
486}
487
488template<typename ValueType>
490 storm::storage::BitVector const& properMaybeStates,
491 storm::storage::BitVector const& targetStates) {
492 return extendedMatrix.getConstrainedRowGroupSumVector(properMaybeStates, targetStates);
493}
494
495template<typename ValueType>
497 std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>>& explicitRepresentation,
498 SolverRequirementsData<ValueType>& solverRequirementsData, storm::storage::BitVector const& targetStates, bool computeOneStepTargetProbabilities) {
499 // Get easier handles to the data.
500 auto& transitionMatrix = explicitRepresentation.first;
501 auto& rewardVector = explicitRepresentation.second;
502
503 // Start by computing the choices with reward 0, as we only want ECs within this fragment.
504 storm::storage::BitVector zeroRewardChoices(transitionMatrix.getRowCount());
505
506 uint64_t index = 0;
507 for (auto const& e : rewardVector) {
508 if (storm::utility::isZero(e)) {
509 zeroRewardChoices.set(index);
510 }
511 ++index;
512 }
513
514 // Compute the states that have some zero reward choice.
515 storm::storage::BitVector candidateStates(solverRequirementsData.properMaybeStates);
516 for (auto state : solverRequirementsData.properMaybeStates) {
517 bool keepState = false;
518
519 for (auto row = transitionMatrix.getRowGroupIndices()[state], rowEnd = transitionMatrix.getRowGroupIndices()[state + 1]; row < rowEnd; ++row) {
520 if (zeroRewardChoices.get(row)) {
521 keepState = true;
522 break;
523 }
524 }
525
526 if (!keepState) {
527 candidateStates.set(state, false);
528 }
529 }
530
531 bool doDecomposition = !candidateStates.empty();
532
534 if (doDecomposition) {
535 auto backwardTransitions = transitionMatrix.transpose(true);
536
537 // Only keep the candidate states that (under some scheduler) can stay in the set of candidates forever
538 candidateStates = storm::utility::graph::performProb0E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, candidateStates,
539 ~candidateStates);
540
541 doDecomposition = !candidateStates.empty();
542
543 if (doDecomposition) {
544 // If there are candidates, compute the states that are in MECs with zero reward.
545 endComponentDecomposition =
546 storm::storage::MaximalEndComponentDecomposition<ValueType>(transitionMatrix, backwardTransitions, candidateStates, zeroRewardChoices);
547 }
548 }
549
550 // Only do more work if there are actually end-components.
551 if (doDecomposition && !endComponentDecomposition.empty()) {
552 STORM_LOG_DEBUG("Eliminating " << endComponentDecomposition.size() << " EC(s).");
553 if (computeOneStepTargetProbabilities) {
554 solverRequirementsData.oneStepTargetProbabilities =
555 std::vector<ValueType>(solverRequirementsData.properMaybeStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
556 }
557
558 std::vector<ValueType> subvector(solverRequirementsData.properMaybeStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
560 endComponentDecomposition, transitionMatrix, solverRequirementsData.properMaybeStates, computeOneStepTargetProbabilities ? &targetStates : nullptr,
561 nullptr, &rewardVector, transitionMatrix, computeOneStepTargetProbabilities ? &solverRequirementsData.oneStepTargetProbabilities.get() : nullptr,
562 &subvector);
563 rewardVector = std::move(subvector);
564 } else {
565 STORM_LOG_DEBUG("Not eliminating ECs as there are none.");
566 if (computeOneStepTargetProbabilities) {
568 explicitRepresentation.first, solverRequirementsData.properMaybeStates, targetStates);
569 }
570 eliminateExtendedStatesFromExplicitRepresentation(explicitRepresentation, solverRequirementsData.initialScheduler,
571 solverRequirementsData.properMaybeStates);
572 }
573}
574
575template<typename ValueType>
577 storm::storage::SparseMatrix<ValueType> const& submatrix, std::vector<ValueType> const& choiceRewards,
578 std::vector<ValueType> const& oneStepTargetProbabilities) {
579 // For the min-case, we use DS-MPI, for the max-case variant 2 of the Baier et al. paper (CAV'17).
580 if (direction == storm::OptimizationDirection::Minimize) {
581 DsMpiMdpUpperRewardBoundsComputer<ValueType> dsmpi(submatrix, choiceRewards, oneStepTargetProbabilities);
582 solver.setUpperBounds(dsmpi.computeUpperBounds());
583 } else {
584 BaierUpperRewardBoundsComputer<ValueType> baier(submatrix, oneStepTargetProbabilities);
585 solver.setUpperBound(baier.computeTotalRewardBounds(choiceRewards).upper);
586 }
587}
588
589template<storm::dd::DdType DdType, typename ValueType>
592 storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates,
593 bool qualitative) {
594 // Only compute the result if there is at least one reward model.
595 STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
596
597 // Determine which states have a reward of infinity by definition.
598 storm::dd::Bdd<DdType> infinityStates;
599 storm::dd::Bdd<DdType> transitionMatrixBdd = transitionMatrix.notZero();
600 if (dir == OptimizationDirection::Minimize) {
602 model, transitionMatrixBdd, model.getReachableStates(), targetStates,
603 storm::utility::graph::performProbGreater0E(model, transitionMatrixBdd, model.getReachableStates(), targetStates));
604 } else {
606 model, transitionMatrixBdd, targetStates,
607 storm::utility::graph::performProbGreater0A(model, transitionMatrixBdd, model.getReachableStates(), targetStates));
608 }
609 infinityStates = !infinityStates && model.getReachableStates();
610 storm::dd::Bdd<DdType> maybeStatesWithTargetStates = !infinityStates && model.getReachableStates();
611 storm::dd::Bdd<DdType> maybeStates = !targetStates && maybeStatesWithTargetStates;
612
613 STORM_LOG_INFO("Preprocessing: " << infinityStates.getNonZeroCount() << " states with reward infinity, " << targetStates.getNonZeroCount()
614 << " target states (" << maybeStates.getNonZeroCount() << " states remaining).");
615
616 // Check whether we need to compute exact rewards for some states.
617 if (qualitative) {
618 // Set the values for all maybe-states to 1 to indicate that their reward values
619 // are neither 0 nor infinity.
620 return std::unique_ptr<CheckResult>(new SymbolicQuantitativeCheckResult<DdType, ValueType>(
621 model.getReachableStates(),
622 infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), model.getManager().template getAddZero<ValueType>()) +
623 maybeStates.template toAdd<ValueType>() * model.getManager().getConstant(storm::utility::one<ValueType>())));
624 } else {
625 // If there are maybe states, we need to solve an equation system.
626 if (!maybeStates.isZero()) {
627 // If we maximize, we know that the solution to the equation system is unique.
628 bool hasNoEndComponents = dir == storm::solver::OptimizationDirection::Maximize;
629 bool hasUniqueSolution = hasNoEndComponents;
630 // Check for requirements of the solver this early so we can adapt the maybe states accordingly.
633 linearEquationSolverFactory.getRequirements(env, hasUniqueSolution, hasNoEndComponents, dir);
634 storm::solver::MinMaxLinearEquationSolverRequirements clearedRequirements = requirements;
635 bool extendMaybeStates = false;
636 if (clearedRequirements.hasEnabledRequirement()) {
637 if (clearedRequirements.uniqueSolution()) {
638 STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires it.");
639 extendMaybeStates = true;
640 clearedRequirements.clearUniqueSolution();
641 hasUniqueSolution = true;
642 // There might still be end components in which reward is collected.
643 }
644 if (clearedRequirements.validInitialScheduler()) {
645 STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it.");
646 extendMaybeStates = true;
647 clearedRequirements.clearValidInitialScheduler();
648 }
649 clearedRequirements.clearLowerBounds();
650 if (clearedRequirements.upperBounds()) {
651 STORM_LOG_DEBUG("Computing upper bounds, because the solver requires it.");
652 extendMaybeStates = true;
653 clearedRequirements.clearUpperBounds();
654 }
655 STORM_LOG_THROW(!clearedRequirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
656 "Solver requirements " + clearedRequirements.getEnabledRequirementsAsString() + " not checked.");
657 }
658
659 // Compute the set of maybe states that we are required to keep in the translation to explicit.
660 storm::dd::Bdd<DdType> requiredMaybeStates = extendMaybeStates ? maybeStatesWithTargetStates : maybeStates;
661
662 storm::utility::Stopwatch conversionWatch;
663
664 // Create the ODD for the translation between symbolic and explicit storage.
665 conversionWatch.start();
666 storm::dd::Odd odd = requiredMaybeStates.createOdd();
667 conversionWatch.stop();
668
669 // Create the matrix and the vector for the equation system.
670 storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>();
671
672 // Start by getting rid of
673 // (a) transitions from non-maybe states, and
674 // (b) the choices in the transition matrix that lead to a state that is neither a maybe state
675 // nor a target state ('infinity choices').
676 storm::dd::Add<DdType, ValueType> choiceFilterAdd =
677 maybeStatesAdd * (transitionMatrixBdd && maybeStatesWithTargetStates.renameVariables(model.getRowVariables(), model.getColumnVariables()))
678 .existsAbstract(model.getColumnVariables())
679 .template toAdd<ValueType>();
680 storm::dd::Add<DdType, ValueType> submatrix = transitionMatrix * choiceFilterAdd;
681
682 // Then compute the reward vector to use in the computation.
684 rewardModel.getTotalRewardVector(maybeStatesAdd, choiceFilterAdd, submatrix, model.getColumnVariables());
685
686 conversionWatch.start();
687 std::vector<uint_fast64_t> rowGroupSizes = (submatrix.notZero().existsAbstract(model.getColumnVariables()) || subvector.notZero())
688 .template toAdd<uint_fast64_t>()
689 .sumAbstract(model.getNondeterminismVariables())
690 .toVector(odd);
691 conversionWatch.stop();
692
693 // Finally cut away all columns targeting non-maybe states (or non-(maybe or target) states, respectively).
694 submatrix *= extendMaybeStates ? maybeStatesWithTargetStates.swapVariables(model.getRowColumnMetaVariablePairs()).template toAdd<ValueType>()
695 : maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
696
697 // Translate the symbolic matrix/vector to their explicit representations.
698 conversionWatch.start();
699 std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(
700 std::move(rowGroupSizes), subvector, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), odd, odd);
701 conversionWatch.stop();
702 STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms.");
703
704 // Fulfill the solver's requirements.
705 SolverRequirementsData<ValueType> solverRequirementsData;
706 if (extendMaybeStates) {
708 solverRequirementsData.properMaybeStates = ~targetStates;
709
710 if (requirements.uniqueSolution()) {
711 STORM_LOG_THROW(!requirements.validInitialScheduler(), storm::exceptions::UncheckedRequirementException,
712 "The underlying solver requires a unique solution and an initial valid scheduler. This is currently not supported for "
713 "expected reward properties.");
714 // eliminate the end components with reward 0.
715 // Note that this may also compute the oneStepTargetProbabilities if upper bounds are required.
716 eliminateEndComponentsAndTargetStatesReachabilityRewards(explicitRepresentation, solverRequirementsData, targetStates,
717 requirements.upperBounds());
718 // The solution becomes unique after end components have been eliminated.
719 hasUniqueSolution = true;
720 } else {
721 if (requirements.validInitialScheduler()) {
722 // Compute a valid initial scheduler.
724 explicitRepresentation.first, solverRequirementsData.properMaybeStates, targetStates);
725 }
726
727 if (requirements.upperBounds()) {
729 explicitRepresentation.first, solverRequirementsData.properMaybeStates, targetStates);
730 }
731
732 // Since we needed the transitions to target states to be translated as well for the computation
733 // of the scheduler, we have to get rid of them now.
734 eliminateExtendedStatesFromExplicitRepresentation(explicitRepresentation, solverRequirementsData.initialScheduler,
735 solverRequirementsData.properMaybeStates);
736 }
737 }
738
739 // Create the solution vector.
740 std::vector<ValueType> x(explicitRepresentation.first.getRowGroupCount(), storm::utility::zero<ValueType>());
741
742 // Now solve the resulting equation system.
743 std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env);
744
745 // Set whether the equation system will have a unique solution / no end components
746 solver->setHasUniqueSolution(hasUniqueSolution);
747 solver->setHasNoEndComponents(hasNoEndComponents);
748
749 // If the solver requires upper bounds, compute them now.
750 if (requirements.upperBounds()) {
751 setUpperRewardBounds(*solver, dir, explicitRepresentation.first, explicitRepresentation.second,
752 solverRequirementsData.oneStepTargetProbabilities.get());
753 }
754
755 solver->setMatrix(std::move(explicitRepresentation.first));
756
757 // Move the scheduler to the solver.
758 if (solverRequirementsData.initialScheduler) {
759 solver->setInitialScheduler(std::move(solverRequirementsData.initialScheduler.get()));
760 }
761
762 solver->setLowerBound(storm::utility::zero<ValueType>());
763 solver->setRequirementsChecked();
764 solver->solveEquations(env, dir, x, explicitRepresentation.second);
765
766 // If we eliminated end components, we need to extend the solution vector.
767 if (requirements.uniqueSolution() && solverRequirementsData.ecInformation) {
768 expandSolutionAfterEndComponentElimination(solverRequirementsData, x);
769 }
770
771 // If we extended the maybe states, we create a new ODD that only contains proper maybe states.
772 if (extendMaybeStates) {
773 odd = maybeStates.createOdd();
774 }
775
776 // Return a hybrid check result that stores the numerical values explicitly.
777 return std::unique_ptr<CheckResult>(new storm::modelchecker::HybridQuantitativeCheckResult<DdType, ValueType>(
778 model.getReachableStates(), model.getReachableStates() && !maybeStates,
779 infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), model.getManager().template getAddZero<ValueType>()),
780 maybeStates, odd, x));
781 } else {
783 model.getReachableStates(), infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()),
784 model.getManager().template getAddZero<ValueType>())));
785 }
786 }
787}
788
789template<storm::dd::DdType DdType, typename ValueType>
792 storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates, bool qualitative) {
793 RewardModelType rewardModel(model.getManager().getConstant(storm::utility::one<ValueType>()), boost::none, boost::none);
794 return computeReachabilityRewards(env, dir, model, transitionMatrix, rewardModel, targetStates, qualitative);
795}
796
799
801
802} // namespace helper
803} // namespace modelchecker
804} // namespace storm
Add< LibraryType, ValueType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the ADD.
Definition Add.cpp:285
storm::storage::SparseMatrix< ValueType > toMatrix() const
Converts the ADD to a (sparse) matrix.
Definition Add.cpp:627
std::pair< storm::storage::SparseMatrix< ValueType >, std::vector< ValueType > > toMatrixVector(storm::dd::Add< LibraryType, ValueType > const &vector, std::set< storm::expressions::Variable > const &groupMetaVariables, storm::dd::Odd const &rowOdd, storm::dd::Odd const &columnOdd) const
Converts the ADD to a row-grouped (sparse) matrix and the given vector to a row-grouped vector.
Definition Add.cpp:909
Add< LibraryType, ValueType > sumAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Sum-abstracts from the given meta variables.
Definition Add.cpp:171
Bdd< LibraryType > notZero() const
Computes a BDD that represents the function in which all assignments with a function value unequal to...
Definition Add.cpp:424
std::vector< ValueType > toVector() const
Converts the ADD to a vector.
Definition Add.cpp:545
Bdd< LibraryType > existsAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Existentially abstracts from the given meta variables.
Definition Bdd.cpp:172
bool isZero() const
Retrieves whether this DD represents the constant zero function.
Definition Bdd.cpp:541
virtual uint_fast64_t getNonZeroCount() const override
Retrieves the number of encodings that are mapped to a non-zero value.
Definition Bdd.cpp:507
Bdd< LibraryType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the BDD.
Definition Bdd.cpp:296
Odd createOdd() const
Creates an ODD based on the current BDD.
Definition Bdd.cpp:565
storm::storage::BitVector toVector(storm::dd::Odd const &rowOdd) const
Converts the BDD to a bit vector.
Definition Bdd.cpp:491
Bdd< LibraryType > ite(Bdd< LibraryType > const &thenBdd, Bdd< LibraryType > const &elseBdd) const
Performs an if-then-else with the given operands, i.e.
Definition Bdd.cpp:107
Bdd< LibraryType > renameVariables(std::set< storm::expressions::Variable > const &from, std::set< storm::expressions::Variable > const &to) const
Renames the given meta variables in the BDD.
Definition Bdd.cpp:341
Bdd< LibraryType > relationalProduct(Bdd< LibraryType > const &relation, std::set< storm::expressions::Variable > const &rowMetaVariables, std::set< storm::expressions::Variable > const &columnMetaVariables) const
Computes the relational product of the current BDD and the given BDD representing a relation.
Definition Bdd.cpp:214
Bounds computeTotalRewardBounds(std::vector< ValueType > const &rewards)
Computes a lower and an upper bound on the expected total rewards.
std::vector< ValueType > computeUpperBounds()
Computes upper bounds on the expected rewards.
static std::unique_ptr< CheckResult > computeGloballyProbabilities(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &psiStates, bool qualitative)
static std::unique_ptr< CheckResult > computeNextProbabilities(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &nextStates)
static std::unique_ptr< CheckResult > computeInstantaneousRewards(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepBound)
storm::models::symbolic::NondeterministicModel< DdType, ValueType >::RewardModelType RewardModelType
static std::unique_ptr< CheckResult > computeReachabilityTimes(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &targetStates, bool qualitative)
static std::unique_ptr< CheckResult > computeCumulativeRewards(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepBound)
static std::unique_ptr< CheckResult > computeBoundedUntilProbabilities(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &phiStates, storm::dd::Bdd< DdType > const &psiStates, uint_fast64_t stepBound)
static std::unique_ptr< CheckResult > computeUntilProbabilities(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &phiStates, storm::dd::Bdd< DdType > const &psiStates, bool qualitative)
static std::unique_ptr< CheckResult > computeReachabilityRewards(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, RewardModelType const &rewardModel, storm::dd::Bdd< DdType > const &targetStates, bool qualitative)
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 std::unique_ptr< CheckResult > computeNextProbabilities(Environment const &env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel< DdType, ValueType > const &model, storm::dd::Add< DdType, ValueType > const &transitionMatrix, storm::dd::Bdd< DdType > const &nextStates)
storm::dd::DdManager< Type > & getManager() const
Retrieves the manager responsible for the DDs that represent this model.
Definition Model.cpp:89
std::set< storm::expressions::Variable > const & getColumnVariables() const
Retrieves the meta variables used to encode the columns of the transition matrix and the vector indic...
Definition Model.cpp:194
std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const & getRowColumnMetaVariablePairs() const
Retrieves the pairs of row and column meta variables.
Definition Model.cpp:220
std::set< storm::expressions::Variable > const & getRowVariables() const
Retrieves the meta variables used to encode the rows of the transition matrix and the vector indices.
Definition Model.cpp:189
storm::dd::Bdd< Type > const & getReachableStates() const
Retrieves the reachable states of the model.
Definition Model.cpp:99
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
Definition Model.cpp:74
Base class for all nondeterministic symbolic models.
virtual std::set< storm::expressions::Variable > const & getNondeterminismVariables() const override
Retrieves the meta variables used to encode the nondeterminism in the model.
bool hasStateRewards() const
Retrieves whether the reward model has state rewards.
storm::dd::Add< Type, ValueType > getTotalRewardVector(storm::dd::Add< Type, ValueType > const &transitionMatrix, std::set< storm::expressions::Variable > const &columnVariables) const
Creates a vector representing the complete reward vector based on the state-, state-action- and trans...
bool empty() const
Retrieves whether the reward model is empty.
storm::dd::Add< Type, ValueType > const & getStateRewardVector() const
Retrieves the state rewards of the reward model.
virtual std::unique_ptr< MinMaxLinearEquationSolver< ValueType, SolutionType > > create(Environment const &env) const override
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.
A class representing the interface that all min-max linear equation solvers shall implement.
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)
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
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.
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
A class that holds a possibly non-square matrix in the compressed row storage format.
index_type getRowGroupCount() const
Returns the number of row groups in 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...
storm::storage::SparseMatrix< value_type > transpose(bool joinGroups=false, bool keepZeros=false) const
Transposes the matrix.
A class that provides convenience operations to display run times.
Definition Stopwatch.h:13
MilisecondType getTimeInMilliseconds() const
Gets the measured time in milliseconds.
Definition Stopwatch.cpp:21
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:34
#define STORM_LOG_DEBUG(message)
Definition logging.h:28
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
storm::storage::BitVector computeTargetStatesForReachabilityRewardsFromExplicitRepresentation(storm::storage::SparseMatrix< ValueType > const &transitionMatrix)
void eliminateEndComponentsAndExtendedStatesUntilProbabilities(std::pair< storm::storage::SparseMatrix< ValueType >, std::vector< ValueType > > &explicitRepresentation, SolverRequirementsData< ValueType > &solverRequirementsData, storm::storage::BitVector const &targetStates)
void eliminateEndComponentsAndTargetStatesReachabilityRewards(std::pair< storm::storage::SparseMatrix< ValueType >, std::vector< ValueType > > &explicitRepresentation, SolverRequirementsData< ValueType > &solverRequirementsData, storm::storage::BitVector const &targetStates, bool computeOneStepTargetProbabilities)
void setUpperRewardBounds(storm::solver::MinMaxLinearEquationSolver< ValueType > &solver, storm::OptimizationDirection const &direction, storm::storage::SparseMatrix< ValueType > const &submatrix, std::vector< ValueType > const &choiceRewards, std::vector< ValueType > const &oneStepTargetProbabilities)
std::vector< ValueType > computeOneStepTargetProbabilitiesFromExtendedExplicitRepresentation(storm::storage::SparseMatrix< ValueType > const &extendedMatrix, storm::storage::BitVector const &properMaybeStates, storm::storage::BitVector const &targetStates)
void eliminateExtendedStatesFromExplicitRepresentation(std::pair< storm::storage::SparseMatrix< ValueType >, std::vector< ValueType > > &explicitRepresentation, boost::optional< std::vector< uint64_t > > &scheduler, storm::storage::BitVector const &properMaybeStates)
std::vector< uint64_t > computeValidInitialSchedulerForReachabilityRewards(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &properMaybeStates, storm::storage::BitVector const &targetStates)
std::vector< uint64_t > computeValidInitialSchedulerForUntilProbabilities(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< ValueType > const &b)
void expandSolutionAfterEndComponentElimination(SolverRequirementsData< ValueType > &solverRequirementsData, std::vector< ValueType > &x)
Lifts the solution of an equation system in which end components have been eliminated back to the pro...
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:855
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:536
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:881
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:609
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:1019
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:674
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:998
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:1101
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:740
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
Definition vector.h:1069
bool isZero(ValueType const &a)
Definition constants.cpp:44
ValueType zero()
Definition constants.cpp:26
ValueType infinity()
Definition constants.cpp:31
ValueType one()
Definition constants.cpp:21
TargetType convertNumber(SourceType const &number)
solver::OptimizationDirection OptimizationDirection
boost::optional< std::vector< uint64_t > > initialScheduler
boost::optional< SparseMdpEndComponentInformation< ValueType > > ecInformation
boost::optional< std::vector< ValueType > > oneStepTargetProbabilities