3#include <boost/algorithm/string/join.hpp>
15Odd::Odd(std::shared_ptr<Odd> elseNode, uint_fast64_t elseOffset, std::shared_ptr<Odd> thenNode, uint_fast64_t thenOffset)
16 : elseNode(elseNode), thenNode(thenNode), elseOffset(elseOffset), thenOffset(thenOffset) {
17 STORM_LOG_ASSERT(
this != elseNode.get() &&
this != thenNode.get(),
"Cyclic ODD.");
21 return *this->thenNode;
25 return *this->elseNode;
29 return this->elseOffset;
33 this->elseOffset = newOffset;
37 return this->thenOffset;
41 this->thenOffset = newOffset;
45 return this->elseOffset + this->thenOffset;
50 if (this->elseNode ==
nullptr && this->thenNode ==
nullptr) {
55 if (this->elseNode == this->thenNode) {
56 return this->elseNode->getNodeCount();
58 return this->elseNode->getNodeCount() + this->thenNode->getNodeCount();
72 return this->elseNode ==
nullptr && this->thenNode ==
nullptr;
75template<
typename ValueType>
77 expandValuesToVectorRec(0, *
this, oldValues, 0, newOdd, newValues);
80template<
typename ValueType>
81void Odd::expandValuesToVectorRec(uint_fast64_t oldOffset,
storm::dd::Odd const& oldOdd, std::vector<ValueType>
const& oldValues, uint_fast64_t newOffset,
84 STORM_LOG_THROW(newOdd.
isTerminalNode(), storm::exceptions::InvalidArgumentException,
"The ODDs for the translation must have the same height.");
86 newValues[newOffset] += oldValues[oldOffset];
97 oldToNewIndexRec(0, *
this, 0, newOdd, callback);
101 std::function<
void(uint64_t oldOffset, uint64_t newOffset)>
const& callback) {
110 callback(oldOffset, newOffset);
113 oldToNewIndexRec(oldOffset, oldOdd, newOffset, newOdd.
getElseSuccessor(), callback);
125 std::ofstream dotFile;
129 dotFile <<
"digraph \"ODD\" {\n"
131 <<
"edge [dir = none];\n";
134 dotFile <<
"{ node [shape = plaintext];\n"
135 <<
"edge [style = invis];\n";
136 std::vector<std::string> levelNames;
137 for (uint_fast64_t level = 0; level < this->
getHeight(); ++level) {
138 levelNames.push_back(
"\"" + std::to_string(level) +
"\"");
140 dotFile << boost::join(levelNames,
" -> ") <<
";";
143 std::map<uint_fast64_t, std::unordered_set<storm::dd::Odd const*>> levelToOddNodesMap;
144 this->addToLevelToOddNodesMap(levelToOddNodesMap);
146 for (
auto const& levelNodes : levelToOddNodesMap) {
147 dotFile <<
"{ rank = same; \"" << levelNodes.first <<
"\"\n";
148 for (
auto const& node : levelNodes.second) {
149 dotFile <<
"\"" << node <<
"\";\n";
154 for (
auto const& levelNodes : levelToOddNodesMap) {
155 for (
auto const& node : levelNodes.second) {
156 dotFile <<
"\"" << node <<
"\" [label=\"" << node->getTotalOffset() <<
"\"];\n";
157 if (!node->isTerminalNode()) {
158 dotFile <<
"\"" << node <<
"\" -> \"" << &node->getElseSuccessor() <<
"\" [style=dashed, label=\"0\"];\n";
159 dotFile <<
"\"" << node <<
"\" -> \"" << &node->getThenSuccessor() <<
"\" [style=solid, label=\"" << node->getElseOffset() <<
"\"];\n";
169 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Operation not supported");
177 bool thenPath =
false;
192void Odd::addToLevelToOddNodesMap(std::map<uint_fast64_t, std::unordered_set<storm::dd::Odd const*>>& levelToOddNodesMap, uint_fast64_t level)
const {
193 levelToOddNodesMap[level].emplace(
this);
195 this->
getElseSuccessor().addToLevelToOddNodesMap(levelToOddNodesMap, level + 1);
196 if (this->thenNode != this->elseNode) {
197 this->
getThenSuccessor().addToLevelToOddNodesMap(levelToOddNodesMap, level + 1);
204 std::vector<storm::RationalNumber>& newValues)
const;
206 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(uint64_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.