Storm 1.13.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
Order.cpp
Go to the documentation of this file.
2
3#include <iostream>
4#include <queue>
5
7
8namespace storm {
9namespace analysis {
10Order::Order(storm::storage::BitVector const& topStates, storm::storage::BitVector const& bottomStates, uint_fast64_t numberOfStates,
11 storage::Decomposition<storage::StronglyConnectedComponent> decomposition, std::vector<uint_fast64_t> statesSorted) {
12 init(numberOfStates, decomposition);
13 this->numberOfAddedStates = 0;
14 this->onlyBottomTopOrder = true;
15 for (auto i : topStates) {
16 this->doneStates.set(i);
17 this->bottom->statesAbove.set(i);
18 this->top->states.insert(i);
19 this->nodes[i] = top;
20 numberOfAddedStates++;
21 }
22 this->statesSorted = statesSorted;
23
24 for (auto i : bottomStates) {
25 this->doneStates.set(i);
26 this->bottom->states.insert(i);
27 this->nodes[i] = bottom;
28 numberOfAddedStates++;
29 }
30 assert(numberOfAddedStates <= numberOfStates);
31 assert(doneStates.getNumberOfSetBits() == (topStates.getNumberOfSetBits() + bottomStates.getNumberOfSetBits()));
32 if (numberOfAddedStates == numberOfStates) {
33 doneBuilding = doneStates.full();
34 }
35}
36
37Order::Order(uint_fast64_t topState, uint_fast64_t bottomState, uint_fast64_t numberOfStates,
38 storage::Decomposition<storage::StronglyConnectedComponent> decomposition, std::vector<uint_fast64_t> statesSorted) {
39 init(numberOfStates, decomposition);
40
41 this->onlyBottomTopOrder = true;
42 this->doneStates.set(topState);
43
44 this->bottom->statesAbove.set(topState);
45 this->top->states.insert(topState);
46 this->nodes[topState] = top;
47
48 this->doneStates.set(bottomState);
49
50 this->bottom->states.insert(bottomState);
51 this->nodes[bottomState] = bottom;
52 this->numberOfAddedStates = 2;
53 assert(numberOfAddedStates <= numberOfStates);
54
55 this->statesSorted = statesSorted;
56 assert(doneStates.getNumberOfSetBits() == 2);
57 if (numberOfAddedStates == numberOfStates) {
58 doneBuilding = doneStates.full();
59 }
60}
61
63 this->invalid = false;
64}
65
66/*** Modifying the order ***/
67
68void Order::add(uint_fast64_t state) {
69 assert(nodes[state] == nullptr);
70 addBetween(state, top, bottom);
71 addStateToHandle(state);
72}
73
74void Order::addAbove(uint_fast64_t state, Node* node) {
75 STORM_LOG_INFO("Add " << state << " above " << *node->states.begin() << '\n');
76
77 assert(nodes[state] == nullptr);
78 Node* newNode = new Node();
79 nodes[state] = newNode;
80
81 newNode->states.insert(state);
82 newNode->statesAbove = storm::storage::BitVector(numberOfStates, false);
83 for (auto const& state : top->states) {
84 newNode->statesAbove.set(state);
85 }
86 node->statesAbove.set(state);
87 numberOfAddedStates++;
88 onlyBottomTopOrder = false;
89 if (numberOfAddedStates == numberOfStates) {
90 doneBuilding = doneStates.full();
91 }
92}
93
94void Order::addBelow(uint_fast64_t state, Node* node) {
95 STORM_LOG_INFO("Add " << state << " below " << *node->states.begin() << '\n');
96
97 assert(nodes[state] == nullptr);
98 Node* newNode = new Node();
99 nodes[state] = newNode;
100 newNode->states.insert(state);
102 for (auto statesAbove : node->states) {
103 newNode->statesAbove.set(statesAbove);
104 }
105 bottom->statesAbove.set(state);
106 numberOfAddedStates++;
107 onlyBottomTopOrder = false;
108 if (numberOfAddedStates == numberOfStates) {
109 doneBuilding = doneStates.full();
110 }
111 assert(numberOfAddedStates <= numberOfStates);
112}
113
114void Order::addBetween(uint_fast64_t state, Node* above, Node* below) {
115 STORM_LOG_INFO("Add " << state << " between (above) " << *above->states.begin() << " and " << *below->states.begin() << '\n');
116
117 assert(compare(above, below) == ABOVE);
118 assert(above != nullptr && below != nullptr);
119 if (nodes[state] == nullptr) {
120 // State is not in the order yet
121 Node* newNode = new Node();
122 nodes[state] = newNode;
123
124 newNode->states.insert(state);
125 newNode->statesAbove = storm::storage::BitVector(above->statesAbove);
126 for (auto aboveStates : above->states) {
127 newNode->statesAbove.set(aboveStates);
128 }
129 below->statesAbove.set(state);
130 numberOfAddedStates++;
131 onlyBottomTopOrder = false;
132 if (numberOfAddedStates == numberOfStates) {
133 doneBuilding = doneStates.full();
134 }
135 assert(numberOfAddedStates <= numberOfStates);
136 } else {
137 // State is in the order already, so we add the new relations
138 addRelationNodes(above, nodes[state]);
139 addRelationNodes(nodes[state], below);
140 }
141}
142
143void Order::addBetween(uint_fast64_t state, uint_fast64_t above, uint_fast64_t below) {
144 assert(compare(above, below) == ABOVE);
145 assert(getNode(below)->states.find(below) != getNode(below)->states.end());
146 assert(getNode(above)->states.find(above) != getNode(above)->states.end());
147
148 addBetween(state, getNode(above), getNode(below));
149}
150
151void Order::addRelation(uint_fast64_t above, uint_fast64_t below, bool allowMerge) {
152 assert(getNode(above) != nullptr && getNode(below) != nullptr);
153 addRelationNodes(getNode(above), getNode(below), allowMerge);
154}
155
156void Order::addRelationNodes(Order::Node* above, Order::Node* below, bool allowMerge) {
157 assert(allowMerge || compare(above, below) != BELOW);
158
159 STORM_LOG_INFO("Add relation between (above) " << *above->states.begin() << " and " << *below->states.begin() << '\n');
160
161 if (allowMerge) {
162 if (compare(below, above) == ABOVE) {
163 mergeNodes(above, below);
164 return;
165 }
166 }
167 below->statesAbove |= ((above->statesAbove));
168 for (auto const& state : above->states) {
169 below->statesAbove.set(state);
170 }
171 assert(compare(above, below) == ABOVE);
172}
173
174void Order::addToNode(uint_fast64_t state, Node* node) {
175 STORM_LOG_INFO("Add " << state << " to between (above) " << *node->states.begin() << '\n');
176
177 if (nodes[state] == nullptr) {
178 // State is not in the order yet
179 node->states.insert(state);
180 nodes[state] = node;
181 numberOfAddedStates++;
182 if (numberOfAddedStates == numberOfStates) {
183 doneBuilding = doneStates.full();
184 }
185 assert(numberOfAddedStates <= numberOfStates);
186
187 } else {
188 // State is in the order already, so we merge the nodes
189 mergeNodes(nodes[state], node);
190 }
191}
192
194 STORM_LOG_INFO("Merge " << *node1->states.begin() << " and " << *node2->states.begin() << '\n');
195
196 // Merges node2 into node 1
197 // everything above n2 also above n1
198 node1->statesAbove |= ((node2->statesAbove));
199 // add states of node 2 to node 1
200 node1->states.insert(node2->states.begin(), node2->states.end());
201
202 for (auto const& i : node2->states) {
203 nodes[i] = node1;
204 }
205
206 for (auto const& node : nodes) {
207 if (node != nullptr) {
208 for (auto state2 : node2->states) {
209 if (node->statesAbove[state2]) {
210 for (auto state1 : node1->states) {
211 node->statesAbove.set(state1);
212 }
213 break;
214 }
215 }
216 }
217 }
218 for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
219 for (uint_fast64_t j = i + 1; j < numberOfStates; ++j) {
220 auto comp1 = compare(i, j);
221 auto comp2 = compare(j, i);
222 if (!((comp1 == BELOW && comp2 == ABOVE) || (comp1 == ABOVE && comp2 == BELOW) || (comp1 == UNKNOWN && comp2 == UNKNOWN) ||
223 (comp1 == SAME && comp2 == SAME))) {
224 invalid = true;
225 return false;
226 }
227 }
228 }
229 return !invalid;
230}
231
232bool Order::merge(uint_fast64_t var1, uint_fast64_t var2) {
233 return mergeNodes(getNode(var1), getNode(var2));
234}
235
236/*** Checking on the order ***/
237
238Order::NodeComparison Order::compare(uint_fast64_t state1, uint_fast64_t state2, NodeComparison hypothesis) {
239 return compare(getNode(state1), getNode(state2), hypothesis);
240}
241
242Order::NodeComparison Order::compareFast(uint_fast64_t state1, uint_fast64_t state2, NodeComparison hypothesis) const {
243 auto res = compareFast(getNode(state1), getNode(state2), hypothesis);
244 return res;
245}
246
248 if (node1 != nullptr && node2 != nullptr) {
249 if (node1 == node2) {
250 return SAME;
251 }
252
253 if ((hypothesis == UNKNOWN || hypothesis == ABOVE) && ((node1 == top || node2 == bottom) || aboveFast(node1, node2))) {
254 return ABOVE;
255 }
256
257 if ((hypothesis == UNKNOWN || hypothesis == BELOW) && ((node2 == top || node1 == bottom) || aboveFast(node2, node1))) {
258 return BELOW;
259 }
260 } else if (node1 == top || node2 == bottom) {
261 return ABOVE;
262 } else if (node2 == top || node1 == bottom) {
263 return BELOW;
264 }
265 return UNKNOWN;
266}
267
269 if (node1 != nullptr && node2 != nullptr) {
270 auto comp = compareFast(node1, node2, hypothesis);
271 if (comp != UNKNOWN) {
272 return comp;
273 }
274 if ((hypothesis == UNKNOWN || hypothesis == ABOVE) && above(node1, node2)) {
275 assert(!above(node2, node1));
276 return ABOVE;
277 }
278
279 if ((hypothesis == UNKNOWN || hypothesis == BELOW) && above(node2, node1)) {
280 return BELOW;
281 }
282 } else if (node1 == top || node2 == bottom) {
283 return ABOVE;
284 } else if (node2 == top || node1 == bottom) {
285 return BELOW;
286 }
287 return UNKNOWN;
288}
289
290bool Order::contains(uint_fast64_t state) const {
291 return state < numberOfStates && nodes[state] != nullptr;
292}
293
295 return bottom;
296}
297
299 assert(!doneStates.full() || numberOfAddedStates == numberOfStates);
300 return doneStates.full();
301}
302
303uint_fast64_t Order::getNextDoneState(uint_fast64_t state) const {
304 return doneStates.getNextSetIndex(state + 1);
305}
306
307Order::Node* Order::getNode(uint_fast64_t stateNumber) const {
308 assert(stateNumber < numberOfStates);
309 return nodes[stateNumber];
310}
311
312std::vector<Order::Node*> Order::getNodes() const {
313 return nodes;
314}
315
316std::vector<uint_fast64_t>& Order::getStatesSorted() {
317 return statesSorted;
318}
319
321 return top;
322}
323
324uint_fast64_t Order::getNumberOfAddedStates() const {
325 return numberOfAddedStates;
326}
327
328uint_fast64_t Order::getNumberOfStates() const {
329 return numberOfStates;
330}
331
332bool Order::isBottomState(uint_fast64_t state) const {
333 auto states = bottom->states;
334 return states.find(state) != states.end();
335}
336
337bool Order::isTopState(uint_fast64_t state) const {
338 auto states = top->states;
339 return states.find(state) != states.end();
340}
341
343 return onlyBottomTopOrder;
344}
345
346std::vector<uint_fast64_t> Order::sortStates(std::vector<uint_fast64_t>* states) {
347 assert(states != nullptr);
348 uint_fast64_t numberOfStatesToSort = states->size();
349 std::vector<uint_fast64_t> result;
350 // Go over all states
351 for (auto state : *states) {
352 bool unknown = false;
353 if (result.size() == 0) {
354 result.push_back(state);
355 } else {
356 bool added = false;
357 for (auto itr = result.begin(); itr != result.end(); ++itr) {
358 auto compareRes = compare(state, (*itr));
359 if (compareRes == ABOVE || compareRes == SAME) {
360 // insert at current pointer (while keeping other values)
361 result.insert(itr, state);
362 added = true;
363 break;
364 } else if (compareRes == UNKNOWN) {
365 unknown = true;
366 break;
367 }
368 }
369 if (unknown) {
370 break;
371 }
372 if (!added) {
373 result.push_back(state);
374 }
375 }
376 }
377 while (result.size() < numberOfStatesToSort) {
378 result.push_back(numberOfStates);
379 }
380 assert(result.size() == numberOfStatesToSort);
381 return result;
382}
383
384std::pair<std::pair<uint_fast64_t, uint_fast64_t>, std::vector<uint_fast64_t>> Order::sortStatesForForward(uint_fast64_t currentState,
385 std::vector<uint_fast64_t> const& states) {
386 std::vector<uint_fast64_t> statesSorted;
387 statesSorted.push_back(currentState);
388 // Go over all states
389 bool oneUnknown = false;
390 bool unknown = false;
391 uint_fast64_t s1 = numberOfStates;
392 uint_fast64_t s2 = numberOfStates;
393 for (auto& state : states) {
394 unknown = false;
395 bool added = false;
396 for (auto itr = statesSorted.begin(); itr != statesSorted.end(); ++itr) {
397 auto compareRes = compare(state, (*itr));
398 if (compareRes == ABOVE || compareRes == SAME) {
399 if (!contains(state) && compareRes == ABOVE) {
400 add(state);
401 }
402 added = true;
403 // insert at current pointer (while keeping other values)
404 statesSorted.insert(itr, state);
405 break;
406 } else if (compareRes == UNKNOWN && !oneUnknown) {
407 // We miss state in the result.
408 s1 = state;
409 s2 = *itr;
410 oneUnknown = true;
411 added = true;
412 break;
413 } else if (compareRes == UNKNOWN && oneUnknown) {
414 unknown = true;
415 added = true;
416 break;
417 }
418 }
419 if (!added) {
420 // State will be last in the list
421 statesSorted.push_back(state);
422 }
423 if (unknown && oneUnknown) {
424 break;
425 }
426 }
427 if (!unknown && oneUnknown) {
428 assert(statesSorted.size() == states.size());
429 s2 = numberOfStates;
430 }
431 assert(s1 == numberOfStates || (s1 != numberOfStates && s2 == numberOfStates && statesSorted.size() == states.size()) ||
432 (s1 != numberOfStates && s2 != numberOfStates && statesSorted.size() < states.size()));
433
434 return {{s1, s2}, statesSorted};
435}
436
437std::pair<std::pair<uint_fast64_t, uint_fast64_t>, std::vector<uint_fast64_t>> Order::sortStatesUnorderedPair(const std::vector<uint_fast64_t>* states) {
438 assert(states != nullptr);
439 uint_fast64_t numberOfStatesToSort = states->size();
440 std::vector<uint_fast64_t> result;
441 // Go over all states
442 for (auto state : *states) {
443 bool unknown = false;
444 if (result.size() == 0) {
445 result.push_back(state);
446 } else {
447 bool added = false;
448 for (auto itr = result.begin(); itr != result.end(); ++itr) {
449 auto compareRes = compare(state, (*itr));
450 if (compareRes == ABOVE || compareRes == SAME) {
451 // insert at current pointer (while keeping other values)
452 result.insert(itr, state);
453 added = true;
454 break;
455 } else if (compareRes == UNKNOWN) {
456 return {{(*itr), state}, std::move(result)};
457 }
458 }
459 if (unknown) {
460 break;
461 }
462 if (!added) {
463 result.push_back(state);
464 }
465 }
466 }
467
468 assert(result.size() == numberOfStatesToSort);
469 return {{numberOfStates, numberOfStates}, std::move(result)};
470}
471
472std::vector<uint_fast64_t> Order::sortStates(storm::storage::BitVector* states) {
473 uint_fast64_t numberOfStatesToSort = states->getNumberOfSetBits();
474 std::vector<uint_fast64_t> result;
475 // Go over all states
476 for (auto state : *states) {
477 bool unknown = false;
478 if (result.size() == 0) {
479 result.push_back(state);
480 } else {
481 bool added = false;
482 for (auto itr = result.begin(); itr != result.end(); ++itr) {
483 auto compareRes = compare(state, (*itr));
484 if (compareRes == ABOVE || compareRes == SAME) {
485 // insert at current pointer (while keeping other values)
486 result.insert(itr, state);
487 added = true;
488 break;
489 } else if (compareRes == UNKNOWN) {
490 unknown = true;
491 break;
492 }
493 }
494 if (unknown) {
495 break;
496 }
497 if (!added) {
498 result.push_back(state);
499 }
500 }
501 }
502 while (result.size() < numberOfStatesToSort) {
503 result.push_back(numberOfStates);
504 }
505 assert(result.size() == numberOfStatesToSort);
506 return result;
507}
508
509/*** Checking on helpfunctionality for building of order ***/
510
511std::shared_ptr<Order> Order::copy() const {
512 assert(!isInvalid());
513 std::shared_ptr<Order> copiedOrder = std::make_shared<Order>();
514 copiedOrder->nodes = std::vector<Node*>(numberOfStates, nullptr);
515 copiedOrder->onlyBottomTopOrder = this->isOnlyBottomTopOrder();
516 copiedOrder->numberOfStates = this->getNumberOfStates();
517 copiedOrder->statesSorted = std::vector<uint_fast64_t>(this->statesSorted);
518 copiedOrder->statesToHandle = std::vector<uint_fast64_t>(this->statesToHandle);
519 copiedOrder->trivialStates = storm::storage::BitVector(trivialStates);
520 copiedOrder->doneStates = storm::storage::BitVector(doneStates);
521 copiedOrder->numberOfAddedStates = this->numberOfAddedStates;
522 copiedOrder->doneBuilding = this->doneBuilding;
523
524 auto seenStates = storm::storage::BitVector(numberOfStates, false);
525 // copy nodes
526 for (uint_fast64_t state = 0; state < numberOfStates; ++state) {
527 Node* oldNode = nodes.at(state);
528 if (oldNode != nullptr) {
529 if (!seenStates[*(oldNode->states.begin())]) {
530 Node* newNode = new Node();
531 if (oldNode == this->getTop()) {
532 copiedOrder->top = newNode;
533 } else if (oldNode == this->getBottom()) {
534 copiedOrder->bottom = newNode;
535 }
537 for (size_t i = 0; i < oldNode->statesAbove.size(); ++i) {
538 assert(newNode->statesAbove[i] == oldNode->statesAbove[i]);
539 }
540 for (auto const& i : oldNode->states) {
541 assert(!seenStates[i]);
542 newNode->states.insert(i);
543 seenStates.set(i);
544 copiedOrder->nodes[i] = newNode;
545 }
546 }
547 } else {
548 assert(copiedOrder->nodes[state] == nullptr);
549 }
550 }
551
552 return copiedOrder;
553}
554
555/*** Setters ***/
556void Order::setDoneState(uint_fast64_t stateNumber) {
557 doneStates.set(stateNumber);
558}
559
560/*** Output ***/
561
562void Order::toDotOutput() const {
563 // Graphviz Output start
564 STORM_PRINT("Dot Output:\n" << "digraph model {\n");
565
566 // Vertices of the digraph
567 storm::storage::BitVector stateCoverage = storm::storage::BitVector(doneStates);
568 for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
569 if (nodes[i] != nullptr) {
570 stateCoverage.set(i);
571 }
572 }
573 for (uint_fast64_t i = stateCoverage.getNextSetIndex(0); i != numberOfStates; i = stateCoverage.getNextSetIndex(i + 1)) {
574 for (uint_fast64_t j = i + 1; j < numberOfStates; j++) {
575 if (getNode(j) == getNode(i))
576 stateCoverage.set(j, false);
577 }
578 STORM_PRINT("\t" << nodeName(*getNode(i)) << " [ label = \"" << nodeLabel(*getNode(i)) << "\" ];\n");
579 }
580
581 // Edges of the digraph
582 for (uint_fast64_t i = stateCoverage.getNextSetIndex(0); i != numberOfStates; i = stateCoverage.getNextSetIndex(i + 1)) {
583 storm::storage::BitVector v = storm::storage::BitVector(numberOfStates, false);
584 Node* currentNode = getNode(i);
585 for (uint_fast64_t s1 : getNode(i)->statesAbove) {
586 v |= (currentNode->statesAbove & getNode(s1)->statesAbove);
587 }
588
589 std::set<Node*> seenNodes;
590 for (uint_fast64_t state : currentNode->statesAbove) {
591 Node* n = getNode(state);
592 if (std::find(seenNodes.begin(), seenNodes.end(), n) == seenNodes.end()) {
593 seenNodes.insert(n);
594 if (!v[state]) {
595 STORM_PRINT("\t" << nodeName(*currentNode) << " -> " << nodeName(*getNode(state)) << ";\n");
596 }
597 }
598 }
599 }
600 // Graphviz Output end
601 STORM_PRINT("}\n");
602}
603
604void Order::dotOutputToFile(std::ofstream& dotOutfile) const {
605 // Graphviz Output start
606 dotOutfile << "Dot Output:\n"
607 << "digraph model {\n";
608
609 // Vertices of the digraph
610 storm::storage::BitVector stateCoverage = storm::storage::BitVector(numberOfStates, true);
611 for (uint_fast64_t i = stateCoverage.getNextSetIndex(0); i != numberOfStates; i = stateCoverage.getNextSetIndex(i + 1)) {
612 if (getNode(i) == NULL) {
613 continue;
614 }
615 for (uint_fast64_t j = i + 1; j < numberOfStates; j++) {
616 if (getNode(j) == getNode(i))
617 stateCoverage.set(j, false);
618 }
619
620 dotOutfile << "\t" << nodeName(*getNode(i)) << " [ label = \"" << nodeLabel(*getNode(i)) << "\" ];\n";
621 }
622
623 // Edges of the digraph
624 for (uint_fast64_t i = stateCoverage.getNextSetIndex(0); i != numberOfStates; i = stateCoverage.getNextSetIndex(i + 1)) {
625 storm::storage::BitVector v = storm::storage::BitVector(numberOfStates, false);
626 Node* currentNode = getNode(i);
627 if (currentNode == NULL) {
628 continue;
629 }
630
631 for (uint_fast64_t s1 : getNode(i)->statesAbove) {
632 v |= (currentNode->statesAbove & getNode(s1)->statesAbove);
633 }
634
635 std::set<Node*> seenNodes;
636 for (uint_fast64_t state : currentNode->statesAbove) {
637 Node* n = getNode(state);
638 if (std::find(seenNodes.begin(), seenNodes.end(), n) == seenNodes.end()) {
639 seenNodes.insert(n);
640 if (!v[state]) {
641 dotOutfile << "\t" << nodeName(*currentNode) << " -> " << nodeName(*getNode(state)) << ";\n";
642 }
643 }
644 }
645 }
646
647 // Graphviz Output end
648 dotOutfile << "}\n";
649}
650
651/*** Private methods ***/
652
653void Order::init(uint_fast64_t numberOfStates, storage::Decomposition<storage::StronglyConnectedComponent> decomposition, bool doneBuilding) {
654 this->numberOfStates = numberOfStates;
655 this->invalid = false;
656 this->nodes = std::vector<Node*>(numberOfStates, nullptr);
657 this->doneStates = storm::storage::BitVector(numberOfStates, false);
658 assert(doneStates.getNumberOfSetBits() == 0);
659 if (decomposition.size() == 0) {
660 this->trivialStates = storm::storage::BitVector(numberOfStates, true);
661 } else {
662 this->trivialStates = storm::storage::BitVector(numberOfStates, false);
663 for (auto& scc : decomposition) {
664 if (scc.size() == 1) {
665 trivialStates.set(*(scc.begin()));
666 }
667 }
668 }
669 this->top = new Node();
670 this->bottom = new Node();
671 this->top->statesAbove = storm::storage::BitVector(numberOfStates, false);
672 this->bottom->statesAbove = storm::storage::BitVector(numberOfStates, false);
673 this->doneBuilding = doneBuilding;
674}
675
676bool Order::aboveFast(Node* node1, Node* node2) const {
677 bool found = false;
678 for (auto const& state : node1->states) {
679 found = ((node2->statesAbove))[state];
680 if (found) {
681 break;
682 }
683 }
684 return found;
685}
686
687bool Order::above(Node* node1, Node* node2) {
688 assert(!aboveFast(node1, node2));
689 // Check whether node1 is above node2 by going over all states that are above state 2
690 bool above = false;
691 // Only do this when we have to deal with forward reasoning or we are not yet done with the building of the order
692 if (!trivialStates.full() || !doneBuilding) {
693 // First gather all states that are above node 2;
694
695 storm::storage::BitVector statesSeen((node2->statesAbove));
696 std::queue<uint_fast64_t> statesToHandle;
697 for (auto state : statesSeen) {
698 statesToHandle.push(state);
699 }
700 while (!above && !statesToHandle.empty()) {
701 // Get first item from the queue
702 auto state = statesToHandle.front();
703 statesToHandle.pop();
704 auto node = getNode(state);
705 if (aboveFast(node1, node)) {
706 above = true;
707 continue;
708 }
709 for (auto newState : node->statesAbove) {
710 if (!statesSeen[newState]) {
711 statesToHandle.push(newState);
712 statesSeen.set(newState);
713 }
714 }
715 }
716 }
717 if (above) {
718 for (auto state : node1->states) {
719 node2->statesAbove.set(state);
720 }
721 }
722 return above;
723}
724
725std::string Order::nodeName(Node n) const {
726 auto itr = n.states.begin();
727 std::string name = "n" + std::to_string(*itr);
728 return name;
729}
730
731std::string Order::nodeLabel(Node n) const {
732 if (n.states == top->states)
733 return "=)";
734 if (n.states == bottom->states)
735 return "=(";
736 auto itr = n.states.begin();
737 std::string label = "s" + std::to_string(*itr);
738 ++itr;
739 if (itr != n.states.end())
740 label = "[" + label + "]";
741 return label;
742}
743
745 return !doneStates.full();
746}
747
748bool Order::isTrivial(uint_fast64_t state) {
749 return trivialStates[state];
750}
751
752std::pair<uint_fast64_t, bool> Order::getNextStateNumber() {
753 while (!statesSorted.empty()) {
754 auto state = statesSorted.back();
755 statesSorted.pop_back();
756 if (!doneStates[state]) {
757 return {state, true};
758 }
759 }
760 return {numberOfStates, true};
761}
762
763std::pair<uint_fast64_t, bool> Order::getStateToHandle() {
764 assert(existsStateToHandle());
765 auto state = statesToHandle.back();
766 statesToHandle.pop_back();
767 return {state, false};
768}
769
771 while (!statesToHandle.empty() && doneStates[statesToHandle.back()]) {
772 statesToHandle.pop_back();
773 }
774 return !statesToHandle.empty();
775}
776
777void Order::addStateToHandle(uint_fast64_t state) {
778 if (!doneStates[state]) {
779 statesToHandle.push_back(state);
780 }
781}
782
783void Order::addStateSorted(uint_fast64_t state) {
784 statesSorted.push_back(state);
785}
786
787std::pair<bool, bool> Order::allAboveBelow(std::vector<uint_fast64_t> const states, uint_fast64_t state) {
788 auto allAbove = true;
789 auto allBelow = true;
790 for (auto& checkState : states) {
791 auto comp = compare(checkState, state);
792 allAbove &= (comp == ABOVE || comp == SAME);
793 allBelow &= (comp == BELOW || comp == SAME);
794 }
795 return {allAbove, allBelow};
796}
797
798uint_fast64_t Order::getNumberOfDoneStates() const {
799 return doneStates.getNumberOfSetBits();
800}
801
802bool Order::isInvalid() const {
803 return invalid;
804}
805} // namespace analysis
806} // namespace storm
uint_fast64_t getNumberOfDoneStates() const
Definition Order.cpp:798
void addAbove(uint_fast64_t state, Node *node)
Adds a node with the given state above the given node.
Definition Order.cpp:74
bool isTrivial(uint_fast64_t state)
Definition Order.cpp:748
void addStateSorted(uint_fast64_t state)
Definition Order.cpp:783
Node * getBottom() const
Retrieves the bottom node of the order.
Definition Order.cpp:294
bool contains(uint_fast64_t state) const
Check if state is already contained in order.
Definition Order.cpp:290
bool isInvalid() const
Definition Order.cpp:802
Order::NodeComparison compareFast(uint_fast64_t state1, uint_fast64_t state2, NodeComparison hypothesis=UNKNOWN) const
Definition Order.cpp:242
Order::NodeComparison compare(uint_fast64_t state1, uint_fast64_t state2, NodeComparison hypothesis=UNKNOWN)
Compares the level of the nodes of the states.
Definition Order.cpp:238
std::pair< uint_fast64_t, bool > getStateToHandle()
Definition Order.cpp:763
std::vector< uint_fast64_t > & getStatesSorted()
Definition Order.cpp:316
std::vector< uint_fast64_t > sortStates(std::vector< uint_fast64_t > *states)
Sorts the given states if possible.
Definition Order.cpp:346
NodeComparison
Constants for comparison of nodes/states.
Definition Order.h:18
Order()
Constructs a new Order.
Definition Order.cpp:62
void toDotOutput() const
Prints the dot output to normal STORM_PRINT.
Definition Order.cpp:562
void dotOutputToFile(std::ofstream &dotOutfile) const
Writes dotoutput to the given file.
Definition Order.cpp:604
void addRelation(uint_fast64_t above, uint_fast64_t below, bool allowMerge=false)
Adds a new relation between two states to the order.
Definition Order.cpp:151
Node * getNode(uint_fast64_t state) const
Retrieves the pointer to a Node at which the state occurs.
Definition Order.cpp:307
bool merge(uint_fast64_t var1, uint_fast64_t var2)
Merges node of var2 into node of var1.
Definition Order.cpp:232
std::vector< Node * > getNodes() const
Returns the vector with the nodes of the order.
Definition Order.cpp:312
bool mergeNodes(Node *node1, Node *node2)
Merges node2 into node1.
Definition Order.cpp:193
std::pair< bool, bool > allAboveBelow(std::vector< uint_fast64_t > const states, uint_fast64_t state)
Definition Order.cpp:787
uint_fast64_t getNextDoneState(uint_fast64_t state) const
Returns the next done state of the order, returns the number of state if end of done states is reache...
Definition Order.cpp:303
bool getDoneBuilding() const
Returns true if done building the order.
Definition Order.cpp:298
void addToNode(uint_fast64_t state, Node *node)
Adds state to the states of the given node.
Definition Order.cpp:174
bool isTopState(uint_fast64_t) const
Checks if the given state is a top state.
Definition Order.cpp:337
std::pair< std::pair< uint_fast64_t, uint_fast64_t >, std::vector< uint_fast64_t > > sortStatesForForward(uint_fast64_t currentState, std::vector< uint_fast64_t > const &successors)
Sorts the given states if possible.
Definition Order.cpp:384
std::pair< std::pair< uint_fast64_t, uint_fast64_t >, std::vector< uint_fast64_t > > sortStatesUnorderedPair(const std::vector< uint_fast64_t > *states)
Sorts the given states if possible.
Definition Order.cpp:437
void addStateToHandle(uint_fast64_t state)
Definition Order.cpp:777
void addBetween(uint_fast64_t state, Node *node1, Node *node2)
Adds a node with the given state below node1 and above node2.
Definition Order.cpp:114
uint_fast64_t getNumberOfStates() const
Returns the number of possible states in the order.
Definition Order.cpp:328
void addBelow(uint_fast64_t state, Node *node)
Adds a node with the given state below the given node.
Definition Order.cpp:94
void setDoneState(uint_fast64_t sccNumber)
Definition Order.cpp:556
std::pair< uint_fast64_t, bool > getNextStateNumber()
Definition Order.cpp:752
std::shared_ptr< Order > copy() const
Creates a copy of the calling Order.
Definition Order.cpp:511
bool isOnlyBottomTopOrder() const
Returns if the order only consists of bottom and top states (so no in-between nodes).
Definition Order.cpp:342
uint_fast64_t getNumberOfAddedStates() const
Returns the number of added states.
Definition Order.cpp:324
bool isBottomState(uint_fast64_t) const
Checks if the given state is a bottom state.
Definition Order.cpp:332
Node * getTop() const
Retrieves the top node of the order.
Definition Order.cpp:320
void add(uint_fast64_t state)
Adds state between the top and bottom node of the order.
Definition Order.cpp:68
void addRelationNodes(storm::analysis::Order::Node *above, storm::analysis::Order::Node *below, bool allowMerge=false)
Adds a new relation between two nodes to the order.
Definition Order.cpp:156
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
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.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
size_t size() const
Retrieves the number of bits this bit vector can store.
This class represents the decomposition of a model into blocks which are of the template type.
std::size_t size() const
Retrieves the number of blocks of this decomposition.
#define STORM_LOG_INFO(message)
Definition logging.h:24
#define STORM_PRINT(message)
Define the macros that print information and optionally also log it.
Definition macros.h:62
Nodes of the Reachability Order.
Definition Order.h:28
boost::container::flat_set< uint_fast64_t > states
Definition Order.h:29
storm::storage::BitVector statesAbove
Definition Order.h:30