Browse Source

ADDs and BDDs are no longer mixed in the abstraction layer.

Former-commit-id: 3c31063ea6
main
dehnert 10 years ago
parent
commit
60701cebdb
  1. 70
      src/adapters/AddExpressionAdapter.cpp
  2. 8
      src/adapters/AddExpressionAdapter.h
  3. 179
      src/builder/DdPrismModelBuilder.cpp
  4. 64
      src/builder/DdPrismModelBuilder.h
  5. 2
      src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp
  6. 2
      src/modelchecker/results/SymbolicQualitativeCheckResult.cpp
  7. 8
      src/modelchecker/results/SymbolicQualitativeCheckResult.h
  8. 2
      src/modelchecker/results/SymbolicQuantitativeCheckResult.cpp
  9. 8
      src/modelchecker/results/SymbolicQuantitativeCheckResult.h
  10. 14
      src/models/symbolic/DeterministicModel.cpp
  11. 14
      src/models/symbolic/DeterministicModel.h
  12. 14
      src/models/symbolic/Dtmc.cpp
  13. 14
      src/models/symbolic/Dtmc.h
  14. 14
      src/models/symbolic/Mdp.cpp
  15. 14
      src/models/symbolic/Mdp.h
  16. 34
      src/models/symbolic/Model.cpp
  17. 50
      src/models/symbolic/Model.h
  18. 18
      src/models/symbolic/NondeterministicModel.cpp
  19. 18
      src/models/symbolic/NondeterministicModel.h
  20. 846
      src/storage/dd/CuddAdd.cpp
  21. 556
      src/storage/dd/CuddAdd.h
  22. 138
      src/storage/dd/CuddBdd.cpp
  23. 12
      src/storage/dd/CuddBdd.h
  24. 14
      src/storage/dd/CuddDd.cpp
  25. 7
      src/storage/dd/CuddDd.h
  26. 4
      src/storage/dd/CuddDdForwardIterator.h
  27. 69
      src/storage/dd/CuddDdManager.cpp
  28. 51
      src/storage/dd/CuddDdManager.h
  29. 15
      src/storage/dd/CuddDdMetaVariable.cpp
  30. 29
      src/storage/dd/CuddDdMetaVariable.h
  31. 8
      src/storage/dd/CuddOdd.cpp
  32. 6
      src/storage/dd/CuddOdd.h
  33. 155
      src/utility/graph.h
  34. 182
      test/functional/storage/CuddDdTest.cpp
  35. 4
      test/functional/utility/GraphTest.cpp

70
src/adapters/DdExpressionAdapter.cpp → src/adapters/AddExpressionAdapter.cpp

