3#include <boost/algorithm/string/join.hpp>
18Odd::Odd(std::shared_ptr<Odd> elseNode, uint_fast64_t elseOffset, std::shared_ptr<Odd> thenNode, uint_fast64_t thenOffset)
19 : elseNode(elseNode), thenNode(thenNode), elseOffset(elseOffset), thenOffset(thenOffset) {
20 STORM_LOG_ASSERT(
this != elseNode.get() &&
this != thenNode.get(),
"Cyclic ODD.");
24 return *this->thenNode;
28 return *this->elseNode;
32 return this->elseOffset;
36 this->elseOffset = newOffset;
40 return this->thenOffset;
44 this->thenOffset = newOffset;
48 return this->elseOffset + this->thenOffset;
53 if (this->elseNode ==
nullptr && this->thenNode ==
nullptr) {
58 if (this->elseNode == this->thenNode) {
59 return this->elseNode->getNodeCount();
61 return this->elseNode->getNodeCount() + this->thenNode->getNodeCount();
75 return this->elseNode ==
nullptr && this->thenNode ==
nullptr;
78template<
typename ValueType>
80 expandValuesToVectorRec(0, *
this, oldValues, 0, newOdd, newValues);
83template<
typename ValueType>
84void Odd::expandValuesToVectorRec(uint_fast64_t oldOffset,
storm::dd::Odd const& oldOdd, std::vector<ValueType>
const& oldValues, uint_fast64_t newOffset,
87 STORM_LOG_THROW(newOdd.
isTerminalNode(), storm::exceptions::InvalidArgumentException,
"The ODDs for the translation must have the same height.");
89 newValues[newOffset] += oldValues[oldOffset];
100 oldToNewIndexRec(0, *
this, 0, newOdd, callback);
104 std::function<
void(uint64_t oldOffset, uint64_t newOffset)>
const& callback) {
113 callback(oldOffset, newOffset);
116 oldToNewIndexRec(oldOffset, oldOdd, newOffset, newOdd.
getElseSuccessor(), callback);
128 std::ofstream dotFile;
132 dotFile <<
"digraph \"ODD\" {\n"
134 <<
"edge [dir = none];\n";
137 dotFile <<
"{ node [shape = plaintext];\n"
138 <<
"edge [style = invis];\n";
139 std::vector<std::string> levelNames;
140 for (uint_fast64_t level = 0; level < this->
getHeight(); ++level) {
141 levelNames.push_back(
"\"" + std::to_string(level) +
"\"");
143 dotFile << boost::join(levelNames,
" -> ") <<
";";
146 std::map<uint_fast64_t, std::unordered_set<storm::dd::Odd const*>> levelToOddNodesMap;
147 this->addToLevelToOddNodesMap(levelToOddNodesMap);
149 for (
auto const& levelNodes : levelToOddNodesMap) {
150 dotFile <<
"{ rank = same; \"" << levelNodes.first <<
"\"\n";
152 for (
auto const& node : levelNodes.second) {
153 dotFile <<
"\"" << node <<
"\";\n";
158 for (
auto const& levelNodes : levelToOddNodesMap) {
159 for (
auto const& node : levelNodes.second) {
160 dotFile <<
"\"" << node <<
"\" [label=\"" << node->getTotalOffset() <<
"\"];\n";
161 if (!node->isTerminalNode()) {
162 dotFile <<
"\"" << node <<
"\" -> \"" << &node->getElseSuccessor() <<
"\" [style=dashed, label=\"0\"];\n";
163 dotFile <<
"\"" << node <<
"\" -> \"" << &node->getThenSuccessor() <<
"\" [style=solid, label=\"" << node->getElseOffset() <<
"\"];\n";
173 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Operation not supported");
181 bool thenPath =
false;
196void Odd::addToLevelToOddNodesMap(std::map<uint_fast64_t, std::unordered_set<storm::dd::Odd const*>>& levelToOddNodesMap, uint_fast64_t level)
const {
197 levelToOddNodesMap[level].emplace(
this);
199 this->
getElseSuccessor().addToLevelToOddNodesMap(levelToOddNodesMap, level + 1);
200 if (this->thenNode != this->elseNode) {
201 this->
getThenSuccessor().addToLevelToOddNodesMap(levelToOddNodesMap, level + 1);
208 std::vector<storm::RationalNumber>& newValues)
const;
210 std::vector<storm::RationalFunction>& newValues)
const;
Odd const & getThenSuccessor() const
Retrieves the then-successor of this ODD node.
void expandExplicitVector(storm::dd::Odd const &newOdd, std::vector< ValueType > const &oldValues, std::vector< ValueType > &newValues) const
Adds the old values to the new values.
void exportToText(std::string const &filename) const
Exports the ODD in the text format to the given file.
uint_fast64_t getNodeCount() const
Retrieves the size of the ODD.
uint_fast64_t getTotalOffset() const
Retrieves the total offset, i.e., the sum of the then- and else-offset.
uint_fast64_t getElseOffset() const
Retrieves the else-offset of this ODD node.
void oldToNewIndex(storm::dd::Odd const &newOdd, std::function< void(uint64_t oldOffset, uint64_t newOffset)> const &callback) const
Translates the indices of the old ODD to that of the new ODD by calling the callback for each old-new...
void setElseOffset(uint_fast64_t newOffset)
Sets the else-offset of this ODD node.
uint_fast64_t getHeight() const
Retrieves the height of the ODD.
bool isTerminalNode() const
Checks whether the given ODD node is a terminal node, i.e.
void setThenOffset(uint_fast64_t newOffset)
Sets the then-offset of this ODD node.
storm::storage::BitVector getEncoding(uint64_t offset, uint64_t variableCount=0) const
Retrieves the encoding for the given offset.
Odd const & getElseSuccessor() const
Retrieves the else-successor of this ODD node.
void exportToDot(std::string const &filename) const
Exports the ODD in the dot format to the given file.
uint_fast64_t getThenOffset() const
Retrieves the then-offset of this ODD node.
A bit vector that is internally represented as a vector of 64-bit values.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
void getEncodingRec(Odd const &odd, uint64_t index, uint64_t offset, storm::storage::BitVector &result)
void closeFile(std::ofstream &stream)
Close the given file after writing.
void openFile(std::string const &filepath, std::ofstream &filestream, bool append=false, bool silent=false)
Open the given file for writing.