Browse Source
started refactoring DD-interface a bit in an attempt to ease the integration of sylvan
started refactoring DD-interface a bit in an attempt to ease the integration of sylvan
Former-commit-id: 3a90e171b8
main
19 changed files with 1184 additions and 722 deletions
-
8src/storage/dd/Add.cpp
-
6src/storage/dd/Add.h
-
238src/storage/dd/Bdd.cpp
-
250src/storage/dd/Bdd.h
-
92src/storage/dd/Dd.cpp
-
172src/storage/dd/Dd.h
-
0src/storage/dd/DdManager.cpp
-
10src/storage/dd/DdManager.h
-
6src/storage/dd/DdMetaVariable.h
-
3src/storage/dd/DdType.h
-
14src/storage/dd/InternalAdd.h
-
14src/storage/dd/InternalBdd.h
-
0src/storage/dd/Odd.cpp
-
6src/storage/dd/Odd.h
-
384src/storage/dd/cudd/CuddBdd.cpp
-
70src/storage/dd/cudd/CuddDd.cpp
-
182src/storage/dd/cudd/CuddDd.h
-
316src/storage/dd/cudd/InternalCuddBdd.cpp
-
127src/storage/dd/cudd/InternalCuddBdd.h
@ -0,0 +1,8 @@ |
|||||
|
#include "src/storage/dd/Add.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace dd { |
||||
|
|
||||
|
template class Add<storm::dd::DdType::CUDD, double>; |
||||
|
} |
||||
|
} |
@ -0,0 +1,238 @@ |
|||||
|
#include "src/storage/dd/Bdd.h"
|
||||
|
#include "src/storage/dd/Add.h"
|
||||
|
#include "src/storage/dd/Odd.h"
|
||||
|
|
||||
|
#include "src/storage/dd/DdMetaVariable.h"
|
||||
|
#include "src/storage/dd/DdManager.h"
|
||||
|
|
||||
|
#include "src/storage/BitVector.h"
|
||||
|
|
||||
|
#include "src/utility/macros.h"
|
||||
|
#include "src/exceptions/InvalidArgumentException.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace dd { |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType>::Bdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, InternalBdd<LibraryType> const& internalBdd, std::set<storm::expressions::Variable> const& containedMetaVariables) : Dd<LibraryType>(ddManager, containedMetaVariables), internalBdd(internalBdd) { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType>::Bdd(std::shared_ptr<DdManager<LibraryType> const> ddManager, std::vector<double> const& explicitValues, storm::dd::Odd<LibraryType> const& odd, std::set<storm::expressions::Variable> const& metaVariables, storm::logic::ComparisonType comparisonType, double value) { |
||||
|
switch (comparisonType) { |
||||
|
case storm::logic::ComparisonType::Less: |
||||
|
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::greater<double>(), value, std::placeholders::_1)); |
||||
|
break; |
||||
|
case storm::logic::ComparisonType::LessEqual: |
||||
|
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::greater_equal<double>(), value, std::placeholders::_1)); |
||||
|
break; |
||||
|
case storm::logic::ComparisonType::Greater: |
||||
|
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::less<double>(), value, std::placeholders::_1)); |
||||
|
break; |
||||
|
case storm::logic::ComparisonType::GreaterEqual: |
||||
|
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::less_equal<double>(), value, std::placeholders::_1)); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
bool Bdd<LibraryType>::operator==(Bdd<LibraryType> const& other) const { |
||||
|
return internalBdd == other.internalBdd; |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
bool Bdd<LibraryType>::operator!=(Bdd<LibraryType> const& other) const { |
||||
|
return internalBdd != other.internalBdd; |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::ite(Bdd<LibraryType> const& thenBdd, Bdd<LibraryType> const& elseBdd) const { |
||||
|
std::set<storm::expressions::Variable> metaVariables = Dd<LibraryType>::joinMetaVariables(*this, thenBdd); |
||||
|
metaVariables.insert(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end()); |
||||
|
return Bdd<LibraryType>(this->getDdManager(), internalBdd.ite(thenBdd.internalBdd, elseBdd.internalBdd), metaVariables); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::operator||(Bdd<LibraryType> const& other) const { |
||||
|
return Bdd<LibraryType>(this->getDdManager(), internalBdd || other.internalBdd, Dd<LibraryType>::joinMetaVariables(*this, other)); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType>& Bdd<LibraryType>::operator|=(Bdd<LibraryType> const& other) { |
||||
|
this->addMetaVariables(other.getContainedMetaVariables()); |
||||
|
internalBdd |= other.internalBdd; |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::operator&&(Bdd<LibraryType> const& other) const { |
||||
|
return Bdd<LibraryType>(this->getDdManager(), internalBdd && other.internalBdd, Dd<LibraryType>::joinMetaVariables(*this, other)); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType>& Bdd<LibraryType>::operator&=(Bdd<LibraryType> const& other) { |
||||
|
this->addMetaVariables(other.getContainedMetaVariables()); |
||||
|
internalBdd &= other.internalBdd; |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::iff(Bdd<LibraryType> const& other) const { |
||||
|
return Bdd<LibraryType>(this->getDdManager(), internalBdd.iff(other.internalBdd), Dd<LibraryType>::joinMetaVariables(*this, other)); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::exclusiveOr(Bdd<LibraryType> const& other) const { |
||||
|
return Bdd<LibraryType>(this->getDdManager(), internalBdd.exclusiveOr(other.internalBdd), Dd<LibraryType>::joinMetaVariables(*this, other)); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::implies(Bdd<LibraryType> const& other) const { |
||||
|
return Bdd<LibraryType>(this->getDdManager(), internalBdd.implies(other.internalBdd), Dd<LibraryType>::joinMetaVariables(*this, other)); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::operator!() const { |
||||
|
return Bdd<LibraryType>(this->getDdManager(), !internalBdd, this->getContainedMetaVariables()); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType>& Bdd<LibraryType>::complement() { |
||||
|
internalBdd.complement(); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::existsAbstract(std::set<storm::expressions::Variable> const& metaVariables) const { |
||||
|
Bdd<LibraryType> cubeBdd = this->getDdManager()->getBddOne(); |
||||
|
|
||||
|
std::set<storm::expressions::Variable> newMetaVariables = this->getContainedMetaVariables(); |
||||
|
for (auto const& metaVariable : metaVariables) { |
||||
|
// First check whether the BDD contains the meta variable and erase it, if this is the case.
|
||||
|
STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidArgumentException, "Cannot abstract from meta variable '" << metaVariable.getName() << "' that is not present in the DD."); |
||||
|
newMetaVariables.erase(metaVariable); |
||||
|
|
||||
|
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable); |
||||
|
cubeBdd &= ddMetaVariable.getCube(); |
||||
|
} |
||||
|
|
||||
|
return Bdd<LibraryType>(internalBdd.existsAbstract(cubeBdd)); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::universalAbstract(std::set<storm::expressions::Variable> const& metaVariables) const { |
||||
|
InternalBdd<LibraryType> cubeBdd = this->getDdManager()->getBddOne(); |
||||
|
|
||||
|
std::set<storm::expressions::Variable> newMetaVariables = this->getContainedMetaVariables(); |
||||
|
for (auto const& metaVariable : metaVariables) { |
||||
|
// First check whether the BDD contains the meta variable and erase it, if this is the case.
|
||||
|
STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidArgumentException, "Cannot abstract from meta variable '" << metaVariable.getName() << "' that is not present in the DD."); |
||||
|
newMetaVariables.erase(metaVariable); |
||||
|
|
||||
|
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable); |
||||
|
cubeBdd &= ddMetaVariable.getCube(); |
||||
|
} |
||||
|
|
||||
|
return Bdd<LibraryType>(internalBdd.universalAbstract(cubeBdd)); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::andExists(Bdd<LibraryType> const& other, std::set<storm::expressions::Variable> const& existentialVariables) const { |
||||
|
InternalBdd<DdType::CUDD> cubeBdd(this->getDdManager()->getBddOne()); |
||||
|
for (auto const& metaVariable : existentialVariables) { |
||||
|
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable); |
||||
|
cubeBdd &= ddMetaVariable.getCube(); |
||||
|
} |
||||
|
|
||||
|
std::set<storm::expressions::Variable> unionOfMetaVariables; |
||||
|
std::set_union(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), other.getContainedMetaVariables().begin(), other.getContainedMetaVariables().end(), std::inserter(unionOfMetaVariables, unionOfMetaVariables.begin())); |
||||
|
std::set<storm::expressions::Variable> containedMetaVariables; |
||||
|
std::set_difference(unionOfMetaVariables.begin(), unionOfMetaVariables.end(), existentialVariables.begin(), existentialVariables.end(), std::inserter(containedMetaVariables, containedMetaVariables.begin())); |
||||
|
|
||||
|
return Bdd<LibraryType>(internalBdd.andExists(other.internalBdd, cubeBdd)); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::constrain(Bdd<LibraryType> const& constraint) const { |
||||
|
this->addMetaVariables(constraint.getContainedMetaVariables()); |
||||
|
return internalBdd.constraint(constraint.internalBdd); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::restrict(Bdd<LibraryType> const& constraint) const { |
||||
|
this->addMetaVariables(constraint.getContainedMetaVariables()); |
||||
|
return internalBdd.constraint(constraint.internalBdd); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) const { |
||||
|
std::set<storm::expressions::Variable> newContainedMetaVariables; |
||||
|
std::vector<std::pair<std::reference_wrapper<DdMetaVariable<LibraryType> const>, std::reference_wrapper<DdMetaVariable<LibraryType> const>>> fromTo; |
||||
|
for (auto const& metaVariablePair : metaVariablePairs) { |
||||
|
std::reference_wrapper<DdMetaVariable<LibraryType> const> variable1 = this->getDdManager()->getMetaVariable(metaVariablePair.first); |
||||
|
std::reference_wrapper<DdMetaVariable<LibraryType> const> variable2 = this->getDdManager()->getMetaVariable(metaVariablePair.second); |
||||
|
fromTo.push_back(std::make_pair(variable1, variable2)); |
||||
|
} |
||||
|
return Bdd<LibraryType>(internalBdd.swapVariables(fromTo)); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
template<typename ValueType> |
||||
|
Add<LibraryType, ValueType> Bdd<LibraryType>::toAdd() const { |
||||
|
return Add<LibraryType, ValueType>(internalBdd.template toAdd<ValueType>()); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
storm::storage::BitVector Bdd<LibraryType>::toVector(storm::dd::Odd<LibraryType> const& rowOdd) const { |
||||
|
return internalBdd.toVector(rowOdd); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
Bdd<LibraryType> Bdd<LibraryType>::getSupport() const { |
||||
|
return Bdd<LibraryType>(internalBdd.getSupport()); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
uint_fast64_t Bdd<LibraryType>::getNonZeroCount() const { |
||||
|
std::size_t numberOfDdVariables = 0; |
||||
|
for (auto const& metaVariable : this->getContainedMetaVariables()) { |
||||
|
numberOfDdVariables += this->getDdManager()->getMetaVariable(metaVariable).getNumberOfDdVariables(); |
||||
|
} |
||||
|
return internalBdd.getNonZeroCount(numberOfDdVariables); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
uint_fast64_t Bdd<LibraryType>::getLeafCount() const { |
||||
|
return internalBdd.getLeafCount(); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
uint_fast64_t Bdd<LibraryType>::getNodeCount() const { |
||||
|
return internalBdd.getNodeCount(); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
uint_fast64_t Bdd<LibraryType>::getIndex() const { |
||||
|
return internalBdd.getIndex(); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
bool Bdd<LibraryType>::isOne() const { |
||||
|
return internalBdd.isOne(); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
bool Bdd<LibraryType>::isZero() const { |
||||
|
return internalBdd.isZero(); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
void Bdd<LibraryType>::exportToDot(std::string const& filename) const { |
||||
|
internalBdd.exportToDot(filename, this->getDdManager()->getDdVariableNames()); |
||||
|
} |
||||
|
|
||||
|
template class Bdd<storm::dd::DdType::CUDD>; |
||||
|
} |
||||
|
} |
@ -0,0 +1,92 @@ |
|||||
|
#include "src/storage/dd/Dd.h"
|
||||
|
|
||||
|
#include <algorithm>
|
||||
|
|
||||
|
#include "src/storage/dd/DdManager.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace dd { |
||||
|
template<DdType LibraryType> |
||||
|
Dd<LibraryType>::Dd(std::shared_ptr<DdManager<LibraryType> const> ddManager, std::set<storm::expressions::Variable> const& containedMetaVariables) : ddManager(ddManager), containedMetaVariables(containedMetaVariables) { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
bool Dd<LibraryType>::containsMetaVariable(storm::expressions::Variable const& metaVariable) const { |
||||
|
return containedMetaVariables.find(metaVariable) != containedMetaVariables.end(); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
bool Dd<LibraryType>::containsMetaVariables(std::set<storm::expressions::Variable> const& metaVariables) const { |
||||
|
return std::includes(containedMetaVariables.begin(), containedMetaVariables.end(), metaVariables.begin(), metaVariables.end()); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
std::set<storm::expressions::Variable> const& Dd<LibraryType>::getContainedMetaVariables() const { |
||||
|
return this->containedMetaVariables; |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
std::set<storm::expressions::Variable>& Dd<LibraryType>::getContainedMetaVariables() { |
||||
|
return this->containedMetaVariables; |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
std::shared_ptr<DdManager<LibraryType> const> Dd<LibraryType>::getDdManager() const { |
||||
|
return this->ddManager; |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
void Dd<LibraryType>::addMetaVariables(std::set<storm::expressions::Variable> const& metaVariables) { |
||||
|
std::set<storm::expressions::Variable> result; |
||||
|
std::set_union(containedMetaVariables.begin(), containedMetaVariables.end(), metaVariables.begin(), metaVariables.end(), std::inserter(result, result.begin())); |
||||
|
containedMetaVariables = std::move(result); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
void Dd<LibraryType>::addMetaVariable(storm::expressions::Variable const& metaVariable) { |
||||
|
this->getContainedMetaVariables().insert(metaVariable); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
void Dd<LibraryType>::removeMetaVariable(storm::expressions::Variable const& metaVariable) { |
||||
|
this->getContainedMetaVariables().erase(metaVariable); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
void Dd<LibraryType>::removeMetaVariables(std::set<storm::expressions::Variable> const& metaVariables) { |
||||
|
std::set<storm::expressions::Variable> result; |
||||
|
std::set_difference(containedMetaVariables.begin(), containedMetaVariables.end(), metaVariables.begin(), metaVariables.end(), std::inserter(result, result.begin())); |
||||
|
containedMetaVariables = std::move(result); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
std::vector<uint_fast64_t> Dd<LibraryType>::getSortedVariableIndices() const { |
||||
|
return getSortedVariableIndices(*this->getDdManager(), this->getContainedMetaVariables()); |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
std::vector<uint_fast64_t> Dd<LibraryType>::getSortedVariableIndices(DdManager<LibraryType> const& manager, std::set<storm::expressions::Variable> const& metaVariables) { |
||||
|
std::vector<uint_fast64_t> ddVariableIndices; |
||||
|
for (auto const& metaVariableName : metaVariables) { |
||||
|
auto const& metaVariable = manager.getMetaVariable(metaVariableName); |
||||
|
for (auto const& ddVariable : metaVariable.getDdVariables()) { |
||||
|
ddVariableIndices.push_back(ddVariable.getIndex()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Next, we need to sort them, since they may be arbitrarily ordered otherwise.
|
||||
|
std::sort(ddVariableIndices.begin(), ddVariableIndices.end()); |
||||
|
return ddVariableIndices; |
||||
|
} |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
std::set<storm::expressions::Variable> Dd<LibraryType>::joinMetaVariables(storm::dd::Dd<LibraryType> const& first, storm::dd::Dd<LibraryType> const& second) { |
||||
|
std::set<storm::expressions::Variable> metaVariables; |
||||
|
std::set_union(first.getContainedMetaVariables().begin(), first.getContainedMetaVariables().end(), second.getContainedMetaVariables().begin(), second.getContainedMetaVariables().end(), std::inserter(metaVariables, metaVariables.begin())); |
||||
|
return metaVariables; |
||||
|
} |
||||
|
|
||||
|
template class Dd<storm::dd::DdType::CUDD>; |
||||
|
} |
||||
|
} |
@ -1,12 +1,180 @@ |
|||||
#ifndef STORM_STORAGE_DD_DD_H_ |
#ifndef STORM_STORAGE_DD_DD_H_ |
||||
#define STORM_STORAGE_DD_DD_H_ |
#define STORM_STORAGE_DD_DD_H_ |
||||
|
|
||||
|
#include <vector> |
||||
|
#include <string> |
||||
|
#include <set> |
||||
|
|
||||
#include "src/storage/dd/DdType.h" |
#include "src/storage/dd/DdType.h" |
||||
|
#include "src/storage/expressions/Variable.h" |
||||
|
|
||||
namespace storm { |
namespace storm { |
||||
namespace dd { |
namespace dd { |
||||
// Declare Dd class so we can then specialize it for the different DD types. |
|
||||
template<DdType Type> class Dd; |
|
||||
|
// Forward-declare some classes. |
||||
|
template<DdType LibraryType> class DdManager; |
||||
|
template<DdType LibraryType> class Bdd; |
||||
|
|
||||
|
template<DdType LibraryType> |
||||
|
class Dd { |
||||
|
public: |
||||
|
// Declare the DdManager so it can access the internals of a DD. |
||||
|
friend class DdManager<LibraryType>; |
||||
|
|
||||
|
// Instantiate all copy/move constructors/assignments with the default implementation. |
||||
|
Dd() = default; |
||||
|
Dd(Dd<LibraryType> const& other) = default; |
||||
|
Dd& operator=(Dd<LibraryType> const& other) = default; |
||||
|
Dd(Dd<LibraryType>&& other) = default; |
||||
|
Dd& operator=(Dd<LibraryType>&& other) = default; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the support of the current DD. |
||||
|
* |
||||
|
* @return The support represented as a BDD. |
||||
|
*/ |
||||
|
virtual Bdd<LibraryType> getSupport() const = 0; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the number of encodings that are mapped to a non-zero value. |
||||
|
* |
||||
|
* @return The number of encodings that are mapped to a non-zero value. |
||||
|
*/ |
||||
|
virtual uint_fast64_t getNonZeroCount() const = 0; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the number of leaves of the DD. |
||||
|
* |
||||
|
* @return The number of leaves of the DD. |
||||
|
*/ |
||||
|
virtual uint_fast64_t getLeafCount() const = 0; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the number of nodes necessary to represent the DD. |
||||
|
* |
||||
|
* @return The number of nodes in this DD. |
||||
|
*/ |
||||
|
virtual uint_fast64_t getNodeCount() const = 0; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the index of the topmost variable in the DD. |
||||
|
* |
||||
|
* @return The index of the topmost variable in DD. |
||||
|
*/ |
||||
|
virtual uint_fast64_t getIndex() const = 0; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves whether the given meta variable is contained in the DD. |
||||
|
* |
||||
|
* @param metaVariable The meta variable for which to query membership. |
||||
|
* @return True iff the meta variable is contained in the DD. |
||||
|
*/ |
||||
|
bool containsMetaVariable(storm::expressions::Variable const& metaVariable) const; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves whether the given meta variables are all contained in the DD. |
||||
|
* |
||||
|
* @param metaVariables The meta variables for which to query membership. |
||||
|
* @return True iff all meta variables are contained in the DD. |
||||
|
*/ |
||||
|
bool containsMetaVariables(std::set<storm::expressions::Variable> const& metaVariables) const; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the set of all meta variables contained in the DD. |
||||
|
* |
||||
|
* @return The set of all meta variables contained in the DD. |
||||
|
*/ |
||||
|
std::set<storm::expressions::Variable> const& getContainedMetaVariables() const; |
||||
|
|
||||
|
/*! |
||||
|
* Exports the DD to the given file in the dot format. |
||||
|
* |
||||
|
* @param filename The name of the file to which the DD is to be exported. |
||||
|
*/ |
||||
|
virtual void exportToDot(std::string const& filename) const = 0; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the manager that is responsible for this DD. |
||||
|
* |
||||
|
* A pointer to the manager that is responsible for this DD. |
||||
|
*/ |
||||
|
std::shared_ptr<DdManager<LibraryType> const> getDdManager() const; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the set of all meta variables contained in the DD. |
||||
|
* |
||||
|
* @return The set of all meta variables contained in the DD. |
||||
|
*/ |
||||
|
std::set<storm::expressions::Variable>& getContainedMetaVariables(); |
||||
|
|
||||
|
protected: |
||||
|
/*! |
||||
|
* Retrieves the (sorted) list of the variable indices of DD variables contained in this DD. |
||||
|
* |
||||
|
* @return The sorted list of variable indices. |
||||
|
*/ |
||||
|
std::vector<uint_fast64_t> getSortedVariableIndices() const; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the (sorted) list of the variable indices of the DD variables given by the meta variable set. |
||||
|
* |
||||
|
* @param manager The manager responsible for the DD. |
||||
|
* @param metaVariable The set of meta variables for which to retrieve the index list. |
||||
|
* @return The sorted list of variable indices. |
||||
|
*/ |
||||
|
static std::vector<uint_fast64_t> getSortedVariableIndices(DdManager<LibraryType> const& manager, std::set<storm::expressions::Variable> const& metaVariables); |
||||
|
|
||||
|
/*! |
||||
|
* Adds the given set of meta variables to the DD. |
||||
|
* |
||||
|
* @param metaVariables The set of meta variables to add. |
||||
|
*/ |
||||
|
void addMetaVariables(std::set<storm::expressions::Variable> const& metaVariables); |
||||
|
|
||||
|
/*! |
||||
|
* Adds the given meta variable to the set of meta variables that are contained in this DD. |
||||
|
* |
||||
|
* @param metaVariable The name of the meta variable to add. |
||||
|
*/ |
||||
|
void addMetaVariable(storm::expressions::Variable const& metaVariable); |
||||
|
|
||||
|
/*! |
||||
|
* Removes the given meta variable to the set of meta variables that are contained in this DD. |
||||
|
* |
||||
|
* @param metaVariable The name of the meta variable to remove. |
||||
|
*/ |
||||
|
void removeMetaVariable(storm::expressions::Variable const& metaVariable); |
||||
|
|
||||
|
/*! |
||||
|
* Removes the given set of meta variables from the DD. |
||||
|
* |
||||
|
* @param metaVariables The set of meta variables to remove. |
||||
|
*/ |
||||
|
void removeMetaVariables(std::set<storm::expressions::Variable> const& metaVariables); |
||||
|
|
||||
|
/*! |
||||
|
* Creates a DD with the given manager and meta variables. |
||||
|
* |
||||
|
* @param ddManager The manager responsible for this DD. |
||||
|
* @param containedMetaVariables The meta variables that appear in the DD. |
||||
|
*/ |
||||
|
Dd(std::shared_ptr<DdManager<LibraryType> const> ddManager, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>()); |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the set of meta variables contained in both DDs. |
||||
|
* |
||||
|
* @param first The first DD. |
||||
|
* @param second The second DD. |
||||
|
* @return The set of all contained meta variables. |
||||
|
*/ |
||||
|
static std::set<storm::expressions::Variable> joinMetaVariables(storm::dd::Dd<LibraryType> const& first, storm::dd::Dd<LibraryType> const& second); |
||||
|
|
||||
|
private: |
||||
|
// A pointer to the manager responsible for this DD. |
||||
|
std::shared_ptr<DdManager<LibraryType> const> ddManager; |
||||
|
|
||||
|
// The meta variables that appear in this DD. |
||||
|
std::set<storm::expressions::Variable> containedMetaVariables; |
||||
|
}; |
||||
} |
} |
||||
} |
} |
||||
|
|
@ -0,0 +1,14 @@ |
|||||
|
#ifndef STORM_STORAGE_DD_INTERNALADD_H_ |
||||
|
#define STORM_STORAGE_DD_INTERNALADD_H_ |
||||
|
|
||||
|
#include "src/storage/dd/DdType.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace dd { |
||||
|
template <storm::dd::DdType LibraryType, typename ValueType> |
||||
|
class InternalAdd; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#endif /* STORM_STORAGE_DD_INTERNALADD_H_ */ |
@ -0,0 +1,14 @@ |
|||||
|
#ifndef STORM_STORAGE_DD_INTERNALBDD_H_ |
||||
|
#define STORM_STORAGE_DD_INTERNALBDD_H_ |
||||
|
|
||||
|
#include "src/storage/dd/DdType.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace dd { |
||||
|
template <storm::dd::DdType LibraryType> |
||||
|
class InternalBdd; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#endif /* STORM_STORAGE_DD_CUDD_INTERNALBDD_H_ */ |
@ -1,384 +0,0 @@ |
|||||
#include <cstring>
|
|
||||
#include <algorithm>
|
|
||||
#include <functional>
|
|
||||
|
|
||||
#include "src/storage/dd/cudd/CuddAdd.h"
|
|
||||
#include "src/storage/dd/cudd/CuddBdd.h"
|
|
||||
#include "src/storage/dd/cudd/CuddOdd.h"
|
|
||||
#include "src/storage/dd/cudd/CuddDdManager.h"
|
|
||||
|
|
||||
#include "src/storage/BitVector.h"
|
|
||||
|
|
||||
#include "src/logic/ComparisonType.h"
|
|
||||
|
|
||||
#include "src/utility/macros.h"
|
|
||||
#include "src/exceptions/InvalidArgumentException.h"
|
|
||||
|
|
||||
namespace storm { |
|
||||
namespace dd { |
|
||||
Bdd<DdType::CUDD>::Bdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddBdd, std::set<storm::expressions::Variable> const& containedMetaVariables) : Dd<DdType::CUDD>(ddManager, containedMetaVariables), cuddBdd(cuddBdd) { |
|
||||
// Intentionally left empty.
|
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD>::Bdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, std::vector<double> const& explicitValues, storm::dd::Odd<DdType::CUDD> const& odd, std::set<storm::expressions::Variable> const& metaVariables, storm::logic::ComparisonType comparisonType, double value) : Dd<DdType::CUDD>(ddManager, metaVariables) { |
|
||||
switch (comparisonType) { |
|
||||
case storm::logic::ComparisonType::Less: |
|
||||
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::greater<double>(), value, std::placeholders::_1)); |
|
||||
break; |
|
||||
case storm::logic::ComparisonType::LessEqual: |
|
||||
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::greater_equal<double>(), value, std::placeholders::_1)); |
|
||||
break; |
|
||||
case storm::logic::ComparisonType::Greater: |
|
||||
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::less<double>(), value, std::placeholders::_1)); |
|
||||
break; |
|
||||
case storm::logic::ComparisonType::GreaterEqual: |
|
||||
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::less_equal<double>(), value, std::placeholders::_1)); |
|
||||
break; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
Add<DdType::CUDD> Bdd<DdType::CUDD>::toAdd() const { |
|
||||
return Add<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Add(), this->getContainedMetaVariables()); |
|
||||
} |
|
||||
|
|
||||
BDD Bdd<DdType::CUDD>::getCuddBdd() const { |
|
||||
return this->cuddBdd; |
|
||||
} |
|
||||
|
|
||||
DdNode* Bdd<DdType::CUDD>::getCuddDdNode() const { |
|
||||
return this->getCuddBdd().getNode(); |
|
||||
} |
|
||||
|
|
||||
bool Bdd<DdType::CUDD>::operator==(Bdd<DdType::CUDD> const& other) const { |
|
||||
return this->getCuddBdd() == other.getCuddBdd(); |
|
||||
} |
|
||||
|
|
||||
bool Bdd<DdType::CUDD>::operator!=(Bdd<DdType::CUDD> const& other) const { |
|
||||
return !(*this == other); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::ite(Bdd<DdType::CUDD> const& thenDd, Bdd<DdType::CUDD> const& elseDd) const { |
|
||||
std::set<storm::expressions::Variable> metaVariableNames; |
|
||||
std::set_union(thenDd.getContainedMetaVariables().begin(), thenDd.getContainedMetaVariables().end(), elseDd.getContainedMetaVariables().begin(), elseDd.getContainedMetaVariables().end(), std::inserter(metaVariableNames, metaVariableNames.begin())); |
|
||||
metaVariableNames.insert(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end()); |
|
||||
|
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Ite(thenDd.getCuddBdd(), elseDd.getCuddBdd()), metaVariableNames); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::operator!() const { |
|
||||
Bdd<DdType::CUDD> result(*this); |
|
||||
result.complement(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD>& Bdd<DdType::CUDD>::complement() { |
|
||||
this->cuddBdd = ~this->getCuddBdd(); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::operator&&(Bdd<DdType::CUDD> const& other) const { |
|
||||
Bdd<DdType::CUDD> result(*this); |
|
||||
result &= other; |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD>& Bdd<DdType::CUDD>::operator&=(Bdd<DdType::CUDD> const& other) { |
|
||||
this->addMetaVariables(other.getContainedMetaVariables()); |
|
||||
this->cuddBdd = this->getCuddBdd() & other.getCuddBdd(); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::operator||(Bdd<DdType::CUDD> const& other) const { |
|
||||
Bdd<DdType::CUDD> result(*this); |
|
||||
result |= other; |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD>& Bdd<DdType::CUDD>::operator|=(Bdd<DdType::CUDD> const& other) { |
|
||||
this->addMetaVariables(other.getContainedMetaVariables()); |
|
||||
this->cuddBdd = this->getCuddBdd() | other.getCuddBdd(); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::iff(Bdd<DdType::CUDD> const& other) const { |
|
||||
std::set<storm::expressions::Variable> metaVariables(this->getContainedMetaVariables()); |
|
||||
metaVariables.insert(other.getContainedMetaVariables().begin(), other.getContainedMetaVariables().end()); |
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Xnor(other.getCuddBdd()), metaVariables); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::exclusiveOr(Bdd<DdType::CUDD> const& other) const { |
|
||||
std::set<storm::expressions::Variable> metaVariables(this->getContainedMetaVariables()); |
|
||||
metaVariables.insert(other.getContainedMetaVariables().begin(), other.getContainedMetaVariables().end()); |
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Xor(other.getCuddBdd()), metaVariables); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::implies(Bdd<DdType::CUDD> const& other) const { |
|
||||
std::set<storm::expressions::Variable> metaVariables(this->getContainedMetaVariables()); |
|
||||
metaVariables.insert(other.getContainedMetaVariables().begin(), other.getContainedMetaVariables().end()); |
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Ite(other.getCuddBdd(), this->getDdManager()->getBddOne().getCuddBdd()), metaVariables); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::existsAbstract(std::set<storm::expressions::Variable> const& metaVariables) const { |
|
||||
Bdd<DdType::CUDD> cubeBdd = this->getDdManager()->getBddOne(); |
|
||||
|
|
||||
std::set<storm::expressions::Variable> newMetaVariables = this->getContainedMetaVariables(); |
|
||||
for (auto const& metaVariable : metaVariables) { |
|
||||
// First check whether the BDD contains the meta variable and erase it, if this is the case.
|
|
||||
STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidArgumentException, "Cannot abstract from meta variable '" << metaVariable.getName() << "' that is not present in the DD."); |
|
||||
newMetaVariables.erase(metaVariable); |
|
||||
|
|
||||
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable); |
|
||||
cubeBdd &= ddMetaVariable.getCube(); |
|
||||
} |
|
||||
|
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().ExistAbstract(cubeBdd.getCuddBdd()), newMetaVariables); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::universalAbstract(std::set<storm::expressions::Variable> const& metaVariables) const { |
|
||||
Bdd<DdType::CUDD> cubeBdd = this->getDdManager()->getBddOne(); |
|
||||
|
|
||||
std::set<storm::expressions::Variable> newMetaVariables = this->getContainedMetaVariables(); |
|
||||
for (auto const& metaVariable : metaVariables) { |
|
||||
// First check whether the BDD contains the meta variable and erase it, if this is the case.
|
|
||||
STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidArgumentException, "Cannot abstract from meta variable '" << metaVariable.getName() << "' that is not present in the DD."); |
|
||||
newMetaVariables.erase(metaVariable); |
|
||||
|
|
||||
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable); |
|
||||
cubeBdd &= ddMetaVariable.getCube(); |
|
||||
} |
|
||||
|
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().UnivAbstract(cubeBdd.getCuddBdd()), newMetaVariables); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) const { |
|
||||
std::set<storm::expressions::Variable> newContainedMetaVariables; |
|
||||
std::vector<BDD> from; |
|
||||
std::vector<BDD> to; |
|
||||
for (auto const& metaVariablePair : metaVariablePairs) { |
|
||||
DdMetaVariable<DdType::CUDD> const& variable1 = this->getDdManager()->getMetaVariable(metaVariablePair.first); |
|
||||
DdMetaVariable<DdType::CUDD> const& variable2 = this->getDdManager()->getMetaVariable(metaVariablePair.second); |
|
||||
|
|
||||
// Check if it's legal so swap the meta variables.
|
|
||||
STORM_LOG_THROW(variable1.getNumberOfDdVariables() == variable2.getNumberOfDdVariables(), storm::exceptions::InvalidArgumentException, "Unable to swap meta variables with different size."); |
|
||||
|
|
||||
// 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); |
|
||||
} |
|
||||
|
|
||||
// Add the variables to swap to the corresponding vectors.
|
|
||||
for (auto const& ddVariable : variable1.getDdVariables()) { |
|
||||
from.push_back(ddVariable.getCuddBdd()); |
|
||||
} |
|
||||
for (auto const& ddVariable : variable2.getDdVariables()) { |
|
||||
to.push_back(ddVariable.getCuddBdd()); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Finally, call CUDD to swap the variables.
|
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().SwapVariables(from, to), newContainedMetaVariables); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::andExists(Bdd<DdType::CUDD> const& other, std::set<storm::expressions::Variable> const& existentialVariables) const { |
|
||||
Bdd<DdType::CUDD> cubeBdd(this->getDdManager()->getBddOne()); |
|
||||
for (auto const& metaVariable : existentialVariables) { |
|
||||
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable); |
|
||||
cubeBdd &= ddMetaVariable.getCube(); |
|
||||
} |
|
||||
|
|
||||
std::set<storm::expressions::Variable> unionOfMetaVariables; |
|
||||
std::set_union(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), other.getContainedMetaVariables().begin(), other.getContainedMetaVariables().end(), std::inserter(unionOfMetaVariables, unionOfMetaVariables.begin())); |
|
||||
std::set<storm::expressions::Variable> containedMetaVariables; |
|
||||
std::set_difference(unionOfMetaVariables.begin(), unionOfMetaVariables.end(), existentialVariables.begin(), existentialVariables.end(), std::inserter(containedMetaVariables, containedMetaVariables.begin())); |
|
||||
|
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().AndAbstract(other.getCuddBdd(), cubeBdd.getCuddBdd()), containedMetaVariables); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::constrain(Bdd<DdType::CUDD> const& constraint) const { |
|
||||
std::set<storm::expressions::Variable> metaVariables; |
|
||||
std::set_union(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), constraint.getContainedMetaVariables().begin(), constraint.getContainedMetaVariables().end(), std::inserter(metaVariables, metaVariables.begin())); |
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Constrain(constraint.getCuddBdd()), metaVariables); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::restrict(Bdd<DdType::CUDD> const& constraint) const { |
|
||||
std::set<storm::expressions::Variable> metaVariables; |
|
||||
std::set_union(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), constraint.getContainedMetaVariables().begin(), constraint.getContainedMetaVariables().end(), std::inserter(metaVariables, metaVariables.begin())); |
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Restrict(constraint.getCuddBdd()), metaVariables); |
|
||||
} |
|
||||
|
|
||||
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::getSupport() const { |
|
||||
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Support(), this->getContainedMetaVariables()); |
|
||||
} |
|
||||
|
|
||||
uint_fast64_t Bdd<DdType::CUDD>::getNonZeroCount() const { |
|
||||
std::size_t numberOfDdVariables = 0; |
|
||||
for (auto const& metaVariable : this->getContainedMetaVariables()) { |
|
||||
numberOfDdVariables += this->getDdManager()->getMetaVariable(metaVariable).getNumberOfDdVariables(); |
|
||||
} |
|
||||
return static_cast<uint_fast64_t>(this->getCuddBdd().CountMinterm(static_cast<int>(numberOfDdVariables))); |
|
||||
} |
|
||||
|
|
||||
uint_fast64_t Bdd<DdType::CUDD>::getLeafCount() const { |
|
||||
return static_cast<uint_fast64_t>(this->getCuddBdd().CountLeaves()); |
|
||||
} |
|
||||
|
|
||||
uint_fast64_t Bdd<DdType::CUDD>::getNodeCount() const { |
|
||||
return static_cast<uint_fast64_t>(this->getCuddBdd().nodeCount()); |
|
||||
} |
|
||||
|
|
||||
bool Bdd<DdType::CUDD>::isOne() const { |
|
||||
return this->getCuddBdd().IsOne(); |
|
||||
} |
|
||||
|
|
||||
bool Bdd<DdType::CUDD>::isZero() const { |
|
||||
return this->getCuddBdd().IsZero(); |
|
||||
} |
|
||||
|
|
||||
uint_fast64_t Bdd<DdType::CUDD>::getIndex() const { |
|
||||
return static_cast<uint_fast64_t>(this->getCuddBdd().NodeReadIndex()); |
|
||||
} |
|
||||
|
|
||||
void Bdd<DdType::CUDD>::exportToDot(std::string const& filename) const { |
|
||||
if (filename.empty()) { |
|
||||
std::vector<BDD> cuddBddVector = { this->getCuddBdd() }; |
|
||||
this->getDdManager()->getCuddManager().DumpDot(cuddBddVector); |
|
||||
} else { |
|
||||
// Build the name input of the DD.
|
|
||||
std::vector<char*> ddNames; |
|
||||
std::string ddName("f"); |
|
||||
ddNames.push_back(new char[ddName.size() + 1]); |
|
||||
std::copy(ddName.c_str(), ddName.c_str() + 2, ddNames.back()); |
|
||||
|
|
||||
// Now build the variables names.
|
|
||||
std::vector<std::string> ddVariableNamesAsStrings = this->getDdManager()->getDdVariableNames(); |
|
||||
std::vector<char*> ddVariableNames; |
|
||||
for (auto const& element : ddVariableNamesAsStrings) { |
|
||||
ddVariableNames.push_back(new char[element.size() + 1]); |
|
||||
std::copy(element.c_str(), element.c_str() + element.size() + 1, ddVariableNames.back()); |
|
||||
} |
|
||||
|
|
||||
// Open the file, dump the DD and close it again.
|
|
||||
FILE* filePointer = fopen(filename.c_str() , "w"); |
|
||||
std::vector<BDD> cuddBddVector = { this->getCuddBdd() }; |
|
||||
this->getDdManager()->getCuddManager().DumpDot(cuddBddVector, &ddVariableNames[0], &ddNames[0], filePointer); |
|
||||
fclose(filePointer); |
|
||||
|
|
||||
// Finally, delete the names.
|
|
||||
for (char* element : ddNames) { |
|
||||
delete element; |
|
||||
} |
|
||||
for (char* element : ddVariableNames) { |
|
||||
delete element; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template<typename ValueType> |
|
||||
BDD Bdd<DdType::CUDD>::fromVector(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, std::vector<ValueType> const& values, Odd<DdType::CUDD> const& odd, std::set<storm::expressions::Variable> const& metaVariables, std::function<bool (ValueType const&)> const& filter) { |
|
||||
std::vector<uint_fast64_t> ddVariableIndices = getSortedVariableIndices(*ddManager, metaVariables); |
|
||||
uint_fast64_t offset = 0; |
|
||||
return BDD(ddManager->getCuddManager(), fromVectorRec(ddManager->getCuddManager().getManager(), offset, 0, ddVariableIndices.size(), values, odd, ddVariableIndices, filter)); |
|
||||
} |
|
||||
|
|
||||
template<typename ValueType> |
|
||||
DdNode* Bdd<DdType::CUDD>::fromVectorRec(::DdManager* manager, uint_fast64_t& currentOffset, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::vector<ValueType> const& values, Odd<DdType::CUDD> const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::function<bool (ValueType const&)> const& filter) { |
|
||||
if (currentLevel == maxLevel) { |
|
||||
// If we are in a terminal node of the ODD, we need to check whether the then-offset of the ODD is one
|
|
||||
// (meaning the encoding is a valid one) or zero (meaning the encoding is not valid). Consequently, we
|
|
||||
// need to copy the next value of the vector iff the then-offset is greater than zero.
|
|
||||
if (odd.getThenOffset() > 0) { |
|
||||
if (filter(values[currentOffset++])) { |
|
||||
return Cudd_ReadOne(manager); |
|
||||
} else { |
|
||||
return Cudd_ReadLogicZero(manager); |
|
||||
} |
|
||||
} else { |
|
||||
return Cudd_ReadZero(manager); |
|
||||
} |
|
||||
} else { |
|
||||
// If the total offset is zero, we can just return the constant zero DD.
|
|
||||
if (odd.getThenOffset() + odd.getElseOffset() == 0) { |
|
||||
return Cudd_ReadZero(manager); |
|
||||
} |
|
||||
|
|
||||
// Determine the new else-successor.
|
|
||||
DdNode* elseSuccessor = nullptr; |
|
||||
if (odd.getElseOffset() > 0) { |
|
||||
elseSuccessor = fromVectorRec(manager, currentOffset, currentLevel + 1, maxLevel, values, odd.getElseSuccessor(), ddVariableIndices, filter); |
|
||||
} else { |
|
||||
elseSuccessor = Cudd_ReadLogicZero(manager); |
|
||||
} |
|
||||
Cudd_Ref(elseSuccessor); |
|
||||
|
|
||||
// Determine the new then-successor.
|
|
||||
DdNode* thenSuccessor = nullptr; |
|
||||
if (odd.getThenOffset() > 0) { |
|
||||
thenSuccessor = fromVectorRec(manager, currentOffset, currentLevel + 1, maxLevel, values, odd.getThenSuccessor(), ddVariableIndices, filter); |
|
||||
} else { |
|
||||
thenSuccessor = Cudd_ReadLogicZero(manager); |
|
||||
} |
|
||||
Cudd_Ref(thenSuccessor); |
|
||||
|
|
||||
// Create a node representing ITE(currentVar, thenSuccessor, elseSuccessor);
|
|
||||
DdNode* result = Cudd_bddIthVar(manager, static_cast<int>(ddVariableIndices[currentLevel])); |
|
||||
Cudd_Ref(result); |
|
||||
DdNode* newResult = Cudd_bddIte(manager, result, thenSuccessor, elseSuccessor); |
|
||||
Cudd_Ref(newResult); |
|
||||
|
|
||||
// Dispose of the intermediate results
|
|
||||
Cudd_RecursiveDeref(manager, result); |
|
||||
Cudd_RecursiveDeref(manager, thenSuccessor); |
|
||||
Cudd_RecursiveDeref(manager, elseSuccessor); |
|
||||
|
|
||||
// Before returning, we remove the protection imposed by the previous call to Cudd_Ref.
|
|
||||
Cudd_Deref(newResult); |
|
||||
|
|
||||
return newResult; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
storm::storage::BitVector Bdd<DdType::CUDD>::toVector(storm::dd::Odd<DdType::CUDD> const& rowOdd) const { |
|
||||
std::vector<uint_fast64_t> ddVariableIndices = this->getSortedVariableIndices(); |
|
||||
storm::storage::BitVector result(rowOdd.getTotalOffset()); |
|
||||
this->toVectorRec(this->getCuddDdNode(), this->getDdManager()->getCuddManager(), result, rowOdd, Cudd_IsComplement(this->getCuddDdNode()), 0, ddVariableIndices.size(), 0, ddVariableIndices); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
void Bdd<DdType::CUDD>::toVectorRec(DdNode const* dd, Cudd const& manager, storm::storage::BitVector& result, Odd<DdType::CUDD> const& rowOdd, bool complement, uint_fast64_t currentRowLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices) const { |
|
||||
// If there are no more values to select, we can directly return.
|
|
||||
if (dd == Cudd_ReadLogicZero(manager.getManager()) && !complement) { |
|
||||
return; |
|
||||
} else if (dd == Cudd_ReadOne(manager.getManager()) && complement) { |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
// If we are at the maximal level, the value to be set is stored as a constant in the DD.
|
|
||||
if (currentRowLevel == maxLevel) { |
|
||||
result.set(currentRowOffset, true); |
|
||||
} else if (ddRowVariableIndices[currentRowLevel] < dd->index) { |
|
||||
toVectorRec(dd, manager, result, rowOdd.getElseSuccessor(), complement, currentRowLevel + 1, maxLevel, currentRowOffset, ddRowVariableIndices); |
|
||||
toVectorRec(dd, manager, result, rowOdd.getThenSuccessor(), complement, currentRowLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), ddRowVariableIndices); |
|
||||
} else { |
|
||||
// Otherwise, we compute the ODDs for both the then- and else successors.
|
|
||||
DdNode* elseDdNode = Cudd_E(dd); |
|
||||
DdNode* thenDdNode = Cudd_T(dd); |
|
||||
|
|
||||
// Determine whether we have to evaluate the successors as if they were complemented.
|
|
||||
bool elseComplemented = Cudd_IsComplement(elseDdNode) ^ complement; |
|
||||
bool thenComplemented = Cudd_IsComplement(thenDdNode) ^ complement; |
|
||||
|
|
||||
toVectorRec(Cudd_Regular(elseDdNode), manager, result, rowOdd.getElseSuccessor(), elseComplemented, currentRowLevel + 1, maxLevel, currentRowOffset, ddRowVariableIndices); |
|
||||
toVectorRec(Cudd_Regular(thenDdNode), manager, result, rowOdd.getThenSuccessor(), thenComplemented, currentRowLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), ddRowVariableIndices); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
std::ostream& operator<<(std::ostream& out, const Bdd<DdType::CUDD>& bdd) { |
|
||||
bdd.exportToDot(); |
|
||||
return out; |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,70 +0,0 @@ |
|||||
#include <algorithm>
|
|
||||
|
|
||||
#include "src/storage/dd/cudd/CuddDd.h"
|
|
||||
#include "src/storage/dd/cudd/CuddDdManager.h"
|
|
||||
|
|
||||
namespace storm { |
|
||||
namespace dd { |
|
||||
Dd<DdType::CUDD>::Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, std::set<storm::expressions::Variable> const& containedMetaVariables) : ddManager(ddManager), containedMetaVariables(containedMetaVariables) { |
|
||||
// Intentionally left empty.
|
|
||||
} |
|
||||
|
|
||||
bool Dd<DdType::CUDD>::containsMetaVariable(storm::expressions::Variable const& metaVariable) const { |
|
||||
return containedMetaVariables.find(metaVariable) != containedMetaVariables.end(); |
|
||||
} |
|
||||
|
|
||||
bool Dd<DdType::CUDD>::containsMetaVariables(std::set<storm::expressions::Variable> const& metaVariables) const { |
|
||||
return std::includes(containedMetaVariables.begin(), containedMetaVariables.end(), metaVariables.begin(), metaVariables.end()); |
|
||||
} |
|
||||
|
|
||||
std::set<storm::expressions::Variable> const& Dd<DdType::CUDD>::getContainedMetaVariables() const { |
|
||||
return this->containedMetaVariables; |
|
||||
} |
|
||||
|
|
||||
std::set<storm::expressions::Variable>& Dd<DdType::CUDD>::getContainedMetaVariables() { |
|
||||
return this->containedMetaVariables; |
|
||||
} |
|
||||
|
|
||||
std::shared_ptr<DdManager<DdType::CUDD> const> Dd<DdType::CUDD>::getDdManager() const { |
|
||||
return this->ddManager; |
|
||||
} |
|
||||
|
|
||||
void Dd<DdType::CUDD>::addMetaVariables(std::set<storm::expressions::Variable> const& metaVariables) { |
|
||||
std::set<storm::expressions::Variable> result; |
|
||||
std::set_union(containedMetaVariables.begin(), containedMetaVariables.end(), metaVariables.begin(), metaVariables.end(), std::inserter(result, result.begin())); |
|
||||
containedMetaVariables = std::move(result); |
|
||||
} |
|
||||
|
|
||||
void Dd<DdType::CUDD>::addMetaVariable(storm::expressions::Variable const& metaVariable) { |
|
||||
this->getContainedMetaVariables().insert(metaVariable); |
|
||||
} |
|
||||
|
|
||||
void Dd<DdType::CUDD>::removeMetaVariable(storm::expressions::Variable const& metaVariable) { |
|
||||
this->getContainedMetaVariables().erase(metaVariable); |
|
||||
} |
|
||||
|
|
||||
void Dd<DdType::CUDD>::removeMetaVariables(std::set<storm::expressions::Variable> const& metaVariables) { |
|
||||
std::set<storm::expressions::Variable> result; |
|
||||
std::set_difference(containedMetaVariables.begin(), containedMetaVariables.end(), metaVariables.begin(), metaVariables.end(), std::inserter(result, result.begin())); |
|
||||
containedMetaVariables = std::move(result); |
|
||||
} |
|
||||
|
|
||||
std::vector<uint_fast64_t> Dd<DdType::CUDD>::getSortedVariableIndices() const { |
|
||||
return getSortedVariableIndices(*this->getDdManager(), this->getContainedMetaVariables()); |
|
||||
} |
|
||||
|
|
||||
std::vector<uint_fast64_t> Dd<DdType::CUDD>::getSortedVariableIndices(DdManager<DdType::CUDD> const& manager, std::set<storm::expressions::Variable> const& metaVariables) { |
|
||||
std::vector<uint_fast64_t> ddVariableIndices; |
|
||||
for (auto const& metaVariableName : metaVariables) { |
|
||||
auto const& metaVariable = manager.getMetaVariable(metaVariableName); |
|
||||
for (auto const& ddVariable : metaVariable.getDdVariables()) { |
|
||||
ddVariableIndices.push_back(ddVariable.getIndex()); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Next, we need to sort them, since they may be arbitrarily ordered otherwise.
|
|
||||
std::sort(ddVariableIndices.begin(), ddVariableIndices.end()); |
|
||||
return ddVariableIndices; |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -1,182 +0,0 @@ |
|||||
#ifndef STORM_STORAGE_DD_CUDDDD_H_ |
|
||||
#define STORM_STORAGE_DD_CUDDDD_H_ |
|
||||
|
|
||||
#include <set> |
|
||||
#include <memory> |
|
||||
|
|
||||
#include "src/storage/dd/Dd.h" |
|
||||
#include "src/storage/expressions/Variable.h" |
|
||||
#include "src/utility/OsDetection.h" |
|
||||
|
|
||||
// Include the C++-interface of CUDD. |
|
||||
#include "cuddObj.hh" |
|
||||
|
|
||||
namespace storm { |
|
||||
namespace dd { |
|
||||
// Forward-declare some classes. |
|
||||
template<DdType Type> class DdManager; |
|
||||
template<DdType Type> class Odd; |
|
||||
template<DdType Type> class Bdd; |
|
||||
|
|
||||
template<> |
|
||||
class Dd<DdType::CUDD> { |
|
||||
public: |
|
||||
// Declare the DdManager so it can access the internals of a DD. |
|
||||
friend class DdManager<DdType::CUDD>; |
|
||||
|
|
||||
// Instantiate all copy/move constructors/assignments with the default implementation. |
|
||||
Dd() = default; |
|
||||
Dd(Dd<DdType::CUDD> const& other) = default; |
|
||||
Dd& operator=(Dd<DdType::CUDD> const& other) = default; |
|
||||
#ifndef WINDOWS |
|
||||
Dd(Dd<DdType::CUDD>&& other) = default; |
|
||||
Dd& operator=(Dd<DdType::CUDD>&& other) = default; |
|
||||
#endif |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the support of the current DD. |
|
||||
* |
|
||||
* @return The support represented as a BDD. |
|
||||
*/ |
|
||||
virtual Bdd<DdType::CUDD> getSupport() const = 0; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the number of encodings that are mapped to a non-zero value. |
|
||||
* |
|
||||
* @return The number of encodings that are mapped to a non-zero value. |
|
||||
*/ |
|
||||
virtual uint_fast64_t getNonZeroCount() const = 0; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the number of leaves of the DD. |
|
||||
* |
|
||||
* @return The number of leaves of the DD. |
|
||||
*/ |
|
||||
virtual uint_fast64_t getLeafCount() const = 0; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the number of nodes necessary to represent the DD. |
|
||||
* |
|
||||
* @return The number of nodes in this DD. |
|
||||
*/ |
|
||||
virtual uint_fast64_t getNodeCount() const = 0; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the index of the topmost variable in the DD. |
|
||||
* |
|
||||
* @return The index of the topmost variable in DD. |
|
||||
*/ |
|
||||
virtual uint_fast64_t getIndex() const = 0; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves whether the given meta variable is contained in the DD. |
|
||||
* |
|
||||
* @param metaVariable The meta variable for which to query membership. |
|
||||
* @return True iff the meta variable is contained in the DD. |
|
||||
*/ |
|
||||
bool containsMetaVariable(storm::expressions::Variable const& metaVariable) const; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves whether the given meta variables are all contained in the DD. |
|
||||
* |
|
||||
* @param metaVariables The meta variables for which to query membership. |
|
||||
* @return True iff all meta variables are contained in the DD. |
|
||||
*/ |
|
||||
bool containsMetaVariables(std::set<storm::expressions::Variable> const& metaVariables) const; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the set of all meta variables contained in the DD. |
|
||||
* |
|
||||
* @return The set of all meta variables contained in the DD. |
|
||||
*/ |
|
||||
std::set<storm::expressions::Variable> const& getContainedMetaVariables() const; |
|
||||
|
|
||||
/*! |
|
||||
* Exports the DD to the given file in the dot format. |
|
||||
* |
|
||||
* @param filename The name of the file to which the DD is to be exported. |
|
||||
*/ |
|
||||
virtual void exportToDot(std::string const& filename = "") const = 0; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the manager that is responsible for this DD. |
|
||||
* |
|
||||
* A pointer to the manager that is responsible for this DD. |
|
||||
*/ |
|
||||
std::shared_ptr<DdManager<DdType::CUDD> const> getDdManager() const; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the set of all meta variables contained in the DD. |
|
||||
* |
|
||||
* @return The set of all meta variables contained in the DD. |
|
||||
*/ |
|
||||
std::set<storm::expressions::Variable>& getContainedMetaVariables(); |
|
||||
|
|
||||
protected: |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the (sorted) list of the variable indices of DD variables contained in this DD. |
|
||||
* |
|
||||
* @return The sorted list of variable indices. |
|
||||
*/ |
|
||||
std::vector<uint_fast64_t> getSortedVariableIndices() const; |
|
||||
|
|
||||
/*! |
|
||||
* Retrieves the (sorted) list of the variable indices of the DD variables given by the meta variable set. |
|
||||
* |
|
||||
* @param manager The manager responsible for the DD. |
|
||||
* @param metaVariable The set of meta variables for which to retrieve the index list. |
|
||||
* @return The sorted list of variable indices. |
|
||||
*/ |
|
||||
static std::vector<uint_fast64_t> getSortedVariableIndices(DdManager<DdType::CUDD> const& manager, std::set<storm::expressions::Variable> const& metaVariables); |
|
||||
|
|
||||
/*! |
|
||||
* Adds the given set of meta variables to the DD. |
|
||||
* |
|
||||
* @param metaVariables The set of meta variables to add. |
|
||||
*/ |
|
||||
void addMetaVariables(std::set<storm::expressions::Variable> const& metaVariables); |
|
||||
|
|
||||
/*! |
|
||||
* Adds the given meta variable to the set of meta variables that are contained in this DD. |
|
||||
* |
|
||||
* @param metaVariable The name of the meta variable to add. |
|
||||
*/ |
|
||||
void addMetaVariable(storm::expressions::Variable const& metaVariable); |
|
||||
|
|
||||
/*! |
|
||||
* Removes the given meta variable to the set of meta variables that are contained in this DD. |
|
||||
* |
|
||||
* @param metaVariable The name of the meta variable to remove. |
|
||||
*/ |
|
||||
void removeMetaVariable(storm::expressions::Variable const& metaVariable); |
|
||||
|
|
||||
/*! |
|
||||
* Removes the given set of meta variables from the DD. |
|
||||
* |
|
||||
* @param metaVariables The set of meta variables to remove. |
|
||||
*/ |
|
||||
void removeMetaVariables(std::set<storm::expressions::Variable> const& metaVariables); |
|
||||
|
|
||||
protected: |
|
||||
|
|
||||
/*! |
|
||||
* Creates a DD with the given manager and meta variables. |
|
||||
* |
|
||||
* @param ddManager The manager responsible for this DD. |
|
||||
* @param containedMetaVariables The meta variables that appear in the DD. |
|
||||
*/ |
|
||||
Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>()); |
|
||||
|
|
||||
private: |
|
||||
|
|
||||
// A pointer to the manager responsible for this DD. |
|
||||
std::shared_ptr<DdManager<DdType::CUDD> const> ddManager; |
|
||||
|
|
||||
// The meta variables that appear in this DD. |
|
||||
std::set<storm::expressions::Variable> containedMetaVariables; |
|
||||
}; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif /* STORM_STORAGE_DD_CUDDDD_H_ */ |
|
@ -0,0 +1,316 @@ |
|||||
|
#include "src/storage/dd/cudd/InternalCuddBdd.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace dd { |
||||
|
bool InternalBdd<DdType::CUDD>::operator==(InternalBdd<DdType::CUDD> const& other) const { |
||||
|
return this->getCuddBdd() == other.getCuddBdd(); |
||||
|
} |
||||
|
|
||||
|
bool InternalBdd<DdType::CUDD>::operator!=(InternalBdd<DdType::CUDD> const& other) const { |
||||
|
return !(*this == other); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::ite(InternalBdd<DdType::CUDD> const& thenDd, InternalBdd<DdType::CUDD> const& elseDd) const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Ite(thenDd.getCuddBdd(), elseDd.getCuddBdd()), metaVariableNames); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::operator||(InternalBdd<DdType::CUDD> const& other) const { |
||||
|
InternalBdd<DdType::CUDD> result(*this); |
||||
|
result |= other; |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD>& InternalBdd<DdType::CUDD>::operator|=(InternalBdd<DdType::CUDD> const& other) { |
||||
|
this->cuddBdd = this->getCuddBdd() | other.getCuddBdd(); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::operator&&(InternalBdd<DdType::CUDD> const& other) const { |
||||
|
InternalBdd<DdType::CUDD> result(*this); |
||||
|
result &= other; |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD>& InternalBdd<DdType::CUDD>::operator&=(InternalBdd<DdType::CUDD> const& other) { |
||||
|
this->cuddBdd = this->getCuddBdd() & other.getCuddBdd(); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::iff(InternalBdd<DdType::CUDD> const& other) const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Xnor(other.getCuddBdd()), metaVariables); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::exclusiveOr(InternalBdd<DdType::CUDD> const& other) const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Xor(other.getCuddBdd()), metaVariables); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::implies(InternalBdd<DdType::CUDD> const& other) const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Ite(other.getCuddBdd(), this->getDdManager()->getBddOne().getCuddBdd()), metaVariables); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::operator!() const { |
||||
|
InternalBdd<DdType::CUDD> result(*this); |
||||
|
result.complement(); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD>& InternalBdd<DdType::CUDD>::complement() { |
||||
|
this->cuddBdd = ~this->getCuddBdd(); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::existsAbstract(InternalBdd<DdType> const& cube) const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().ExistAbstract(cube.getCuddBdd()), newMetaVariables); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::universalAbstract(InternalBdd<DdType> const& cube) const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().UnivAbstract(cube.getCuddBdd()), newMetaVariables); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::andExists(InternalBdd<DdType::CUDD> const& other, InternalBdd<DdType> const& cube) const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().AndAbstract(other.getCuddBdd(), cube.getCuddBdd()), containedMetaVariables); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::constrain(InternalBdd<DdType::CUDD> const& constraint) const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Constrain(constraint.getCuddBdd()), metaVariables); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::restrict(InternalBdd<DdType::CUDD> const& constraint) const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Restrict(constraint.getCuddBdd()), metaVariables); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::swapVariables(std::vector<std::pair<std::reference_wrapper<DdMetaVariable<LibraryType> const>, std::reference_wrapper<DdMetaVariable<LibraryType> const>>> const& fromTo) const { |
||||
|
std::vector<BDD> fromBdd; |
||||
|
std::vector<BDD> toBdd; |
||||
|
for (auto const& metaVariablePair : fromTo) { |
||||
|
DdMetaVariable<DdType::CUDD> const& variable1 = metaVariablePair.first.get(); |
||||
|
DdMetaVariable<DdType::CUDD> const& variable2 = metaVariablePair.second.get(); |
||||
|
|
||||
|
// Add the variables to swap to the corresponding vectors.
|
||||
|
for (auto const& ddVariable : variable1.getDdVariables()) { |
||||
|
fromBdd.push_back(ddVariable.getCuddBdd()); |
||||
|
} |
||||
|
for (auto const& ddVariable : variable2.getDdVariables()) { |
||||
|
toBdd.push_back(ddVariable.getCuddBdd()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Finally, call CUDD to swap the variables.
|
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().SwapVariables(fromBdd, toBdd), newContainedMetaVariables); |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::getSupport() const { |
||||
|
return InternalBdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Support(), this->getContainedMetaVariables()); |
||||
|
} |
||||
|
|
||||
|
uint_fast64_t InternalBdd<DdType::CUDD>::getNonZeroCount(uint_fast64_t numberOfDdVariables) const { |
||||
|
return static_cast<uint_fast64_t>(this->getCuddBdd().CountMinterm(static_cast<int>(numberOfDdVariables))); |
||||
|
} |
||||
|
|
||||
|
uint_fast64_t InternalBdd<DdType::CUDD>::getLeafCount() const { |
||||
|
return static_cast<uint_fast64_t>(this->getCuddBdd().CountLeaves()); |
||||
|
} |
||||
|
|
||||
|
uint_fast64_t InternalBdd<DdType::CUDD>::getNodeCount() const { |
||||
|
return static_cast<uint_fast64_t>(this->getCuddBdd().nodeCount()); |
||||
|
} |
||||
|
|
||||
|
bool InternalBdd<DdType::CUDD>::isOne() const { |
||||
|
return this->getCuddBdd().IsOne(); |
||||
|
} |
||||
|
|
||||
|
bool InternalBdd<DdType::CUDD>::isZero() const { |
||||
|
return this->getCuddBdd().IsZero(); |
||||
|
} |
||||
|
|
||||
|
uint_fast64_t InternalBdd<DdType::CUDD>::getIndex() const { |
||||
|
return static_cast<uint_fast64_t>(this->getCuddBdd().NodeReadIndex()); |
||||
|
} |
||||
|
|
||||
|
void InternalBdd<DdType::CUDD>::exportToDot(std::string const& filename, std::vector<std::string> const& ddVariableNamesAsStrings) const { |
||||
|
// Build the name input of the DD.
|
||||
|
std::vector<char*> ddNames; |
||||
|
std::string ddName("f"); |
||||
|
ddNames.push_back(new char[ddName.size() + 1]); |
||||
|
std::copy(ddName.c_str(), ddName.c_str() + 2, ddNames.back()); |
||||
|
|
||||
|
// Now build the variables names.
|
||||
|
std::vector<char*> ddVariableNames; |
||||
|
for (auto const& element : ddVariableNamesAsStrings) { |
||||
|
ddVariableNames.push_back(new char[element.size() + 1]); |
||||
|
std::copy(element.c_str(), element.c_str() + element.size() + 1, ddVariableNames.back()); |
||||
|
} |
||||
|
|
||||
|
// Open the file, dump the DD and close it again.
|
||||
|
FILE* filePointer = fopen(filename.c_str() , "w"); |
||||
|
std::vector<BDD> cuddBddVector = { this->getCuddBdd() }; |
||||
|
this->getDdManager()->getCuddManager().DumpDot(cuddBddVector, &ddVariableNames[0], &ddNames[0], filePointer); |
||||
|
fclose(filePointer); |
||||
|
|
||||
|
// Finally, delete the names.
|
||||
|
for (char* element : ddNames) { |
||||
|
delete element; |
||||
|
} |
||||
|
for (char* element : ddVariableNames) { |
||||
|
delete element; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
BDD InternalBdd<DdType::CUDD>::getCuddBdd() const { |
||||
|
return this->cuddBdd; |
||||
|
} |
||||
|
|
||||
|
DdNode* InternalBdd<DdType::CUDD>::getCuddDdNode() const { |
||||
|
return this->getCuddBdd().getNode(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
Add<DdType::CUDD> InternalBdd<DdType::CUDD>::toAdd() const { |
||||
|
return Add<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Add(), this->getContainedMetaVariables()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
template<typename ValueType> |
||||
|
BDD InternalBdd<DdType::CUDD>::fromVector(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, std::vector<ValueType> const& values, Odd<DdType::CUDD> const& odd, std::set<storm::expressions::Variable> const& metaVariables, std::function<bool (ValueType const&)> const& filter) { |
||||
|
std::vector<uint_fast64_t> ddVariableIndices = getSortedVariableIndices(*ddManager, metaVariables); |
||||
|
uint_fast64_t offset = 0; |
||||
|
return BDD(ddManager->getCuddManager(), fromVectorRec(ddManager->getCuddManager().getManager(), offset, 0, ddVariableIndices.size(), values, odd, ddVariableIndices, filter)); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
DdNode* InternalBdd<DdType::CUDD>::fromVectorRec(::DdManager* manager, uint_fast64_t& currentOffset, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::vector<ValueType> const& values, Odd<DdType::CUDD> const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::function<bool (ValueType const&)> const& filter) { |
||||
|
if (currentLevel == maxLevel) { |
||||
|
// If we are in a terminal node of the ODD, we need to check whether the then-offset of the ODD is one
|
||||
|
// (meaning the encoding is a valid one) or zero (meaning the encoding is not valid). Consequently, we
|
||||
|
// need to copy the next value of the vector iff the then-offset is greater than zero.
|
||||
|
if (odd.getThenOffset() > 0) { |
||||
|
if (filter(values[currentOffset++])) { |
||||
|
return Cudd_ReadOne(manager); |
||||
|
} else { |
||||
|
return Cudd_ReadLogicZero(manager); |
||||
|
} |
||||
|
} else { |
||||
|
return Cudd_ReadZero(manager); |
||||
|
} |
||||
|
} else { |
||||
|
// If the total offset is zero, we can just return the constant zero DD.
|
||||
|
if (odd.getThenOffset() + odd.getElseOffset() == 0) { |
||||
|
return Cudd_ReadZero(manager); |
||||
|
} |
||||
|
|
||||
|
// Determine the new else-successor.
|
||||
|
DdNode* elseSuccessor = nullptr; |
||||
|
if (odd.getElseOffset() > 0) { |
||||
|
elseSuccessor = fromVectorRec(manager, currentOffset, currentLevel + 1, maxLevel, values, odd.getElseSuccessor(), ddVariableIndices, filter); |
||||
|
} else { |
||||
|
elseSuccessor = Cudd_ReadLogicZero(manager); |
||||
|
} |
||||
|
Cudd_Ref(elseSuccessor); |
||||
|
|
||||
|
// Determine the new then-successor.
|
||||
|
DdNode* thenSuccessor = nullptr; |
||||
|
if (odd.getThenOffset() > 0) { |
||||
|
thenSuccessor = fromVectorRec(manager, currentOffset, currentLevel + 1, maxLevel, values, odd.getThenSuccessor(), ddVariableIndices, filter); |
||||
|
} else { |
||||
|
thenSuccessor = Cudd_ReadLogicZero(manager); |
||||
|
} |
||||
|
Cudd_Ref(thenSuccessor); |
||||
|
|
||||
|
// Create a node representing ITE(currentVar, thenSuccessor, elseSuccessor);
|
||||
|
DdNode* result = Cudd_bddIthVar(manager, static_cast<int>(ddVariableIndices[currentLevel])); |
||||
|
Cudd_Ref(result); |
||||
|
DdNode* newResult = Cudd_bddIte(manager, result, thenSuccessor, elseSuccessor); |
||||
|
Cudd_Ref(newResult); |
||||
|
|
||||
|
// Dispose of the intermediate results
|
||||
|
Cudd_RecursiveDeref(manager, result); |
||||
|
Cudd_RecursiveDeref(manager, thenSuccessor); |
||||
|
Cudd_RecursiveDeref(manager, elseSuccessor); |
||||
|
|
||||
|
// Before returning, we remove the protection imposed by the previous call to Cudd_Ref.
|
||||
|
Cudd_Deref(newResult); |
||||
|
|
||||
|
return newResult; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
storm::storage::BitVector InternalBdd<DdType::CUDD>::toVector(storm::dd::Odd<DdType::CUDD> const& rowOdd) const { |
||||
|
std::vector<uint_fast64_t> ddVariableIndices = this->getSortedVariableIndices(); |
||||
|
storm::storage::BitVector result(rowOdd.getTotalOffset()); |
||||
|
this->toVectorRec(this->getCuddDdNode(), this->getDdManager()->getCuddManager(), result, rowOdd, Cudd_IsComplement(this->getCuddDdNode()), 0, ddVariableIndices.size(), 0, ddVariableIndices); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
void InternalBdd<DdType::CUDD>::toVectorRec(DdNode const* dd, Cudd const& manager, storm::storage::BitVector& result, Odd<DdType::CUDD> const& rowOdd, bool complement, uint_fast64_t currentRowLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices) const { |
||||
|
// If there are no more values to select, we can directly return.
|
||||
|
if (dd == Cudd_ReadLogicZero(manager.getManager()) && !complement) { |
||||
|
return; |
||||
|
} else if (dd == Cudd_ReadOne(manager.getManager()) && complement) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// If we are at the maximal level, the value to be set is stored as a constant in the DD.
|
||||
|
if (currentRowLevel == maxLevel) { |
||||
|
result.set(currentRowOffset, true); |
||||
|
} else if (ddRowVariableIndices[currentRowLevel] < dd->index) { |
||||
|
toVectorRec(dd, manager, result, rowOdd.getElseSuccessor(), complement, currentRowLevel + 1, maxLevel, currentRowOffset, ddRowVariableIndices); |
||||
|
toVectorRec(dd, manager, result, rowOdd.getThenSuccessor(), complement, currentRowLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), ddRowVariableIndices); |
||||
|
} else { |
||||
|
// Otherwise, we compute the ODDs for both the then- and else successors.
|
||||
|
DdNode* elseDdNode = Cudd_E(dd); |
||||
|
DdNode* thenDdNode = Cudd_T(dd); |
||||
|
|
||||
|
// Determine whether we have to evaluate the successors as if they were complemented.
|
||||
|
bool elseComplemented = Cudd_IsComplement(elseDdNode) ^ complement; |
||||
|
bool thenComplemented = Cudd_IsComplement(thenDdNode) ^ complement; |
||||
|
|
||||
|
toVectorRec(Cudd_Regular(elseDdNode), manager, result, rowOdd.getElseSuccessor(), elseComplemented, currentRowLevel + 1, maxLevel, currentRowOffset, ddRowVariableIndices); |
||||
|
toVectorRec(Cudd_Regular(thenDdNode), manager, result, rowOdd.getThenSuccessor(), thenComplemented, currentRowLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(), ddRowVariableIndices); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD>::InternalBdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddBdd, std::set<storm::expressions::Variable> const& containedMetaVariables) : Dd<DdType::CUDD>(ddManager, containedMetaVariables), cuddBdd(cuddBdd) { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
InternalBdd<DdType::CUDD>::InternalBdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, std::vector<double> const& explicitValues, storm::dd::Odd<DdType::CUDD> const& odd, std::set<storm::expressions::Variable> const& metaVariables, storm::logic::ComparisonType comparisonType, double value) : Dd<DdType::CUDD>(ddManager, metaVariables) { |
||||
|
switch (comparisonType) { |
||||
|
case storm::logic::ComparisonType::Less: |
||||
|
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::greater<double>(), value, std::placeholders::_1)); |
||||
|
break; |
||||
|
case storm::logic::ComparisonType::LessEqual: |
||||
|
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::greater_equal<double>(), value, std::placeholders::_1)); |
||||
|
break; |
||||
|
case storm::logic::ComparisonType::Greater: |
||||
|
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::less<double>(), value, std::placeholders::_1)); |
||||
|
break; |
||||
|
case storm::logic::ComparisonType::GreaterEqual: |
||||
|
this->cuddBdd = fromVector<double>(ddManager, explicitValues, odd, metaVariables, std::bind(std::less_equal<double>(), value, std::placeholders::_1)); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue