Storm 1.11.1.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);
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.
bool full() const
Retrieves whether all bits are set in this bit vector.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
size_t size() const
Retrieves the number of bits this bit vector can store.
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