16template<DdType LibraryType>
18 : internalDdManager(env.
dd().get<LibraryType>()), metaVariableMap(), manager(new
storm::
expressions::ExpressionManager()) {
22template<DdType LibraryType>
27template<DdType LibraryType>
29 return this->shared_from_this();
32template<DdType LibraryType>
34 return this->shared_from_this();
37template<DdType LibraryType>
42template<DdType LibraryType>
43template<
typename ValueType>
48template<DdType LibraryType>
53template<DdType LibraryType>
54template<
typename ValueType>
59template<DdType LibraryType>
60template<
typename ValueType>
65template<DdType LibraryType>
66template<
typename ValueType>
71template<DdType LibraryType>
72template<
typename ValueType>
77template<DdType LibraryType>
82 "Illegal value " << value <<
" for meta variable '" << variable.
getName() <<
"'.");
87 std::vector<Bdd<LibraryType>>
const& ddVariables = metaVariable.getDdVariables();
90 if (mostSignificantBitAtTop) {
91 if (value & (1ull << (ddVariables.size() - 1))) {
92 result = ddVariables[0];
94 result = !ddVariables[0];
97 for (std::size_t i = 1; i < ddVariables.size(); ++i) {
98 if (value & (1ull << (ddVariables.size() - i - 1))) {
99 result &= ddVariables[i];
101 result &= !ddVariables[i];
106 result = ddVariables[0];
108 result = !ddVariables[0];
112 for (std::size_t i = 1; i < ddVariables.size(); ++i) {
114 result &= ddVariables[i];
116 result &= !ddVariables[i];
125template<DdType LibraryType>
131 internalDdManager.getBddEncodingLessOrEqualThan(
static_cast<uint64_t
>(metaVariable.
getHigh() - metaVariable.
getLow()),
142template<DdType LibraryType>
143template<
typename ValueType>
146 STORM_LOG_THROW(metaVariable.
hasHigh(), storm::exceptions::InvalidOperationException,
"Cannot create identity for meta variable.");
149 for (int_fast64_t value = metaVariable.
getLow(); value <= metaVariable.
getHigh(); ++value) {
155template<DdType LibraryType>
157 bool restrictToFirstRange)
const {
159 for (
auto const& pair : variablePairs) {
160 result &= this->
getIdentity(pair.first, pair.second, restrictToFirstRange);
165template<DdType LibraryType>
167 bool restrictToFirstRange)
const {
171 STORM_LOG_THROW(firstMetaVariable.getNumberOfDdVariables() == secondMetaVariable.getNumberOfDdVariables(), storm::exceptions::InvalidOperationException,
172 "Mismatching sizes of meta variables.");
174 auto const& firstDdVariables = firstMetaVariable.getDdVariables();
175 auto const& secondDdVariables = secondMetaVariable.getDdVariables();
178 for (
auto it1 = firstDdVariables.begin(), it2 = secondDdVariables.begin(), ite1 = firstDdVariables.end(); it1 != ite1; ++it1, ++it2) {
179 result &= it1->
iff(*it2);
185#pragma GCC diagnostic push
186#pragma GCC diagnostic ignored "-Winfinite-recursion"
187template<DdType LibraryType>
191#pragma GCC diagnostic pop
193template<DdType LibraryType>
196 for (
auto const& variable : variables) {
198 result &= metaVariable.
getCube();
203template<DdType LibraryType>
205 std::string
const& newMetaVariableName,
206 boost::optional<uint64_t>
const& numberOfLayers) {
207 std::vector<storm::expressions::Variable> newMetaVariables;
212 newMetaVariables = this->
addMetaVariable(newMetaVariableName, ddMetaVariable.getLow(), ddMetaVariable.getHigh(), 3);
216 return newMetaVariables;
219template<DdType LibraryType>
221 std::string
const& name, int_fast64_t low, int_fast64_t high,
222 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
223 std::vector<storm::expressions::Variable> result =
addMetaVariable(name, low, high, 2, position);
224 return std::make_pair(result[0], result[1]);
227template<DdType LibraryType>
229 std::string
const& name, int_fast64_t low, int_fast64_t high, uint64_t numberOfLayers,
230 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
232 std::max(
static_cast<uint64_t
>(std::ceil(std::log2(high - low + 1))),
static_cast<uint64_t
>(1)), numberOfLayers,
233 position, std::make_pair(low, high));
236template<DdType LibraryType>
238 std::string
const& variableName, uint64_t bits, uint64_t numberOfLayers,
239 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
243template<DdType LibraryType>
245 std::string
const& name, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
246 std::vector<storm::expressions::Variable> result = this->addMetaVariableHelper(
MetaVariableType::Bool, name, 1, 2, position);
247 return std::make_pair(result[0], result[1]);
250template<DdType LibraryType>
252 std::string
const& name, uint64_t numberOfLayers, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
256template<DdType LibraryType>
257std::vector<storm::expressions::Variable> DdManager<LibraryType>::addMetaVariableHelper(
258 MetaVariableType const& type, std::string
const& name, uint64_t numberOfDdVariables, uint64_t numberOfLayers,
259 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position,
260 boost::optional<std::pair<int_fast64_t, int_fast64_t>>
const& bounds) {
262 STORM_LOG_THROW(numberOfLayers >= 1, storm::exceptions::InvalidArgumentException,
"Layers must be at least 1.");
265 STORM_LOG_THROW(numberOfDdVariables >= 1, storm::exceptions::InvalidArgumentException,
"Illegal number of DD variables.");
268 STORM_LOG_THROW(name !=
"" && name.back() !=
'\'', storm::exceptions::InvalidArgumentException,
"Illegal name of meta variable: '" << name <<
"'.");
274 boost::optional<uint_fast64_t> level;
277 level = position.get().first ==
MetaVariablePosition::Above ? std::numeric_limits<uint_fast64_t>::max() : std::numeric_limits<uint_fast64_t>::min();
278 for (
auto const& ddVariable : beforeVariable.getDdVariables()) {
280 :
std::max(level.get(), ddVariable.getLevel());
287 STORM_LOG_TRACE(
"Creating meta variable with " << numberOfDdVariables <<
" bit(s) and " << numberOfLayers <<
" layer(s).");
289 std::stringstream tmp1;
290 std::vector<storm::expressions::Variable> result;
291 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
293 result.emplace_back(manager->declareIntegerVariable(name + tmp1.str()));
295 result.emplace_back(manager->declareBooleanVariable(name + tmp1.str()));
297 result.emplace_back(manager->declareBitVectorVariable(name + tmp1.str(), numberOfDdVariables));
302 std::vector<std::vector<Bdd<LibraryType>>> variables(numberOfLayers);
303 for (std::size_t i = 0; i < numberOfDdVariables; ++i) {
304 std::vector<InternalBdd<LibraryType>> ddVariables = internalDdManager.createDdVariables(numberOfLayers, level);
305 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
306 variables[layer].emplace_back(
Bdd<LibraryType>(*
this, ddVariables[layer], {result[layer]}));
312 level.get() += numberOfLayers;
316 std::stringstream tmp2;
317 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
319 metaVariableMap.emplace(result[layer], DdMetaVariable<LibraryType>(name + tmp2.str(), bounds.get().first, bounds.get().second, variables[layer]));
321 metaVariableMap.emplace(result[layer], DdMetaVariable<LibraryType>(type, name + tmp2.str(), variables[layer]));
329template<DdType LibraryType>
331 auto const& variablePair = metaVariableMap.find(variable);
334 STORM_LOG_THROW(variablePair != metaVariableMap.end(), storm::exceptions::InvalidArgumentException,
335 "Unknown meta variable name '" << variable.
getName() <<
"'.");
337 return variablePair->second;
340template<DdType LibraryType>
342 std::set<std::string> result;
343 for (
auto const& variablePair : metaVariableMap) {
344 result.insert(variablePair.first.getName());
349template<DdType LibraryType>
351 return this->metaVariableMap.size();
354template<DdType LibraryType>
356 return manager->hasVariable(metaVariableName);
359template<DdType LibraryType>
362 STORM_LOG_THROW(
hasMetaVariable(metaVariableName), storm::exceptions::InvalidArgumentException,
"Unknown meta variable name '" << metaVariableName <<
"'.");
364 return manager->getVariable(metaVariableName);
367template<DdType LibraryType>
369 return internalDdManager.supportsOrderedInsertion();
372template<DdType LibraryType>
377template<DdType LibraryType>
382template<DdType LibraryType>
383std::vector<std::string> DdManager<LibraryType>::getDdVariableNames()
const {
385 std::vector<std::pair<uint_fast64_t, std::string>> variablePairs;
386 for (
auto const& variablePair : this->metaVariableMap) {
387 DdMetaVariable<LibraryType>
const& metaVariable = variablePair.second;
390 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first.getName());
393 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
394 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(),
395 variablePair.first.getName() +
'.' + std::to_string(variableIndex));
401 std::sort(variablePairs.begin(), variablePairs.end(),
402 [](std::pair<uint_fast64_t, std::string>
const& a, std::pair<uint_fast64_t, std::string>
const& b) { return a.first < b.first; });
405 std::vector<std::string> result;
406 for (
auto const& element : variablePairs) {
407 result.push_back(element.second);
413template<DdType LibraryType>
414std::vector<storm::expressions::Variable> DdManager<LibraryType>::getDdVariables()
const {
416 std::vector<std::pair<uint_fast64_t, storm::expressions::Variable>> variablePairs;
417 for (
auto const& variablePair : this->metaVariableMap) {
421 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first);
424 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
425 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(), variablePair.first);
431 std::sort(variablePairs.begin(), variablePairs.end(),
432 [](std::pair<uint_fast64_t, storm::expressions::Variable>
const& a, std::pair<uint_fast64_t, storm::expressions::Variable>
const& b) {
433 return a.first < b.first;
437 std::vector<storm::expressions::Variable> result;
438 for (
auto const& element : variablePairs) {
439 result.push_back(element.second);
445template<DdType LibraryType>
447 internalDdManager.allowDynamicReordering(value);
450template<DdType LibraryType>
452 return internalDdManager.isDynamicReorderingAllowed();
455template<DdType LibraryType>
457 internalDdManager.triggerReordering();
460template<DdType LibraryType>
462 std::set<storm::expressions::Variable> result;
463 for (
auto const& variable : this->metaVariableMap) {
464 result.insert(variable.first);
469template<DdType LibraryType>
474template<DdType LibraryType>
476 std::vector<uint_fast64_t> ddVariableIndices;
477 for (
auto const& metaVariable : metaVariables) {
478 for (
auto const& ddVariable : metaVariableMap.at(metaVariable).getDdVariables()) {
479 ddVariableIndices.push_back(ddVariable.getIndex());
484 std::ranges::sort(ddVariableIndices);
485 return ddVariableIndices;
488template<DdType LibraryType>
490 return internalDdManager;
493template<DdType LibraryType>
495 return internalDdManager;
498template<DdType LibraryType>
500 return &internalDdManager;
503template<DdType LibraryType>
504InternalDdManager<LibraryType>
const* DdManager<LibraryType>::getInternalDdManagerPointer()
const {
505 return &internalDdManager;
508template<DdType LibraryType>
510 internalDdManager.debugCheck();
513template<DdType LibraryType>
515 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
std::shared_ptr< DdManager< LibraryType > > asSharedPointer()
static std::shared_ptr< DdManager< LibraryType > > createWithDefaultEnvironment()
Creates a new manager that is configured according to a default environment.
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.
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.
DdManager(storm::Environment const &env)
Creates an empty manager without any meta variables.
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)
TargetType convertNumber(SourceType const &number)
carl::RationalFunction< Polynomial, true > RationalFunction