Browse Source

Started refactoring DD abstraction layer.

Former-commit-id: 60f7713c24
main
dehnert 10 years ago
parent
commit
5bd6ca606f
  1. 14
      src/storage/dd/Add.h
  2. 14
      src/storage/dd/Bdd.h
  3. 1174
      src/storage/dd/CuddAdd.cpp
  4. 845
      src/storage/dd/CuddAdd.h
  5. 321
      src/storage/dd/CuddBdd.cpp
  6. 275
      src/storage/dd/CuddBdd.h
  7. 1158
      src/storage/dd/CuddDd.cpp
  8. 731
      src/storage/dd/CuddDd.h

14
src/storage/dd/Add.h

@ -0,0 +1,14 @@
#ifndef STORM_STORAGE_DD_ADD_H_
#define STORM_STORAGE_DD_ADD_H_
#include "src/storage/dd/Dd.h"
#include "src/storage/dd/DdType.h"
namespace storm {
namespace dd {
// Declare Add class so we can then specialize it for the different ADD types.
template<DdType Type> class Add;
}
}
#endif /* STORM_STORAGE_DD_ADD_H_ */

14
src/storage/dd/Bdd.h

@ -0,0 +1,14 @@
#ifndef STORM_STORAGE_DD_BDD_H_
#define STORM_STORAGE_DD_BDD_H_
#include "src/storage/dd/Dd.h"
#include "src/storage/dd/DdType.h"
namespace storm {
namespace dd {
// Declare Bdd class so we can then specialize it for the different BDD types.
template<DdType Type> class Bdd;
}
}
#endif /* STORM_STORAGE_DD_BDD_H_ */

1174
src/storage/dd/CuddAdd.cpp
File diff suppressed because it is too large
View File

845
src/storage/dd/CuddAdd.h

