12 init(numberOfStates, decomposition);
13 this->numberOfAddedStates = 0;
14 this->onlyBottomTopOrder =
true;
15 for (
auto i : topStates) {
16 this->doneStates.
set(i);
18 this->top->
states.insert(i);
20 numberOfAddedStates++;
22 this->statesSorted = statesSorted;
24 for (
auto i : bottomStates) {
25 this->doneStates.
set(i);
26 this->bottom->
states.insert(i);
27 this->nodes[i] = bottom;
28 numberOfAddedStates++;
30 assert(numberOfAddedStates <= numberOfStates);
32 if (numberOfAddedStates == numberOfStates) {
33 doneBuilding = doneStates.
full();
37Order::Order(uint_fast64_t topState, uint_fast64_t bottomState, uint_fast64_t numberOfStates,
39 init(numberOfStates, decomposition);
41 this->onlyBottomTopOrder =
true;
42 this->doneStates.
set(topState);
45 this->top->
states.insert(topState);
46 this->nodes[topState] = top;
48 this->doneStates.
set(bottomState);
50 this->bottom->
states.insert(bottomState);
51 this->nodes[bottomState] = bottom;
52 this->numberOfAddedStates = 2;
53 assert(numberOfAddedStates <= numberOfStates);
55 this->statesSorted = statesSorted;
57 if (numberOfAddedStates == numberOfStates) {
58 doneBuilding = doneStates.
full();
63 this->invalid =
false;
69 assert(nodes[state] ==
nullptr);
77 assert(nodes[state] ==
nullptr);
79 nodes[state] = newNode;
81 newNode->
states.insert(state);
83 for (
auto const& state : top->
states) {
87 numberOfAddedStates++;
88 onlyBottomTopOrder =
false;
89 if (numberOfAddedStates == numberOfStates) {
90 doneBuilding = doneStates.
full();
97 assert(nodes[state] ==
nullptr);
99 nodes[state] = newNode;
100 newNode->
states.insert(state);
102 for (
auto statesAbove : node->
states) {
106 numberOfAddedStates++;
107 onlyBottomTopOrder =
false;
108 if (numberOfAddedStates == numberOfStates) {
109 doneBuilding = doneStates.
full();
111 assert(numberOfAddedStates <= numberOfStates);
115 STORM_LOG_INFO(
"Add " << state <<
" between (above) " << *above->
states.begin() <<
" and " << *below->
states.begin() <<
'\n');
118 assert(above !=
nullptr && below !=
nullptr);
119 if (nodes[state] ==
nullptr) {
122 nodes[state] = newNode;
124 newNode->
states.insert(state);
126 for (
auto aboveStates : above->
states) {
130 numberOfAddedStates++;
131 onlyBottomTopOrder =
false;
132 if (numberOfAddedStates == numberOfStates) {
133 doneBuilding = doneStates.
full();
135 assert(numberOfAddedStates <= numberOfStates);
145 assert(
getNode(below)->states.find(below) !=
getNode(below)->states.end());
146 assert(
getNode(above)->states.find(above) !=
getNode(above)->states.end());
168 for (
auto const& state : above->
states) {
177 if (nodes[state] ==
nullptr) {
179 node->
states.insert(state);
181 numberOfAddedStates++;
182 if (numberOfAddedStates == numberOfStates) {
183 doneBuilding = doneStates.
full();
185 assert(numberOfAddedStates <= numberOfStates);
202 for (
auto const& i : node2->
states) {
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) {
218 for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
219 for (uint_fast64_t j = i + 1; j < numberOfStates; ++j) {
223 (comp1 ==
SAME && comp2 ==
SAME))) {
248 if (node1 !=
nullptr && node2 !=
nullptr) {
249 if (node1 == node2) {
253 if ((hypothesis ==
UNKNOWN || hypothesis ==
ABOVE) && ((node1 == top || node2 == bottom) || aboveFast(node1, node2))) {
257 if ((hypothesis ==
UNKNOWN || hypothesis ==
BELOW) && ((node2 == top || node1 == bottom) || aboveFast(node2, node1))) {
260 }
else if (node1 == top || node2 == bottom) {
262 }
else if (node2 == top || node1 == bottom) {
269 if (node1 !=
nullptr && node2 !=
nullptr) {
274 if ((hypothesis ==
UNKNOWN || hypothesis ==
ABOVE) && above(node1, node2)) {
275 assert(!above(node2, node1));
279 if ((hypothesis ==
UNKNOWN || hypothesis ==
BELOW) && above(node2, node1)) {
282 }
else if (node1 == top || node2 == bottom) {
284 }
else if (node2 == top || node1 == bottom) {
291 return state < numberOfStates && nodes[state] !=
nullptr;
299 assert(!doneStates.
full() || numberOfAddedStates == numberOfStates);
300 return doneStates.
full();
308 assert(stateNumber < numberOfStates);
309 return nodes[stateNumber];
325 return numberOfAddedStates;
329 return numberOfStates;
333 auto states = bottom->
states;
334 return states.find(state) != states.end();
338 auto states = top->
states;
339 return states.find(state) != states.end();
343 return onlyBottomTopOrder;
347 assert(states !=
nullptr);
348 uint_fast64_t numberOfStatesToSort = states->size();
349 std::vector<uint_fast64_t> result;
351 for (
auto state : *states) {
352 bool unknown =
false;
353 if (result.size() == 0) {
354 result.push_back(state);
357 for (
auto itr = result.begin(); itr != result.end(); ++itr) {
358 auto compareRes =
compare(state, (*itr));
359 if (compareRes ==
ABOVE || compareRes ==
SAME) {
361 result.insert(itr, state);
364 }
else if (compareRes ==
UNKNOWN) {
373 result.push_back(state);
377 while (result.size() < numberOfStatesToSort) {
378 result.push_back(numberOfStates);
380 assert(result.size() == numberOfStatesToSort);
385 std::vector<uint_fast64_t>
const& states) {
386 std::vector<uint_fast64_t> statesSorted;
387 statesSorted.push_back(currentState);
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) {
396 for (
auto itr = statesSorted.begin(); itr != statesSorted.end(); ++itr) {
397 auto compareRes =
compare(state, (*itr));
398 if (compareRes ==
ABOVE || compareRes ==
SAME) {
404 statesSorted.insert(itr, state);
406 }
else if (compareRes ==
UNKNOWN && !oneUnknown) {
413 }
else if (compareRes ==
UNKNOWN && oneUnknown) {
421 statesSorted.push_back(state);
423 if (unknown && oneUnknown) {
427 if (!unknown && oneUnknown) {
428 assert(statesSorted.size() == states.size());
431 assert(s1 == numberOfStates || (s1 != numberOfStates && s2 == numberOfStates && statesSorted.size() == states.size()) ||
432 (s1 != numberOfStates && s2 != numberOfStates && statesSorted.size() < states.size()));
434 return {{s1, s2}, statesSorted};
438 assert(states !=
nullptr);
439 uint_fast64_t numberOfStatesToSort = states->size();
440 std::vector<uint_fast64_t> result;
442 for (
auto state : *states) {
443 bool unknown =
false;
444 if (result.size() == 0) {
445 result.push_back(state);
448 for (
auto itr = result.begin(); itr != result.end(); ++itr) {
449 auto compareRes =
compare(state, (*itr));
450 if (compareRes ==
ABOVE || compareRes ==
SAME) {
452 result.insert(itr, state);
455 }
else if (compareRes ==
UNKNOWN) {
456 return {{(*itr), state}, std::move(result)};
463 result.push_back(state);
468 assert(result.size() == numberOfStatesToSort);
469 return {{numberOfStates, numberOfStates}, std::move(result)};
474 std::vector<uint_fast64_t> result;
476 for (
auto state : *states) {
477 bool unknown =
false;
478 if (result.size() == 0) {
479 result.push_back(state);
482 for (
auto itr = result.begin(); itr != result.end(); ++itr) {
483 auto compareRes =
compare(state, (*itr));
484 if (compareRes ==
ABOVE || compareRes ==
SAME) {
486 result.insert(itr, state);
489 }
else if (compareRes ==
UNKNOWN) {
498 result.push_back(state);
502 while (result.size() < numberOfStatesToSort) {
503 result.push_back(numberOfStates);
505 assert(result.size() == numberOfStatesToSort);
513 std::shared_ptr<Order> copiedOrder = std::make_shared<Order>();
514 copiedOrder->nodes = std::vector<Node*>(numberOfStates,
nullptr);
517 copiedOrder->statesSorted = std::vector<uint_fast64_t>(this->statesSorted);
518 copiedOrder->statesToHandle = std::vector<uint_fast64_t>(this->statesToHandle);
521 copiedOrder->numberOfAddedStates = this->numberOfAddedStates;
522 copiedOrder->doneBuilding = this->doneBuilding;
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())]) {
531 if (oldNode == this->
getTop()) {
532 copiedOrder->top = newNode;
533 }
else if (oldNode == this->
getBottom()) {
534 copiedOrder->bottom = newNode;
540 for (
auto const& i : oldNode->
states) {
541 assert(!seenStates[i]);
542 newNode->
states.insert(i);
544 copiedOrder->nodes[i] = newNode;
548 assert(copiedOrder->nodes[state] ==
nullptr);
557 doneStates.
set(stateNumber);
564 STORM_PRINT(
"Dot Output:\n" <<
"digraph model {\n");
568 for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
569 if (nodes[i] !=
nullptr) {
570 stateCoverage.
set(i);
574 for (uint_fast64_t j = i + 1; j < numberOfStates; j++) {
576 stateCoverage.
set(j,
false);
589 std::set<Node*> seenNodes;
590 for (uint_fast64_t state : currentNode->
statesAbove) {
592 if (std::find(seenNodes.begin(), seenNodes.end(), n) == seenNodes.end()) {
595 STORM_PRINT(
"\t" << nodeName(*currentNode) <<
" -> " << nodeName(*
getNode(state)) <<
";\n");
606 dotOutfile <<
"Dot Output:\n"
607 <<
"digraph model {\n";
615 for (uint_fast64_t j = i + 1; j < numberOfStates; j++) {
617 stateCoverage.
set(j,
false);
620 dotOutfile <<
"\t" << nodeName(*
getNode(i)) <<
" [ label = \"" << nodeLabel(*
getNode(i)) <<
"\" ];\n";
627 if (currentNode == NULL) {
635 std::set<Node*> seenNodes;
636 for (uint_fast64_t state : currentNode->
statesAbove) {
638 if (std::find(seenNodes.begin(), seenNodes.end(), n) == seenNodes.end()) {
641 dotOutfile <<
"\t" << nodeName(*currentNode) <<
" -> " << nodeName(*
getNode(state)) <<
";\n";
654 this->numberOfStates = numberOfStates;
655 this->invalid =
false;
656 this->nodes = std::vector<Node*>(numberOfStates,
nullptr);
659 if (decomposition.
size() == 0) {
663 for (
auto& scc : decomposition) {
664 if (scc.size() == 1) {
665 trivialStates.
set(*(scc.begin()));
669 this->top =
new Node();
670 this->bottom =
new Node();
673 this->doneBuilding = doneBuilding;
676bool Order::aboveFast(Node* node1, Node* node2)
const {
678 for (
auto const& state : node1->states) {
679 found = ((node2->statesAbove))[state];
687bool Order::above(Node* node1, Node* node2) {
688 assert(!aboveFast(node1, node2));
692 if (!trivialStates.
full() || !doneBuilding) {
696 std::queue<uint_fast64_t> statesToHandle;
697 for (
auto state : statesSeen) {
698 statesToHandle.push(state);
700 while (!above && !statesToHandle.empty()) {
702 auto state = statesToHandle.front();
703 statesToHandle.pop();
705 if (aboveFast(node1, node)) {
709 for (
auto newState : node->statesAbove) {
710 if (!statesSeen[newState]) {
711 statesToHandle.push(newState);
712 statesSeen.set(newState);
718 for (
auto state : node1->states) {
719 node2->statesAbove.set(state);
725std::string Order::nodeName(Node n)
const {
726 auto itr = n.states.begin();
727 std::string name =
"n" + std::to_string(*itr);
731std::string Order::nodeLabel(Node n)
const {
732 if (n.states == top->
states)
734 if (n.states == bottom->
states)
736 auto itr = n.states.begin();
737 std::string label =
"s" + std::to_string(*itr);
739 if (itr != n.states.end())
740 label =
"[" + label +
"]";
745 return !doneStates.
full();
749 return trivialStates[state];
753 while (!statesSorted.empty()) {
754 auto state = statesSorted.back();
755 statesSorted.pop_back();
756 if (!doneStates[state]) {
757 return {state,
true};
760 return {numberOfStates,
true};
765 auto state = statesToHandle.back();
766 statesToHandle.pop_back();
767 return {state,
false};
771 while (!statesToHandle.empty() && doneStates[statesToHandle.back()]) {
772 statesToHandle.pop_back();
774 return !statesToHandle.empty();
778 if (!doneStates[state]) {
779 statesToHandle.push_back(state);
784 statesSorted.push_back(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);
795 return {allAbove, allBelow};
uint_fast64_t getNumberOfDoneStates() const
void addAbove(uint_fast64_t state, Node *node)
Adds a node with the given state above the given node.
bool isTrivial(uint_fast64_t state)
void addStateSorted(uint_fast64_t state)
Node * getBottom() const
Retrieves the bottom node of the order.
bool contains(uint_fast64_t state) const
Check if state is already contained in order.
Order::NodeComparison compareFast(uint_fast64_t state1, uint_fast64_t state2, NodeComparison hypothesis=UNKNOWN) const
bool existsStateToHandle()
Order::NodeComparison compare(uint_fast64_t state1, uint_fast64_t state2, NodeComparison hypothesis=UNKNOWN)
Compares the level of the nodes of the states.
std::pair< uint_fast64_t, bool > getStateToHandle()
std::vector< uint_fast64_t > & getStatesSorted()
std::vector< uint_fast64_t > sortStates(std::vector< uint_fast64_t > *states)
Sorts the given states if possible.
NodeComparison
Constants for comparison of nodes/states.
Order()
Constructs a new Order.
void toDotOutput() const
Prints the dot output to normal STORM_PRINT.
void dotOutputToFile(std::ofstream &dotOutfile) const
Writes dotoutput to the given file.
void addRelation(uint_fast64_t above, uint_fast64_t below, bool allowMerge=false)
Adds a new relation between two states to the order.
Node * getNode(uint_fast64_t state) const
Retrieves the pointer to a Node at which the state occurs.
bool merge(uint_fast64_t var1, uint_fast64_t var2)
Merges node of var2 into node of var1.
std::vector< Node * > getNodes() const
Returns the vector with the nodes of the order.
bool mergeNodes(Node *node1, Node *node2)
Merges node2 into node1.
std::pair< bool, bool > allAboveBelow(std::vector< uint_fast64_t > const states, uint_fast64_t state)
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...
bool getDoneBuilding() const
Returns true if done building the order.
void addToNode(uint_fast64_t state, Node *node)
Adds state to the states of the given node.
bool isTopState(uint_fast64_t) const
Checks if the given state is a top state.
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.
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.
void addStateToHandle(uint_fast64_t state)
void addBetween(uint_fast64_t state, Node *node1, Node *node2)
Adds a node with the given state below node1 and above node2.
uint_fast64_t getNumberOfStates() const
Returns the number of possible states in the order.
void addBelow(uint_fast64_t state, Node *node)
Adds a node with the given state below the given node.
void setDoneState(uint_fast64_t sccNumber)
std::pair< uint_fast64_t, bool > getNextStateNumber()
std::shared_ptr< Order > copy() const
Creates a copy of the calling Order.
bool isOnlyBottomTopOrder() const
Returns if the order only consists of bottom and top states (so no in-between nodes).
uint_fast64_t getNumberOfAddedStates() const
Returns the number of added states.
bool isBottomState(uint_fast64_t) const
Checks if the given state is a bottom state.
Node * getTop() const
Retrieves the top node of the order.
void add(uint_fast64_t state)
Adds state between the top and bottom node of the order.
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.
A bit vector that is internally represented as a vector of 64-bit values.
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)
#define STORM_PRINT(message)
Define the macros that print information and optionally also log it.
Nodes of the Reachability Order.
boost::container::flat_set< uint_fast64_t > states
storm::storage::BitVector statesAbove