diff --git a/src/storage/dd/CuddDd.cpp b/src/storage/dd/CuddDd.cpp index d3ad10493..23f148da0 100644 --- a/src/storage/dd/CuddDd.cpp +++ b/src/storage/dd/CuddDd.cpp @@ -1,8 +1,9 @@ #include "src/storage/dd/CuddDd.h" +#include "src/storage/dd/CuddDdManager.h" namespace storm { namespace dd { - Dd(std::shared_ptr> ddManager, ADD cuddAdd, std::unordered_set const& containedMetaVariableNames) noexcept : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) { + Dd::Dd(std::shared_ptr> ddManager, ADD cuddAdd, std::unordered_set const& containedMetaVariableNames) noexcept : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) { // Intentionally left empty. } @@ -13,10 +14,10 @@ namespace storm { } Dd& Dd::operator+=(Dd const& other) { - cuddAdd += other; + cuddAdd += other.getCuddAdd(); // Join the variable sets of the two participating DDs. - std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end())); + std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end())); return *this; } @@ -28,10 +29,10 @@ namespace storm { } Dd& Dd::operator*=(Dd const& other) { - cuddAdd *= other; + cuddAdd *= other.getCuddAdd(); // Join the variable sets of the two participating DDs. - std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end())); + std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end())); return *this; } @@ -43,10 +44,10 @@ namespace storm { } Dd& Dd::operator-=(Dd const& other) { - cuddAdd -= other; + cuddAdd -= other.getCuddAdd(); // Join the variable sets of the two participating DDs. - std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end())); + std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end())); return *this; } @@ -58,10 +59,10 @@ namespace storm { } Dd& Dd::operator/=(Dd const& other) { - cuddAdd.Divide(other); + cuddAdd.Divide(other.getCuddAdd()); // Join the variable sets of the two participating DDs. - std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().containedMetaVariableNames.end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end())); + std::copy(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end(), std::inserter(this->containedMetaVariableNames, this->containedMetaVariableNames.end())); return *this; } @@ -77,12 +78,137 @@ namespace storm { return *this; } + Dd Dd::equals(Dd const& other) const { + Dd result(*this); + result.getCuddAdd().Equals(other.getCuddAdd()); + return result; + } + + Dd Dd::notEquals(Dd const& other) const { + Dd result(*this); + result.getCuddAdd().NotEquals(other.getCuddAdd()); + return result; + } + + Dd Dd::less(Dd const& other) const { + Dd result(*this); + result.getCuddAdd().LessThan(other.getCuddAdd()); + return result; + } + + Dd Dd::lessOrEqual(Dd const& other) const { + Dd result(*this); + result.getCuddAdd().LessThanOrEqual(other.getCuddAdd()); + return result; + } + + Dd Dd::greater(Dd const& other) const { + Dd result(*this); + result.getCuddAdd().GreaterThan(other.getCuddAdd()); + return result; + } + + Dd Dd::greaterOrEqual(Dd const& other) const { + Dd result(*this); + result.getCuddAdd().GreaterThanOrEqual(other.getCuddAdd()); + return result; + } + + void Dd::existsAbstract(std::unordered_set const& metaVariableNames) { + Dd cubeDd(this->getDdManager()->getOne()); + + for (auto const& metaVariableName : metaVariableNames) { + DdMetaVariable const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName); + cubeDd *= metaVariable.getCube(); + } + + this->getCuddAdd().OrAbstract(cubeDd.getCuddAdd()); + } + + void Dd::sumAbstract(std::unordered_set const& metaVariableNames) { + Dd cubeDd(this->getDdManager()->getOne()); + + for (auto const& metaVariableName : metaVariableNames) { + DdMetaVariable const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName); + cubeDd *= metaVariable.getCube(); + } + + this->getCuddAdd().ExistAbstract(cubeDd.getCuddAdd()); + } + + void Dd::minAbstract(std::unordered_set const& metaVariableNames) { + Dd cubeDd(this->getDdManager()->getOne()); + + for (auto const& metaVariableName : metaVariableNames) { + DdMetaVariable const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName); + cubeDd *= metaVariable.getCube(); + } + + this->getCuddAdd().Minimum(cubeDd.getCuddAdd()); + } + + void Dd::maxAbstract(std::unordered_set const& metaVariableNames) { + Dd cubeDd(this->getDdManager()->getOne()); + + for (auto const& metaVariableName : metaVariableNames) { + DdMetaVariable const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName); + cubeDd *= metaVariable.getCube(); + } + + this->getCuddAdd().Maximum(cubeDd.getCuddAdd()); + } + + void Dd::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) { + std::unordered_map metaVariableNameToValueMap; + metaVariableNameToValueMap.emplace(metaVariableName, variableValue); + this->setValue(metaVariableNameToValueMap, targetValue); + } + + void Dd::setValue(std::string const& metaVariableName1, int_fast64_t variableValue1, std::string const& metaVariableName2, int_fast64_t variableValue2, double targetValue) { + std::unordered_map metaVariableNameToValueMap; + metaVariableNameToValueMap.emplace(metaVariableName1, variableValue1); + metaVariableNameToValueMap.emplace(metaVariableName2, variableValue2); + this->setValue(metaVariableNameToValueMap, targetValue); + } + + void Dd::setValue(std::unordered_map const& metaVariableNameToValueMap, double targetValue) { + // TODO: Fill this + } + + bool Dd::containsMetaVariable(std::string const& metaVariableName) const { + auto const& metaVariable = containedMetaVariableNames.find(metaVariableName); + return metaVariable != containedMetaVariableNames.end(); + } + + bool Dd::containsMetaVariables(std::unordered_set metaVariableNames) const { + for (auto const& metaVariableName : metaVariableNames) { + auto const& metaVariable = containedMetaVariableNames.find(metaVariableName); + + if (metaVariable == containedMetaVariableNames.end()) { + return false; + } + } + return true; + } + + std::unordered_set const& Dd::getContainedMetaVariableNames() const { + return containedMetaVariableNames; + } + void Dd::exportToDot(std::string const& filename) const { FILE* filePointer = fopen(filename.c_str() , "w"); this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd}, nullptr, nullptr, filePointer); fclose(filePointer); } + ADD Dd::getCuddAdd() { + return this->cuddAdd; + } + + ADD const& Dd::getCuddAdd() const { + return this->cuddAdd; + } + std::shared_ptr> Dd::getDdManager() const { return this->ddManager; } diff --git a/src/storage/dd/CuddDd.h b/src/storage/dd/CuddDd.h index eff759bd3..b0a3e33eb 100644 --- a/src/storage/dd/CuddDd.h +++ b/src/storage/dd/CuddDd.h @@ -1,14 +1,18 @@ #ifndef STORM_STORAGE_DD_CUDDDD_H_ #define STORM_STORAGE_DD_CUDDDD_H_ +#include +#include + #include "src/storage/dd/Dd.h" -#include "src/storage/dd/CuddDdManager.h" // Include the C++-interface of CUDD. #include "cuddObj.hh" namespace storm { namespace dd { + // Forward-declare the DdManager class. + template class DdManager; template<> class Dd { @@ -264,6 +268,20 @@ namespace storm { std::shared_ptr> getDdManager() const; private: + /*! + * Retrieves the CUDD ADD object associated with this DD. + * + * @return The CUDD ADD object assoicated with this DD. + */ + ADD getCuddAdd(); + + /*! + * Retrieves the CUDD ADD object associated with this DD. + * + * @return The CUDD ADD object assoicated with this DD. + */ + ADD const& getCuddAdd() const; + /*! * Creates a DD that encapsulates the given CUDD ADD. * diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp index 580c6c9a6..40c11fbaa 100644 --- a/src/storage/dd/CuddDdManager.cpp +++ b/src/storage/dd/CuddDdManager.cpp @@ -24,10 +24,10 @@ namespace storm { std::vector> variables; for (std::size_t i = 0; i < numberOfBits; ++i) { - variables.emplace_back(cuddManager.addVar()); + variables.emplace_back(Dd(this->shared_from_this(), cuddManager.addVar(), {name})); } - metaVariableMap.emplace(name, low, high, variables, this->shared_from_this()); + metaVariableMap.emplace(name, DdMetaVariable(name, low, high, variables, this->shared_from_this())); } void DdManager::addMetaVariablesInterleaved(std::vector const& names, int_fast64_t low, int_fast64_t high) { @@ -40,13 +40,13 @@ namespace storm { std::vector>> variables; for (uint_fast64_t bit = 0; bit < numberOfBits; ++bit) { for (uint_fast64_t i = 0; i < names.size(); ++i) { - variables[i].emplace_back(cuddManager.addVar()); + variables[i].emplace_back(Dd(this->shared_from_this(), cuddManager.addVar(), {names[i]})); } } // Now add the meta variables. for (uint_fast64_t i = 0; i < names.size(); ++i) { - metaVariableMap.emplace(names[i], low, high, variables[i], this->shared_from_this()); + metaVariableMap.emplace(names[i], DdMetaVariable(names[i], low, high, variables[i], this->shared_from_this())); } } diff --git a/src/storage/dd/CuddDdManager.h b/src/storage/dd/CuddDdManager.h index 72f2aea0c..ede42104d 100644 --- a/src/storage/dd/CuddDdManager.h +++ b/src/storage/dd/CuddDdManager.h @@ -16,7 +16,6 @@ namespace storm { template<> class DdManager : std::enable_shared_from_this> { // To break the cylic dependencies, we need to forward-declare the other DD-related classes. - friend class DdMetaVariable; friend class Dd; /*! diff --git a/src/storage/dd/DdMetaVariable.cpp b/src/storage/dd/DdMetaVariable.cpp index c2795562b..d5cae858c 100644 --- a/src/storage/dd/DdMetaVariable.cpp +++ b/src/storage/dd/DdMetaVariable.cpp @@ -1,4 +1,5 @@ #include "src/storage/dd/DdMetaVariable.h" +#include "src/storage/dd/CuddDdManager.h" namespace storm { namespace dd { diff --git a/src/storage/dd/DdMetaVariable.h b/src/storage/dd/DdMetaVariable.h index f784fda2c..6bf5f6c3c 100644 --- a/src/storage/dd/DdMetaVariable.h +++ b/src/storage/dd/DdMetaVariable.h @@ -6,16 +6,19 @@ #include #include -#include "src/storage/dd/CuddDdManager.h" #include "src/storage/dd/CuddDd.h" namespace storm { namespace dd { + // Forward-declare the DdManager class. + template class DdManager; template class DdMetaVariable { + public: // Declare the DdManager class as friend so it can access the internals of a meta variable. friend class DdManager; + friend class Dd; /*! * Creates a meta variable with the given name, range bounds.