3#include <boost/functional/hash.hpp>
17InternalBdd<DdType::CUDD>::InternalBdd(InternalDdManager<DdType::CUDD>
const* ddManager, cudd::BDD cuddBdd) : ddManager(ddManager), cuddBdd(cuddBdd) {
21InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::fromVector(InternalDdManager<DdType::CUDD>
const* ddManager, Odd
const& odd,
22 std::vector<uint_fast64_t>
const& sortedDdVariableIndices,
23 std::function<
bool(uint64_t)>
const& filter) {
24 uint_fast64_t offset = 0;
25 return InternalBdd<DdType::CUDD>(
26 ddManager, cudd::BDD(ddManager->getCuddManager(), fromVectorRec(ddManager->getCuddManager().getManager(), offset, 0, sortedDdVariableIndices.size(),
27 odd, sortedDdVariableIndices, filter)));
30bool InternalBdd<DdType::CUDD>::operator==(InternalBdd<DdType::CUDD>
const& other)
const {
31 return this->getCuddBdd() == other.getCuddBdd();
34bool InternalBdd<DdType::CUDD>::operator!=(InternalBdd<DdType::CUDD>
const& other)
const {
35 return !(*
this == other);
38InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::relationalProduct(InternalBdd<DdType::CUDD>
const& relation,
39 std::vector<InternalBdd<DdType::CUDD>>
const& rowVariables,
40 std::vector<InternalBdd<DdType::CUDD>>
const& columnVariables)
const {
41 InternalBdd<DdType::CUDD> cube = ddManager->getBddOne();
42 for (
auto const& variable : rowVariables) {
46 InternalBdd<DdType::CUDD> result = this->andExists(relation, cube);
47 result = result.swapVariables(rowVariables, columnVariables);
51InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::inverseRelationalProduct(InternalBdd<DdType::CUDD>
const& relation,
52 std::vector<InternalBdd<DdType::CUDD>>
const& rowVariables,
53 std::vector<InternalBdd<DdType::CUDD>>
const& columnVariables)
const {
54 InternalBdd<DdType::CUDD> cube = ddManager->getBddOne();
55 for (
auto const& variable : columnVariables) {
59 InternalBdd<DdType::CUDD> result = this->swapVariables(rowVariables, columnVariables).andExists(relation, cube);
63InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::inverseRelationalProductWithExtendedRelation(
64 InternalBdd<DdType::CUDD>
const& relation, std::vector<InternalBdd<DdType::CUDD>>
const& rowVariables,
65 std::vector<InternalBdd<DdType::CUDD>>
const& columnVariables)
const {
66 return this->inverseRelationalProduct(relation, rowVariables, columnVariables);
69InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::ite(InternalBdd<DdType::CUDD>
const& thenDd, InternalBdd<DdType::CUDD>
const& elseDd)
const {
70 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().
Ite(thenDd.getCuddBdd(), elseDd.getCuddBdd()));
73template<
typename ValueType>
74InternalAdd<DdType::CUDD, ValueType> InternalBdd<DdType::CUDD>::ite(InternalAdd<DdType::CUDD, ValueType>
const& thenAdd,
75 InternalAdd<DdType::CUDD, ValueType>
const& elseAdd)
const {
76 return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddBdd().Add().
Ite(thenAdd.getCuddAdd(), elseAdd.getCuddAdd()));
79InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::operator||(InternalBdd<DdType::CUDD>
const& other)
const {
80 InternalBdd<DdType::CUDD> result(*
this);
85InternalBdd<DdType::CUDD>& InternalBdd<DdType::CUDD>::operator|=(InternalBdd<DdType::CUDD>
const& other) {
86 this->cuddBdd = this->getCuddBdd() | other.getCuddBdd();
90InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::operator&&(InternalBdd<DdType::CUDD>
const& other)
const {
91 InternalBdd<DdType::CUDD> result(*
this);
96InternalBdd<DdType::CUDD>& InternalBdd<DdType::CUDD>::operator&=(InternalBdd<DdType::CUDD>
const& other) {
97 this->cuddBdd = this->getCuddBdd() & other.getCuddBdd();
101InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::iff(InternalBdd<DdType::CUDD>
const& other)
const {
102 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().Xnor(other.getCuddBdd()));
105InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::exclusiveOr(InternalBdd<DdType::CUDD>
const& other)
const {
106 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().
Xor(other.getCuddBdd()));
109InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::implies(InternalBdd<DdType::CUDD>
const& other)
const {
110 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().
Ite(other.getCuddBdd(), ddManager->getBddOne().getCuddBdd()));
113InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::operator!()
const {
114 InternalBdd<DdType::CUDD> result(*
this);
119InternalBdd<DdType::CUDD>& InternalBdd<DdType::CUDD>::complement() {
120 this->cuddBdd = ~this->getCuddBdd();
124InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::existsAbstract(InternalBdd<DdType::CUDD>
const& cube)
const {
125 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().ExistAbstract(cube.getCuddBdd()));
128InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::existsAbstractRepresentative(InternalBdd<DdType::CUDD>
const& cube)
const {
129 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().ExistAbstractRepresentative(cube.getCuddBdd()));
132InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::universalAbstract(InternalBdd<DdType::CUDD>
const& cube)
const {
133 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().UnivAbstract(cube.getCuddBdd()));
136InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::andExists(InternalBdd<DdType::CUDD>
const& other, InternalBdd<DdType::CUDD>
const& cube)
const {
137 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().AndAbstract(other.getCuddBdd(), cube.getCuddBdd()));
140InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::constrain(InternalBdd<DdType::CUDD>
const& constraint)
const {
141 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().Constrain(constraint.getCuddBdd()));
144InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::restrict(InternalBdd<DdType::CUDD>
const& constraint)
const {
145 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().Restrict(constraint.getCuddBdd()));
148InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::swapVariables(std::vector<InternalBdd<DdType::CUDD>>
const& from,
149 std::vector<InternalBdd<DdType::CUDD>>
const& to)
const {
150 std::vector<cudd::BDD> fromBdd;
151 std::vector<cudd::BDD> toBdd;
152 for (
auto it1 = from.begin(), ite1 = from.end(), it2 = to.begin(); it1 != ite1; ++it1, ++it2) {
153 fromBdd.push_back(it1->getCuddBdd());
154 toBdd.push_back(it2->getCuddBdd());
156 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().SwapVariables(fromBdd, toBdd));
159InternalBdd<DdType::CUDD> InternalBdd<DdType::CUDD>::getSupport()
const {
160 return InternalBdd<DdType::CUDD>(ddManager, this->getCuddBdd().Support());
163uint_fast64_t InternalBdd<DdType::CUDD>::getNonZeroCount(uint_fast64_t numberOfDdVariables)
const {
166 if (numberOfDdVariables == 0) {
169 return static_cast<uint_fast64_t
>(this->getCuddBdd().CountMinterm(
static_cast<int>(numberOfDdVariables)));
172uint_fast64_t InternalBdd<DdType::CUDD>::getLeafCount()
const {
173 return static_cast<uint_fast64_t
>(this->getCuddBdd().CountLeaves());
176uint_fast64_t InternalBdd<DdType::CUDD>::getNodeCount()
const {
177 return static_cast<uint_fast64_t
>(this->getCuddBdd().nodeCount());
180bool InternalBdd<DdType::CUDD>::isOne()
const {
181 return this->getCuddBdd().IsOne();
184bool InternalBdd<DdType::CUDD>::isZero()
const {
185 return this->getCuddBdd().IsZero();
188uint_fast64_t InternalBdd<DdType::CUDD>::getIndex()
const {
189 return static_cast<uint_fast64_t
>(this->getCuddBdd().NodeReadIndex());
192uint_fast64_t InternalBdd<DdType::CUDD>::getLevel()
const {
193 return static_cast<uint_fast64_t
>(ddManager->getCuddManager().ReadPerm(this->getIndex()));
196void InternalBdd<DdType::CUDD>::exportToDot(std::string
const& filename, std::vector<std::string>
const& ddVariableNamesAsStrings,
197 bool showVariablesIfPossible)
const {
199 std::vector<char*> ddNames;
200 std::string ddName(
"f");
201 ddNames.push_back(
new char[ddName.size() + 1]);
202 std::copy(ddName.c_str(), ddName.c_str() + 2, ddNames.back());
205 std::vector<char*> ddVariableNames;
206 for (
auto const& element : ddVariableNamesAsStrings) {
207 ddVariableNames.push_back(
new char[element.size() + 1]);
208 std::copy(element.c_str(), element.c_str() + element.size() + 1, ddVariableNames.back());
212 std::vector<cudd::BDD> cuddBddVector = {this->getCuddBdd()};
213 FILE* filePointer = fopen(filename.c_str(),
"a+");
214 if (showVariablesIfPossible) {
215 ddManager->getCuddManager().DumpDot(cuddBddVector, ddVariableNames.data(), &ddNames[0], filePointer);
217 ddManager->getCuddManager().DumpDot(cuddBddVector,
nullptr, &ddNames[0], filePointer);
222 for (
char* element : ddNames) {
225 for (
char* element : ddVariableNames) {
230void InternalBdd<DdType::CUDD>::exportToText(std::string
const&)
const {
231 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Operation not supported");
234cudd::BDD InternalBdd<DdType::CUDD>::getCuddBdd()
const {
235 return this->cuddBdd;
238DdNode* InternalBdd<DdType::CUDD>::getCuddDdNode()
const {
239 return this->getCuddBdd().getNode();
242template<
typename ValueType>
243InternalAdd<DdType::CUDD, ValueType> InternalBdd<DdType::CUDD>::toAdd()
const {
244 return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddBdd().Add());
247DdNode* InternalBdd<DdType::CUDD>::fromVectorRec(::DdManager* manager, uint_fast64_t& currentOffset, uint_fast64_t currentLevel, uint_fast64_t maxLevel,
248 Odd
const& odd, std::vector<uint_fast64_t>
const& ddVariableIndices,
249 std::function<
bool(uint64_t)>
const& filter) {
250 if (currentLevel == maxLevel) {
254 if (odd.getThenOffset() > 0) {
255 if (
filter(currentOffset++)) {
256 return Cudd_ReadOne(manager);
258 return Cudd_ReadLogicZero(manager);
261 return Cudd_ReadZero(manager);
265 if (odd.getThenOffset() + odd.getElseOffset() == 0) {
266 return Cudd_ReadZero(manager);
270 DdNode* elseSuccessor =
nullptr;
271 if (odd.getElseOffset() > 0) {
272 elseSuccessor = fromVectorRec(manager, currentOffset, currentLevel + 1, maxLevel, odd.getElseSuccessor(), ddVariableIndices, filter);
274 elseSuccessor = Cudd_ReadLogicZero(manager);
276 Cudd_Ref(elseSuccessor);
279 DdNode* thenSuccessor =
nullptr;
280 if (odd.getThenOffset() > 0) {
281 thenSuccessor = fromVectorRec(manager, currentOffset, currentLevel + 1, maxLevel, odd.getThenSuccessor(), ddVariableIndices, filter);
283 thenSuccessor = Cudd_ReadLogicZero(manager);
285 Cudd_Ref(thenSuccessor);
288 DdNode* currentVar = Cudd_bddIthVar(manager,
static_cast<int>(ddVariableIndices[currentLevel]));
289 Cudd_Ref(currentVar);
290 DdNode* result = Cudd_bddIte(manager, currentVar, thenSuccessor, elseSuccessor);
294 Cudd_RecursiveDeref(manager, currentVar);
295 Cudd_RecursiveDeref(manager, thenSuccessor);
296 Cudd_RecursiveDeref(manager, elseSuccessor);
307 this->toVectorRec(Cudd_Regular(this->getCuddDdNode()), ddManager->getCuddManager(), result, rowOdd, Cudd_IsComplement(this->getCuddDdNode()), 0,
308 ddVariableIndices.size(), 0, ddVariableIndices);
312void InternalBdd<DdType::CUDD>::toVectorRec(DdNode
const* dd, cudd::Cudd
const& manager,
storm::storage::BitVector& result, Odd
const& rowOdd,
bool complement,
313 uint_fast64_t currentRowLevel, uint_fast64_t maxLevel, uint_fast64_t currentRowOffset,
314 std::vector<uint_fast64_t>
const& ddRowVariableIndices)
const {
316 if (dd == Cudd_ReadLogicZero(
manager.getManager()) && !complement) {
318 }
else if (dd == Cudd_ReadOne(
manager.getManager()) && complement) {
323 if (currentRowLevel == maxLevel) {
324 result.
set(currentRowOffset,
true);
325 }
else if (ddRowVariableIndices[currentRowLevel] < Cudd_NodeReadIndex(dd)) {
326 toVectorRec(dd, manager, result, rowOdd.getElseSuccessor(), complement, currentRowLevel + 1, maxLevel, currentRowOffset, ddRowVariableIndices);
327 toVectorRec(dd, manager, result, rowOdd.getThenSuccessor(), complement, currentRowLevel + 1, maxLevel, currentRowOffset + rowOdd.getElseOffset(),
328 ddRowVariableIndices);
331 DdNode
const* elseDdNode = Cudd_E_const(dd);
332 DdNode
const* thenDdNode = Cudd_T_const(dd);
335 bool elseComplemented = Cudd_IsComplement(elseDdNode) ^ complement;
336 bool thenComplemented = Cudd_IsComplement(thenDdNode) ^ complement;
338 toVectorRec(Cudd_Regular(elseDdNode), manager, result, rowOdd.getElseSuccessor(), elseComplemented, currentRowLevel + 1, maxLevel, currentRowOffset,
339 ddRowVariableIndices);
340 toVectorRec(Cudd_Regular(thenDdNode), manager, result, rowOdd.getThenSuccessor(), thenComplemented, currentRowLevel + 1, maxLevel,
341 currentRowOffset + rowOdd.getElseOffset(), ddRowVariableIndices);
345Odd InternalBdd<DdType::CUDD>::createOdd(std::vector<uint_fast64_t>
const& ddVariableIndices)
const {
347 std::vector<std::unordered_map<DdNode const*, std::shared_ptr<Odd>>> uniqueTableForLevels(ddVariableIndices.size() + 1);
350 std::shared_ptr<Odd> rootOdd =
351 createOddRec(this->getCuddDdNode(), ddManager->getCuddManager(), 0, ddVariableIndices.size(), ddVariableIndices, uniqueTableForLevels);
354 return Odd(*rootOdd);
357std::size_t InternalBdd<DdType::CUDD>::HashFunctor::operator()(std::pair<DdNode const*, bool>
const& key)
const {
358 std::size_t result = 0;
359 boost::hash_combine(result, key.first);
360 boost::hash_combine(result, key.second);
364std::shared_ptr<Odd> InternalBdd<DdType::CUDD>::createOddRec(DdNode
const* dd, cudd::Cudd
const& manager, uint_fast64_t currentLevel, uint_fast64_t maxLevel,
365 std::vector<uint_fast64_t>
const& ddVariableIndices,
366 std::vector<std::unordered_map<DdNode
const*, std::shared_ptr<Odd>>>& uniqueTableForLevels) {
368 auto it = uniqueTableForLevels[currentLevel].find(dd);
369 if (it != uniqueTableForLevels[currentLevel].end()) {
376 if (currentLevel == maxLevel) {
377 auto oddNode = std::make_shared<Odd>(
nullptr, 0,
nullptr, dd != Cudd_ReadLogicZero(
manager.getManager()) ? 1 : 0);
378 uniqueTableForLevels[currentLevel].emplace(dd, oddNode);
380 }
else if (ddVariableIndices[currentLevel] < Cudd_NodeReadIndex(dd)) {
383 std::shared_ptr<Odd> elseNode = createOddRec(dd, manager, currentLevel + 1, maxLevel, ddVariableIndices, uniqueTableForLevels);
384 std::shared_ptr<Odd> thenNode = elseNode;
386 auto oddNode = std::make_shared<Odd>(elseNode, elseNode->getTotalOffset(), thenNode, elseNode->getTotalOffset());
387 uniqueTableForLevels[currentLevel].emplace(dd, oddNode);
391 DdNode
const* thenDdNode = Cudd_T_const(dd);
392 DdNode
const* elseDdNode = Cudd_E_const(dd);
394 if (Cudd_IsComplement(dd)) {
395 thenDdNode = Cudd_Not(thenDdNode);
396 elseDdNode = Cudd_Not(elseDdNode);
399 std::shared_ptr<Odd> elseNode = createOddRec(elseDdNode, manager, currentLevel + 1, maxLevel, ddVariableIndices, uniqueTableForLevels);
400 std::shared_ptr<Odd> thenNode = createOddRec(thenDdNode, manager, currentLevel + 1, maxLevel, ddVariableIndices, uniqueTableForLevels);
402 auto oddNode = std::make_shared<Odd>(elseNode, elseNode->getTotalOffset(), thenNode, thenNode->getTotalOffset());
403 uniqueTableForLevels[currentLevel].emplace(dd, oddNode);
409template<
typename ValueType>
410void InternalBdd<DdType::CUDD>::filterExplicitVector(Odd
const& odd, std::vector<uint_fast64_t>
const& ddVariableIndices,
411 std::vector<ValueType>
const& sourceValues, std::vector<ValueType>& targetValues)
const {
412 uint_fast64_t currentIndex = 0;
413 filterExplicitVectorRec(Cudd_Regular(this->getCuddDdNode()), ddManager->getCuddManager(), 0, Cudd_IsComplement(this->getCuddDdNode()),
414 ddVariableIndices.size(), ddVariableIndices, 0, odd, targetValues, currentIndex, sourceValues);
417template<
typename ValueType>
418void InternalBdd<DdType::CUDD>::filterExplicitVectorRec(DdNode
const* dd, cudd::Cudd
const& manager, uint_fast64_t currentLevel,
bool complement,
419 uint_fast64_t maxLevel, std::vector<uint_fast64_t>
const& ddVariableIndices,
420 uint_fast64_t currentOffset,
storm::dd::Odd const& odd, std::vector<ValueType>& result,
421 uint_fast64_t& currentIndex, std::vector<ValueType>
const& values) {
423 if (dd == Cudd_ReadLogicZero(
manager.getManager()) && !complement) {
425 }
else if (dd == Cudd_ReadOne(
manager.getManager()) && complement) {
429 if (currentLevel == maxLevel) {
430 result[currentIndex++] = values[currentOffset];
431 }
else if (ddVariableIndices[currentLevel] < Cudd_NodeReadIndex(dd)) {
434 filterExplicitVectorRec(dd, manager, currentLevel + 1, complement, maxLevel, ddVariableIndices, currentOffset, odd.
getElseSuccessor(), result,
435 currentIndex, values);
436 filterExplicitVectorRec(dd, manager, currentLevel + 1, complement, maxLevel, ddVariableIndices, currentOffset + odd.
getElseOffset(),
440 DdNode
const* thenDdNode = Cudd_T_const(dd);
441 DdNode
const* elseDdNode = Cudd_E_const(dd);
444 bool elseComplemented = Cudd_IsComplement(elseDdNode) ^ complement;
445 bool thenComplemented = Cudd_IsComplement(thenDdNode) ^ complement;
447 filterExplicitVectorRec(Cudd_Regular(elseDdNode), manager, currentLevel + 1, elseComplemented, maxLevel, ddVariableIndices, currentOffset,
449 filterExplicitVectorRec(Cudd_Regular(thenDdNode), manager, currentLevel + 1, thenComplemented, maxLevel, ddVariableIndices,
454std::vector<InternalBdd<DdType::CUDD>> InternalBdd<DdType::CUDD>::splitIntoGroups(std::vector<uint_fast64_t>
const& ddGroupVariableIndices)
const {
455 std::vector<InternalBdd<DdType::CUDD>> result;
456 splitIntoGroupsRec(Cudd_Regular(this->getCuddDdNode()), Cudd_IsComplement(this->getCuddDdNode()), result, ddGroupVariableIndices, 0,
457 ddGroupVariableIndices.size());
461void InternalBdd<DdType::CUDD>::splitIntoGroupsRec(DdNode* dd,
bool negated, std::vector<InternalBdd<DdType::CUDD>>& groups,
462 std::vector<uint_fast64_t>
const& ddGroupVariableIndices, uint_fast64_t currentLevel,
463 uint_fast64_t maxLevel)
const {
465 if (negated && dd == Cudd_ReadOne(ddManager->getCuddManager().getManager())) {
469 if (currentLevel == maxLevel) {
470 groups.push_back(InternalBdd<DdType::CUDD>(ddManager, cudd::BDD(ddManager->getCuddManager(), negated ? Cudd_Complement(dd) : dd)));
471 }
else if (ddGroupVariableIndices[currentLevel] < Cudd_NodeReadIndex(dd)) {
472 splitIntoGroupsRec(dd, negated, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
473 splitIntoGroupsRec(dd, negated, groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
475 DdNode* elseNode = Cudd_E(dd);
476 DdNode* thenNode = Cudd_T(dd);
478 splitIntoGroupsRec(elseNode, negated ^ Cudd_IsComplement(elseNode), groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
479 splitIntoGroupsRec(thenNode, negated ^ Cudd_IsComplement(thenNode), groups, ddGroupVariableIndices, currentLevel + 1, maxLevel);
483void InternalBdd<DdType::CUDD>::filterExplicitVector(Odd
const& odd, std::vector<uint_fast64_t>
const& ddVariableIndices,
485 uint_fast64_t currentIndex = 0;
486 filterExplicitVectorRec(Cudd_Regular(this->getCuddDdNode()), ddManager->getCuddManager(), 0, Cudd_IsComplement(this->getCuddDdNode()),
487 ddVariableIndices.size(), ddVariableIndices, 0, odd, targetValues, currentIndex, sourceValues);
490void InternalBdd<DdType::CUDD>::filterExplicitVectorRec(DdNode
const* dd, cudd::Cudd
const& manager, uint_fast64_t currentLevel,
bool complement,
491 uint_fast64_t maxLevel, std::vector<uint_fast64_t>
const& ddVariableIndices,
495 if (dd == Cudd_ReadLogicZero(
manager.getManager()) && !complement) {
497 }
else if (dd == Cudd_ReadOne(
manager.getManager()) && complement) {
501 if (currentLevel == maxLevel) {
502 result.
set(currentIndex++, values.
get(currentOffset));
503 }
else if (ddVariableIndices[currentLevel] < Cudd_NodeReadIndex(dd)) {
506 filterExplicitVectorRec(dd, manager, currentLevel + 1, complement, maxLevel, ddVariableIndices, currentOffset, odd.
getElseSuccessor(), result,
507 currentIndex, values);
508 filterExplicitVectorRec(dd, manager, currentLevel + 1, complement, maxLevel, ddVariableIndices, currentOffset + odd.
getElseOffset(),
512 DdNode
const* thenDdNode = Cudd_T_const(dd);
513 DdNode
const* elseDdNode = Cudd_E_const(dd);
516 bool elseComplemented = Cudd_IsComplement(elseDdNode) ^ complement;
517 bool thenComplemented = Cudd_IsComplement(thenDdNode) ^ complement;
519 filterExplicitVectorRec(Cudd_Regular(elseDdNode), manager, currentLevel + 1, elseComplemented, maxLevel, ddVariableIndices, currentOffset,
521 filterExplicitVectorRec(Cudd_Regular(thenDdNode), manager, currentLevel + 1, thenComplemented, maxLevel, ddVariableIndices,
526std::pair<std::vector<storm::expressions::Expression>, std::unordered_map<uint_fast64_t, storm::expressions::Variable>> InternalBdd<DdType::CUDD>::toExpression(
528 std::pair<std::vector<storm::expressions::Expression>, std::unordered_map<uint_fast64_t, storm::expressions::Variable>> result;
532 std::unordered_map<DdNode const*, uint_fast64_t> nodeToCounterMap;
533 std::vector<uint_fast64_t> nextCounterForIndex(ddManager->getNumberOfDdVariables(), 0);
536 bool negated = Cudd_Regular(this->getCuddDdNode()) != this->getCuddDdNode();
539 storm::expressions::Variable topVariable = this->toExpressionRec(Cudd_Regular(this->getCuddDdNode()), ddManager->getCuddManager(), manager, result.first,
540 result.second, countIndexToVariablePair, nodeToCounterMap, nextCounterForIndex);
544 result.first.push_back(!topVariable);
546 result.first.push_back(topVariable);
554 std::unordered_map<uint_fast64_t, storm::expressions::Variable>& indexToVariableMap,
556 std::unordered_map<DdNode const*, uint_fast64_t>& nodeToCounterMap, std::vector<uint_fast64_t>& nextCounterForIndex) {
560 auto nodeCounterIt = nodeToCounterMap.find(dd);
561 if (nodeCounterIt != nodeToCounterMap.end()) {
563 auto variableIt = countIndexToVariablePair.find(std::make_pair(nodeCounterIt->second, Cudd_NodeReadIndex(dd)));
564 STORM_LOG_ASSERT(variableIt != countIndexToVariablePair.end(),
"Unable to find node.");
565 return variableIt->second;
572 if (!Cudd_IsConstant_const(dd)) {
574 nodeToCounterMap[dd] = nextCounterForIndex[Cudd_NodeReadIndex(dd)];
575 countIndexToVariablePair[std::make_pair(nextCounterForIndex[Cudd_NodeReadIndex(dd)], Cudd_NodeReadIndex(dd))] = newNodeVariable;
576 ++nextCounterForIndex[Cudd_NodeReadIndex(dd)];
579 nodeToCounterMap[dd] = 0;
580 countIndexToVariablePair[std::make_pair(0, Cudd_NodeReadIndex(dd))] = newNodeVariable;
584 if (dd == Cudd_ReadOne(ddManager.getManager())) {
589 DdNode
const* t = Cudd_T_const(dd);
590 DdNode
const* e = Cudd_E_const(dd);
591 DdNode
const* T = Cudd_Regular(t);
592 DdNode
const* E = Cudd_Regular(e);
594 toExpressionRec(T, ddManager, manager, expressions, indexToVariableMap, countIndexToVariablePair, nodeToCounterMap, nextCounterForIndex);
596 toExpressionRec(E, ddManager, manager, expressions, indexToVariableMap, countIndexToVariablePair, nodeToCounterMap, nextCounterForIndex);
599 auto indexVariable = indexToVariableMap.find(Cudd_NodeReadIndex(dd));
601 if (indexVariable == indexToVariableMap.end()) {
602 levelVariable =
manager.declareFreshBooleanVariable();
603 indexToVariableMap[Cudd_NodeReadIndex(dd)] = levelVariable;
605 levelVariable = indexVariable->second;
608 newNodeVariable,
storm::expressions::ite(levelVariable, t == T ? thenVariable : !thenVariable, e == E ? elseVariable : !elseVariable)));
612 return newNodeVariable;
616 std::vector<uint_fast64_t>
const& sortedDdVariableIndices,
617 std::function<
bool(uint64_t)>
const& filter) {
619 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
620 "of Storm with CUDD support.");
625 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
626 "of Storm with CUDD support.");
631 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
632 "of Storm with CUDD support.");
639 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
640 "of Storm with CUDD support.");
647 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
648 "of Storm with CUDD support.");
655 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
656 "of Storm with CUDD support.");
661 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
662 "of Storm with CUDD support.");
665template<
typename ValueType>
669 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
670 "of Storm with CUDD support.");
675 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
676 "of Storm with CUDD support.");
681 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
682 "of Storm with CUDD support.");
687 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
688 "of Storm with CUDD support.");
693 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
694 "of Storm with CUDD support.");
699 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
700 "of Storm with CUDD support.");
705 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
706 "of Storm with CUDD support.");
711 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
712 "of Storm with CUDD support.");
717 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
718 "of Storm with CUDD support.");
723 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
724 "of Storm with CUDD support.");
729 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
730 "of Storm with CUDD support.");
735 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
736 "of Storm with CUDD support.");
741 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
742 "of Storm with CUDD support.");
747 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
748 "of Storm with CUDD support.");
753 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
754 "of Storm with CUDD support.");
759 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
760 "of Storm with CUDD support.");
766 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
767 "of Storm with CUDD support.");
772 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
773 "of Storm with CUDD support.");
778 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
779 "of Storm with CUDD support.");
784 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
785 "of Storm with CUDD support.");
790 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
791 "of Storm with CUDD support.");
796 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
797 "of Storm with CUDD support.");
802 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
803 "of Storm with CUDD support.");
808 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
809 "of Storm with CUDD support.");
814 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
815 "of Storm with CUDD support.");
819 bool showVariablesIfPossible)
const {
821 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
822 "of Storm with CUDD support.");
827 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
828 "of Storm with CUDD support.");
831template<
typename ValueType>
834 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
835 "of Storm with CUDD support.");
840 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
841 "of Storm with CUDD support.");
846 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
847 "of Storm with CUDD support.");
850template<
typename ValueType>
852 std::vector<ValueType>
const& sourceValues, std::vector<ValueType>& targetValues)
const {
854 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
855 "of Storm with CUDD support.");
860 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
861 "of Storm with CUDD support.");
867 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
868 "of Storm with CUDD support.");
874 "This version of Storm was compiled without support for CUDD. Yet, a method was called that requires this support. Please choose a version "
875 "of Storm with CUDD support.");
884#ifdef STORM_HAVE_CUDD
886 bool complement, uint_fast64_t maxLevel,
887 std::vector<uint_fast64_t>
const& ddVariableIndices, uint_fast64_t currentOffset,
888 storm::dd::Odd const& odd, std::vector<double>& result, uint_fast64_t& currentIndex,
889 std::vector<double>
const& values);
891 bool complement, uint_fast64_t maxLevel,
892 std::vector<uint_fast64_t>
const& ddVariableIndices,
894 std::vector<uint_fast64_t>& result, uint_fast64_t& currentIndex,
895 std::vector<uint_fast64_t>
const& values);
899 std::vector<double>
const& sourceValues, std::vector<double>& targetValues)
const;
901 std::vector<uint_fast64_t>
const& sourceValues, std::vector<uint_fast64_t>& targetValues)
const;
Odd const & getThenSuccessor() const
Retrieves the then-successor of this ODD node.
uint_fast64_t getTotalOffset() const
Retrieves the total offset, i.e., the sum of the then- and else-offset.
uint_fast64_t getElseOffset() const
Retrieves the else-offset of this ODD node.
Odd const & getElseSuccessor() const
Retrieves the else-successor of this ODD node.
This class is responsible for managing a set of typed variables and all expressions using these varia...
A bit vector that is internally represented as a vector of 64-bit values.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
Expression ite(Expression const &condition, Expression const &thenExpression, Expression const &elseExpression)
Expression iff(Expression const &first, Expression const &second)
SettingsManager const & manager()
Retrieves the settings manager.
storm::storage::BitVector filter(std::vector< T > const &values, std::function< bool(T const &value)> const &function)
Retrieves a bit vector containing all the indices for which the value at this position makes the give...