12#include "storm-config.h"
20template<DdType LibraryType>
25template<DdType LibraryType>
27 return this->shared_from_this();
30template<DdType LibraryType>
32 return this->shared_from_this();
35template<DdType LibraryType>
40template<DdType LibraryType>
41template<
typename ValueType>
46template<DdType LibraryType>
51template<DdType LibraryType>
52template<
typename ValueType>
57template<DdType LibraryType>
58template<
typename ValueType>
63template<DdType LibraryType>
64template<
typename ValueType>
66 return getConstant(storm::utility::infinity<ValueType>());
69template<DdType LibraryType>
70template<
typename ValueType>
75template<DdType LibraryType>
80 "Illegal value " << value <<
" for meta variable '" << variable.
getName() <<
"'.");
83 value -= metaVariable.
getLow();
85 std::vector<Bdd<LibraryType>>
const& ddVariables = metaVariable.getDdVariables();
88 if (mostSignificantBitAtTop) {
89 if (value & (1ull << (ddVariables.size() - 1))) {
90 result = ddVariables[0];
92 result = !ddVariables[0];
95 for (std::size_t i = 1; i < ddVariables.size(); ++i) {
96 if (value & (1ull << (ddVariables.size() - i - 1))) {
97 result &= ddVariables[i];
99 result &= !ddVariables[i];
104 result = ddVariables[0];
106 result = !ddVariables[0];
110 for (std::size_t i = 1;
i < ddVariables.size(); ++
i) {
112 result &= ddVariables[
i];
114 result &= !ddVariables[i];
123template<DdType LibraryType>
129 internalDdManager.getBddEncodingLessOrEqualThan(
static_cast<uint64_t
>(metaVariable.
getHigh() - metaVariable.
getLow()),
140template<DdType LibraryType>
141template<
typename ValueType>
144 STORM_LOG_THROW(metaVariable.
hasHigh(), storm::exceptions::InvalidOperationException,
"Cannot create identity for meta variable.");
147 for (int_fast64_t value = metaVariable.
getLow(); value <= metaVariable.
getHigh(); ++value) {
148 result += this->getEncoding(variable, value).template toAdd<ValueType>() * this->getConstant(storm::utility::convertNumber<ValueType>(value));
153template<DdType LibraryType>
155 bool restrictToFirstRange)
const {
156 auto result = this->getBddOne();
157 for (
auto const& pair : variablePairs) {
158 result &= this->getIdentity(pair.first, pair.second, restrictToFirstRange);
163template<DdType LibraryType>
165 bool restrictToFirstRange)
const {
166 auto const& firstMetaVariable = this->getMetaVariable(first);
167 auto const& secondMetaVariable = this->getMetaVariable(second);
169 STORM_LOG_THROW(firstMetaVariable.getNumberOfDdVariables() == secondMetaVariable.getNumberOfDdVariables(), storm::exceptions::InvalidOperationException,
170 "Mismatching sizes of meta variables.");
172 auto const& firstDdVariables = firstMetaVariable.getDdVariables();
173 auto const& secondDdVariables = secondMetaVariable.getDdVariables();
175 auto result = restrictToFirstRange ? this->getRange(first) : this->getBddOne();
176 for (
auto it1 = firstDdVariables.begin(), it2 = secondDdVariables.begin(), ite1 = firstDdVariables.end(); it1 != ite1; ++it1, ++it2) {
177 result &= it1->
iff(*it2);
183#pragma GCC diagnostic push
184#pragma GCC diagnostic ignored "-Winfinite-recursion"
185template<DdType LibraryType>
187 return getCube({variable});
189#pragma GCC diagnostic pop
191template<DdType LibraryType>
194 for (
auto const& variable : variables) {
201template<DdType LibraryType>
203 std::string
const& newMetaVariableName,
204 boost::optional<uint64_t>
const& numberOfLayers) {
205 std::vector<storm::expressions::Variable> newMetaVariables;
206 auto const& ddMetaVariable = this->getMetaVariable(variable);
208 newMetaVariables = this->addMetaVariable(newMetaVariableName, 3);
210 newMetaVariables = this->addMetaVariable(newMetaVariableName, ddMetaVariable.getLow(), ddMetaVariable.getHigh(), 3);
212 newMetaVariables = this->addBitVectorMetaVariable(newMetaVariableName, ddMetaVariable.getNumberOfDdVariables(), 3);
214 return newMetaVariables;
217template<DdType LibraryType>
219 std::string
const& name, int_fast64_t low, int_fast64_t high,
220 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
221 std::vector<storm::expressions::Variable> result = addMetaVariable(name, low, high, 2, position);
222 return std::make_pair(result[0], result[1]);
225template<DdType LibraryType>
227 std::string
const& name, int_fast64_t low, int_fast64_t high, uint64_t numberOfLayers,
228 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
230 std::max(
static_cast<uint64_t
>(std::ceil(std::log2(high - low + 1))),
static_cast<uint64_t
>(1)), numberOfLayers,
231 position, std::make_pair(low, high));
234template<DdType LibraryType>
236 std::string
const& variableName, uint64_t bits, uint64_t numberOfLayers,
237 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
241template<DdType LibraryType>
243 std::string
const& name, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
244 std::vector<storm::expressions::Variable> result = this->addMetaVariableHelper(
MetaVariableType::Bool, name, 1, 2, position);
245 return std::make_pair(result[0], result[1]);
248template<DdType LibraryType>
250 std::string
const& name, uint64_t numberOfLayers, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
254template<DdType LibraryType>
256 MetaVariableType const& type, std::string
const& name, uint64_t numberOfDdVariables, uint64_t numberOfLayers,
257 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position,
258 boost::optional<std::pair<int_fast64_t, int_fast64_t>>
const& bounds) {
260 STORM_LOG_THROW(numberOfLayers >= 1, storm::exceptions::InvalidArgumentException,
"Layers must be at least 1.");
263 STORM_LOG_THROW(numberOfDdVariables >= 1, storm::exceptions::InvalidArgumentException,
"Illegal number of DD variables.");
266 STORM_LOG_THROW(name !=
"" && name.back() !=
'\'', storm::exceptions::InvalidArgumentException,
"Illegal name of meta variable: '" << name <<
"'.");
269 STORM_LOG_THROW(!this->hasMetaVariable(name), storm::exceptions::InvalidArgumentException,
"A meta variable '" << name <<
"' already exists.");
272 boost::optional<uint_fast64_t> level;
275 level = position.get().first ==
MetaVariablePosition::Above ? std::numeric_limits<uint_fast64_t>::max() : std::numeric_limits<uint_fast64_t>::min();
276 for (
auto const& ddVariable : beforeVariable.getDdVariables()) {
278 :
std::max(level.get(), ddVariable.getLevel());
285 STORM_LOG_TRACE(
"Creating meta variable with " << numberOfDdVariables <<
" bit(s) and " << numberOfLayers <<
" layer(s).");
287 std::stringstream tmp1;
288 std::vector<storm::expressions::Variable> result;
289 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
291 result.emplace_back(manager->declareIntegerVariable(name + tmp1.str()));
293 result.emplace_back(manager->declareBooleanVariable(name + tmp1.str()));
295 result.emplace_back(manager->declareBitVectorVariable(name + tmp1.str(), numberOfDdVariables));
300 std::vector<std::vector<Bdd<LibraryType>>> variables(numberOfLayers);
301 for (std::size_t i = 0; i < numberOfDdVariables; ++i) {
302 std::vector<InternalBdd<LibraryType>> ddVariables = internalDdManager.createDdVariables(numberOfLayers, level);
303 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
304 variables[layer].emplace_back(
Bdd<LibraryType>(*
this, ddVariables[layer], {result[layer]}));
310 level.get() += numberOfLayers;
314 std::stringstream tmp2;
315 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
317 metaVariableMap.emplace(result[layer],
DdMetaVariable<LibraryType>(name + tmp2.str(), bounds.get().first, bounds.get().second, variables[layer]));
327template<DdType LibraryType>
329 auto const& variablePair = metaVariableMap.find(variable);
332 STORM_LOG_THROW(variablePair != metaVariableMap.end(), storm::exceptions::InvalidArgumentException,
333 "Unknown meta variable name '" << variable.
getName() <<
"'.");
335 return variablePair->second;
338template<DdType LibraryType>
340 std::set<std::string> result;
341 for (
auto const& variablePair : metaVariableMap) {
342 result.insert(variablePair.first.getName());
347template<DdType LibraryType>
349 return this->metaVariableMap.size();
352template<DdType LibraryType>
354 return manager->hasVariable(metaVariableName);
357template<DdType LibraryType>
360 STORM_LOG_THROW(hasMetaVariable(metaVariableName), storm::exceptions::InvalidArgumentException,
"Unknown meta variable name '" << metaVariableName <<
"'.");
362 return manager->getVariable(metaVariableName);
365template<DdType LibraryType>
367 return internalDdManager.supportsOrderedInsertion();
370template<DdType LibraryType>
375template<DdType LibraryType>
380template<DdType LibraryType>
381std::vector<std::string> DdManager<LibraryType>::getDdVariableNames()
const {
383 std::vector<std::pair<uint_fast64_t, std::string>> variablePairs;
384 for (
auto const& variablePair : this->metaVariableMap) {
385 DdMetaVariable<LibraryType>
const& metaVariable = variablePair.second;
388 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first.getName());
391 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
392 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(),
393 variablePair.first.getName() +
'.' + std::to_string(variableIndex));
399 std::sort(variablePairs.begin(), variablePairs.end(),
400 [](std::pair<uint_fast64_t, std::string>
const& a, std::pair<uint_fast64_t, std::string>
const& b) { return a.first < b.first; });
403 std::vector<std::string> result;
404 for (
auto const& element : variablePairs) {
405 result.push_back(element.second);
411template<DdType LibraryType>
412std::vector<storm::expressions::Variable> DdManager<LibraryType>::getDdVariables()
const {
414 std::vector<std::pair<uint_fast64_t, storm::expressions::Variable>> variablePairs;
415 for (
auto const& variablePair : this->metaVariableMap) {
416 DdMetaVariable<LibraryType>
const& metaVariable = variablePair.second;
419 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first);
422 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
423 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(), variablePair.first);
429 std::sort(variablePairs.begin(), variablePairs.end(),
430 [](std::pair<uint_fast64_t, storm::expressions::Variable>
const& a, std::pair<uint_fast64_t, storm::expressions::Variable>
const& b) {
431 return a.first < b.first;
435 std::vector<storm::expressions::Variable> result;
436 for (
auto const& element : variablePairs) {
437 result.push_back(element.second);
443template<DdType LibraryType>
445 internalDdManager.allowDynamicReordering(value);
448template<DdType LibraryType>
450 return internalDdManager.isDynamicReorderingAllowed();
453template<DdType LibraryType>
455 internalDdManager.triggerReordering();
458template<DdType LibraryType>
460 std::set<storm::expressions::Variable> result;
461 for (
auto const& variable : this->metaVariableMap) {
462 result.insert(variable.first);
467template<DdType LibraryType>
469 return this->getSortedVariableIndices(this->getAllMetaVariables());
472template<DdType LibraryType>
474 std::vector<uint_fast64_t> ddVariableIndices;
475 for (
auto const& metaVariable : metaVariables) {
476 for (
auto const& ddVariable : metaVariableMap.at(metaVariable).getDdVariables()) {
477 ddVariableIndices.push_back(ddVariable.getIndex());
482 std::sort(ddVariableIndices.begin(), ddVariableIndices.end());
483 return ddVariableIndices;
486template<DdType LibraryType>
488 return internalDdManager;
491template<DdType LibraryType>
493 return internalDdManager;
496template<DdType LibraryType>
498 return &internalDdManager;
501template<DdType LibraryType>
502InternalDdManager<LibraryType>
const* DdManager<LibraryType>::getInternalDdManagerPointer()
const {
503 return &internalDdManager;
506template<DdType LibraryType>
511template<DdType LibraryType>
513 internalDdManager.execute(f);
521#ifdef STORM_HAVE_CARL
528#ifdef STORM_HAVE_CARL
538#ifdef STORM_HAVE_CARL
549#ifdef STORM_HAVE_CARL
556#ifdef STORM_HAVE_CARL
563#ifdef STORM_HAVE_CARL
570#ifdef STORM_HAVE_CARL
577#ifdef STORM_HAVE_CARL
584#ifdef STORM_HAVE_CARL
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 > getInfinity() const
Retrieves an ADD representing the constant infinity 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()
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...
Add< LibraryType, ValueType > getAddZero() const
Retrieves an ADD representing the constant zero function.
std::set< storm::expressions::Variable > getAllMetaVariables() const
Retrieves the set of meta variables contained in the DD.
Add< LibraryType, ValueType > getAddUndefined() const
Retrieves an ADD representing an undefined value.
Add< LibraryType, ValueType > getAddOne() const
Retrieves an ADD representing the constant one function.
InternalDdManager< LibraryType > & getInternalDdManager()
Retrieves the internal DD manager.
Add< LibraryType, ValueType > getConstant(ValueType const &value) const
Retrieves an ADD representing the constant function with the given value.
Bdd< LibraryType > getCube(storm::expressions::Variable const &variable) const
Retrieves a BDD that is the cube of the variables representing the given meta variable.
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...
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).
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 or not 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)