14template<DdType LibraryType>
19template<DdType LibraryType>
21 return this->shared_from_this();
24template<DdType LibraryType>
26 return this->shared_from_this();
29template<DdType LibraryType>
34template<DdType LibraryType>
35template<
typename ValueType>
40template<DdType LibraryType>
45template<DdType LibraryType>
46template<
typename ValueType>
51template<DdType LibraryType>
52template<
typename ValueType>
57template<DdType LibraryType>
58template<
typename ValueType>
60 return getConstant(storm::utility::infinity<ValueType>());
63template<DdType LibraryType>
64template<
typename ValueType>
69template<DdType LibraryType>
74 "Illegal value " << value <<
" for meta variable '" << variable.
getName() <<
"'.");
77 value -= metaVariable.getLow();
79 std::vector<Bdd<LibraryType>>
const& ddVariables = metaVariable.getDdVariables();
82 if (mostSignificantBitAtTop) {
83 if (value & (1ull << (ddVariables.size() - 1))) {
84 result = ddVariables[0];
86 result = !ddVariables[0];
89 for (std::size_t i = 1; i < ddVariables.size(); ++i) {
90 if (value & (1ull << (ddVariables.size() - i - 1))) {
91 result &= ddVariables[i];
93 result &= !ddVariables[i];
98 result = ddVariables[0];
100 result = !ddVariables[0];
104 for (std::size_t i = 1; i < ddVariables.size(); ++i) {
106 result &= ddVariables[i];
108 result &= !ddVariables[i];
117template<DdType LibraryType>
123 internalDdManager.getBddEncodingLessOrEqualThan(
static_cast<uint64_t
>(metaVariable.
getHigh() - metaVariable.
getLow()),
134template<DdType LibraryType>
135template<
typename ValueType>
138 STORM_LOG_THROW(metaVariable.
hasHigh(), storm::exceptions::InvalidOperationException,
"Cannot create identity for meta variable.");
141 for (int_fast64_t value = metaVariable.
getLow(); value <= metaVariable.
getHigh(); ++value) {
142 result += this->getEncoding(variable, value).template toAdd<ValueType>() * this->getConstant(storm::utility::convertNumber<ValueType>(value));
147template<DdType LibraryType>
149 bool restrictToFirstRange)
const {
150 auto result = this->getBddOne();
151 for (
auto const& pair : variablePairs) {
152 result &= this->getIdentity(pair.first, pair.second, restrictToFirstRange);
157template<DdType LibraryType>
159 bool restrictToFirstRange)
const {
160 auto const& firstMetaVariable = this->getMetaVariable(first);
161 auto const& secondMetaVariable = this->getMetaVariable(second);
163 STORM_LOG_THROW(firstMetaVariable.getNumberOfDdVariables() == secondMetaVariable.getNumberOfDdVariables(), storm::exceptions::InvalidOperationException,
164 "Mismatching sizes of meta variables.");
166 auto const& firstDdVariables = firstMetaVariable.getDdVariables();
167 auto const& secondDdVariables = secondMetaVariable.getDdVariables();
169 auto result = restrictToFirstRange ? this->getRange(first) : this->getBddOne();
170 for (
auto it1 = firstDdVariables.begin(), it2 = secondDdVariables.begin(), ite1 = firstDdVariables.end(); it1 != ite1; ++it1, ++it2) {
171 result &= it1->iff(*it2);
177#pragma GCC diagnostic push
178#pragma GCC diagnostic ignored "-Winfinite-recursion"
179template<DdType LibraryType>
181 return getCube({variable});
183#pragma GCC diagnostic pop
185template<DdType LibraryType>
188 for (
auto const& variable : variables) {
190 result &= metaVariable.
getCube();
195template<DdType LibraryType>
197 std::string
const& newMetaVariableName,
198 boost::optional<uint64_t>
const& numberOfLayers) {
199 std::vector<storm::expressions::Variable> newMetaVariables;
200 auto const& ddMetaVariable = this->getMetaVariable(variable);
202 newMetaVariables = this->addMetaVariable(newMetaVariableName, 3);
204 newMetaVariables = this->addMetaVariable(newMetaVariableName, ddMetaVariable.getLow(), ddMetaVariable.getHigh(), 3);
206 newMetaVariables = this->addBitVectorMetaVariable(newMetaVariableName, ddMetaVariable.getNumberOfDdVariables(), 3);
208 return newMetaVariables;
211template<DdType LibraryType>
213 std::string
const& name, int_fast64_t low, int_fast64_t high,
214 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
215 std::vector<storm::expressions::Variable> result = addMetaVariable(name, low, high, 2, position);
216 return std::make_pair(result[0], result[1]);
219template<DdType LibraryType>
221 std::string
const& name, int_fast64_t low, int_fast64_t high, uint64_t numberOfLayers,
222 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
224 std::max(
static_cast<uint64_t
>(std::ceil(std::log2(high - low + 1))),
static_cast<uint64_t
>(1)), numberOfLayers,
225 position, std::make_pair(low, high));
228template<DdType LibraryType>
230 std::string
const& variableName, uint64_t bits, uint64_t numberOfLayers,
231 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
235template<DdType LibraryType>
237 std::string
const& name, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
238 std::vector<storm::expressions::Variable> result = this->addMetaVariableHelper(
MetaVariableType::Bool, name, 1, 2, position);
239 return std::make_pair(result[0], result[1]);
242template<DdType LibraryType>
244 std::string
const& name, uint64_t numberOfLayers, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
248template<DdType LibraryType>
250 MetaVariableType const& type, std::string
const& name, uint64_t numberOfDdVariables, uint64_t numberOfLayers,
251 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position,
252 boost::optional<std::pair<int_fast64_t, int_fast64_t>>
const& bounds) {
254 STORM_LOG_THROW(numberOfLayers >= 1, storm::exceptions::InvalidArgumentException,
"Layers must be at least 1.");
257 STORM_LOG_THROW(numberOfDdVariables >= 1, storm::exceptions::InvalidArgumentException,
"Illegal number of DD variables.");
260 STORM_LOG_THROW(name !=
"" && name.back() !=
'\'', storm::exceptions::InvalidArgumentException,
"Illegal name of meta variable: '" << name <<
"'.");
263 STORM_LOG_THROW(!this->hasMetaVariable(name), storm::exceptions::InvalidArgumentException,
"A meta variable '" << name <<
"' already exists.");
266 boost::optional<uint_fast64_t> level;
269 level = position.get().first ==
MetaVariablePosition::Above ? std::numeric_limits<uint_fast64_t>::max() :
std::numeric_limits<uint_fast64_t>::min();
270 for (
auto const& ddVariable : beforeVariable.getDdVariables()) {
272 :
std::max(level.get(), ddVariable.getLevel());
279 STORM_LOG_TRACE(
"Creating meta variable with " << numberOfDdVariables <<
" bit(s) and " << numberOfLayers <<
" layer(s).");
281 std::stringstream tmp1;
282 std::vector<storm::expressions::Variable> result;
283 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
285 result.emplace_back(manager->declareIntegerVariable(name + tmp1.str()));
287 result.emplace_back(manager->declareBooleanVariable(name + tmp1.str()));
289 result.emplace_back(manager->declareBitVectorVariable(name + tmp1.str(), numberOfDdVariables));
294 std::vector<std::vector<Bdd<LibraryType>>> variables(numberOfLayers);
295 for (std::size_t i = 0; i < numberOfDdVariables; ++i) {
296 std::vector<InternalBdd<LibraryType>> ddVariables = internalDdManager.createDdVariables(numberOfLayers, level);
297 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
298 variables[layer].emplace_back(
Bdd<LibraryType>(*
this, ddVariables[layer], {result[layer]}));
304 level.get() += numberOfLayers;
308 std::stringstream tmp2;
309 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
311 metaVariableMap.emplace(result[layer],
DdMetaVariable<LibraryType>(name + tmp2.str(), bounds.get().first, bounds.get().second, variables[layer]));
321template<DdType LibraryType>
323 auto const& variablePair = metaVariableMap.find(variable);
326 STORM_LOG_THROW(variablePair != metaVariableMap.end(), storm::exceptions::InvalidArgumentException,
327 "Unknown meta variable name '" << variable.
getName() <<
"'.");
329 return variablePair->second;
332template<DdType LibraryType>
334 std::set<std::string> result;
335 for (
auto const& variablePair : metaVariableMap) {
336 result.insert(variablePair.first.getName());
341template<DdType LibraryType>
343 return this->metaVariableMap.size();
346template<DdType LibraryType>
348 return manager->hasVariable(metaVariableName);
351template<DdType LibraryType>
354 STORM_LOG_THROW(hasMetaVariable(metaVariableName), storm::exceptions::InvalidArgumentException,
"Unknown meta variable name '" << metaVariableName <<
"'.");
356 return manager->getVariable(metaVariableName);
359template<DdType LibraryType>
361 return internalDdManager.supportsOrderedInsertion();
364template<DdType LibraryType>
369template<DdType LibraryType>
374template<DdType LibraryType>
375std::vector<std::string> DdManager<LibraryType>::getDdVariableNames()
const {
377 std::vector<std::pair<uint_fast64_t, std::string>> variablePairs;
378 for (
auto const& variablePair : this->metaVariableMap) {
379 DdMetaVariable<LibraryType>
const& metaVariable = variablePair.second;
382 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first.getName());
385 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
386 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(),
387 variablePair.first.getName() +
'.' + std::to_string(variableIndex));
393 std::sort(variablePairs.begin(), variablePairs.end(),
394 [](std::pair<uint_fast64_t, std::string>
const& a, std::pair<uint_fast64_t, std::string>
const& b) { return a.first < b.first; });
397 std::vector<std::string> result;
398 for (
auto const& element : variablePairs) {
399 result.push_back(element.second);
405template<DdType LibraryType>
406std::vector<storm::expressions::Variable> DdManager<LibraryType>::getDdVariables()
const {
408 std::vector<std::pair<uint_fast64_t, storm::expressions::Variable>> variablePairs;
409 for (
auto const& variablePair : this->metaVariableMap) {
410 DdMetaVariable<LibraryType>
const& metaVariable = variablePair.second;
413 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first);
416 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
417 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(), variablePair.first);
423 std::sort(variablePairs.begin(), variablePairs.end(),
424 [](std::pair<uint_fast64_t, storm::expressions::Variable>
const& a, std::pair<uint_fast64_t, storm::expressions::Variable>
const& b) {
425 return a.first < b.first;
429 std::vector<storm::expressions::Variable> result;
430 for (
auto const& element : variablePairs) {
431 result.push_back(element.second);
437template<DdType LibraryType>
439 internalDdManager.allowDynamicReordering(value);
442template<DdType LibraryType>
444 return internalDdManager.isDynamicReorderingAllowed();
447template<DdType LibraryType>
449 internalDdManager.triggerReordering();
452template<DdType LibraryType>
454 std::set<storm::expressions::Variable> result;
455 for (
auto const& variable : this->metaVariableMap) {
456 result.insert(variable.first);
461template<DdType LibraryType>
463 return this->getSortedVariableIndices(this->getAllMetaVariables());
466template<DdType LibraryType>
468 std::vector<uint_fast64_t> ddVariableIndices;
469 for (
auto const& metaVariable : metaVariables) {
470 for (
auto const& ddVariable : metaVariableMap.at(metaVariable).getDdVariables()) {
471 ddVariableIndices.push_back(ddVariable.getIndex());
476 std::ranges::sort(ddVariableIndices);
477 return ddVariableIndices;
480template<DdType LibraryType>
482 return internalDdManager;
485template<DdType LibraryType>
487 return internalDdManager;
490template<DdType LibraryType>
492 return &internalDdManager;
495template<DdType LibraryType>
496InternalDdManager<LibraryType>
const* DdManager<LibraryType>::getInternalDdManagerPointer()
const {
497 return &internalDdManager;
500template<DdType LibraryType>
505template<DdType LibraryType>
507 internalDdManager.execute(f);
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)