Storm 1.11.1.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 ? true : false;
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 ? true : false;
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);
1966 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
1967 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates,
1968 storm::storage::BitVector const& psiStates);
1969
1972 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
1975 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
1977 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
1978 storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates,
1979 storm::storage::BitVector const& psiStates);
1980
1981template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::storage::SparseMatrix<double> const& transitionMatrix,
1982 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
1983 storm::storage::SparseMatrix<double> const& backwardTransitions,
1984 storm::storage::BitVector const& phiStates,
1985 storm::storage::BitVector const& psiStates);
1986
1987template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
1989 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
1990template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
1992 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
1993
1994template ExplicitGameProb01Result performProb0(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<uint64_t> const& player1RowGrouping,
1995 storm::storage::SparseMatrix<double> const& player1BackwardTransitions,
1996 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
1997 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
1998 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair);
1999
2000template ExplicitGameProb01Result performProb1(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<uint64_t> const& player1RowGrouping,
2001 storm::storage::SparseMatrix<double> const& player1BackwardTransitions,
2002 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2003 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2004 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair,
2005 boost::optional<storm::storage::BitVector> const& player1Candidates);
2006
2007template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<double> const& matrix, std::vector<uint64_t> const& firstStates);
2008
2009// Instantiations for storm::RationalNumber.
2011 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates,
2012 storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps,
2013 boost::optional<storm::storage::BitVector> const& choiceFilter);
2014
2016
2018 boost::optional<storm::storage::BitVector> const& subsystem);
2019
2021 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2022 storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices);
2023
2024template std::vector<uint_fast64_t> getDistances(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix,
2025 storm::storage::BitVector const& initialStates, boost::optional<storm::storage::BitVector> const& subsystem);
2026
2028 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2029 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2030
2032 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2033 storm::storage::BitVector const& statesWithProbabilityGreater0);
2034
2036 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2037
2038template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2040 storm::storage::BitVector const& psiStates);
2041
2042template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2043 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2044 storm::storage::BitVector const& psiStates);
2045
2047 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2048 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2050 boost::optional<storm::storage::BitVector> const& rowFilter);
2051
2054
2056 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2058
2060 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2062 boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
2063
2065 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2066 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2067
2069 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2070
2072 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2073 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2074 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2075 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2076
2078 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2079 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2080
2081template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2082 storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2083 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2084 storm::storage::BitVector const& psiStates);
2085
2086template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2088 storm::storage::BitVector const& psiStates);
2089
2091 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2092 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2093 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2094 bool useStepBound = false, uint_fast64_t maximalSteps = 0,
2095 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2096
2098 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2099 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2100
2102 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2103 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2104 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2105
2107 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2108 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions,
2109 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2110
2111template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2112 storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2113 storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2114 storm::storage::BitVector const& psiStates);
2115
2116template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2118 storm::storage::BitVector const& psiStates);
2119
2121 std::vector<uint64_t> const& player1RowGrouping,
2122 storm::storage::SparseMatrix<storm::RationalNumber> const& player1BackwardTransitions,
2123 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2124 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2125 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair);
2126
2128 std::vector<uint64_t> const& player1RowGrouping,
2129 storm::storage::SparseMatrix<storm::RationalNumber> const& player1BackwardTransitions,
2130 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2131 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2132 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair,
2133 boost::optional<storm::storage::BitVector> const& player1Candidates);
2134
2135template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::RationalNumber> const& matrix,
2136 std::vector<uint64_t> const& firstStates);
2137// End of instantiations for storm::RationalNumber.
2138// Instantiations for storm::interval
2139
2141 storm::storage::BitVector const& initialStates);
2142
2144 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates,
2145 storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps,
2146 boost::optional<storm::storage::BitVector> const& choiceFilter);
2147
2149
2150template bool hasCycle(storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix, boost::optional<storm::storage::BitVector> const& subsystem);
2151
2153 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::storage::BitVector const& subsystem,
2154 storm::storage::BitVector const& choices);
2155
2156template std::vector<uint_fast64_t> getDistances(storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix,
2157 storm::storage::BitVector const& initialStates, boost::optional<storm::storage::BitVector> const& subsystem);
2158
2160 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2161 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2162
2164 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2165 storm::storage::BitVector const& statesWithProbabilityGreater0);
2166
2168 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2169
2170template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::models::sparse::DeterministicModel<storm::Interval> const& model,
2171 storm::storage::BitVector const& phiStates,
2172 storm::storage::BitVector const& psiStates);
2173
2174template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2175 storm::storage::BitVector const& phiStates,
2176 storm::storage::BitVector const& psiStates);
2177
2179 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2180 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2181 storm::storage::Scheduler<double>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter);
2182
2185
2188
2190 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2192 boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
2193
2195 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2196 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2197
2199 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2200
2202 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2203 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2204 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2205 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2206
2208 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2209 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2210
2211template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2212 storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2213 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2214 storm::storage::BitVector const& psiStates);
2215
2216template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2218 storm::storage::BitVector const& psiStates);
2219
2221 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2222 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2223 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2224 bool useStepBound = false, uint_fast64_t maximalSteps = 0,
2225 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2226
2228 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2229 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2230
2232 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2233 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2234 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2235
2237 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2238 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions,
2239 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2240
2241template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2242 storm::storage::SparseMatrix<storm::Interval> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2243 storm::storage::SparseMatrix<storm::Interval> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2244 storm::storage::BitVector const& psiStates);
2245
2246template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2248 storm::storage::BitVector const& psiStates);
2249
2251 std::vector<uint64_t> const& player1RowGrouping,
2252 storm::storage::SparseMatrix<storm::Interval> const& player1BackwardTransitions,
2253 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2254 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2255 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair);
2256
2258 std::vector<uint64_t> const& player1RowGrouping,
2259 storm::storage::SparseMatrix<storm::Interval> const& player1BackwardTransitions,
2260 std::vector<uint64_t> const& player2BackwardTransitions, storm::storage::BitVector const& phiStates,
2261 storm::storage::BitVector const& psiStates, storm::OptimizationDirection const& player1Direction,
2262 storm::OptimizationDirection const& player2Direction, storm::storage::ExplicitGameStrategyPair* strategyPair,
2263 boost::optional<storm::storage::BitVector> const& player1Candidates);
2264
2265template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::Interval> const& matrix, std::vector<uint64_t> const& firstStates);
2266// End storm::interval
2267
2269 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates,
2270 storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps,
2271 boost::optional<storm::storage::BitVector> const& choiceFilter);
2272
2274
2276 boost::optional<storm::storage::BitVector> const& subsystem);
2277
2280 storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices);
2281
2282template std::vector<uint_fast64_t> getDistances(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix,
2283 storm::storage::BitVector const& initialStates, boost::optional<storm::storage::BitVector> const& subsystem);
2284
2286 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2287 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2288
2290 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2291 storm::storage::BitVector const& statesWithProbabilityGreater0);
2292
2294 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2295
2296template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2298 storm::storage::BitVector const& psiStates);
2299
2300template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(
2301 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2302 storm::storage::BitVector const& psiStates);
2303
2304template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates,
2307 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2309 boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
2310
2312 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2313 bool useStepBound = false, uint_fast64_t maximalSteps = 0);
2314
2316 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2317
2319 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2321 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2322 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2323
2326 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2327
2328template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2329 storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2330 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2331 storm::storage::BitVector const& psiStates);
2332
2333template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(
2335 storm::storage::BitVector const& psiStates);
2336
2338 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2340 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
2341 bool useStepBound = false, uint_fast64_t maximalSteps = 0,
2342 boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none);
2343
2346 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2348 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2350 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2351
2354 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2356 std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2358 storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
2359
2360template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2361 storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices,
2362 storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates,
2363 storm::storage::BitVector const& psiStates);
2364
2365template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(
2367 storm::storage::BitVector const& psiStates);
2368
2369template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::RationalFunction> const& matrix,
2370 std::vector<uint64_t> const& firstStates);
2371
2372// Instantiations for CUDD.
2373
2375 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2378 boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>());
2379
2381 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2384 storm::dd::Bdd<storm::dd::DdType::CUDD> const& statesWithProbabilityGreater0);
2385
2387 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2390
2391template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01(
2394
2395template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01(
2398
2403
2408
2410 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2413
2418
2420 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2423
2425 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2427 storm::dd::Bdd<storm::dd::DdType::CUDD> const& statesWithProbabilityGreater0A);
2428
2430 storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitionMatrix,
2433 storm::dd::Bdd<storm::dd::DdType::CUDD> const& statesWithProbabilityGreater0E);
2434
2438 storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& statesWithProbability1E);
2439
2440template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01Max(
2443
2444template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01Max(
2448
2449template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01Min(
2452
2453template std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> performProb01Min(
2457
2461 storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, storm::OptimizationDirection const& player1Strategy,
2462 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy);
2463
2467 storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, storm::OptimizationDirection const& player1Strategy,
2468 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy,
2469 boost::optional<storm::dd::Bdd<storm::dd::DdType::CUDD>> const& player1Candidates);
2470
2471// Instantiations for Sylvan (double).
2472
2474 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2477 boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>());
2478
2480 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2483 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0);
2484
2486 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2489
2490template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2493
2494template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2497
2502
2507
2509 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2512
2517
2519 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2522
2524 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2526 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0A);
2527
2529 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2532 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0E);
2533
2537 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbability1E);
2538
2539template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2542
2543template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2547
2548template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2551
2552template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2556
2560 storm::OptimizationDirection const& player1Strategy, storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy,
2561 bool producePlayer2Strategy);
2562
2566 storm::OptimizationDirection const& player1Strategy, storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy,
2567 bool producePlayer2Strategy, boost::optional<storm::dd::Bdd<storm::dd::DdType::Sylvan>> const& player1Candidates);
2568
2569// Instantiations for Sylvan (rational number).
2570
2574 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>());
2575
2577 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2580 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0);
2581
2583 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2586
2587template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2590
2591template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2595
2600
2605
2610
2615
2620
2624 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0A);
2625
2629 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0E);
2630
2634 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbability1E);
2635
2636template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2639
2640template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2644
2645template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2648
2649template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2653
2657 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::OptimizationDirection const& player1Strategy,
2658 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy);
2659
2663 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::OptimizationDirection const& player1Strategy,
2664 storm::OptimizationDirection const& player2Strategy, bool producePlayer1Strategy, bool producePlayer2Strategy,
2665 boost::optional<storm::dd::Bdd<storm::dd::DdType::Sylvan>> const& player1Candidates);
2666
2667// Instantiations for Sylvan (rational function).
2668
2672 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>());
2673
2675 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2678 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0);
2679
2681 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitionMatrix,
2684
2685template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2688
2689template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01(
2693
2698
2703
2708
2713
2718
2722 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0A);
2723
2727 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbabilityGreater0E);
2728
2732 storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& statesWithProbability1E);
2733
2734template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2737
2738template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Max(
2742
2743template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2746
2747template std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, storm::dd::Bdd<storm::dd::DdType::Sylvan>> performProb01Min(
2751
2752} // namespace graph
2753} // namespace utility
2754} // 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:199
storm::storage::SparseMatrix< ValueType > getBackwardTransitions() const
Retrieves the backward transition relation of the model, i.e.
Definition Model.cpp:159
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:87
storm::dd::Add< Type, ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Definition Model.cpp:172
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:192
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:218
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:187
storm::dd::Bdd< Type > const & getReachableStates() const
Retrieves the reachable states of the model.
Definition Model.cpp:97
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:87
void setChoice(SchedulerChoice< ValueType > const &choice, uint_fast64_t modelState, uint_fast64_t memoryState=0)
Sets the choice defined by the scheduler for the given state.
Definition Scheduler.cpp:38
uint_fast64_t getNumberOfMemoryStates() const
Retrieves the number of memory states this scheduler considers.
A class that holds a possibly non-square matrix in the compressed row storage format.
const_rows getRow(index_type row) const
Returns an object representing the given row.
const_iterator begin(index_type row) const
Retrieves an iterator that points to the beginning of the given row.
const_rows getRowGroup(index_type rowGroup) const
Returns an object representing the given row group.
const_iterator end(index_type row) const
Retrieves an iterator that points past the end of the given row.
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
index_type getColumnCount() const
Returns the number of columns of the matrix.
std::vector< MatrixEntry< index_type, value_type > >::const_iterator const_iterator
std::vector< index_type > const & getRowGroupIndices() const
Returns the grouping of rows of this matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
This class represents the decomposition of a graph-like structure into its strongly connected compone...
#define STORM_LOG_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
storm::storage::BitVector player2States
Definition graph.h:764
storm::storage::BitVector player1States
Definition graph.h:763