@ -1,4 +1,4 @@
#include "src/adapters/DdExpressionAdapter.h"
#include "src/adapters/AddExpressionAdapter.h"
#include "src/utility/macros.h"
#include "src/exceptions/ExpressionEvaluationException.h"
@ -9,44 +9,44 @@ namespace storm {
namespace adapters {
template<storm::dd::DdType Type>
DdExpressionAdapter<Type>::DdExpressionAdapter(std::shared_ptr<storm::dd::DdManager<Type>> ddManager, std::map<storm::expressions::Variable, storm::expressions::Variable> const& variableMapping) : ddManager(ddManager), variableMapping(variableMapping) {
AddExpressionAdapter<Type>::AddExpressionAdapter(std::shared_ptr<storm::dd::DdManager<Type>> ddManager, std::map<storm::expressions::Variable, storm::expressions::Variable> const& variableMapping) : ddManager(ddManager), variableMapping(variableMapping) {
// Intentionally left empty.
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type> DdExpressionAdapter<Type>::translateExpression(storm::expressions::Expression const& expression) {
return boost::any_cast<storm::dd::Dd<Type>>(expression.accept(*this));
storm::dd::Add<Type> AddExpressionAdapter<Type>::translateExpression(storm::expressions::Expression const& expression) {
return boost::any_cast<storm::dd::Add<Type>>(expression.accept(*this));
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::IfThenElseExpression const& expression) {
storm::dd::Dd<Type> elseDd = boost::any_cast<storm::dd::Dd<Type>>(expression.getElseExpression()->accept(*this));
storm::dd::Dd<Type> thenDd = boost::any_cast<storm::dd::Dd<Type>>(expression.getThenExpression()->accept(*this));
storm::dd::Dd<Type> conditionDd = boost::any_cast<storm::dd::Dd<Type>>(expression.getCondition()->accept(*this));
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::IfThenElseExpression const& expression) {
storm::dd::Add<Type> elseDd = boost::any_cast<storm::dd::Add<Type>>(expression.getElseExpression()->accept(*this));
storm::dd::Add<Type> thenDd = boost::any_cast<storm::dd::Add<Type>>(expression.getThenExpression()->accept(*this));
storm::dd::Add<Type> conditionDd = boost::any_cast<storm::dd::Add<Type>>(expression.getCondition()->accept(*this));
return conditionDd.ite(thenDd, elseDd);
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::BinaryBooleanFunctionExpression const& expression) {
storm::dd::Dd<Type> leftResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getFirstOperand()->accept(*this));
storm::dd::Dd<Type> rightResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getSecondOperand()->accept(*this));
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::BinaryBooleanFunctionExpression const& expression) {
storm::dd::Bdd<Type> leftResult = boost::any_cast<storm::dd::Add<Type>>(expression.getFirstOperand()->accept(*this)).toBdd();
storm::dd::Bdd<Type> rightResult = boost::any_cast<storm::dd::Add<Type>>(expression.getSecondOperand()->accept(*this)).toBdd();
storm::dd::Dd<Type> result;
storm::dd::Add<Type> result;
switch (expression.getOperatorType()) {
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And:
result = leftResult && rightResult;
result = (leftResult && rightResult).toAdd();
break;
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Or:
result = leftResult || rightResult;
result = (leftResult || rightResult).toAdd();
break;
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff:
result = leftResult.iff(rightResult);
result = (leftResult.iff(rightResult)).toAdd();
break;
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Implies:
result = !leftResult || rightResult;
result = (!leftResult || rightResult).toAdd();
break;
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Xor:
result = leftResult.exclusiveOr(rightResult);
result = (leftResult.exclusiveOr(rightResult)).toAdd();
break;
}
@ -54,11 +54,11 @@ namespace storm {
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::BinaryNumericalFunctionExpression const& expression) {
storm::dd::Dd<Type> leftResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getFirstOperand()->accept(*this));
storm::dd::Dd<Type> rightResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getSecondOperand()->accept(*this));
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::BinaryNumericalFunctionExpression const& expression) {
storm::dd::Add<Type> leftResult = boost::any_cast<storm::dd::Add<Type>>(expression.getFirstOperand()->accept(*this));
storm::dd::Add<Type> rightResult = boost::any_cast<storm::dd::Add<Type>>(expression.getSecondOperand()->accept(*this));
storm::dd::Dd<Type> result;
storm::dd::Add<Type> result;
switch (expression.getOperatorType()) {
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Plus:
result = leftResult + rightResult;
@ -86,11 +86,11 @@ namespace storm {
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::BinaryRelationExpression const& expression) {
storm::dd::Dd<Type> leftResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getFirstOperand()->accept(*this));
storm::dd::Dd<Type> rightResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getSecondOperand()->accept(*this));
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::BinaryRelationExpression const& expression) {
storm::dd::Add<Type> leftResult = boost::any_cast<storm::dd::Add<Type>>(expression.getFirstOperand()->accept(*this));
storm::dd::Add<Type> rightResult = boost::any_cast<storm::dd::Add<Type>>(expression.getSecondOperand()->accept(*this));
storm::dd::Dd<Type> result;
storm::dd::Add<Type> result;
switch (expression.getRelationType()) {
case storm::expressions::BinaryRelationExpression::RelationType::Equal:
result = leftResult.equals(rightResult);
@ -116,15 +116,15 @@ namespace storm {
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::VariableExpression const& expression) {
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::VariableExpression const& expression) {
auto const& variablePair = variableMapping.find(expression.getVariable());
STORM_LOG_THROW(variablePair != variableMapping.end(), storm::exceptions::InvalidArgumentException, "Cannot translate the given expression, because it contains the variable '" << expression.getVariableName() << "' for which no DD counterpart is known.");
return ddManager->getIdentity(variablePair->second);
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::UnaryBooleanFunctionExpression const& expression) {
storm::dd::Dd<Type> result = boost::any_cast<storm::dd::Dd<Type>>(expression.getOperand()->accept(*this));
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::UnaryBooleanFunctionExpression const& expression) {
storm::dd::Bdd<Type> result = boost::any_cast<storm::dd::Add<Type>>(expression.getOperand()->accept(*this)).toBdd();
switch (expression.getOperatorType()) {
case storm::expressions::UnaryBooleanFunctionExpression::OperatorType::Not:
@ -132,12 +132,12 @@ namespace storm {
break;
}
return result;
return result.toAdd();
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::UnaryNumericalFunctionExpression const& expression) {
storm::dd::Dd<Type> result = boost::any_cast<storm::dd::Dd<Type>>(expression.getOperand()->accept(*this));
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::UnaryNumericalFunctionExpression const& expression) {
storm::dd::Add<Type> result = boost::any_cast<storm::dd::Add<Type>>(expression.getOperand()->accept(*this));
switch (expression.getOperatorType()) {
case storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Minus:
@ -151,22 +151,22 @@ namespace storm {
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::BooleanLiteralExpression const& expression) {
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::BooleanLiteralExpression const& expression) {
return ddManager->getConstant(expression.getValue());
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::IntegerLiteralExpression const& expression) {
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::IntegerLiteralExpression const& expression) {
return ddManager->getConstant(expression.getValue());
}
template<storm::dd::DdType Type>
boost::any DdExpressionAdapter<Type>::visit(storm::expressions::DoubleLiteralExpression const& expression) {
boost::any AddExpressionAdapter<Type>::visit(storm::expressions::DoubleLiteralExpression const& expression) {
return ddManager->getConstant(expression.getValue());
}
// Explicitly instantiate the symbolic expression adapter
template class DdExpressionAdapter<storm::dd::DdType::CUDD>;
template class AddExpressionAdapter<storm::dd::DdType::CUDD>;
} // namespace adapters
} // namespace storm

8
src/adapters/DdExpressionAdapter.h → src/adapters/AddExpressionAdapter.h

@ -5,18 +5,18 @@
#include "src/storage/expressions/Expressions.h"
#include "storage/expressions/ExpressionVisitor.h"
#include "src/storage/dd/Dd.h"
#include "src/storage/dd/Add.h"
#include "src/storage/dd/DdManager.h"
namespace storm {
namespace adapters {
template<storm::dd::DdType Type>
class DdExpressionAdapter : public storm::expressions::ExpressionVisitor {
class AddExpressionAdapter : public storm::expressions::ExpressionVisitor {
public:
DdExpressionAdapter(std::shared_ptr<storm::dd::DdManager<Type>> ddManager, std::map<storm::expressions::Variable, storm::expressions::Variable> const& variableMapping);
AddExpressionAdapter(std::shared_ptr<storm::dd::DdManager<Type>> ddManager, std::map<storm::expressions::Variable, storm::expressions::Variable> const& variableMapping);
storm::dd::Dd<Type> translateExpression(storm::expressions::Expression const& expression);
storm::dd::Add<Type> translateExpression(storm::expressions::Expression const& expression);
virtual boost::any visit(storm::expressions::IfThenElseExpression const& expression) override;
virtual boost::any visit(storm::expressions::BinaryBooleanFunctionExpression const& expression) override;

179
src/builder/DdPrismModelBuilder.cpp

@ -52,8 +52,8 @@ namespace storm {
}
template <storm::dd::DdType Type>
storm::dd::Dd<Type> DdPrismModelBuilder<Type>::createUpdateDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::dd::Dd<Type> const& guard, storm::prism::Update const& update) {
storm::dd::Dd<Type> updateDd = generationInfo.manager->getOne(true);
storm::dd::Add<Type> DdPrismModelBuilder<Type>::createUpdateDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::dd::Add<Type> const& guard, storm::prism::Update const& update) {
storm::dd::Add<Type> updateDd = generationInfo.manager->getAddOne();
STORM_LOG_TRACE("Translating update " << update);
@ -67,20 +67,20 @@ namespace storm {
// Translate the written variable.
auto const& primedMetaVariable = generationInfo.variableToColumnMetaVariableMap.at(assignment.getVariable());
storm::dd::Dd<Type> writtenVariable = generationInfo.manager->getIdentity(primedMetaVariable);
storm::dd::Add<Type> writtenVariable = generationInfo.manager->getIdentity(primedMetaVariable);
// Translate the expression that is being assigned.
storm::dd::Dd<Type> updateExpression = generationInfo.rowExpressionAdapter->translateExpression(assignment.getExpression());
storm::dd::Add<Type> updateExpression = generationInfo.rowExpressionAdapter->translateExpression(assignment.getExpression());
// Combine the update expression with the guard.
storm::dd::Dd<Type> result = updateExpression * guard;
storm::dd::Add<Type> result = updateExpression * guard;
// Combine the variable and the assigned expression.
result = result.equals(writtenVariable);
result *= guard;
// Restrict the transitions to the range of the written variable.
result = result * generationInfo.manager->getRange(primedMetaVariable, true);
result = result * generationInfo.manager->getRange(primedMetaVariable).toAdd();
updateDd *= result;
}
@ -129,17 +129,17 @@ namespace storm {
template <storm::dd::DdType Type>
typename DdPrismModelBuilder<Type>::ActionDecisionDiagram DdPrismModelBuilder<Type>::createCommandDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::prism::Command const& command) {
STORM_LOG_TRACE("Translating guard " << command.getGuardExpression());
storm::dd::Dd<Type> guardDd = generationInfo.rowExpressionAdapter->translateExpression(command.getGuardExpression()) * generationInfo.moduleToRangeMap[module.getName()];
storm::dd::Add<Type> guardDd = generationInfo.rowExpressionAdapter->translateExpression(command.getGuardExpression()) * generationInfo.moduleToRangeMap[module.getName()];
STORM_LOG_WARN_COND(!guardDd.isZero(), "The guard '" << command.getGuardExpression() << "' is unsatisfiable.");
if (!guardDd.isZero()) {
storm::dd::Dd<Type> commandDd = generationInfo.manager->getZero(true);
storm::dd::Add<Type> commandDd = generationInfo.manager->getAddZero();
for (storm::prism::Update const& update : command.getUpdates()) {
storm::dd::Dd<Type> updateDd = createUpdateDecisionDiagram(generationInfo, module, guardDd, update);
storm::dd::Add<Type> updateDd = createUpdateDecisionDiagram(generationInfo, module, guardDd, update);
STORM_LOG_WARN_COND(!updateDd.isZero(), "Update '" << update << "' does not have any effect.");
storm::dd::Dd<Type> probabilityDd = generationInfo.rowExpressionAdapter->translateExpression(update.getLikelihoodExpression());
storm::dd::Add<Type> probabilityDd = generationInfo.rowExpressionAdapter->translateExpression(update.getLikelihoodExpression());
updateDd *= probabilityDd;
commandDd += updateDd;
@ -186,9 +186,9 @@ namespace storm {
template <storm::dd::DdType Type>
typename DdPrismModelBuilder<Type>::ActionDecisionDiagram DdPrismModelBuilder<Type>::combineCommandsToActionDTMC(GenerationInformation& generationInfo, std::vector<ActionDecisionDiagram> const& commandDds) {
storm::dd::Dd<Type> allGuards = generationInfo.manager->getZero(true);
storm::dd::Dd<Type> allCommands = generationInfo.manager->getZero(true);
storm::dd::Dd<Type> temporary;
storm::dd::Add<Type> allGuards = generationInfo.manager->getAddZero();
storm::dd::Add<Type> allCommands = generationInfo.manager->getAddZero();
storm::dd::Add<Type> temporary;
for (auto const& commandDd : commandDds) {
// Check for overlapping guards.
@ -203,8 +203,8 @@ namespace storm {
}
template <storm::dd::DdType Type>
storm::dd::Dd<Type> DdPrismModelBuilder<Type>::encodeChoice(GenerationInformation& generationInfo, uint_fast64_t nondeterminismVariableOffset, uint_fast64_t numberOfBinaryVariables, int_fast64_t value) {
storm::dd::Dd<Type> result = generationInfo.manager->getZero(true);
storm::dd::Add<Type> DdPrismModelBuilder<Type>::encodeChoice(GenerationInformation& generationInfo, uint_fast64_t nondeterminismVariableOffset, uint_fast64_t numberOfBinaryVariables, int_fast64_t value) {
storm::dd::Add<Type> result = generationInfo.manager->getAddZero();
STORM_LOG_TRACE("Encoding " << value << " with " << numberOfBinaryVariables << " binary variable(s) starting from offset " << nondeterminismVariableOffset << ".");
@ -223,11 +223,11 @@ namespace storm {
template <storm::dd::DdType Type>
typename DdPrismModelBuilder<Type>::ActionDecisionDiagram DdPrismModelBuilder<Type>::combineCommandsToActionMDP(GenerationInformation& generationInfo, std::vector<ActionDecisionDiagram> const& commandDds, uint_fast64_t nondeterminismVariableOffset) {
storm::dd::Dd<Type> allGuards = generationInfo.manager->getZero(true);
storm::dd::Dd<Type> allCommands = generationInfo.manager->getZero(true);
storm::dd::Add<Type> allGuards = generationInfo.manager->getAddZero();
storm::dd::Add<Type> allCommands = generationInfo.manager->getAddZero();
// Sum all guards, so we can read off the maximal number of nondeterministic choices in any given state.
storm::dd::Dd<Type> sumOfGuards = generationInfo.manager->getZero(true);
storm::dd::Add<Type> sumOfGuards = generationInfo.manager->getAddZero();
for (auto const& commandDd : commandDds) {
sumOfGuards += commandDd.guardDd;
allGuards = allGuards || commandDd.guardDd;
@ -242,17 +242,16 @@ namespace storm {
} else if (maxChoices == 1) {
// Sum up all commands.
for (auto const& commandDd : commandDds) {
// FIXME: necessary to multiply with guard again?
allCommands += commandDd.guardDd * commandDd.transitionsDd;
allCommands += commandDd.transitionsDd;
}
return ActionDecisionDiagram(sumOfGuards, allCommands);
} else {
// Calculate number of required variables to encode the nondeterminism.
uint_fast64_t numberOfBinaryVariables = static_cast<uint_fast64_t>(std::ceil(storm::utility::math::log2(maxChoices)));
storm::dd::Dd<Type> equalsNumberOfChoicesDd = generationInfo.manager->getZero(true);
std::vector<storm::dd::Dd<Type>> choiceDds(maxChoices, generationInfo.manager->getZero(true));
std::vector<storm::dd::Dd<Type>> remainingDds(maxChoices, generationInfo.manager->getZero(true));
storm::dd::Add<Type> equalsNumberOfChoicesDd = generationInfo.manager->getAddZero();
std::vector<storm::dd::Add<Type>> choiceDds(maxChoices, generationInfo.manager->getAddZero());
std::vector<storm::dd::Add<Type>> remainingDds(maxChoices, generationInfo.manager->getAddZero());
for (uint_fast64_t currentChoices = 1; currentChoices <= maxChoices; ++currentChoices) {
// Determine the set of states with exactly currentChoices choices.
@ -265,14 +264,14 @@ namespace storm {
// Reset the previously used intermediate storage.
for (uint_fast64_t j = 0; j < currentChoices; ++j) {
choiceDds[j] = generationInfo.manager->getZero(true);
choiceDds[j] = generationInfo.manager->getAddZero();
remainingDds[j] = equalsNumberOfChoicesDd;
}
for (std::size_t j = 0; j < commandDds.size(); ++j) {
// Check if command guard overlaps with equalsNumberOfChoicesDd. That is, there are states with exactly currentChoices
// choices such that one outgoing choice is given by the j-th command.
storm::dd::Dd<Type> guardChoicesIntersection = commandDds[j].guardDd && equalsNumberOfChoicesDd;
storm::dd::Add<Type> guardChoicesIntersection = commandDds[j].guardDd * equalsNumberOfChoicesDd;
// If there is no such state, continue with the next command.
if (guardChoicesIntersection.isZero()) {
@ -282,19 +281,19 @@ namespace storm {
// Split the currentChoices nondeterministic choices.
for (uint_fast64_t k = 0; k < currentChoices; ++k) {
// Calculate the overlapping part of command guard and the remaining DD.
storm::dd::Dd<Type> remainingGuardChoicesIntersection = guardChoicesIntersection && remainingDds[k];
storm::dd::Add<Type> remainingGuardChoicesIntersection = guardChoicesIntersection * remainingDds[k];
// Check if we can add some overlapping parts to the current index.
if (!remainingGuardChoicesIntersection.isZero()) {
// Remove overlapping parts from the remaining DD.
remainingDds[k] = remainingDds[k] && !remainingGuardChoicesIntersection;
remainingDds[k] = remainingDds[k] * !remainingGuardChoicesIntersection;
// Combine the overlapping part of the guard with command updates and add it to the resulting DD.
choiceDds[k] += remainingGuardChoicesIntersection * commandDds[j].transitionsDd;
}
// Remove overlapping parts from the command guard DD
guardChoicesIntersection = guardChoicesIntersection && !remainingGuardChoicesIntersection;
guardChoicesIntersection = guardChoicesIntersection * !remainingGuardChoicesIntersection;
// If the guard DD has become equivalent to false, we can stop here.
if (guardChoicesIntersection.isZero()) {
@ -309,7 +308,7 @@ namespace storm {
}
// Delete currentChoices out of overlapping DD
sumOfGuards = sumOfGuards * (!equalsNumberOfChoicesDd);
sumOfGuards = sumOfGuards * !equalsNumberOfChoicesDd;
}
return ActionDecisionDiagram(allGuards, allCommands, nondeterminismVariableOffset + numberOfBinaryVariables);
@ -322,9 +321,9 @@ namespace storm {
}
template <storm::dd::DdType Type>
typename DdPrismModelBuilder<Type>::ActionDecisionDiagram DdPrismModelBuilder<Type>::combineUnsynchronizedActions(GenerationInformation const& generationInfo, ActionDecisionDiagram const& action1, ActionDecisionDiagram const& action2, storm::dd::Dd<Type> const& identityDd1, storm::dd::Dd<Type> const& identityDd2) {
storm::dd::Dd<Type> action1Extended = action1.transitionsDd * identityDd2;
storm::dd::Dd<Type> action2Extended = action2.transitionsDd * identityDd1;
typename DdPrismModelBuilder<Type>::ActionDecisionDiagram DdPrismModelBuilder<Type>::combineUnsynchronizedActions(GenerationInformation const& generationInfo, ActionDecisionDiagram const& action1, ActionDecisionDiagram const& action2, storm::dd::Add<Type> const& identityDd1, storm::dd::Add<Type> const& identityDd2) {
storm::dd::Add<Type> action1Extended = action1.transitionsDd * identityDd2;
storm::dd::Add<Type> action2Extended = action2.transitionsDd * identityDd1;
if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) {
return ActionDecisionDiagram(action1.guardDd + action2.guardDd, action1Extended + action2Extended, 0);
@ -338,23 +337,23 @@ namespace storm {
// Bring both choices to the same number of variables that encode the nondeterminism.
uint_fast64_t numberOfUsedNondeterminismVariables = std::max(action1.numberOfUsedNondeterminismVariables, action2.numberOfUsedNondeterminismVariables);
if (action1.numberOfUsedNondeterminismVariables > action2.numberOfUsedNondeterminismVariables) {
storm::dd::Dd<Type> nondeterminisimEncoding = generationInfo.manager->getOne(true);
storm::dd::Add<Type> nondeterminismEncoding = generationInfo.manager->getAddOne();
for (uint_fast64_t i = action2.numberOfUsedNondeterminismVariables; i < action1.numberOfUsedNondeterminismVariables; ++i) {
nondeterminisimEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0, true);
nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).toAdd();
}
action2Extended *= nondeterminisimEncoding;
action2Extended *= nondeterminismEncoding;
} else if (action2.numberOfUsedNondeterminismVariables > action1.numberOfUsedNondeterminismVariables) {
storm::dd::Dd<Type> nondeterminisimEncoding = generationInfo.manager->getOne(true);
storm::dd::Add<Type> nondeterminismEncoding = generationInfo.manager->getAddOne();
for (uint_fast64_t i = action1.numberOfUsedNondeterminismVariables; i < action2.numberOfUsedNondeterminismVariables; ++i) {
nondeterminisimEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0, true);
nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).toAdd();
}
action1Extended *= nondeterminisimEncoding;
action1Extended *= nondeterminismEncoding;
}
// Add a new variable that resolves the nondeterminism between the two choices.
storm::dd::Dd<Type> combinedTransitions = generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[numberOfUsedNondeterminismVariables], 1, true).ite(action2Extended, action1Extended);
storm::dd::Add<Type> combinedTransitions = generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[numberOfUsedNondeterminismVariables], 1).toAdd().ite(action2Extended, action1Extended);
return ActionDecisionDiagram(action1.guardDd || action2.guardDd, combinedTransitions, numberOfUsedNondeterminismVariables + 1);
} else {
@ -381,41 +380,41 @@ namespace storm {
}
template <storm::dd::DdType Type>
storm::dd::Dd<Type> DdPrismModelBuilder<Type>::getSynchronizationDecisionDiagram(GenerationInformation& generationInfo, boost::optional<uint_fast64_t> const& synchronizationAction) {
storm::dd::Dd<Type> synchronization = generationInfo.manager->getOne(true);
storm::dd::Add<Type> DdPrismModelBuilder<Type>::getSynchronizationDecisionDiagram(GenerationInformation& generationInfo, boost::optional<uint_fast64_t> const& synchronizationAction) {
storm::dd::Add<Type> synchronization = generationInfo.manager->getAddOne();
for (uint_fast64_t i = 0; i < generationInfo.synchronizationMetaVariables.size(); ++i) {
if (synchronizationAction && synchronizationAction.get() == i) {
synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 1, true);
synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 1).toAdd();
} else {
synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 0, true);
synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 0).toAdd();
}
}
return synchronization;
}
template <storm::dd::DdType Type>
storm::dd::Dd<Type> DdPrismModelBuilder<Type>::createSystemFromModule(GenerationInformation& generationInfo, ModuleDecisionDiagram const& module) {
storm::dd::Add<Type> DdPrismModelBuilder<Type>::createSystemFromModule(GenerationInformation& generationInfo, ModuleDecisionDiagram const& module) {
// If the model is an MDP, we need to encode the nondeterminism using additional variables.
if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) {
storm::dd::Dd<Type> result = generationInfo.manager->getZero(true);
storm::dd::Add<Type> result = generationInfo.manager->getAddZero();
// First, determine the highest number of nondeterminism variables that is used in any action and make
// all actions use the same amout of nondeterminism variables.
uint_fast64_t numberOfUsedNondeterminismVariables = module.numberOfUsedNondeterminismVariables;
// Add variables to independent action DD.
storm::dd::Dd<Type> nondeterminismEncoding = generationInfo.manager->getOne(true);
storm::dd::Add<Type> nondeterminismEncoding = generationInfo.manager->getAddOne();
for (uint_fast64_t i = module.independentAction.numberOfUsedNondeterminismVariables; i < numberOfUsedNondeterminismVariables; ++i) {
nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0, true);
nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).toAdd();
}
result = module.independentAction.transitionsDd * nondeterminismEncoding;
// Add variables to synchronized action DDs.
std::map<uint_fast64_t, storm::dd::Dd<Type>> synchronizingActionToDdMap;
std::map<uint_fast64_t, storm::dd::Add<Type>> synchronizingActionToDdMap;
for (auto const& synchronizingAction : module.synchronizingActionToDecisionDiagramMap) {
nondeterminismEncoding = generationInfo.manager->getOne(true);
nondeterminismEncoding = generationInfo.manager->getAddOne();
for (uint_fast64_t i = synchronizingAction.second.numberOfUsedNondeterminismVariables; i < numberOfUsedNondeterminismVariables; ++i) {
nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0, true);
nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).toAdd();
}
synchronizingActionToDdMap.emplace(synchronizingAction.first, synchronizingAction.second.transitionsDd * nondeterminismEncoding);
}
@ -435,7 +434,7 @@ namespace storm {
return result;
} else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) {
// Simply add all actions.
storm::dd::Dd<Type> result = module.independentAction.transitionsDd;
storm::dd::Add<Type> result = module.independentAction.transitionsDd;
for (auto const& synchronizingAction : module.synchronizingActionToDecisionDiagramMap) {
result += synchronizingAction.second.transitionsDd;
}
@ -446,7 +445,7 @@ namespace storm {
}
template <storm::dd::DdType Type>
std::pair<storm::dd::Dd<Type>, typename DdPrismModelBuilder<Type>::ModuleDecisionDiagram> DdPrismModelBuilder<Type>::createSystemDecisionDiagram(GenerationInformation& generationInfo) {
std::pair<storm::dd::Add<Type>, typename DdPrismModelBuilder<Type>::ModuleDecisionDiagram> DdPrismModelBuilder<Type>::createSystemDecisionDiagram(GenerationInformation& generationInfo) {
// Create the initial offset mapping.
std::map<uint_fast64_t, uint_fast64_t> synchronizingActionToOffsetMap;
for (auto const& actionIndex : generationInfo.program.getActionIndices()) {
@ -501,7 +500,7 @@ namespace storm {
system.numberOfUsedNondeterminismVariables = std::max(system.numberOfUsedNondeterminismVariables, numberOfUsedNondeterminismVariables);
}
storm::dd::Dd<Type> result = createSystemFromModule(generationInfo, system);
storm::dd::Add<Type> result = createSystemFromModule(generationInfo, system);
// For DTMCs, we normalize each row to 1 (to account for non-determinism).
if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) {
@ -519,12 +518,12 @@ namespace storm {
}
template <storm::dd::DdType Type>
std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> DdPrismModelBuilder<Type>::createRewardDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Dd<Type> const& fullTransitionMatrix) {
std::pair<storm::dd::Add<Type>, storm::dd::Add<Type>> DdPrismModelBuilder<Type>::createRewardDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Add<Type> const& fullTransitionMatrix) {
// Start by creating the state reward vector.
storm::dd::Dd<Type> stateRewards = generationInfo.manager->getZero();
storm::dd::Add<Type> stateRewards = generationInfo.manager->getAddZero();
for (auto const& stateReward : rewardModel.getStateRewards()) {
storm::dd::Dd<Type> states = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getStatePredicateExpression());
storm::dd::Dd<Type> rewards = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getRewardValueExpression());
storm::dd::Add<Type> states = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getStatePredicateExpression());
storm::dd::Add<Type> rewards = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getRewardValueExpression());
// Restrict the rewards to those states that satisfy the condition.
rewards = states * rewards;
@ -538,13 +537,13 @@ namespace storm {
}
// Then build the transition reward matrix.
storm::dd::Dd<Type> transitionRewards = generationInfo.manager->getZero();
storm::dd::Add<Type> transitionRewards = generationInfo.manager->getAddZero();
for (auto const& transitionReward : rewardModel.getTransitionRewards()) {
storm::dd::Dd<Type> states = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getStatePredicateExpression());
storm::dd::Dd<Type> rewards = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getRewardValueExpression());
storm::dd::Add<Type> states = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getStatePredicateExpression());
storm::dd::Add<Type> rewards = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getRewardValueExpression());
storm::dd::Dd<Type> synchronization;
storm::dd::Dd<Type> transitions;
storm::dd::Add<Type> synchronization;
storm::dd::Add<Type> transitions;
if (transitionReward.isLabeled()) {
synchronization = getSynchronizationDecisionDiagram(generationInfo, transitionReward.getActionIndex());
transitions = globalModule.synchronizingActionToDecisionDiagramMap.at(transitionReward.getActionIndex()).transitionsDd;
@ -553,9 +552,9 @@ namespace storm {
transitions = globalModule.independentAction.transitionsDd;
}
storm::dd::Dd<Type> transitionRewardDd = synchronization * states * rewards;
storm::dd::Add<Type> transitionRewardDd = synchronization * states * rewards;
if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) {
transitionRewardDd += transitions.notZero() * transitionRewardDd;
transitionRewardDd += transitions.notZero().toAdd() * transitionRewardDd;
} else {
transitionRewardDd += transitions * transitionRewardDd;
}
@ -608,15 +607,15 @@ namespace storm {
// In particular, this creates the meta variables used to encode the model.
GenerationInformation generationInfo(preparedProgram);
std::pair<storm::dd::Dd<Type>, ModuleDecisionDiagram> transitionMatrixModulePair = createSystemDecisionDiagram(generationInfo);
storm::dd::Dd<Type> transitionMatrix = transitionMatrixModulePair.first;
std::pair<storm::dd::Add<Type>, ModuleDecisionDiagram> transitionMatrixModulePair = createSystemDecisionDiagram(generationInfo);
storm::dd::Add<Type> transitionMatrix = transitionMatrixModulePair.first;
ModuleDecisionDiagram const& globalModule = transitionMatrixModulePair.second;
// Finally, we build the DDs for a reward structure, if requested. It is important to do this now, because
// we still have the uncut transition matrix, which is needed for the reward computation. This is because
// the reward computation might divide by the transition probabilities, which must therefore never be 0.
// However, cutting it to the reachable fragment, there might be zero probability transitions.
boost::optional<std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>>> stateAndTransitionRewards;
boost::optional<std::pair<storm::dd::Add<Type>, storm::dd::Add<Type>>> stateAndTransitionRewards;
if (options.buildRewards) {
// If a specific reward model was selected or one with the empty name exists, select it.
storm::prism::RewardModel rewardModel = storm::prism::RewardModel();
@ -634,17 +633,17 @@ namespace storm {
}
// Cut the transition matrix to the reachable fragment of the state space.
storm::dd::Dd<Type> initialStates = createInitialStatesDecisionDiagram(generationInfo);
storm::dd::Dd<Type> reachableStates = computeReachableStates(generationInfo, initialStates, transitionMatrix);
transitionMatrix *= reachableStates.toMtbdd();
// Detect deadlocks and 1) fix them if requested 2) throw an error otherwise.
storm::dd::Dd<Type> statesWithTransition = transitionMatrix.notZero();
storm::dd::Bdd<Type> initialStates = createInitialStatesDecisionDiagram(generationInfo);
storm::dd::Bdd<Type> transitionMatrixBdd = transitionMatrix.notZero();
if (program.getModelType() == storm::prism::Program::ModelType::MDP) {
statesWithTransition = statesWithTransition.existsAbstract(generationInfo.allNondeterminismVariables);
transitionMatrixBdd = transitionMatrixBdd.existsAbstract(generationInfo.allNondeterminismVariables);
}
statesWithTransition = statesWithTransition.existsAbstract(generationInfo.columnMetaVariables);
storm::dd::Dd<Type> deadlockStates = (reachableStates && !statesWithTransition).toMtbdd();
storm::dd::Bdd<Type> reachableStates = computeReachableStates(generationInfo, initialStates, transitionMatrixBdd);
transitionMatrix *= reachableStates.toAdd();
// Detect deadlocks and 1) fix them if requested 2) throw an error otherwise.
storm::dd::Bdd<Type> statesWithTransition = transitionMatrixBdd.existsAbstract(generationInfo.columnMetaVariables);
storm::dd::Add<Type> deadlockStates = (reachableStates && !statesWithTransition).toAdd();
if (!deadlockStates.isZero()) {
// If we need to fix deadlocks, we do so now.
@ -657,7 +656,7 @@ namespace storm {
} else if (program.getModelType() == storm::prism::Program::ModelType::MDP) {
// For MDPs, however, we need to select an action associated with the self-loop, if we do not
// want to attach a lot of self-loops to the deadlock states.
storm::dd::Dd<Type> action = generationInfo.manager->getOne(true);
storm::dd::Add<Type> action = generationInfo.manager->getAddOne();
std::for_each(generationInfo.allNondeterminismVariables.begin(), generationInfo.allNondeterminismVariables.end(), [&action,&generationInfo] (storm::expressions::Variable const& metaVariable) { action *= !generationInfo.manager->getIdentity(metaVariable); } );
transitionMatrix += deadlockStates * globalModule.identity * action;
}
@ -673,17 +672,17 @@ namespace storm {
}
if (program.getModelType() == storm::prism::Program::ModelType::DTMC) {
return std::shared_ptr<storm::models::symbolic::Model<Type>>(new storm::models::symbolic::Dtmc<Type>(generationInfo.manager, reachableStates, initialStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, stateAndTransitionRewards ? stateAndTransitionRewards.get().first : boost::optional<storm::dd::Dd<Type>>(), stateAndTransitionRewards ? stateAndTransitionRewards.get().second : boost::optional<storm::dd::Dd<Type>>()));
return std::shared_ptr<storm::models::symbolic::Model<Type>>(new storm::models::symbolic::Dtmc<Type>(generationInfo.manager, reachableStates, initialStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, stateAndTransitionRewards ? stateAndTransitionRewards.get().first : boost::optional<storm::dd::Add<Type>>(), stateAndTransitionRewards ? stateAndTransitionRewards.get().second : boost::optional<storm::dd::Add<Type>>()));
} else if (program.getModelType() == storm::prism::Program::ModelType::MDP) {
return std::shared_ptr<storm::models::symbolic::Model<Type>>(new storm::models::symbolic::Mdp<Type>(generationInfo.manager, reachableStates, initialStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, generationInfo.allNondeterminismVariables, labelToExpressionMapping, stateAndTransitionRewards ? stateAndTransitionRewards.get().first : boost::optional<storm::dd::Dd<Type>>(), stateAndTransitionRewards ? stateAndTransitionRewards.get().second : boost::optional<storm::dd::Dd<Type>>()));
return std::shared_ptr<storm::models::symbolic::Model<Type>>(new storm::models::symbolic::Mdp<Type>(generationInfo.manager, reachableStates, initialStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, generationInfo.allNondeterminismVariables, labelToExpressionMapping, stateAndTransitionRewards ? stateAndTransitionRewards.get().first : boost::optional<storm::dd::Add<Type>>(), stateAndTransitionRewards ? stateAndTransitionRewards.get().second : boost::optional<storm::dd::Add<Type>>()));
} else {
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Invalid model type.");
}
}
template <storm::dd::DdType Type>
storm::dd::Dd<Type> DdPrismModelBuilder<Type>::createInitialStatesDecisionDiagram(GenerationInformation& generationInfo) {
storm::dd::Dd<Type> initialStates = generationInfo.rowExpressionAdapter->translateExpression(generationInfo.program.getInitialConstruct().getInitialStatesExpression()).toBdd();
storm::dd::Bdd<Type> DdPrismModelBuilder<Type>::createInitialStatesDecisionDiagram(GenerationInformation& generationInfo) {
storm::dd::Bdd<Type> initialStates = generationInfo.rowExpressionAdapter->translateExpression(generationInfo.program.getInitialConstruct().getInitialStatesExpression()).toBdd();
for (auto const& metaVariable : generationInfo.rowMetaVariables) {
initialStates &= generationInfo.manager->getRange(metaVariable);
@ -693,14 +692,8 @@ namespace storm {
}
template <storm::dd::DdType Type>
storm::dd::Dd<Type> DdPrismModelBuilder<Type>::computeReachableStates(GenerationInformation& generationInfo, storm::dd::Dd<Type> const& initialStates, storm::dd::Dd<Type> const& transitions) {
storm::dd::Dd<Type> reachableStatesBdd = initialStates.toBdd();
// If the model is an MDP, we can abstract from the variables encoding the nondeterminism in the model.
storm::dd::Dd<Type> transitionBdd = transitions.notZero();
if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) {
transitionBdd = transitionBdd.existsAbstract(generationInfo.allNondeterminismVariables);
}
storm::dd::Bdd<Type> DdPrismModelBuilder<Type>::computeReachableStates(GenerationInformation& generationInfo, storm::dd::Bdd<Type> const& initialStates, storm::dd::Bdd<Type> const& transitionBdd) {
storm::dd::Bdd<Type> reachableStates = initialStates;
// Perform the BFS to discover all reachable states.
bool changed = true;
@ -708,21 +701,21 @@ namespace storm {
do {
STORM_LOG_TRACE("Iteration " << iteration << " of computing reachable states.");
changed = false;
storm::dd::Dd<Type> tmp = reachableStatesBdd.andExists(transitionBdd, generationInfo.rowMetaVariables);
storm::dd::Bdd<Type> tmp = reachableStates.andExists(transitionBdd, generationInfo.rowMetaVariables);
tmp = tmp.swapVariables(generationInfo.rowColumnMetaVariablePairs);
storm::dd::Dd<Type> newReachableStates = tmp && (!reachableStatesBdd);
storm::dd::Bdd<Type> newReachableStates = tmp && (!reachableStates);
// Check whether new states were indeed discovered.
if (!newReachableStates.isZero()) {
changed = true;
}
reachableStatesBdd |= newReachableStates;
reachableStates |= newReachableStates;
++iteration;
} while (changed);
return reachableStatesBdd;
return reachableStates;
}
// Explicitly instantiate the symbolic expression adapter

64
src/builder/DdPrismModelBuilder.h

@ -7,7 +7,7 @@
#include "src/models/symbolic/Model.h"
#include "src/logic/Formulas.h"
#include "src/storage/prism/Program.h"
#include "src/adapters/DdExpressionAdapter.h"
#include "src/adapters/AddExpressionAdapter.h"
#include "src/utility/macros.h"
namespace storm {
@ -71,11 +71,11 @@ namespace storm {
// Intentionally left empty.
}
ActionDecisionDiagram(storm::dd::DdManager<Type> const& manager, uint_fast64_t numberOfUsedNondeterminismVariables = 0) : guardDd(manager.getZero(true)), transitionsDd(manager.getZero(true)), numberOfUsedNondeterminismVariables(numberOfUsedNondeterminismVariables) {
ActionDecisionDiagram(storm::dd::DdManager<Type> const& manager, uint_fast64_t numberOfUsedNondeterminismVariables = 0) : guardDd(manager.getAddZero()), transitionsDd(manager.getAddZero()), numberOfUsedNondeterminismVariables(numberOfUsedNondeterminismVariables) {
// Intentionally left empty.
}
ActionDecisionDiagram(storm::dd::Dd<Type> guardDd, storm::dd::Dd<Type> transitionsDd, uint_fast64_t numberOfUsedNondeterminismVariables = 0) : guardDd(guardDd), transitionsDd(transitionsDd), numberOfUsedNondeterminismVariables(numberOfUsedNondeterminismVariables) {
ActionDecisionDiagram(storm::dd::Add<Type> guardDd, storm::dd::Add<Type> transitionsDd, uint_fast64_t numberOfUsedNondeterminismVariables = 0) : guardDd(guardDd), transitionsDd(transitionsDd), numberOfUsedNondeterminismVariables(numberOfUsedNondeterminismVariables) {
// Intentionally left empty.
}
@ -83,10 +83,10 @@ namespace storm {
ActionDecisionDiagram& operator=(ActionDecisionDiagram const& other) = default;
// The guard of the action.
storm::dd::Dd<Type> guardDd;
storm::dd::Add<Type> guardDd;
// The actual transitions (source and target states).
storm::dd::Dd<Type> transitionsDd;
storm::dd::Add<Type> transitionsDd;
// The number of variables that are used to encode the nondeterminism.
uint_fast64_t numberOfUsedNondeterminismVariables;
@ -98,11 +98,11 @@ namespace storm {
// Intentionally left empty.
}
ModuleDecisionDiagram(storm::dd::DdManager<Type> const& manager) : independentAction(manager), synchronizingActionToDecisionDiagramMap(), identity(manager.getZero(true)), numberOfUsedNondeterminismVariables(0) {
ModuleDecisionDiagram(storm::dd::DdManager<Type> const& manager) : independentAction(manager), synchronizingActionToDecisionDiagramMap(), identity(manager.getAddZero()), numberOfUsedNondeterminismVariables(0) {
// Intentionally left empty.
}
ModuleDecisionDiagram(ActionDecisionDiagram const& independentAction, std::map<uint_fast64_t, ActionDecisionDiagram> const& synchronizingActionToDecisionDiagramMap, storm::dd::Dd<Type> const& identity, uint_fast64_t numberOfUsedNondeterminismVariables = 0) : independentAction(independentAction), synchronizingActionToDecisionDiagramMap(synchronizingActionToDecisionDiagramMap), identity(identity), numberOfUsedNondeterminismVariables(numberOfUsedNondeterminismVariables) {
ModuleDecisionDiagram(ActionDecisionDiagram const& independentAction, std::map<uint_fast64_t, ActionDecisionDiagram> const& synchronizingActionToDecisionDiagramMap, storm::dd::Add<Type> const& identity, uint_fast64_t numberOfUsedNondeterminismVariables = 0) : independentAction(independentAction), synchronizingActionToDecisionDiagramMap(synchronizingActionToDecisionDiagramMap), identity(identity), numberOfUsedNondeterminismVariables(numberOfUsedNondeterminismVariables) {
// Intentionally left empty.
}
@ -120,7 +120,7 @@ namespace storm {
std::map<uint_fast64_t, ActionDecisionDiagram> synchronizingActionToDecisionDiagramMap;
// A decision diagram that represents the identity of this module.
storm::dd::Dd<Type> identity;
storm::dd::Add<Type> identity;
// The number of variables encoding the nondeterminism that were actually used.
uint_fast64_t numberOfUsedNondeterminismVariables;
@ -135,8 +135,8 @@ namespace storm {
// Initializes variables and identity DDs.
createMetaVariablesAndIdentities();
rowExpressionAdapter = std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>>(new storm::adapters::DdExpressionAdapter<Type>(manager, variableToRowMetaVariableMap));
columnExpressionAdapter = std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>>(new storm::adapters::DdExpressionAdapter<Type>(manager, variableToColumnMetaVariableMap));
rowExpressionAdapter = std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>>(new storm::adapters::AddExpressionAdapter<Type>(manager, variableToRowMetaVariableMap));
columnExpressionAdapter = std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>>(new storm::adapters::AddExpressionAdapter<Type>(manager, variableToColumnMetaVariableMap));
}
// The program that is currently translated.
@ -148,12 +148,12 @@ namespace storm {
// The meta variables for the row encoding.
std::set<storm::expressions::Variable> rowMetaVariables;
std::map<storm::expressions::Variable, storm::expressions::Variable> variableToRowMetaVariableMap;
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter;
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter;
// The meta variables for the column encoding.
std::set<storm::expressions::Variable> columnMetaVariables;
std::map<storm::expressions::Variable, storm::expressions::Variable> variableToColumnMetaVariableMap;
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter;
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter;
// All pairs of row/column meta variables.
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> rowColumnMetaVariablePairs;
@ -169,13 +169,13 @@ namespace storm {
std::set<storm::expressions::Variable> allNondeterminismVariables;
// DDs representing the identity for each variable.
std::map<storm::expressions::Variable, storm::dd::Dd<Type>> variableToIdentityMap;
std::map<storm::expressions::Variable, storm::dd::Add<Type>> variableToIdentityMap;
// DDs representing the identity for each module.
std::map<std::string, storm::dd::Dd<Type>> moduleToIdentityMap;
std::map<std::string, storm::dd::Add<Type>> moduleToIdentityMap;
// DDs representing the valid ranges of the variables of each module.
std::map<std::string, storm::dd::Dd<Type>> moduleToRangeMap;
std::map<std::string, storm::dd::Add<Type>> moduleToRangeMap;
private:
/*!
@ -212,7 +212,7 @@ namespace storm {
columnMetaVariables.insert(variablePair.second);
variableToColumnMetaVariableMap.emplace(integerVariable.getExpressionVariable(), variablePair.second);
storm::dd::Dd<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second)) * manager->getRange(variablePair.first, true);
storm::dd::Add<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second)) * manager->getRange(variablePair.first).toAdd();
variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity);
rowColumnMetaVariablePairs.push_back(variablePair);
}
@ -225,7 +225,7 @@ namespace storm {
columnMetaVariables.insert(variablePair.second);
variableToColumnMetaVariableMap.emplace(booleanVariable.getExpressionVariable(), variablePair.second);
storm::dd::Dd<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second));
storm::dd::Add<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second));
variableToIdentityMap.emplace(booleanVariable.getExpressionVariable(), variableIdentity);
rowColumnMetaVariablePairs.push_back(variablePair);
@ -233,8 +233,8 @@ namespace storm {
// Create meta variables for each of the modules' variables.
for (storm::prism::Module const& module : program.getModules()) {
storm::dd::Dd<Type> moduleIdentity = manager->getOne(true);
storm::dd::Dd<Type> moduleRange = manager->getOne(true);
storm::dd::Add<Type> moduleIdentity = manager->getAddOne();
storm::dd::Add<Type> moduleRange = manager->getAddOne();
for (storm::prism::IntegerVariable const& integerVariable : module.getIntegerVariables()) {
int_fast64_t low = integerVariable.getLowerBoundExpression().evaluateAsInt();
@ -248,10 +248,10 @@ namespace storm {
columnMetaVariables.insert(variablePair.second);
variableToColumnMetaVariableMap.emplace(integerVariable.getExpressionVariable(), variablePair.second);
storm::dd::Dd<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second)) * manager->getRange(variablePair.first, true) * manager->getRange(variablePair.second, true);
storm::dd::Add<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second)) * manager->getRange(variablePair.first).toAdd() * manager->getRange(variablePair.second).toAdd();
variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity);
moduleIdentity *= variableIdentity;
moduleRange *= manager->getRange(variablePair.first, true);
moduleRange *= manager->getRange(variablePair.first).toAdd();
rowColumnMetaVariablePairs.push_back(variablePair);
}
@ -265,10 +265,10 @@ namespace storm {
columnMetaVariables.insert(variablePair.second);
variableToColumnMetaVariableMap.emplace(booleanVariable.getExpressionVariable(), variablePair.second);
storm::dd::Dd<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second)) * manager->getRange(variablePair.first, true) * manager->getRange(variablePair.second, true);
storm::dd::Add<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second)) * manager->getRange(variablePair.first).toAdd() * manager->getRange(variablePair.second).toAdd();
variableToIdentityMap.emplace(booleanVariable.getExpressionVariable(), variableIdentity);
moduleIdentity *= variableIdentity;
moduleRange *= manager->getRange(variablePair.first, true);
moduleRange *= manager->getRange(variablePair.first).toAdd();
rowColumnMetaVariablePairs.push_back(variablePair);
}
@ -280,9 +280,9 @@ namespace storm {
private:
static storm::dd::Dd<Type> encodeChoice(GenerationInformation& generationInfo, uint_fast64_t nondeterminismVariableOffset, uint_fast64_t numberOfBinaryVariables, int_fast64_t value);
static storm::dd::Add<Type> encodeChoice(GenerationInformation& generationInfo, uint_fast64_t nondeterminismVariableOffset, uint_fast64_t numberOfBinaryVariables, int_fast64_t value);
static storm::dd::Dd<Type> createUpdateDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::dd::Dd<Type> const& guard, storm::prism::Update const& update);
static storm::dd::Add<Type> createUpdateDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::dd::Add<Type> const& guard, storm::prism::Update const& update);
static ActionDecisionDiagram createCommandDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::prism::Command const& command);
@ -294,21 +294,21 @@ namespace storm {
static ActionDecisionDiagram combineSynchronizingActions(GenerationInformation const& generationInfo, ActionDecisionDiagram const& action1, ActionDecisionDiagram const& action2);
static ActionDecisionDiagram combineUnsynchronizedActions(GenerationInformation const& generationInfo, ActionDecisionDiagram const& action1, ActionDecisionDiagram const& action2, storm::dd::Dd<Type> const& identityDd1, storm::dd::Dd<Type> const& identityDd2);
static ActionDecisionDiagram combineUnsynchronizedActions(GenerationInformation const& generationInfo, ActionDecisionDiagram const& action1, ActionDecisionDiagram const& action2, storm::dd::Add<Type> const& identityDd1, storm::dd::Add<Type> const& identityDd2);
static ModuleDecisionDiagram createModuleDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap);
static storm::dd::Dd<Type> getSynchronizationDecisionDiagram(GenerationInformation& generationInfo, boost::optional<uint_fast64_t> const& synchronizationAction = boost::optional<uint_fast64_t>());
static storm::dd::Add<Type> getSynchronizationDecisionDiagram(GenerationInformation& generationInfo, boost::optional<uint_fast64_t> const& synchronizationAction = boost::optional<uint_fast64_t>());
static storm::dd::Dd<Type> createSystemFromModule(GenerationInformation& generationInfo, ModuleDecisionDiagram const& module);
static storm::dd::Add<Type> createSystemFromModule(GenerationInformation& generationInfo, ModuleDecisionDiagram const& module);
static std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> createRewardDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Dd<Type> const& fullTransitionMatrix);
static std::pair<storm::dd::Add<Type>, storm::dd::Add<Type>> createRewardDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Add<Type> const& fullTransitionMatrix);
static std::pair<storm::dd::Dd<Type>, ModuleDecisionDiagram> createSystemDecisionDiagram(GenerationInformation& generationInfo);
static std::pair<storm::dd::Add<Type>, ModuleDecisionDiagram> createSystemDecisionDiagram(GenerationInformation& generationInfo);
static storm::dd::Dd<Type> createInitialStatesDecisionDiagram(GenerationInformation& generationInfo);
static storm::dd::Bdd<Type> createInitialStatesDecisionDiagram(GenerationInformation& generationInfo);
static storm::dd::Dd<Type> computeReachableStates(GenerationInformation& generationInfo, storm::dd::Dd<Type> const& initialStates, storm::dd::Dd<Type> const& transitions);
static storm::dd::Bdd<Type> computeReachableStates(GenerationInformation& generationInfo, storm::dd::Bdd<Type> const& initialStates, storm::dd::Bdd<Type> const& transitions);
};

2
src/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp

@ -25,7 +25,7 @@ namespace storm {
if (stateFormula.isTrueFormula()) {
return std::unique_ptr<CheckResult>(new SymbolicQualitativeCheckResult<Type>(model.getReachableStates(), model.getReachableStates()));
} else {
return std::unique_ptr<CheckResult>(new SymbolicQualitativeCheckResult<Type>(model.getReachableStates(), model.getManager().getZero()));
return std::unique_ptr<CheckResult>(new SymbolicQualitativeCheckResult<Type>(model.getReachableStates(), model.getManager().getBddZero()));
}
}

2
src/modelchecker/results/SymbolicQualitativeCheckResult.cpp

@ -6,7 +6,7 @@
namespace storm {
namespace modelchecker {
template <storm::dd::DdType Type>
SymbolicQualitativeCheckResult<Type>::SymbolicQualitativeCheckResult(storm::dd::Dd<Type> const& allStates, storm::dd::Dd<Type> const& truthValues) : allStates(allStates), truthValues(truthValues) {
SymbolicQualitativeCheckResult<Type>::SymbolicQualitativeCheckResult(storm::dd::Bdd<Type> const& allStates, storm::dd::Bdd<Type> const& truthValues) : allStates(allStates), truthValues(truthValues) {
// Intentionally left empty.
}

8
src/modelchecker/results/SymbolicQualitativeCheckResult.h

@ -2,7 +2,7 @@
#define STORM_MODELCHECKER_SYMBOLICQUALITATIVECHECKRESULT_H_
#include "src/storage/dd/DdType.h"
#include "src/storage/dd/Dd.h"
#include "src/storage/dd/CuddBdd.h"
#include "src/modelchecker/results/QualitativeCheckResult.h"
#include "src/utility/OsDetection.h"
@ -12,7 +12,7 @@ namespace storm {
class SymbolicQualitativeCheckResult : public QualitativeCheckResult {
public:
SymbolicQualitativeCheckResult() = default;
SymbolicQualitativeCheckResult(storm::dd::Dd<Type> const& allStates, storm::dd::Dd<Type> const& truthValues);
SymbolicQualitativeCheckResult(storm::dd::Bdd<Type> const& allStates, storm::dd::Bdd<Type> const& truthValues);
SymbolicQualitativeCheckResult(SymbolicQualitativeCheckResult const& other) = default;
SymbolicQualitativeCheckResult& operator=(SymbolicQualitativeCheckResult const& other) = default;
@ -38,10 +38,10 @@ namespace storm {
private:
// The set of all states.
storm::dd::Dd<Type> allStates;
storm::dd::Bdd<Type> allStates;
// The values of the qualitative check result.
storm::dd::Dd<Type> truthValues;
storm::dd::Bdd<Type> truthValues;
};
}
}

2
src/modelchecker/results/SymbolicQuantitativeCheckResult.cpp

@ -7,7 +7,7 @@
namespace storm {
namespace modelchecker {
template<storm::dd::DdType Type>
SymbolicQuantitativeCheckResult<Type>::SymbolicQuantitativeCheckResult(storm::dd::Dd<Type> const& allStates, storm::dd::Dd<Type> const& values) : allStates(allStates), values(values) {
SymbolicQuantitativeCheckResult<Type>::SymbolicQuantitativeCheckResult(storm::dd::Add<Type> const& allStates, storm::dd::Add<Type> const& values) : allStates(allStates), values(values) {
// Intentionally left empty.
}

8
src/modelchecker/results/SymbolicQuantitativeCheckResult.h

@ -2,7 +2,7 @@
#define STORM_MODELCHECKER_SYMBOLICQUANTITATIVECHECKRESULT_H_
#include "src/storage/dd/DdType.h"
#include "src/storage/dd/Dd.h"
#include "src/storage/dd/CuddAdd.h"
#include "src/modelchecker/results/QuantitativeCheckResult.h"
#include "src/utility/OsDetection.h"
@ -12,7 +12,7 @@ namespace storm {
class SymbolicQuantitativeCheckResult : public QuantitativeCheckResult {
public:
SymbolicQuantitativeCheckResult() = default;
SymbolicQuantitativeCheckResult(storm::dd::Dd<Type> const& allStates, storm::dd::Dd<Type> const& values);
SymbolicQuantitativeCheckResult(storm::dd::Add<Type> const& allStates, storm::dd::Add<Type> const& values);
SymbolicQuantitativeCheckResult(SymbolicQuantitativeCheckResult const& other) = default;
SymbolicQuantitativeCheckResult& operator=(SymbolicQuantitativeCheckResult const& other) = default;
@ -36,10 +36,10 @@ namespace storm {
private:
// The set of all states.
storm::dd::Dd<Type> allStates;
storm::dd::Add<Type> allStates;
// The values of the quantitative check result.
storm::dd::Dd<Type> values;
storm::dd::Add<Type> values;
};
}
}

14
src/models/symbolic/DeterministicModel.cpp

@ -7,17 +7,17 @@ namespace storm {
template<storm::dd::DdType Type>
DeterministicModel<Type>::DeterministicModel(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix)
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix)
: Model<Type>(modelType, manager, reachableStates, initialStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, optionalStateRewardVector, optionalTransitionRewardMatrix) {
// Intentionally left empty.
}

14
src/models/symbolic/DeterministicModel.h

@ -43,17 +43,17 @@ namespace storm {
*/
DeterministicModel(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap = std::map<std::string, storm::expressions::Expression>(),
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
};
} // namespace symbolic

14
src/models/symbolic/Dtmc.cpp

@ -6,17 +6,17 @@ namespace storm {
template<storm::dd::DdType Type>
Dtmc<Type>::Dtmc(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix)
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix)
: DeterministicModel<Type>(storm::models::ModelType::Dtmc, manager, reachableStates, initialStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, optionalStateRewardVector, optionalTransitionRewardMatrix) {
// Intentionally left empty.
}

14
src/models/symbolic/Dtmc.h

@ -41,17 +41,17 @@ namespace storm {
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
*/
Dtmc(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap = std::map<std::string, storm::expressions::Expression>(),
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
};
} // namespace symbolic

14
src/models/symbolic/Mdp.cpp

@ -6,18 +6,18 @@ namespace storm {
template<storm::dd::DdType Type>
Mdp<Type>::Mdp(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix)
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix)
: NondeterministicModel<Type>(storm::models::ModelType::Mdp, manager, reachableStates, initialStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, nondeterminismVariables, labelToExpressionMap, optionalStateRewardVector, optionalTransitionRewardMatrix) {
// Intentionally left empty.
}

14
src/models/symbolic/Mdp.h

@ -43,18 +43,18 @@ namespace storm {
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
*/
Mdp(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap = std::map<std::string, storm::expressions::Expression>(),
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
};

34
src/models/symbolic/Model.cpp

@ -6,17 +6,17 @@ namespace storm {
template<storm::dd::DdType Type>
Model<Type>::Model(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix)
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix)
: ModelBase(modelType), manager(manager), reachableStates(reachableStates), initialStates(initialStates), transitionMatrix(transitionMatrix), rowVariables(rowVariables), rowExpressionAdapter(rowExpressionAdapter), columnVariables(columnVariables), columnExpressionAdapter(columnExpressionAdapter), rowColumnMetaVariablePairs(rowColumnMetaVariablePairs), labelToExpressionMap(labelToExpressionMap), stateRewardVector(optionalStateRewardVector), transitionRewardMatrix(optionalTransitionRewardMatrix) {
// Intentionally left empty.
}
@ -42,23 +42,23 @@ namespace storm {
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type> const& Model<Type>::getReachableStates() const {
storm::dd::Bdd<Type> const& Model<Type>::getReachableStates() const {
return reachableStates;
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type> const& Model<Type>::getInitialStates() const {
storm::dd::Bdd<Type> const& Model<Type>::getInitialStates() const {
return initialStates;
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type> Model<Type>::getStates(std::string const& label) const {
storm::dd::Bdd<Type> Model<Type>::getStates(std::string const& label) const {
STORM_LOG_THROW(labelToExpressionMap.find(label) != labelToExpressionMap.end(), storm::exceptions::InvalidArgumentException, "The label " << label << " is invalid for the labeling of the model.");
return rowExpressionAdapter->translateExpression(labelToExpressionMap.at(label)).toBdd() && this->reachableStates;
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type> Model<Type>::getStates(storm::expressions::Expression const& expression) const {
storm::dd::Bdd<Type> Model<Type>::getStates(storm::expressions::Expression const& expression) const {
return rowExpressionAdapter->translateExpression(expression).toBdd() && this->reachableStates;
}
@ -68,27 +68,27 @@ namespace storm {
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type> const& Model<Type>::getTransitionMatrix() const {
storm::dd::Add<Type> const& Model<Type>::getTransitionMatrix() const {
return transitionMatrix;
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type>& Model<Type>::getTransitionMatrix() {
storm::dd::Add<Type>& Model<Type>::getTransitionMatrix() {
return transitionMatrix;
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type> const& Model<Type>::getTransitionRewardMatrix() const {
storm::dd::Add<Type> const& Model<Type>::getTransitionRewardMatrix() const {
return transitionRewardMatrix.get();
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type>& Model<Type>::getTransitionRewardMatrix() {
storm::dd::Add<Type>& Model<Type>::getTransitionRewardMatrix() {
return transitionRewardMatrix.get();
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type> const& Model<Type>::getStateRewardVector() const {
storm::dd::Add<Type> const& Model<Type>::getStateRewardVector() const {
return stateRewardVector.get();
}
@ -123,7 +123,7 @@ namespace storm {
}
template<storm::dd::DdType Type>
void Model<Type>::setTransitionMatrix(storm::dd::Dd<Type> const& transitionMatrix) {
void Model<Type>::setTransitionMatrix(storm::dd::Add<Type> const& transitionMatrix) {
this->transitionMatrix = transitionMatrix;
}

50
src/models/symbolic/Model.h

@ -7,7 +7,7 @@
#include "src/storage/expressions/Expression.h"
#include "src/storage/expressions/Variable.h"
#include "src/adapters/DdExpressionAdapter.h"
#include "src/adapters/AddExpressionAdapter.h"
#include "src/storage/dd/CuddDd.h"
#include "src/storage/dd/CuddDdManager.h"
#include "src/models/ModelBase.h"
@ -52,17 +52,17 @@ namespace storm {
*/
Model(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap = std::map<std::string, storm::expressions::Expression>(),
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
virtual uint_fast64_t getNumberOfStates() const override;
@ -87,14 +87,14 @@ namespace storm {
*
* @return The reachble states of the model.
*/
storm::dd::Dd<Type> const& getReachableStates() const;
storm::dd::Bdd<Type> const& getReachableStates() const;
/*!
* Retrieves the initial states of the model.
*
* @return The initial states of the model.
*/
storm::dd::Dd<Type> const& getInitialStates() const;
storm::dd::Bdd<Type> const& getInitialStates() const;
/*!
* Returns the sets of states labeled with the given label.
@ -102,7 +102,7 @@ namespace storm {
* @param label The label for which to get the labeled states.
* @return The set of states labeled with the requested label in the form of a bit vector.
*/
storm::dd::Dd<Type> getStates(std::string const& label) const;
storm::dd::Bdd<Type> getStates(std::string const& label) const;
/*!
* Returns the set of states labeled satisfying the given expression (that must be of boolean type).
@ -110,7 +110,7 @@ namespace storm {
* @param expression The expression that needs to hold in the states.
* @return The set of states labeled satisfying the given expression.
*/
storm::dd::Dd<Type> getStates(storm::expressions::Expression const& expression) const;
storm::dd::Bdd<Type> getStates(storm::expressions::Expression const& expression) const;
/*!
* Retrieves whether the given label is a valid label in this model.
@ -125,14 +125,14 @@ namespace storm {
*
* @return A matrix representing the transitions of the model.
*/
storm::dd::Dd<Type> const& getTransitionMatrix() const;
storm::dd::Add<Type> const& getTransitionMatrix() const;
/*!
* Retrieves the matrix representing the transitions of the model.
*
* @return A matrix representing the transitions of the model.
*/
storm::dd::Dd<Type>& getTransitionMatrix();
storm::dd::Add<Type>& getTransitionMatrix();
/*!
* Retrieves the matrix representing the transition rewards of the model. Note that calling this method
@ -140,7 +140,7 @@ namespace storm {
*
* @return The matrix representing the transition rewards of the model.
*/
storm::dd::Dd<Type> const& getTransitionRewardMatrix() const;
storm::dd::Add<Type> const& getTransitionRewardMatrix() const;
/*!
* Retrieves the matrix representing the transition rewards of the model. Note that calling this method
@ -148,7 +148,7 @@ namespace storm {
*
* @return The matrix representing the transition rewards of the model.
*/
storm::dd::Dd<Type>& getTransitionRewardMatrix();
storm::dd::Add<Type>& getTransitionRewardMatrix();
/*!
* Retrieves a vector representing the state rewards of the model. Note that calling this method is only
@ -156,7 +156,7 @@ namespace storm {
*
* @return A vector representing the state rewards of the model.
*/
storm::dd::Dd<Type> const& getStateRewardVector() const;
storm::dd::Add<Type> const& getStateRewardVector() const;
/*!
* Retrieves whether this model has state rewards.
@ -206,7 +206,7 @@ namespace storm {
*
* @param transitionMatrix The new transition matrix of the model.
*/
void setTransitionMatrix(storm::dd::Dd<Type> const& transitionMatrix);
void setTransitionMatrix(storm::dd::Add<Type> const& transitionMatrix);
/*!
* Retrieves the mapping of labels to their defining expressions.
@ -220,25 +220,25 @@ namespace storm {
std::shared_ptr<storm::dd::DdManager<Type>> manager;
// A vector representing the reachable states of the model.
storm::dd::Dd<Type> reachableStates;
storm::dd::Bdd<Type> reachableStates;
// A vector representing the initial states of the model.
storm::dd::Dd<Type> initialStates;
storm::dd::Bdd<Type> initialStates;
// A matrix representing transition relation.
storm::dd::Dd<Type> transitionMatrix;
storm::dd::Add<Type> transitionMatrix;
// The meta variables used to encode the rows of the transition matrix.
std::set<storm::expressions::Variable> rowVariables;
// An adapter that can translate expressions to DDs over the row meta variables.
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter;
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter;
// The meta variables used to encode the columns of the transition matrix.
std::set<storm::expressions::Variable> columnVariables;
// An adapter that can translate expressions to DDs over the column meta variables.
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter;
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter;
// A vector holding all pairs of row and column meta variable pairs. This is used to swap the variables
// in the DDs from row to column variables and vice versa.
@ -248,10 +248,10 @@ namespace storm {
std::map<std::string, storm::expressions::Expression> labelToExpressionMap;
// If set, a vector representing the rewards of the states.
boost::optional<storm::dd::Dd<Type>> stateRewardVector;
boost::optional<storm::dd::Add<Type>> stateRewardVector;
// If set, a matrix representing the rewards of transitions.
boost::optional<storm::dd::Dd<Type>> transitionRewardMatrix;
boost::optional<storm::dd::Add<Type>> transitionRewardMatrix;
};
} // namespace symbolic

18
src/models/symbolic/NondeterministicModel.cpp

@ -7,18 +7,18 @@ namespace storm {
template<storm::dd::DdType Type>
NondeterministicModel<Type>::NondeterministicModel(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix)
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector,
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix)
: Model<Type>(modelType, manager, reachableStates, initialStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, optionalStateRewardVector, optionalTransitionRewardMatrix), nondeterminismVariables(nondeterminismVariables) {
// Prepare the mask of illegal nondeterministic choices.
@ -31,7 +31,7 @@ namespace storm {
std::set<storm::expressions::Variable> rowAndNondeterminsmVariables;
std::set_union(this->getNondeterminismVariables().begin(), this->getNondeterminismVariables().end(), this->getRowVariables().begin(), this->getRowVariables().end(), std::inserter(rowAndNondeterminsmVariables, rowAndNondeterminsmVariables.begin()));
storm::dd::Dd<Type> tmp = this->getTransitionMatrix().notZero().existsAbstract(this->getColumnVariables()).toMtbdd().sumAbstract(rowAndNondeterminsmVariables);
storm::dd::Add<Type> tmp = this->getTransitionMatrix().notZero().existsAbstract(this->getColumnVariables()).toAdd().sumAbstract(rowAndNondeterminsmVariables);
return static_cast<uint_fast64_t>(tmp.getValue());
}
@ -41,7 +41,7 @@ namespace storm {
}
template<storm::dd::DdType Type>
storm::dd::Dd<Type> const& NondeterministicModel<Type>::getIllegalMask() const {
storm::dd::Bdd<Type> const& NondeterministicModel<Type>::getIllegalMask() const {
return illegalMask;
}

18
src/models/symbolic/NondeterministicModel.h

@ -44,18 +44,18 @@ namespace storm {
*/
NondeterministicModel(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Dd<Type> reachableStates,
storm::dd::Dd<Type> initialStates,
storm::dd::Dd<Type> transitionMatrix,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Add<Type> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> rowExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::DdExpressionAdapter<Type>> columnExpressionAdapter,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap = std::map<std::string, storm::expressions::Expression>(),
boost::optional<storm::dd::Dd<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Dd<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
boost::optional<storm::dd::Add<Type>> const& optionalStateRewardVector = boost::optional<storm::dd::Dd<Type>>(),
boost::optional<storm::dd::Add<Type>> const& optionalTransitionRewardMatrix = boost::optional<storm::dd::Dd<Type>>());
/*!
* Retrieves the number of nondeterministic choices in the model.
@ -76,7 +76,7 @@ namespace storm {
*
* @return A BDD characterizing all illegal nondeterminism encodings in the model.
*/
storm::dd::Dd<Type> const& getIllegalMask() const;
storm::dd::Bdd<Type> const& getIllegalMask() const;
virtual void printModelInformationToStream(std::ostream& out) const override;
@ -86,7 +86,7 @@ namespace storm {
std::set<storm::expressions::Variable> nondeterminismVariables;
// A mask that characterizes all legal nondeterministic choices.
storm::dd::Dd<Type> illegalMask;
storm::dd::Bdd<Type> illegalMask;
};
} // namespace symbolic

846
src/storage/dd/CuddAdd.cpp
File diff suppressed because it is too large
View File

556
src/storage/dd/CuddAdd.h

@ -1,16 +1,10 @@
#ifndef STORM_STORAGE_DD_CUDDDD_H_
#define STORM_STORAGE_DD_CUDDDD_H_
#ifndef STORM_STORAGE_DD_CUDDADD_H_
#define STORM_STORAGE_DD_CUDDADD_H_
#include <map>
#include <set>
#include <memory>
#include <iostream>
#include <boost/variant.hpp>
#include "src/storage/dd/Dd.h"
#include "src/storage/dd/Add.h"
#include "src/storage/dd/CuddDd.h"
#include "src/storage/dd/CuddDdForwardIterator.h"
#include "src/storage/SparseMatrix.h"
#include "src/storage/expressions/Expression.h"
#include "src/storage/expressions/Variable.h"
#include "src/utility/OsDetection.h"
@ -22,22 +16,24 @@ namespace storm {
// Forward-declare some classes.
template<DdType Type> class DdManager;
template<DdType Type> class Odd;
template<DdType Type> class Bdd;
template<>
class Dd<DdType::CUDD> {
class Add<DdType::CUDD> : public Dd<DdType::CUDD> {
public:
// Declare the DdManager and DdIterator class as friend so it can access the internals of a DD.
friend class DdManager<DdType::CUDD>;
friend class DdForwardIterator<DdType::CUDD>;
friend class Bdd<DdType::CUDD>;
friend class Odd<DdType::CUDD>;
// Instantiate all copy/move constructors/assignments with the default implementation.
Dd() = default;
Dd(Dd<DdType::CUDD> const& other) = default;
Dd& operator=(Dd<DdType::CUDD> const& other) = default;
Add() = default;
Add(Add<DdType::CUDD> const& other) = default;
Add& operator=(Add<DdType::CUDD> const& other) = default;
#ifndef WINDOWS
Dd(Dd<DdType::CUDD>&& other) = default;
Dd& operator=(Dd<DdType::CUDD>&& other) = default;
Add(Add<DdType::CUDD>&& other) = default;
Add& operator=(Add<DdType::CUDD>&& other) = default;
#endif
/*!
@ -46,7 +42,7 @@ namespace storm {
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the same function.
*/
bool operator==(Dd<DdType::CUDD> const& other) const;
bool operator==(Add<DdType::CUDD> const& other) const;
/*!
* Retrieves whether the two DDs represent different functions.
@ -54,375 +50,309 @@ namespace storm {
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the different functions.
*/
bool operator!=(Dd<DdType::CUDD> const& other) const;
bool operator!=(Add<DdType::CUDD> const& other) const;
/*!
* Performs an if-then-else with the given operands, i.e. maps all valuations that are mapped to a non-zero
* function value to the function values specified by the first DD and all others to the function values
* specified by the second DD.
*/
Dd<DdType::CUDD> ite(Dd<DdType::CUDD> const& thenDd, Dd<DdType::CUDD> const& elseDd) const;
/*!
* Performs a logical or of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical or of the operands.
*/
Dd<DdType::CUDD> operator||(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical or of the current and the given DD and assigns it to the current DD.
*
* @param other The second DD used for the operation.
* @return A reference to the current DD after the operation
*/
Dd<DdType::CUDD>& operator|=(Dd<DdType::CUDD> const& other);
/*!
* Performs a logical and of the current and the given DD.
*
* @param other The second DD used for the operation.
* @return The logical and of the operands.
*/
Dd<DdType::CUDD> operator&&(Dd<DdType::CUDD> const& other) const;
/*!
* Performs a logical and of the current and the given DD and assigns it to the current DD.
*
* @param other The second DD used for the operation.
* @return A reference to the current DD after the operation
* @param thenDd The ADD specifying the 'then' part.
* @param elseDd The ADD specifying the 'else' part.
* @return The ADD corresponding to the if-then-else of the operands.
*/
Dd<DdType::CUDD>& operator&=(Dd<DdType::CUDD> const& other);
Add<DdType::CUDD> ite(Add<DdType::CUDD> const& thenDd, Add<DdType::CUDD> const& elseDd) const;
/*!
* Performs a logical iff of the current and the given DD.
* Logically inverts the current ADD. That is, all inputs yielding non-zero values will be mapped to zero in
* the result and vice versa.
*
* @param other The second DD used for the operation.
* @return The logical iff of the operands.
* @return The resulting ADD.
*/
Dd<DdType::CUDD> iff(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> operator!() const;
/*!
* Performs a logical exclusive-or of the current and the given DD.
* Performs a logical or of the current anBd the given ADD. As a prerequisite, the operand ADDs need to be
* 0/1 ADDs.
*
* @param other The second DD used for the operation.
* @return The logical exclusive-or of the operands.
* @param other The second ADD used for the operation.
* @return The logical or of the operands.
*/
Dd<DdType::CUDD> exclusiveOr(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> operator||(Add<DdType::CUDD> const& other) const;
/*!
* Performs a logical implication of the current and the given DD.
* Performs a logical or of the current and the given ADD and assigns it to the current ADD. As a
* prerequisite, the operand ADDs need to be 0/1 ADDs.
*
* @param other The second DD used for the operation.
* @return The logical implication of the operands.
* @param other The second ADD used for the operation.
* @return A reference to the current ADD after the operation
*/
Dd<DdType::CUDD> implies(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD>& operator|=(Add<DdType::CUDD> const& other);
/*!
* Adds the two DDs.
* Adds the two ADDs.
*
* @param other The DD to add to the current one.
* @param other The ADD to add to the current one.
* @return The result of the addition.
*/
Dd<DdType::CUDD> operator+(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> operator+(Add<DdType::CUDD> const& other) const;
/*!
* Adds the given DD to the current one.
* Adds the given ADD to the current one.
*
* @param other The DD to add to the current one.
* @return A reference to the current DD after the operation.
* @param other The ADD to add to the current one.
* @return A reference to the current ADD after the operation.
*/
Dd<DdType::CUDD>& operator+=(Dd<DdType::CUDD> const& other);
Add<DdType::CUDD>& operator+=(Add<DdType::CUDD> const& other);
/*!
* Multiplies the two DDs.
* Multiplies the two ADDs.
*
* @param other The DD to multiply with the current one.
* @param other The ADD to multiply with the current one.
* @return The result of the multiplication.
*/
Dd<DdType::CUDD> operator*(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> operator*(Add<DdType::CUDD> const& other) const;
/*!
* Multiplies the given DD with the current one and assigns the result to the current DD.
* Multiplies the given ADD with the current one and assigns the result to the current ADD.
*
* @param other The DD to multiply with the current one.
* @return A reference to the current DD after the operation.
* @param other The ADD to multiply with the current one.
* @return A reference to the current ADD after the operation.
*/
Dd<DdType::CUDD>& operator*=(Dd<DdType::CUDD> const& other);
Add<DdType::CUDD>& operator*=(Add<DdType::CUDD> const& other);
/*!
* Subtracts the given DD from the current one.
* Subtracts the given ADD from the current one.
*
* @param other The DD to subtract from the current one.
* @param other The ADD to subtract from the current one.
* @return The result of the subtraction.
*/
Dd<DdType::CUDD> operator-(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> operator-(Add<DdType::CUDD> const& other) const;
/*!
* Subtracts the DD from the constant zero function.
* Subtracts the ADD from the constant zero function.
*
* @return The resulting function represented as a DD.
* @return The resulting function represented as a ADD.
*/
Dd<DdType::CUDD> operator-() const;
Add<DdType::CUDD> operator-() const;
/*!
* Subtracts the given DD from the current one and assigns the result to the current DD.
* Subtracts the given ADD from the current one and assigns the result to the current ADD.
*
* @param other The DD to subtract from the current one.
* @return A reference to the current DD after the operation.
* @param other The ADD to subtract from the current one.
* @return A reference to the current ADD after the operation.
*/
Dd<DdType::CUDD>& operator-=(Dd<DdType::CUDD> const& other);
Add<DdType::CUDD>& operator-=(Add<DdType::CUDD> const& other);
/*!
* Divides the current DD by the given one.
* Divides the current ADD by the given one.
*
* @param other The DD by which to divide the current one.
* @param other The ADD by which to divide the current one.
* @return The result of the division.
*/
Dd<DdType::CUDD> operator/(Dd<DdType::CUDD> const& other) const;
/*!
* Divides the current DD by the given one and assigns the result to the current DD.
*
* @param other The DD by which to divide the current one.
* @return A reference to the current DD after the operation.
*/
Dd<DdType::CUDD>& operator/=(Dd<DdType::CUDD> const& other);
/*!
* Retrieves the logical complement of the current DD. The result will map all encodings with a value
* unequal to zero to false and all others to true.
*
* @return The logical complement of the current DD.
*/
Dd<DdType::CUDD> operator!() const;
Add<DdType::CUDD> operator/(Add<DdType::CUDD> const& other) const;
/*!
* Logically complements the current DD. The result will map all encodings with a value
* unequal to zero to false and all others to true.
* Divides the current ADD by the given one and assigns the result to the current ADD.
*
* @return A reference to the current DD after the operation.
* @param other The ADD by which to divide the current one.
* @return A reference to the current ADD after the operation.
*/
Dd<DdType::CUDD>& complement();
Add<DdType::CUDD>& operator/=(Add<DdType::CUDD> const& other);
/*!
* Retrieves the function that maps all evaluations to one that have an identical function values.
* Retrieves the function that maps all evaluations to one that have identical function values.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
* @param other The ADD with which to perform the operation.
* @return The resulting function represented as an ADD.
*/
Dd<DdType::CUDD> equals(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> equals(Add<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one that have distinct function values.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> notEquals(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are less
* than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<DdType::CUDD> less(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are less or
* equal than the one in the given DD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
* @param other The ADD with which to perform the operation.
* @return The resulting function represented as an ADD.
*/
Dd<DdType::CUDD> lessOrEqual(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> notEquals(Add<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
* than the one in the given DD.
* Retrieves the function that maps all evaluations to one whose function value in the first ADD are less
* than the one in the given ADD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
* @param other The ADD with which to perform the operation.
* @return The resulting function represented as an ADD.
*/
Dd<DdType::CUDD> greater(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> less(Add<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
* or equal than the one in the given DD.
* Retrieves the function that maps all evaluations to one whose function value in the first ADD are less or
* equal than the one in the given ADD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
* @return The resulting function represented as an ADD.
*/
Dd<DdType::CUDD> greaterOrEqual(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> lessOrEqual(Add<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to the minimum of the function values of the two DDs.
* Retrieves the function that maps all evaluations to one whose function value in the first ADD are greater
* than the one in the given ADD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
* @param other The ADD with which to perform the operation.
* @return The resulting function represented as an ADD.
*/
Dd<DdType::CUDD> minimum(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> greater(Add<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to the maximum of the function values of the two DDs.
* Retrieves the function that maps all evaluations to one whose function value in the first ADD are greater
* or equal than the one in the given ADD.
*
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
* @param other The ADD with which to perform the operation.
* @return The resulting function represented as an ADD.
*/
Dd<DdType::CUDD> maximum(Dd<DdType::CUDD> const& other) const;
Add<DdType::CUDD> greaterOrEqual(Add<DdType::CUDD> const& other) const;
/*!
* Existentially abstracts from the given meta variables.
* Retrieves the function that maps all evaluations to the minimum of the function values of the two ADDs.
*
* @param metaVariables The meta variables from which to abstract.
* @param other The ADD with which to perform the operation.
* @return The resulting function represented as an ADD.
*/
Dd<DdType::CUDD> existsAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
Add<DdType::CUDD> minimum(Add<DdType::CUDD> const& other) const;
/*!
* Universally abstracts from the given meta variables.
* Retrieves the function that maps all evaluations to the maximum of the function values of the two ADDs.
*
* @param metaVariables The meta variables from which to abstract.
* @param other The ADD with which to perform the operation.
* @return The resulting function represented as an ADD.
*/
Dd<DdType::CUDD> universalAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
Add<DdType::CUDD> maximum(Add<DdType::CUDD> const& other) const;
/*!
* Sum-abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> sumAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
Add<DdType::CUDD> sumAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Min-abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> minAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
Add<DdType::CUDD> minAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Max-abstracts from the given meta variables.
*
* @param metaVariables The meta variables from which to abstract.
*/
Dd<DdType::CUDD> maxAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
Add<DdType::CUDD> maxAbstract(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Checks whether the current and the given DD represent the same function modulo some given precision.
* Checks whether the current and the given ADD represent the same function modulo some given precision.
*
* @param other The DD with which to compare.
* @param other The ADD with which to compare.
* @param precision An upper bound on the maximal difference between any two function values that is to be
* tolerated.
* @param relative If set to true, not the absolute values have to be within the precision, but the relative
* values.
*/
bool equalModuloPrecision(Dd<DdType::CUDD> const& other, double precision, bool relative = true) const;
bool equalModuloPrecision(Add<DdType::CUDD> const& other, double precision, bool relative = true) const;
/*!
* Swaps the given pairs of meta variables in the DD. The pairs of meta variables must be guaranteed to have
* the same number of underlying DD variables.
* Swaps the given pairs of meta variables in the ADD. The pairs of meta variables must be guaranteed to have
* the same number of underlying ADD variables.
*
* @param metaVariablePairs A vector of meta variable pairs that are to be swapped for one another.
* @return The resulting DD.
* @return The resulting ADD.
*/
Dd<DdType::CUDD> swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs);
Add<DdType::CUDD> swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs);
/*!
* Multiplies the current DD (representing a matrix) with the given matrix by summing over the given meta
* Multiplies the current ADD (representing a matrix) with the given matrix by summing over the given meta
* variables.
*
* @param otherMatrix The matrix with which to multiply.
* @param summationMetaVariables The names of the meta variables over which to sum during the matrix-
* matrix multiplication.
* @return A DD representing the result of the matrix-matrix multiplication.
*/
Dd<DdType::CUDD> multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<storm::expressions::Variable> const& summationMetaVariables) const;
/*!
* Computes the logical and of the current and the given DD and existentially abstracts from the given set
* of variables.
*
* @param other The second DD for the logical and.
* @param existentialVariables The variables from which to existentially abstract.
* @return A DD representing the result.
* @return An ADD representing the result of the matrix-matrix multiplication.
*/
Dd<DdType::CUDD> andExists(Dd<DdType::CUDD> const& other, std::set<storm::expressions::Variable> const& existentialVariables) const;
Add<DdType::CUDD> multiplyMatrix(Add<DdType::CUDD> const& otherMatrix, std::set<storm::expressions::Variable> const& summationMetaVariables) const;
/*!
* Computes a DD that represents the function in which all assignments with a function value strictly larger
* than the given value are mapped to one and all others to zero.
* Computes a BDD that represents the function in which all assignments with a function value strictly
* larger than the given value are mapped to one and all others to zero.
*
* @param value The value used for the comparison.
* @return The resulting DD.
* @return The resulting BDD.
*/
Dd<DdType::CUDD> greater(double value) const;
Bdd<DdType::CUDD> greater(double value) const;
/*!
* Computes a DD that represents the function in which all assignments with a function value larger or equal
* Computes a BDD that represents the function in which all assignments with a function value larger or equal
* to the given value are mapped to one and all others to zero.
*
* @param value The value used for the comparison.
* @return The resulting DD.
* @return The resulting BDD.
*/
Dd<DdType::CUDD> greaterOrEqual(double value) const;
Bdd<DdType::CUDD> greaterOrEqual(double value) const;
/*!
* Computes a DD that represents the function in which all assignments with a function value unequal to zero
* are mapped to one and all others to zero.
* Computes a BDD that represents the function in which all assignments with a function value unequal to
* zero are mapped to one and all others to zero.
*
* @return The resulting DD.
*/
Dd<DdType::CUDD> notZero() const;
Bdd<DdType::CUDD> notZero() const;
/*!
* Computes the constraint of the current DD with the given constraint. That is, the function value of the
* resulting DD will be the same as the current ones for all assignments mapping to one in the constraint
* Computes the constraint of the current ADD with the given constraint. That is, the function value of the
* resulting ADD will be the same as the current ones for all assignments mapping to one in the constraint
* and may be different otherwise.
*
* @param constraint The constraint to use for the operation.
* @return The resulting DD.
* @return The resulting ADD.
*/
Dd<DdType::CUDD> constrain(Dd<DdType::CUDD> const& constraint) const;
Add<DdType::CUDD> constrain(Add<DdType::CUDD> const& constraint) const;
/*!
* Computes the restriction of the current DD with the given constraint. That is, the function value of the
* Computes the restriction of the current ADD with the given constraint. That is, the function value of the
* resulting DD will be the same as the current ones for all assignments mapping to one in the constraint
* and may be different otherwise.
*
* @param constraint The constraint to use for the operation.
* @return The resulting DD.
* @return The resulting ADD.
*/
Dd<DdType::CUDD> restrict(Dd<DdType::CUDD> const& constraint) const;
Add<DdType::CUDD> restrict(Add<DdType::CUDD> const& constraint) const;
/*!
* Retrieves the support of the current DD.
* Retrieves the support of the current ADD.
*
* @return The support represented as a DD.
* @return The support represented as a BDD.
*/
Dd<DdType::CUDD> getSupport() const;
Bdd<DdType::CUDD> getSupport() const;
/*!
* Retrieves the number of encodings that are mapped to a non-zero value.
*
* @return The number of encodings that are mapped to a non-zero value.
*/
uint_fast64_t getNonZeroCount() const;
virtual uint_fast64_t getNonZeroCount() const override;
/*!
* Retrieves the number of leaves of the DD.
* Retrieves the number of leaves of the ADD.
*
* @return The number of leaves of the DD.
* @return The number of leaves of the ADD.
*/
uint_fast64_t getLeafCount() const;
virtual uint_fast64_t getLeafCount() const override;
/*!
* Retrieves the number of nodes necessary to represent the DD.
*
* @return The number of nodes in this DD.
*/
uint_fast64_t getNodeCount() const;
virtual uint_fast64_t getNodeCount() const override;
/*!
* Retrieves the lowest function value of any encoding.
@ -485,23 +415,23 @@ namespace storm {
double getValue(std::map<storm::expressions::Variable, int_fast64_t> const& metaVariableToValueMap = std::map<storm::expressions::Variable, int_fast64_t>()) const;
/*!
* Retrieves whether this DD represents the constant one function.
* Retrieves whether this ADD represents the constant one function.
*
* @return True if this DD represents the constant one function.
* @return True if this ADD represents the constant one function.
*/
bool isOne() const;
/*!
* Retrieves whether this DD represents the constant zero function.
* Retrieves whether this ADD represents the constant zero function.
*
* @return True if this DD represents the constant zero function.
* @return True if this ADD represents the constant zero function.
*/
bool isZero() const;
/*!
* Retrieves whether this DD represents a constant function.
* Retrieves whether this ADD represents a constant function.
*
* @return True if this DD represents a constants function.
* @return True if this ADD represents a constants function.
*/
bool isConstant() const;
@ -510,101 +440,71 @@ namespace storm {
*
* @return The index of the topmost variable in DD.
*/
uint_fast64_t getIndex() const;
virtual uint_fast64_t getIndex() const override;
/*!
* Converts the DD to a vector.
* Converts the ADD to a vector.
*
* @return The double vector that is represented by this DD.
* @return The double vector that is represented by this ADD.
*/
template<typename ValueType>
std::vector<ValueType> toVector() const;
/*!
* Converts the DD to a vector. The given offset-labeled DD is used to determine the correct row of
* Converts the ADD to a vector. The given offset-labeled DD is used to determine the correct row of
* each entry.
*
* @param rowOdd The ODD used for determining the correct row.
* @return The double vector that is represented by this DD.
* @return The double vector that is represented by this ADD.
*/
template<typename ValueType>
std::vector<ValueType> toVector(storm::dd::Odd<DdType::CUDD> const& rowOdd) const;
/*!
* Converts the DD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
* Converts the ADD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
* row, whereas all primed variables are assumed to encode the column.
*
* @return The matrix that is represented by this DD.
* @return The matrix that is represented by this ADD.
*/
storm::storage::SparseMatrix<double> toMatrix() const;
/*!
* Converts the DD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
* Converts the ADD to a (sparse) double matrix. All contained non-primed variables are assumed to encode the
* row, whereas all primed variables are assumed to encode the column. The given offset-labeled DDs are used
* to determine the correct row and column, respectively, for each entry.
*
* @param rowOdd The ODD used for determining the correct row.
* @param columnOdd The ODD used for determining the correct column.
* @return The matrix that is represented by this DD.
* @return The matrix that is represented by this ADD.
*/
storm::storage::SparseMatrix<double> toMatrix(storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
/*!
* Converts the DD to a (sparse) double matrix. The given offset-labeled DDs are used to determine the
* Converts the ADD to a (sparse) double matrix. The given offset-labeled DDs are used to determine the
* correct row and column, respectively, for each entry.
*
* @param rowMetaVariables The meta variables that encode the rows of the matrix.
* @param columnMetaVariables The meta variables that encode the columns of the matrix.
* @param rowOdd The ODD used for determining the correct row.
* @param columnOdd The ODD used for determining the correct column.
* @return The matrix that is represented by this DD.
* @return The matrix that is represented by this ADD.
*/
storm::storage::SparseMatrix<double> toMatrix(std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
/*!
* Converts the DD to a row-grouped (sparse) double matrix. The given offset-labeled DDs are used to
* Converts the ADD to a row-grouped (sparse) double matrix. The given offset-labeled DDs are used to
* determine the correct row and column, respectively, for each entry. Note: this function assumes that
* the meta variables used to distinguish different row groups are at the very top of the DD.
* the meta variables used to distinguish different row groups are at the very top of the ADD.
*
* @param rowMetaVariables The meta variables that encode the rows of the matrix.
* @param columnMetaVariables The meta variables that encode the columns of the matrix.
* @param groupMetaVariables The meta variables that are used to distinguish different row groups.
* @param rowOdd The ODD used for determining the correct row.
* @param columnOdd The ODD used for determining the correct column.
* @return The matrix that is represented by this DD.
* @return The matrix that is represented by this ADD.
*/
storm::storage::SparseMatrix<double> toMatrix(std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::set<storm::expressions::Variable> const& groupMetaVariables, storm::dd::Odd<DdType::CUDD> const& rowOdd, storm::dd::Odd<DdType::CUDD> const& columnOdd) const;
/*!
* Retrieves whether the given meta variable is contained in the DD.
*
* @param metaVariable The meta variable for which to query membership.
* @return True iff the meta variable is contained in the DD.
*/
bool containsMetaVariable(storm::expressions::Variable const& metaVariable) const;
/*!
* Retrieves whether the given meta variables are all contained in the DD.
*
* @param metaVariables The meta variables for which to query membership.
* @return True iff all meta variables are contained in the DD.
*/
bool containsMetaVariables(std::set<storm::expressions::Variable> const& metaVariables) const;
/*!
* Retrieves the set of all meta variables contained in the DD.
*
* @return The set of all meta variables contained in the DD.
*/
std::set<storm::expressions::Variable> const& getContainedMetaVariables() const;
/*!
* Retrieves the set of all meta variables contained in the DD.
*
* @return The set of all meta variables contained in the DD.
*/
std::set<storm::expressions::Variable>& getContainedMetaVariables();
/*!
* Exports the DD to the given file in the dot format.
*
@ -612,13 +512,6 @@ namespace storm {
*/
void exportToDot(std::string const& filename = "") const;
/*!
* Retrieves the manager that is responsible for this DD.
*
* A pointer to the manager that is responsible for this DD.
*/
std::shared_ptr<DdManager<DdType::CUDD> const> getDdManager() const;
/*!
* Retrieves an iterator that points to the first meta variable assignment with a non-zero function value.
*
@ -637,137 +530,40 @@ namespace storm {
*/
DdForwardIterator<DdType::CUDD> end(bool enumerateDontCareMetaVariables = true) const;
/*!
* Converts the DD into a (heavily nested) if-then-else expression that represents the very same function.
* The variable names used in the expression are derived from the meta variable name and are extended with a
* suffix ".i" if the meta variable is integer-valued, expressing that the variable is the i-th bit of the
* meta variable.
*
* @return The resulting expression.
*/
storm::expressions::Expression toExpression() const;
/*!
* Converts the DD into a (heavily nested) if-then-else (with negations) expression that evaluates to true
* if and only if the assignment is minterm of the DD. The variable names used in the expression are derived
* from the meta variable name and are extended with a suffix ".i" if the meta variable is integer-valued,
* expressing that the variable is the i-th bit of the meta variable.
*
* @return The resulting expression.
*/
storm::expressions::Expression getMintermExpression() const;
friend std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd);
friend std::ostream & operator<<(std::ostream& out, const Add<DdType::CUDD>& add);
/*!
* Converts an MTBDD to a BDD by mapping all values unequal to zero to 1. This effectively does the same as
* Converts the ADD to a BDD by mapping all values unequal to zero to 1. This effectively does the same as
* a call to notZero().
*
* @return The corresponding BDD.
*/
Dd<DdType::CUDD> toBdd() const;
/*!
* Converts a BDD to an equivalent MTBDD.
*
* @return The corresponding MTBDD.
*/
Dd<DdType::CUDD> toMtbdd() const;
/*!
* Retrieves whether this DD is a BDD.
*
* @return True iff this DD is a BDD.
*/
bool isBdd() const;
/*!
* Retrieves whether this DD is an MTBDD. Even though MTBDDs technicall subsume BDDs, this will return false
* if the DD is actually a BDD.
*
* @return True iff this DD is an MTBDD.
*/
bool isMtbdd() const;
Bdd<DdType::CUDD> toBdd() const;
private:
/*!
* Retrieves the CUDD BDD object associated with this DD.
*
* @return The CUDD BDD object associated with this DD.
*/
BDD getCuddBdd() const;
/*!
* Retrieves the CUDD MTBDD object associated with this DD.
* Retrieves the CUDD ADD object associated with this ADD.
*
* @return The CUDD MTBDD object associated with this DD.
* @return The CUDD ADD object associated with this ADD.
*/
ADD getCuddMtbdd() const;
ADD getCuddAdd() const;
/*!
* Retrieves the CUDD object associated with this DD.
* Retrieves the raw DD node of CUDD associated with this ADD.
*
* @return The CUDD object associated with this DD.
*/
ABDD const& getCuddDd() const;
/*!
* Retrieves the raw DD node of CUDD associated with this DD.
*
* @return The DD node of CUDD associated with this DD.
* @return The DD node of CUDD associated with this ADD.
*/
DdNode* getCuddDdNode() const;
/*!
* Adds the given meta variable to the set of meta variables that are contained in this DD.
*
* @param metaVariable The name of the meta variable to add.
*/
void addContainedMetaVariable(storm::expressions::Variable const& metaVariable);
/*!
* Removes the given meta variable to the set of meta variables that are contained in this DD.
*
* @param metaVariable The name of the meta variable to remove.
*/
void removeContainedMetaVariable(storm::expressions::Variable const& metaVariable);
/*!
* Performs the recursive step of toExpression on the given DD.
*
* @param dd The dd to translate into an expression.
* @param variables The variables to use in the expression.
* @return The resulting expression.
*/
static storm::expressions::Expression toExpressionRecur(DdNode const* dd, std::vector<storm::expressions::Variable> const& variables);
/*!
* Performs the recursive step of getMintermExpression on the given DD.
*
* @param manager The manager of the DD.
* @param dd The dd whose minterms to translate into an expression.
* @param variables The variables to use in the expression.
* @return The resulting expression.
*/
static storm::expressions::Expression getMintermExpressionRecur(::DdManager* manager, DdNode const* dd, std::vector<storm::expressions::Variable> const& variables);
/*!
* Creates a DD that encapsulates the given CUDD ADD.
*
* @param ddManager The manager responsible for this DD.
* @param cuddDd The CUDD ADD to store.
* @param containedMetaVariables The meta variables that appear in the DD.
*/
Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, ADD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
/*!
* Creates a DD that encapsulates the given CUDD ADD.
* Creates an ADD that encapsulates the given CUDD ADD.
*
* @param ddManager The manager responsible for this DD.
* @param cuddDd The CUDD ADD to store.
* @param cuddAdd The CUDD ADD to store.
* @param containedMetaVariables The meta variables that appear in the DD.
*/
Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
Add(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, ADD cuddAdd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
/*!
* Helper function to convert the DD into a (sparse) matrix.
@ -806,7 +602,7 @@ namespace storm {
* @param maxLevel The number of levels that need to be considered.
* @param remainingMetaVariables The meta variables that remain in the DDs after the groups have been split.
*/
void splitGroupsRec(DdNode* dd, std::vector<Dd<DdType::CUDD>>& groups, std::vector<uint_fast64_t> const& ddGroupVariableIndices, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::set<storm::expressions::Variable> const& remainingMetaVariables) const;
void splitGroupsRec(DdNode* dd, std::vector<Add<DdType::CUDD>>& groups, std::vector<uint_fast64_t> const& ddGroupVariableIndices, uint_fast64_t currentLevel, uint_fast64_t maxLevel, std::set<storm::expressions::Variable> const& remainingMetaVariables) const;
/*!
* Performs a recursive step to add the given DD-based vector to the given explicit vector.
@ -822,24 +618,10 @@ namespace storm {
template<typename ValueType>
void addToVectorRec(DdNode const* dd, uint_fast64_t currentLevel, uint_fast64_t maxLevel, uint_fast64_t currentOffset, Odd<DdType::CUDD> const& odd, std::vector<uint_fast64_t> const& ddVariableIndices, std::vector<ValueType>& targetVector) const;
/*!
* Retrieves the indices of all DD variables that are contained in this DD (not necessarily in the support,
* because they could be "don't cares"). Additionally, the indices are sorted to allow for easy access.
*
* @return The (sorted) indices of all DD variables that are contained in this DD.
*/
std::vector<uint_fast64_t> getSortedVariableIndices() const;
// A pointer to the manager responsible for this DD.
std::shared_ptr<DdManager<DdType::CUDD> const> ddManager;
// The ADD created by CUDD.
boost::variant<BDD, ADD> cuddDd;
// The meta variables that appear in this DD.
std::set<storm::expressions::Variable> containedMetaVariables;
ADD cuddAdd;
};
}
}
#endif /* STORM_STORAGE_DD_CUDDDD_H_ */
#endif /* STORM_STORAGE_DD_CUDDADD_H_ */

138
src/storage/dd/CuddBdd.cpp

@ -5,9 +5,12 @@
#include "src/storage/dd/CuddAdd.h"
#include "src/storage/dd/CuddDdManager.h"
#include "src/utility/macros.h"
#include "src/exceptions/InvalidArgumentException.h"
namespace storm {
namespace dd {
Bdd<DdType::CUDD>::Bdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables) : Dd<DdType::CUDD>(ddManager, containedMetaVariables) {
Bdd<DdType::CUDD>::Bdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddBdd, std::set<storm::expressions::Variable> const& containedMetaVariables) : Dd<DdType::CUDD>(ddManager, containedMetaVariables), cuddBdd(cuddBdd) {
// Intentionally left empty.
}
@ -47,10 +50,11 @@ namespace storm {
Bdd<DdType::CUDD>& Bdd<DdType::CUDD>::complement() {
this->cuddBdd = ~this->getCuddBdd();
return *this;
}
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::operator&&(Bdd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
Bdd<DdType::CUDD> result(*this);
result &= other;
return result;
}
@ -92,7 +96,7 @@ namespace storm {
}
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::existsAbstract(std::set<storm::expressions::Variable> const& metaVariables) const {
Dd<DdType::CUDD> cubeDd(this->getDdManager()->getBddOne());
Bdd<DdType::CUDD> cubeBdd = this->getDdManager()->getBddOne();
std::set<storm::expressions::Variable> newMetaVariables = this->getContainedMetaVariables();
for (auto const& metaVariable : metaVariables) {
@ -101,14 +105,14 @@ namespace storm {
newMetaVariables.erase(metaVariable);
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable);
cubeDd &= ddMetaVariable.getCube();
cubeBdd &= ddMetaVariable.getCube();
}
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().ExistAbstract(cubeDd.getCuddBdd()), newMetaVariables);
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().ExistAbstract(cubeBdd.getCuddBdd()), newMetaVariables);
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::universalAbstract(std::set<storm::expressions::Variable> const& metaVariables) const {
Dd<DdType::CUDD> cubeDd(this->getDdManager()->getBddOne());
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::universalAbstract(std::set<storm::expressions::Variable> const& metaVariables) const {
Bdd<DdType::CUDD> cubeBdd = this->getDdManager()->getBddOne();
std::set<storm::expressions::Variable> newMetaVariables = this->getContainedMetaVariables();
for (auto const& metaVariable : metaVariables) {
@ -117,13 +121,13 @@ namespace storm {
newMetaVariables.erase(metaVariable);
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable);
cubeDd &= ddMetaVariable.getCube();
cubeBdd &= ddMetaVariable.getCube();
}
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().UnivAbstract(cubeDd.getCuddBdd()), newMetaVariables);
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().UnivAbstract(cubeBdd.getCuddBdd()), newMetaVariables);
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) {
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) {
std::set<storm::expressions::Variable> newContainedMetaVariables;
std::vector<BDD> from;
std::vector<BDD> to;
@ -156,12 +160,10 @@ namespace storm {
}
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::andExists(Bdd<DdType::CUDD> const& other, std::set<storm::expressions::Variable> const& existentialVariables) const {
STORM_LOG_WARN_COND(this->isBdd() && other.isBdd(), "Performing logical operation on MTBDD(s).");
Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
Bdd<DdType::CUDD> cubeBdd(this->getDdManager()->getBddOne());
for (auto const& metaVariable : existentialVariables) {
DdMetaVariable<DdType::CUDD> const& ddMetaVariable = this->getDdManager()->getMetaVariable(metaVariable);
cubeDd &= ddMetaVariable.getCube();
cubeBdd &= ddMetaVariable.getCube();
}
std::set<storm::expressions::Variable> unionOfMetaVariables;
@ -169,37 +171,23 @@ namespace storm {
std::set<storm::expressions::Variable> containedMetaVariables;
std::set_difference(unionOfMetaVariables.begin(), unionOfMetaVariables.end(), existentialVariables.begin(), existentialVariables.end(), std::inserter(containedMetaVariables, containedMetaVariables.begin()));
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().AndAbstract(other.getCuddBdd(), cubeDd.getCuddBdd()), containedMetaVariables);
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().AndAbstract(other.getCuddBdd(), cubeBdd.getCuddBdd()), containedMetaVariables);
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::constrain(Dd<DdType::CUDD> const& constraint) const {
std::set<storm::expressions::Variable> metaVariables(this->getContainedMetaVariables());
metaVariables.insert(constraint.getContainedMetaVariables().begin(), constraint.getContainedMetaVariables().end());
if (this->isBdd() && constraint.isBdd()) {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Constrain(constraint.getCuddBdd()), metaVariables);
} else {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddMtbdd().Constrain(constraint.getCuddMtbdd()), metaVariables);
}
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::constrain(Bdd<DdType::CUDD> const& constraint) const {
std::set<storm::expressions::Variable> metaVariables;
std::set_union(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), constraint.getContainedMetaVariables().begin(), constraint.getContainedMetaVariables().end(), std::inserter(metaVariables, metaVariables.begin()));
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Constrain(constraint.getCuddBdd()), metaVariables);
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::restrict(Dd<DdType::CUDD> const& constraint) const {
std::set<storm::expressions::Variable> metaVariables(this->getContainedMetaVariables());
metaVariables.insert(constraint.getContainedMetaVariables().begin(), constraint.getContainedMetaVariables().end());
if (this->isBdd() && constraint.isBdd()) {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Restrict(constraint.getCuddBdd()), metaVariables);
} else {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddMtbdd().Restrict(constraint.getCuddMtbdd()), metaVariables);
}
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::restrict(Bdd<DdType::CUDD> const& constraint) const {
std::set<storm::expressions::Variable> metaVariables;
std::set_union(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), constraint.getContainedMetaVariables().begin(), constraint.getContainedMetaVariables().end(), std::inserter(metaVariables, metaVariables.begin()));
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Restrict(constraint.getCuddBdd()), metaVariables);
}
Dd<DdType::CUDD> Bdd<DdType::CUDD>::getSupport() const {
if (this->isBdd()) {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Support(), this->getContainedMetaVariables());
} else {
return Dd<DdType::CUDD>(this->getDdManager(), this->getCuddMtbdd().Support(), this->getContainedMetaVariables());
}
Bdd<DdType::CUDD> Bdd<DdType::CUDD>::getSupport() const {
return Bdd<DdType::CUDD>(this->getDdManager(), this->getCuddBdd().Support(), this->getContainedMetaVariables());
}
uint_fast64_t Bdd<DdType::CUDD>::getNonZeroCount() const {
@ -207,76 +195,33 @@ namespace storm {
for (auto const& metaVariable : this->getContainedMetaVariables()) {
numberOfDdVariables += this->getDdManager()->getMetaVariable(metaVariable).getNumberOfDdVariables();
}
if (this->isBdd()) {
return static_cast<uint_fast64_t>(this->getCuddBdd().CountMinterm(static_cast<int>(numberOfDdVariables)));
} else {
return static_cast<uint_fast64_t>(this->getCuddMtbdd().CountMinterm(static_cast<int>(numberOfDdVariables)));
}
return static_cast<uint_fast64_t>(this->getCuddBdd().CountMinterm(static_cast<int>(numberOfDdVariables)));
}
uint_fast64_t Bdd<DdType::CUDD>::getLeafCount() const {
if (this->isBdd()) {
return static_cast<uint_fast64_t>(this->getCuddBdd().CountLeaves());
} else {
return static_cast<uint_fast64_t>(this->getCuddMtbdd().CountLeaves());
}
return static_cast<uint_fast64_t>(this->getCuddBdd().CountLeaves());
}
uint_fast64_t Bdd<DdType::CUDD>::getNodeCount() const {
if (this->isBdd()) {
return static_cast<uint_fast64_t>(this->getCuddBdd().nodeCount());
} else {
return static_cast<uint_fast64_t>(this->getCuddMtbdd().nodeCount());
}
return static_cast<uint_fast64_t>(this->getCuddBdd().nodeCount());
}
bool Bdd<DdType::CUDD>::isOne() const {
if (this->isBdd()) {
return this->getCuddBdd().IsOne();
} else {
return this->getCuddMtbdd().IsOne();
}
return this->getCuddBdd().IsOne();
}
bool Bdd<DdType::CUDD>::isZero() const {
if (this->isBdd()) {
return this->getCuddBdd().IsZero();
} else {
return this->getCuddMtbdd().IsZero();
}
return this->getCuddBdd().IsZero();
}
uint_fast64_t Bdd<DdType::CUDD>::getIndex() const {
if (this->isBdd()) {
return static_cast<uint_fast64_t>(this->getCuddBdd().NodeReadIndex());
} else {
return static_cast<uint_fast64_t>(this->getCuddMtbdd().NodeReadIndex());
}
}
std::vector<uint_fast64_t> Bdd<DdType::CUDD>::getSortedVariableIndices() const {
std::vector<uint_fast64_t> ddVariableIndices;
for (auto const& metaVariableName : this->getContainedMetaVariables()) {
auto const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
for (auto const& ddVariable : metaVariable.getDdVariables()) {
ddVariableIndices.push_back(ddVariable.getIndex());
}
}
// Next, we need to sort them, since they may be arbitrarily ordered otherwise.
std::sort(ddVariableIndices.begin(), ddVariableIndices.end());
return ddVariableIndices;
return static_cast<uint_fast64_t>(this->getCuddBdd().NodeReadIndex());
}
void Bdd<DdType::CUDD>::exportToDot(std::string const& filename) const {
if (filename.empty()) {
if (this->isBdd()) {
std::vector<BDD> cuddBddVector = { this->getCuddBdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddBddVector);
} else {
std::vector<ADD> cuddAddVector = { this->getCuddMtbdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddAddVector);
}
std::vector<BDD> cuddBddVector = { this->getCuddBdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddBddVector);
} else {
// Build the name input of the DD.
std::vector<char*> ddNames;
@ -294,13 +239,8 @@ namespace storm {
// Open the file, dump the DD and close it again.
FILE* filePointer = fopen(filename.c_str() , "w");
if (this->isBdd()) {
std::vector<BDD> cuddBddVector = { this->getCuddBdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddBddVector, &ddVariableNames[0], &ddNames[0], filePointer);
} else {
std::vector<ADD> cuddAddVector = { this->getCuddMtbdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddAddVector, &ddVariableNames[0], &ddNames[0], filePointer);
}
std::vector<BDD> cuddBddVector = { this->getCuddBdd() };
this->getDdManager()->getCuddManager().DumpDot(cuddBddVector, &ddVariableNames[0], &ddNames[0], filePointer);
fclose(filePointer);
// Finally, delete the names.
@ -313,8 +253,8 @@ namespace storm {
}
}
std::ostream& operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd) {
dd.exportToDot();
std::ostream& operator<<(std::ostream& out, const Bdd<DdType::CUDD>& bdd) {
bdd.exportToDot();
return out;
}
}

12
src/storage/dd/CuddBdd.h

@ -23,6 +23,7 @@ namespace storm {
// Declare the DdManager and DdIterator class as friend so it can access the internals of a DD.
friend class DdManager<DdType::CUDD>;
friend class DdForwardIterator<DdType::CUDD>;
friend class Add<DdType::CUDD>;
friend class Odd<DdType::CUDD>;
// Instantiate all copy/move constructors/assignments with the default implementation.
@ -198,6 +199,13 @@ namespace storm {
*/
virtual uint_fast64_t getNonZeroCount() const override;
/*!
* Retrieves the number of leaves of the DD.
*
* @return The number of leaves of the DD.
*/
virtual uint_fast64_t getLeafCount() const override;
/*!
* Retrieves the number of nodes necessary to represent the DD.
*
@ -261,10 +269,10 @@ namespace storm {
* Creates a DD that encapsulates the given CUDD ADD.
*
* @param ddManager The manager responsible for this DD.
* @param cuddDd The CUDD ADD to store.
* @param cuddBdd The CUDD BDD to store.
* @param containedMetaVariables The meta variables that appear in the DD.
*/
Bdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddDd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
Bdd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, BDD cuddBdd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
// The BDD created by CUDD.
BDD cuddBdd;

14
src/storage/dd/CuddDd.cpp

@ -48,5 +48,19 @@ namespace storm {
std::set_difference(containedMetaVariables.begin(), containedMetaVariables.end(), metaVariables.begin(), metaVariables.end(), std::inserter(result, result.begin()));
containedMetaVariables = std::move(result);
}
std::vector<uint_fast64_t> Dd<DdType::CUDD>::getSortedVariableIndices() const {
std::vector<uint_fast64_t> ddVariableIndices;
for (auto const& metaVariableName : this->getContainedMetaVariables()) {
auto const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
for (auto const& ddVariable : metaVariable.getDdVariables()) {
ddVariableIndices.push_back(ddVariable.getIndex());
}
}
// Next, we need to sort them, since they may be arbitrarily ordered otherwise.
std::sort(ddVariableIndices.begin(), ddVariableIndices.end());
return ddVariableIndices;
}
}
}

7
src/storage/dd/CuddDd.h

@ -105,6 +105,13 @@ namespace storm {
*/
std::shared_ptr<DdManager<DdType::CUDD> const> getDdManager() const;
/*!
* Retrieves the (sorted) list of the variable indices of DD variables contained in this DD.
*
* @return The sorted list of variable indices.
*/
std::vector<uint_fast64_t> getSortedVariableIndices() const;
protected:
/*!

4
src/storage/dd/CuddDdForwardIterator.h

@ -17,12 +17,12 @@ namespace storm {
namespace dd {
// Forward-declare the DdManager class.
template<DdType Type> class DdManager;
template<DdType Type> class Dd;
template<DdType Type> class Add;
template<>
class DdForwardIterator<DdType::CUDD> {
public:
friend class Dd<DdType::CUDD>;
friend class Add<DdType::CUDD>;
// Default-instantiate the constructor.
DdForwardIterator();

69
src/storage/dd/CuddDdManager.cpp

@ -37,27 +37,28 @@ namespace storm {
}
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getOne(bool asMtbdd) const {
if (asMtbdd) {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addOne());
} else {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddOne());
}
Bdd<DdType::CUDD> DdManager<DdType::CUDD>::getBddOne() const {
return Bdd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddOne());
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getZero(bool asMtbdd) const {
if (asMtbdd) {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addZero());
} else {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddZero());
}
Add<DdType::CUDD> DdManager<DdType::CUDD>::getAddOne() const {
return Add<DdType::CUDD>(this->shared_from_this(), cuddManager.addOne());
}
Bdd<DdType::CUDD> DdManager<DdType::CUDD>::getBddZero() const {
return Bdd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddZero());
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getConstant(double value) const {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.constant(value));
Add<DdType::CUDD> DdManager<DdType::CUDD>::getAddZero() const {
return Add<DdType::CUDD>(this->shared_from_this(), cuddManager.addZero());
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getEncoding(storm::expressions::Variable const& variable, int_fast64_t value, bool asMtbdd) const {
Add<DdType::CUDD> DdManager<DdType::CUDD>::getConstant(double value) const {
return Add<DdType::CUDD>(this->shared_from_this(), cuddManager.constant(value));
}
Bdd<DdType::CUDD> DdManager<DdType::CUDD>::getEncoding(storm::expressions::Variable const& variable, int_fast64_t value) const {
DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(variable);
STORM_LOG_THROW(value >= metaVariable.getLow() && value <= metaVariable.getHigh(), storm::exceptions::InvalidArgumentException, "Illegal value " << value << " for meta variable '" << variable.getName() << "'.");
@ -65,9 +66,9 @@ namespace storm {
// Now compute the encoding relative to the low value of the meta variable.
value -= metaVariable.getLow();
std::vector<Dd<DdType::CUDD>> const& ddVariables = metaVariable.getDdVariables();
std::vector<Bdd<DdType::CUDD>> const& ddVariables = metaVariable.getDdVariables();
Dd<DdType::CUDD> result;
Bdd<DdType::CUDD> result;
if (value & (1ull << (ddVariables.size() - 1))) {
result = ddVariables[0];
} else {
@ -82,31 +83,27 @@ namespace storm {
}
}
if (asMtbdd) {
return result.toMtbdd();
} else {
return result;
}
return result;
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getRange(storm::expressions::Variable const& variable, bool asMtbdd) const {
Bdd<DdType::CUDD> DdManager<DdType::CUDD>::getRange(storm::expressions::Variable const& variable) const {
storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(variable);
Dd<DdType::CUDD> result = this->getZero(asMtbdd);
Bdd<DdType::CUDD> result = this->getBddZero();
for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
result.setValue(variable, value, static_cast<double>(1));
result |= this->getEncoding(variable, value);
}
return result;
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getIdentity(storm::expressions::Variable const& variable) const {
Add<DdType::CUDD> DdManager<DdType::CUDD>::getIdentity(storm::expressions::Variable const& variable) const {
storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(variable);
Dd<DdType::CUDD> result = this->getZero(true);
Add<DdType::CUDD> result = this->getAddZero();
for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
result.setValue(variable, value, static_cast<double>(value));
result += this->getEncoding(variable, value).toAdd() * this->getConstant(value);
}
return result;
}
@ -126,11 +123,11 @@ namespace storm {
storm::expressions::Variable unprimed = manager->declareBitVectorVariable(name, numberOfBits);
storm::expressions::Variable primed = manager->declareBitVectorVariable(name + "'", numberOfBits);
std::vector<Dd<DdType::CUDD>> variables;
std::vector<Dd<DdType::CUDD>> variablesPrime;
std::vector<Bdd<DdType::CUDD>> variables;
std::vector<Bdd<DdType::CUDD>> variablesPrime;
for (std::size_t i = 0; i < numberOfBits; ++i) {
variables.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddVar(), {unprimed}));
variablesPrime.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddVar(), {primed}));
variables.emplace_back(Bdd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddVar(), {unprimed}));
variablesPrime.emplace_back(Bdd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddVar(), {primed}));
}
// Now group the non-primed and primed variable.
@ -154,10 +151,10 @@ namespace storm {
storm::expressions::Variable unprimed = manager->declareBooleanVariable(name);
storm::expressions::Variable primed = manager->declareBooleanVariable(name + "'");
std::vector<Dd<DdType::CUDD>> variables;
std::vector<Dd<DdType::CUDD>> variablesPrime;
variables.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddVar(), {unprimed}));
variablesPrime.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddVar(), {primed}));
std::vector<Bdd<DdType::CUDD>> variables;
std::vector<Bdd<DdType::CUDD>> variablesPrime;
variables.emplace_back(Bdd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddVar(), {unprimed}));
variablesPrime.emplace_back(Bdd<DdType::CUDD>(this->shared_from_this(), cuddManager.bddVar(), {primed}));
// Now group the non-primed and primed variable.
this->getCuddManager().MakeTreeNode(variables.front().getIndex(), 2, MTR_FIXED);

51
src/storage/dd/CuddDdManager.h

@ -18,7 +18,8 @@ namespace storm {
template<>
class DdManager<DdType::CUDD> : public std::enable_shared_from_this<DdManager<DdType::CUDD>> {
public:
friend class Dd<DdType::CUDD>;
friend class Bdd<DdType::CUDD>;
friend class Add<DdType::CUDD>;
friend class Odd<DdType::CUDD>;
friend class DdForwardIterator<DdType::CUDD>;
@ -36,58 +37,68 @@ namespace storm {
#endif
/*!
* Retrieves a DD representing the constant one function. If the flag is set, the result will be given in
* terms of an MTBDD rather than a BDD.
* Retrieves a BDD representing the constant one function.
*
* @return A DD representing the constant one function.
* @return A BDD representing the constant one function.
*/
Dd<DdType::CUDD> getOne(bool asMtbdd = false) const;
Bdd<DdType::CUDD> getBddOne() const;
/*!
* Retrieves a DD representing the constant zero function. If the flag is set, the result will be given in
* terms of an MTBDD rather than a BDD.
* Retrieves an ADD representing the constant one function.
*
* @return A DD representing the constant zero function.
* @return An ADD representing the constant one function.
*/
Dd<DdType::CUDD> getZero(bool asMtbdd = false) const;
Add<DdType::CUDD> getAddOne() const;
/*!
* Retrieves a DD representing the constant function with the given value.
* Retrieves a BDD representing the constant zero function.
*
* @return A DD representing the constant function with the given value.
* @return A BDD representing the constant zero function.
*/
Dd<DdType::CUDD> getConstant(double value) const;
Bdd<DdType::CUDD> getBddZero() const;
/*!
* Retrieves the DD representing the function that maps all inputs which have the given meta variable equal
* Retrieves an ADD representing the constant zero function.
*
* @return An ADD representing the constant zero function.
*/
Add<DdType::CUDD> getAddZero() const;
/*!
* Retrieves an ADD representing the constant function with the given value.
*
* @return An ADD representing the constant function with the given value.
*/
Add<DdType::CUDD> getConstant(double value) const;
/*!
* Retrieves the BDD representing the function that maps all inputs which have the given meta variable equal
* to the given value one.
*
* @param variable The expression variable associated with the meta variable.
* @param value The value the meta variable is supposed to have.
* @param asMtbdd If set to true, the result will be given in terms of an MTBDD.
* @return The DD representing the function that maps all inputs which have the given meta variable equal
* to the given value one.
*/
Dd<DdType::CUDD> getEncoding(storm::expressions::Variable const& variable, int_fast64_t value, bool asMtbdd = false) const;
Bdd<DdType::CUDD> getEncoding(storm::expressions::Variable const& variable, int_fast64_t value) const;
/*!
* Retrieves the DD representing the range of the meta variable, i.e., a function that maps all legal values
* Retrieves the BDD representing the range of the meta variable, i.e., a function that maps all legal values
* of the range of the meta variable to one.
*
* @param variable The expression variable associated with the meta variable.
* @param asMtbdd If set to true, the result will be given in terms of an MTBDD.
* @return The range of the meta variable.
*/
Dd<DdType::CUDD> getRange(storm::expressions::Variable const& variable, bool asMtbdd = false) const;
Bdd<DdType::CUDD> getRange(storm::expressions::Variable const& variable) const;
/*!
* Retrieves the DD representing the identity of the meta variable, i.e., a function that maps all legal
* Retrieves the ADD representing the identity of the meta variable, i.e., a function that maps all legal
* values of the range of the meta variable to themselves.
*
* @param variable The expression variable associated with the meta variable.
* @return The identity of the meta variable.
*/
Dd<DdType::CUDD> getIdentity(storm::expressions::Variable const& variable) const;
Add<DdType::CUDD> getIdentity(storm::expressions::Variable const& variable) const;
/*!
* Adds an integer meta variable with the given range.

15
src/storage/dd/CuddDdMetaVariable.cpp

@ -3,20 +3,18 @@
namespace storm {
namespace dd {
DdMetaVariable<DdType::CUDD>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager) : name(name), type(MetaVariableType::Int), low(low), high(high), ddVariables(ddVariables), cube(manager->getOne()), cubeAsMtbdd(manager->getOne(true)), manager(manager) {
DdMetaVariable<DdType::CUDD>::DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Bdd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager) : name(name), type(MetaVariableType::Int), low(low), high(high), ddVariables(ddVariables), cube(manager->getBddOne()), manager(manager) {
// Create the cube of all variables of this meta variable.
for (auto const& ddVariable : this->ddVariables) {
this->cube &= ddVariable;
}
this->cubeAsMtbdd = this->cube.toMtbdd();
}
DdMetaVariable<DdType::CUDD>::DdMetaVariable(std::string const& name, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager) : name(name), type(MetaVariableType::Bool), low(0), high(1), ddVariables(ddVariables), cube(manager->getOne()), cubeAsMtbdd(manager->getOne(true)), manager(manager) {
DdMetaVariable<DdType::CUDD>::DdMetaVariable(std::string const& name, std::vector<Bdd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager) : name(name), type(MetaVariableType::Bool), low(0), high(1), ddVariables(ddVariables), cube(manager->getBddOne()), manager(manager) {
// Create the cube of all variables of this meta variable.
for (auto const& ddVariable : this->ddVariables) {
this->cube &= ddVariable;
}
this->cubeAsMtbdd = this->cube.toMtbdd();
}
std::string const& DdMetaVariable<DdType::CUDD>::getName() const {
@ -43,17 +41,12 @@ namespace storm {
return this->manager;
}
std::vector<Dd<DdType::CUDD>> const& DdMetaVariable<DdType::CUDD>::getDdVariables() const {
std::vector<Bdd<DdType::CUDD>> const& DdMetaVariable<DdType::CUDD>::getDdVariables() const {
return this->ddVariables;
}
Dd<DdType::CUDD> const& DdMetaVariable<DdType::CUDD>::getCube() const {
Bdd<DdType::CUDD> const& DdMetaVariable<DdType::CUDD>::getCube() const {
return this->cube;
}
Dd<DdType::CUDD> const& DdMetaVariable<DdType::CUDD>::getCubeAsMtbdd() const {
return this->cubeAsMtbdd;
}
}
}

29
src/storage/dd/CuddDdMetaVariable.h

@ -7,8 +7,10 @@
#include <string>
#include "utility/OsDetection.h"
#include "src/storage/dd/CuddDd.h"
#include "src/storage/dd/CuddBdd.h"
#include "src/storage/dd/CuddAdd.h"
#include "src/storage/dd/DdMetaVariable.h"
#include "src/storage/dd/CuddDdForwardIterator.h"
#include "src/storage/expressions/Expression.h"
namespace storm {
@ -23,6 +25,8 @@ namespace storm {
// Declare the DdManager class as friend so it can access the internals of a meta variable.
friend class DdManager<DdType::CUDD>;
friend class Dd<DdType::CUDD>;
friend class Bdd<DdType::CUDD>;
friend class Add<DdType::CUDD>;
friend class Odd<DdType::CUDD>;
friend class DdForwardIterator<DdType::CUDD>;
@ -38,7 +42,7 @@ namespace storm {
* @param ddVariables The vector of variables used to encode this variable.
* @param manager A pointer to the manager that is responsible for this meta variable.
*/
DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager);
DdMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high, std::vector<Bdd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager);
/*!
* Creates a boolean meta variable with the given name.
@ -46,7 +50,7 @@ namespace storm {
* @param ddVariables The vector of variables used to encode this variable.
* @param manager A pointer to the manager that is responsible for this meta variable.
*/
DdMetaVariable(std::string const& name, std::vector<Dd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager);
DdMetaVariable(std::string const& name, std::vector<Bdd<DdType::CUDD>> const& ddVariables, std::shared_ptr<DdManager<DdType::CUDD>> manager);
// Explictly generate all default versions of copy/move constructors/assignments.
DdMetaVariable(DdMetaVariable const& other) = default;
@ -104,21 +108,14 @@ namespace storm {
*
* @return A vector of variables used to encode the meta variable.
*/
std::vector<Dd<DdType::CUDD>> const& getDdVariables() const;
std::vector<Bdd<DdType::CUDD>> const& getDdVariables() const;
/*!
* Retrieves the cube of all variables that encode this meta variable.
*
* @return The cube of all variables that encode this meta variable.
*/
Dd<DdType::CUDD> const& getCube() const;
/*!
* Retrieves the cube of all variables that encode this meta variable represented as an MTBDD.
*
* @return The cube of all variables that encode this meta variable.
*/
Dd<DdType::CUDD> const& getCubeAsMtbdd() const;
Bdd<DdType::CUDD> const& getCube() const;
// The name of the meta variable.
std::string name;
@ -133,14 +130,10 @@ namespace storm {
int_fast64_t high;
// The vector of variables that are used to encode the meta variable.
std::vector<Dd<DdType::CUDD>> ddVariables;
std::vector<Bdd<DdType::CUDD>> ddVariables;
// The cube consisting of all variables that encode the meta variable.
Dd<DdType::CUDD> cube;
// The cube consisting of all variables that encode the meta variable represented by an MTBDD. This is
// used as a shortcut mainly for the abstraction methods.
Dd<DdType::CUDD> cubeAsMtbdd;
Bdd<DdType::CUDD> cube;
// A pointer to the manager responsible for this meta variable.
std::shared_ptr<DdManager<DdType::CUDD>> manager;

8
src/storage/dd/CuddOdd.cpp

@ -7,18 +7,18 @@
namespace storm {
namespace dd {
Odd<DdType::CUDD>::Odd(Dd<DdType::CUDD> const& dd) {
std::shared_ptr<DdManager<DdType::CUDD> const> manager = dd.getDdManager();
Odd<DdType::CUDD>::Odd(Add<DdType::CUDD> const& add) {
std::shared_ptr<DdManager<DdType::CUDD> const> manager = add.getDdManager();
// First, we need to determine the involved DD variables indices.
std::vector<uint_fast64_t> ddVariableIndices = dd.getSortedVariableIndices();
std::vector<uint_fast64_t> ddVariableIndices = add.getSortedVariableIndices();
// Prepare a unique table for each level that keeps the constructed ODD nodes unique.
std::vector<std::map<DdNode*, std::shared_ptr<Odd<DdType::CUDD>>>> uniqueTableForLevels(ddVariableIndices.size() + 1);
// Now construct the ODD structure.
// Currently, the DD needs to be an MTBDD, because complement edges are not supported.
std::shared_ptr<Odd<DdType::CUDD>> rootOdd = buildOddRec(dd.toMtbdd().getCuddDdNode(), manager->getCuddManager(), 0, ddVariableIndices.size(), ddVariableIndices, uniqueTableForLevels);
std::shared_ptr<Odd<DdType::CUDD>> rootOdd = buildOddRec(add.getCuddDdNode(), manager->getCuddManager(), 0, ddVariableIndices.size(), ddVariableIndices, uniqueTableForLevels);
// Finally, move the children of the root ODD into this ODD.
this->elseNode = std::move(rootOdd->elseNode);

6
src/storage/dd/CuddOdd.h

@ -4,7 +4,7 @@
#include <memory>
#include "src/storage/dd/Odd.h"
#include "src/storage/dd/CuddDd.h"
#include "src/storage/dd/CuddAdd.h"
#include "src/utility/OsDetection.h"
// Include the C++-interface of CUDD.
@ -18,9 +18,9 @@ namespace storm {
/*!
* Constructs an offset-labeled DD from the given DD.
*
* @param dd The DD for which to build the offset-labeled DD.
* @param add The ADD for which to build the offset-labeled DD.
*/
Odd(Dd<DdType::CUDD> const& dd);
Odd(Add<DdType::CUDD> const& add);
// Instantiate all copy/move constructors/assignments with the default implementation.
Odd() = default;

155
src/utility/graph.h

@ -259,24 +259,24 @@ namespace storm {
*
* @param model The (symbolic) model for which to compute the set of states.
* @param transitionMatrixBdd The transition matrix of the model as a BDD.
* @param phiStatesBdd The BDD containing all phi states of the model.
* @param psiStatesBdd The BDD containing all psi states of the model.
* @param phiStates The BDD containing all phi states of the model.
* @param psiStates The BDD containing all psi states of the model.
* @return All states with positive probability.
*/
template <storm::dd::DdType Type>
storm::dd::Dd<Type> performProbGreater0(storm::models::symbolic::DeterministicModel<Type> const& model, storm::dd::Dd<Type> const& transitionMatrixBdd, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd) {
storm::dd::Bdd<Type> performProbGreater0(storm::models::symbolic::DeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Dd<Type> lastIterationStates = manager.getZero();
storm::dd::Dd<Type> statesWithProbabilityGreater0 = psiStatesBdd;
storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
storm::dd::Bdd<Type> statesWithProbabilityGreater0 = psiStates;
uint_fast64_t iterations = 0;
while (lastIterationStates != statesWithProbabilityGreater0) {
lastIterationStates = statesWithProbabilityGreater0;
statesWithProbabilityGreater0 = statesWithProbabilityGreater0.swapVariables(model.getRowColumnMetaVariablePairs());
statesWithProbabilityGreater0 &= transitionMatrixBdd;
statesWithProbabilityGreater0 &= transitionMatrix;
statesWithProbabilityGreater0 = statesWithProbabilityGreater0.existsAbstract(model.getColumnVariables());
statesWithProbabilityGreater0 &= phiStatesBdd;
statesWithProbabilityGreater0 &= phiStates;
statesWithProbabilityGreater0 |= lastIterationStates;
++iterations;
}
@ -289,17 +289,16 @@ namespace storm {
* deterministic model.
*
* @param model The (symbolic) model for which to compute the set of states.
* @param transitionMatrixBdd The transition matrix of the model as a BDD.
* @param phiStatesBdd The BDD containing all phi states of the model.
* @param psiStatesBdd The BDD containing all psi states of the model.
* @return A pair of DDs that represent all states with probability 0 and 1, respectively.
* @param phiStates The BDD containing all phi states of the model.
* @param psiStates The BDD containing all psi states of the model.
* @return A pair of BDDs that represent all states with probability 0 and 1, respectively.
*/
template <storm::dd::DdType Type>
static std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> performProb01(storm::models::symbolic::DeterministicModel<Type> const& model, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd) {
std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> result;
storm::dd::Dd<Type> transitionMatrixBdd = model.getTransitionMatrix().notZero();
result.first = performProbGreater0(model, transitionMatrixBdd, phiStatesBdd, psiStatesBdd);
result.second = !performProbGreater0(model, transitionMatrixBdd, !psiStatesBdd && model.getReachableStates(), !result.first && model.getReachableStates()) && model.getReachableStates();
static std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01(storm::models::symbolic::DeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
storm::dd::Bdd<Type> transitionMatrix = model.getTransitionMatrix().notZero();
result.first = performProbGreater0(model, transitionMatrix, phiStates, psiStates);
result.second = !performProbGreater0(model, transitionMatrix, !psiStates && model.getReachableStates(), !result.first && model.getReachableStates()) && model.getReachableStates();
result.first = !result.first && model.getReachableStates();
return result;
}
@ -706,25 +705,25 @@ namespace storm {
* zero of satisfying phi until psi.
*
* @param model The (symbolic) model for which to compute the set of states.
* @param transitionMatrixBdd The transition matrix of the model as a BDD.
* @param phiStatesBdd The BDD containing all phi states of the model.
* @param psiStatesBdd The BDD containing all psi states of the model.
* @return A DD representing all such states.
* @param transitionMatrix The transition matrix of the model as a BDD.
* @param phiStates The BDD containing all phi states of the model.
* @param psiStates The BDD containing all psi states of the model.
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Dd<Type> performProbGreater0E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Dd<Type> const& transitionMatrixBdd, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd) {
storm::dd::Bdd<Type> performProbGreater0E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Dd<Type> lastIterationStates = manager.getZero();
storm::dd::Dd<Type> statesWithProbabilityGreater0E = psiStatesBdd;
storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
storm::dd::Bdd<Type> statesWithProbabilityGreater0E = psiStates;
uint_fast64_t iterations = 0;
storm::dd::Dd<Type> abstractedTransitionMatrixBdd = transitionMatrixBdd.existsAbstract(model.getNondeterminismVariables());
storm::dd::Bdd<Type> abstractedTransitionMatrix = transitionMatrix.existsAbstract(model.getNondeterminismVariables());
while (lastIterationStates != statesWithProbabilityGreater0E) {
lastIterationStates = statesWithProbabilityGreater0E;
statesWithProbabilityGreater0E = statesWithProbabilityGreater0E.swapVariables(model.getRowColumnMetaVariablePairs());
statesWithProbabilityGreater0E = statesWithProbabilityGreater0E.andExists(abstractedTransitionMatrixBdd, model.getColumnVariables());
statesWithProbabilityGreater0E &= phiStatesBdd;
statesWithProbabilityGreater0E = statesWithProbabilityGreater0E.andExists(abstractedTransitionMatrix, model.getColumnVariables());
statesWithProbabilityGreater0E &= phiStates;
statesWithProbabilityGreater0E |= lastIterationStates;
++iterations;
}
@ -737,14 +736,14 @@ namespace storm {
* than zero of satisfying phi until psi.
*
* @param model The (symbolic) model for which to compute the set of states.
* @param transitionMatrixBdd The transition matrix of the model as a BDD.
* @param transitionMatrix The transition matrix of the model as a BDD.
* @param phiStates The phi states of the model.
* @param psiStates The psi states of the model.
* @return A DD representing all such states.
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Dd<Type> performProb0A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Dd<Type> const& transitionMatrixBdd, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd) {
return !performProbGreater0E(model, transitionMatrixBdd, phiStatesBdd, psiStatesBdd) && model.getReachableStates();
storm::dd::Bdd<Type> performProb0A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
return !performProbGreater0E(model, transitionMatrix, phiStates, psiStates) && model.getReachableStates();
}
/*!
@ -752,27 +751,27 @@ namespace storm {
* phi until psi.
*
* @param model The (symbolic) model for which to compute the set of states.
* @param transitionMatrixBdd The transition matrix of the model as a BDD.
* @param phiStatesBdd The BDD containing all phi states of the model.
* @param psiStatesBdd The BDD containing all psi states of the model.
* @return A DD representing all such states.
* @param transitionMatrix The transition matrix of the model as a BDD.
* @param phiStates The BDD containing all phi states of the model.
* @param psiStates The BDD containing all psi states of the model.
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Dd<Type> performProbGreater0A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Dd<Type> const& transitionMatrixBdd, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd) {
storm::dd::Bdd<Type> performProbGreater0A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Dd<Type> lastIterationStates = manager.getZero();
storm::dd::Dd<Type> statesWithProbabilityGreater0A = psiStatesBdd;
storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
storm::dd::Bdd<Type> statesWithProbabilityGreater0A = psiStates;
uint_fast64_t iterations = 0;
while (lastIterationStates != statesWithProbabilityGreater0A) {
lastIterationStates = statesWithProbabilityGreater0A;
statesWithProbabilityGreater0A = statesWithProbabilityGreater0A.swapVariables(model.getRowColumnMetaVariablePairs());
statesWithProbabilityGreater0A = statesWithProbabilityGreater0A.andExists(transitionMatrixBdd, model.getColumnVariables());
statesWithProbabilityGreater0A = statesWithProbabilityGreater0A.andExists(transitionMatrix, model.getColumnVariables());
statesWithProbabilityGreater0A |= model.getIllegalMask();
statesWithProbabilityGreater0A = statesWithProbabilityGreater0A.universalAbstract(model.getNondeterminismVariables());
statesWithProbabilityGreater0A &= phiStatesBdd;
statesWithProbabilityGreater0A |= psiStatesBdd;
statesWithProbabilityGreater0A &= phiStates;
statesWithProbabilityGreater0A |= psiStates;
++iterations;
}
@ -784,43 +783,43 @@ namespace storm {
* phi until psi.
*
* @param model The (symbolic) model for which to compute the set of states.
* @param transitionMatrixBdd The transition matrix of the model as a BDD.
* @param phiStatesBdd The BDD containing all phi states of the model.
* @param psiStatesBdd The BDD containing all psi states of the model.
* @return A DD representing all such states.
* @param transitionMatrix The transition matrix of the model as a BDD.
* @param phiStates The BDD containing all phi states of the model.
* @param psiStates The BDD containing all psi states of the model.
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Dd<Type> performProb0E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Dd<Type> const& transitionMatrixBdd, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd) {
return !performProbGreater0A(model, transitionMatrixBdd, phiStatesBdd, psiStatesBdd) && model.getReachableStates();
storm::dd::Bdd<Type> performProb0E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
return !performProbGreater0A(model, transitionMatrix, phiStates, psiStates) && model.getReachableStates();
}
/*!
* Computes the set of states for which all schedulers achieve probability one of satisfying phi until psi.
*
* @param model The (symbolic) model for which to compute the set of states.
* @param transitionMatrixBdd The transition matrix of the model as a BDD.
* @param phiStatesBdd The BDD containing all phi states of the model.
* @param psiStatesBdd The BDD containing all psi states of the model.
* @param transitionMatrix The transition matrix of the model as a BDD.
* @param phiStates The BDD containing all phi states of the model.
* @param psiStates The BDD containing all psi states of the model.
* @param statesWithProbabilityGreater0A The states of the model that have a probability greater zero under
* all schedulers.
* @return A DD representing all such states.
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Dd<Type> performProb1A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Dd<Type> const& transitionMatrixBdd, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd, storm::dd::Dd<Type> const& statesWithProbabilityGreater0A) {
storm::dd::Bdd<Type> performProb1A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbabilityGreater0A) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Dd<Type> lastIterationStates = manager.getZero();
storm::dd::Dd<Type> statesWithProbability1A = psiStatesBdd || statesWithProbabilityGreater0A;
storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
storm::dd::Bdd<Type> statesWithProbability1A = psiStates || statesWithProbabilityGreater0A;
uint_fast64_t iterations = 0;
while (lastIterationStates != statesWithProbability1A) {
lastIterationStates = statesWithProbability1A;
statesWithProbability1A = statesWithProbability1A.swapVariables(model.getRowColumnMetaVariablePairs());
statesWithProbability1A = transitionMatrixBdd.implies(statesWithProbability1A).universalAbstract(model.getColumnVariables());
statesWithProbability1A = transitionMatrix.implies(statesWithProbability1A).universalAbstract(model.getColumnVariables());
statesWithProbability1A |= model.getIllegalMask();
statesWithProbability1A = statesWithProbability1A.universalAbstract(model.getNondeterminismVariables());
statesWithProbability1A &= statesWithProbabilityGreater0A;
statesWithProbability1A |= psiStatesBdd;
statesWithProbability1A |= psiStates;
++iterations;
}
@ -832,35 +831,35 @@ namespace storm {
* phi until psi.
*
* @param model The (symbolic) model for which to compute the set of states.
* @param transitionMatrixBdd The transition matrix of the model as a BDD.
* @param phiStatesBdd The BDD containing all phi states of the model.
* @param psiStatesBdd The BDD containing all psi states of the model.
* @param transitionMatrix The transition matrix of the model as a BDD.
* @param phiStates The BDD containing all phi states of the model.
* @param psiStates The BDD containing all psi states of the model.
* @param statesWithProbabilityGreater0E The states of the model that have a scheduler that achieves a value
* greater than zero.
* @return A DD representing all such states.
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Dd<Type> performProb1E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Dd<Type> const& transitionMatrixBdd, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd, storm::dd::Dd<Type> const& statesWithProbabilityGreater0E) {
storm::dd::Bdd<Type> performProb1E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbabilityGreater0E) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Dd<Type> statesWithProbability1E = statesWithProbabilityGreater0E;
storm::dd::Bdd<Type> statesWithProbability1E = statesWithProbabilityGreater0E;
uint_fast64_t iterations = 0;
bool outerLoopDone = false;
while (!outerLoopDone) {
storm::dd::Dd<Type> innerStates = manager.getZero();
storm::dd::Bdd<Type> innerStates = manager.getBddZero();
bool innerLoopDone = false;
while (!innerLoopDone) {
storm::dd::Dd<Type> temporary = statesWithProbability1E.swapVariables(model.getRowColumnMetaVariablePairs());
temporary = transitionMatrixBdd.implies(temporary).universalAbstract(model.getColumnVariables());
storm::dd::Bdd<Type> temporary = statesWithProbability1E.swapVariables(model.getRowColumnMetaVariablePairs());
temporary = transitionMatrix.implies(temporary).universalAbstract(model.getColumnVariables());
storm::dd::Dd<Type> temporary2 = innerStates.swapVariables(model.getRowColumnMetaVariablePairs());
temporary2 = transitionMatrixBdd.andExists(temporary2, model.getColumnVariables());
storm::dd::Bdd<Type> temporary2 = innerStates.swapVariables(model.getRowColumnMetaVariablePairs());
temporary2 = transitionMatrix.andExists(temporary2, model.getColumnVariables());
temporary = temporary.andExists(temporary2, model.getNondeterminismVariables());
temporary &= phiStatesBdd;
temporary |= psiStatesBdd;
temporary &= phiStates;
temporary |= psiStates;
if (innerStates == temporary) {
innerLoopDone = true;
@ -881,20 +880,20 @@ namespace storm {
}
template <storm::dd::DdType Type>
std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> performProb01Max(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd) {
std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> result;
storm::dd::Dd<Type> transitionMatrixBdd = model.getTransitionMatrix().notZero();
result.first = performProb0A(model, transitionMatrixBdd, phiStatesBdd, psiStatesBdd);
result.second = performProb1E(model, transitionMatrixBdd, phiStatesBdd, psiStatesBdd, !result.first && model.getReachableStates());
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01Max(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
storm::dd::Bdd<Type> transitionMatrix = model.getTransitionMatrix().notZero();
result.first = performProb0A(model, transitionMatrix, phiStates, psiStates);
result.second = performProb1E(model, transitionMatrix, phiStates, psiStates, !result.first && model.getReachableStates());
return result;
}
template <storm::dd::DdType Type>
std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> performProb01Min(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Dd<Type> const& phiStatesBdd, storm::dd::Dd<Type> const& psiStatesBdd) {
std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> result;
storm::dd::Dd<Type> transitionMatrixBdd = model.getTransitionMatrix().notZero();
result.first = performProb0E(model, transitionMatrixBdd, phiStatesBdd, psiStatesBdd);
result.second = performProb1A(model, transitionMatrixBdd, phiStatesBdd, psiStatesBdd, !result.first && model.getReachableStates());
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01Min(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
storm::dd::Bdd<Type> transitionMatrix = model.getTransitionMatrix().notZero();
result.first = performProb0E(model, transitionMatrix, phiStates, psiStates);
result.second = performProb1A(model, transitionMatrix, phiStates, psiStates, !result.first && model.getReachableStates());
return result;
}

182
test/functional/storage/CuddDdTest.cpp

@ -2,14 +2,14 @@
#include "storm-config.h"
#include "src/exceptions/InvalidArgumentException.h"
#include "src/storage/dd/CuddDdManager.h"
#include "src/storage/dd/CuddDd.h"
#include "src/storage/dd/CuddAdd.h"
#include "src/storage/dd/CuddOdd.h"
#include "src/storage/dd/DdMetaVariable.h"
TEST(CuddDdManager, Constants) {
std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
storm::dd::Dd<storm::dd::DdType::CUDD> zero;
ASSERT_NO_THROW(zero = manager->getZero());
storm::dd::Add<storm::dd::DdType::CUDD> zero;
ASSERT_NO_THROW(zero = manager->getAddZero());
EXPECT_EQ(0, zero.getNonZeroCount());
EXPECT_EQ(1, zero.getLeafCount());
@ -17,8 +17,8 @@ TEST(CuddDdManager, Constants) {
EXPECT_EQ(0, zero.getMin());
EXPECT_EQ(0, zero.getMax());
storm::dd::Dd<storm::dd::DdType::CUDD> one;
ASSERT_NO_THROW(one = manager->getOne());
storm::dd::Add<storm::dd::DdType::CUDD> one;
ASSERT_NO_THROW(one = manager->getAddOne());
EXPECT_EQ(1, one.getNonZeroCount());
EXPECT_EQ(1, one.getLeafCount());
@ -26,7 +26,7 @@ TEST(CuddDdManager, Constants) {
EXPECT_EQ(1, one.getMin());
EXPECT_EQ(1, one.getMax());
storm::dd::Dd<storm::dd::DdType::CUDD> two;
storm::dd::Add<storm::dd::DdType::CUDD> two;
ASSERT_NO_THROW(two = manager->getConstant(2));
EXPECT_EQ(1, two.getNonZeroCount());
@ -57,7 +57,7 @@ TEST(CuddDdManager, EncodingTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
storm::dd::Dd<storm::dd::DdType::CUDD> encoding;
storm::dd::Bdd<storm::dd::DdType::CUDD> encoding;
ASSERT_THROW(encoding = manager->getEncoding(x.first, 0), storm::exceptions::InvalidArgumentException);
ASSERT_THROW(encoding = manager->getEncoding(x.first, 10), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(encoding = manager->getEncoding(x.first, 4));
@ -69,8 +69,8 @@ TEST(CuddDdManager, EncodingTest) {
EXPECT_EQ(1, encoding.getLeafCount());
// As an MTBDD, the 0-leaf is there, so the count is actually 2 and the node count is 6.
EXPECT_EQ(6, encoding.toMtbdd().getNodeCount());
EXPECT_EQ(2, encoding.toMtbdd().getLeafCount());
EXPECT_EQ(6, encoding.toAdd().getNodeCount());
EXPECT_EQ(2, encoding.toAdd().getLeafCount());
}
TEST(CuddDdManager, RangeTest) {
@ -78,7 +78,7 @@ TEST(CuddDdManager, RangeTest) {
std::pair<storm::expressions::Variable, storm::expressions::Variable> x;
ASSERT_NO_THROW(x = manager->addMetaVariable("x", 1, 9));
storm::dd::Dd<storm::dd::DdType::CUDD> range;
storm::dd::Bdd<storm::dd::DdType::CUDD> range;
ASSERT_NO_THROW(range = manager->getRange(x.first));
EXPECT_EQ(9, range.getNonZeroCount());
@ -90,29 +90,29 @@ TEST(CuddDdManager, IdentityTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
storm::dd::Dd<storm::dd::DdType::CUDD> range;
ASSERT_NO_THROW(range = manager->getIdentity(x.first));
storm::dd::Add<storm::dd::DdType::CUDD> identity;
ASSERT_NO_THROW(identity = manager->getIdentity(x.first));
EXPECT_EQ(9, range.getNonZeroCount());
EXPECT_EQ(10, range.getLeafCount());
EXPECT_EQ(21, range.getNodeCount());
EXPECT_EQ(9, identity.getNonZeroCount());
EXPECT_EQ(10, identity.getLeafCount());
EXPECT_EQ(21, identity.getNodeCount());
}
TEST(CuddDd, OperatorTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
EXPECT_TRUE(manager->getZero() == manager->getZero());
EXPECT_FALSE(manager->getZero() == manager->getOne());
EXPECT_TRUE(manager->getAddZero() == manager->getAddZero());
EXPECT_FALSE(manager->getAddZero() == manager->getAddOne());
EXPECT_FALSE(manager->getZero() != manager->getZero());
EXPECT_TRUE(manager->getZero() != manager->getOne());
EXPECT_FALSE(manager->getAddZero() != manager->getAddZero());
EXPECT_TRUE(manager->getAddZero() != manager->getAddOne());
storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getOne(true);
storm::dd::Dd<storm::dd::DdType::CUDD> dd2 = manager->getOne(true);
storm::dd::Dd<storm::dd::DdType::CUDD> dd3 = dd1 + dd2;
storm::dd::Add<storm::dd::DdType::CUDD> dd1 = manager->getAddOne();
storm::dd::Add<storm::dd::DdType::CUDD> dd2 = manager->getAddOne();
storm::dd::Add<storm::dd::DdType::CUDD> dd3 = dd1 + dd2;
EXPECT_TRUE(dd3 == manager->getConstant(2));
dd3 += manager->getZero(true);
dd3 += manager->getAddZero();
EXPECT_TRUE(dd3 == manager->getConstant(2));
dd3 = dd1 * manager->getConstant(3);
@ -130,13 +130,13 @@ TEST(CuddDd, OperatorTest) {
dd3 /= manager->getConstant(2);
EXPECT_TRUE(dd3.isOne());
dd3 = dd3.toBdd().complement();
dd3 = !dd3;
EXPECT_TRUE(dd3.isZero());
dd1 = !dd3;
EXPECT_TRUE(dd1.isOne());
dd3 = dd1 || dd2.toBdd();
dd3 = dd1 || dd2;
EXPECT_TRUE(dd3.isOne());
dd1 = manager->getIdentity(x.first);
@ -145,7 +145,7 @@ TEST(CuddDd, OperatorTest) {
dd3 = dd1.equals(dd2);
EXPECT_EQ(1, dd3.getNonZeroCount());
storm::dd::Dd<storm::dd::DdType::CUDD> dd4 = dd1.notEquals(dd2);
storm::dd::Add<storm::dd::DdType::CUDD> dd4 = dd1.notEquals(dd2);
EXPECT_TRUE(dd4.toBdd() == !dd3.toBdd());
dd3 = dd1.less(dd2);
@ -160,17 +160,17 @@ TEST(CuddDd, OperatorTest) {
dd3 = dd1.greaterOrEqual(dd2);
EXPECT_EQ(5, dd3.getNonZeroCount());
dd3 = (manager->getEncoding(x.first, 2)).ite(dd2, dd1);
dd3 = (manager->getEncoding(x.first, 2).toAdd()).ite(dd2, dd1);
dd4 = dd3.less(dd2);
EXPECT_EQ(10, dd4.getNonZeroCount());
dd4 = dd3.minimum(dd1);
dd4 *= manager->getEncoding(x.first, 2, true);
dd4 *= manager->getEncoding(x.first, 2).toAdd();
dd4 = dd4.sumAbstract({x.first});
EXPECT_EQ(2, dd4.getValue());
dd4 = dd3.maximum(dd1);
dd4 *= manager->getEncoding(x.first, 2, true);
dd4 *= manager->getEncoding(x.first, 2).toAdd();
dd4 = dd4.sumAbstract({x.first});
EXPECT_EQ(5, dd4.getValue());
@ -183,25 +183,26 @@ TEST(CuddDd, OperatorTest) {
TEST(CuddDd, AbstractionTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
storm::dd::Dd<storm::dd::DdType::CUDD> dd1;
storm::dd::Dd<storm::dd::DdType::CUDD> dd2;
storm::dd::Dd<storm::dd::DdType::CUDD> dd3;
storm::dd::Add<storm::dd::DdType::CUDD> dd1;
storm::dd::Add<storm::dd::DdType::CUDD> dd2;
storm::dd::Add<storm::dd::DdType::CUDD> dd3;
dd1 = manager->getIdentity(x.first);
dd2 = manager->getConstant(5);
dd3 = dd1.equals(dd2);
EXPECT_EQ(1, dd3.getNonZeroCount());
ASSERT_THROW(dd3 = dd3.existsAbstract({x.second}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd3 = dd3.existsAbstract({x.first}));
EXPECT_EQ(1, dd3.getNonZeroCount());
EXPECT_EQ(1, dd3.getMax());
storm::dd::Bdd<storm::dd::DdType::CUDD> dd3Bdd = dd3.toBdd();
EXPECT_EQ(1, dd3Bdd.getNonZeroCount());
ASSERT_THROW(dd3Bdd = dd3Bdd.existsAbstract({x.second}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd3Bdd = dd3Bdd.existsAbstract({x.first}));
EXPECT_EQ(1, dd3Bdd.getNonZeroCount());
EXPECT_EQ(1, dd3Bdd.toAdd().getMax());
dd3 = dd1.equals(dd2);
dd3 *= manager->getConstant(3);
EXPECT_EQ(1, dd3.getNonZeroCount());
ASSERT_THROW(dd3 = dd3.existsAbstract({x.second}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd3 = dd3.existsAbstract({x.first}));
EXPECT_TRUE(dd3.isOne());
ASSERT_THROW(dd3Bdd = dd3.toBdd().existsAbstract({x.second}), storm::exceptions::InvalidArgumentException);
ASSERT_NO_THROW(dd3Bdd = dd3.toBdd().existsAbstract({x.first}));
EXPECT_TRUE(dd3Bdd.isOne());
dd3 = dd1.equals(dd2);
dd3 *= manager->getConstant(3);
@ -230,8 +231,8 @@ TEST(CuddDd, SwapTest) {
std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
std::pair<storm::expressions::Variable, storm::expressions::Variable> z = manager->addMetaVariable("z", 2, 8);
storm::dd::Dd<storm::dd::DdType::CUDD> dd1;
storm::dd::Dd<storm::dd::DdType::CUDD> dd2;
storm::dd::Add<storm::dd::DdType::CUDD> dd1;
storm::dd::Add<storm::dd::DdType::CUDD> dd2;
dd1 = manager->getIdentity(x.first);
ASSERT_THROW(dd1 = dd1.swapVariables({std::make_pair(x.first, z.first)}), storm::exceptions::InvalidArgumentException);
@ -243,9 +244,9 @@ TEST(CuddDd, MultiplyMatrixTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getIdentity(x.first).equals(manager->getIdentity(x.second));
storm::dd::Dd<storm::dd::DdType::CUDD> dd2 = manager->getRange(x.second);
storm::dd::Dd<storm::dd::DdType::CUDD> dd3;
storm::dd::Add<storm::dd::DdType::CUDD> dd1 = manager->getIdentity(x.first).equals(manager->getIdentity(x.second));
storm::dd::Add<storm::dd::DdType::CUDD> dd2 = manager->getRange(x.second).toAdd();
storm::dd::Add<storm::dd::DdType::CUDD> dd3;
dd1 *= manager->getConstant(2);
ASSERT_NO_THROW(dd3 = dd1.multiplyMatrix(dd2, {x.second}));
@ -257,7 +258,7 @@ TEST(CuddDd, GetSetValueTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
storm::dd::Dd<storm::dd::DdType::CUDD> dd1 = manager->getOne(true);
storm::dd::Add<storm::dd::DdType::CUDD> dd1 = manager->getAddOne();
ASSERT_NO_THROW(dd1.setValue(x.first, 4, 2));
EXPECT_EQ(2, dd1.getLeafCount());
@ -275,8 +276,8 @@ TEST(CuddDd, ForwardIteratorTest) {
std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
std::pair<storm::expressions::Variable, storm::expressions::Variable> y = manager->addMetaVariable("y", 0, 3);
storm::dd::Dd<storm::dd::DdType::CUDD> dd;
ASSERT_NO_THROW(dd = manager->getRange(x.first));
storm::dd::Add<storm::dd::DdType::CUDD> dd;
ASSERT_NO_THROW(dd = manager->getRange(x.first).toAdd());
storm::dd::DdForwardIterator<storm::dd::DdType::CUDD> it, ite;
ASSERT_NO_THROW(it = dd.begin());
@ -290,8 +291,8 @@ TEST(CuddDd, ForwardIteratorTest) {
}
EXPECT_EQ(9, numberOfValuations);
dd = manager->getRange(x.first);
dd = dd.ite(manager->getOne(), manager->getOne());
dd = manager->getRange(x.first).toAdd();
dd = dd.ite(manager->getAddOne(), manager->getAddOne());
ASSERT_NO_THROW(it = dd.begin());
ASSERT_NO_THROW(ite = dd.end());
numberOfValuations = 0;
@ -313,81 +314,12 @@ TEST(CuddDd, ForwardIteratorTest) {
EXPECT_EQ(1, numberOfValuations);
}
// FIXME: make toExpression work again and then fix this test.
//TEST(CuddDd, ToExpressionTest) {
// std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
// std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
//
// storm::dd::Dd<storm::dd::DdType::CUDD> dd;
// ASSERT_NO_THROW(dd = manager->getIdentity(x.first));
//
// storm::expressions::Expression ddAsExpression;
// ASSERT_NO_THROW(ddAsExpression = dd.toExpression());
//
// storm::expressions::SimpleValuation valuation;
// for (std::size_t bit = 0; bit < manager->getMetaVariable(x.first).getNumberOfDdVariables(); ++bit) {
// valuation.addBooleanIdentifier("x." + std::to_string(bit));
// }
//
// storm::dd::DdMetaVariable<storm::dd::DdType::CUDD> const& metaVariable = manager->getMetaVariable("x");
//
// for (auto valuationValuePair : dd) {
// for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
// // Check if the i-th bit is set or not and modify the valuation accordingly.
// if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1ull << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
// valuation.setBooleanValue("x." + std::to_string(i), true);
// } else {
// valuation.setBooleanValue("x." + std::to_string(i), false);
// }
// }
//
// // At this point, the constructed valuation should make the expression obtained from the DD evaluate to the very
// // same value as the current value obtained from the DD.
// EXPECT_EQ(valuationValuePair.second, ddAsExpression.evaluateAsDouble(&valuation));
// }
//
// storm::expressions::Expression mintermExpression = dd.getMintermExpression();
//
// // Check whether all minterms are covered.
// for (auto valuationValuePair : dd) {
// for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
// // Check if the i-th bit is set or not and modify the valuation accordingly.
// if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1ull << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
// valuation.setBooleanValue("x." + std::to_string(i), true);
// } else {
// valuation.setBooleanValue("x." + std::to_string(i), false);
// }
// }
//
// // At this point, the constructed valuation should make the expression obtained from the DD evaluate to the very
// // same value as the current value obtained from the DD.
// EXPECT_TRUE(mintermExpression.evaluateAsBool(&valuation));
// }
//
// // Now check no additional minterms are covered.
// dd = !dd;
// for (auto valuationValuePair : dd) {
// for (std::size_t i = 0; i < metaVariable.getNumberOfDdVariables(); ++i) {
// // Check if the i-th bit is set or not and modify the valuation accordingly.
// if (((valuationValuePair.first.getIntegerValue("x") - metaVariable.getLow()) & (1ull << (metaVariable.getNumberOfDdVariables() - i - 1))) != 0) {
// valuation.setBooleanValue("x." + std::to_string(i), true);
// } else {
// valuation.setBooleanValue("x." + std::to_string(i), false);
// }
// }
//
// // At this point, the constructed valuation should make the expression obtained from the DD evaluate to the very
// // same value as the current value obtained from the DD.
// EXPECT_FALSE(mintermExpression.evaluateAsBool(&valuation));
// }
//}
TEST(CuddDd, OddTest) {
std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>());
std::pair<storm::expressions::Variable, storm::expressions::Variable> a = manager->addMetaVariable("a");
std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9);
storm::dd::Dd<storm::dd::DdType::CUDD> dd = manager->getIdentity(x.first);
storm::dd::Add<storm::dd::DdType::CUDD> dd = manager->getIdentity(x.first);
storm::dd::Odd<storm::dd::DdType::CUDD> odd;
ASSERT_NO_THROW(odd = storm::dd::Odd<storm::dd::DdType::CUDD>(dd));
EXPECT_EQ(9, odd.getTotalOffset());
@ -401,14 +333,14 @@ TEST(CuddDd, OddTest) {
}
// Create a non-trivial matrix.
dd = manager->getIdentity(x.first).equals(manager->getIdentity(x.second)) * manager->getRange(x.first);
dd += manager->getEncoding(x.first, 1) * manager->getRange(x.second) + manager->getEncoding(x.second, 1) * manager->getRange(x.first);
dd = manager->getIdentity(x.first).equals(manager->getIdentity(x.second)) * manager->getRange(x.first).toAdd();
dd += manager->getEncoding(x.first, 1).toAdd() * manager->getRange(x.second).toAdd() + manager->getEncoding(x.second, 1).toAdd() * manager->getRange(x.first).toAdd();
// Create the ODDs.
storm::dd::Odd<storm::dd::DdType::CUDD> rowOdd;
ASSERT_NO_THROW(rowOdd = storm::dd::Odd<storm::dd::DdType::CUDD>(manager->getRange(x.first)));
ASSERT_NO_THROW(rowOdd = storm::dd::Odd<storm::dd::DdType::CUDD>(manager->getRange(x.first).toAdd()));
storm::dd::Odd<storm::dd::DdType::CUDD> columnOdd;
ASSERT_NO_THROW(columnOdd = storm::dd::Odd<storm::dd::DdType::CUDD>(manager->getRange(x.second)));
ASSERT_NO_THROW(columnOdd = storm::dd::Odd<storm::dd::DdType::CUDD>(manager->getRange(x.second).toAdd()));
// Try to translate the matrix.
storm::storage::SparseMatrix<double> matrix;
@ -418,7 +350,7 @@ TEST(CuddDd, OddTest) {
EXPECT_EQ(9, matrix.getColumnCount());
EXPECT_EQ(25, matrix.getNonzeroEntryCount());
dd = manager->getRange(x.first) * manager->getRange(x.second) * manager->getEncoding(a.first, 0).ite(dd, dd + manager->getConstant(1));
dd = manager->getRange(x.first).toAdd() * manager->getRange(x.second).toAdd() * manager->getEncoding(a.first, 0).toAdd().ite(dd, dd + manager->getConstant(1));
ASSERT_NO_THROW(matrix = dd.toMatrix({x.first}, {x.second}, {a.first}, rowOdd, columnOdd));
EXPECT_EQ(18, matrix.getRowCount());
EXPECT_EQ(9, matrix.getRowGroupCount());

4
test/functional/utility/GraphTest.cpp

@ -17,7 +17,7 @@ TEST(GraphTest, SymbolicProb01) {
ASSERT_TRUE(model->getType() == storm::models::ModelType::Dtmc);
std::pair<storm::dd::Dd<storm::dd::DdType::CUDD>, storm::dd::Dd<storm::dd::DdType::CUDD>> statesWithProbability01;
std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> statesWithProbability01;
ASSERT_NO_THROW(statesWithProbability01 = storm::utility::graph::performProb01(*model->as<storm::models::symbolic::Dtmc<storm::dd::DdType::CUDD>>(), model->getReachableStates(), model->getStates("observe0Greater1")));
EXPECT_EQ(4409, statesWithProbability01.first.getNonZeroCount());
@ -38,7 +38,7 @@ TEST(GraphTest, SymbolicProb01MinMax) {
ASSERT_TRUE(model->getType() == storm::models::ModelType::Mdp);
std::pair<storm::dd::Dd<storm::dd::DdType::CUDD>, storm::dd::Dd<storm::dd::DdType::CUDD>> statesWithProbability01;
std::pair<storm::dd::Bdd<storm::dd::DdType::CUDD>, storm::dd::Bdd<storm::dd::DdType::CUDD>> statesWithProbability01;
ASSERT_NO_THROW(statesWithProbability01 = storm::utility::graph::performProb01Min(*model->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>>(), model->getReachableStates(), model->getStates("elected")));
EXPECT_EQ(0, statesWithProbability01.first.getNonZeroCount());

Loading…
Cancel
Save