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