#include #include "src/storage/dd/CuddDdManager.h" #include "src/exceptions/InvalidArgumentException.h" namespace storm { namespace dd { DdManager::DdManager() : metaVariableMap(), cuddManager() { // Intentionally left empty. } Dd DdManager::getOne() { return Dd(this->shared_from_this(), cuddManager.addOne(), {""}); } Dd DdManager::getZero() { return Dd(this->shared_from_this(), cuddManager.addZero(), {""}); } Dd DdManager::getConstant(double value) { return Dd(this->shared_from_this(), cuddManager.constant(value), {""}); } Dd DdManager::getEncoding(std::string const& metaVariableName, int_fast64_t value) { std::vector> ddVariables = this->getMetaVariable(metaVariableName).getDdVariables(); Dd result; if (value & (1ull << (ddVariables.size() - 1))) { result = ddVariables[0]; } else { result = ddVariables[0]; } for (std::size_t i = 1; i < ddVariables.size(); ++i) { if (value & (1ull << (ddVariables.size() - i - 1))) { result *= ddVariables[i]; } else { result *= ~ddVariables[i]; } } return result; } Dd DdManager::getRange(std::string const metaVariableName) { storm::dd::DdMetaVariable const& metaVariable = this->getMetaVariable(metaVariableName); Dd result = this->getZero(); for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) { result.setValue(metaVariableName, value - metaVariable.getLow(), static_cast(value)); } return result; } void DdManager::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) { if (high == low) { throw storm::exceptions::InvalidArgumentException() << "Range of meta variable must be at least 2 elements."; } std::size_t numberOfBits = static_cast(std::ceil(std::log2(high - low))); std::vector> variables; for (std::size_t i = 0; i < numberOfBits; ++i) { variables.emplace_back(Dd(this->shared_from_this(), cuddManager.addVar(), {name})); } 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) { if (names.size() == 0) { throw storm::exceptions::InvalidArgumentException() << "Illegal to add zero meta variables."; } // Add the variables in interleaved order. std::size_t numberOfBits = static_cast(std::ceil(std::log2(high - low))); 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(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], DdMetaVariable(names[i], low, high, variables[i], this->shared_from_this())); } } DdMetaVariable const& DdManager::getMetaVariable(std::string const& metaVariableName) const { auto const& nameVariablePair = metaVariableMap.find(metaVariableName); if (nameVariablePair == metaVariableMap.end()) { throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name."; } return nameVariablePair->second; } std::set DdManager::getAllMetaVariableNames() const { std::set result; for (auto const& nameValuePair : metaVariableMap) { result.insert(nameValuePair.first); } return result; } Cudd& DdManager::getCuddManager() { return this->cuddManager; } } }