@ -0,0 +1,845 @@
#ifndef STORM_STORAGE_DD_CUDDDD_H_
#define STORM_STORAGE_DD_CUDDDD_H_
#include <map>
#include <set>
#include <memory>
#include <iostream>
#include <boost/variant.hpp>
#include "src/storage/dd/Dd.h"
#include "src/storage/dd/CuddDdForwardIterator.h"
#include "src/storage/SparseMatrix.h"
#include "src/storage/expressions/Expression.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<>
class Dd<DdType::CUDD> {
public:
// Declare the DdManager and DdIterator class as friend so it can access the internals of a DD.
friend class DdManager<DdType::CUDD>;
friend class DdForwardIterator<DdType::CUDD>;
friend class Odd<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 whether the two DDs represent the same function.
*
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the same function.
*/
bool operator==(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves whether the two DDs represent different functions.
*
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the different functions.
*/
bool operator!=(Dd<DdType::CUDD> const& other) const;
/*!
* Performs an if-then-else with the given operands, i.e. maps all valuations that are mapped to a non-zero
* function value to the function values specified by the first DD and all others to the function values
* specified by the second DD.
*/
Dd<DdType::CUDD> ite(Dd<DdType::CUDD> const& thenDd, Dd<DdType::CUDD> const& elseDd) const;
/*!
* Performs a logical or of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical or of the operands.
*/
Dd<DdType::CUDD> operator||(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical or of the current and the given DD and assigns it to the current DD.
*
* @param other The second DD used for the operation.
* @return A reference to the current DD after the operation
*/
Dd<DdType::CUDD>& operator|=(Dd<DdType::CUDD> const& other);
/*!
* Performs a logical and of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical and of the operands.
*/
Dd<DdType::CUDD> operator&&(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical and of the current and the given DD and assigns it to the current DD.
*
* @param other The second DD used for the operation.
* @return A reference to the current DD after the operation
*/
Dd<DdType::CUDD>& operator&=(Dd<DdType::CUDD> const& other);
/*!
* Performs a logical iff of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical iff of the operands.
*/
Dd<DdType::CUDD> iff(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical exclusive-or of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical exclusive-or of the operands.
*/
Dd<DdType::CUDD> exclusiveOr(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical implication of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical implication of the operands.
*/
Dd<DdType::CUDD> implies(Dd<DdType::CUDD> const& other) const;
/*!
* Adds the two DDs.
*
* @param other The DD to add to the current one.
* @return The result of the addition.
*/
Dd<DdType::CUDD> operator+(Dd<DdType::CUDD> const& other) const;
/*!
* Adds the given DD to the current one.
*
* @param other The DD to add to the current one.
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& operator+=(Dd<DdType::CUDD> const& other);
/*!
* Multiplies the two DDs.
*
* @param other The DD to multiply with the current one.
* @return The result of the multiplication.
*/
Dd<DdType::CUDD> operator*(Dd<DdType::CUDD> const& other) const;
/*!
* Multiplies the given DD with the current one and assigns the result to the current DD.
*
* @param other The DD to multiply with the current one.
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& operator*=(Dd<DdType::CUDD> const& other);
/*!
* Subtracts the given DD from the current one.
*
* @param other The DD to subtract from the current one.
* @return The result of the subtraction.
*/
Dd<DdType::CUDD> operator-(Dd<DdType::CUDD> const& other) const;
/*!
* Subtracts the DD from the constant zero function.
*
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> operator-() const;
/*!
* Subtracts the given DD from the current one and assigns the result to the current DD.
*
* @param other The DD to subtract from the current one.
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& operator-=(Dd<DdType::CUDD> const& other);
/*!
* Divides the current DD by the given one.
*
* @param other The DD by which to divide the current one.
* @return The result of the division.
*/
Dd<DdType::CUDD> operator/(Dd<DdType::CUDD> const& other) const;
/*!
* Divides the current DD by the given one and assigns the result to the current DD.
*
* @param other The DD by which to divide the current one.
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& operator/=(Dd<DdType::CUDD> const& other);
/*!
* Retrieves the logical complement of the current DD. The result will map all encodings with a value
* unequal to zero to false and all others to true.
*
* @return The logical complement of the current DD.
*/
Dd<DdType::CUDD> operator!() const;
/*!
* Logically complements the current DD. The result will map all encodings with a value
* unequal to zero to false and all others to true.
*
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& complement();
/*!
* Retrieves the function that maps all evaluations to one that have an identical function values.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> equals(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one that have distinct function values.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> notEquals(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are less
* than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> less(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are less or
* equal than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> lessOrEqual(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
* than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> greater(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
* or equal than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> greaterOrEqual(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to the minimum of the function values of the two DDs.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> minimum(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to the maximum of the function values of the two DDs.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> maximum(Dd<DdType::CUDD> const& other) const;
/*!
* Existentially abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> existsAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Universally abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> universalAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Sum-abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> sumAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Min-abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> minAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Max-abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> maxAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Checks whether the current and the given DD represent the same function modulo some given precision.
*
* @param other The DD with which to compare.
* @param precision An upper bound on the maximal difference between any two function values that is to be
* tolerated.
* @param relative If set to true, not the absolute values have to be within the precision, but the relative
* values.
*/
bool equalModuloPrecision(Dd<DdType::CUDD> const& other, double precision, bool relative = true) const;
/*!
* Swaps the given pairs of meta variables in the DD. The pairs of meta variables must be guaranteed to have
* the same number of underlying DD variables.
*
* @param metaVariablePairs A vector of meta variable pairs that are to be swapped for one another.
* @return The resulting DD.
*/
Dd<DdType::CUDD> swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs);
/*!
* Multiplies the current DD (representing a matrix) with the given matrix by summing over the given meta
* variables.
*
* @param otherMatrix The matrix with which to multiply.
* @param summationMetaVariables The names of the meta variables over which to sum during the matrix-
* matrix multiplication.
* @return A DD representing the result of the matrix-matrix multiplication.
*/
Dd<DdType::CUDD> multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<storm::expressions::Variable> const& summationMetaVariables) const;
/*!
* Computes the logical and of the current and the given DD and existentially abstracts from the given set
* of variables.
*
* @param other The second DD for the logical and.
* @param existentialVariables The variables from which to existentially abstract.
* @return A DD representing the result.
*/
Dd<DdType::CUDD> andExists(Dd<DdType::CUDD> const& other, std::set<storm::expressions::Variable> const& existentialVariables) const;
/*!
* Computes a DD that represents the function in which all assignments with a function value strictly larger
* than the given value are mapped to one and all others to zero.
*
* @param value The value used for the comparison.
* @return The resulting DD.
*/
Dd<DdType::CUDD> greater(double value) const;
/*!
* Computes a DD that represents the function in which all assignments with a function value larger or equal
* to the given value are mapped to one and all others to zero.
*
* @param value The value used for the comparison.
* @return The resulting DD.
*/
Dd<DdType::CUDD> greaterOrEqual(double value) const;
/*!
* Computes a DD that represents the function in which all assignments with a function value unequal to zero
* are mapped to one and all others to zero.
*
* @return The resulting DD.
*/
Dd<DdType::CUDD> notZero() const;
/*!
* Computes the constraint of the current DD with the given constraint. That is, the function value of the
* resulting DD will be the same as the current ones for all assignments mapping to one in the constraint
* and may be different otherwise.
*
* @param constraint The constraint to use for the operation.
* @return The resulting DD.
*/
Dd<DdType::CUDD> constrain(Dd<DdType::CUDD> const& constraint) const;
/*!
* Computes the restriction of the current DD with the given constraint. That is, the function value of the
* resulting DD will be the same as the current ones for all assignments mapping to one in the constraint
* and may be different otherwise.
*
* @param constraint The constraint to use for the operation.
* @return The resulting DD.
*/
Dd<DdType::CUDD> restrict(Dd<DdType::CUDD> const& constraint) const;
/*!
* Retrieves the support of the current DD.
*
* @return The support represented as a DD.
*/
Dd<DdType::CUDD> getSupport() const;
/*!
* 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.
*/
uint_fast64_t getNonZeroCount() const;
/*!
* Retrieves the number of leaves of the DD.
*
* @return The number of leaves of the DD.
*/
uint_fast64_t getLeafCount() const;
/*!
* Retrieves the number of nodes necessary to represent the DD.
*
* @return The number of nodes in this DD.
*/
uint_fast64_t getNodeCount() const;
/*!
* Retrieves the lowest function value of any encoding.
*
* @return The lowest function value of any encoding.
*/
double getMin() const;
/*!
* Retrieves the highest function value of any encoding.
*
* @return The highest function value of any encoding.
*/
double getMax() const;
/*!
* Sets the function values of all encodings that have the given value of the meta variable to the given
* target value.
*
* @param metaVariable The meta variable that has to be equal to the given value.
* @param variableValue The value that the meta variable is supposed to have. This must be within the range
* of the meta variable.
* @param targetValue The new function value of the modified encodings.
*/
void setValue(storm::expressions::Variable const& metaVariable, int_fast64_t variableValue, double targetValue);
/*!
* Sets the function values of all encodings that have the given values of the two meta variables to the
* given target value.
*
* @param metaVariable1 The first meta variable that has to be equal to the first given
* value.
* @param variableValue1 The value that the first meta variable is supposed to have. This must be within the
* range of the meta variable.
* @param metaVariable2 The second meta variable that has to be equal to the second given
* value.
* @param variableValue2 The value that the second meta variable is supposed to have. This must be within
* the range of the meta variable.
* @param targetValue The new function value of the modified encodings.
*/
void setValue(storm::expressions::Variable const& metaVariable1, int_fast64_t variableValue1, storm::expressions::Variable const& metaVariable2, int_fast64_t variableValue2, double targetValue);
/*!
* Sets the function values of all encodings that have the given values of the given meta variables to the
* given target value.
*
* @param metaVariableToValueMap A mapping of meta variables to the values they are supposed to have. All
* values must be within the range of the respective meta variable.
* @param targetValue The new function value of the modified encodings.
*/
void setValue(std::map<storm::expressions::Variable, int_fast64_t> const& metaVariableToValueMap = std::map<storm::expressions::Variable, int_fast64_t>(), double targetValue = 0);
/*!
* Retrieves the value of the function when all meta variables are assigned the values of the given mapping.
* Note that the mapping must specify values for all meta variables contained in the DD.
*
* @param metaVariableToValueMap A mapping of meta variables to their values.
* @return The value of the function evaluated with the given input.
*/
double getValue(std::map<storm::expressions::Variable, int_fast64_t> const& metaVariableToValueMap = std::map<storm::expressions::Variable, int_fast64_t>()) const;
/*!
* Retrieves whether this DD represents the constant one function.
*
* @return True if this DD represents the constant one function.
*/
bool isOne() const;
/*!
* Retrieves whether this DD represents the constant zero function.
*
* @return True if this DD represents the constant zero function.
*/
bool isZero() const;
/*!
* Retrieves whether this DD represents a constant function.
*
* @return True if this DD represents a constants function.
*/
bool isConstant() const;
/*!
* Retrieves the index of the topmost variable in the DD.
*
* @return The index of the topmost variable in DD.
*/
uint_fast64_t getIndex() const;
/*!
* Converts the DD to a vector.
*
* @return The double vector that is represented by this DD.
*/
template<typename ValueType>
std::vector<ValueType> toVector() const;
/*!
* Converts the DD to a vector. The given offset-labeled DD is used to determine the correct row of
* each entry.
*
* @param rowOdd The ODD used for determining the correct row.
* @return The double vector that is represented by this DD.
*/
template<typename ValueType>
std::vector<ValueType> toVector(storm::dd::Odd<DdType::CUDD> const& rowOdd) const;
/*!
* Converts the DD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
* row, whereas all primed variables are assumed to encode the column.
*
* @return The matrix that is represented by this DD.
*/
storm::storage::SparseMatrix<double> toMatrix() const;
/*!
* Converts the DD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
* row, whereas all primed variables are assumed to encode the column. The given offset-labeled DDs are used
* to determine the correct row and column, respectively, for each entry.
*
* @param rowOdd The ODD used for determining the correct row.
* @param columnOdd The ODD used for determining the correct column.
* @return The matrix that is represented by this DD.
*/
storm::storage::SparseMatrix<double> toMatrix(storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
/*!
* Converts the DD to a (sparse) double matrix. The given offset-labeled DDs are used to determine the
* correct row and column, respectively, for each entry.
*
* @param rowMetaVariables The meta variables that encode the rows of the matrix.
* @param columnMetaVariables The meta variables that encode the columns of the matrix.
* @param rowOdd The ODD used for determining the correct row.
* @param columnOdd The ODD used for determining the correct column.
* @return The matrix that is represented by this DD.
*/
storm::storage::SparseMatrix<double> toMatrix(std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
/*!
* Converts the DD to a row-grouped (sparse) double matrix. The given offset-labeled DDs are used to
* determine the correct row and column, respectively, for each entry. Note: this function assumes that
* the meta variables used to distinguish different row groups are at the very top of the DD.
*
* @param rowMetaVariables The meta variables that encode the rows of the matrix.
* @param columnMetaVariables The meta variables that encode the columns of the matrix.
* @param groupMetaVariables The meta variables that are used to distinguish different row groups.
* @param rowOdd The ODD used for determining the correct row.
* @param columnOdd The ODD used for determining the correct column.
* @return The matrix that is represented by this DD.
*/
storm::storage::SparseMatrix<double> toMatrix(std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::set<storm::expressions::Variable> const& groupMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
/*!
* 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;
/*!
* 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();
/*!
* 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.
*/
void exportToDot(std::string const& filename = "") const;
/*!
* 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 an iterator that points to the first meta variable assignment with a non-zero function value.
*
* @param enumerateDontCareMetaVariables If set to true, all meta variable assignments are enumerated, even
* if a meta variable does not at all influence the the function value.
* @return An iterator that points to the first meta variable assignment with a non-zero function value.
*/
DdForwardIterator<DdType::CUDD> begin(bool enumerateDontCareMetaVariables = true) const;
/*!
* Retrieves an iterator that points past the end of the container.
*
* @param enumerateDontCareMetaVariables If set to true, all meta variable assignments are enumerated, even
* if a meta variable does not at all influence the the function value.
* @return An iterator that points past the end of the container.
*/
DdForwardIterator<DdType::CUDD> end(bool enumerateDontCareMetaVariables = true) const;
/*!
* Converts the DD into a (heavily nested) if-then-else expression that represents the very same function.
* The variable names used in the expression are derived from the meta variable name and are extended with a
* suffix ".i" if the meta variable is integer-valued, expressing that the variable is the i-th bit of the
* meta variable.
*
* @return The resulting expression.
*/
storm::expressions::Expression toExpression() const;
/*!
* Converts the DD into a (heavily nested) if-then-else (with negations) expression that evaluates to true
* if and only if the assignment is minterm of the DD. The variable names used in the expression are derived
* from the meta variable name and are extended with a suffix ".i" if the meta variable is integer-valued,
* expressing that the variable is the i-th bit of the meta variable.
*
* @return The resulting expression.
*/
storm::expressions::Expression getMintermExpression() const;
friend std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd);
/*!
* Converts an MTBDD to a BDD by mapping all values unequal to zero to 1. This effectively does the same as
* a call to notZero().
*
* @return The corresponding BDD.
*/
Dd<DdType::CUDD> toBdd() const;
/*!
* Converts a BDD to an equivalent MTBDD.
*
* @return The corresponding MTBDD.
*/
Dd<DdType::CUDD> toMtbdd() const;
/*!
* Retrieves whether this DD is a BDD.
*
* @return True iff this DD is a BDD.
*/
bool isBdd() const;
/*!
* Retrieves whether this DD is an MTBDD. Even though MTBDDs technicall subsume BDDs, this will return false
* if the DD is actually a BDD.
*
* @return True iff this DD is an MTBDD.
*/
bool isMtbdd() const;
private:
/*!
* Retrieves the CUDD BDD object associated with this DD.
*
* @return The CUDD BDD object associated with this DD.
*/
BDD getCuddBdd() const;
/*!
* Retrieves the CUDD MTBDD object associated with this DD.
*
* @return The CUDD MTBDD object associated with this DD.
*/
ADD getCuddMtbdd() const;
/*!
* Retrieves the CUDD object associated with this DD.
*
* @return The CUDD object associated with this DD.
*/
ABDD const& getCuddDd() const;
/*!
* Retrieves the raw DD node of CUDD associated with this DD.
*
* @return The DD node of CUDD associated with this DD.
*/
DdNode* getCuddDdNode() const;
/*!
* 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 addContainedMetaVariable(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 removeContainedMetaVariable(storm::expressions::Variable const& metaVariable);
/*!
* Performs the recursive step of toExpression on the given DD.
*
* @param dd The dd to translate into an expression.
* @param variables The variables to use in the expression.
* @return The resulting expression.
*/
static storm::expressions::Expression toExpressionRecur(DdNode const* dd, std::vector<storm::expressions::Variable> const& variables);
/*!
* Performs the recursive step of getMintermExpression on the given DD.
*
* @param manager The manager of the DD.
* @param dd The dd whose minterms to translate into an expression.
* @param variables The variables to use in the expression.
* @return The resulting expression.
*/
static storm::expressions::Expression getMintermExpressionRecur(::DdManager* manager, DdNode const* dd, std::vector<storm::expressions::Variable> const& variables);
/*!
* Creates a DD that encapsulates the given CUDD ADD.
*
* @param ddManager The manager responsible for this DD.
* @param cuddDd The CUDD ADD to store.
* @param containedMetaVariables The meta variables that appear in the DD.
*/
Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, ADD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
/*!
* Creates a DD that encapsulates the given CUDD ADD.
*
* @param ddManager The manager responsible for this DD.
* @param cuddDd The CUDD ADD to store.
* @param containedMetaVariables The meta variables that appear in the DD.
*/
Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
/*!
* Helper function to convert the DD into a (sparse) matrix.
*
* @param dd The DD to convert.
* @param rowIndications A vector indicating at which position in the columnsAndValues vector the entries
* of row i start. Note: this vector is modified in the computation. More concretely, each entry i in the
* vector will be increased by the number of entries in the row. This can be used to count the number
* of entries in each row. If the values are not to be modified, a copy needs to be provided or the entries
* need to be restored afterwards.
* @param columnsAndValues The vector that will hold the columns and values of non-zero entries upon successful
* completion.
* @param rowGroupOffsets The row offsets at which a given row group starts.
* @param rowOdd The ODD used for the row translation.
* @param columnOdd The ODD used for the column translation.
* @param currentRowLevel The currently considered row level in the DD.
* @param currentColumnLevel The currently considered row level in the DD.
* @param maxLevel The number of levels that need to be considered.
* @param currentRowOffset The current row offset.
* @param currentColumnOffset The current row offset.
* @param ddRowVariableIndices The (sorted) indices of all DD row variables that need to be considered.
* @param ddColumnVariableIndices The (sorted) indices of all DD row variables that need to be considered.
* @param generateValues If set to true, the vector columnsAndValues is filled with the actual entries, which
* only works if the offsets given in rowIndications are already correct. If they need to be computed first,
* this flag needs to be false.
*/
void toMatrixRec(DdNode const* dd, std::vector<uint_fast64_t>& rowIndications, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>>& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupOffsets, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool generateValues = true) const;
/*!
* Splits the given matrix DD into the groups using the given group variables.
*
* @param dd The DD to split.
* @param groups A vector that is to be filled with the DDs for the individual groups.
* @param ddGroupVariableIndices The (sorted) indices of all DD group variables that need to be considered.
* @param currentLevel The currently considered level in the DD.
* @param maxLevel The number of levels that need to be considered.
* @param remainingMetaVariables The meta variables that remain in the DDs after the groups have been split.
*/
void splitGroupsRec(DdNode* dd, std::vector<Dd<DdType::CUDD>>& groups, std::vector<uint_fast64_t> const& ddGroupVariableIndices, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::set<storm::expressions::Variable> const& remainingMetaVariables) const;
/*!
* Performs a recursive step to add the given DD-based vector to the given explicit vector.
*
* @param dd The DD to add to the explicit vector.
* @param currentLevel The currently considered level in the DD.
* @param maxLevel The number of levels that need to be considered.
* @param currentOffset The current offset.
* @param odd The ODD used for the translation.
* @param ddVariableIndices The (sorted) indices of all DD variables that need to be considered.
* @param targetVector The vector to which the translated DD-based vector is to be added.
*/
template<typename ValueType>
void addToVectorRec(DdNode const* dd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, Odd<DdType::CUDD> const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<ValueType>& targetVector) const;
/*!
* Retrieves the indices of all DD variables that are contained in this DD (not necessarily in the support,
* because they could be "don't cares"). Additionally, the indices are sorted to allow for easy access.
*
* @return The (sorted) indices of all DD variables that are contained in this DD.
*/
std::vector<uint_fast64_t> getSortedVariableIndices() const;
// A pointer to the manager responsible for this DD.
std::shared_ptr<DdManager<DdType::CUDD> const> ddManager;
// The ADD created by CUDD.
boost::variant<BDD, ADD> cuddDd;
// The meta variables that appear in this DD.
std::set<storm::expressions::Variable> containedMetaVariables;
};
}
}
#endif /* STORM_STORAGE_DD_CUDDDD_H_ */

321
src/storage/dd/CuddBdd.cpp

@ -0,0 +1,321 @@
#include <cstring>
#include <algorithm>
#include "src/storage/dd/CuddBdd.h"
#include "src/storage/dd/CuddAdd.h"
#include "src/storage/dd/CuddDdManager.h"
namespace storm {
namespace dd {
Bdd<DdType::CUDD>::Bdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables) : Dd<DdType::CUDD>(ddManager, containedMetaVariables) {
// Intentionally left empty.
}
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();
}
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::operator&&(Bdd<DdType::CUDD> const& other) const {
Dd<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 {
Dd<DdType::CUDD> cubeDd(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);
cubeDd &= ddMetaVariable.getCube();
}
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().ExistAbstract(cubeDd.getCuddBdd()), newMetaVariables);
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::universalAbstract(std::set<storm::expressions::Variable> const& metaVariables) const {
Dd<DdType::CUDD> cubeDd(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);
cubeDd &= ddMetaVariable.getCube();
}
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().UnivAbstract(cubeDd.getCuddBdd()), newMetaVariables);
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) {
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 {
STORM_LOG_WARN_COND(this->isBdd() && other.isBdd(), "Performing logical operation on MTBDD(s).");
Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
for (auto const& metaVariable : existentialVariables) {
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable);
cubeDd &= 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 Dd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().AndAbstract(other.getCuddBdd(), cubeDd.getCuddBdd()), containedMetaVariables);
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::constrain(Dd<DdType::CUDD> const& constraint) const {
std::set<storm::expressions::Variable> metaVariables(this->getContainedMetaVariables());
metaVariables.insert(constraint.getContainedMetaVariables().begin(), constraint.getContainedMetaVariables().end());
if (this->isBdd() && constraint.isBdd()) {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Constrain(constraint.getCuddBdd()), metaVariables);
} else {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddMtbdd().Constrain(constraint.getCuddMtbdd()), metaVariables);
}
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::restrict(Dd<DdType::CUDD> const& constraint) const {
std::set<storm::expressions::Variable> metaVariables(this->getContainedMetaVariables());
metaVariables.insert(constraint.getContainedMetaVariables().begin(), constraint.getContainedMetaVariables().end());
if (this->isBdd() && constraint.isBdd()) {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Restrict(constraint.getCuddBdd()), metaVariables);
} else {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddMtbdd().Restrict(constraint.getCuddMtbdd()), metaVariables);
}
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::getSupport() const {
if (this->isBdd()) {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Support(), this->getContainedMetaVariables());
} else {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddMtbdd().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();
}
if (this->isBdd()) {
return static_cast<uint_fast64_t>(this->getCuddBdd().CountMinterm(static_cast<int>(numberOfDdVariables)));
} else {
return static_cast<uint_fast64_t>(this->getCuddMtbdd().CountMinterm(static_cast<int>(numberOfDdVariables)));
}
}
uint_fast64_t Bdd<DdType::CUDD>::getLeafCount() const {
if (this->isBdd()) {
return static_cast<uint_fast64_t>(this->getCuddBdd().CountLeaves());
} else {
return static_cast<uint_fast64_t>(this->getCuddMtbdd().CountLeaves());
}
}
uint_fast64_t Bdd<DdType::CUDD>::getNodeCount() const {
if (this->isBdd()) {
return static_cast<uint_fast64_t>(this->getCuddBdd().nodeCount());
} else {
return static_cast<uint_fast64_t>(this->getCuddMtbdd().nodeCount());
}
}
bool Bdd<DdType::CUDD>::isOne() const {
if (this->isBdd()) {
return this->getCuddBdd().IsOne();
} else {
return this->getCuddMtbdd().IsOne();
}
}
bool Bdd<DdType::CUDD>::isZero() const {
if (this->isBdd()) {
return this->getCuddBdd().IsZero();
} else {
return this->getCuddMtbdd().IsZero();
}
}
uint_fast64_t Bdd<DdType::CUDD>::getIndex() const {
if (this->isBdd()) {
return static_cast<uint_fast64_t>(this->getCuddBdd().NodeReadIndex());
} else {
return static_cast<uint_fast64_t>(this->getCuddMtbdd().NodeReadIndex());
}
}
std::vector<uint_fast64_t> Bdd<DdType::CUDD>::getSortedVariableIndices() const {
std::vector<uint_fast64_t> ddVariableIndices;
for (auto const& metaVariableName : this->getContainedMetaVariables()) {
auto const& metaVariable = this->getDdManager()->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;
}
void Bdd<DdType::CUDD>::exportToDot(std::string const& filename) const {
if (filename.empty()) {
if (this->isBdd()) {
std::vector<BDD> cuddBddVector = { this->getCuddBdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddBddVector);
} else {
std::vector<ADD> cuddAddVector = { this->getCuddMtbdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddAddVector);
}
} 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");
if (this->isBdd()) {
std::vector<BDD> cuddBddVector = { this->getCuddBdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddBddVector, &ddVariableNames[0], &ddNames[0], filePointer);
} else {
std::vector<ADD> cuddAddVector = { this->getCuddMtbdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddAddVector, &ddVariableNames[0], &ddNames[0], filePointer);
}
fclose(filePointer);
// Finally, delete the names.
for (char* element : ddNames) {
delete element;
}
for (char* element : ddVariableNames) {
delete element;
}
}
}
std::ostream& operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd) {
dd.exportToDot();
return out;
}
}
}

