12 init(numberOfStates, decomposition);
13 this->numberOfAddedStates = 0;
14 this->onlyBottomTopOrder =
true;
15 for (uint64_t i : topStates) {
16 this->doneStates.set(i);
17 this->bottom->statesAbove.set(i);
18 this->top->states.insert(i);
20 numberOfAddedStates++;
22 this->statesSorted = statesSorted;
24 for (uint64_t i : bottomStates) {
25 this->doneStates.set(i);
26 this->bottom->states.insert(i);
27 this->nodes[i] = bottom;
28 numberOfAddedStates++;
30 STORM_LOG_ASSERT(numberOfAddedStates <= numberOfStates,
"Number of added states exceeds total states.");
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);
44 this->bottom->statesAbove.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 STORM_LOG_ASSERT(numberOfAddedStates <= numberOfStates,
"Number of added states exceeds total states.");
55 this->statesSorted = statesSorted;
56 STORM_LOG_ASSERT(doneStates.getNumberOfSetBits() == 2,
"Done states bits should be 2.");
57 if (numberOfAddedStates == numberOfStates) {
58 doneBuilding = doneStates.full();
63 this->invalid =
false;
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();
99 nodes[state] = newNode;
100 newNode->
states.insert(state);
102 for (
auto statesAbove : node->
states) {
105 bottom->statesAbove.set(state);
106 numberOfAddedStates++;
107 onlyBottomTopOrder =
false;
108 if (numberOfAddedStates == numberOfStates) {
109 doneBuilding = doneStates.full();
111 STORM_LOG_ASSERT(numberOfAddedStates <= numberOfStates,
"Number of added states exceeds total states.");
115 STORM_LOG_INFO(
"Add " << state <<
" between (above) " << *above->states.begin() <<
" and " << *below->
states.begin() <<
'\n');
118 STORM_LOG_ASSERT(above !=
nullptr && below !=
nullptr,
"Above or below is null.");
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 STORM_LOG_ASSERT(numberOfAddedStates <= numberOfStates,
"Number of added states exceeds total states.");
159 STORM_LOG_INFO(
"Add relation between (above) " << *above->states.begin() <<
" and " << *below->
states.begin() <<
'\n');
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 STORM_LOG_ASSERT(numberOfAddedStates <= numberOfStates,
"Number of added states exceeds total states.");
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) {
211 node->statesAbove.set(state1);
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)) {
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 STORM_LOG_ASSERT(!doneStates.full() || numberOfAddedStates == numberOfStates,
"Done states full but not all states added.");
300 return doneStates.full();
304 return doneStates.getNextSetIndex(state + 1);
308 STORM_LOG_ASSERT(stateNumber < numberOfStates,
"State number exceeds total states.");
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;
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 STORM_LOG_ASSERT(result.size() == numberOfStatesToSort,
"Result size mismatch.");
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 STORM_LOG_ASSERT(statesSorted.size() == states.size(),
"States sorted size mismatch.");
431 STORM_LOG_ASSERT(s1 == numberOfStates || (s1 != numberOfStates && s2 == numberOfStates && statesSorted.size() == states.size()) ||
432 (s1 != numberOfStates && s2 != numberOfStates && statesSorted.size() < states.size()),
433 "States are not sorted.");
435 return {{s1, s2}, statesSorted};
440 [[maybe_unused]] uint_fast64_t numberOfStatesToSort = states->size();
441 std::vector<uint_fast64_t> result;
443 for (
auto state : *states) {
444 bool unknown =
false;
445 if (result.size() == 0) {
446 result.push_back(state);
449 for (
auto itr = result.begin(); itr != result.end(); ++itr) {
450 auto compareRes =
compare(state, (*itr));
451 if (compareRes ==
ABOVE || compareRes ==
SAME) {
453 result.insert(itr, state);
456 }
else if (compareRes ==
UNKNOWN) {
457 return {{(*itr), state}, std::move(result)};
464 result.push_back(state);
469 STORM_LOG_ASSERT(result.size() == numberOfStatesToSort,
"Result size mismatch.");
470 return {{numberOfStates, numberOfStates}, std::move(result)};
475 std::vector<uint_fast64_t> result;
477 for (uint64_t state : *states) {
478 bool unknown =
false;
479 if (result.size() == 0) {
480 result.push_back(state);
483 for (
auto itr = result.begin(); itr != result.end(); ++itr) {
484 auto compareRes =
compare(state, (*itr));
485 if (compareRes ==
ABOVE || compareRes ==
SAME) {
487 result.insert(itr, state);
490 }
else if (compareRes ==
UNKNOWN) {
499 result.push_back(state);
503 while (result.size() < numberOfStatesToSort) {
504 result.push_back(numberOfStates);
506 STORM_LOG_ASSERT(result.size() == numberOfStatesToSort,
"Result size mismatch.");
514 std::shared_ptr<Order> copiedOrder = std::make_shared<Order>();
515 copiedOrder->nodes = std::vector<Node*>(numberOfStates,
nullptr);
518 copiedOrder->statesSorted = std::vector<uint_fast64_t>(this->statesSorted);
519 copiedOrder->statesToHandle = std::vector<uint_fast64_t>(this->statesToHandle);
522 copiedOrder->numberOfAddedStates = this->numberOfAddedStates;
523 copiedOrder->doneBuilding = this->doneBuilding;
527 for (uint_fast64_t state = 0; state < numberOfStates; ++state) {
528 Node* oldNode = nodes.at(state);
529 if (oldNode !=
nullptr) {
530 if (!seenStates[*(oldNode->
states.begin())]) {
532 if (oldNode == this->
getTop()) {
533 copiedOrder->top = newNode;
534 }
else if (oldNode == this->
getBottom()) {
535 copiedOrder->bottom = newNode;
541 for (
auto const& i : oldNode->
states) {
543 newNode->
states.insert(i);
545 copiedOrder->nodes[i] = newNode;
549 STORM_LOG_ASSERT(copiedOrder->nodes[state] ==
nullptr,
"Copied order node already exists.");
558 doneStates.set(stateNumber);
566 std::cout <<
"Dot Output:\n"
567 <<
"digraph model {\n";
571 for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
572 if (nodes[i] !=
nullptr) {
573 stateCoverage.
set(i);
577 for (uint_fast64_t j = i + 1; j < numberOfStates; j++) {
579 stateCoverage.
set(j,
false);
582 std::cout <<
"\t" << nodeName(*
getNode(i)) <<
" [ label = \"" << nodeLabel(*
getNode(i)) <<
"\" ];\n";
589 for (uint_fast64_t s1 :
getNode(i)->statesAbove) {
593 std::set<Node*> seenNodes;
594 for (uint_fast64_t state : currentNode->
statesAbove) {
596 if (std::find(seenNodes.begin(), seenNodes.end(), n) == seenNodes.end()) {
599 std::cout <<
"\t" << nodeName(*currentNode) <<
" -> " << nodeName(*
getNode(state)) <<
";\n";
610 dotOutfile <<
"Dot Output:\n"
611 <<
"digraph model {\n";
619 for (uint_fast64_t j = i + 1; j < numberOfStates; j++) {
621 stateCoverage.
set(j,
false);
625 dotOutfile <<
"\t" << nodeName(*
getNode(i)) <<
" [ label = \"" << nodeLabel(*
getNode(i)) <<
"\" ];\n";
632 if (currentNode ==
nullptr) {
636 for (uint_fast64_t s1 :
getNode(i)->statesAbove) {
640 std::set<Node*> seenNodes;
641 for (uint_fast64_t state : currentNode->
statesAbove) {
643 if (std::find(seenNodes.begin(), seenNodes.end(), n) == seenNodes.end()) {
646 dotOutfile <<
"\t" << nodeName(*currentNode) <<
" -> " << nodeName(*
getNode(state)) <<
";\n";
659 this->numberOfStates = numberOfStates;
660 this->invalid =
false;
661 this->nodes = std::vector<Node*>(numberOfStates,
nullptr);
664 if (decomposition.
size() == 0) {
668 for (
auto& scc : decomposition) {
669 if (scc.size() == 1) {
670 trivialStates.
set(*(scc.begin()));
674 this->top =
new Node();
675 this->bottom =
new Node();
676 this->top->statesAbove = storm::storage::BitVector(numberOfStates,
false);
677 this->bottom->statesAbove = storm::storage::BitVector(numberOfStates,
false);
678 this->doneBuilding = doneBuilding;
681bool Order::aboveFast(Node* node1, Node* node2)
const {
683 for (
auto const& state : node1->states) {
684 found = ((node2->statesAbove))[state];
692bool Order::above(Node* node1, Node* node2) {
697 if (!trivialStates.full() || !doneBuilding) {
700 storm::storage::BitVector statesSeen((node2->statesAbove));
701 std::queue<uint_fast64_t> statesToHandle;
702 for (uint64_t state : statesSeen) {
703 statesToHandle.push(state);
705 while (!above && !statesToHandle.empty()) {
707 auto state = statesToHandle.front();
708 statesToHandle.pop();
710 if (aboveFast(node1, node)) {
714 for (uint64_t newState : node->statesAbove) {
715 if (!statesSeen[newState]) {
716 statesToHandle.push(newState);
717 statesSeen.set(newState);
723 for (
auto state : node1->states) {
724 node2->statesAbove.set(state);
730std::string Order::nodeName(Node n)
const {
731 auto itr = n.states.begin();
732 std::string name =
"n" + std::to_string(*itr);
736std::string Order::nodeLabel(Node n)
const {
737 if (n.states == top->states) {
740 if (n.states == bottom->states) {
743 auto itr = n.states.begin();
744 std::string label =
"s" + std::to_string(*itr);
746 if (itr != n.states.end()) {
747 label =
"[" + label +
"]";
753 return !doneStates.full();
757 return trivialStates[state];
761 while (!statesSorted.empty()) {
762 auto state = statesSorted.back();
763 statesSorted.pop_back();
764 if (!doneStates[state]) {
765 return {state,
true};
768 return {numberOfStates,
true};
773 auto state = statesToHandle.back();
774 statesToHandle.pop_back();
775 return {state,
false};
779 while (!statesToHandle.empty() && doneStates[statesToHandle.back()]) {
780 statesToHandle.pop_back();
782 return !statesToHandle.empty();
786 if (!doneStates[state]) {
787 statesToHandle.push_back(state);
792 statesSorted.push_back(state);
796 auto allAbove =
true;
797 auto allBelow =
true;
798 for (
auto& checkState : states) {
799 auto comp =
compare(checkState, state);
800 allAbove &= (comp ==
ABOVE || comp ==
SAME);
801 allBelow &= (comp ==
BELOW || comp ==
SAME);
803 return {allAbove, allBelow};
807 return doneStates.getNumberOfSetBits();
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 stdout.
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.
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_LOG_ASSERT(cond, message)
Nodes of the Reachability Order.
boost::container::flat_set< uint_fast64_t > states
storm::storage::BitVector statesAbove