You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
10 KiB
212 lines
10 KiB
#ifndef STORM_STORAGE_DD_CUDDODD_H_
|
|
#define STORM_STORAGE_DD_CUDDODD_H_
|
|
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
|
|
#include "src/storage/dd/Odd.h"
|
|
#include "src/storage/dd/CuddAdd.h"
|
|
#include "src/utility/OsDetection.h"
|
|
|
|
// Include the C++-interface of CUDD.
|
|
#include "cuddObj.hh"
|
|
|
|
namespace storm {
|
|
namespace dd {
|
|
template<>
|
|
class Odd<DdType::CUDD> {
|
|
public:
|
|
/*!
|
|
* Constructs an offset-labeled DD from the given ADD.
|
|
*
|
|
* @param add The ADD for which to build the offset-labeled ADD.
|
|
*/
|
|
Odd(Add<DdType::CUDD> const& add);
|
|
|
|
/*!
|
|
* Constructs an offset-labeled DD from the given BDD.
|
|
*
|
|
* @param bdd The BDD for which to build the offset-labeled ADD.
|
|
*/
|
|
Odd(Bdd<DdType::CUDD> const& bdd);
|
|
|
|
// Instantiate all copy/move constructors/assignments with the default implementation.
|
|
Odd() = default;
|
|
Odd(Odd<DdType::CUDD> const& other) = default;
|
|
Odd& operator=(Odd<DdType::CUDD> const& other) = default;
|
|
#ifndef WINDOWS
|
|
Odd(Odd<DdType::CUDD>&& other) = default;
|
|
Odd& operator=(Odd<DdType::CUDD>&& other) = default;
|
|
#endif
|
|
|
|
/*!
|
|
* Retrieves the then-successor of this ODD node.
|
|
*
|
|
* @return The then-successor of this ODD node.
|
|
*/
|
|
Odd<DdType::CUDD> const& getThenSuccessor() const;
|
|
|
|
/*!
|
|
* Retrieves the else-successor of this ODD node.
|
|
*
|
|
* @return The else-successor of this ODD node.
|
|
*/
|
|
Odd<DdType::CUDD> const& getElseSuccessor() const;
|
|
|
|
/*!
|
|
* Retrieves the else-offset of this ODD node.
|
|
*
|
|
* @return The else-offset of this ODD node.
|
|
*/
|
|
uint_fast64_t getElseOffset() const;
|
|
|
|
/*!
|
|
* Sets the else-offset of this ODD node.
|
|
*
|
|
* @param newOffset The new else-offset of this ODD node.
|
|
*/
|
|
void setElseOffset(uint_fast64_t newOffset);
|
|
|
|
/*!
|
|
* Retrieves the then-offset of this ODD node.
|
|
*
|
|
* @return The then-offset of this ODD node.
|
|
*/
|
|
uint_fast64_t getThenOffset() const;
|
|
|
|
/*!
|
|
* Sets the then-offset of this ODD node.
|
|
*
|
|
* @param newOffset The new then-offset of this ODD node.
|
|
*/
|
|
void setThenOffset(uint_fast64_t newOffset);
|
|
|
|
/*!
|
|
* Retrieves the total offset, i.e., the sum of the then- and else-offset.
|
|
*
|
|
* @return The total offset of this ODD.
|
|
*/
|
|
uint_fast64_t getTotalOffset() const;
|
|
|
|
/*!
|
|
* Retrieves the size of the ODD. Note: the size is computed by a traversal, so this may be costlier than
|
|
* expected.
|
|
*
|
|
* @return The size (in nodes) of this ODD.
|
|
*/
|
|
uint_fast64_t getNodeCount() const;
|
|
|
|
/*!
|
|
* Checks whether the given ODD node is a terminal node, i.e. has no successors.
|
|
*
|
|
* @return True iff the node is terminal.
|
|
*/
|
|
bool isTerminalNode() const;
|
|
|
|
/*!
|
|
* Filters the given explicit vector using the symbolic representation of which values to select.
|
|
*
|
|
* @param selectedValues A symbolic representation of which values to select.
|
|
* @param values The value vector from which to select the values.
|
|
* @return The resulting vector.
|
|
*/
|
|
std::vector<double> filterExplicitVector(storm::dd::Bdd<DdType::CUDD> const& selectedValues, std::vector<double> const& values) const;
|
|
|
|
/*!
|
|
* Adds the old values to the new values. It does so by writing the old values at their correct positions
|
|
* wrt. to the new ODD.
|
|
*
|
|
* @param newOdd The new ODD to use.
|
|
* @param oldValues The old vector of values (which is being read).
|
|
* @param newValues The new vector of values (which is being written).
|
|
*/
|
|
void expandExplicitVector(storm::dd::Odd<DdType::CUDD> const& newOdd, std::vector<double> const& oldValues, std::vector<double>& newValues) const;
|
|
|
|
private:
|
|
// Declare a hash functor that is used for the unique tables in the construction process.
|
|
class HashFunctor {
|
|
public:
|
|
std::size_t operator()(std::pair<DdNode*, bool> const& key) const;
|
|
};
|
|
|
|
/*!
|
|
* Constructs an offset-labeled DD with the given topmost DD node, else- and then-successor.
|
|
*
|
|
* @param dd The DD node associated with this ODD node.
|
|
* @param elseNode The else-successor of thie ODD node.
|
|
* @param elseOffset The offset of the else-successor.
|
|
* @param thenNode The then-successor of thie ODD node.
|
|
* @param thenOffset The offset of the then-successor.
|
|
*/
|
|
Odd(std::shared_ptr<Odd<DdType::CUDD>> elseNode, uint_fast64_t elseOffset, std::shared_ptr<Odd<DdType::CUDD>> thenNode, uint_fast64_t thenOffset);
|
|
|
|
/*!
|
|
* Recursively builds the ODD from an ADD (that has no complement edges).
|
|
*
|
|
* @param dd The DD for which to build the ODD.
|
|
* @param manager The manager responsible for the DD.
|
|
* @param currentLevel The currently considered level in the DD.
|
|
* @param maxLevel The number of levels that need to be considered.
|
|
* @param ddVariableIndices The (sorted) indices of all DD variables that need to be considered.
|
|
* @param uniqueTableForLevels A vector of unique tables, one for each level to be considered, that keeps
|
|
* ODD nodes for the same DD and level unique.
|
|
* @return A pointer to the constructed ODD for the given arguments.
|
|
*/
|
|
static std::shared_ptr<Odd<DdType::CUDD>> buildOddFromAddRec(DdNode* dd, Cudd const& manager, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<std::unordered_map<DdNode*, std::shared_ptr<Odd<DdType::CUDD>>>>& uniqueTableForLevels);
|
|
|
|
/*!
|
|
* Recursively builds the ODD from a BDD (that potentially has complement edges).
|
|
*
|
|
* @param dd The DD for which to build the ODD.
|
|
* @param manager The manager responsible for the DD.
|
|
* @param currentLevel The currently considered level in the DD.
|
|
* @param complement A flag indicating whether or not the given node is to be considered as complemented.
|
|
* @param maxLevel The number of levels that need to be considered.
|
|
* @param ddVariableIndices The (sorted) indices of all DD variables that need to be considered.
|
|
* @param uniqueTableForLevels A vector of unique tables, one for each level to be considered, that keeps
|
|
* ODD nodes for the same DD and level unique.
|
|
* @return A pointer to the constructed ODD for the given arguments.
|
|
*/
|
|
static std::shared_ptr<Odd<DdType::CUDD>> buildOddFromBddRec(DdNode* dd, Cudd const& manager, uint_fast64_t currentLevel, bool complement, uint_fast64_t maxLevel, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<std::unordered_map<std::pair<DdNode*, bool>, std::shared_ptr<Odd<DdType::CUDD>>, HashFunctor>>& uniqueTableForLevels);
|
|
|
|
/*!
|
|
* Adds the selected values the target vector.
|
|
*
|
|
* @param dd The current node of the DD representing the selected values.
|
|
* @param manager The manager responsible for the DD.
|
|
* @param currentLevel The currently considered level in the DD.
|
|
* @param maxLevel The number of levels that need to be considered.
|
|
* @param ddVariableIndices The sorted list of variable indices to use.
|
|
* @param currentOffset The offset along the path taken in the DD representing the selected values.
|
|
* @param odd The current ODD node.
|
|
* @param result The target vector to which to write the values.
|
|
* @param currentIndex The index at which the next element is to be written.
|
|
* @param values The value vector from which to select the values.
|
|
*/
|
|
static void addSelectedValuesToVectorRec(DdNode* dd, Cudd const& manager, uint_fast64_t currentLevel, bool complement, uint_fast64_t maxLevel, std::vector<uint_fast64_t> const& ddVariableIndices, uint_fast64_t currentOffset, storm::dd::Odd<DdType::CUDD> const& odd, std::vector<double>& result, uint_fast64_t& currentIndex, std::vector<double> const& values);
|
|
|
|
/*!
|
|
* Adds the values of the old explicit values to the new explicit values where the positions in the old vector
|
|
* are given by the current old ODD and the positions in the new vector are given by the new ODD.
|
|
*
|
|
* @param oldOffset The offset in the old explicit values.
|
|
* @param oldOdd The ODD to use for the old explicit values.
|
|
* @param oldValues The vector of old values.
|
|
* @param newOffset The offset in the new explicit values.
|
|
* @param newOdd The ODD to use for the new explicit values.
|
|
* @param newValues The vector of new values.
|
|
*/
|
|
static void expandValuesToVectorRec(uint_fast64_t oldOffset, storm::dd::Odd<DdType::CUDD> const& oldOdd, std::vector<double> const& oldValues, uint_fast64_t newOffset, storm::dd::Odd<DdType::CUDD> const& newOdd, std::vector<double>& newValues);
|
|
|
|
// The then- and else-nodes.
|
|
std::shared_ptr<Odd<DdType::CUDD>> elseNode;
|
|
std::shared_ptr<Odd<DdType::CUDD>> thenNode;
|
|
|
|
// The offsets that need to be added if the then- or else-successor is taken, respectively.
|
|
uint_fast64_t elseOffset;
|
|
uint_fast64_t thenOffset;
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif /* STORM_STORAGE_DD_CUDDODD_H_ */
|