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
-
135src/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_ |
|||
#define STORM_STORAGE_DD_DD_H_ |
|||
|
|||
#include <vector> |
|||
#include <string> |
|||
#include <set> |
|||
|
|||
#include "src/storage/dd/DdType.h" |
|||
#include "src/storage/expressions/Variable.h" |
|||
|
|||
namespace storm { |
|||
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