6#include "storm-config.h"
16template<DdType LibraryType>
21template<DdType LibraryType>
23 return this->shared_from_this();
26template<DdType LibraryType>
28 return this->shared_from_this();
31template<DdType LibraryType>
36template<DdType LibraryType>
37template<
typename ValueType>
42template<DdType LibraryType>
47template<DdType LibraryType>
48template<
typename ValueType>
53template<DdType LibraryType>
54template<
typename ValueType>
59template<DdType LibraryType>
60template<
typename ValueType>
62 return getConstant(storm::utility::infinity<ValueType>());
65template<DdType LibraryType>
66template<
typename ValueType>
71template<DdType LibraryType>
76 "Illegal value " << value <<
" for meta variable '" << variable.
getName() <<
"'.");
79 value -= metaVariable.
getLow();
81 std::vector<Bdd<LibraryType>>
const& ddVariables = metaVariable.getDdVariables();
84 if (mostSignificantBitAtTop) {
85 if (value & (1ull << (ddVariables.size() - 1))) {
86 result = ddVariables[0];
88 result = !ddVariables[0];
91 for (std::size_t i = 1; i < ddVariables.size(); ++i) {
92 if (value & (1ull << (ddVariables.size() - i - 1))) {
93 result &= ddVariables[i];
95 result &= !ddVariables[i];
100 result = ddVariables[0];
102 result = !ddVariables[0];
106 for (std::size_t i = 1; i < ddVariables.size(); ++i) {
108 result &= ddVariables[i];
110 result &= !ddVariables[
i];
119template<DdType LibraryType>
125 internalDdManager.getBddEncodingLessOrEqualThan(
static_cast<uint64_t
>(metaVariable.
getHigh() - metaVariable.
getLow()),
136template<DdType LibraryType>
137template<
typename ValueType>
140 STORM_LOG_THROW(metaVariable.
hasHigh(), storm::exceptions::InvalidOperationException,
"Cannot create identity for meta variable.");
143 for (int_fast64_t value = metaVariable.
getLow(); value <= metaVariable.
getHigh(); ++value) {
144 result += this->getEncoding(variable, value).template toAdd<ValueType>() * this->getConstant(storm::utility::convertNumber<ValueType>(value));
149template<DdType LibraryType>
151 bool restrictToFirstRange)
const {
152 auto result = this->getBddOne();
153 for (
auto const& pair : variablePairs) {
154 result &= this->getIdentity(pair.first, pair.second, restrictToFirstRange);
159template<DdType LibraryType>
161 bool restrictToFirstRange)
const {
162 auto const& firstMetaVariable = this->getMetaVariable(first);
163 auto const& secondMetaVariable = this->getMetaVariable(second);
165 STORM_LOG_THROW(firstMetaVariable.getNumberOfDdVariables() == secondMetaVariable.getNumberOfDdVariables(), storm::exceptions::InvalidOperationException,
166 "Mismatching sizes of meta variables.");
168 auto const& firstDdVariables = firstMetaVariable.getDdVariables();
169 auto const& secondDdVariables = secondMetaVariable.getDdVariables();
171 auto result = restrictToFirstRange ? this->getRange(first) : this->getBddOne();
172 for (
auto it1 = firstDdVariables.begin(), it2 = secondDdVariables.begin(), ite1 = firstDdVariables.end(); it1 != ite1; ++it1, ++it2) {
179#pragma GCC diagnostic push
180#pragma GCC diagnostic ignored "-Winfinite-recursion"
181template<DdType LibraryType>
183 return getCube({variable});
185#pragma GCC diagnostic pop
187template<DdType LibraryType>
190 for (
auto const& variable : variables) {
192 result &= metaVariable.
getCube();
197template<DdType LibraryType>
199 std::string
const& newMetaVariableName,
200 boost::optional<uint64_t>
const& numberOfLayers) {
201 std::vector<storm::expressions::Variable> newMetaVariables;
202 auto const& ddMetaVariable = this->getMetaVariable(variable);
204 newMetaVariables = this->addMetaVariable(newMetaVariableName, 3);
206 newMetaVariables = this->addMetaVariable(newMetaVariableName, ddMetaVariable.getLow(), ddMetaVariable.getHigh(), 3);
208 newMetaVariables = this->addBitVectorMetaVariable(newMetaVariableName, ddMetaVariable.getNumberOfDdVariables(), 3);
210 return newMetaVariables;
213template<DdType LibraryType>
215 std::string
const& name, int_fast64_t low, int_fast64_t high,
216 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
217 std::vector<storm::expressions::Variable> result = addMetaVariable(name, low, high, 2, position);
218 return std::make_pair(result[0], result[1]);
221template<DdType LibraryType>
223 std::string
const& name, int_fast64_t low, int_fast64_t high, uint64_t numberOfLayers,
224 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
226 std::max(
static_cast<uint64_t
>(std::ceil(std::log2(high - low + 1))),
static_cast<uint64_t
>(1)), numberOfLayers,
227 position, std::make_pair(low, high));
230template<DdType LibraryType>
232 std::string
const& variableName, uint64_t bits, uint64_t numberOfLayers,
233 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
237template<DdType LibraryType>
239 std::string
const& name, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
240 std::vector<storm::expressions::Variable> result = this->addMetaVariableHelper(
MetaVariableType::Bool, name, 1, 2, position);
241 return std::make_pair(result[0], result[1]);
244template<DdType LibraryType>
246 std::string
const& name, uint64_t numberOfLayers, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
250template<DdType LibraryType>
252 MetaVariableType const& type, std::string
const& name, uint64_t numberOfDdVariables, uint64_t numberOfLayers,
253 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position,
254 boost::optional<std::pair<int_fast64_t, int_fast64_t>>
const& bounds) {
256 STORM_LOG_THROW(numberOfLayers >= 1, storm::exceptions::InvalidArgumentException,
"Layers must be at least 1.");
259 STORM_LOG_THROW(numberOfDdVariables >= 1, storm::exceptions::InvalidArgumentException,
"Illegal number of DD variables.");
262 STORM_LOG_THROW(name !=
"" && name.back() !=
'\'', storm::exceptions::InvalidArgumentException,
"Illegal name of meta variable: '" << name <<
"'.");
265 STORM_LOG_THROW(!this->hasMetaVariable(name), storm::exceptions::InvalidArgumentException,
"A meta variable '" << name <<
"' already exists.");
268 boost::optional<uint_fast64_t> level;
271 level = position.get().first ==
MetaVariablePosition::Above ? std::numeric_limits<uint_fast64_t>::max() : std::numeric_limits<uint_fast64_t>::min();
272 for (
auto const& ddVariable : beforeVariable.getDdVariables()) {
274 : std::max(level.get(), ddVariable.getLevel());
281 STORM_LOG_TRACE(
"Creating meta variable with " << numberOfDdVariables <<
" bit(s) and " << numberOfLayers <<
" layer(s).");
283 std::stringstream tmp1;
284 std::vector<storm::expressions::Variable> result;
285 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
287 result.emplace_back(manager->declareIntegerVariable(name + tmp1.str()));
289 result.emplace_back(manager->declareBooleanVariable(name + tmp1.str()));
291 result.emplace_back(manager->declareBitVectorVariable(name + tmp1.str(), numberOfDdVariables));
296 std::vector<std::vector<Bdd<LibraryType>>> variables(numberOfLayers);
297 for (std::size_t i = 0; i < numberOfDdVariables; ++i) {
298 std::vector<InternalBdd<LibraryType>> ddVariables = internalDdManager.createDdVariables(numberOfLayers, level);
299 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
300 variables[layer].emplace_back(
Bdd<LibraryType>(*
this, ddVariables[layer], {result[layer]}));
306 level.get() += numberOfLayers;
310 std::stringstream tmp2;
311 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
313 metaVariableMap.emplace(result[layer],
DdMetaVariable<LibraryType>(name + tmp2.str(), bounds.get().first, bounds.get().second, variables[layer]));
323template<DdType LibraryType>
325 auto const& variablePair = metaVariableMap.find(variable);
328 STORM_LOG_THROW(variablePair != metaVariableMap.end(), storm::exceptions::InvalidArgumentException,
329 "Unknown meta variable name '" << variable.
getName() <<
"'.");
331 return variablePair->second;
334template<DdType LibraryType>
336 std::set<std::string> result;
337 for (
auto const& variablePair : metaVariableMap) {
338 result.insert(variablePair.first.getName());
343template<DdType LibraryType>
345 return this->metaVariableMap.size();
348template<DdType LibraryType>
350 return manager->hasVariable(metaVariableName);
353template<DdType LibraryType>
356 STORM_LOG_THROW(hasMetaVariable(metaVariableName), storm::exceptions::InvalidArgumentException,
"Unknown meta variable name '" << metaVariableName <<
"'.");
358 return manager->getVariable(metaVariableName);
361template<DdType LibraryType>
363 return internalDdManager.supportsOrderedInsertion();
366template<DdType LibraryType>
371template<DdType LibraryType>
376template<DdType LibraryType>
377std::vector<std::string> DdManager<LibraryType>::getDdVariableNames()
const {
379 std::vector<std::pair<uint_fast64_t, std::string>> variablePairs;
380 for (
auto const& variablePair : this->metaVariableMap) {
381 DdMetaVariable<LibraryType>
const& metaVariable = variablePair.second;
384 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first.getName());
387 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
388 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(),
389 variablePair.first.getName() +
'.' + std::to_string(variableIndex));
395 std::sort(variablePairs.begin(), variablePairs.end(),
396 [](std::pair<uint_fast64_t, std::string>
const& a, std::pair<uint_fast64_t, std::string>
const& b) { return a.first < b.first; });
399 std::vector<std::string> result;
400 for (
auto const& element : variablePairs) {
401 result.push_back(element.second);
407template<DdType LibraryType>
408std::vector<storm::expressions::Variable> DdManager<LibraryType>::getDdVariables()
const {
410 std::vector<std::pair<uint_fast64_t, storm::expressions::Variable>> variablePairs;
411 for (
auto const& variablePair : this->metaVariableMap) {
412 DdMetaVariable<LibraryType>
const& metaVariable = variablePair.second;
415 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first);
418 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
419 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(), variablePair.first);
425 std::sort(variablePairs.begin(), variablePairs.end(),
426 [](std::pair<uint_fast64_t, storm::expressions::Variable>
const& a, std::pair<uint_fast64_t, storm::expressions::Variable>
const& b) {
427 return a.first < b.first;
431 std::vector<storm::expressions::Variable> result;
432 for (
auto const& element : variablePairs) {
433 result.push_back(element.second);
439template<DdType LibraryType>
441 internalDdManager.allowDynamicReordering(value);
444template<DdType LibraryType>
446 return internalDdManager.isDynamicReorderingAllowed();
449template<DdType LibraryType>
451 internalDdManager.triggerReordering();
454template<DdType LibraryType>
456 std::set<storm::expressions::Variable> result;
457 for (
auto const& variable : this->metaVariableMap) {
458 result.insert(variable.first);
463template<DdType LibraryType>
465 return this->getSortedVariableIndices(this->getAllMetaVariables());
468template<DdType LibraryType>
470 std::vector<uint_fast64_t> ddVariableIndices;
471 for (
auto const& metaVariable : metaVariables) {
472 for (
auto const& ddVariable : metaVariableMap.at(metaVariable).getDdVariables()) {
473 ddVariableIndices.push_back(ddVariable.getIndex());
478 std::ranges::sort(ddVariableIndices);
479 return ddVariableIndices;
482template<DdType LibraryType>
484 return internalDdManager;
487template<DdType LibraryType>
489 return internalDdManager;
492template<DdType LibraryType>
494 return &internalDdManager;
497template<DdType LibraryType>
498InternalDdManager<LibraryType>
const* DdManager<LibraryType>::getInternalDdManagerPointer()
const {
499 return &internalDdManager;
502template<DdType LibraryType>
507template<DdType LibraryType>
509 internalDdManager.execute(f);
Bdd< LibraryType > iff(Bdd< LibraryType > const &other) const
Performs a logical iff of the current and the given BDD.
void addMetaVariable(storm::expressions::Variable const &metaVariable)
Adds the given meta variable to the set of meta variables that are contained in this DD.
storm::expressions::Variable getMetaVariable(std::string const &variableName) const
Retrieves the given meta variable by name.
Add< LibraryType, ValueType > getAddOne() const
Retrieves an ADD representing the constant one function.
bool hasMetaVariable(std::string const &variableName) const
Retrieves whether the given meta variable name is already in use.
std::shared_ptr< DdManager< LibraryType > > asSharedPointer()
Add< LibraryType, ValueType > getAddZero() const
Retrieves an ADD representing the constant zero function.
std::vector< uint_fast64_t > getSortedVariableIndices() const
Retrieves the (sorted) list of the variable indices of the DD variables given by the meta variable se...
std::set< storm::expressions::Variable > getAllMetaVariables() const
Retrieves the set of meta variables contained in the DD.
InternalDdManager< LibraryType > & getInternalDdManager()
Retrieves the internal DD manager.
Bdd< LibraryType > getCube(storm::expressions::Variable const &variable) const
Retrieves a BDD that is the cube of the variables representing the given meta variable.
Add< LibraryType, ValueType > getInfinity() const
Retrieves an ADD representing the constant infinity function.
void execute(std::function< void()> const &f) const
All code that manipulates DDs shall be called through this function.
Bdd< LibraryType > getBddOne() const
Retrieves a BDD representing the constant one function.
DdManager()
Creates an empty manager without any meta variables.
std::set< std::string > getAllMetaVariableNames() const
Retrieves the names of all meta variables that have been added to the manager.
Bdd< LibraryType > getBddZero() const
Retrieves a BDD representing the constant zero function.
void triggerReordering()
Triggers a reordering of the DDs managed by this manager (if supported).
Bdd< LibraryType > getEncoding(storm::expressions::Variable const &variable, int_fast64_t value, bool mostSignificantBitAtTop=true) const
Retrieves the BDD representing the function that maps all inputs which have the given meta variable e...
bool isDynamicReorderingAllowed() const
Retrieves whether dynamic reordering is currently allowed (if supported).
std::vector< storm::expressions::Variable > cloneVariable(storm::expressions::Variable const &variable, std::string const &newVariableName, boost::optional< uint64_t > const &numberOfLayers=boost::none)
Clones the given meta variable and optionally changes the number of layers of the variable.
Add< LibraryType, ValueType > getIdentity(storm::expressions::Variable const &variable) const
Retrieves the ADD representing the identity of the meta variable, i.e., a function that maps all lega...
Add< LibraryType, ValueType > getAddUndefined() const
Retrieves an ADD representing an undefined value.
bool supportsOrderedInsertion() const
Checks whether this manager supports the ordered insertion of variables, i.e.
Bdd< LibraryType > getRange(storm::expressions::Variable const &variable) const
Retrieves the BDD representing the range of the meta variable, i.e., a function that maps all legal v...
std::pair< storm::expressions::Variable, storm::expressions::Variable > addMetaVariable(std::string const &variableName, int_fast64_t low, int_fast64_t high, boost::optional< std::pair< MetaVariablePosition, storm::expressions::Variable > > const &position=boost::none)
Adds an integer meta variable with the given range with two layers (a 'normal' and a 'primed' one).
Add< LibraryType, ValueType > getConstant(ValueType const &value) const
Retrieves an ADD representing the constant function with the given value.
std::vector< storm::expressions::Variable > addBitVectorMetaVariable(std::string const &variableName, uint64_t bits, uint64_t numberOfLayers, boost::optional< std::pair< MetaVariablePosition, storm::expressions::Variable > > const &position=boost::none)
Creates a meta variable with the given number of layers.
void allowDynamicReordering(bool value)
Sets whether dynamic reordering is allowed for the DDs managed by this manager (if supported).
void debugCheck() const
Performs a debug check if available.
std::size_t getNumberOfMetaVariables() const
Retrieves the number of meta variables that are contained in this manager.
This class is responsible for managing a set of typed variables and all expressions using these varia...
std::string const & getName() const
Retrieves the name of the variable.
#define STORM_LOG_TRACE(message)
#define STORM_LOG_THROW(cond, exception, message)