#include #include "src/storage/dd/Bdd.h" #include "src/storage/dd/Add.h" #include "src/storage/dd/Odd.h" #include "src/logic/ComparisonType.h" #include "src/storage/dd/DdMetaVariable.h" #include "src/storage/dd/DdManager.h" #include "src/storage/dd/Odd.h" #include "src/storage/BitVector.h" #include "src/utility/macros.h" #include "src/exceptions/InvalidArgumentException.h" namespace storm { namespace dd { template Bdd::Bdd(DdManager const& ddManager, InternalBdd const& internalBdd, std::set const& containedMetaVariables) : Dd(ddManager, containedMetaVariables), internalBdd(internalBdd) { // Intentionally left empty. } template Bdd Bdd::fromVector(DdManager const& ddManager, std::vector const& explicitValues, storm::dd::Odd const& odd, std::set const& metaVariables, storm::logic::ComparisonType comparisonType, double value) { switch (comparisonType) { case storm::logic::ComparisonType::Less: return fromVector(ddManager, explicitValues, odd, metaVariables, std::bind(std::greater(), value, std::placeholders::_1)); case storm::logic::ComparisonType::LessEqual: return fromVector(ddManager, explicitValues, odd, metaVariables, std::bind(std::greater_equal(), value, std::placeholders::_1)); case storm::logic::ComparisonType::Greater: return fromVector(ddManager, explicitValues, odd, metaVariables, std::bind(std::less(), value, std::placeholders::_1)); case storm::logic::ComparisonType::GreaterEqual: return fromVector(ddManager, explicitValues, odd, metaVariables, std::bind(std::less_equal(), value, std::placeholders::_1)); } } template template Bdd Bdd::fromVector(DdManager const& ddManager, std::vector const& values, Odd const& odd, std::set const& metaVariables, std::function const& filter) { return Bdd(ddManager, InternalBdd::fromVector(&ddManager.internalDdManager, values, odd, ddManager.getSortedVariableIndices(metaVariables), filter), metaVariables); } template bool Bdd::operator==(Bdd const& other) const { return internalBdd == other.internalBdd; } template bool Bdd::operator!=(Bdd const& other) const { return internalBdd != other.internalBdd; } template Bdd Bdd::ite(Bdd const& thenBdd, Bdd const& elseBdd) const { std::set metaVariables = Dd::joinMetaVariables(thenBdd, elseBdd); metaVariables.insert(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end()); return Bdd(this->getDdManager(), internalBdd.ite(thenBdd.internalBdd, elseBdd.internalBdd), metaVariables); } template template Add Bdd::ite(Add const& thenAdd, Add const& elseAdd) const { std::set metaVariables = Dd::joinMetaVariables(thenAdd, elseAdd); metaVariables.insert(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end()); return Add(this->getDdManager(), internalBdd.ite(thenAdd.internalAdd, elseAdd.internalAdd), metaVariables); } template Bdd Bdd::operator||(Bdd const& other) const { return Bdd(this->getDdManager(), internalBdd || other.internalBdd, Dd::joinMetaVariables(*this, other)); } template Bdd& Bdd::operator|=(Bdd const& other) { this->addMetaVariables(other.getContainedMetaVariables()); internalBdd |= other.internalBdd; return *this; } template Bdd Bdd::operator&&(Bdd const& other) const { return Bdd(this->getDdManager(), internalBdd && other.internalBdd, Dd::joinMetaVariables(*this, other)); } template Bdd& Bdd::operator&=(Bdd const& other) { this->addMetaVariables(other.getContainedMetaVariables()); internalBdd &= other.internalBdd; return *this; } template Bdd Bdd::iff(Bdd const& other) const { return Bdd(this->getDdManager(), internalBdd.iff(other.internalBdd), Dd::joinMetaVariables(*this, other)); } template Bdd Bdd::exclusiveOr(Bdd const& other) const { return Bdd(this->getDdManager(), internalBdd.exclusiveOr(other.internalBdd), Dd::joinMetaVariables(*this, other)); } template Bdd Bdd::implies(Bdd const& other) const { return Bdd(this->getDdManager(), internalBdd.implies(other.internalBdd), Dd::joinMetaVariables(*this, other)); } template Bdd Bdd::operator!() const { return Bdd(this->getDdManager(), !internalBdd, this->getContainedMetaVariables()); } template Bdd& Bdd::complement() { internalBdd.complement(); return *this; } template Bdd Bdd::existsAbstract(std::set const& metaVariables) const { Bdd cube = getCube(this->getDdManager(), metaVariables); return Bdd(this->getDdManager(), internalBdd.existsAbstract(cube), Dd::subtractMetaVariables(*this, cube)); } template Bdd Bdd::universalAbstract(std::set const& metaVariables) const { Bdd cube = getCube(this->getDdManager(), metaVariables); return Bdd(this->getDdManager(), internalBdd.universalAbstract(cube), Dd::subtractMetaVariables(*this, cube)); } template Bdd Bdd::andExists(Bdd const& other, std::set const& existentialVariables) const { Bdd cube = getCube(this->getDdManager(), existentialVariables); std::set unionOfMetaVariables; std::set_union(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), other.getContainedMetaVariables().begin(), other.getContainedMetaVariables().end(), std::inserter(unionOfMetaVariables, unionOfMetaVariables.begin())); std::set containedMetaVariables; std::set_difference(unionOfMetaVariables.begin(), unionOfMetaVariables.end(), existentialVariables.begin(), existentialVariables.end(), std::inserter(containedMetaVariables, containedMetaVariables.begin())); return Bdd(this->getDdManager(), internalBdd.andExists(other, cube), containedMetaVariables); } template Bdd Bdd::constrain(Bdd const& constraint) const { return Bdd(this->getDdManager(), internalBdd.constrain(constraint), Dd::joinMetaVariables(*this, constraint)); } template Bdd Bdd::restrict(Bdd const& constraint) const { return Bdd(this->getDdManager(), internalBdd.restrict(constraint), Dd::joinMetaVariables(*this, constraint)); } template Bdd Bdd::relationalProduct(Bdd const& relation, std::set const& rowMetaVariables, std::set const& columnMetaVariables) const { std::set newMetaVariables; std::set_difference(relation.getContainedMetaVariables().begin(), relation.getContainedMetaVariables().end(), columnMetaVariables.begin(), columnMetaVariables.end(), std::inserter(newMetaVariables, newMetaVariables.begin())); std::vector> rowVariables; for (auto const& metaVariable : rowMetaVariables) { DdMetaVariable const& variable = this->getDdManager().getMetaVariable(metaVariable); for (auto const& ddVariable : variable.getDdVariables()) { rowVariables.push_back(ddVariable); } } std::vector> columnVariables; for (auto const& metaVariable : columnMetaVariables) { DdMetaVariable const& variable = this->getDdManager().getMetaVariable(metaVariable); for (auto const& ddVariable : variable.getDdVariables()) { columnVariables.push_back(ddVariable); } } return Bdd(this->getDdManager(), internalBdd.relationalProduct(relation, rowVariables, columnVariables), newMetaVariables); } template Bdd Bdd::inverseRelationalProduct(Bdd const& relation, std::set const& rowMetaVariables, std::set const& columnMetaVariables) const { std::set newMetaVariables; std::set_difference(relation.getContainedMetaVariables().begin(), relation.getContainedMetaVariables().end(), columnMetaVariables.begin(), columnMetaVariables.end(), std::inserter(newMetaVariables, newMetaVariables.begin())); std::vector> rowVariables; for (auto const& metaVariable : rowMetaVariables) { DdMetaVariable const& variable = this->getDdManager().getMetaVariable(metaVariable); for (auto const& ddVariable : variable.getDdVariables()) { rowVariables.push_back(ddVariable); } } std::vector> columnVariables; for (auto const& metaVariable : columnMetaVariables) { DdMetaVariable const& variable = this->getDdManager().getMetaVariable(metaVariable); for (auto const& ddVariable : variable.getDdVariables()) { columnVariables.push_back(ddVariable); } } return Bdd(this->getDdManager(), internalBdd.inverseRelationalProduct(relation, rowVariables, columnVariables), newMetaVariables); } template Bdd Bdd::inverseRelationalProductWithExtendedRelation(Bdd const& relation, std::set const& rowMetaVariables, std::set const& columnMetaVariables) const { std::set newMetaVariables; std::set_difference(relation.getContainedMetaVariables().begin(), relation.getContainedMetaVariables().end(), columnMetaVariables.begin(), columnMetaVariables.end(), std::inserter(newMetaVariables, newMetaVariables.begin())); std::vector> rowVariables; for (auto const& metaVariable : rowMetaVariables) { DdMetaVariable const& variable = this->getDdManager().getMetaVariable(metaVariable); for (auto const& ddVariable : variable.getDdVariables()) { rowVariables.push_back(ddVariable); } } std::vector> columnVariables; for (auto const& metaVariable : columnMetaVariables) { DdMetaVariable const& variable = this->getDdManager().getMetaVariable(metaVariable); for (auto const& ddVariable : variable.getDdVariables()) { columnVariables.push_back(ddVariable); } } return Bdd(this->getDdManager(), internalBdd.inverseRelationalProductWithExtendedRelation(relation, rowVariables, columnVariables), newMetaVariables); } template Bdd Bdd::swapVariables(std::vector> const& metaVariablePairs) const { std::set newContainedMetaVariables; std::vector> from; std::vector> to; for (auto const& metaVariablePair : metaVariablePairs) { DdMetaVariable const& variable1 = this->getDdManager().getMetaVariable(metaVariablePair.first); DdMetaVariable const& variable2 = this->getDdManager().getMetaVariable(metaVariablePair.second); // Keep track of the contained meta variables in the DD. if (this->containsMetaVariable(metaVariablePair.first)) { newContainedMetaVariables.insert(metaVariablePair.second); } if (this->containsMetaVariable(metaVariablePair.second)) { newContainedMetaVariables.insert(metaVariablePair.first); } for (auto const& ddVariable : variable1.getDdVariables()) { from.push_back(ddVariable); } for (auto const& ddVariable : variable2.getDdVariables()) { to.push_back(ddVariable); } } return Bdd(this->getDdManager(), internalBdd.swapVariables(from, to), newContainedMetaVariables); } template template Add Bdd::toAdd() const { return Add(this->getDdManager(), internalBdd.template toAdd(), this->getContainedMetaVariables()); } template storm::storage::BitVector Bdd::toVector(storm::dd::Odd const& rowOdd) const { return internalBdd.toVector(rowOdd, this->getSortedVariableIndices()); } template Bdd Bdd::getSupport() const { return Bdd(this->getDdManager(), internalBdd.getSupport(), this->getContainedMetaVariables()); } template uint_fast64_t Bdd::getNonZeroCount() const { std::size_t numberOfDdVariables = 0; for (auto const& metaVariable : this->getContainedMetaVariables()) { numberOfDdVariables += this->getDdManager().getMetaVariable(metaVariable).getNumberOfDdVariables(); } return internalBdd.getNonZeroCount(numberOfDdVariables); } template uint_fast64_t Bdd::getLeafCount() const { return internalBdd.getLeafCount(); } template uint_fast64_t Bdd::getNodeCount() const { return internalBdd.getNodeCount(); } template uint_fast64_t Bdd::getIndex() const { return internalBdd.getIndex(); } template bool Bdd::isOne() const { return internalBdd.isOne(); } template bool Bdd::isZero() const { return internalBdd.isZero(); } template void Bdd::exportToDot(std::string const& filename) const { internalBdd.exportToDot(filename, this->getDdManager().getDdVariableNames()); } template Bdd Bdd::getCube(DdManager const& manager, std::set const& metaVariables) { Bdd cube = manager.getBddOne(); for (auto const& metaVariable : metaVariables) { cube &= manager.getMetaVariable(metaVariable).getCube(); } return cube; } template Odd Bdd::createOdd() const { return internalBdd.createOdd(this->getSortedVariableIndices()); } template template std::vector Bdd::filterExplicitVector(Odd const& odd, std::vector const& values) const { std::vector result(this->getNonZeroCount()); internalBdd.filterExplicitVector(odd, this->getSortedVariableIndices(), values, result); return result; } template Bdd::operator InternalBdd() const { return internalBdd; } template class Bdd; template Bdd Bdd::fromVector(DdManager const& ddManager, std::vector const& values, Odd const& odd, std::set const& metaVariables, std::function const& filter); template Bdd Bdd::fromVector(DdManager const& ddManager, std::vector const& values, Odd const& odd, std::set const& metaVariables, std::function const& filter); template Add Bdd::toAdd() const; template Add Bdd::toAdd() const; template std::vector Bdd::filterExplicitVector(Odd const& odd, std::vector const& values) const; template std::vector Bdd::filterExplicitVector(Odd const& odd, std::vector const& values) const; template Add Bdd::ite(Add const& thenAdd, Add const& elseAdd) const; template Add Bdd::ite(Add const& thenAdd, Add const& elseAdd) const; template class Bdd; template Bdd Bdd::fromVector(DdManager const& ddManager, std::vector const& values, Odd const& odd, std::set const& metaVariables, std::function const& filter); template Bdd Bdd::fromVector(DdManager const& ddManager, std::vector const& values, Odd const& odd, std::set const& metaVariables, std::function const& filter); template Add Bdd::toAdd() const; template Add Bdd::toAdd() const; template std::vector Bdd::filterExplicitVector(Odd const& odd, std::vector const& values) const; template std::vector Bdd::filterExplicitVector(Odd const& odd, std::vector const& values) const; template Add Bdd::ite(Add const& thenAdd, Add const& elseAdd) const; template Add Bdd::ite(Add const& thenAdd, Add const& elseAdd) const; } }