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#if defined(__clang__)
184#pragma clang diagnostic push
185#pragma clang diagnostic ignored "-Winfinite-recursion"
188template<DdType LibraryType>
190 return getCube({variable});
193#if defined(__clang__)
194#pragma clang diagnostic pop
197template<DdType LibraryType>
200 for (
auto const& variable : variables) {
202 result &= metaVariable.
getCube();
207template<DdType LibraryType>
209 std::string
const& newMetaVariableName,
210 boost::optional<uint64_t>
const& numberOfLayers) {
211 std::vector<storm::expressions::Variable> newMetaVariables;
212 auto const& ddMetaVariable = this->getMetaVariable(variable);
214 newMetaVariables = this->addMetaVariable(newMetaVariableName, 3);
216 newMetaVariables = this->addMetaVariable(newMetaVariableName, ddMetaVariable.getLow(), ddMetaVariable.getHigh(), 3);
218 newMetaVariables = this->addBitVectorMetaVariable(newMetaVariableName, ddMetaVariable.getNumberOfDdVariables(), 3);
220 return newMetaVariables;
223template<DdType LibraryType>
225 std::string
const& name, int_fast64_t low, int_fast64_t high,
226 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
227 std::vector<storm::expressions::Variable> result = addMetaVariable(name, low, high, 2, position);
228 return std::make_pair(result[0], result[1]);
231template<DdType LibraryType>
233 std::string
const& name, int_fast64_t low, int_fast64_t high, uint64_t numberOfLayers,
234 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
236 std::max(
static_cast<uint64_t
>(std::ceil(std::log2(high - low + 1))),
static_cast<uint64_t
>(1)), numberOfLayers,
237 position, std::make_pair(low, high));
240template<DdType LibraryType>
242 std::string
const& variableName, uint64_t bits, uint64_t numberOfLayers,
243 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
247template<DdType LibraryType>
249 std::string
const& name, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
250 std::vector<storm::expressions::Variable> result = this->addMetaVariableHelper(
MetaVariableType::Bool, name, 1, 2, position);
251 return std::make_pair(result[0], result[1]);
254template<DdType LibraryType>
256 std::string
const& name, uint64_t numberOfLayers, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position) {
260template<DdType LibraryType>
262 MetaVariableType const& type, std::string
const& name, uint64_t numberOfDdVariables, uint64_t numberOfLayers,
263 boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>>
const& position,
264 boost::optional<std::pair<int_fast64_t, int_fast64_t>>
const& bounds) {
266 STORM_LOG_THROW(numberOfLayers >= 1, storm::exceptions::InvalidArgumentException,
"Layers must be at least 1.");
269 STORM_LOG_THROW(numberOfDdVariables >= 1, storm::exceptions::InvalidArgumentException,
"Illegal number of DD variables.");
272 STORM_LOG_THROW(name !=
"" && name.back() !=
'\'', storm::exceptions::InvalidArgumentException,
"Illegal name of meta variable: '" << name <<
"'.");
275 STORM_LOG_THROW(!this->hasMetaVariable(name), storm::exceptions::InvalidArgumentException,
"A meta variable '" << name <<
"' already exists.");
278 boost::optional<uint_fast64_t> level;
281 level = position.get().first ==
MetaVariablePosition::Above ? std::numeric_limits<uint_fast64_t>::max() : std::numeric_limits<uint_fast64_t>::min();
282 for (
auto const& ddVariable : beforeVariable.getDdVariables()) {
284 :
std::max(level.get(), ddVariable.getLevel());
291 STORM_LOG_TRACE(
"Creating meta variable with " << numberOfDdVariables <<
" bit(s) and " << numberOfLayers <<
" layer(s).");
293 std::stringstream tmp1;
294 std::vector<storm::expressions::Variable> result;
295 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
297 result.emplace_back(manager->declareIntegerVariable(name + tmp1.str()));
299 result.emplace_back(manager->declareBooleanVariable(name + tmp1.str()));
301 result.emplace_back(manager->declareBitVectorVariable(name + tmp1.str(), numberOfDdVariables));
306 std::vector<std::vector<Bdd<LibraryType>>> variables(numberOfLayers);
307 for (std::size_t i = 0; i < numberOfDdVariables; ++i) {
308 std::vector<InternalBdd<LibraryType>> ddVariables = internalDdManager.createDdVariables(numberOfLayers, level);
309 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
310 variables[layer].emplace_back(
Bdd<LibraryType>(*
this, ddVariables[layer], {result[layer]}));
316 level.get() += numberOfLayers;
320 std::stringstream tmp2;
321 for (uint64_t layer = 0; layer < numberOfLayers; ++layer) {
323 metaVariableMap.emplace(result[layer],
DdMetaVariable<LibraryType>(name + tmp2.str(), bounds.get().first, bounds.get().second, variables[layer]));
333template<DdType LibraryType>
335 auto const& variablePair = metaVariableMap.find(variable);
338 STORM_LOG_THROW(variablePair != metaVariableMap.end(), storm::exceptions::InvalidArgumentException,
339 "Unknown meta variable name '" << variable.
getName() <<
"'.");
341 return variablePair->second;
344template<DdType LibraryType>
346 std::set<std::string> result;
347 for (
auto const& variablePair : metaVariableMap) {
348 result.insert(variablePair.first.getName());
353template<DdType LibraryType>
355 return this->metaVariableMap.size();
358template<DdType LibraryType>
360 return manager->hasVariable(metaVariableName);
363template<DdType LibraryType>
366 STORM_LOG_THROW(hasMetaVariable(metaVariableName), storm::exceptions::InvalidArgumentException,
"Unknown meta variable name '" << metaVariableName <<
"'.");
368 return manager->getVariable(metaVariableName);
371template<DdType LibraryType>
373 return internalDdManager.supportsOrderedInsertion();
376template<DdType LibraryType>
381template<DdType LibraryType>
386template<DdType LibraryType>
387std::vector<std::string> DdManager<LibraryType>::getDdVariableNames()
const {
389 std::vector<std::pair<uint_fast64_t, std::string>> variablePairs;
390 for (
auto const& variablePair : this->metaVariableMap) {
391 DdMetaVariable<LibraryType>
const& metaVariable = variablePair.second;
394 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first.getName());
397 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
398 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(),
399 variablePair.first.getName() +
'.' + std::to_string(variableIndex));
405 std::sort(variablePairs.begin(), variablePairs.end(),
406 [](std::pair<uint_fast64_t, std::string>
const& a, std::pair<uint_fast64_t, std::string>
const& b) { return a.first < b.first; });
409 std::vector<std::string> result;
410 for (
auto const& element : variablePairs) {
411 result.push_back(element.second);
417template<DdType LibraryType>
418std::vector<storm::expressions::Variable> DdManager<LibraryType>::getDdVariables()
const {
420 std::vector<std::pair<uint_fast64_t, storm::expressions::Variable>> variablePairs;
421 for (
auto const& variablePair : this->metaVariableMap) {
422 DdMetaVariable<LibraryType>
const& metaVariable = variablePair.second;
425 variablePairs.emplace_back(metaVariable.getDdVariables().front().getIndex(), variablePair.first);
428 for (uint_fast64_t variableIndex = 0; variableIndex < metaVariable.getNumberOfDdVariables(); ++variableIndex) {
429 variablePairs.emplace_back(metaVariable.getDdVariables()[variableIndex].getIndex(), variablePair.first);
435 std::sort(variablePairs.begin(), variablePairs.end(),
436 [](std::pair<uint_fast64_t, storm::expressions::Variable>
const& a, std::pair<uint_fast64_t, storm::expressions::Variable>
const& b) {
437 return a.first < b.first;
441 std::vector<storm::expressions::Variable> result;
442 for (
auto const& element : variablePairs) {
443 result.push_back(element.second);
449template<DdType LibraryType>
451 internalDdManager.allowDynamicReordering(value);
454template<DdType LibraryType>
456 return internalDdManager.isDynamicReorderingAllowed();
459template<DdType LibraryType>
461 internalDdManager.triggerReordering();
464template<DdType LibraryType>
466 std::set<storm::expressions::Variable> result;
467 for (
auto const& variable : this->metaVariableMap) {
468 result.insert(variable.first);
473template<DdType LibraryType>
475 return this->getSortedVariableIndices(this->getAllMetaVariables());
478template<DdType LibraryType>
480 std::vector<uint_fast64_t> ddVariableIndices;
481 for (
auto const& metaVariable : metaVariables) {
482 for (
auto const& ddVariable : metaVariableMap.at(metaVariable).getDdVariables()) {
483 ddVariableIndices.push_back(ddVariable.getIndex());
488 std::sort(ddVariableIndices.begin(), ddVariableIndices.end());
489 return ddVariableIndices;
492template<DdType LibraryType>
494 return internalDdManager;
497template<DdType LibraryType>
499 return internalDdManager;
502template<DdType LibraryType>
504 return &internalDdManager;
507template<DdType LibraryType>
508InternalDdManager<LibraryType>
const* DdManager<LibraryType>::getInternalDdManagerPointer()
const {
509 return &internalDdManager;
512template<DdType LibraryType>
517template<DdType LibraryType>
519 internalDdManager.execute(f);
527#ifdef STORM_HAVE_CARL
534#ifdef STORM_HAVE_CARL
544#ifdef STORM_HAVE_CARL
555#ifdef STORM_HAVE_CARL
562#ifdef STORM_HAVE_CARL
569#ifdef STORM_HAVE_CARL
576#ifdef STORM_HAVE_CARL
583#ifdef STORM_HAVE_CARL
590#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)