|
@ -19,7 +19,66 @@ namespace storm { |
|
|
|
|
|
|
|
|
template<typename ValueType> |
|
|
template<typename ValueType> |
|
|
InternalBdd<DdType::Sylvan> InternalBdd<DdType::Sylvan>::fromVector(InternalDdManager<DdType::Sylvan> const* ddManager, std::vector<ValueType> const& values, Odd const& odd, std::vector<uint_fast64_t> const& sortedDdVariableIndices, std::function<bool (ValueType const&)> const& filter) { |
|
|
InternalBdd<DdType::Sylvan> InternalBdd<DdType::Sylvan>::fromVector(InternalDdManager<DdType::Sylvan> const* ddManager, std::vector<ValueType> const& values, Odd const& odd, std::vector<uint_fast64_t> const& sortedDdVariableIndices, std::function<bool (ValueType const&)> const& filter) { |
|
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Not yet implemented."); |
|
|
|
|
|
|
|
|
uint_fast64_t offset = 0; |
|
|
|
|
|
return InternalBdd<DdType::Sylvan>(ddManager, sylvan::Bdd(fromVectorRec(offset, 0, sortedDdVariableIndices.size(), values, odd, sortedDdVariableIndices, filter))); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template<typename ValueType> |
|
|
|
|
|
BDD InternalBdd<DdType::Sylvan>::fromVectorRec(uint_fast64_t& currentOffset, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::vector<ValueType> const& values, Odd const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::function<bool (ValueType const&)> const& filter) { |
|
|
|
|
|
if (currentLevel == maxLevel) { |
|
|
|
|
|
// If we are in a terminal node of the ODD, we need to check whether the then-offset of the ODD is one
|
|
|
|
|
|
// (meaning the encoding is a valid one) or zero (meaning the encoding is not valid). Consequently, we
|
|
|
|
|
|
// need to copy the next value of the vector iff the then-offset is greater than zero.
|
|
|
|
|
|
if (odd.getThenOffset() > 0) { |
|
|
|
|
|
if (filter(values[currentOffset++])) { |
|
|
|
|
|
return mtbdd_true; |
|
|
|
|
|
} else { |
|
|
|
|
|
return mtbdd_false; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
return mtbdd_false; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
// If the total offset is zero, we can just return the constant zero DD.
|
|
|
|
|
|
if (odd.getThenOffset() + odd.getElseOffset() == 0) { |
|
|
|
|
|
return mtbdd_false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Determine the new else-successor.
|
|
|
|
|
|
BDD elseSuccessor; |
|
|
|
|
|
if (odd.getElseOffset() > 0) { |
|
|
|
|
|
elseSuccessor = fromVectorRec(currentOffset, currentLevel + 1, maxLevel, values, odd.getElseSuccessor(), ddVariableIndices, filter); |
|
|
|
|
|
} else { |
|
|
|
|
|
elseSuccessor = mtbdd_false; |
|
|
|
|
|
} |
|
|
|
|
|
sylvan_ref(elseSuccessor); |
|
|
|
|
|
|
|
|
|
|
|
// Determine the new then-successor.
|
|
|
|
|
|
BDD thenSuccessor; |
|
|
|
|
|
if (odd.getThenOffset() > 0) { |
|
|
|
|
|
thenSuccessor = fromVectorRec(currentOffset, currentLevel + 1, maxLevel, values, odd.getThenSuccessor(), ddVariableIndices, filter); |
|
|
|
|
|
} else { |
|
|
|
|
|
thenSuccessor = mtbdd_false; |
|
|
|
|
|
} |
|
|
|
|
|
sylvan_ref(thenSuccessor); |
|
|
|
|
|
|
|
|
|
|
|
// Create a node representing ITE(currentVar, thenSuccessor, elseSuccessor);
|
|
|
|
|
|
BDD result = sylvan_ithvar(static_cast<BDDVAR>(ddVariableIndices[currentLevel])); |
|
|
|
|
|
sylvan_ref(result); |
|
|
|
|
|
LACE_ME; |
|
|
|
|
|
BDD newResult = sylvan_ite(result, thenSuccessor, elseSuccessor); |
|
|
|
|
|
sylvan_ref(newResult); |
|
|
|
|
|
|
|
|
|
|
|
// Dispose of the intermediate results
|
|
|
|
|
|
sylvan_deref(result); |
|
|
|
|
|
sylvan_deref(thenSuccessor); |
|
|
|
|
|
sylvan_deref(elseSuccessor); |
|
|
|
|
|
|
|
|
|
|
|
// Before returning, we remove the protection imposed by the previous call to sylvan_ref.
|
|
|
|
|
|
sylvan_deref(newResult); |
|
|
|
|
|
|
|
|
|
|
|
return newResult; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool InternalBdd<DdType::Sylvan>::operator==(InternalBdd<DdType::Sylvan> const& other) const { |
|
|
bool InternalBdd<DdType::Sylvan>::operator==(InternalBdd<DdType::Sylvan> const& other) const { |
|
|