Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
graph.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <ranges>
5
24
25namespace storm {
26namespace utility {
27namespace graph {
28
29template<typename T>
31 storm::storage::BitVector result{initialStates.size()};
32 for (uint64_t currentState : initialStates) {
33 for (auto const& successor : transitionMatrix.getRowGroup(currentState)) {
34 STORM_LOG_ASSERT(!storm::utility::isZero(successor.getValue()), "Matrix should not have zero entries.");
35 result.set(successor.getColumn());
36 }
37 }
38 return result;
39}
40
41template<typename T>
43 storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates,
44 bool useStepBound, uint_fast64_t maximalSteps, boost::optional<storm::storage::BitVector> const& choiceFilter) {
45 storm::storage::BitVector reachableStates(initialStates);
46
47 uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount();
48
49 // Initialize the stack used for the DFS with the states.
50 std::vector<uint_fast64_t> stack;
51 stack.reserve(initialStates.size());
52 for (uint64_t state : initialStates) {
53 if (constraintStates.get(state)) {
54 stack.push_back(state);
55 }
56 }
57
58 // Initialize the stack for the step bound, if the number of steps is bounded.
59 std::vector<uint_fast64_t> stepStack;
60 std::vector<uint_fast64_t> remainingSteps;
61 if (useStepBound) {
62 stepStack.reserve(numberOfStates);
63 stepStack.insert(stepStack.begin(), stack.size(), maximalSteps);
64 remainingSteps.resize(numberOfStates);
65 for (auto state : stack) {
66 remainingSteps[state] = maximalSteps;
67 }
68 }
69
70 // Perform the actual DFS.
71 uint_fast64_t currentState = 0, currentStepBound = 0;
72 while (!stack.empty()) {
73 currentState = stack.back();
74 stack.pop_back();
75
76 if (useStepBound) {
77 currentStepBound = stepStack.back();
78 stepStack.pop_back();
79
80 if (currentStepBound == 0) {
81 continue;
82 }
83 }
84
85 uint64_t row = transitionMatrix.getRowGroupIndices()[currentState];
86 if (choiceFilter) {
87 row = choiceFilter->getNextSetIndex(row);
88 }
89 uint64_t const rowGroupEnd = transitionMatrix.getRowGroupIndices()[currentState + 1];
90 while (row < rowGroupEnd) {
91 for (auto const& successor : transitionMatrix.getRow(row)) {
92 // Only explore the state if the transition was actually there and the successor has not yet
93 // been visited.
94 if (!storm::utility::isZero(successor.getValue()) &&
95 (!reachableStates.get(successor.getColumn()) || (useStepBound && remainingSteps[successor.getColumn()] < currentStepBound - 1))) {
96 // If the successor is one of the target states, we need to include it, but must not explore
97 // it further.
98 if (targetStates.get(successor.getColumn())) {
99 reachableStates.set(successor.getColumn());
100 } else if (constraintStates.get(successor.getColumn())) {
101 // However, if the state is in the constrained set of states, we potentially need to follow it.
102 if (useStepBound) {
103 // As there is at least one more step to go, we need to push the state and the new number of steps.
104 remainingSteps[successor.getColumn()] = currentStepBound - 1;
105 stepStack.push_back(currentStepBound - 1);
106 }
107 reachableStates.set(successor.getColumn());
108 stack.push_back(successor.getColumn());
109 }
110 }
111 }
112 ++row;
113 if (choiceFilter) {
114 row = choiceFilter->getNextSetIndex(row);
115 }
116 }
117 }
118
119 return reachableStates;
120}
121
122template<typename T>
124 storm::storage::BitVector result(transitionMatrix.getRowGroupCount());
127
128 // Take the first state out of each BSCC.
129 for (auto const& scc : decomposition) {
130 result.set(*scc.begin());
131 }
132
133 return result;
134}
135
136template<typename T>
137bool hasCycle(storm::storage::SparseMatrix<T> const& transitionMatrix, boost::optional<storm::storage::BitVector> const& subsystem) {
138 storm::storage::BitVector unexploredStates; // States that have not been visited yet
139 storm::storage::BitVector acyclicStates; // States that are known to not lie on a cycle consisting of subsystem states
140 if (subsystem) {
141 unexploredStates = subsystem.get();
142 acyclicStates = ~subsystem.get();
143 } else {
144 unexploredStates.resize(transitionMatrix.getRowGroupCount(), true);
145 acyclicStates.resize(transitionMatrix.getRowGroupCount(), false);
146 }
147 std::vector<uint64_t> dfsStack;
148 for (uint64_t start = unexploredStates.getNextSetIndex(0); start < unexploredStates.size(); start = unexploredStates.getNextSetIndex(start + 1)) {
149 dfsStack.push_back(start);
150 while (!dfsStack.empty()) {
151 uint64_t state = dfsStack.back();
152 if (unexploredStates.get(state)) {
153 unexploredStates.set(state, false);
154 for (auto const& entry : transitionMatrix.getRowGroup(state)) {
155 if (!storm::utility::isZero(entry.getValue())) {
156 if (unexploredStates.get(entry.getColumn())) {
157 dfsStack.push_back(entry.getColumn());
158 } else {
159 if (!acyclicStates.get(entry.getColumn())) {
160 // The state has been visited before but is not known to be acyclic.
161 return true;
162 }
163 }
164 }
165 }
166 } else {
167 acyclicStates.set(state, true);
168 dfsStack.pop_back();
169 }
170 }
171 }
172 return false;
173}
174
175template<typename T>
177 storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices) {
178 STORM_LOG_THROW(subsystem.size() == transitionMatrix.getRowGroupCount(), storm::exceptions::InvalidArgumentException, "Invalid size of subsystem.");
179 STORM_LOG_THROW(choices.size() == transitionMatrix.getRowCount(), storm::exceptions::InvalidArgumentException, "Invalid size of choice vector.");
180
181 if (subsystem.empty() || choices.empty()) {
182 return false;
183 }
184
185 storm::storage::BitVector statesWithChoice(transitionMatrix.getRowGroupCount(), false);
186 uint_fast64_t state = 0;
187 for (uint64_t choice : choices) {
188 // Get the correct state
189 while (choice >= transitionMatrix.getRowGroupIndices()[state + 1]) {
190 ++state;
191 }
192 STORM_LOG_ASSERT(choice >= transitionMatrix.getRowGroupIndices()[state], "Choice index out of range.");
193 // make sure that the choice originates from the subsystem and also stays within the subsystem
194 if (subsystem.get(state)) {
195 bool choiceStaysInSubsys = true;
196 for (auto const& entry : transitionMatrix.getRow(choice)) {
197 if (!subsystem.get(entry.getColumn())) {
198 choiceStaysInSubsys = false;
199 break;
200 }
201 }
202 if (choiceStaysInSubsys) {
203 statesWithChoice.set(state, true);
204 }
205 }
206 }
207
208 // Initialize candidate states that satisfy some necessary conditions for being part of an EC with a specified choice:
209
210 // Get the states for which a policy can enforce that a choice is reached while staying inside the subsystem
211 storm::storage::BitVector candidateStates =
212 storm::utility::graph::performProb1E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, subsystem, statesWithChoice);
213
214 // Only keep the states that can stay in the set of candidates forever
215 candidateStates =
216 storm::utility::graph::performProb0E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, candidateStates, ~candidateStates);
217
218 // Only keep the states that can be reached after performing one of the specified choices
219 statesWithChoice &= candidateStates;
220 storm::storage::BitVector choiceTargets(transitionMatrix.getRowGroupCount(), false);
221 for (uint64_t state : statesWithChoice) {
222 for (uint_fast64_t choice = choices.getNextSetIndex(transitionMatrix.getRowGroupIndices()[state]);
223 choice < transitionMatrix.getRowGroupIndices()[state + 1]; choice = choices.getNextSetIndex(choice + 1)) {
224 bool choiceStaysInCandidateSet = true;
225 for (auto const& entry : transitionMatrix.getRow(choice)) {
226 if (!candidateStates.get(entry.getColumn())) {
227 choiceStaysInCandidateSet = false;
228 break;
229 }
230 }
231 if (choiceStaysInCandidateSet) {
232 for (auto const& entry : transitionMatrix.getRow(choice)) {
233 choiceTargets.set(entry.getColumn(), true);
234 }
235 }
236 }
237 }
238 candidateStates =
239 storm::utility::graph::getReachableStates(transitionMatrix, choiceTargets, candidateStates, storm::storage::BitVector(candidateStates.size(), false));
240
241 // At this point we know that every candidate state can reach a state with a choice without leaving the set of candidate states.
242 // We now compute the states that can reach a choice at least twice, three times, four times, ... until a fixpoint is reached.
243 while (!candidateStates.empty()) {
244 // Update the states with a choice that stays within the set of candidates
245 statesWithChoice &= candidateStates;
246 for (uint64_t state : statesWithChoice) {
247 bool stateHasChoice = false;
248 for (uint_fast64_t choice = choices.getNextSetIndex(transitionMatrix.getRowGroupIndices()[state]);
249 choice < transitionMatrix.getRowGroupIndices()[state + 1]; choice = choices.getNextSetIndex(choice + 1)) {
250 bool choiceStaysInCandidateSet = true;
251 for (auto const& entry : transitionMatrix.getRow(choice)) {
252 if (!candidateStates.get(entry.getColumn())) {
253 choiceStaysInCandidateSet = false;
254 break;
255 }
256 }
257 if (choiceStaysInCandidateSet) {
258 stateHasChoice = true;
259 break;
260 }
261 }
262 if (!stateHasChoice) {
263 statesWithChoice.set(state, false);
264 }
265 }
266
267 // Update the candidates
268 storm::storage::BitVector newCandidates = storm::utility::graph::performProb1E(transitionMatrix, transitionMatrix.getRowGroupIndices(),
269 backwardTransitions, candidateStates, statesWithChoice);
270
271 // Check if converged
272 if (newCandidates == candidateStates) {
273 STORM_LOG_ASSERT(!candidateStates.empty(), "Expected non-empty candidate states.");
274 return true;
275 }
276 candidateStates = std::move(newCandidates);
277 }
278 return false;
279}
280
281template<typename T>
282std::vector<uint_fast64_t> getDistances(storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::BitVector const& initialStates,
283 boost::optional<storm::storage::BitVector> const& subsystem) {
284 std::vector<uint_fast64_t> distances(transitionMatrix.getRowGroupCount());
285
286 std::vector<std::pair<storm::storage::sparse::state_type, uint_fast64_t>> stateQueue;
287 stateQueue.reserve(transitionMatrix.getRowGroupCount());
288 storm::storage::BitVector statesInQueue(transitionMatrix.getRowGroupCount());
289
290 storm::storage::sparse::state_type currentPosition = 0;
291 for (uint64_t initialState : initialStates) {
292 stateQueue.emplace_back(initialState, 0);
293 statesInQueue.set(initialState);
294 }
295
296 // Perform a BFS.
297 while (currentPosition < stateQueue.size()) {
298 std::pair<storm::storage::sparse::state_type, std::size_t> const& stateDistancePair = stateQueue[currentPosition];
299 distances[stateDistancePair.first] = stateDistancePair.second;
300
301 for (auto const& successorEntry : transitionMatrix.getRowGroup(stateDistancePair.first)) {
302 if (!statesInQueue.get(successorEntry.getColumn())) {
303 if (!subsystem || subsystem.get()[successorEntry.getColumn()]) {
304 stateQueue.emplace_back(successorEntry.getColumn(), stateDistancePair.second + 1);
305 statesInQueue.set(successorEntry.getColumn());
306 }
307 }
308 }
309 ++currentPosition;
310 }
311
312 return distances;
313}
314
315template<typename T>
317 storm::storage::BitVector const& psiStates, bool useStepBound, uint_fast64_t maximalSteps) {
318 // Prepare the resulting bit vector.
319 uint_fast64_t numberOfStates = phiStates.size();
320 storm::storage::BitVector statesWithProbabilityGreater0(numberOfStates);
321
322 // Add all psi states as they already satisfy the condition.
323 statesWithProbabilityGreater0 |= psiStates;
324
325 // Initialize the stack used for the DFS with the states.
326 std::vector<uint_fast64_t> stack(psiStates.begin(), psiStates.end());
327
328 // Initialize the stack for the step bound, if the number of steps is bounded.
329 std::vector<uint_fast64_t> stepStack;
330 std::vector<uint_fast64_t> remainingSteps;
331 if (useStepBound) {
332 stepStack.reserve(numberOfStates);
333 stepStack.insert(stepStack.begin(), psiStates.getNumberOfSetBits(), maximalSteps);
334 remainingSteps.resize(numberOfStates);
335 for (uint64_t state : psiStates) {
336 remainingSteps[state] = maximalSteps;
337 }
338 }
339
340 // Perform the actual DFS.
341 uint_fast64_t currentState, currentStepBound;
342 while (!stack.empty()) {
343 currentState = stack.back();
344 stack.pop_back();
345
346 if (useStepBound) {
347 currentStepBound = stepStack.back();
348 stepStack.pop_back();
349 if (currentStepBound == 0) {
350 continue;
351 }
352 }
353
354 for (typename storm::storage::SparseMatrix<T>::const_iterator entryIt = backwardTransitions.begin(currentState),
355 entryIte = backwardTransitions.end(currentState);
356 entryIt != entryIte; ++entryIt) {
357 if (phiStates[entryIt->getColumn()] &&
358 (!statesWithProbabilityGreater0.get(entryIt->getColumn()) || (useStepBound && remainingSteps[entryIt->getColumn()] < currentStepBound - 1))) {
359 statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
360
361 // If we don't have a bound on the number of steps to take, just add the state to the stack.
362 if (useStepBound) {
363 // As there is at least one more step to go, we need to push the state and the new number of steps.
364 remainingSteps[entryIt->getColumn()] = currentStepBound - 1;
365 stepStack.push_back(currentStepBound - 1);
366 }
367 stack.push_back(entryIt->getColumn());
368 }
369 }
370 }
371
372 // Return result.
373 return statesWithProbabilityGreater0;
374}
375
376template<typename T>
378 storm::storage::BitVector const& psiStates, storm::storage::BitVector const& statesWithProbabilityGreater0) {
379 storm::storage::BitVector statesWithProbability1 = performProbGreater0(backwardTransitions, ~psiStates, ~statesWithProbabilityGreater0);
380 statesWithProbability1.complement();
381 return statesWithProbability1;
382}
383
384template<typename T>
386 storm::storage::BitVector const& psiStates) {
387 storm::storage::BitVector statesWithProbabilityGreater0 = performProbGreater0(backwardTransitions, phiStates, psiStates);
388 storm::storage::BitVector statesWithProbability1 = performProbGreater0(backwardTransitions, ~psiStates, ~(statesWithProbabilityGreater0));
389 statesWithProbability1.complement();
390 return statesWithProbability1;
391}
392
393template<typename T>
394std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::models::sparse::DeterministicModel<T> const& model,
395 storm::storage::BitVector const& phiStates,
396 storm::storage::BitVector const& psiStates) {
397 std::pair<storm::storage::BitVector, storm::storage::BitVector> result;
398 storm::storage::SparseMatrix<T> backwardTransitions = model.getBackwardTransitions();
399 result.first = performProbGreater0(backwardTransitions, phiStates, psiStates);
400 result.second = performProb1(backwardTransitions, phiStates, psiStates, result.first);
401 result.first.complement();
402 return result;
403}
404
405template<typename T>
406std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::storage::SparseMatrix<T> const& backwardTransitions,
407 storm::storage::BitVector const& phiStates,
408 storm::storage::BitVector const& psiStates) {
409 std::pair<storm::storage::BitVector, storm::storage::BitVector> result;
410 result.first = performProbGreater0(backwardTransitions, phiStates, psiStates);
411 result.second = performProb1(backwardTransitions, phiStates, psiStates, result.first);
412 result.first.complement();
413 return result;
414}
415
416template<storm::dd::DdType Type, typename ValueType>
418 storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates,
419 boost::optional<uint_fast64_t> const& stepBound) {
420 // Initialize environment for backward search.
421 storm::dd::DdManager<Type> const& manager = model.getManager();
422 storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
423 storm::dd::Bdd<Type> statesWithProbabilityGreater0 = psiStates;
424
425 uint_fast64_t iterations = 0;
426 while (lastIterationStates != statesWithProbabilityGreater0) {
427 if (stepBound && iterations >= stepBound.get()) {
428 break;
429 }
430
431 lastIterationStates = statesWithProbabilityGreater0;
432 statesWithProbabilityGreater0 =
433 statesWithProbabilityGreater0.inverseRelationalProduct(transitionMatrix, model.getRowVariables(), model.getColumnVariables());
434 statesWithProbabilityGreater0 &= phiStates;
435 statesWithProbabilityGreater0 |= lastIterationStates;
436 ++iterations;
437 }
438
439 return statesWithProbabilityGreater0;
440}
441
442template<storm::dd::DdType Type, typename ValueType>
444 storm::dd::Bdd<Type> const&, storm::dd::Bdd<Type> const& psiStates,
445 storm::dd::Bdd<Type> const& statesWithProbabilityGreater0) {
446 storm::dd::Bdd<Type> statesWithProbability1 =
447 performProbGreater0(model, transitionMatrix, !psiStates && model.getReachableStates(), !statesWithProbabilityGreater0 && model.getReachableStates());
448 statesWithProbability1 = !statesWithProbability1 && model.getReachableStates();
449 return statesWithProbability1;
450}
451
452template<storm::dd::DdType Type, typename ValueType>
454 storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
455 storm::dd::Bdd<Type> statesWithProbabilityGreater0 = performProbGreater0(model, transitionMatrix, phiStates, psiStates);
456 return performProb1(model, transitionMatrix, phiStates, psiStates, statesWithProbabilityGreater0);
457}
458
459template<storm::dd::DdType Type, typename ValueType>
461 storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
462 std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
463 storm::dd::Bdd<Type> transitionMatrix = model.getTransitionMatrix().notZero();
464 result.first = performProbGreater0(model, transitionMatrix, phiStates, psiStates);
465 result.second = !performProbGreater0(model, transitionMatrix, !psiStates && model.getReachableStates(), !result.first && model.getReachableStates()) &&
466 model.getReachableStates();
467 result.first = !result.first && model.getReachableStates();
468 return result;
469}
470
471template<storm::dd::DdType Type, typename ValueType>
473 storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates,
474 storm::dd::Bdd<Type> const& psiStates) {
475 std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
476 result.first = performProbGreater0(model, transitionMatrix, phiStates, psiStates);
477 result.second = !performProbGreater0(model, transitionMatrix, !psiStates && model.getReachableStates(), !result.first && model.getReachableStates()) &&
478 model.getReachableStates();
479 result.first = !result.first && model.getReachableStates();
480 return result;
481}
482
483template<typename T, typename SchedulerValueType>
485 storm::storage::Scheduler<SchedulerValueType>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter) {
486 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = transitionMatrix.getRowGroupIndices();
487
488 for (uint64_t state : states) {
489 [[maybe_unused]] bool setValue{false};
490 for (auto choice : transitionMatrix.getRowGroupIndices(state)) {
491 if (rowFilter && !rowFilter->get(choice)) {
492 continue;
493 }
494 auto const row = transitionMatrix.getRow(choice);
495 bool const allSuccessorsInStates = std::all_of(row.begin(), row.end(), [&states](auto const& entry) { return states.get(entry.getColumn()); });
496 if (allSuccessorsInStates) {
497 for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) {
498 scheduler.setChoice(choice - nondeterministicChoiceIndices[state], state, memState);
499 }
500 setValue = true;
501 break;
502 }
503 }
504 STORM_LOG_ASSERT(setValue, "Expected that at least one action for state " << state << " stays within the selected state");
505 }
506}
507
508template<typename T, typename SchedulerValueType>
511 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = transitionMatrix.getRowGroupIndices();
512
513 for (uint64_t state : states) {
514 [[maybe_unused]] bool setValue = false;
515 for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) {
516 bool oneSuccessorInStates = false;
517 for (auto const& element : transitionMatrix.getRow(choice)) {
518 if (states.get(element.getColumn())) {
519 oneSuccessorInStates = true;
520 break;
521 }
522 }
523 if (oneSuccessorInStates) {
524 for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) {
525 scheduler.setChoice(choice - nondeterministicChoiceIndices[state], state, memState);
526 }
527 setValue = true;
528 break;
529 }
530 }
531 STORM_LOG_ASSERT(setValue, "Expected that at least one action for state " << state << " leads with positive probability to the selected state");
532 }
533}
534
535template<typename T, typename SchedulerValueType>
537 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
538 storm::storage::Scheduler<SchedulerValueType>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter) {
539 // Perform backwards DFS from psiStates and find a valid choice for each visited state.
540
541 std::vector<uint_fast64_t> stack;
542 storm::storage::BitVector currentStates(psiStates); // the states that are either psiStates or for which we have found a valid choice.
543 stack.insert(stack.end(), currentStates.begin(), currentStates.end());
544 uint_fast64_t currentState = 0;
545
546 while (!stack.empty()) {
547 currentState = stack.back();
548 stack.pop_back();
549
550 for (typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState),
551 predecessorEntryIte = backwardTransitions.end(currentState);
552 predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
553 uint_fast64_t const& predecessor = predecessorEntryIt->getColumn();
554 if (phiStates.get(predecessor) && !currentStates.get(predecessor)) {
555 // The predecessor is a probGreater0E state that has not been considered yet. Let's find the right choice that leads to a state in
556 // currentStates.
557 bool foundValidChoice = false;
558 for (uint_fast64_t row = transitionMatrix.getRowGroupIndices()[predecessor]; row < transitionMatrix.getRowGroupIndices()[predecessor + 1];
559 ++row) {
560 if (rowFilter && !rowFilter->get(row)) {
561 continue;
562 }
563 for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row),
564 successorEntryIte = transitionMatrix.end(row);
565 successorEntryIt != successorEntryIte; ++successorEntryIt) {
566 if (currentStates.get(successorEntryIt->getColumn())) {
567 foundValidChoice = true;
568 break;
569 }
570 }
571 if (foundValidChoice) {
572 for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) {
573 scheduler.setChoice(row - transitionMatrix.getRowGroupIndices()[predecessor], predecessor, memState);
574 }
575 currentStates.set(predecessor, true);
576 stack.push_back(predecessor);
577 break;
578 }
579 }
580 STORM_LOG_INFO_COND(foundValidChoice, "Could not find a valid choice for ProbGreater0E state " << predecessor << ".");
581 }
582 }
583 }
584}
585
586template<typename T, typename SchedulerValueType>
589 computeSchedulerStayingInStates(prob0EStates, transitionMatrix, scheduler);
590}
591
592template<typename T, typename SchedulerValueType>
595 // Get the states from which we can never exit the rewInfStates, i.e. the states satisfying Pmax=1 [ G "rewInfStates"]
596 // or, equivalently, the states satisfying Pmin=0 [ F !"rewInfStates"].
597 auto trapStates = performProb0E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, rewInfStates, ~rewInfStates);
598 // Also set a corresponding choice for all those states
599 computeSchedulerProb0E(trapStates, transitionMatrix, scheduler);
600
601 // All remaining rewInfStates must reach a trapState with positive probability
602 auto remainingStates = rewInfStates & ~trapStates;
603 if (!remainingStates.empty()) {
604 computeSchedulerProbGreater0E(transitionMatrix, backwardTransitions, remainingStates, trapStates, scheduler);
605 }
606}
607
608template<typename T, typename SchedulerValueType>
610 storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates,
612 boost::optional<storm::storage::BitVector> const& rowFilter) {
613 // set an arbitrary (valid) choice for the psi states.
614 for (uint64_t psiState : psiStates) {
615 for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) {
616 if (!scheduler.getChoice(psiState, memState).isDefined()) {
617 scheduler.setChoice(0, psiState, memState);
618 }
619 }
620 }
621
622 // Now perform a backwards search from the psi states and store choices with prob. 1
623 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = transitionMatrix.getRowGroupIndices();
624 std::vector<uint_fast64_t> stack;
625 storm::storage::BitVector currentStates(psiStates);
626 stack.insert(stack.end(), currentStates.begin(), currentStates.end());
627 uint_fast64_t currentState = 0;
628
629 while (!stack.empty()) {
630 currentState = stack.back();
631 stack.pop_back();
632
633 for (typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState),
634 predecessorEntryIte = backwardTransitions.end(currentState);
635 predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
636 if (phiStates.get(predecessorEntryIt->getColumn()) && !currentStates.get(predecessorEntryIt->getColumn())) {
637 // Check whether the predecessor has only successors in the prob1E state set for one of the
638 // nondeterminstic choices.
639 for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()];
640 row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) {
641 if (!rowFilter || rowFilter.get().get(row)) {
642 bool allSuccessorsInProb1EStates = true;
643 bool hasSuccessorInCurrentStates = false;
644 for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row),
645 successorEntryIte = transitionMatrix.end(row);
646 successorEntryIt != successorEntryIte; ++successorEntryIt) {
647 if (!prob1EStates.get(successorEntryIt->getColumn())) {
648 allSuccessorsInProb1EStates = false;
649 break;
650 } else if (currentStates.get(successorEntryIt->getColumn())) {
651 hasSuccessorInCurrentStates = true;
652 }
653 }
654
655 // If all successors for a given nondeterministic choice are in the prob1E state set, we
656 // perform a backward search from that state.
657 if (allSuccessorsInProb1EStates && hasSuccessorInCurrentStates) {
658 for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) {
659 scheduler.setChoice(row - nondeterministicChoiceIndices[predecessorEntryIt->getColumn()], predecessorEntryIt->getColumn(),
660 memState);
661 }
662 currentStates.set(predecessorEntryIt->getColumn(), true);
663 stack.push_back(predecessorEntryIt->getColumn());
664 break;
665 }
666 }
667 }
668 }
669 }
670 }
671}
672
673template<typename T>
675 storm::storage::BitVector const& psiStates, bool useStepBound, uint_fast64_t maximalSteps) {
676 size_t numberOfStates = phiStates.size();
677
678 // Prepare resulting bit vector.
679 // Add all psi states as the already satisfy the condition.
680 storm::storage::BitVector statesWithProbabilityGreater0 = psiStates;
681
682 // Initialize the stack used for the DFS with the states
683 std::vector<uint_fast64_t> stack(psiStates.begin(), psiStates.end());
684
685 // Initialize the stack for the step bound, if the number of steps is bounded.
686 std::vector<uint_fast64_t> stepStack;
687 std::vector<uint_fast64_t> remainingSteps;
688 if (useStepBound) {
689 stepStack.reserve(numberOfStates);
690 stepStack.insert(stepStack.begin(), psiStates.getNumberOfSetBits(), maximalSteps);
691 remainingSteps.resize(numberOfStates);
692 for (uint64_t state : psiStates) {
693 remainingSteps[state] = maximalSteps;
694 }
695 }
696
697 // Perform the actual DFS.
698 uint_fast64_t currentState, currentStepBound;
699 while (!stack.empty()) {
700 currentState = stack.back();
701 stack.pop_back();
702
703 if (useStepBound) {
704 currentStepBound = stepStack.back();
705 stepStack.pop_back();
706 if (currentStepBound == 0) {
707 continue;
708 }
709 }
710
711 for (typename storm::storage::SparseMatrix<T>::const_iterator entryIt = backwardTransitions.begin(currentState),
712 entryIte = backwardTransitions.end(currentState);
713 entryIt != entryIte; ++entryIt) {
714 if (phiStates.get(entryIt->getColumn()) &&
715 (!statesWithProbabilityGreater0.get(entryIt->getColumn()) || (useStepBound && remainingSteps[entryIt->getColumn()] < currentStepBound - 1))) {
716 // If we don't have a bound on the number of steps to take, just add the state to the stack.
717 if (useStepBound) {
718 // If there is at least one more step to go, we need to push the state and the new number of steps.
719 remainingSteps[entryIt->getColumn()] = currentStepBound - 1;
720 stepStack.push_back(currentStepBound - 1);
721 }
722 statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
723 stack.push_back(entryIt->getColumn());
724 }
725 }
726 }
727
728 return statesWithProbabilityGreater0;
729}
730
731template<typename T>
733 storm::storage::BitVector const& psiStates) {
734 storm::storage::BitVector statesWithProbability0 = performProbGreater0E(backwardTransitions, phiStates, psiStates);
735 statesWithProbability0.complement();
736 return statesWithProbability0;
737}
738
739template<typename T>
741 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
742 storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates,
743 storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint) {
744 // We compute the largest set of candidates such that
745 // (i) every candidate that is not a psi state has an enabled choice whose successors are all candidates and
746 // (ii) from every candidate, a psi state can be reached within the candidates using only choices as in (i).
747 // Starting with all (phi|psi)-states, we alternate two kinds of removals: Candidates violating (i) are removed by a cascading backward search and
748 // candidates violating (ii) are removed after a backward search from the psi states. As removing a state can invalidate (i) for its
749 // predecessors and (ii) for the states that reached the psi states through it, this is repeated until nothing changes anymore.
750 // Since we only ever remove states that can not be part of a set satisfying (i) and (ii), the computation converges to the desired set.
751 storm::storage::BitVector candidates = phiStates | psiStates;
752
753 // The choices of the given state.
754 auto choicesOf = [&nondeterministicChoiceIndices](uint64_t const state) {
755 return std::views::iota(nondeterministicChoiceIndices[state], nondeterministicChoiceIndices[state + 1]);
756 };
757
758 // Whether the given choice is enabled and all of its successors are candidates.
759 auto choiceStaysInCandidates = [&](uint64_t const choice) -> bool {
760 return (!choiceConstraint || choiceConstraint->get(choice)) &&
761 std::ranges::all_of(transitionMatrix.getRow(choice), [&candidates](auto const& entry) { return candidates.get(entry.getColumn()); });
762 };
763
764 // Whether the given state satisfies (i).
765 auto satisfiesSafety = [&](uint64_t const state) -> bool { return psiStates.get(state) || std::ranges::any_of(choicesOf(state), choiceStaysInCandidates); };
766
767 std::vector<uint64_t> stack; // used for backpropagation.
768
769 // Removes the candidates that (transitively) violate (i) by backpropagating from the current stack contents
770 auto propagateRemovals = [&] {
771 while (!stack.empty()) {
772 uint64_t const removedState = stack.back();
773 stack.pop_back();
774 for (auto const& predecessorEntry : backwardTransitions.getRow(removedState)) {
775 uint64_t const predecessor = predecessorEntry.getColumn();
776 if (candidates.get(predecessor) && !satisfiesSafety(predecessor)) {
777 candidates.set(predecessor, false);
778 stack.push_back(predecessor);
779 }
780 }
781 }
782 };
783
784 storm::storage::BitVector auxStates; // Auxiliary storage used to check (ii)
785
786 // Whether the given choice stays in the candidates and has a successor in auxStates
787 auto isSafeChoiceReachingAux = [&](uint64_t const choice) -> bool {
788 if (choiceConstraint && !choiceConstraint->get(choice)) {
789 return false;
790 }
791 bool hasReachingSuccessor = false;
792 for (auto const& successorEntry : transitionMatrix.getRow(choice)) {
793 if (!candidates.get(successorEntry.getColumn())) {
794 return false;
795 }
796 hasReachingSuccessor = hasReachingSuccessor || auxStates.get(successorEntry.getColumn());
797 }
798 return hasReachingSuccessor;
799 };
800
801 // Gathers the states that satisfy (ii) with respect to the current candidates and stores them into auxStates
802 auto gatherReachingStates = [&] {
803 auxStates = psiStates;
804 stack.assign(psiStates.begin(), psiStates.end());
805 while (!stack.empty()) {
806 uint64_t const currentState = stack.back();
807 stack.pop_back();
808 for (auto const& predecessorEntry : backwardTransitions.getRow(currentState)) {
809 uint64_t const predecessor = predecessorEntry.getColumn();
810 if (candidates.get(predecessor) && !auxStates.get(predecessor) && std::ranges::any_of(choicesOf(predecessor), isSafeChoiceReachingAux)) {
811 auxStates.set(predecessor, true);
812 stack.push_back(predecessor);
813 }
814 }
815 }
816 };
817
818 // Initially, safety (i) has to be checked for every candidate.
819 for (uint64_t const state : candidates) {
820 if (!satisfiesSafety(state)) {
821 candidates.set(state, false); // Note: BitVectors support removing elements while iterating over them.
822 stack.push_back(state);
823 }
824 }
825
826 // Now alternate the two kinds of removals until a fixed point is reached.
827 do {
828 // Propagate the removals of states from the candidates set (these are stored in the stack at this point)
829 propagateRemovals();
830 STORM_LOG_ASSERT(stack.empty(), "Expected empty stack after propagating removals.");
831 // Perform a backward search from the psi states, only using choices that stay in the candidates (puts result into auxStates)
832 gatherReachingStates();
833 STORM_LOG_ASSERT(stack.empty(), "Expected empty stack after gathering reaching states.");
834 STORM_LOG_ASSERT(auxStates.isSubsetOf(candidates), "Expected that reaching states are a subset of the candidates.");
835 auxStates ^= candidates;
836 // At this point auxStates contains those candidates that cannot reach psi. Remove those states from the candidates.
837 for (uint64_t const state : auxStates) {
838 candidates.set(state, false);
839 stack.push_back(state);
840 }
841 // Now either propagate the removals or terminate if no more candidates have been removed
842 } while (!stack.empty());
843
844 return candidates;
845}
846
847template<typename T, typename RM>
849 storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates,
850 storm::storage::BitVector const& psiStates) {
851 return performProb1E(model.getTransitionMatrix(), model.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates);
852}
853
854template<typename T>
855std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(storm::storage::SparseMatrix<T> const& transitionMatrix,
856 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
857 storm::storage::SparseMatrix<T> const& backwardTransitions,
858 storm::storage::BitVector const& phiStates,
859 storm::storage::BitVector const& psiStates) {
860 std::pair<storm::storage::BitVector, storm::storage::BitVector> result;
861
862 result.first = performProbGreater0E(backwardTransitions, phiStates, psiStates); // Will be complemented below to get prob0A-states.
863
864 // Take the probGreater0E-states as phiStates to narrow down the search. The probGreater0E-states are a subset of (phi|psi)-state and a superset of prob1E.
865 result.second = performProb1E(transitionMatrix, nondeterministicChoiceIndices, backwardTransitions, result.first, psiStates);
866
867 result.first.complement(); // prob0A = ~probGreater0E
868
869 return result;
870}
871
872template<typename T, typename RM>
873std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(storm::models::sparse::NondeterministicModel<T, RM> const& model,
874 storm::storage::BitVector const& phiStates,
875 storm::storage::BitVector const& psiStates) {
876 return performProb01Max(model.getTransitionMatrix(), model.getTransitionMatrix().getRowGroupIndices(), model.getBackwardTransitions(), phiStates,
877 psiStates);
878}
879
880template<typename T>
882 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
883 storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates,
884 storm::storage::BitVector const& psiStates, bool useStepBound, uint_fast64_t maximalSteps,
885 boost::optional<storm::storage::BitVector> const& choiceConstraint) {
886 size_t numberOfStates = phiStates.size();
887
888 // Prepare resulting bit vector.
889 // Add all psi states as the already satisfy the condition.
890 storm::storage::BitVector statesWithProbabilityGreater0 = psiStates;
891
892 // Initialize the stack used for the DFS with the states
893 std::vector<uint_fast64_t> stack(psiStates.begin(), psiStates.end());
894
895 // Initialize the stack for the step bound, if the number of steps is bounded.
896 std::vector<uint_fast64_t> stepStack;
897 std::vector<uint_fast64_t> remainingSteps;
898 if (useStepBound) {
899 stepStack.reserve(numberOfStates);
900 stepStack.insert(stepStack.begin(), psiStates.getNumberOfSetBits(), maximalSteps);
901 remainingSteps.resize(numberOfStates);
902 for (uint64_t state : psiStates) {
903 remainingSteps[state] = maximalSteps;
904 }
905 }
906
907 // Perform the actual DFS.
908 uint_fast64_t currentState, currentStepBound;
909 while (!stack.empty()) {
910 currentState = stack.back();
911 stack.pop_back();
912
913 if (useStepBound) {
914 currentStepBound = stepStack.back();
915 stepStack.pop_back();
916 if (currentStepBound == 0) {
917 continue;
918 }
919 }
920
921 for (typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState),
922 predecessorEntryIte = backwardTransitions.end(currentState);
923 predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
924 if (phiStates.get(predecessorEntryIt->getColumn())) {
925 if (!statesWithProbabilityGreater0.get(predecessorEntryIt->getColumn())) {
926 // Check whether the predecessor has at least one successor in the current state set for every
927 // nondeterministic choice within the possibly given choiceConstraint.
928
929 // Note: The backwards edge might be induced by a choice that violates the choiceConstraint.
930 // However this is not problematic as long as there is at least one enabled choice for the predecessor.
931 uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()];
932 uint_fast64_t const& endOfGroup = nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1];
933 if (!choiceConstraint || choiceConstraint->getNextSetIndex(row) < endOfGroup) {
934 bool addToStatesWithProbabilityGreater0 = true;
935 for (; row < endOfGroup; ++row) {
936 if (!choiceConstraint || choiceConstraint->get(row)) {
937 bool hasAtLeastOneSuccessorWithProbabilityGreater0 = false;
938 for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row),
939 successorEntryIte = transitionMatrix.end(row);
940 successorEntryIt != successorEntryIte; ++successorEntryIt) {
941 if (statesWithProbabilityGreater0.get(successorEntryIt->getColumn())) {
942 hasAtLeastOneSuccessorWithProbabilityGreater0 = true;
943 break;
944 }
945 }
946
947 if (!hasAtLeastOneSuccessorWithProbabilityGreater0) {
948 addToStatesWithProbabilityGreater0 = false;
949 break;
950 }
951 }
952 }
953
954 // If we need to add the state, then actually add it and perform further search from the state.
955 if (addToStatesWithProbabilityGreater0) {
956 // If we don't have a bound on the number of steps to take, just add the state to the stack.
957 if (useStepBound) {
958 // If there is at least one more step to go, we need to push the state and the new number of steps.
959 remainingSteps[predecessorEntryIt->getColumn()] = currentStepBound - 1;
960 stepStack.push_back(currentStepBound - 1);
961 }
962 statesWithProbabilityGreater0.set(predecessorEntryIt->getColumn(), true);
963 stack.push_back(predecessorEntryIt->getColumn());
964 }
965 }
966
967 } else if (useStepBound && remainingSteps[predecessorEntryIt->getColumn()] < currentStepBound - 1) {
968 // We have found a shorter path to the predecessor. Hence, we need to explore it again.
969 // If there is a choiceConstraint, we still need to check whether the backwards edge was induced by a valid action
970 bool predecessorIsValid = true;
971 if (choiceConstraint) {
972 predecessorIsValid = false;
973 uint_fast64_t row = choiceConstraint->getNextSetIndex(nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]);
974 uint_fast64_t const& endOfGroup = nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1];
975 for (; row < endOfGroup && !predecessorIsValid; row = choiceConstraint->getNextSetIndex(row + 1)) {
976 for (auto const& entry : transitionMatrix.getRow(row)) {
977 if (entry.getColumn() == currentState) {
978 predecessorIsValid = true;
979 break;
980 }
981 }
982 }
983 }
984 if (predecessorIsValid) {
985 remainingSteps[predecessorEntryIt->getColumn()] = currentStepBound - 1;
986 stepStack.push_back(currentStepBound - 1);
987 stack.push_back(predecessorEntryIt->getColumn());
988 }
989 }
990 }
991 }
992 }
993
994 return statesWithProbabilityGreater0;
995}
996
997template<typename T, typename RM>
999 storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates,
1000 storm::storage::BitVector const& psiStates) {
1001 storm::storage::BitVector statesWithProbability0 =
1002 performProbGreater0A(model.getTransitionMatrix(), model.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates);
1003 statesWithProbability0.complement();
1004 return statesWithProbability0;
1005}
1006
1007template<typename T>
1009 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
1010 storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates,
1011 storm::storage::BitVector const& psiStates) {
1012 storm::storage::BitVector statesWithProbability0 =
1013 performProbGreater0A(transitionMatrix, nondeterministicChoiceIndices, backwardTransitions, phiStates, psiStates);
1014 statesWithProbability0.complement();
1015 return statesWithProbability0;
1016}
1017
1018template<typename T, typename RM>
1020 storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates,
1021 storm::storage::BitVector const& psiStates) {
1022 return performProb1A(model.getTransitionMatrix(), model.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates);
1023}
1024
1025template<typename T>
1027 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
1028 storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates,
1029 storm::storage::BitVector const& psiStates) {
1030 size_t numberOfStates = phiStates.size();
1031
1032 // Initialize the environment for the iterative algorithm.
1033 storm::storage::BitVector currentStates(numberOfStates, true);
1034 std::vector<uint_fast64_t> stack;
1035 stack.reserve(numberOfStates);
1036
1037 // Perform the loop as long as the set of states gets smaller.
1038 bool done = false;
1039 uint_fast64_t currentState;
1040 while (!done) {
1041 stack.clear();
1042 storm::storage::BitVector nextStates(psiStates);
1043 stack.insert(stack.end(), psiStates.begin(), psiStates.end());
1044
1045 while (!stack.empty()) {
1046 currentState = stack.back();
1047 stack.pop_back();
1048
1049 for (typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState),
1050 predecessorEntryIte = backwardTransitions.end(currentState);
1051 predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
1052 if (phiStates.get(predecessorEntryIt->getColumn()) && !nextStates.get(predecessorEntryIt->getColumn())) {
1053 // Check whether the predecessor has only successors in the current state set for all of the
1054 // nondeterminstic choices and that for each choice there exists a successor that is already
1055 // in the next states.
1056 bool addToStatesWithProbability1 = true;
1057 for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()];
1058 row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) {
1059 bool hasAtLeastOneSuccessorWithProbability1 = false;
1060 for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row),
1061 successorEntryIte = transitionMatrix.end(row);
1062 successorEntryIt != successorEntryIte; ++successorEntryIt) {
1063 if (!currentStates.get(successorEntryIt->getColumn())) {
1064 addToStatesWithProbability1 = false;
1065 goto afterCheckLoop;
1066 }
1067 if (nextStates.get(successorEntryIt->getColumn())) {
1068 hasAtLeastOneSuccessorWithProbability1 = true;
1069 }
1070 }
1071
1072 if (!hasAtLeastOneSuccessorWithProbability1) {
1073 addToStatesWithProbability1 = false;
1074 break;
1075 }
1076 }
1077
1078 afterCheckLoop:
1079 // If all successors for all nondeterministic choices are in the current state set, we
1080 // add it to the set of states for the next iteration and perform a backward search from
1081 // that state.
1082 if (addToStatesWithProbability1) {
1083 nextStates.set(predecessorEntryIt->getColumn(), true);
1084 stack.push_back(predecessorEntryIt->getColumn());
1085 }
1086 }
1087 }
1088 }
1089
1090 // Check whether we need to perform an additional iteration.
1091 if (currentStates == nextStates) {
1092 done = true;
1093 } else {
1094 currentStates = std::move(nextStates);
1095 }
1096 }
1097 return currentStates;
1098}
1099
1100template<typename T>
1101std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::storage::SparseMatrix<T> const& transitionMatrix,
1102 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
1103 storm::storage::SparseMatrix<T> const& backwardTransitions,
1104 storm::storage::BitVector const& phiStates,
1105 storm::storage::BitVector const& psiStates) {
1106 std::pair<storm::storage::BitVector, storm::storage::BitVector> result;
1107 result.first = performProb0E(transitionMatrix, nondeterministicChoiceIndices, backwardTransitions, phiStates, psiStates);
1108 // Instead of calling performProb1A, we call the (more easier) performProb0A on the Prob0E states.
1109 // This is valid because, when minimizing probabilities, states that have prob1 cannot reach a state with prob 0 (and will eventually reach a psiState).
1110 // States that do not have prob1 will eventually reach a state with prob0.
1111 result.second = performProb0A(backwardTransitions, ~psiStates, result.first);
1112 return result;
1113}
1114
1115template<typename T, typename RM>
1116std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::models::sparse::NondeterministicModel<T, RM> const& model,
1117 storm::storage::BitVector const& phiStates,
1118 storm::storage::BitVector const& psiStates) {
1119 return performProb01Min(model.getTransitionMatrix(), model.getTransitionMatrix().getRowGroupIndices(), model.getBackwardTransitions(), phiStates,
1120 psiStates);
1121}
1122
1123template<storm::dd::DdType Type, typename ValueType>
1125 storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates,
1126 storm::dd::Bdd<Type> const& psiStates) {
1127 // Initialize environment for backward search.
1128 storm::dd::DdManager<Type> const& manager = model.getManager();
1129 storm::dd::Bdd<Type> statesWithProbabilityGreater0E = manager.getBddZero();
1130 storm::dd::Bdd<Type> frontier = psiStates;
1131 storm::dd::Bdd<Type> scheduler = manager.getBddZero();
1132
1133 while (!frontier.isZero()) {
1134 storm::dd::Bdd<Type> statesAndChoicesWithProbabilityGreater0E =
1135 frontier.inverseRelationalProductWithExtendedRelation(transitionMatrix, model.getRowVariables(), model.getColumnVariables());
1136 frontier = phiStates && statesAndChoicesWithProbabilityGreater0E.existsAbstract(model.getNondeterminismVariables()) && !statesWithProbabilityGreater0E;
1137 scheduler = scheduler || (frontier && statesAndChoicesWithProbabilityGreater0E).existsAbstractRepresentative(model.getNondeterminismVariables());
1138 statesWithProbabilityGreater0E |= frontier;
1139 }
1140
1141 return scheduler;
1142}
1143
1144template<storm::dd::DdType Type, typename ValueType>
1146 storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates,
1147 storm::dd::Bdd<Type> const& psiStates) {
1148 // Initialize environment for backward search.
1149 storm::dd::DdManager<Type> const& manager = model.getManager();
1150 storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
1151 storm::dd::Bdd<Type> statesWithProbabilityGreater0E = psiStates;
1152
1153 storm::dd::Bdd<Type> abstractedTransitionMatrix = transitionMatrix.existsAbstract(model.getNondeterminismVariables());
1154 while (lastIterationStates != statesWithProbabilityGreater0E) {
1155 lastIterationStates = statesWithProbabilityGreater0E;
1156 statesWithProbabilityGreater0E =
1157 statesWithProbabilityGreater0E.inverseRelationalProduct(abstractedTransitionMatrix, model.getRowVariables(), model.getColumnVariables());
1158 statesWithProbabilityGreater0E &= phiStates;
1159 statesWithProbabilityGreater0E |= lastIterationStates;
1160 }
1161
1162 return statesWithProbabilityGreater0E;
1163}
1164
1165template<storm::dd::DdType Type, typename ValueType>
1167 storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
1168 return !performProbGreater0E(model, transitionMatrix, phiStates, psiStates) && model.getReachableStates();
1169}
1170
1171template<storm::dd::DdType Type, typename ValueType>
1173 storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates,
1174 storm::dd::Bdd<Type> const& psiStates) {
1175 // Initialize environment for backward search.
1176 storm::dd::DdManager<Type> const& manager = model.getManager();
1177 storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
1178 storm::dd::Bdd<Type> statesWithProbabilityGreater0A = psiStates;
1179
1180 while (lastIterationStates != statesWithProbabilityGreater0A) {
1181 lastIterationStates = statesWithProbabilityGreater0A;
1182 statesWithProbabilityGreater0A =
1183 statesWithProbabilityGreater0A.inverseRelationalProductWithExtendedRelation(transitionMatrix, model.getRowVariables(), model.getColumnVariables());
1184 statesWithProbabilityGreater0A |= model.getIllegalMask();
1185 statesWithProbabilityGreater0A = statesWithProbabilityGreater0A.universalAbstract(model.getNondeterminismVariables());
1186 statesWithProbabilityGreater0A &= phiStates;
1187 statesWithProbabilityGreater0A |= psiStates;
1188 }
1189
1190 return statesWithProbabilityGreater0A;
1191}
1192
1193template<storm::dd::DdType Type, typename ValueType>
1195 storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
1196 return !performProbGreater0A(model, transitionMatrix, phiStates, psiStates) && model.getReachableStates();
1197}
1198
1199template<storm::dd::DdType Type, typename ValueType>
1201 storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbabilityGreater0A) {
1202 // Initialize environment for backward search.
1203 storm::dd::DdManager<Type> const& manager = model.getManager();
1204 storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
1205 storm::dd::Bdd<Type> statesWithProbability1A = psiStates || statesWithProbabilityGreater0A;
1206
1207 while (lastIterationStates != statesWithProbability1A) {
1208 lastIterationStates = statesWithProbability1A;
1209 statesWithProbability1A = statesWithProbability1A.swapVariables(model.getRowColumnMetaVariablePairs());
1210 statesWithProbability1A = transitionMatrix.implies(statesWithProbability1A).universalAbstract(model.getColumnVariables());
1211 statesWithProbability1A |= model.getIllegalMask();
1212 statesWithProbability1A = statesWithProbability1A.universalAbstract(model.getNondeterminismVariables());
1213 statesWithProbability1A &= statesWithProbabilityGreater0A;
1214 statesWithProbability1A |= psiStates;
1215 }
1216
1217 return statesWithProbability1A;
1218}
1219
1220template<storm::dd::DdType Type, typename ValueType>
1222 storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates,
1223 storm::dd::Bdd<Type> const& statesWithProbabilityGreater0E) {
1224 // Initialize environment for backward search.
1225 storm::dd::DdManager<Type> const& manager = model.getManager();
1226 storm::dd::Bdd<Type> statesWithProbability1E = statesWithProbabilityGreater0E;
1227
1228 bool outerLoopDone = false;
1229 while (!outerLoopDone) {
1230 storm::dd::Bdd<Type> innerStates = manager.getBddZero();
1231
1232 bool innerLoopDone = false;
1233 while (!innerLoopDone) {
1234 storm::dd::Bdd<Type> temporary = statesWithProbability1E.swapVariables(model.getRowColumnMetaVariablePairs());
1235 temporary = transitionMatrix.implies(temporary).universalAbstract(model.getColumnVariables());
1236
1237 storm::dd::Bdd<Type> temporary2 =
1238 innerStates.inverseRelationalProductWithExtendedRelation(transitionMatrix, model.getRowVariables(), model.getColumnVariables());
1239
1240 temporary = temporary.andExists(temporary2, model.getNondeterminismVariables());
1241 temporary &= phiStates;
1242 temporary |= psiStates;
1243
1244 if (innerStates == temporary) {
1245 innerLoopDone = true;
1246 } else {
1247 innerStates = temporary;
1248 }
1249 }
1250
1251 if (statesWithProbability1E == innerStates) {
1252 outerLoopDone = true;
1253 } else {
1254 statesWithProbability1E = innerStates;
1255 }
1256 }
1257
1258 return statesWithProbability1E;
1259}
1260
1261template<storm::dd::DdType Type, typename ValueType>
1263 storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates,
1264 storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbability1E) {
1265 // Initialize environment for backward search.
1266 storm::dd::DdManager<Type> const& manager = model.getManager();
1267 storm::dd::Bdd<Type> scheduler = manager.getBddZero();
1268
1269 storm::dd::Bdd<Type> innerStates = manager.getBddZero();
1270
1271 bool innerLoopDone = false;
1272 while (!innerLoopDone) {
1273 storm::dd::Bdd<Type> temporary = statesWithProbability1E.swapVariables(model.getRowColumnMetaVariablePairs());
1274 temporary = transitionMatrix.implies(temporary).universalAbstract(model.getColumnVariables());
1275
1276 storm::dd::Bdd<Type> temporary2 =
1277 innerStates.inverseRelationalProductWithExtendedRelation(transitionMatrix, model.getRowVariables(), model.getColumnVariables());
1278 temporary &= temporary2;
1279 temporary &= phiStates;
1280
1281 // Extend the scheduler for those states that have not been seen as inner states before.
1282 scheduler |= (temporary && !innerStates).existsAbstractRepresentative(model.getNondeterminismVariables());
1283
1284 temporary = temporary.existsAbstract(model.getNondeterminismVariables());
1285 temporary |= psiStates;
1286
1287 if (innerStates == temporary) {
1288 innerLoopDone = true;
1289 } else {
1290 innerStates = temporary;
1291 }
1292 }
1293
1294 return scheduler;
1295}
1296
1297template<storm::dd::DdType Type, typename ValueType>
1299 storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
1300 return performProb01Max(model, model.getTransitionMatrix().notZero(), phiStates, psiStates);
1301}
1302
1303template<storm::dd::DdType Type, typename ValueType>
1305 storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates,
1306 storm::dd::Bdd<Type> const& psiStates) {
1307 std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
1308 result.first = performProb0A(model, transitionMatrix, phiStates, psiStates);
1309 result.second = performProb1E(model, transitionMatrix, phiStates, psiStates, !result.first && model.getReachableStates());
1310 return result;
1311}
1312
1313template<storm::dd::DdType Type, typename ValueType>
1315 storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
1316 return performProb01Min(model, model.getTransitionMatrix().notZero(), phiStates, psiStates);
1317}
1318
1319template<storm::dd::DdType Type, typename ValueType>
1321 storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates,
1322 storm::dd::Bdd<Type> const& psiStates) {
1323 std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
1324 result.first = performProb0E(model, transitionMatrix, phiStates, psiStates);
1325 result.second = performProb1A(model, transitionMatrix, psiStates, !result.first && model.getReachableStates());
1326 return result;
1327}
1328
1329template<typename ValueType>
1330ExplicitGameProb01Result performProb0(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint64_t> const& player1Groups,
1331 storm::storage::SparseMatrix<ValueType> const& player1BackwardTransitions,
1332 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
1333 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
1334 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair) {
1335 ExplicitGameProb01Result result(psiStates, storm::storage::BitVector(transitionMatrix.getRowGroupCount()));
1336
1337 // Initialize the stack used for the DFS with the states
1338 std::vector<uint_fast64_t> stack(psiStates.begin(), psiStates.end());
1339
1340 // Perform the actual DFS.
1341 uint_fast64_t currentState;
1342 while (!stack.empty()) {
1343 currentState = stack.back();
1344 stack.pop_back();
1345
1346 // Check which player 2 predecessors of the current player 1 state to add.
1347 for (auto const& player2PredecessorEntry : player1BackwardTransitions.getRow(currentState)) {
1348 uint64_t player2Predecessor = player2PredecessorEntry.getColumn();
1349 if (!result.player2States.get(player2Predecessor)) {
1350 bool addPlayer2State = false;
1351 if (player2Direction == OptimizationDirection::Minimize) {
1352 bool allChoicesHavePlayer1State = true;
1353 for (uint64_t row = transitionMatrix.getRowGroupIndices()[player2Predecessor];
1354 row < transitionMatrix.getRowGroupIndices()[player2Predecessor + 1]; ++row) {
1355 bool choiceHasPlayer1State = false;
1356 for (auto const& entry : transitionMatrix.getRow(row)) {
1357 if (result.player1States.get(entry.getColumn())) {
1358 choiceHasPlayer1State = true;
1359 break;
1360 }
1361 }
1362 if (!choiceHasPlayer1State) {
1363 allChoicesHavePlayer1State = false;
1364 }
1365 }
1366 if (allChoicesHavePlayer1State) {
1367 addPlayer2State = true;
1368 }
1369 } else {
1370 addPlayer2State = true;
1371 }
1372
1373 if (addPlayer2State) {
1374 result.player2States.set(player2Predecessor);
1375
1376 // Now check whether adding the player 2 state changes something with respect to the
1377 // (single) player 1 predecessor.
1378 uint64_t player1Predecessor = player2BackwardTransitions[player2Predecessor];
1379
1380 if (!result.player1States.get(player1Predecessor)) {
1381 bool addPlayer1State = false;
1382 if (player1Direction == OptimizationDirection::Minimize) {
1383 bool allPlayer2Successors = true;
1384 for (uint64_t player2State = player1Groups[player1Predecessor]; player2State < player1Groups[player1Predecessor + 1];
1385 ++player2State) {
1386 if (!result.player2States.get(player2State)) {
1387 allPlayer2Successors = false;
1388 break;
1389 }
1390 }
1391 if (allPlayer2Successors) {
1392 addPlayer1State = true;
1393 }
1394 } else {
1395 addPlayer1State = true;
1396 }
1397
1398 if (addPlayer1State) {
1399 result.player1States.set(player1Predecessor);
1400 stack.emplace_back(player1Predecessor);
1401 }
1402 }
1403 }
1404 }
1405 }
1406 }
1407
1408 // Since we have determined the complements of the desired sets, we need to complement it now.
1409 result.player1States.complement();
1410 result.player2States.complement();
1411
1412 // Generate player 1 strategy if required.
1413 if (strategyPair) {
1414 for (uint64_t player1State : result.player1States) {
1415 if (player1Direction == storm::OptimizationDirection::Minimize) {
1416 // At least one player 2 successor is a state with probability 0, find it.
1417 [[maybe_unused]] bool foundProb0Successor = false;
1418 uint64_t player2State;
1419 for (player2State = player1Groups[player1State]; player2State < player1Groups[player1State + 1]; ++player2State) {
1420 if (result.player2States.get(player2State)) {
1421 foundProb0Successor = true;
1422 break;
1423 }
1424 }
1425 STORM_LOG_ASSERT(foundProb0Successor, "Expected at least one state 2 successor with probability 0.");
1426 strategyPair->getPlayer1Strategy().setChoice(player1State, player2State);
1427 } else {
1428 // Since all player 2 successors are states with probability 0, just pick any.
1429 strategyPair->getPlayer1Strategy().setChoice(player1State, player1Groups[player1State]);
1430 }
1431 }
1432 }
1433
1434 // Generate player 2 strategy if required.
1435 if (strategyPair) {
1436 for (uint64_t player2State : result.player2States) {
1437 if (player2Direction == storm::OptimizationDirection::Minimize) {
1438 // At least one distribution only has successors with probability 0, find it.
1439 [[maybe_unused]] bool foundProb0SuccessorDistribution = false;
1440
1441 uint64_t row;
1442 for (row = transitionMatrix.getRowGroupIndices()[player2State]; row < transitionMatrix.getRowGroupIndices()[player2State + 1]; ++row) {
1443 bool distributionHasOnlyProb0Successors = true;
1444 for (auto const& player1SuccessorEntry : transitionMatrix.getRow(row)) {
1445 if (!result.player1States.get(player1SuccessorEntry.getColumn())) {
1446 distributionHasOnlyProb0Successors = false;
1447 break;
1448 }
1449 }
1450 if (distributionHasOnlyProb0Successors) {
1451 foundProb0SuccessorDistribution = true;
1452 break;
1453 }
1454 }
1455
1456 STORM_LOG_ASSERT(foundProb0SuccessorDistribution, "Expected at least one distribution with only successors with probability 0.");
1457 strategyPair->getPlayer2Strategy().setChoice(player2State, row);
1458 } else {
1459 // Since all player 1 successors are states with probability 0, just pick any.
1460 strategyPair->getPlayer2Strategy().setChoice(player2State, transitionMatrix.getRowGroupIndices()[player2State]);
1461 }
1462 }
1463 }
1464
1465 return result;
1466}
1467
1468template<storm::dd::DdType Type, typename ValueType>
1470 storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates,
1471 storm::dd::Bdd<Type> const& psiStates, storm::OptimizationDirection const& player1Strategy,
1472 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy) {
1473 // The solution sets.
1474 storm::dd::Bdd<Type> player1States = psiStates;
1475 storm::dd::Bdd<Type> player2States = model.getManager().getBddZero();
1476
1477 bool done = false;
1478 while (!done) {
1480 (transitionMatrix && player1States.swapVariables(model.getRowColumnMetaVariablePairs())).existsAbstract(model.getColumnVariables()) && phiStates;
1481
1482 if (player2Strategy == OptimizationDirection::Minimize) {
1483 tmp = (tmp || model.getIllegalPlayer2Mask()).universalAbstract(model.getPlayer2Variables());
1484 } else {
1485 tmp = tmp.existsAbstract(model.getPlayer2Variables());
1486 }
1487 player2States |= tmp;
1488
1489 if (player1Strategy == OptimizationDirection::Minimize) {
1490 tmp = (tmp || model.getIllegalPlayer1Mask()).universalAbstract(model.getPlayer1Variables());
1491 } else {
1492 tmp = tmp.existsAbstract(model.getPlayer1Variables());
1493 }
1494
1495 // Re-add all previous player 1 states.
1496 tmp |= player1States;
1497
1498 if (tmp == player1States) {
1499 done = true;
1500 }
1501
1502 player1States = tmp;
1503 }
1504
1505 // Since we have determined the complements of the desired sets, we need to complement it now.
1506 player1States = !player1States && model.getReachableStates();
1507
1508 std::set<storm::expressions::Variable> variablesToAbstract(model.getColumnVariables());
1509 variablesToAbstract.insert(model.getPlayer2Variables().begin(), model.getPlayer2Variables().end());
1510 player2States = !player2States && transitionMatrix.existsAbstract(variablesToAbstract);
1511
1512 // Determine all transitions between prob0 states.
1513 storm::dd::Bdd<Type> transitionsBetweenProb0States =
1514 player2States && (transitionMatrix && player1States.swapVariables(model.getRowColumnMetaVariablePairs()));
1515
1516 // Determine the distributions that have only successors that are prob0 states.
1517 storm::dd::Bdd<Type> onlyProb0Successors = (transitionsBetweenProb0States || model.getIllegalSuccessorMask()).universalAbstract(model.getColumnVariables());
1518
1519 boost::optional<storm::dd::Bdd<Type>> player2StrategyBdd;
1520 if (producePlayer2Strategy) {
1521 // Pick a distribution that has only prob0 successors.
1522 player2StrategyBdd = onlyProb0Successors.existsAbstractRepresentative(model.getPlayer2Variables());
1523 }
1524
1525 boost::optional<storm::dd::Bdd<Type>> player1StrategyBdd;
1526 if (producePlayer1Strategy) {
1527 // Move from player 2 choices with only prob0 successors to player 1 choices with only prob 0 successors.
1528 onlyProb0Successors = (player1States && onlyProb0Successors).existsAbstract(model.getPlayer2Variables());
1529
1530 // Pick a prob0 player 2 state.
1531 player1StrategyBdd = onlyProb0Successors.existsAbstractRepresentative(model.getPlayer1Variables());
1532 }
1533
1534 return SymbolicGameProb01Result<Type>(player1States, player2States, player1StrategyBdd, player2StrategyBdd);
1535}
1536
1537template<typename ValueType>
1538ExplicitGameProb01Result performProb1(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint64_t> const& player1Groups,
1539 storm::storage::SparseMatrix<ValueType> const& player1BackwardTransitions,
1540 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
1541 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
1542 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair,
1543 boost::optional<storm::storage::BitVector> const& player1Candidates) {
1544 // During the execution, the two state sets in the result hold the potential player 1/2 states.
1546 if (player1Candidates) {
1547 result = ExplicitGameProb01Result(player1Candidates.get(), storm::storage::BitVector(transitionMatrix.getRowGroupCount()));
1548 } else {
1550 }
1551
1552 // A flag that governs whether strategies are produced in the current iteration.
1553 bool produceStrategiesInIteration = false;
1554
1555 // Initialize the stack used for the DFS with the states
1556 std::vector<uint_fast64_t> stack;
1557 bool maybeStatesDone = false;
1558 while (!maybeStatesDone || produceStrategiesInIteration) {
1559 storm::storage::BitVector player1Solution = psiStates;
1560 storm::storage::BitVector player2Solution(result.player2States.size());
1561
1562 stack.clear();
1563 stack.insert(stack.end(), psiStates.begin(), psiStates.end());
1564
1565 // Perform the actual DFS.
1566 uint_fast64_t currentState;
1567 while (!stack.empty()) {
1568 currentState = stack.back();
1569 stack.pop_back();
1570
1571 for (auto player2PredecessorEntry : player1BackwardTransitions.getRow(currentState)) {
1572 uint64_t player2Predecessor = player2PredecessorEntry.getColumn();
1573 if (!player2Solution.get(player2PredecessorEntry.getColumn())) {
1574 bool addPlayer2State = player2Direction == storm::OptimizationDirection::Minimize;
1575
1576 uint64_t validChoice = transitionMatrix.getRowGroupIndices()[player2Predecessor];
1577 for (uint64_t row = validChoice; row < transitionMatrix.getRowGroupIndices()[player2Predecessor + 1]; ++row) {
1578 bool choiceHasSolutionSuccessor = false;
1579 bool choiceStaysInMaybeStates = true;
1580 for (auto const& entry : transitionMatrix.getRow(row)) {
1581 if (player1Solution.get(entry.getColumn())) {
1582 choiceHasSolutionSuccessor = true;
1583 }
1584 if (!result.player1States.get(entry.getColumn())) {
1585 choiceStaysInMaybeStates = false;
1586 break;
1587 }
1588 }
1589
1590 if (choiceHasSolutionSuccessor && choiceStaysInMaybeStates) {
1591 if (player2Direction == storm::OptimizationDirection::Maximize) {
1592 validChoice = row;
1593 addPlayer2State = true;
1594 break;
1595 }
1596 } else if (player2Direction == storm::OptimizationDirection::Minimize) {
1597 addPlayer2State = false;
1598 break;
1599 }
1600 }
1601
1602 if (addPlayer2State) {
1603 player2Solution.set(player2Predecessor);
1604 if (produceStrategiesInIteration) {
1605 strategyPair->getPlayer2Strategy().setChoice(player2Predecessor, validChoice);
1606 }
1607
1608 // Check whether the addition of the player 2 state changes the state of the (single)
1609 // player 1 predecessor.
1610 uint64_t player1Predecessor = player2BackwardTransitions[player2Predecessor];
1611
1612 if (!player1Solution.get(player1Predecessor)) {
1613 bool addPlayer1State = player1Direction == storm::OptimizationDirection::Minimize;
1614
1615 validChoice = player1Groups[player1Predecessor];
1616 for (uint64_t player2Successor = validChoice; player2Successor < player1Groups[player1Predecessor + 1]; ++player2Successor) {
1617 if (player2Solution.get(player2Successor)) {
1618 if (player1Direction == storm::OptimizationDirection::Maximize) {
1619 validChoice = player2Successor;
1620 addPlayer1State = true;
1621 break;
1622 }
1623 } else if (player1Direction == storm::OptimizationDirection::Minimize) {
1624 addPlayer1State = false;
1625 break;
1626 }
1627 }
1628
1629 if (addPlayer1State) {
1630 player1Solution.set(player1Predecessor);
1631
1632 if (produceStrategiesInIteration) {
1633 strategyPair->getPlayer1Strategy().setChoice(player1Predecessor, validChoice);
1634 }
1635
1636 stack.emplace_back(player1Predecessor);
1637 }
1638 }
1639 }
1640 }
1641 }
1642 }
1643
1644 if (result.player1States == player1Solution) {
1645 maybeStatesDone = true;
1646 result.player2States = player2Solution;
1647
1648 // If we were asked to produce strategies, we propagate that by triggering another iteration.
1649 // We only do this if at least one strategy will be produced.
1650 produceStrategiesInIteration = !produceStrategiesInIteration && strategyPair;
1651 } else {
1652 result.player1States = player1Solution;
1653 result.player2States = player2Solution;
1654 }
1655 }
1656
1657 return result;
1658}
1659
1660template<storm::dd::DdType Type, typename ValueType>
1662 storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates,
1663 storm::dd::Bdd<Type> const& psiStates, storm::OptimizationDirection const& player1Strategy,
1664 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy,
1665 boost::optional<storm::dd::Bdd<Type>> const& player1Candidates) {
1666 // Create the potential prob1 states of player 1.
1667 storm::dd::Bdd<Type> maybePlayer1States = model.getReachableStates();
1668 if (player1Candidates) {
1669 maybePlayer1States &= player1Candidates.get();
1670 }
1671
1672 // Initialize potential prob1 states of player 2.
1673 storm::dd::Bdd<Type> maybePlayer2States = model.getManager().getBddZero();
1674
1675 // A flag that governs whether strategies are produced in the current iteration.
1676 bool produceStrategiesInIteration = false;
1677 boost::optional<storm::dd::Bdd<Type>> player1StrategyBdd;
1678 boost::optional<storm::dd::Bdd<Type>> consideredPlayer1States;
1679 boost::optional<storm::dd::Bdd<Type>> player2StrategyBdd;
1680 boost::optional<storm::dd::Bdd<Type>> consideredPlayer2States;
1681
1682 bool maybeStatesDone = false;
1683 while (!maybeStatesDone || produceStrategiesInIteration) {
1684 bool solutionStatesDone = false;
1685
1686 // If we are to produce strategies in this iteration, we prepare some storage.
1687 if (produceStrategiesInIteration) {
1688 if (player1Strategy == storm::OptimizationDirection::Maximize) {
1689 player1StrategyBdd = model.getManager().getBddZero();
1690 consideredPlayer1States = model.getManager().getBddZero();
1691 }
1692 if (player2Strategy == storm::OptimizationDirection::Maximize) {
1693 player2StrategyBdd = model.getManager().getBddZero();
1694 consideredPlayer2States = model.getManager().getBddZero();
1695 }
1696 }
1697
1698 storm::dd::Bdd<Type> player1Solution = psiStates;
1699 storm::dd::Bdd<Type> player2Solution = model.getManager().getBddZero();
1700 while (!solutionStatesDone) {
1701 // Start by computing the transitions that have only maybe states as successors. Note that at
1702 // this point, there may be illegal transitions.
1703 storm::dd::Bdd<Type> distributionsStayingInMaybe =
1704 (!transitionMatrix || maybePlayer1States.swapVariables(model.getRowColumnMetaVariablePairs())).universalAbstract(model.getColumnVariables());
1705
1706 // Then, determine all distributions that have at least one successor in the states that have
1707 // probability 1.
1708 storm::dd::Bdd<Type> distributionsWithProb1Successor =
1709 (transitionMatrix && player1Solution.swapVariables(model.getRowColumnMetaVariablePairs())).existsAbstract(model.getColumnVariables());
1710
1711 // The valid distributions are then those that emanate from phi states, stay completely in the
1712 // maybe states and have at least one successor with probability 1.
1713 storm::dd::Bdd<Type> valid = phiStates && distributionsStayingInMaybe && distributionsWithProb1Successor;
1714
1715 // Depending on the strategy of player 2, we need to check whether all choices are valid or
1716 // there exists a valid choice.
1717 if (player2Strategy == OptimizationDirection::Minimize) {
1718 valid = (valid || model.getIllegalPlayer2Mask()).universalAbstract(model.getPlayer2Variables());
1719 } else {
1720 if (produceStrategiesInIteration) {
1721 storm::dd::Bdd<Type> newValidDistributions = valid && !consideredPlayer2States.get();
1722 player2StrategyBdd.get() = player2StrategyBdd.get() || newValidDistributions.existsAbstractRepresentative(model.getPlayer2Variables());
1723 }
1724
1725 valid = valid.existsAbstract(model.getPlayer2Variables());
1726
1727 if (produceStrategiesInIteration) {
1728 consideredPlayer2States.get() |= valid;
1729 }
1730 }
1731
1732 player2Solution |= valid;
1733
1734 // And do the same for player 1.
1735 if (player1Strategy == OptimizationDirection::Minimize) {
1736 valid = (valid || model.getIllegalPlayer1Mask()).universalAbstract(model.getPlayer1Variables());
1737 } else {
1738 if (produceStrategiesInIteration) {
1739 storm::dd::Bdd<Type> newValidDistributions = valid && !consideredPlayer1States.get();
1740 player1StrategyBdd.get() = player1StrategyBdd.get() || newValidDistributions.existsAbstractRepresentative(model.getPlayer1Variables());
1741 }
1742
1743 valid = valid.existsAbstract(model.getPlayer1Variables());
1744
1745 if (produceStrategiesInIteration) {
1746 consideredPlayer1States.get() |= valid;
1747 }
1748 }
1749
1750 // Explicitly add psi states to result since they may have transitions going to some state that
1751 // does not have a reachability probability of 1.
1752 valid |= psiStates;
1753
1754 // If no new states were added, we have found the current hypothesis for the states with
1755 // probability 1.
1756 if (valid == player1Solution) {
1757 solutionStatesDone = true;
1758 } else {
1759 player1Solution = valid;
1760 }
1761 }
1762
1763 // If the states with probability 1 and the potential probability 1 states coincide, we have found
1764 // the solution.
1765 if (player1Solution == maybePlayer1States) {
1766 maybePlayer2States = player2Solution;
1767 maybeStatesDone = true;
1768
1769 // If we were asked to produce strategies, we propagate that by triggering another iteration.
1770 // We only do this if at least one strategy will be produced.
1771 produceStrategiesInIteration = !produceStrategiesInIteration && ((producePlayer1Strategy && player1Strategy == OptimizationDirection::Maximize) ||
1772 (producePlayer2Strategy && player2Strategy == OptimizationDirection::Maximize));
1773 } else {
1774 // Otherwise, we use the current hypothesis for the states with probability 1 as the new maybe
1775 // state set.
1776 maybePlayer1States = player1Solution;
1777 }
1778 }
1779
1780 // From now on, the solution is stored in maybeStates (as it coincides with the previous solution).
1781
1782 // If we were asked to produce strategies that do not need to pick a certain successor but are
1783 // 'arbitrary', do so now.
1784 bool strategiesToCompute = (producePlayer1Strategy && !player1StrategyBdd) || (producePlayer2Strategy && !player2StrategyBdd);
1785 if (strategiesToCompute) {
1786 storm::dd::Bdd<Type> relevantStates = (transitionMatrix && maybePlayer2States).existsAbstract(model.getColumnVariables());
1787 if (producePlayer2Strategy && !player2StrategyBdd) {
1788 player2StrategyBdd = relevantStates.existsAbstractRepresentative(model.getPlayer2Variables());
1789 }
1790 if (producePlayer1Strategy && !player1StrategyBdd) {
1791 relevantStates = (maybePlayer1States && relevantStates).existsAbstract(model.getPlayer2Variables());
1792 player1StrategyBdd = relevantStates.existsAbstractRepresentative(model.getPlayer1Variables());
1793 }
1794 }
1795
1796 return SymbolicGameProb01Result<Type>(maybePlayer1States, maybePlayer2States, player1StrategyBdd, player2StrategyBdd);
1797}
1798
1799template<typename T>
1800void topologicalSortHelper(storm::storage::SparseMatrix<T> const& matrix, uint64_t state, std::vector<uint_fast64_t>& topologicalSort,
1801 std::vector<uint_fast64_t>& recursionStack,
1802 std::vector<typename storm::storage::SparseMatrix<T>::const_iterator>& iteratorRecursionStack,
1803 storm::storage::BitVector& visitedStates) {
1804 if (!visitedStates.get(state)) {
1805 recursionStack.push_back(state);
1806 iteratorRecursionStack.push_back(matrix.begin(state));
1807
1808 recursionStepForward:
1809 while (!recursionStack.empty()) {
1810 uint_fast64_t currentState = recursionStack.back();
1811 typename storm::storage::SparseMatrix<T>::const_iterator successorIterator = iteratorRecursionStack.back();
1812
1813 visitedStates.set(currentState, true);
1814
1815 recursionStepBackward:
1816 for (; successorIterator != matrix.end(currentState); ++successorIterator) {
1817 if (!visitedStates.get(successorIterator->getColumn())) {
1818 // Put unvisited successor on top of our recursion stack and remember that.
1819 recursionStack.push_back(successorIterator->getColumn());
1820
1821 // Also, put initial value for iterator on corresponding recursion stack.
1822 iteratorRecursionStack.push_back(matrix.begin(successorIterator->getColumn()));
1823
1824 goto recursionStepForward;
1825 }
1826 }
1827
1828 topologicalSort.push_back(currentState);
1829
1830 // If we reach this point, we have completed the recursive descent for the current state.
1831 // That is, we need to pop it from the recursion stacks.
1832 recursionStack.pop_back();
1833 iteratorRecursionStack.pop_back();
1834
1835 // If there is at least one state under the current one in our recursion stack, we need
1836 // to restore the topmost state as the current state and jump to the part after the
1837 // original recursive call.
1838 if (recursionStack.size() > 0) {
1839 currentState = recursionStack.back();
1840 successorIterator = iteratorRecursionStack.back();
1841
1842 goto recursionStepBackward;
1843 }
1844 }
1845 }
1846}
1847
1848template<typename T>
1849std::vector<uint_fast64_t> getBFSSort(storm::storage::SparseMatrix<T> const& matrix, std::vector<uint_fast64_t> const& firstStates) {
1850 storm::storage::BitVector seenStates(matrix.getRowGroupCount());
1851
1852 std::vector<uint_fast64_t> stateQueue;
1853 stateQueue.reserve(matrix.getRowGroupCount());
1854 std::vector<uint_fast64_t> result;
1855 result.reserve(matrix.getRowGroupCount());
1856
1857 // storm::storage::sparse::state_type currentPosition = 0;
1858 auto count = matrix.getRowGroupCount() - 1;
1859 for (auto const& state : firstStates) {
1860 stateQueue.push_back(state);
1861 result[count] = state;
1862 count--;
1863 }
1864
1865 // Perform a BFS.
1866 while (!stateQueue.empty()) {
1867 auto state = stateQueue.back();
1868 stateQueue.pop_back();
1869 seenStates.set(state);
1870 for (auto const& successorEntry : matrix.getRowGroup(state)) {
1871 auto succ = successorEntry.geColumn();
1872 if (!seenStates[succ]) {
1873 result[count] = succ;
1874 count--;
1875 stateQueue.insert(stateQueue.begin(), succ);
1876 }
1877 }
1878 }
1879 return result;
1880}
1881
1882template<typename T>
1883std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<T> const& matrix, std::vector<uint64_t> const& firstStates) {
1884 STORM_LOG_THROW(matrix.getRowCount() == matrix.getColumnCount(), storm::exceptions::InvalidArgumentException, "Provided matrix is required to be square.");
1885
1886 uint_fast64_t numberOfStates = matrix.getRowCount();
1887
1888 // Prepare the result. This relies on the matrix being square.
1889 std::vector<uint_fast64_t> topologicalSort;
1890 topologicalSort.reserve(numberOfStates);
1891
1892 // Prepare the stacks needed for recursion.
1893 std::vector<uint_fast64_t> recursionStack;
1894 recursionStack.reserve(matrix.getRowCount());
1895 std::vector<typename storm::storage::SparseMatrix<T>::const_iterator> iteratorRecursionStack;
1896 iteratorRecursionStack.reserve(numberOfStates);
1897
1898 // Perform a depth-first search over the given transitions and record states in the reverse order they were visited.
1899 storm::storage::BitVector visitedStates(numberOfStates);
1900 for (auto const state : firstStates) {
1901 topologicalSortHelper<T>(matrix, state, topologicalSort, recursionStack, iteratorRecursionStack, visitedStates);
1902 }
1903 for (uint_fast64_t state = 0; state < numberOfStates; ++state) {
1904 topologicalSortHelper<T>(matrix, state, topologicalSort, recursionStack, iteratorRecursionStack, visitedStates);
1905 }
1906
1907 return topologicalSort;
1908}
1909
1911 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates,
1912 storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps,
1913 boost::optional<storm::storage::BitVector> const& choiceFilter);
1914
1916
1917template bool hasCycle(storm::storage::SparseMatrix<double> const& transitionMatrix, boost::optional<storm::storage::BitVector> const& subsystem);
1918
1920 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& subsystem,
1921 storm::storage::BitVector const& choices);
1922
1923template std::vector<uint_fast64_t> getDistances(storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::BitVector const& initialStates,
1924 boost::optional<storm::storage::BitVector> const& subsystem);
1925
1927 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
1928 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
1929
1931 storm::storage::BitVector const& psiStates, storm::storage::BitVector const& statesWithProbabilityGreater0);
1932
1934 storm::storage::BitVector const& psiStates);
1935
1936template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::models::sparse::DeterministicModel<double> const& model,
1937 storm::storage::BitVector const& phiStates,
1938 storm::storage::BitVector const& psiStates);
1939
1940template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::storage::SparseMatrix<double> const& backwardTransitions,
1941 storm::storage::BitVector const& phiStates,
1942 storm::storage::BitVector const& psiStates);
1943
1945 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates,
1947 boost::optional<storm::storage::BitVector> const& rowFilter);
1948
1949template void computeSchedulerProb0E(storm::storage::BitVector const& prob0EStates, storm::storage::SparseMatrix<double> const& transitionMatrix,
1951
1952template void computeSchedulerRewInf(storm::storage::BitVector const& rewInfStates, storm::storage::SparseMatrix<double> const& transitionMatrix,
1953 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::Scheduler<double>& scheduler);
1954
1955template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<double> const& transitionMatrix,
1956 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates,
1958 boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
1959
1961 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
1962 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
1963
1965 storm::storage::BitVector const& psiStates);
1966
1968 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
1969 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates,
1970 storm::storage::BitVector const& psiStates,
1971 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
1972
1975 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
1976
1977template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(storm::storage::SparseMatrix<double> const& transitionMatrix,
1978 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
1979 storm::storage::SparseMatrix<double> const& backwardTransitions,
1980 storm::storage::BitVector const& phiStates,
1981 storm::storage::BitVector const& psiStates);
1982
1983template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
1985 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
1986
1988 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
1989 storm::storage::SparseMatrix<double> const& backwardTransitions,
1990 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
1991 bool useStepBound = false, uint_fast64_t maximalSteps = 0,
1992 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
1993
1996 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
1999 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2002 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2003 storm::storage::BitVector const& psiStates);
2005 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2006 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2007 storm::storage::BitVector const& psiStates);
2008
2011 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2014 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2017 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2018 storm::storage::BitVector const& psiStates);
2021 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2022 storm::storage::BitVector const& psiStates);
2024 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2025 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2026 storm::storage::BitVector const& psiStates);
2027
2028template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::storage::SparseMatrix<double> const& transitionMatrix,
2029 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2030 storm::storage::SparseMatrix<double> const& backwardTransitions,
2031 storm::storage::BitVector const& phiStates,
2032 storm::storage::BitVector const& psiStates);
2033
2034template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2036 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2037template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2039 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2040
2041template ExplicitGameProb01Result performProb0(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<uint64_t> const& player1RowGrouping,
2042 storm::storage::SparseMatrix<double> const& player1BackwardTransitions,
2043 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2044 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2045 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair);
2046
2047template ExplicitGameProb01Result performProb1(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<uint64_t> const& player1RowGrouping,
2048 storm::storage::SparseMatrix<double> const& player1BackwardTransitions,
2049 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2050 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2051 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair,
2052 boost::optional<storm::storage::BitVector> const& player1Candidates);
2053
2054template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<double> const& matrix, std::vector<uint64_t> const& firstStates);
2055
2056// Instantiations for storm::RationalNumber.
2058 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates,
2059 storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps,
2060 boost::optional<storm::storage::BitVector> const& choiceFilter);
2061
2063
2065 boost::optional<storm::storage::BitVector> const& subsystem);
2066
2068 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2069 storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices);
2070
2071template std::vector<uint_fast64_t> getDistances(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
2072 storm::storage::BitVector const& initialStates, boost::optional<storm::storage::BitVector> const& subsystem);
2073
2075 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2076 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2077
2079 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2080 storm::storage::BitVector const& statesWithProbabilityGreater0);
2081
2083 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2084
2085template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2087 storm::storage::BitVector const& psiStates);
2088
2089template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2090 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2091 storm::storage::BitVector const& psiStates);
2092
2094 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2095 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2097 boost::optional<storm::storage::BitVector> const& rowFilter);
2098
2101
2103 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2105
2107 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2109 boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
2110
2112 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2113 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2114
2116 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2117
2119 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2120 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2121 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2122 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2123
2125 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2126 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2127
2128template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2129 storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2130 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2131 storm::storage::BitVector const& psiStates);
2132
2133template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2135 storm::storage::BitVector const& psiStates);
2136
2138 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2139 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2140 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2141 bool useStepBound = false, uint_fast64_t maximalSteps = 0,
2142 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2143
2145 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2146 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2147
2149 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2150 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2151 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2152
2154 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2155 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2156 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2157
2158template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2159 storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2160 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2161 storm::storage::BitVector const& psiStates);
2162
2163template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2165 storm::storage::BitVector const& psiStates);
2166
2168 std::vector<uint64_t> const& player1RowGrouping,
2169 storm::storage::SparseMatrix<storm::RationalNumber> const& player1BackwardTransitions,
2170 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2171 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2172 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair);
2173
2175 std::vector<uint64_t> const& player1RowGrouping,
2176 storm::storage::SparseMatrix<storm::RationalNumber> const& player1BackwardTransitions,
2177 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2178 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2179 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair,
2180 boost::optional<storm::storage::BitVector> const& player1Candidates);
2181
2182template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::RationalNumber> const& matrix,
2183 std::vector<uint64_t> const& firstStates);
2184// End of instantiations for storm::RationalNumber.
2185// Instantiations for storm::interval
2186
2188 storm::storage::BitVector const& initialStates);
2189
2191 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates,
2192 storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps,
2193 boost::optional<storm::storage::BitVector> const& choiceFilter);
2194
2196
2197template bool hasCycle(storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix, boost::optional<storm::storage::BitVector> const& subsystem);
2198
2200 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::storage::BitVector const& subsystem,
2201 storm::storage::BitVector const& choices);
2202
2203template std::vector<uint_fast64_t> getDistances(storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
2204 storm::storage::BitVector const& initialStates, boost::optional<storm::storage::BitVector> const& subsystem);
2205
2207 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2208 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2209
2211 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2212 storm::storage::BitVector const& statesWithProbabilityGreater0);
2213
2215 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2216
2217template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::models::sparse::DeterministicModel<storm::Interval> const& model,
2218 storm::storage::BitVector const& phiStates,
2219 storm::storage::BitVector const& psiStates);
2220
2221template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2222 storm::storage::BitVector const& phiStates,
2223 storm::storage::BitVector const& psiStates);
2224
2226 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2227 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2228 storm::storage::Scheduler<double>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter);
2229
2232
2235
2237 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2239 boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
2240
2242 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2243 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2244
2246 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2247
2249 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2250 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2251 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2252 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2253
2255 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2256 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2257
2258template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2259 storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2260 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2261 storm::storage::BitVector const& psiStates);
2262
2263template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2265 storm::storage::BitVector const& psiStates);
2266
2268 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2269 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2270 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2271 bool useStepBound = false, uint_fast64_t maximalSteps = 0,
2272 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2273
2275 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2276 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2277
2279 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2280 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2281 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2282
2284 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2285 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2286 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2287
2288template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2289 storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2290 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2291 storm::storage::BitVector const& psiStates);
2292
2293template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2295 storm::storage::BitVector const& psiStates);
2296
2298 std::vector<uint64_t> const& player1RowGrouping,
2299 storm::storage::SparseMatrix<storm::Interval> const& player1BackwardTransitions,
2300 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2301 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2302 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair);
2303
2305 std::vector<uint64_t> const& player1RowGrouping,
2306 storm::storage::SparseMatrix<storm::Interval> const& player1BackwardTransitions,
2307 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2308 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2309 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair,
2310 boost::optional<storm::storage::BitVector> const& player1Candidates);
2311
2312template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::Interval> const& matrix, std::vector<uint64_t> const& firstStates);
2313// End storm::interval
2314// Instantiations for storm::Rationalinterval
2315
2317 storm::storage::BitVector const& initialStates);
2318
2320 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates,
2321 storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps,
2322 boost::optional<storm::storage::BitVector> const& choiceFilter);
2323
2325
2327 boost::optional<storm::storage::BitVector> const& subsystem);
2328
2331 storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices);
2332
2333template std::vector<uint_fast64_t> getDistances(storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix,
2334 storm::storage::BitVector const& initialStates, boost::optional<storm::storage::BitVector> const& subsystem);
2335
2337 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2338 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2339
2341 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2342 storm::storage::BitVector const& statesWithProbabilityGreater0);
2343
2345 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2346
2347template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2349 storm::storage::BitVector const& psiStates);
2350
2351template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2352 storm::storage::SparseMatrix<storm::RationalInterval> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2353 storm::storage::BitVector const& psiStates);
2354
2357 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2359 boost::optional<storm::storage::BitVector> const& rowFilter);
2360
2361template void computeSchedulerProb0E(storm::storage::BitVector const& prob0EStates,
2364
2365template void computeSchedulerRewInf(storm::storage::BitVector const& rewInfStates,
2369
2370template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates,
2373 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2375 boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
2376
2378 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2379 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2380
2382 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2383
2385 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2387 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2388 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2389
2392 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2393
2394template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2395 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2396 storm::storage::SparseMatrix<storm::RationalInterval> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2397 storm::storage::BitVector const& psiStates);
2398
2399template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2401 storm::storage::BitVector const& psiStates);
2402
2404 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2406 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2407 bool useStepBound = false, uint_fast64_t maximalSteps = 0,
2408 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2409
2412 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2413
2415 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2417 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2418
2420 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2422 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2423
2424template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2425 storm::storage::SparseMatrix<storm::RationalInterval> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2426 storm::storage::SparseMatrix<storm::RationalInterval> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2427 storm::storage::BitVector const& psiStates);
2428
2429template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2431 storm::storage::BitVector const& psiStates);
2432
2434 std::vector<uint64_t> const& player1RowGrouping,
2435 storm::storage::SparseMatrix<storm::RationalInterval> const& player1BackwardTransitions,
2436 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2437 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2438 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair);
2439
2441 std::vector<uint64_t> const& player1RowGrouping,
2442 storm::storage::SparseMatrix<storm::RationalInterval> const& player1BackwardTransitions,
2443 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2444 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2445 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair,
2446 boost::optional<storm::storage::BitVector> const& player1Candidates);
2447
2448template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::RationalInterval> const& matrix,
2449 std::vector<uint64_t> const& firstStates);
2450// End storm::Rationalinterval
2451
2453 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates,
2454 storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps,
2455 boost::optional<storm::storage::BitVector> const& choiceFilter);
2456
2458
2460 boost::optional<storm::storage::BitVector> const& subsystem);
2461
2464 storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices);
2465
2466template std::vector<uint_fast64_t> getDistances(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix,
2467 storm::storage::BitVector const& initialStates, boost::optional<storm::storage::BitVector> const& subsystem);
2468
2470 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2471 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2472
2474 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2475 storm::storage::BitVector const& statesWithProbabilityGreater0);
2476
2478 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2479
2480template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2482 storm::storage::BitVector const& psiStates);
2483
2484template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2485 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2486 storm::storage::BitVector const& psiStates);
2487
2488template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates,
2491 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2493 boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
2494
2496 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2497 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2498
2500 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2501
2503 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2505 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2506 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2507
2510 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2511
2512template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2513 storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2514 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2515 storm::storage::BitVector const& psiStates);
2516
2517template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2519 storm::storage::BitVector const& psiStates);
2520
2522 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2524 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2525 bool useStepBound = false, uint_fast64_t maximalSteps = 0,
2526 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2527
2530 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2532 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2534 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2535
2538 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2540 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2542 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2543
2544template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2545 storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2546 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2547 storm::storage::BitVector const& psiStates);
2548
2549template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2551 storm::storage::BitVector const& psiStates);
2552
2553template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::RationalFunction> const& matrix,
2554 std::vector<uint64_t> const& firstStates);
2555
2556// Instantiations for CUDD.
2557
2559 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2562 boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>());
2563
2565 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2568 storm::dd::Bdd<storm::dd::DdType::CUDD> const& statesWithProbabilityGreater0);
2569
2571 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2574
2575template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01(
2578
2579template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01(
2582
2587
2592
2594 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2597
2602
2604 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2607
2609 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2611 storm::dd::Bdd<storm::dd::DdType::CUDD> const& statesWithProbabilityGreater0A);
2612
2614 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2617 storm::dd::Bdd<storm::dd::DdType::CUDD> const& statesWithProbabilityGreater0E);
2618
2622 storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& statesWithProbability1E);
2623
2624template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01Max(
2627
2628template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01Max(
2632
2633template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01Min(
2636
2637template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01Min(
2641
2645 storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, storm::OptimizationDirection const& player1Strategy,
2646 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy);
2647
2651 storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, storm::OptimizationDirection const& player1Strategy,
2652 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy,
2653 boost::optional<storm::dd::Bdd<storm::dd::DdType::CUDD>> const& player1Candidates);
2654
2655// Instantiations for Sylvan (double).
2656
2658 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2661 boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>());
2662
2664 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2667 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0);
2668
2670 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2673
2674template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2677
2678template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2681
2686
2691
2693 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2696
2701
2703 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2706
2708 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2710 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0A);
2711
2713 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2716 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0E);
2717
2721 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbability1E);
2722
2723template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2726
2727template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2731
2732template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2735
2736template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2740
2744 storm::OptimizationDirection const& player1Strategy, storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy,
2745 bool producePlayer2Strategy);
2746
2750 storm::OptimizationDirection const& player1Strategy, storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy,
2751 bool producePlayer2Strategy, boost::optional<storm::dd::Bdd<storm::dd::DdType::Sylvan>> const& player1Candidates);
2752
2753// Instantiations for Sylvan (rational number).
2754
2758 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>());
2759
2761 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2764 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0);
2765
2767 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2770
2771template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2774
2775template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2779
2784
2789
2794
2799
2804
2808 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0A);
2809
2813 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0E);
2814
2818 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbability1E);
2819
2820template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2823
2824template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2828
2829template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2832
2833template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2837
2841 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::OptimizationDirection const& player1Strategy,
2842 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy);
2843
2847 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::OptimizationDirection const& player1Strategy,
2848 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy,
2849 boost::optional<storm::dd::Bdd<storm::dd::DdType::Sylvan>> const& player1Candidates);
2850
2851// Instantiations for Sylvan (rational function).
2852
2856 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>());
2857
2859 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2862 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0);
2863
2865 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2868
2869template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2872
2873template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2877
2882
2887
2892
2897
2902
2906 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0A);
2907
2911 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0E);
2912
2916 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbability1E);
2917
2918template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2921
2922template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2926
2927template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2930
2931template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2935
2936} // namespace graph
2937} // namespace utility
2938} // namespace storm
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
Bdd< LibraryType > existsAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Existentially abstracts from the given meta variables.
Definition Bdd.cpp:172
Bdd< LibraryType > inverseRelationalProduct(Bdd< LibraryType > const &relation, std::set< storm::expressions::Variable > const &rowMetaVariables, std::set< storm::expressions::Variable > const &columnMetaVariables) const
Computes the inverse relational product of the current BDD and the given BDD representing a relation.
Definition Bdd.cpp:240
bool isZero() const
Retrieves whether this DD represents the constant zero function.
Definition Bdd.cpp:541
Bdd< LibraryType > andExists(Bdd< LibraryType > const &other, std::set< storm::expressions::Variable > const &existentialVariables) const
Computes the logical and of the current and the given BDD and existentially abstracts from the given ...
Definition Bdd.cpp:190
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
Bdd< LibraryType > existsAbstractRepresentative(std::set< storm::expressions::Variable > const &metaVariables) const
Similar to existsAbstract, but does not abstract from the variables but rather picks a valuation of e...
Definition Bdd.cpp:178
Bdd< LibraryType > universalAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Universally abstracts from the given meta variables.
Definition Bdd.cpp:184
Bdd< LibraryType > inverseRelationalProductWithExtendedRelation(Bdd< LibraryType > const &relation, std::set< storm::expressions::Variable > const &rowMetaVariables, std::set< storm::expressions::Variable > const &columnMetaVariables) const
Computes the inverse relational product of the current BDD and the given BDD representing a relation ...
Definition Bdd.cpp:267
Bdd< LibraryType > implies(Bdd< LibraryType > const &other) const
Performs a logical implication of the current and the given BDD.
Definition Bdd.cpp:156
The base class of all sparse deterministic models.
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Definition Model.cpp:226
storm::storage::SparseMatrix< ValueType > getBackwardTransitions() const
Retrieves the backward transition relation of the model, i.e.
Definition Model.cpp:186
The base class of sparse nondeterministic models.
std::vector< uint_fast64_t > const & getNondeterministicChoiceIndices() const
Retrieves the vector indicating which matrix rows represent non-deterministic choices of a certain st...
Base class for all deterministic symbolic models.
Base class for all symbolic models.
Definition Model.h:42
storm::dd::DdManager< Type > & getManager() const
Retrieves the manager responsible for the DDs that represent this model.
Definition Model.cpp:89
storm::dd::Add< Type, ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Definition Model.cpp:174
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
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.
storm::dd::Bdd< Type > const & getIllegalMask() const
Retrieves a BDD characterizing all illegal nondeterminism encodings in the model.
storm::dd::Bdd< Type > getIllegalSuccessorMask() const
Retrieves a BDD characterizing the illegal successors for each choice.
This class represents a discrete-time stochastic two-player game.
std::set< storm::expressions::Variable > const & getPlayer1Variables() const
Retrieeves the set of meta variables used to encode the nondeterministic choices of player 1.
std::set< storm::expressions::Variable > const & getPlayer2Variables() const
Retrieeves the set of meta variables used to encode the nondeterministic choices of player 2.
storm::dd::Bdd< Type > getIllegalPlayer1Mask() const
Retrieves a BDD characterizing all illegal player 1 choice encodings in the model.
storm::dd::Bdd< Type > getIllegalPlayer2Mask() const
Retrieves a BDD characterizing all illegal player 2 choice encodings in the model.
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.
const_iterator end() const
Returns an iterator pointing at the element past the back of the bit vector.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
bool isSubsetOf(BitVector const &other) const
Checks whether all bits that are set in the current bit vector are also set in the given 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.
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
size_t size() const
Retrieves the number of bits this bit vector can store.
void resize(uint64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
void setChoice(uint64_t state, uint64_t choice)
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
uint_fast64_t getNumberOfMemoryStates() const
Retrieves the number of memory states this scheduler considers.
A class that holds a possibly non-square matrix in the compressed row storage format.
const_rows getRow(index_type row) const
Returns an object representing the given row.
const_iterator begin(index_type row) const
Retrieves an iterator that points to the beginning of the given row.
const_rows getRowGroup(index_type rowGroup) const
Returns an object representing the given row group.
const_iterator end(index_type row) const
Retrieves an iterator that points past the end of the given row.
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< MatrixEntry< index_type, value_type > >::const_iterator const_iterator
std::vector< index_type > const & getRowGroupIndices() const
Returns the grouping of rows of this matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
This class represents the decomposition of a graph-like structure into its strongly connected compone...
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
#define STORM_LOG_INFO_COND(cond, message)
Definition macros.h:61
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01(storm::models::sparse::DeterministicModel< T > const &model, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi i...
Definition graph.cpp:394
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 topologicalSortHelper(storm::storage::SparseMatrix< T > const &matrix, uint64_t state, std::vector< uint_fast64_t > &topologicalSort, std::vector< uint_fast64_t > &recursionStack, std::vector< typename storm::storage::SparseMatrix< T >::const_iterator > &iteratorRecursionStack, storm::storage::BitVector &visitedStates)
Definition graph.cpp:1800
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:484
ExplicitGameProb01Result performProb0(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< uint64_t > const &player1Groups, storm::storage::SparseMatrix< ValueType > const &player1BackwardTransitions, std::vector< uint64_t > const &player2BackwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, storm::OptimizationDirection const &player1Direction, storm::OptimizationDirection const &player2Direction, storm::storage::ExplicitGameStrategyPair *strategyPair)
Computes the set of states that have probability 0 given the strategies of the two players.
Definition graph.cpp:1330
std::vector< uint_fast64_t > getTopologicalSort(storm::storage::SparseMatrix< T > const &matrix, std::vector< uint64_t > const &firstStates)
Performs a topological sort of the states of the system according to the given transitions.
Definition graph.cpp:1883
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
std::vector< uint_fast64_t > getBFSSort(storm::storage::SparseMatrix< T > const &matrix, std::vector< uint_fast64_t > const &firstStates)
Definition graph.cpp:1849
storm::storage::BitVector getReachableStates(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &constraintStates, storm::storage::BitVector const &targetStates, bool useStepBound, uint_fast64_t maximalSteps, boost::optional< storm::storage::BitVector > const &choiceFilter)
Performs a forward depth-first search through the underlying graph structure to identify the states t...
Definition graph.cpp:42
storm::storage::BitVector getReachableOneStep(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::BitVector const &initialStates)
Computes the states reachable in one step from the states indicated by the bitvector.
Definition graph.cpp:30
storm::storage::BitVector performProbGreater0(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps)
Performs a backward depth-first search trough the underlying graph structure of the given model to de...
Definition graph.cpp:316
void computeSchedulerWithOneSuccessorInStates(storm::storage::BitVector const &states, storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::Scheduler< SchedulerValueType > &scheduler)
Definition graph.cpp:509
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
bool hasCycle(storm::storage::SparseMatrix< T > const &transitionMatrix, boost::optional< storm::storage::BitVector > const &subsystem)
Returns true if the graph represented by the given matrix has a cycle.
Definition graph.cpp:137
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 performProb0A(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Definition graph.cpp:732
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:377
bool checkIfECWithChoiceExists(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &subsystem, storm::storage::BitVector const &choices)
Checks whether there is an End Component that.
Definition graph.cpp:176
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
storm::storage::BitVector getBsccCover(storm::storage::SparseMatrix< T > const &transitionMatrix)
Retrieves a set of states that covers als BSCCs of the system in the sense that for every BSCC exactl...
Definition graph.cpp:123
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:587
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
std::vector< uint_fast64_t > getDistances(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::BitVector const &initialStates, boost::optional< storm::storage::BitVector > const &subsystem)
Performs a breadth-first search through the underlying graph structure to compute the distance from a...
Definition graph.cpp:282
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
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:593
bool isZero(ValueType const &a)
Definition constants.cpp:44
solver::OptimizationDirection OptimizationDirection
storm::storage::BitVector player2States
Definition graph.h:764
storm::storage::BitVector player1States
Definition graph.h:763