11 init(numberOfStates, decomposition);
12 this->numberOfAddedStates = 0;
13 this->onlyBottomTopOrder =
true;
14 for (
auto const& i : *topStates) {
15 this->doneStates.
set(i);
17 this->top->
states.insert(i);
19 numberOfAddedStates++;
21 this->statesSorted = statesSorted;
23 for (
auto const& i : *bottomStates) {
24 this->doneStates.
set(i);
25 this->bottom->
states.insert(i);
26 this->nodes[i] = bottom;
27 numberOfAddedStates++;
29 assert(numberOfAddedStates <= numberOfStates);
31 if (numberOfAddedStates == numberOfStates) {
32 doneBuilding = doneStates.
full();
36Order::Order(uint_fast64_t topState, uint_fast64_t bottomState, uint_fast64_t numberOfStates,
38 init(numberOfStates, decomposition);
40 this->onlyBottomTopOrder =
true;
41 this->doneStates.
set(topState);
44 this->top->
states.insert(topState);
45 this->nodes[topState] = top;
47 this->doneStates.
set(bottomState);
49 this->bottom->
states.insert(bottomState);
50 this->nodes[bottomState] = bottom;
51 this->numberOfAddedStates = 2;
52 assert(numberOfAddedStates <= numberOfStates);
54 this->statesSorted = statesSorted;
56 if (numberOfAddedStates == numberOfStates) {
57 doneBuilding = doneStates.
full();
62 this->invalid =
false;
68 assert(nodes[state] ==
nullptr);
76 assert(nodes[state] ==
nullptr);
78 nodes[state] = newNode;
80 newNode->
states.insert(state);
82 for (
auto const& state : top->
states) {
86 numberOfAddedStates++;
87 onlyBottomTopOrder =
false;
88 if (numberOfAddedStates == numberOfStates) {
89 doneBuilding = doneStates.
full();
96 assert(nodes[state] ==
nullptr);
98 nodes[state] = newNode;
99 newNode->
states.insert(state);
101 for (
auto statesAbove : node->
states) {
105 numberOfAddedStates++;
106 onlyBottomTopOrder =
false;
107 if (numberOfAddedStates == numberOfStates) {
108 doneBuilding = doneStates.
full();
110 assert(numberOfAddedStates <= numberOfStates);
114 STORM_LOG_INFO(
"Add " << state <<
" between (above) " << *above->
states.begin() <<
" and " << *below->
states.begin() <<
'\n');
117 assert(above !=
nullptr && below !=
nullptr);
118 if (nodes[state] ==
nullptr) {
121 nodes[state] = newNode;
123 newNode->
states.insert(state);
125 for (
auto aboveStates : above->
states) {
129 numberOfAddedStates++;
130 onlyBottomTopOrder =
false;
131 if (numberOfAddedStates == numberOfStates) {
132 doneBuilding = doneStates.
full();
134 assert(numberOfAddedStates <= numberOfStates);
144 assert(
getNode(below)->states.find(below) !=
getNode(below)->states.end());
145 assert(
getNode(above)->states.find(above) !=
getNode(above)->states.end());
167 for (
auto const& state : above->
states) {
176 if (nodes[state] ==
nullptr) {
178 node->
states.insert(state);
180 numberOfAddedStates++;
181 if (numberOfAddedStates == numberOfStates) {
182 doneBuilding = doneStates.
full();
184 assert(numberOfAddedStates <= numberOfStates);
201 for (
auto const& i : node2->
states) {
205 for (
auto const& node : nodes) {
206 if (node !=
nullptr) {
207 for (
auto state2 : node2->
states) {
208 if (node->statesAbove[state2]) {
209 for (
auto state1 : node1->
states) {
217 for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
218 for (uint_fast64_t j = i + 1; j < numberOfStates; ++j) {
222 (comp1 ==
SAME && comp2 ==
SAME))) {
247 if (node1 !=
nullptr && node2 !=
nullptr) {
248 if (node1 == node2) {
252 if ((hypothesis ==
UNKNOWN || hypothesis ==
ABOVE) && ((node1 == top || node2 == bottom) || aboveFast(node1, node2))) {
256 if ((hypothesis ==
UNKNOWN || hypothesis ==
BELOW) && ((node2 == top || node1 == bottom) || aboveFast(node2, node1))) {
259 }
else if (node1 == top || node2 == bottom) {
261 }
else if (node2 == top || node1 == bottom) {
268 if (node1 !=
nullptr && node2 !=
nullptr) {
273 if ((hypothesis ==
UNKNOWN || hypothesis ==
ABOVE) && above(node1, node2)) {
274 assert(!above(node2, node1));
278 if ((hypothesis ==
UNKNOWN || hypothesis ==
BELOW) && above(node2, node1)) {
281 }
else if (node1 == top || node2 == bottom) {
283 }
else if (node2 == top || node1 == bottom) {
290 return state < numberOfStates && nodes[state] !=
nullptr;
298 assert(!doneStates.
full() || numberOfAddedStates == numberOfStates);
299 return doneStates.
full();
307 assert(stateNumber < numberOfStates);
308 return nodes[stateNumber];
324 return numberOfAddedStates;
328 return numberOfStates;
332 auto states = bottom->
states;
333 return states.find(state) != states.end();
337 auto states = top->
states;
338 return states.find(state) != states.end();
342 return onlyBottomTopOrder;
346 assert(states !=
nullptr);
347 uint_fast64_t numberOfStatesToSort = states->size();
348 std::vector<uint_fast64_t> result;
350 for (
auto state : *states) {
351 bool unknown =
false;
352 if (result.size() == 0) {
353 result.push_back(state);
356 for (
auto itr = result.begin(); itr != result.end(); ++itr) {
357 auto compareRes =
compare(state, (*itr));
358 if (compareRes ==
ABOVE || compareRes ==
SAME) {
360 result.insert(itr, state);
363 }
else if (compareRes ==
UNKNOWN) {
372 result.push_back(state);
376 while (result.size() < numberOfStatesToSort) {
377 result.push_back(numberOfStates);
379 assert(result.size() == numberOfStatesToSort);
384 std::vector<uint_fast64_t>
const& states) {
385 std::vector<uint_fast64_t> statesSorted;
386 statesSorted.push_back(currentState);
388 bool oneUnknown =
false;
389 bool unknown =
false;
390 uint_fast64_t s1 = numberOfStates;
391 uint_fast64_t s2 = numberOfStates;
392 for (
auto& state : states) {
395 for (
auto itr = statesSorted.begin(); itr != statesSorted.end(); ++itr) {
396 auto compareRes =
compare(state, (*itr));
397 if (compareRes ==
ABOVE || compareRes ==
SAME) {
403 statesSorted.insert(itr, state);
405 }
else if (compareRes ==
UNKNOWN && !oneUnknown) {
412 }
else if (compareRes ==
UNKNOWN && oneUnknown) {
420 statesSorted.push_back(state);
422 if (unknown && oneUnknown) {
426 if (!unknown && oneUnknown) {
427 assert(statesSorted.size() == states.size());
430 assert(s1 == numberOfStates || (s1 != numberOfStates && s2 == numberOfStates && statesSorted.size() == states.size()) ||
431 (s1 != numberOfStates && s2 != numberOfStates && statesSorted.size() < states.size()));
433 return {{s1, s2}, statesSorted};
437 assert(states !=
nullptr);
438 uint_fast64_t numberOfStatesToSort = states->size();
439 std::vector<uint_fast64_t> result;
441 for (
auto state : *states) {
442 bool unknown =
false;
443 if (result.size() == 0) {
444 result.push_back(state);
447 for (
auto itr = result.begin(); itr != result.end(); ++itr) {
448 auto compareRes =
compare(state, (*itr));
449 if (compareRes ==
ABOVE || compareRes ==
SAME) {
451 result.insert(itr, state);
454 }
else if (compareRes ==
UNKNOWN) {
455 return {{(*itr), state}, std::move(result)};
462 result.push_back(state);
467 assert(result.size() == numberOfStatesToSort);
468 return {{numberOfStates, numberOfStates}, std::move(result)};
473 std::vector<uint_fast64_t> result;
475 for (
auto state : *states) {
476 bool unknown =
false;
477 if (result.size() == 0) {
478 result.push_back(state);
481 for (
auto itr = result.begin(); itr != result.end(); ++itr) {
482 auto compareRes =
compare(state, (*itr));
483 if (compareRes ==
ABOVE || compareRes ==
SAME) {
485 result.insert(itr, state);
488 }
else if (compareRes ==
UNKNOWN) {
497 result.push_back(state);
501 while (result.size() < numberOfStatesToSort) {
502 result.push_back(numberOfStates);
504 assert(result.size() == numberOfStatesToSort);
512 std::shared_ptr<Order> copiedOrder = std::make_shared<Order>();
513 copiedOrder->nodes = std::vector<Node*>(numberOfStates,
nullptr);
516 copiedOrder->statesSorted = std::vector<uint_fast64_t>(this->statesSorted);
517 copiedOrder->statesToHandle = std::vector<uint_fast64_t>(this->statesToHandle);
520 copiedOrder->numberOfAddedStates = this->numberOfAddedStates;
521 copiedOrder->doneBuilding = this->doneBuilding;
525 for (uint_fast64_t state = 0; state < numberOfStates; ++state) {
526 Node* oldNode = nodes.at(state);
527 if (oldNode !=
nullptr) {
528 if (!seenStates[*(oldNode->
states.begin())]) {
530 if (oldNode == this->
getTop()) {
531 copiedOrder->top = newNode;
532 }
else if (oldNode == this->
getBottom()) {
533 copiedOrder->bottom = newNode;
539 for (
auto const& i : oldNode->
states) {
540 assert(!seenStates[i]);
541 newNode->
states.insert(i);
543 copiedOrder->nodes[i] = newNode;
547 assert(copiedOrder->nodes[state] ==
nullptr);
556 doneStates.
set(stateNumber);
563 STORM_PRINT(
"Dot Output:\n" <<
"digraph model {\n");
567 for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
568 if (nodes[i] !=
nullptr) {
569 stateCoverage.
set(i);
573 for (uint_fast64_t j = i + 1; j < numberOfStates; j++) {
575 stateCoverage.
set(j,
false);
588 std::set<Node*> seenNodes;
589 for (uint_fast64_t state : currentNode->
statesAbove) {
591 if (std::find(seenNodes.begin(), seenNodes.end(), n) == seenNodes.end()) {
594 STORM_PRINT(
"\t" << nodeName(*currentNode) <<
" -> " << nodeName(*
getNode(state)) <<
";\n");
605 dotOutfile <<
"Dot Output:\n"
606 <<
"digraph model {\n";
614 for (uint_fast64_t j = i + 1; j < numberOfStates; j++) {
616 stateCoverage.
set(j,
false);
619 dotOutfile <<
"\t" << nodeName(*
getNode(i)) <<
" [ label = \"" << nodeLabel(*
getNode(i)) <<
"\" ];\n";
626 if (currentNode == NULL) {
634 std::set<Node*> seenNodes;
635 for (uint_fast64_t state : currentNode->
statesAbove) {
637 if (std::find(seenNodes.begin(), seenNodes.end(), n) == seenNodes.end()) {
640 dotOutfile <<
"\t" << nodeName(*currentNode) <<
" -> " << nodeName(*
getNode(state)) <<
";\n";
653 this->numberOfStates = numberOfStates;
654 this->invalid =
false;
655 this->nodes = std::vector<Node*>(numberOfStates,
nullptr);
658 if (decomposition.
size() == 0) {
662 for (
auto& scc : decomposition) {
663 if (scc.size() == 1) {
664 trivialStates.
set(*(scc.begin()));
668 this->top =
new Node();
669 this->bottom =
new Node();
672 this->doneBuilding = doneBuilding;
675bool Order::aboveFast(Node* node1, Node* node2)
const {
677 for (
auto const& state : node1->states) {
678 found = ((node2->statesAbove))[state];
686bool Order::above(Node* node1, Node* node2) {
687 assert(!aboveFast(node1, node2));
691 if (!trivialStates.
full() || !doneBuilding) {
695 std::queue<uint_fast64_t> statesToHandle;
696 for (
auto state : statesSeen) {
697 statesToHandle.push(state);
699 while (!above && !statesToHandle.empty()) {
701 auto state = statesToHandle.front();
702 statesToHandle.pop();
704 if (aboveFast(node1, node)) {
708 for (
auto newState : node->statesAbove) {
709 if (!statesSeen[newState]) {
710 statesToHandle.push(newState);
711 statesSeen.set(newState);
717 for (
auto state : node1->states) {
718 node2->statesAbove.set(state);
724std::string Order::nodeName(Node n)
const {
725 auto itr = n.states.begin();
726 std::string name =
"n" + std::to_string(*itr);
730std::string Order::nodeLabel(Node n)
const {
731 if (n.states == top->
states)
733 if (n.states == bottom->
states)
735 auto itr = n.states.begin();
736 std::string label =
"s" + std::to_string(*itr);
738 if (itr != n.states.end())
739 label =
"[" + label +
"]";
744 return !doneStates.
full();
748 return trivialStates[state];
752 while (!statesSorted.empty()) {
753 auto state = statesSorted.back();
754 statesSorted.pop_back();
755 if (!doneStates[state]) {
756 return {state,
true};
759 return {numberOfStates,
true};
764 auto state = statesToHandle.back();
765 statesToHandle.pop_back();
766 return {state,
false};
770 while (!statesToHandle.empty() && doneStates[statesToHandle.back()]) {
771 statesToHandle.pop_back();
773 return !statesToHandle.empty();
777 if (!doneStates[state]) {
778 statesToHandle.push_back(state);
783 statesSorted.push_back(state);
787 auto allAbove =
true;
788 auto allBelow =
true;
789 for (
auto& checkState : states) {
790 auto comp =
compare(checkState, state);
791 allAbove &= (comp ==
ABOVE || comp ==
SAME);
792 allBelow &= (comp ==
BELOW || comp ==
SAME);
794 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.
bool full() const
Retrieves whether all bits are set in this bit vector.
uint_fast64_t getNextSetIndex(uint_fast64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to true in the bit vector.
void set(uint_fast64_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.
uint_fast64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
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