275
src/storage/dd/CuddBdd.h

@ -0,0 +1,275 @@
#ifndef STORM_STORAGE_DD_CUDDBDD_H_
#define STORM_STORAGE_DD_CUDDBDD_H_
#include "src/storage/dd/Bdd.h"
#include "src/storage/dd/CuddDd.h"
#include "src/storage/dd/CuddAdd.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 Add;
template<>
class Bdd<DdType::CUDD> : public Dd<DdType::CUDD> {
public:
// Declare the DdManager and DdIterator class as friend so it can access the internals of a DD.
friend class DdManager<DdType::CUDD>;
friend class DdForwardIterator<DdType::CUDD>;
friend class Odd<DdType::CUDD>;
// Instantiate all copy/move constructors/assignments with the default implementation.
Bdd() = default;
Bdd(Bdd<DdType::CUDD> const& other) = default;
Bdd& operator=(Bdd<DdType::CUDD> const& other) = default;
#ifndef WINDOWS
Bdd(Bdd<DdType::CUDD>&& other) = default;
Bdd& operator=(Bdd<DdType::CUDD>&& other) = default;
#endif
/*!
* Retrieves whether the two BDDs represent the same function.
*
* @param other The BDD that is to be compared with the current one.
* @return True if the BDDs represent the same function.
*/
bool operator==(Bdd<DdType::CUDD> const& other) const;
/*!
* Retrieves whether the two BDDs represent different functions.
*
* @param other The BDD that is to be compared with the current one.
* @return True if the BDDs represent the different functions.
*/
bool operator!=(Bdd<DdType::CUDD> const& other) const;
/*!
* Performs an if-then-else with the given operands, i.e. maps all valuations that are mapped to a non-zero
* function value to the function values specified by the first DD and all others to the function values
* specified by the second DD.
*
* @param thenBdd The BDD defining the 'then' part.
* @param elseBdd The BDD defining the 'else' part.
* @return The resulting BDD.
*/
Bdd<DdType::CUDD> ite(Bdd<DdType::CUDD> const& thenBdd, Bdd<DdType::CUDD> const& elseBdd) const;
/*!
* Performs a logical or of the current and the given BDD.
*
* @param other The second BDD used for the operation.
* @return The logical or of the operands.
*/
Bdd<DdType::CUDD> operator||(Bdd<DdType::CUDD> const& other) const;
/*!
* Performs a logical or of the current and the given BDD and assigns it to the current BDD.
*
* @param other The second BDD used for the operation.
* @return A reference to the current BDD after the operation
*/
Bdd<DdType::CUDD>& operator|=(Bdd<DdType::CUDD> const& other);
/*!
* Performs a logical and of the current and the given BDD.
*
* @param other The second BDD used for the operation.
* @return The logical and of the operands.
*/
Bdd<DdType::CUDD> operator&&(Bdd<DdType::CUDD> const& other) const;
/*!
* Performs a logical and of the current and the given BDD and assigns it to the current BDD.
*
* @param other The second BDD used for the operation.
* @return A reference to the current BDD after the operation
*/
Bdd<DdType::CUDD>& operator&=(Bdd<DdType::CUDD> const& other);
/*!
* Performs a logical iff of the current and the given BDD.
*
* @param other The second BDD used for the operation.
* @return The logical iff of the operands.
*/
Bdd<DdType::CUDD> iff(Bdd<DdType::CUDD> const& other) const;
/*!
* Performs a logical exclusive-or of the current and the given BDD.
*
* @param other The second BDD used for the operation.
* @return The logical exclusive-or of the operands.
*/
Bdd<DdType::CUDD> exclusiveOr(Bdd<DdType::CUDD> const& other) const;
/*!
* Performs a logical implication of the current and the given BDD.
*
* @param other The second BDD used for the operation.
* @return The logical implication of the operands.
*/
Bdd<DdType::CUDD> implies(Bdd<DdType::CUDD> const& other) const;
/*!
* Logically inverts the current BDD.
*
* @return The resulting BDD.
*/
Bdd<DdType::CUDD> operator!() const;
/*!
* Logically complements the current BDD.
*
* @return A reference to the current BDD after the operation.
*/
Bdd<DdType::CUDD>& complement();
/*!
* Existentially abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Bdd<DdType::CUDD> existsAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Universally abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Bdd<DdType::CUDD> universalAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Swaps the given pairs of meta variables in the BDD. The pairs of meta variables must be guaranteed to have
* the same number of underlying BDD variables.
*
* @param metaVariablePairs A vector of meta variable pairs that are to be swapped for one another.
* @return The resulting BDD.
*/
Bdd<DdType::CUDD> swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs);
/*!
* Computes the logical and of the current and the given BDD and existentially abstracts from the given set
* of variables.
*
* @param other The second BDD for the logical and.
* @param existentialVariables The variables from which to existentially abstract.
* @return A BDD representing the result.
*/
Bdd<DdType::CUDD> andExists(Bdd<DdType::CUDD> const& other, std::set<storm::expressions::Variable> const& existentialVariables) const;
/*!
* Computes the constraint of the current BDD with the given constraint. That is, the function value of the
* resulting BDD will be the same as the current ones for all assignments mapping to one in the constraint
* and may be different otherwise.
*
* @param constraint The constraint to use for the operation.
* @return The resulting BDD.
*/
Bdd<DdType::CUDD> constrain(Bdd<DdType::CUDD> const& constraint) const;
/*!
* Computes the restriction of the current BDD with the given constraint. That is, the function value of the
* resulting DD will be the same as the current ones for all assignments mapping to one in the constraint
* and may be different otherwise.
*
* @param constraint The constraint to use for the operation.
* @return The resulting BDD.
*/
Bdd<DdType::CUDD> restrict(Bdd<DdType::CUDD> const& constraint) const;
/*!
* Retrieves the support of the current BDD.
*
* @return The support represented as a BDD.
*/
virtual Bdd<DdType::CUDD> getSupport() const override;
/*!
* 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 override;
/*!
* Retrieves the number of nodes necessary to represent the DD.
*
* @return The number of nodes in this DD.
*/
virtual uint_fast64_t getNodeCount() const override;
/*!
* Retrieves whether this DD represents the constant one function.
*
* @return True if this DD represents the constant one function.
*/
bool isOne() const;
/*!
* Retrieves whether this DD represents the constant zero function.
*
* @return True if this DD represents the constant zero function.
*/
bool isZero() const;
/*!
* Retrieves the index of the topmost variable in the BDD.
*
* @return The index of the topmost variable in BDD.
*/
virtual uint_fast64_t getIndex() const override;
/*!
* Exports the BDD to the given file in the dot format.
*
* @param filename The name of the file to which the BDD is to be exported.
*/
virtual void exportToDot(std::string const& filename = "") const override;
friend std::ostream & operator<<(std::ostream& out, const Bdd<DdType::CUDD>& bdd);
/*!
* Converts a BDD to an equivalent ADD.
*
* @return The corresponding ADD.
*/
Add<DdType::CUDD> toAdd() const;
private:
/*!
* Retrieves the CUDD BDD object associated with this DD.
*
* @return The CUDD BDD object associated with this DD.
*/
BDD getCuddBdd() const;
/*!
* Retrieves the raw DD node of CUDD associated with this BDD.
*
* @return The DD node of CUDD associated with this BDD.
*/
DdNode* getCuddDdNode() const;
/*!
* Creates a DD that encapsulates the given CUDD ADD.
*
* @param ddManager The manager responsible for this DD.
* @param cuddDd The CUDD ADD to store.
* @param containedMetaVariables The meta variables that appear in the DD.
*/
Bdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
// The BDD created by CUDD.
BDD cuddBdd;
};
}
}
#endif /* STORM_STORAGE_DD_CUDDBDD_H_ */

