3#include <boost/algorithm/string/join.hpp>
16Odd::Odd(std::shared_ptr<Odd> elseNode, uint_fast64_t elseOffset, std::shared_ptr<Odd> thenNode, uint_fast64_t thenOffset)
17 : elseNode(elseNode), thenNode(thenNode), elseOffset(elseOffset), thenOffset(thenOffset) {
18 STORM_LOG_ASSERT(
this != elseNode.get() &&
this != thenNode.get(),
"Cyclic ODD.");
22 return *this->thenNode;
26 return *this->elseNode;
30 return this->elseOffset;
34 this->elseOffset = newOffset;
38 return this->thenOffset;
42 this->thenOffset = newOffset;
46 return this->elseOffset + this->thenOffset;
51 if (this->elseNode ==
nullptr && this->thenNode ==
nullptr) {
56 if (this->elseNode == this->thenNode) {
57 return this->elseNode->getNodeCount();
59 return this->elseNode->getNodeCount() + this->thenNode->getNodeCount();
73 return this->elseNode ==
nullptr && this->thenNode ==
nullptr;
76template<
typename ValueType>
78 expandValuesToVectorRec(0, *
this, oldValues, 0, newOdd, newValues);
81template<
typename ValueType>
82void Odd::expandValuesToVectorRec(uint_fast64_t oldOffset,
storm::dd::Odd const& oldOdd, std::vector<ValueType>
const& oldValues, uint_fast64_t newOffset,
85 STORM_LOG_THROW(newOdd.
isTerminalNode(), storm::exceptions::InvalidArgumentException,
"The ODDs for the translation must have the same height.");
87 newValues[newOffset] += oldValues[oldOffset];
98 oldToNewIndexRec(0, *
this, 0, newOdd, callback);
102 std::function<
void(uint64_t oldOffset, uint64_t newOffset)>
const& callback) {
111 callback(oldOffset, newOffset);
114 oldToNewIndexRec(oldOffset, oldOdd, newOffset, newOdd.
getElseSuccessor(), callback);
126 std::ofstream dotFile;
130 dotFile <<
"digraph \"ODD\" {\n"
132 <<
"edge [dir = none];\n";
135 dotFile <<
"{ node [shape = plaintext];\n"
136 <<
"edge [style = invis];\n";
137 std::vector<std::string> levelNames;
138 for (uint_fast64_t level = 0; level < this->
getHeight(); ++level) {
139 levelNames.push_back(
"\"" + std::to_string(level) +
"\"");
141 dotFile << boost::join(levelNames,
" -> ") <<
";";
144 std::map<uint_fast64_t, std::unordered_set<storm::dd::Odd const*>> levelToOddNodesMap;
145 this->addToLevelToOddNodesMap(levelToOddNodesMap);
147 for (
auto const& levelNodes : levelToOddNodesMap) {
148 dotFile <<
"{ rank = same; \"" << levelNodes.first <<
"\"\n";
149 for (
auto const& node : levelNodes.second) {
150 dotFile <<
"\"" << node <<
"\";\n";
155 for (
auto const& levelNodes : levelToOddNodesMap) {
156 for (
auto const& node : levelNodes.second) {
157 dotFile <<
"\"" << node <<
"\" [label=\"" << node->getTotalOffset() <<
"\"];\n";
158 if (!node->isTerminalNode()) {
159 dotFile <<
"\"" << node <<
"\" -> \"" << &node->getElseSuccessor() <<
"\" [style=dashed, label=\"0\"];\n";
160 dotFile <<
"\"" << node <<
"\" -> \"" << &node->getThenSuccessor() <<
"\" [style=solid, label=\"" << node->getElseOffset() <<
"\"];\n";
170 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Operation not supported");
178 bool thenPath =
false;
193void Odd::addToLevelToOddNodesMap(std::map<uint_fast64_t, std::unordered_set<storm::dd::Odd const*>>& levelToOddNodesMap, uint_fast64_t level)
const {
194 levelToOddNodesMap[level].emplace(
this);
196 this->
getElseSuccessor().addToLevelToOddNodesMap(levelToOddNodesMap, level + 1);
197 if (this->thenNode != this->elseNode) {
198 this->
getThenSuccessor().addToLevelToOddNodesMap(levelToOddNodesMap, level + 1);
205 std::vector<storm::RationalNumber>& newValues)
const;
207 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.