1158
src/storage/dd/CuddDd.cpp
File diff suppressed because it is too large
View File

731
src/storage/dd/CuddDd.h

@ -1,16 +1,10 @@
#ifndef STORM_STORAGE_DD_CUDDDD_H_
#define STORM_STORAGE_DD_CUDDDD_H_
#include <map>
#include <set>
#include <memory>
#include <iostream>
#include <boost/variant.hpp>
#include "src/storage/dd/Dd.h"
#include "src/storage/dd/CuddDdForwardIterator.h"
#include "src/storage/SparseMatrix.h"
#include "src/storage/expressions/Expression.h"
#include "src/storage/expressions/Variable.h"
#include "src/utility/OsDetection.h"
@ -22,14 +16,13 @@ namespace storm {
// 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 and DdIterator class as friend so it can access the internals of a DD.
// Declare the DdManager so it can access the internals of a DD.
friend class DdManager<DdType::CUDD>;
friend class DdForwardIterator<DdType::CUDD>;
friend class Odd<DdType::CUDD>;
// Instantiate all copy/move constructors/assignments with the default implementation.
Dd() = default;
@ -40,540 +33,40 @@ namespace storm {
Dd& operator=(Dd<DdType::CUDD>&& other) = default;
#endif
/*!
* Retrieves whether the two DDs represent the same function.
*
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the same function.
*/
bool operator==(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves whether the two DDs represent different functions.
*
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the different functions.
*/
bool operator!=(Dd<DdType::CUDD> const& other) const;
/*!
* Performs an if-then-else with the given operands, i.e. maps all valuations that are mapped to a non-zero
* function value to the function values specified by the first DD and all others to the function values
* specified by the second DD.
*/
Dd<DdType::CUDD> ite(Dd<DdType::CUDD> const& thenDd, Dd<DdType::CUDD> const& elseDd) const;
/*!
* Performs a logical or of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical or of the operands.
*/
Dd<DdType::CUDD> operator||(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical or of the current and the given DD and assigns it to the current DD.
*
* @param other The second DD used for the operation.
* @return A reference to the current DD after the operation
*/
Dd<DdType::CUDD>& operator|=(Dd<DdType::CUDD> const& other);
/*!
* Performs a logical and of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical and of the operands.
*/
Dd<DdType::CUDD> operator&&(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical and of the current and the given DD and assigns it to the current DD.
*
* @param other The second DD used for the operation.
* @return A reference to the current DD after the operation
*/
Dd<DdType::CUDD>& operator&=(Dd<DdType::CUDD> const& other);
/*!
* Performs a logical iff of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical iff of the operands.
*/
Dd<DdType::CUDD> iff(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical exclusive-or of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical exclusive-or of the operands.
*/
Dd<DdType::CUDD> exclusiveOr(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical implication of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical implication of the operands.
*/
Dd<DdType::CUDD> implies(Dd<DdType::CUDD> const& other) const;
/*!
* Adds the two DDs.
*
* @param other The DD to add to the current one.
* @return The result of the addition.
*/
Dd<DdType::CUDD> operator+(Dd<DdType::CUDD> const& other) const;
/*!
* Adds the given DD to the current one.
*
* @param other The DD to add to the current one.
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& operator+=(Dd<DdType::CUDD> const& other);
/*!
* Multiplies the two DDs.
*
* @param other The DD to multiply with the current one.
* @return The result of the multiplication.
*/
Dd<DdType::CUDD> operator*(Dd<DdType::CUDD> const& other) const;
/*!
* Multiplies the given DD with the current one and assigns the result to the current DD.
*
* @param other The DD to multiply with the current one.
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& operator*=(Dd<DdType::CUDD> const& other);
/*!
* Subtracts the given DD from the current one.
*
* @param other The DD to subtract from the current one.
* @return The result of the subtraction.
*/
Dd<DdType::CUDD> operator-(Dd<DdType::CUDD> const& other) const;
/*!
* Subtracts the DD from the constant zero function.
*
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> operator-() const;
/*!
* Subtracts the given DD from the current one and assigns the result to the current DD.
*
* @param other The DD to subtract from the current one.
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& operator-=(Dd<DdType::CUDD> const& other);
/*!
* Divides the current DD by the given one.
*
* @param other The DD by which to divide the current one.
* @return The result of the division.
*/
Dd<DdType::CUDD> operator/(Dd<DdType::CUDD> const& other) const;
/*!
* Divides the current DD by the given one and assigns the result to the current DD.
*
* @param other The DD by which to divide the current one.
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& operator/=(Dd<DdType::CUDD> const& other);
/*!
* Retrieves the logical complement of the current DD. The result will map all encodings with a value
* unequal to zero to false and all others to true.
*
* @return The logical complement of the current DD.
*/
Dd<DdType::CUDD> operator!() const;
/*!
* Logically complements the current DD. The result will map all encodings with a value
* unequal to zero to false and all others to true.
*
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& complement();
/*!
* Retrieves the function that maps all evaluations to one that have an identical function values.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> equals(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one that have distinct function values.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> notEquals(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are less
* than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> less(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are less or
* equal than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> lessOrEqual(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
* than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> greater(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
* or equal than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> greaterOrEqual(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to the minimum of the function values of the two DDs.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> minimum(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to the maximum of the function values of the two DDs.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> maximum(Dd<DdType::CUDD> const& other) const;
/*!
* Existentially abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> existsAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Universally abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> universalAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Sum-abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> sumAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Min-abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> minAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Max-abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> maxAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Checks whether the current and the given DD represent the same function modulo some given precision.
*
* @param other The DD with which to compare.
* @param precision An upper bound on the maximal difference between any two function values that is to be
* tolerated.
* @param relative If set to true, not the absolute values have to be within the precision, but the relative
* values.
*/
bool equalModuloPrecision(Dd<DdType::CUDD> const& other, double precision, bool relative = true) const;
/*!
* Swaps the given pairs of meta variables in the DD. The pairs of meta variables must be guaranteed to have
* the same number of underlying DD variables.
*
* @param metaVariablePairs A vector of meta variable pairs that are to be swapped for one another.
* @return The resulting DD.
*/
Dd<DdType::CUDD> swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs);
/*!
* Multiplies the current DD (representing a matrix) with the given matrix by summing over the given meta
* variables.
*
* @param otherMatrix The matrix with which to multiply.
* @param summationMetaVariables The names of the meta variables over which to sum during the matrix-
* matrix multiplication.
* @return A DD representing the result of the matrix-matrix multiplication.
*/
Dd<DdType::CUDD> multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<storm::expressions::Variable> const& summationMetaVariables) const;
/*!
* Computes the logical and of the current and the given DD and existentially abstracts from the given set
* of variables.
*
* @param other The second DD for the logical and.
* @param existentialVariables The variables from which to existentially abstract.
* @return A DD representing the result.
*/
Dd<DdType::CUDD> andExists(Dd<DdType::CUDD> const& other, std::set<storm::expressions::Variable> const& existentialVariables) const;
/*!
* Computes a DD that represents the function in which all assignments with a function value strictly larger
* than the given value are mapped to one and all others to zero.
*
* @param value The value used for the comparison.
* @return The resulting DD.
*/
Dd<DdType::CUDD> greater(double value) const;
/*!
* Computes a DD that represents the function in which all assignments with a function value larger or equal
* to the given value are mapped to one and all others to zero.
*
* @param value The value used for the comparison.
* @return The resulting DD.
*/
Dd<DdType::CUDD> greaterOrEqual(double value) const;
/*!
* Computes a DD that represents the function in which all assignments with a function value unequal to zero
* are mapped to one and all others to zero.
*
* @return The resulting DD.
*/
Dd<DdType::CUDD> notZero() const;
/*!
* Computes the constraint of the current DD with the given constraint. That is, the function value of the
* resulting DD will be the same as the current ones for all assignments mapping to one in the constraint
* and may be different otherwise.
*
* @param constraint The constraint to use for the operation.
* @return The resulting DD.
*/
Dd<DdType::CUDD> constrain(Dd<DdType::CUDD> const& constraint) const;
/*!
* Computes the restriction of the current DD with the given constraint. That is, the function value of the
* resulting DD will be the same as the current ones for all assignments mapping to one in the constraint
* and may be different otherwise.
*
* @param constraint The constraint to use for the operation.
* @return The resulting DD.
*/
Dd<DdType::CUDD> restrict(Dd<DdType::CUDD> const& constraint) const;
/*!
* Retrieves the support of the current DD.
*
* @return The support represented as a DD.
* @return The support represented as a BDD.
*/
Dd<DdType::CUDD> getSupport() const;
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.
*/
uint_fast64_t getNonZeroCount() const;
virtual uint_fast64_t getNonZeroCount() const = 0;
/*!
* Retrieves the number of leaves of the DD.
*
* @return The number of leaves of the DD.
*/
uint_fast64_t getLeafCount() const;
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.
*/
uint_fast64_t getNodeCount() const;
/*!
* Retrieves the lowest function value of any encoding.
*
* @return The lowest function value of any encoding.
*/
double getMin() const;
/*!
* Retrieves the highest function value of any encoding.
*
* @return The highest function value of any encoding.
*/
double getMax() const;
/*!
* Sets the function values of all encodings that have the given value of the meta variable to the given
* target value.
*
* @param metaVariable The meta variable that has to be equal to the given value.
* @param variableValue The value that the meta variable is supposed to have. This must be within the range
* of the meta variable.
* @param targetValue The new function value of the modified encodings.
*/
void setValue(storm::expressions::Variable const& metaVariable, int_fast64_t variableValue, double targetValue);
/*!
* Sets the function values of all encodings that have the given values of the two meta variables to the
* given target value.
*
* @param metaVariable1 The first meta variable that has to be equal to the first given
* value.
* @param variableValue1 The value that the first meta variable is supposed to have. This must be within the
* range of the meta variable.
* @param metaVariable2 The second meta variable that has to be equal to the second given
* value.
* @param variableValue2 The value that the second meta variable is supposed to have. This must be within
* the range of the meta variable.
* @param targetValue The new function value of the modified encodings.
*/
void setValue(storm::expressions::Variable const& metaVariable1, int_fast64_t variableValue1, storm::expressions::Variable const& metaVariable2, int_fast64_t variableValue2, double targetValue);
/*!
* Sets the function values of all encodings that have the given values of the given meta variables to the
* given target value.
*
* @param metaVariableToValueMap A mapping of meta variables to the values they are supposed to have. All
* values must be within the range of the respective meta variable.
* @param targetValue The new function value of the modified encodings.
*/
void setValue(std::map<storm::expressions::Variable, int_fast64_t> const& metaVariableToValueMap = std::map<storm::expressions::Variable, int_fast64_t>(), double targetValue = 0);
/*!
* Retrieves the value of the function when all meta variables are assigned the values of the given mapping.
* Note that the mapping must specify values for all meta variables contained in the DD.
*
* @param metaVariableToValueMap A mapping of meta variables to their values.
* @return The value of the function evaluated with the given input.
*/
double getValue(std::map<storm::expressions::Variable, int_fast64_t> const& metaVariableToValueMap = std::map<storm::expressions::Variable, int_fast64_t>()) const;
/*!
* Retrieves whether this DD represents the constant one function.
*
* @return True if this DD represents the constant one function.
*/
bool isOne() const;
/*!
* Retrieves whether this DD represents the constant zero function.
*
* @return True if this DD represents the constant zero function.
*/
bool isZero() const;
/*!
* Retrieves whether this DD represents a constant function.
*
* @return True if this DD represents a constants function.
*/
bool isConstant() const;
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.
*/
uint_fast64_t getIndex() const;
/*!
* Converts the DD to a vector.
*
* @return The double vector that is represented by this DD.
*/
template<typename ValueType>
std::vector<ValueType> toVector() const;
/*!
* Converts the DD to a vector. The given offset-labeled DD is used to determine the correct row of
* each entry.
*
* @param rowOdd The ODD used for determining the correct row.
* @return The double vector that is represented by this DD.
*/
template<typename ValueType>
std::vector<ValueType> toVector(storm::dd::Odd<DdType::CUDD> const& rowOdd) const;
/*!
* Converts the DD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
* row, whereas all primed variables are assumed to encode the column.
*
* @return The matrix that is represented by this DD.
*/
storm::storage::SparseMatrix<double> toMatrix() const;
/*!
* Converts the DD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
* row, whereas all primed variables are assumed to encode the column. The given offset-labeled DDs are used
* to determine the correct row and column, respectively, for each entry.
*
* @param rowOdd The ODD used for determining the correct row.
* @param columnOdd The ODD used for determining the correct column.
* @return The matrix that is represented by this DD.
*/
storm::storage::SparseMatrix<double> toMatrix(storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
/*!
* Converts the DD to a (sparse) double matrix. The given offset-labeled DDs are used to determine the
* correct row and column, respectively, for each entry.
*
* @param rowMetaVariables The meta variables that encode the rows of the matrix.
* @param columnMetaVariables The meta variables that encode the columns of the matrix.
* @param rowOdd The ODD used for determining the correct row.
* @param columnOdd The ODD used for determining the correct column.
* @return The matrix that is represented by this DD.
*/
storm::storage::SparseMatrix<double> toMatrix(std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
/*!
* Converts the DD to a row-grouped (sparse) double matrix. The given offset-labeled DDs are used to
* determine the correct row and column, respectively, for each entry. Note: this function assumes that
* the meta variables used to distinguish different row groups are at the very top of the DD.
*
* @param rowMetaVariables The meta variables that encode the rows of the matrix.
* @param columnMetaVariables The meta variables that encode the columns of the matrix.
* @param groupMetaVariables The meta variables that are used to distinguish different row groups.
* @param rowOdd The ODD used for determining the correct row.
* @param columnOdd The ODD used for determining the correct column.
* @return The matrix that is represented by this DD.
*/
storm::storage::SparseMatrix<double> toMatrix(std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::set<storm::expressions::Variable> const& groupMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
virtual uint_fast64_t getIndex() const = 0;
/*!
* Retrieves whether the given meta variable is contained in the DD.
@ -598,19 +91,12 @@ namespace storm {
*/
std::set<storm::expressions::Variable> const& getContainedMetaVariables() 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();
/*!
* 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.
*/
void exportToDot(std::string const& filename = "") const;
virtual void exportToDot(std::string const& filename = "") const = 0;
/*!
* Retrieves the manager that is responsible for this DD.
@ -618,224 +104,59 @@ namespace storm {
* A pointer to the manager that is responsible for this DD.
*/
std::shared_ptr<DdManager<DdType::CUDD> const> getDdManager() const;
protected:
/*!
* Retrieves an iterator that points to the first meta variable assignment with a non-zero function value.
*
* @param enumerateDontCareMetaVariables If set to true, all meta variable assignments are enumerated, even
* if a meta variable does not at all influence the the function value.
* @return An iterator that points to the first meta variable assignment with a non-zero function value.
*/
DdForwardIterator<DdType::CUDD> begin(bool enumerateDontCareMetaVariables = true) const;
/*!
* Retrieves an iterator that points past the end of the container.
*
* @param enumerateDontCareMetaVariables If set to true, all meta variable assignments are enumerated, even
* if a meta variable does not at all influence the the function value.
* @return An iterator that points past the end of the container.
*/
DdForwardIterator<DdType::CUDD> end(bool enumerateDontCareMetaVariables = true) const;
/*!
* Converts the DD into a (heavily nested) if-then-else expression that represents the very same function.
* The variable names used in the expression are derived from the meta variable name and are extended with a
* suffix ".i" if the meta variable is integer-valued, expressing that the variable is the i-th bit of the
* meta variable.
*
* @return The resulting expression.
*/
storm::expressions::Expression toExpression() const;
/*!
* Converts the DD into a (heavily nested) if-then-else (with negations) expression that evaluates to true
* if and only if the assignment is minterm of the DD. The variable names used in the expression are derived
* from the meta variable name and are extended with a suffix ".i" if the meta variable is integer-valued,
* expressing that the variable is the i-th bit of the meta variable.
*
* @return The resulting expression.
*/
storm::expressions::Expression getMintermExpression() const;
friend std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd);
/*!
* Converts an MTBDD to a BDD by mapping all values unequal to zero to 1. This effectively does the same as
* a call to notZero().
*
* @return The corresponding BDD.
*/
Dd<DdType::CUDD> toBdd() const;
/*!
* Converts a BDD to an equivalent MTBDD.
*
* @return The corresponding MTBDD.
*/
Dd<DdType::CUDD> toMtbdd() const;
/*!
* Retrieves whether this DD is a BDD.
*
* @return True iff this DD is a BDD.
*/
bool isBdd() const;
/*!
* Retrieves whether this DD is an MTBDD. Even though MTBDDs technicall subsume BDDs, this will return false
* if the DD is actually a BDD.
*
* @return True iff this DD is an MTBDD.
*/
bool isMtbdd() const;
private:
/*!
* Retrieves the CUDD BDD object associated with this DD.
*
* @return The CUDD BDD object associated with this DD.
*/
BDD getCuddBdd() const;
/*!
* Retrieves the CUDD MTBDD object associated with this DD.
*
* @return The CUDD MTBDD object associated with this DD.
*/
ADD getCuddMtbdd() const;
/*!
* Retrieves the CUDD object associated with this DD.
* Retrieves the set of all meta variables contained in the DD.
*
* @return The CUDD object associated with this DD.
* @return The set of all meta variables contained in the DD.
*/
ABDD const& getCuddDd() const;
std::set<storm::expressions::Variable>& getContainedMetaVariables();
/*!
* Retrieves the raw DD node of CUDD associated with this DD.
* Adds the given set of meta variables to the DD.
*
* @return The DD node of CUDD associated with this DD.
* @param metaVariables The set of meta variables to add.
*/
DdNode* getCuddDdNode() const;
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 addContainedMetaVariable(storm::expressions::Variable const& metaVariable);
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 removeContainedMetaVariable(storm::expressions::Variable const& metaVariable);
void removeMetaVariable(storm::expressions::Variable const& metaVariable);
/*!
* Performs the recursive step of toExpression on the given DD.
* Removes the given set of meta variables from the DD.
*
* @param dd The dd to translate into an expression.
* @param variables The variables to use in the expression.
* @return The resulting expression.
* @param metaVariables The set of meta variables to remove.
*/
static storm::expressions::Expression toExpressionRecur(DdNode const* dd, std::vector<storm::expressions::Variable> const& variables);
void removeMetaVariables(std::set<storm::expressions::Variable> const& metaVariables);
/*!
* Performs the recursive step of getMintermExpression on the given DD.
*
* @param manager The manager of the DD.
* @param dd The dd whose minterms to translate into an expression.
* @param variables The variables to use in the expression.
* @return The resulting expression.
*/
static storm::expressions::Expression getMintermExpressionRecur(::DdManager* manager, DdNode const* dd, std::vector<storm::expressions::Variable> const& variables);
protected:
/*!
* Creates a DD that encapsulates the given CUDD ADD.
*
* @param ddManager The manager responsible for this DD.
* @param cuddDd The CUDD ADD to store.
* @param containedMetaVariables The meta variables that appear in the DD.
*/
Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, ADD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
/*!
* Creates a DD that encapsulates the given CUDD ADD.
* Creates a DD with the given manager and meta variables.
*
* @param ddManager The manager responsible for this DD.
* @param cuddDd The CUDD ADD to store.
* @param containedMetaVariables The meta variables that appear in the DD.
*/
Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
/*!
* Helper function to convert the DD into a (sparse) matrix.
*
* @param dd The DD to convert.
* @param rowIndications A vector indicating at which position in the columnsAndValues vector the entries
* of row i start. Note: this vector is modified in the computation. More concretely, each entry i in the
* vector will be increased by the number of entries in the row. This can be used to count the number
* of entries in each row. If the values are not to be modified, a copy needs to be provided or the entries
* need to be restored afterwards.
* @param columnsAndValues The vector that will hold the columns and values of non-zero entries upon successful
* completion.
* @param rowGroupOffsets The row offsets at which a given row group starts.
* @param rowOdd The ODD used for the row translation.
* @param columnOdd The ODD used for the column translation.
* @param currentRowLevel The currently considered row level in the DD.
* @param currentColumnLevel The currently considered row level in the DD.
* @param maxLevel The number of levels that need to be considered.
* @param currentRowOffset The current row offset.
* @param currentColumnOffset The current row offset.
* @param ddRowVariableIndices The (sorted) indices of all DD row variables that need to be considered.
* @param ddColumnVariableIndices The (sorted) indices of all DD row variables that need to be considered.
* @param generateValues If set to true, the vector columnsAndValues is filled with the actual entries, which
* only works if the offsets given in rowIndications are already correct. If they need to be computed first,
* this flag needs to be false.
*/
void toMatrixRec(DdNode const* dd, std::vector<uint_fast64_t>& rowIndications, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>>& columnsAndValues, std::vector<uint_fast64_t> const& rowGroupOffsets, Odd<DdType::CUDD> const& rowOdd, Odd<DdType::CUDD> const& columnOdd, uint_fast64_t currentRowLevel, uint_fast64_t currentColumnLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset, uint_fast64_t currentColumnOffset, std::vector<uint_fast64_t> const& ddRowVariableIndices, std::vector<uint_fast64_t> const& ddColumnVariableIndices, bool generateValues = true) const;
/*!
* Splits the given matrix DD into the groups using the given group variables.
*
* @param dd The DD to split.
* @param groups A vector that is to be filled with the DDs for the individual groups.
* @param ddGroupVariableIndices The (sorted) indices of all DD group variables that need to be considered.
* @param currentLevel The currently considered level in the DD.
* @param maxLevel The number of levels that need to be considered.
* @param remainingMetaVariables The meta variables that remain in the DDs after the groups have been split.
*/
void splitGroupsRec(DdNode* dd, std::vector<Dd<DdType::CUDD>>& groups, std::vector<uint_fast64_t> const& ddGroupVariableIndices, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::set<storm::expressions::Variable> const& remainingMetaVariables) const;
Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
/*!
* Performs a recursive step to add the given DD-based vector to the given explicit vector.
*
* @param dd The DD to add to the explicit vector.
* @param currentLevel The currently considered level in the DD.
* @param maxLevel The number of levels that need to be considered.
* @param currentOffset The current offset.
* @param odd The ODD used for the translation.
* @param ddVariableIndices The (sorted) indices of all DD variables that need to be considered.
* @param targetVector The vector to which the translated DD-based vector is to be added.
*/
template<typename ValueType>
void addToVectorRec(DdNode const* dd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, Odd<DdType::CUDD> const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<ValueType>& targetVector) const;
/*!
* Retrieves the indices of all DD variables that are contained in this DD (not necessarily in the support,
* because they could be "don't cares"). Additionally, the indices are sorted to allow for easy access.
*
* @return The (sorted) indices of all DD variables that are contained in this DD.
*/
std::vector<uint_fast64_t> getSortedVariableIndices() const;
private:
// A pointer to the manager responsible for this DD.
std::shared_ptr<DdManager<DdType::CUDD> const> ddManager;
// The ADD created by CUDD.
boost::variant<BDD, ADD> cuddDd;
// The meta variables that appear in this DD.
std::set<storm::expressions::Variable> containedMetaVariables;
};

Loading…
Cancel
Save