Browse Source

more work on quotient extraction

main
dehnert 9 years ago
parent
commit
7f346d2f0b
  1. 2
      src/storm/abstraction/MenuGame.cpp
  2. 17
      src/storm/builder/DdJaniModelBuilder.cpp
  3. 18
      src/storm/builder/DdPrismModelBuilder.cpp
  4. 37
      src/storm/models/symbolic/Ctmc.cpp
  5. 58
      src/storm/models/symbolic/Ctmc.h
  6. 19
      src/storm/models/symbolic/DeterministicModel.cpp
  7. 30
      src/storm/models/symbolic/DeterministicModel.h
  8. 18
      src/storm/models/symbolic/Dtmc.cpp
  9. 28
      src/storm/models/symbolic/Dtmc.h
  10. 19
      src/storm/models/symbolic/Mdp.cpp
  11. 31
      src/storm/models/symbolic/Mdp.h
  12. 91
      src/storm/models/symbolic/Model.cpp
  13. 44
      src/storm/models/symbolic/Model.h
  14. 30
      src/storm/models/symbolic/NondeterministicModel.cpp
  15. 33
      src/storm/models/symbolic/NondeterministicModel.h
  16. 33
      src/storm/models/symbolic/StochasticTwoPlayerGame.cpp
  17. 39
      src/storm/models/symbolic/StochasticTwoPlayerGame.h
  18. 19
      src/storm/settings/modules/BisimulationSettings.cpp
  19. 16
      src/storm/settings/modules/BisimulationSettings.h
  20. 62
      src/storm/storage/dd/Add.cpp
  21. 13
      src/storm/storage/dd/Add.h
  22. 52
      src/storm/storage/dd/Bdd.cpp
  23. 11
      src/storm/storage/dd/Bdd.h
  24. 20
      src/storm/storage/dd/BisimulationDecomposition.cpp
  25. 9
      src/storm/storage/dd/BisimulationDecomposition.h
  26. 15
      src/storm/storage/dd/DdManager.cpp
  27. 15
      src/storm/storage/dd/DdManager.h
  28. 114
      src/storm/storage/dd/bisimulation/Partition.cpp
  29. 81
      src/storm/storage/dd/bisimulation/Partition.h
  30. 24
      src/storm/storage/dd/bisimulation/PreservationInformation.cpp
  31. 30
      src/storm/storage/dd/bisimulation/PreservationInformation.h
  32. 161
      src/storm/storage/dd/bisimulation/QuotientExtractor.cpp
  33. 37
      src/storm/storage/dd/bisimulation/QuotientExtractor.h
  34. 5
      src/storm/utility/storm.h

2
src/storm/abstraction/MenuGame.cpp

@ -29,7 +29,7 @@ namespace storm {
std::set<storm::expressions::Variable> const& player2Variables,
std::set<storm::expressions::Variable> const& allNondeterminismVariables,
std::set<storm::expressions::Variable> const& probabilisticBranchingVariables,
std::map<storm::expressions::Expression, storm::dd::Bdd<Type>> const& expressionToBddMap) : storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>(manager, reachableStates, initialStates, deadlockStates, transitionMatrix.sumAbstract(probabilisticBranchingVariables), rowVariables, nullptr, columnVariables, nullptr, rowColumnMetaVariablePairs, player1Variables, player2Variables, allNondeterminismVariables), extendedTransitionMatrix(transitionMatrix), probabilisticBranchingVariables(probabilisticBranchingVariables), expressionToBddMap(expressionToBddMap), bottomStates(bottomStates) {
std::map<storm::expressions::Expression, storm::dd::Bdd<Type>> const& expressionToBddMap) : storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>(manager, reachableStates, initialStates, deadlockStates, transitionMatrix.sumAbstract(probabilisticBranchingVariables), rowVariables, nullptr, columnVariables, rowColumnMetaVariablePairs, player1Variables, player2Variables, allNondeterminismVariables), extendedTransitionMatrix(transitionMatrix), probabilisticBranchingVariables(probabilisticBranchingVariables), expressionToBddMap(expressionToBddMap), bottomStates(bottomStates) {
// Intentionally left empty.
}

17
src/storm/builder/DdJaniModelBuilder.cpp

@ -141,7 +141,7 @@ namespace storm {
template <storm::dd::DdType Type, typename ValueType>
class ParameterCreator {
public:
void create(storm::jani::Model const& model, storm::adapters::AddExpressionAdapter<Type, ValueType>& rowExpressionAdapter, storm::adapters::AddExpressionAdapter<Type, ValueType>& columnExpressionAdapter) {
void create(storm::jani::Model const& model, storm::adapters::AddExpressionAdapter<Type, ValueType>& rowExpressionAdapter) {
// Intentionally left empty: no support for parameters for this data type.
}
@ -160,14 +160,13 @@ namespace storm {
// Intentionally left empty.
}
void create(storm::jani::Model const& model, storm::adapters::AddExpressionAdapter<Type, storm::RationalFunction>& rowExpressionAdapter, storm::adapters::AddExpressionAdapter<Type, storm::RationalFunction>& columnExpressionAdapter) {
void create(storm::jani::Model const& model, storm::adapters::AddExpressionAdapter<Type, storm::RationalFunction>& rowExpressionAdapter) {
for (auto const& constant : model.getConstants()) {
if (!constant.isDefined()) {
carl::Variable carlVariable = carl::freshRealVariable(constant.getExpressionVariable().getName());
parameters.insert(carlVariable);
auto rf = convertVariableToPolynomial(carlVariable);
rowExpressionAdapter.setValue(constant.getExpressionVariable(), rf);
columnExpressionAdapter.setValue(constant.getExpressionVariable(), rf);
}
}
}
@ -202,8 +201,7 @@ namespace storm {
CompositionVariables() : manager(std::make_shared<storm::dd::DdManager<Type>>()),
variableToRowMetaVariableMap(std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>()),
rowExpressionAdapter(std::make_shared<storm::adapters::AddExpressionAdapter<Type, ValueType>>(manager, variableToRowMetaVariableMap)),
variableToColumnMetaVariableMap(std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>()),
columnExpressionAdapter(std::make_shared<storm::adapters::AddExpressionAdapter<Type, ValueType>>(manager, variableToColumnMetaVariableMap)) {
variableToColumnMetaVariableMap(std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>()) {
// Intentionally left empty.
}
@ -217,7 +215,6 @@ namespace storm {
// The meta variables for the column encoding.
std::set<storm::expressions::Variable> columnMetaVariables;
std::shared_ptr<std::map<storm::expressions::Variable, storm::expressions::Variable>> variableToColumnMetaVariableMap;
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter;
// All pairs of row/column meta variables.
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> rowColumnMetaVariablePairs;
@ -392,7 +389,7 @@ namespace storm {
}
ParameterCreator<Type, ValueType> parameterCreator;
parameterCreator.create(model, *result.rowExpressionAdapter, *result.columnExpressionAdapter);
parameterCreator.create(model, *result.rowExpressionAdapter);
if (std::is_same<ValueType, storm::RationalFunction>::value) {
result.parameters = parameterCreator.getParameters();
}
@ -1706,11 +1703,11 @@ namespace storm {
std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>> createModel(storm::jani::ModelType const& modelType, CompositionVariables<Type, ValueType> const& variables, ModelComponents<Type, ValueType> const& modelComponents) {
std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>> result;
if (modelType == storm::jani::ModelType::DTMC) {
result = std::make_shared<storm::models::symbolic::Dtmc<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.columnExpressionAdapter, variables.rowColumnMetaVariablePairs, modelComponents.labelToExpressionMap, modelComponents.rewardModels);
result = std::make_shared<storm::models::symbolic::Dtmc<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, modelComponents.labelToExpressionMap, modelComponents.rewardModels);
} else if (modelType == storm::jani::ModelType::CTMC) {
result = std::make_shared<storm::models::symbolic::Ctmc<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.columnExpressionAdapter, variables.rowColumnMetaVariablePairs, modelComponents.labelToExpressionMap, modelComponents.rewardModels);
result = std::make_shared<storm::models::symbolic::Ctmc<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, modelComponents.labelToExpressionMap, modelComponents.rewardModels);
} else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS) {
result = std::make_shared<storm::models::symbolic::Mdp<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.columnExpressionAdapter, variables.rowColumnMetaVariablePairs, variables.allNondeterminismVariables, modelComponents.labelToExpressionMap, modelComponents.rewardModels);
result = std::make_shared<storm::models::symbolic::Mdp<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, variables.allNondeterminismVariables, modelComponents.labelToExpressionMap, modelComponents.rewardModels);
} else {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Model type '" << modelType << "' not supported.");
}

18
src/storm/builder/DdPrismModelBuilder.cpp

@ -34,7 +34,7 @@ namespace storm {
template <storm::dd::DdType Type, typename ValueType>
class ParameterCreator {
public:
void create(storm::prism::Program const& program, storm::adapters::AddExpressionAdapter<Type, ValueType>& rowExpressionAdapter, storm::adapters::AddExpressionAdapter<Type, ValueType>& columnExpressionAdapter) {
void create(storm::prism::Program const& program, storm::adapters::AddExpressionAdapter<Type, ValueType>& rowExpressionAdapter) {
// Intentionally left empty: no support for parameters for this data type.
}
@ -53,14 +53,13 @@ namespace storm {
// Intentionally left empty.
}
void create(storm::prism::Program const& program, storm::adapters::AddExpressionAdapter<Type, storm::RationalFunction>& rowExpressionAdapter, storm::adapters::AddExpressionAdapter<Type, storm::RationalFunction>& columnExpressionAdapter) {
void create(storm::prism::Program const& program, storm::adapters::AddExpressionAdapter<Type, storm::RationalFunction>& rowExpressionAdapter) {
for (auto const& constant : program.getConstants()) {
if (!constant.isDefined()) {
carl::Variable carlVariable = carl::freshRealVariable(constant.getExpressionVariable().getName());
parameters.insert(carlVariable);
auto rf = convertVariableToPolynomial(carlVariable);
rowExpressionAdapter.setValue(constant.getExpressionVariable(), rf);
columnExpressionAdapter.setValue(constant.getExpressionVariable(), rf);
}
}
}
@ -93,14 +92,14 @@ namespace storm {
template <storm::dd::DdType Type, typename ValueType>
class DdPrismModelBuilder<Type, ValueType>::GenerationInformation {
public:
GenerationInformation(storm::prism::Program const& program) : program(program), manager(std::make_shared<storm::dd::DdManager<Type>>()), rowMetaVariables(), variableToRowMetaVariableMap(std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>()), rowExpressionAdapter(std::make_shared<storm::adapters::AddExpressionAdapter<Type, ValueType>>(manager, variableToRowMetaVariableMap)), columnMetaVariables(), variableToColumnMetaVariableMap((std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>())), columnExpressionAdapter(std::make_shared<storm::adapters::AddExpressionAdapter<Type, ValueType>>(manager, variableToColumnMetaVariableMap)), rowColumnMetaVariablePairs(), nondeterminismMetaVariables(), variableToIdentityMap(), allGlobalVariables(), moduleToIdentityMap(), parameters() {
GenerationInformation(storm::prism::Program const& program) : program(program), manager(std::make_shared<storm::dd::DdManager<Type>>()), rowMetaVariables(), variableToRowMetaVariableMap(std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>()), rowExpressionAdapter(std::make_shared<storm::adapters::AddExpressionAdapter<Type, ValueType>>(manager, variableToRowMetaVariableMap)), columnMetaVariables(), variableToColumnMetaVariableMap((std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>())), rowColumnMetaVariablePairs(), nondeterminismMetaVariables(), variableToIdentityMap(), allGlobalVariables(), moduleToIdentityMap(), parameters() {
// Initializes variables and identity DDs.
createMetaVariablesAndIdentities();
// Initialize the parameters (if any).
ParameterCreator<Type, ValueType> parameterCreator;
parameterCreator.create(this->program, *this->rowExpressionAdapter, *this->columnExpressionAdapter);
parameterCreator.create(this->program, *this->rowExpressionAdapter);
if (std::is_same<ValueType, storm::RationalFunction>::value) {
this->parameters = parameterCreator.getParameters();
}
@ -120,7 +119,6 @@ namespace storm {
// The meta variables for the column encoding.
std::set<storm::expressions::Variable> columnMetaVariables;
std::shared_ptr<std::map<storm::expressions::Variable, storm::expressions::Variable>> variableToColumnMetaVariableMap;
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter;
// All pairs of row/column meta variables.
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> rowColumnMetaVariablePairs;
@ -1358,7 +1356,7 @@ namespace storm {
} else {
STORM_LOG_THROW(labelName == "init" || labelName == "deadlock", storm::exceptions::InvalidArgumentException, "Terminal states refer to illegal label '" << labelName << "'.");
}
}
}
if (terminalExpression.isInitialized()) {
// If the expression refers to constants of the model, we need to substitute them.
@ -1484,11 +1482,11 @@ namespace storm {
std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>> result;
if (program.getModelType() == storm::prism::Program::ModelType::DTMC) {
result = std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Dtmc<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels));
result = std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Dtmc<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels));
} else if (program.getModelType() == storm::prism::Program::ModelType::CTMC) {
result = std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Ctmc<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, system.stateActionDd, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels));
result = std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Ctmc<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, system.stateActionDd, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels));
} else if (program.getModelType() == storm::prism::Program::ModelType::MDP) {
result = std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Mdp<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, generationInfo.allNondeterminismVariables, labelToExpressionMapping, rewardModels));
result = std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Mdp<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.rowColumnMetaVariablePairs, generationInfo.allNondeterminismVariables, labelToExpressionMapping, rewardModels));
} else {
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Invalid model type.");
}

37
src/storm/models/symbolic/Ctmc.cpp

@ -21,11 +21,10 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: DeterministicModel<Type, ValueType>(storm::models::ModelType::Ctmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels) {
: DeterministicModel<Type, ValueType>(storm::models::ModelType::Ctmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels) {
// Intentionally left empty.
}
@ -39,11 +38,41 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: DeterministicModel<Type, ValueType>(storm::models::ModelType::Ctmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels), exitRates(exitRateVector) {
: DeterministicModel<Type, ValueType>(storm::models::ModelType::Ctmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels), exitRates(exitRateVector) {
// Intentionally left empty.
}
template<storm::dd::DdType Type, typename ValueType>
Ctmc<Type, ValueType>::Ctmc(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: DeterministicModel<Type, ValueType>(storm::models::ModelType::Ctmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, columnVariables, rowColumnMetaVariablePairs, labelToBddMap, rewardModels) {
// Intentionally left empty.
}
template<storm::dd::DdType Type, typename ValueType>
Ctmc<Type, ValueType>::Ctmc(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
boost::optional<storm::dd::Add<Type, ValueType>> exitRateVector,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: DeterministicModel<Type, ValueType>(storm::models::ModelType::Ctmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, columnVariables, rowColumnMetaVariablePairs, labelToBddMap, rewardModels), exitRates(exitRateVector) {
// Intentionally left empty.
}

58
src/storm/models/symbolic/Ctmc.h

@ -36,8 +36,6 @@ namespace storm {
* @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row
* meta variables.
* @param columVariables The set of column meta variables used in the DDs.
* @param columnExpressionAdapter An object that can be used to translate expressions in terms of the
* column meta variables.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToExpressionMap A mapping from label names to their defining expressions.
* @param rewardModels The reward models associated with the model.
@ -50,7 +48,6 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> 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>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
@ -68,8 +65,6 @@ namespace storm {
* @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row
* meta variables.
* @param columVariables The set of column meta variables used in the DDs.
* @param columnExpressionAdapter An object that can be used to translate expressions in terms of the
* column meta variables.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToExpressionMap A mapping from label names to their defining expressions.
* @param rewardModels The reward models associated with the model.
@ -83,11 +78,62 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> 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>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Constructs a model from the given data.
*
* @param manager The manager responsible for the decision diagrams.
* @param reachableStates A DD representing the reachable states.
* @param initialStates A DD representing the initial states of the model.
* @param deadlockStates A DD representing the deadlock states of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param rowVariables The set of row meta variables used in the DDs.
* @param columVariables The set of column meta variables used in the DDs.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToBddMap A mapping from label names to their defining BDDs.
* @param rewardModels The reward models associated with the model.
*/
Ctmc(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Constructs a model from the given data.
*
* @param manager The manager responsible for the decision diagrams.
* @param reachableStates A DD representing the reachable states.
* @param initialStates A DD representing the initial states of the model.
* @param deadlockStates A DD representing the deadlock states of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param exitRateVector The vector specifying the exit rates for the states.
* @param rowVariables The set of row meta variables used in the DDs.
* @param columVariables The set of column meta variables used in the DDs.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToBddMap A mapping from label names to their defining BDDs.
* @param rewardModels The reward models associated with the model.
*/
Ctmc(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
boost::optional<storm::dd::Add<Type, ValueType>> exitRateVector,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Retrieves the exit rate vector of the CTMC.
*

19
src/storm/models/symbolic/DeterministicModel.cpp

@ -22,11 +22,26 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: Model<Type, ValueType>(modelType, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels) {
: Model<Type, ValueType>(modelType, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels) {
// Intentionally left empty.
}
template<storm::dd::DdType Type, typename ValueType>
DeterministicModel<Type, ValueType>::DeterministicModel(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: Model<Type, ValueType>(modelType, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, columnVariables, rowColumnMetaVariablePairs, labelToBddMap, rewardModels) {
// Intentionally left empty.
}

30
src/storm/models/symbolic/DeterministicModel.h

@ -37,8 +37,6 @@ namespace storm {
* @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row
* meta variables.
* @param columVariables The set of column meta variables used in the DDs.
* @param columnExpressionAdapter An object that can be used to translate expressions in terms of the
* column meta variables.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToExpressionMap A mapping from label names to their defining expressions.
* @param rewardModels The reward models associated with the model.
@ -52,10 +50,36 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> 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>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Constructs a model from the given data.
*
* @param modelType The type of the model.
* @param manager The manager responsible for the decision diagrams.
* @param reachableStates A DD representing the reachable states.
* @param initialStates A DD representing the initial states of the model.
* @param deadlockStates A DD representing the deadlock states of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param rowVariables The set of row meta variables used in the DDs.
* @param columVariables The set of column meta variables used in the DDs.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToBddMap A mapping from label names to their defining BDDs.
* @param rewardModels The reward models associated with the model.
*/
DeterministicModel(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
};
} // namespace symbolic

18
src/storm/models/symbolic/Dtmc.cpp

@ -21,11 +21,25 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: DeterministicModel<Type, ValueType>(storm::models::ModelType::Dtmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels) {
: DeterministicModel<Type, ValueType>(storm::models::ModelType::Dtmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels) {
// Intentionally left empty.
}
template<storm::dd::DdType Type, typename ValueType>
Dtmc<Type, ValueType>::Dtmc(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: DeterministicModel<Type, ValueType>(storm::models::ModelType::Dtmc, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, columnVariables, rowColumnMetaVariablePairs, labelToBddMap, rewardModels) {
// Intentionally left empty.
}

28
src/storm/models/symbolic/Dtmc.h

@ -36,8 +36,6 @@ namespace storm {
* @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row
* meta variables.
* @param columVariables The set of column meta variables used in the DDs.
* @param columnExpressionAdapter An object that can be used to translate expressions in terms of the
* column meta variables.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToExpressionMap A mapping from label names to their defining expressions.
* @param rewardModels The reward models associated with the model.
@ -50,10 +48,34 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> 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>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Constructs a model from the given data.
*
* @param manager The manager responsible for the decision diagrams.
* @param reachableStates A DD representing the reachable states.
* @param initialStates A DD representing the initial states of the model.
* @param deadlockStates A DD representing the deadlock states of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param rowVariables The set of row meta variables used in the DDs.
* @param columVariables The set of column meta variables used in the DDs.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToBddMap A mapping from label names to their defining BDDs.
* @param rewardModels The reward models associated with the model.
*/
Dtmc(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
};
} // namespace symbolic

19
src/storm/models/symbolic/Mdp.cpp

@ -21,12 +21,27 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> 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::unordered_map<std::string, RewardModelType> const& rewardModels)
: NondeterministicModel<Type, ValueType>(storm::models::ModelType::Mdp, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, nondeterminismVariables, labelToExpressionMap, rewardModels) {
: NondeterministicModel<Type, ValueType>(storm::models::ModelType::Mdp, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToExpressionMap, rewardModels) {
// Intentionally left empty.
}
template<storm::dd::DdType Type, typename ValueType>
Mdp<Type, ValueType>::Mdp(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: NondeterministicModel<Type, ValueType>(storm::models::ModelType::Mdp, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToBddMap, rewardModels) {
// Intentionally left empty.
}

31
src/storm/models/symbolic/Mdp.h

@ -37,8 +37,6 @@ namespace storm {
* @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row
* meta variables.
* @param columVariables The set of column meta variables used in the DDs.
* @param columnExpressionAdapter An object that can be used to translate expressions in terms of the
* column meta variables.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param nondeterminismVariables The meta variables used to encode the nondeterminism in the model.
* @param labelToExpressionMap A mapping from label names to their defining expressions.
@ -52,12 +50,39 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> 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>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Constructs a model from the given data.
*
* @param modelType The type of the model.
* @param manager The manager responsible for the decision diagrams.
* @param reachableStates A DD representing the reachable states.
* @param initialStates A DD representing the initial states of the model.
* @param deadlockStates A DD representing the deadlock states of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param rowVariables The set of row meta variables used in the DDs.
* @param columVariables The set of column meta variables used in the DDs.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param nondeterminismVariables The meta variables used to encode the nondeterminism in the model.
* @param labelToBddMap A mapping from label names to their defining BDDs.
* @param rewardModels The reward models associated with the model.
*/
Mdp(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
};
} // namespace symbolic

91
src/storm/models/symbolic/Model.cpp

@ -17,6 +17,7 @@
#include "storm/utility/dd.h"
#include "storm/exceptions/NotSupportedException.h"
#include "storm/exceptions/WrongFormatException.h"
namespace storm {
namespace models {
@ -31,12 +32,31 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: ModelBase(modelType), manager(manager), reachableStates(reachableStates), initialStates(initialStates), deadlockStates(deadlockStates), transitionMatrix(transitionMatrix), rowVariables(rowVariables), rowExpressionAdapter(rowExpressionAdapter), columnVariables(columnVariables), columnExpressionAdapter(columnExpressionAdapter), rowColumnMetaVariablePairs(rowColumnMetaVariablePairs), labelToExpressionMap(labelToExpressionMap), rewardModels(rewardModels) {
// Intentionally left empty.
: ModelBase(modelType), manager(manager), reachableStates(reachableStates), transitionMatrix(transitionMatrix), rowVariables(rowVariables), rowExpressionAdapter(rowExpressionAdapter), columnVariables(columnVariables), rowColumnMetaVariablePairs(rowColumnMetaVariablePairs), labelToExpressionMap(labelToExpressionMap), rewardModels(rewardModels) {
this->labelToBddMap.emplace("init", initialStates);
this->labelToBddMap.emplace("deadlock", deadlockStates);
}
template<storm::dd::DdType Type, typename ValueType>
Model<Type, ValueType>::Model(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: ModelBase(modelType), manager(manager), reachableStates(reachableStates), transitionMatrix(transitionMatrix), rowVariables(rowVariables), rowExpressionAdapter(nullptr), columnVariables(columnVariables), rowColumnMetaVariablePairs(rowColumnMetaVariablePairs), labelToBddMap(labelToBddMap), rewardModels(rewardModels) {
STORM_LOG_THROW(this->labelToBddMap.find("init") == this->labelToBddMap.end(), storm::exceptions::WrongFormatException, "Illegal custom label 'init'.");
STORM_LOG_THROW(this->labelToBddMap.find("deadlock") == this->labelToBddMap.end(), storm::exceptions::WrongFormatException, "Illegal custom label 'deadlock'.");
this->labelToBddMap.emplace("init", initialStates);
this->labelToBddMap.emplace("deadlock", deadlockStates);
}
template<storm::dd::DdType Type, typename ValueType>
@ -53,7 +73,7 @@ namespace storm {
storm::dd::DdManager<Type>& Model<Type, ValueType>::getManager() const {
return *manager;
}
template<storm::dd::DdType Type, typename ValueType>
std::shared_ptr<storm::dd::DdManager<Type>> const& Model<Type, ValueType>::getManagerAsSharedPointer() const {
return manager;
@ -66,24 +86,33 @@ namespace storm {
template<storm::dd::DdType Type, typename ValueType>
storm::dd::Bdd<Type> const& Model<Type, ValueType>::getInitialStates() const {
return initialStates;
return labelToBddMap.at("init");
}
template<storm::dd::DdType Type, typename ValueType>
storm::dd::Bdd<Type> const& Model<Type, ValueType>::getDeadlockStates() const {
return deadlockStates;
return labelToBddMap.at("deadlock");
}
template<storm::dd::DdType Type, typename ValueType>
storm::dd::Bdd<Type> Model<Type, ValueType>::getStates(std::string const& label) const {
STORM_LOG_THROW(labelToExpressionMap.find(label) != labelToExpressionMap.end(), storm::exceptions::IllegalArgumentException, "The label " << label << " is invalid for the labeling of the model.");
return this->getStates(labelToExpressionMap.at(label));
// First check whether we have a BDD for this label.
auto bddIt = labelToBddMap.find(label);
if (bddIt != labelToBddMap.end()) {
return bddIt->second;
} else {
// If not, check for an expression we can translate.
auto expressionIt = labelToExpressionMap.find(label);
STORM_LOG_THROW(expressionIt != labelToExpressionMap.end(), storm::exceptions::IllegalArgumentException, "The label " << label << " is invalid for the labeling of the model.");
return this->getStates(expressionIt->second);
}
}
template<storm::dd::DdType Type, typename ValueType>
storm::expressions::Expression Model<Type, ValueType>::getExpression(std::string const& label) const {
STORM_LOG_THROW(labelToExpressionMap.find(label) != labelToExpressionMap.end(), storm::exceptions::IllegalArgumentException, "The label " << label << " is invalid for the labeling of the model.");
return labelToExpressionMap.at(label);
auto expressionIt = labelToExpressionMap.find(label);
STORM_LOG_THROW(expressionIt != labelToExpressionMap.end(), storm::exceptions::IllegalArgumentException, "Cannot retrieve the expression for the label " << label << ".");
return expressionIt->second;
}
template<storm::dd::DdType Type, typename ValueType>
@ -93,17 +122,32 @@ namespace storm {
} else if (expression.isFalse()) {
return manager->getBddZero();
}
// Look up the string equivalent of the expression.
std::stringstream stream;
stream << expression;
auto bddIt = labelToBddMap.find(stream.str());
if (bddIt != labelToBddMap.end()) {
return bddIt->second;
}
// Finally try to translate the expression with an adapter.
STORM_LOG_THROW(rowExpressionAdapter != nullptr, storm::exceptions::InvalidOperationException, "Cannot create BDD for expression without expression adapter.");
return rowExpressionAdapter->translateExpression(expression).toBdd() && this->reachableStates;
}
template<storm::dd::DdType Type, typename ValueType>
bool Model<Type, ValueType>::hasLabel(std::string const& label) const {
auto labelIt = labelToExpressionMap.find(label);
if (labelIt != labelToExpressionMap.end()) {
auto bddIt = labelToBddMap.find(label);
if (bddIt != labelToBddMap.end()) {
return true;
}
auto expressionIt = labelToExpressionMap.find(label);
if (expressionIt != labelToExpressionMap.end()) {
return true;
} else {
return label == "init" || label == "deadlock";
return false;
}
}
@ -179,13 +223,13 @@ namespace storm {
STORM_LOG_THROW(this->hasUniqueRewardModel(), storm::exceptions::InvalidOperationException, "Cannot retrieve unique reward model, because there is no unique one.");
return this->rewardModels.cbegin()->second;
}
template<storm::dd::DdType Type, typename ValueType>
typename Model<Type, ValueType>::RewardModelType& Model<Type, ValueType>::getUniqueRewardModel() {
STORM_LOG_THROW(this->hasUniqueRewardModel(), storm::exceptions::InvalidOperationException, "Cannot retrieve unique reward model, because there is no unique one.");
return this->rewardModels.begin()->second;
}
template<storm::dd::DdType Type, typename ValueType>
bool Model<Type, ValueType>::hasUniqueRewardModel() const {
return this->rewardModels.size() == 1;
@ -195,7 +239,7 @@ namespace storm {
bool Model<Type, ValueType>::hasRewardModel() const {
return !this->rewardModels.empty();
}
template<storm::dd::DdType Type, typename ValueType>
std::unordered_map<std::string, typename Model<Type, ValueType>::RewardModelType> const& Model<Type, ValueType>::getRewardModels() const {
return this->rewardModels;
@ -206,7 +250,7 @@ namespace storm {
this->printModelInformationHeaderToStream(out);
this->printModelInformationFooterToStream(out);
}
template<storm::dd::DdType Type, typename ValueType>
std::vector<std::string> Model<Type, ValueType>::getLabels() const {
std::vector<std::string> labels;
@ -229,7 +273,10 @@ namespace storm {
this->printRewardModelsInformationToStream(out);
this->printDdVariableInformationToStream(out);
out << std::endl;
out << "Labels: \t" << this->labelToExpressionMap.size() << std::endl;
out << "Labels: \t" << (this->labelToExpressionMap.size() + this->labelToBddMap.size()) << std::endl;
for (auto const& label : labelToBddMap) {
out << " * " << label.first << " -> " << label.second.getNonZeroCount() << " state(s) (" << label.second.getNodeCount() << " nodes)" << std::endl;
}
for (auto const& label : labelToExpressionMap) {
out << " * " << label.first << std::endl;
}
@ -278,7 +325,7 @@ namespace storm {
std::set<storm::RationalFunctionVariable> const& Model<Type, ValueType>::getParameters() const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "This value type does not support parameters.");
}
template<>
void Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::addParameters(std::set<storm::RationalFunctionVariable> const& parameters) {
this->parameters.insert(parameters.begin(), parameters.end());
@ -288,13 +335,13 @@ namespace storm {
std::set<storm::RationalFunctionVariable> const& Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::getParameters() const {
return parameters;
}
// Explicitly instantiate the template class.
template class Model<storm::dd::DdType::CUDD, double>;
template class Model<storm::dd::DdType::Sylvan, double>;
template class Model<storm::dd::DdType::Sylvan, storm::RationalNumber>;
template class Model<storm::dd::DdType::Sylvan, storm::RationalFunction>;
template class Model<storm::dd::DdType::Sylvan, storm::RationalFunction>;
} // namespace symbolic
} // namespace models
} // namespace storm

44
src/storm/models/symbolic/Model.h

@ -73,8 +73,6 @@ namespace storm {
* @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row
* meta variables.
* @param columVariables The set of column meta variables used in the DDs.
* @param columnExpressionAdapter An object that can be used to translate expressions in terms of the
* column meta variables.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToExpressionMap A mapping from label names to their defining expressions.
* @param rewardModels The reward models associated with the model.
@ -88,11 +86,37 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> 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>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Constructs a model from the given data.
*
* @param modelType The type of the model.
* @param manager The manager responsible for the decision diagrams.
* @param reachableStates A DD representing the reachable states.
* @param initialStates A DD representing the initial states of the model.
* @param deadlockStates A DD representing the deadlock states of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param rowVariables The set of row meta variables used in the DDs.
* @param columVariables The set of column meta variables used in the DDs.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param labelToBddMap A mapping from label names to their defining BDDs.
* @param rewardModels The reward models associated with the model.
*/
Model(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
virtual uint_fast64_t getNumberOfStates() const override;
virtual uint_fast64_t getNumberOfTransitions() const override;
@ -324,13 +348,7 @@ namespace storm {
// A vector representing the reachable states of the model.
storm::dd::Bdd<Type> reachableStates;
// A vector representing the initial states of the model.
storm::dd::Bdd<Type> initialStates;
// A vector representing the deadlock states of the model.
storm::dd::Bdd<Type> deadlockStates;
// A matrix representing transition relation.
storm::dd::Add<Type, ValueType> transitionMatrix;
@ -343,9 +361,6 @@ namespace storm {
// 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::AddExpressionAdapter<Type, ValueType>> 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.
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> rowColumnMetaVariablePairs;
@ -353,6 +368,9 @@ namespace storm {
// A mapping from labels to expressions defining them.
std::map<std::string, storm::expressions::Expression> labelToExpressionMap;
// A mapping from labels to BDDs characterizing the labeled states.
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap;
// The reward models associated with the model.
std::unordered_map<std::string, RewardModelType> rewardModels;

30
src/storm/models/symbolic/NondeterministicModel.cpp

@ -23,15 +23,29 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> 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::unordered_map<std::string, RewardModelType> const& rewardModels)
: Model<Type, ValueType>(modelType, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels), nondeterminismVariables(nondeterminismVariables) {
// Prepare the mask of illegal nondeterministic choices.
illegalMask = !(transitionMatrix.notZero().existsAbstract(this->getColumnVariables())) && reachableStates;
: Model<Type, ValueType>(modelType, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, labelToExpressionMap, rewardModels), nondeterminismVariables(nondeterminismVariables) {
createIllegalMask();
}
template<storm::dd::DdType Type, typename ValueType>
NondeterministicModel<Type, ValueType>::NondeterministicModel(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: Model<Type, ValueType>(modelType, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, columnVariables, rowColumnMetaVariablePairs, labelToBddMap, rewardModels), nondeterminismVariables(nondeterminismVariables) {
createIllegalMask();
}
template<storm::dd::DdType Type, typename ValueType>
@ -76,6 +90,12 @@ namespace storm {
out << ", nondeterminism: " << this->getNondeterminismVariables().size() << " meta variables (" << nondeterminismVariableCount << " DD variables)";
}
template<storm::dd::DdType Type, typename ValueType>
void NondeterministicModel<Type, ValueType>::createIllegalMask() {
// Prepare the mask of illegal nondeterministic choices.
illegalMask = !(this->getTransitionMatrix().notZero().existsAbstract(this->getColumnVariables())) && this->getReachableStates();
}
// Explicitly instantiate the template class.
template class NondeterministicModel<storm::dd::DdType::CUDD, double>;
template class NondeterministicModel<storm::dd::DdType::Sylvan, double>;

33
src/storm/models/symbolic/NondeterministicModel.h

@ -37,8 +37,6 @@ namespace storm {
* @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row
* meta variables.
* @param columVariables The set of column meta variables used in the DDs.
* @param columnExpressionAdapter An object that can be used to translate expressions in terms of the
* column meta variables.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param nondeterminismVariables The meta variables used to encode the nondeterminism in the model.
* @param labelToExpressionMap A mapping from label names to their defining expressions.
@ -53,12 +51,40 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> 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>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Constructs a model from the given data.
*
* @param modelType The type of the model.
* @param manager The manager responsible for the decision diagrams.
* @param reachableStates A DD representing the reachable states.
* @param initialStates A DD representing the initial states of the model.
* @param deadlockStates A DD representing the deadlock states of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param rowVariables The set of row meta variables used in the DDs.
* @param columVariables The set of column meta variables used in the DDs.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param nondeterminismVariables The meta variables used to encode the nondeterminism in the model.
* @param labelToBddMap A mapping from label names to their defining BDDs.
* @param rewardModels The reward models associated with the model.
*/
NondeterministicModel(storm::models::ModelType const& modelType,
std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Retrieves the number of nondeterministic choices in the model.
*
@ -97,6 +123,7 @@ namespace storm {
storm::dd::Bdd<Type> illegalMask;
private:
void createIllegalMask();
// The meta variables encoding the nondeterminism in the model.
std::set<storm::expressions::Variable> nondeterminismVariables;

33
src/storm/models/symbolic/StochasticTwoPlayerGame.cpp

@ -22,23 +22,44 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& player1Variables,
std::set<storm::expressions::Variable> const& player2Variables,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::expressions::Expression> labelToExpressionMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: NondeterministicModel<Type, ValueType>(storm::models::ModelType::S2pg, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, columnExpressionAdapter, rowColumnMetaVariablePairs, nondeterminismVariables, labelToExpressionMap, rewardModels), player1Variables(player1Variables), player2Variables(player2Variables) {
: NondeterministicModel<Type, ValueType>(storm::models::ModelType::S2pg, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToExpressionMap, rewardModels), player1Variables(player1Variables), player2Variables(player2Variables) {
createIllegalMasks();
}
template<storm::dd::DdType Type, typename ValueType>
StochasticTwoPlayerGame<Type, ValueType>::StochasticTwoPlayerGame(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& player1Variables,
std::set<storm::expressions::Variable> const& player2Variables,
std::set<storm::expressions::Variable> const& nondeterminismVariables,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap,
std::unordered_map<std::string, RewardModelType> const& rewardModels)
: NondeterministicModel<Type, ValueType>(storm::models::ModelType::S2pg, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToBddMap, rewardModels), player1Variables(player1Variables), player2Variables(player2Variables) {
createIllegalMasks();
}
template<storm::dd::DdType Type, typename ValueType>
void StochasticTwoPlayerGame<Type, ValueType>::createIllegalMasks() {
// Compute legal player 1 mask.
illegalPlayer1Mask = transitionMatrix.notZero().existsAbstract(this->getColumnVariables()).existsAbstract(this->getPlayer2Variables());
this->illegalPlayer1Mask = this->getTransitionMatrix().notZero().existsAbstract(this->getColumnVariables()).existsAbstract(this->getPlayer2Variables());
// Correct the mask for player 2. This is necessary, because it is not yet restricted to the legal choices of player 1.
illegalPlayer2Mask = this->getIllegalMask() && illegalPlayer1Mask;
illegalPlayer2Mask = this->getIllegalMask() && this->illegalPlayer1Mask;
// Then set the illegal mask for player 1 correctly.
illegalPlayer1Mask = !illegalPlayer1Mask && reachableStates;
this->illegalPlayer1Mask = !illegalPlayer1Mask && this->getReachableStates();
}
template<storm::dd::DdType Type, typename ValueType>

39
src/storm/models/symbolic/StochasticTwoPlayerGame.h

@ -36,8 +36,6 @@ namespace storm {
* @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row
* meta variables.
* @param columVariables The set of column meta variables used in the DDs.
* @param columnExpressionAdapter An object that can be used to translate expressions in terms of the
* column meta variables.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param player1Variables The meta variables used to encode the nondeterministic choices of player 1.
* @param player2Variables The meta variables used to encode the nondeterministic choices of player 2.
@ -53,7 +51,6 @@ namespace storm {
std::set<storm::expressions::Variable> const& rowVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter,
std::set<storm::expressions::Variable> const& columnVariables,
std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& player1Variables,
std::set<storm::expressions::Variable> const& player2Variables,
@ -61,6 +58,37 @@ namespace storm {
std::map<std::string, storm::expressions::Expression> labelToExpressionMap = std::map<std::string, storm::expressions::Expression>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Constructs a model from the given data.
*
* @param manager The manager responsible for the decision diagrams.
* @param reachableStates A DD representing the reachable states.
* @param initialStates A DD representing the initial states of the model.
* @param deadlockStates A DD representing the deadlock states of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param rowVariables The set of row meta variables used in the DDs.
* @param columVariables The set of column meta variables used in the DDs.
* @param rowColumnMetaVariablePairs All pairs of row/column meta variables.
* @param player1Variables The meta variables used to encode the nondeterministic choices of player 1.
* @param player2Variables The meta variables used to encode the nondeterministic choices of player 2.
* @param allNondeterminismVariables The meta variables used to encode the nondeterminism in the model.
* @param labelToBddMap A mapping from label names to their defining BDDs.
* @param rewardModels The reward models associated with the model.
*/
StochasticTwoPlayerGame(std::shared_ptr<storm::dd::DdManager<Type>> manager,
storm::dd::Bdd<Type> reachableStates,
storm::dd::Bdd<Type> initialStates,
storm::dd::Bdd<Type> deadlockStates,
storm::dd::Add<Type, ValueType> transitionMatrix,
std::set<storm::expressions::Variable> const& rowVariables,
std::set<storm::expressions::Variable> const& columnVariables,
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs,
std::set<storm::expressions::Variable> const& player1Variables,
std::set<storm::expressions::Variable> const& player2Variables,
std::set<storm::expressions::Variable> const& allNondeterminismVariables,
std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(),
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>());
/*!
* Retrieeves the set of meta variables used to encode the nondeterministic choices of player 1.
*
@ -90,6 +118,11 @@ namespace storm {
storm::dd::Bdd<Type> getIllegalPlayer2Mask() const;
private:
/*!
* Prepare all illegal masks.
*/
void createIllegalMasks();
// A mask that characterizes all illegal player 1 choices.
storm::dd::Bdd<Type> illegalPlayer1Mask;

19
src/storm/settings/modules/BisimulationSettings.cpp

@ -14,10 +14,17 @@ namespace storm {
const std::string BisimulationSettings::moduleName = "bisimulation";
const std::string BisimulationSettings::typeOptionName = "type";
const std::string BisimulationSettings::representativeOptionName = "repr";
const std::string BisimulationSettings::quotientFormatOptionName = "quot";
BisimulationSettings::BisimulationSettings() : ModuleSettings(moduleName) {
std::vector<std::string> types = { "strong", "weak" };
this->addOption(storm::settings::OptionBuilder(moduleName, typeOptionName, true, "Sets the kind of bisimulation quotienting used.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the type to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(types)).setDefaultValueString("strong").build()).build());
std::vector<std::string> quotTypes = { "sparse", "dd" };
this->addOption(storm::settings::OptionBuilder(moduleName, typeOptionName, true, "Sets the format in which the quotient is extracted (only applies to DD-based bisimulation).").addArgument(storm::settings::ArgumentBuilder::createStringArgument("format", "The format of the quotient.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(quotTypes)).setDefaultValueString("dd").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, representativeOptionName, false, "Sets whether to use representatives in the quotient rather than block numbers.").build());
}
bool BisimulationSettings::isStrongBisimulationSet() const {
@ -34,6 +41,18 @@ namespace storm {
return false;
}
BisimulationSettings::QuotientFormat BisimulationSettings::getQuotientFormat() const {
std::string quotientFormatAsString = this->getOption(typeOptionName).getArgumentByName("format").getValueAsString();
if (quotientFormatAsString == "sparse") {
return BisimulationSettings::QuotientFormat::Sparse;
}
return BisimulationSettings::QuotientFormat::Dd;
}
bool BisimulationSettings::isUseRepresentativesSet() const {
return this->getOption(representativeOptionName).getHasOptionBeenSet();
}
bool BisimulationSettings::check() const {
bool optionsSet = this->getOption(typeOptionName).getHasOptionBeenSet();
STORM_LOG_WARN_COND(storm::settings::getModule<storm::settings::modules::GeneralSettings>().isBisimulationSet() || !optionsSet, "Bisimulation minimization is not selected, so setting options for bisimulation has no effect.");

16
src/storm/settings/modules/BisimulationSettings.h

@ -15,7 +15,7 @@ namespace storm {
// An enumeration of all available bisimulation types.
enum class BisimulationType { Strong, Weak };
enum class CachingStrategy { FullDirect, FullLate, Granularity, Minimal };
enum class QuotientFormat { Sparse, Dd };
/*!
* Creates a new set of bisimulation settings.
@ -36,6 +36,18 @@ namespace storm {
*/
bool isWeakBisimulationSet() const;
/*!
* Retrieves the format in which the quotient is to be extracted.
* NOTE: only applies to DD-based bisimulation.
*/
QuotientFormat getQuotientFormat() const;
/*!
* Retrieves whether representatives for blocks are to be used instead of the block numbers.
* NOTE: only applies to DD-based bisimulation.
*/
bool isUseRepresentativesSet() const;
virtual bool check() const override;
// The name of the module.
@ -44,6 +56,8 @@ namespace storm {
private:
// Define the string names of the options as constants.
static const std::string typeOptionName;
static const std::string representativeOptionName;
static const std::string quotientFormatOptionName;
};
} // namespace modules
} // namespace settings

62
src/storm/storage/dd/Add.cpp

@ -186,9 +186,37 @@ namespace storm {
return internalAdd.equalModuloPrecision(other, precision, relative);
}
template<DdType LibraryType, typename ValueType>
Add<LibraryType, ValueType> Add<LibraryType, ValueType>::renameVariables(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const {
std::vector<InternalBdd<LibraryType>> fromBdds;
std::vector<InternalBdd<LibraryType>> toBdds;
for (auto const& metaVariable : from) {
STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename variable '" << metaVariable.getName() << "' that is not present.");
DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable);
for (auto const& ddVariable : ddMetaVariable.getDdVariables()) {
fromBdds.push_back(ddVariable);
}
}
for (auto const& metaVariable : to) {
STORM_LOG_THROW(!this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename to variable '" << metaVariable.getName() << "' that is already present.");
DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable);
for (auto const& ddVariable : ddMetaVariable.getDdVariables()) {
toBdds.push_back(ddVariable);
}
}
std::set<storm::expressions::Variable> newContainedMetaVariables = to;
std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin()));
STORM_LOG_THROW(fromBdds.size() == toBdds.size(), storm::exceptions::InvalidArgumentException, "Unable to rename mismatching meta variables.");
return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables);
}
template<DdType LibraryType, typename ValueType>
Add<LibraryType, ValueType> Add<LibraryType, ValueType>::swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) const {
std::set<storm::expressions::Variable> newContainedMetaVariables;
std::set<storm::expressions::Variable> deletedMetaVariables;
std::vector<InternalBdd<LibraryType>> from;
std::vector<InternalBdd<LibraryType>> to;
for (auto const& metaVariablePair : metaVariablePairs) {
@ -197,12 +225,20 @@ namespace storm {
// Keep track of the contained meta variables in the DD.
if (this->containsMetaVariable(metaVariablePair.first)) {
newContainedMetaVariables.insert(metaVariablePair.second);
}
if (this->containsMetaVariable(metaVariablePair.second)) {
newContainedMetaVariables.insert(metaVariablePair.first);
if (this->containsMetaVariable(metaVariablePair.second)) {
// Nothing to do here.
} else {
newContainedMetaVariables.insert(metaVariablePair.second);
deletedMetaVariables.insert(metaVariablePair.first);
}
} else {
if (!this->containsMetaVariable(metaVariablePair.second)) {
// Nothing to do here.
} else {
newContainedMetaVariables.insert(metaVariablePair.first);
deletedMetaVariables.insert(metaVariablePair.second);
}
}
for (auto const& ddVariable : variable1.getDdVariables()) {
from.push_back(ddVariable);
}
@ -210,13 +246,19 @@ namespace storm {
to.push_back(ddVariable);
}
}
std::set<storm::expressions::Variable> tmp;
std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), deletedMetaVariables.begin(), deletedMetaVariables.end(), std::inserter(tmp, tmp.begin()));
std::set<storm::expressions::Variable> containedMetaVariables;
std::set_union(tmp.begin(), tmp.end(), newContainedMetaVariables.begin(), newContainedMetaVariables.end(), std::inserter(containedMetaVariables, containedMetaVariables.begin()));
STORM_LOG_THROW(from.size() == to.size(), storm::exceptions::InvalidArgumentException, "Unable to swap mismatching meta variables.");
return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.swapVariables(from, to), newContainedMetaVariables);
return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.swapVariables(from, to), containedMetaVariables);
}
template<DdType LibraryType, typename ValueType>
Add<LibraryType, ValueType> Add<LibraryType, ValueType>::permuteVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) const {
std::set<storm::expressions::Variable> newContainedMetaVariables;
std::set<storm::expressions::Variable> deletedMetaVariables;
std::vector<InternalBdd<LibraryType>> from;
std::vector<InternalBdd<LibraryType>> to;
for (auto const& metaVariablePair : metaVariablePairs) {
@ -225,6 +267,7 @@ namespace storm {
// Keep track of the contained meta variables in the DD.
if (this->containsMetaVariable(metaVariablePair.first)) {
deletedMetaVariables.insert(metaVariablePair.first);
newContainedMetaVariables.insert(metaVariablePair.second);
}
@ -235,8 +278,13 @@ namespace storm {
to.push_back(ddVariable);
}
}
std::set<storm::expressions::Variable> tmp;
std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), deletedMetaVariables.begin(), deletedMetaVariables.end(), std::inserter(tmp, tmp.begin()));
std::set<storm::expressions::Variable> containedMetaVariables;
std::set_union(tmp.begin(), tmp.end(), newContainedMetaVariables.begin(), newContainedMetaVariables.end(), std::inserter(containedMetaVariables, containedMetaVariables.begin()));
STORM_LOG_THROW(from.size() == to.size(), storm::exceptions::InvalidArgumentException, "Unable to swap mismatching meta variables.");
return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.permuteVariables(from, to), newContainedMetaVariables);
return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.permuteVariables(from, to), containedMetaVariables);
}
template<DdType LibraryType, typename ValueType>

13
src/storm/storage/dd/Add.h

@ -310,6 +310,17 @@ namespace storm {
* values.
*/
bool equalModuloPrecision(Add<LibraryType, ValueType> const& other, ValueType const& precision, bool relative = true) const;
/*!
* Renames the given meta variables in the ADD. The number of the underlying DD variables of the both meta
* variable sets needs to agree.
*
* @param from The meta variables to be renamed. The current ADD needs to contain all these meta variables.
* @param to The meta variables that are the target of the renaming process. The current ADD must not contain
* any of these meta variables.
* @return The resulting ADD.
*/
Add<LibraryType, ValueType> renameVariables(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const;
/*!
* Swaps the given pairs of meta variables in the ADD. The pairs of meta variables must be guaranteed to have
@ -319,7 +330,7 @@ namespace storm {
* @return The resulting ADD.
*/
Add<LibraryType, ValueType> swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) const;
/*!
* Permutes 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. The first component of the i-th entry is substituted by the second component.

52
src/storm/storage/dd/Bdd.cpp

@ -253,6 +253,7 @@ namespace storm {
template<DdType LibraryType>
Bdd<LibraryType> Bdd<LibraryType>::swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) const {
std::set<storm::expressions::Variable> newContainedMetaVariables;
std::set<storm::expressions::Variable> deletedMetaVariables;
std::vector<InternalBdd<LibraryType>> from;
std::vector<InternalBdd<LibraryType>> to;
for (auto const& metaVariablePair : metaVariablePairs) {
@ -261,10 +262,19 @@ namespace storm {
// Keep track of the contained meta variables in the DD.
if (this->containsMetaVariable(metaVariablePair.first)) {
newContainedMetaVariables.insert(metaVariablePair.second);
}
if (this->containsMetaVariable(metaVariablePair.second)) {
newContainedMetaVariables.insert(metaVariablePair.first);
if (this->containsMetaVariable(metaVariablePair.second)) {
// Nothing to do here.
} else {
newContainedMetaVariables.insert(metaVariablePair.second);
deletedMetaVariables.insert(metaVariablePair.first);
}
} else {
if (!this->containsMetaVariable(metaVariablePair.second)) {
// Nothing to do here.
} else {
newContainedMetaVariables.insert(metaVariablePair.first);
deletedMetaVariables.insert(metaVariablePair.second);
}
}
for (auto const& ddVariable : variable1.getDdVariables()) {
@ -274,7 +284,39 @@ namespace storm {
to.push_back(ddVariable);
}
}
return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(from, to), newContainedMetaVariables);
std::set<storm::expressions::Variable> tmp;
std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), deletedMetaVariables.begin(), deletedMetaVariables.end(), std::inserter(tmp, tmp.begin()));
std::set<storm::expressions::Variable> containedMetaVariables;
std::set_union(tmp.begin(), tmp.end(), newContainedMetaVariables.begin(), newContainedMetaVariables.end(), std::inserter(containedMetaVariables, containedMetaVariables.begin()));
return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(from, to), containedMetaVariables);
}
template<DdType LibraryType>
Bdd<LibraryType> Bdd<LibraryType>::renameVariables(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const {
std::vector<InternalBdd<LibraryType>> fromBdds;
std::vector<InternalBdd<LibraryType>> toBdds;
for (auto const& metaVariable : from) {
STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename variable '" << metaVariable.getName() << "' that is not present.");
DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable);
for (auto const& ddVariable : ddMetaVariable.getDdVariables()) {
fromBdds.push_back(ddVariable);
}
}
for (auto const& metaVariable : to) {
STORM_LOG_THROW(!this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename to variable '" << metaVariable.getName() << "' that is already present.");
DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable);
for (auto const& ddVariable : ddMetaVariable.getDdVariables()) {
toBdds.push_back(ddVariable);
}
}
std::set<storm::expressions::Variable> newContainedMetaVariables = to;
std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin()));
STORM_LOG_THROW(fromBdds.size() == toBdds.size(), storm::exceptions::InvalidArgumentException, "Unable to rename mismatching meta variables.");
return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables);
}
template<DdType LibraryType>

11
src/storm/storage/dd/Bdd.h

@ -274,6 +274,17 @@ namespace storm {
*/
Bdd<LibraryType> swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) const;
/*!
* Renames the given meta variables in the BDD. The number of the underlying DD variables of the both meta
* variable sets needs to agree.
*
* @param from The meta variables to be renamed. The current BDD needs to contain all these meta variables.
* @param to The meta variables that are the target of the renaming process. The current BDD must not contain
* any of these meta variables.
* @return The resulting BDD.
*/
Bdd<LibraryType> renameVariables(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const;
/*!
* Retrieves whether this DD represents the constant one function.
*

20
src/storm/storage/dd/BisimulationDecomposition.cpp

@ -2,9 +2,11 @@
#include "storm/storage/dd/bisimulation/SignatureComputer.h"
#include "storm/storage/dd/bisimulation/SignatureRefiner.h"
#include "storm/storage/dd/bisimulation/QuotientExtractor.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/InvalidOperationException.h"
#include "storm/exceptions/NotSupportedException.h"
#include <sylvan_table.h>
@ -16,15 +18,20 @@ namespace storm {
using namespace bisimulation;
template <storm::dd::DdType DdType, typename ValueType>
BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model) : status(Status::Initialized), model(model), currentPartition(bisimulation::Partition<DdType, ValueType>::create(model)) {
BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model) : BisimulationDecomposition(model, bisimulation::Partition<DdType, ValueType>::create(model)) {
// Intentionally left empty.
}
template <storm::dd::DdType DdType, typename ValueType>
BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialPartition) : model(model), currentPartition(initialPartition) {
BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) : BisimulationDecomposition(model, bisimulation::Partition<DdType, ValueType>::create(model, formulas)) {
// Intentionally left empty.
}
template <storm::dd::DdType DdType, typename ValueType>
BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialPartition) : model(model), currentPartition(initialPartition) {
STORM_LOG_THROW(!model.hasRewardModel(), storm::exceptions::NotSupportedException, "Symbolic bisimulation currently does not support preserving rewards.");
}
template <storm::dd::DdType DdType, typename ValueType>
void BisimulationDecomposition<DdType, ValueType>::compute() {
this->status = Status::InComputation;
@ -52,7 +59,6 @@ namespace storm {
auto refinementStart = std::chrono::high_resolution_clock::now();
Partition<DdType, ValueType> newPartition = refiner.refine(currentPartition, signature);
// newPartition.getPartitionAdd().exportToDot("part" + std::to_string(iterations) + ".dot");
auto refinementEnd = std::chrono::high_resolution_clock::now();
totalRefinementTime += (refinementEnd - refinementStart);
@ -78,7 +84,13 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType>
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> BisimulationDecomposition<DdType, ValueType>::getQuotient() const {
STORM_LOG_THROW(this->status == Status::FixedPoint, storm::exceptions::InvalidOperationException, "Cannot extract quotient, because bisimulation decomposition was not completed.");
return nullptr;
STORM_LOG_TRACE("Starting quotient extraction.");
QuotientExtractor<DdType, ValueType> extractor;
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> quotient = extractor.extract(model, currentPartition);
STORM_LOG_TRACE("Quotient extraction done.");
return quotient;
}
template class BisimulationDecomposition<storm::dd::DdType::CUDD, double>;

9
src/storm/storage/dd/BisimulationDecomposition.h

@ -1,10 +1,15 @@
#pragma once
#include <memory>
#include <vector>
#include "storm/storage/dd/DdType.h"
#include "storm/storage/dd/bisimulation/Partition.h"
#include "storm/models/symbolic/Model.h"
#include "storm/storage/dd/bisimulation/Partition.h"
#include "storm/logic/Formula.h"
namespace storm {
namespace dd {
@ -17,7 +22,7 @@ namespace storm {
};
BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model);
BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas);
BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, bisimulation::Partition<DdType, ValueType> const& initialPartition);
/*!

15
src/storm/storage/dd/DdManager.cpp

@ -21,6 +21,16 @@ namespace storm {
// Intentionally left empty.
}
template<DdType LibraryType>
std::shared_ptr<DdManager<LibraryType>> DdManager<LibraryType>::asSharedPointer() {
return this->shared_from_this();
}
template<DdType LibraryType>
std::shared_ptr<DdManager<LibraryType> const> DdManager<LibraryType>::asSharedPointer() const {
return this->shared_from_this();
}
template<DdType LibraryType>
Bdd<LibraryType> DdManager<LibraryType>::getBddOne() const {
return Bdd<LibraryType>(*this, internalDdManager.getBddOne());
@ -221,6 +231,11 @@ namespace storm {
return result;
}
template<DdType LibraryType>
std::vector<storm::expressions::Variable> DdManager<LibraryType>::addBitVectorMetaVariable(std::string const& variableName, uint64_t bits, uint64_t numberOfLayers, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>> const& position) {
return this->addMetaVariable(variableName, 0, (1ull << bits) - 1, numberOfLayers, position);
}
template<DdType LibraryType>
std::pair<storm::expressions::Variable, storm::expressions::Variable> DdManager<LibraryType>::addMetaVariable(std::string const& name, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>> const& position) {
std::vector<storm::expressions::Variable> result = addMetaVariable(name, 2, position);

15
src/storm/storage/dd/DdManager.h

@ -21,7 +21,7 @@ namespace storm {
namespace dd {
// Declare DdManager class so we can then specialize it for the different DD types.
template<DdType LibraryType>
class DdManager {
class DdManager : public std::enable_shared_from_this<DdManager<LibraryType>> {
public:
friend class Bdd<LibraryType>;
@ -41,6 +41,9 @@ namespace storm {
DdManager<LibraryType>& operator=(DdManager<LibraryType> const& other) = delete;
DdManager(DdManager<LibraryType>&& other) = default;
DdManager<LibraryType>& operator=(DdManager<LibraryType>&& other) = default;
std::shared_ptr<DdManager<LibraryType>> asSharedPointer();
std::shared_ptr<DdManager<LibraryType> const> asSharedPointer() const;
/*!
* Retrieves a BDD representing the constant one function.
@ -160,7 +163,15 @@ namespace storm {
* @param numberOfLayers The number of layers of this variable (must be greater or equal 1).
*/
std::vector<storm::expressions::Variable> addMetaVariable(std::string const& variableName, int_fast64_t low, int_fast64_t high, uint64_t numberOfLayers, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>> const& position = boost::none);
/*!
* Creates a meta variable with the given number of layers.
*
* @param variableName The name of the variable.
* @param numberOfLayers The number of layers of this variable (must be greater or equal 1).
*/
std::vector<storm::expressions::Variable> addBitVectorMetaVariable(std::string const& variableName, uint64_t bits, uint64_t numberOfLayers, boost::optional<std::pair<MetaVariablePosition, storm::expressions::Variable>> const& position = boost::none);
/*!
* Adds a boolean meta variable with two layers (a 'normal' and a 'primed' one).
*

114
src/storm/storage/dd/bisimulation/Partition.cpp

@ -2,33 +2,42 @@
#include "storm/storage/dd/DdManager.h"
#include "storm/storage/dd/bisimulation/PreservationInformation.h"
#include "storm/logic/Formula.h"
#include "storm/logic/AtomicExpressionFormula.h"
#include "storm/logic/AtomicLabelFormula.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/InvalidPropertyException.h"
namespace storm {
namespace dd {
namespace bisimulation {
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType>::Partition(storm::dd::Add<DdType, ValueType> const& partitionAdd, storm::expressions::Variable const& blockVariable, uint64_t nextFreeBlockIndex) : partition(partitionAdd), blockVariable(blockVariable), nextFreeBlockIndex(nextFreeBlockIndex) {
Partition<DdType, ValueType>::Partition(std::shared_ptr<PreservationInformation> preservationInformation, storm::dd::Add<DdType, ValueType> const& partitionAdd, std::pair<storm::expressions::Variable, storm::expressions::Variable> const& blockVariables, uint64_t nextFreeBlockIndex) : preservationInformation(preservationInformation), partition(partitionAdd), blockVariables(blockVariables), nextFreeBlockIndex(nextFreeBlockIndex) {
// Intentionally left empty.
}
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType>::Partition(storm::dd::Bdd<DdType> const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t nextFreeBlockIndex) : partition(partitionBdd), blockVariable(blockVariable), nextFreeBlockIndex(nextFreeBlockIndex) {
Partition<DdType, ValueType>::Partition(std::shared_ptr<PreservationInformation> preservationInformation, storm::dd::Bdd<DdType> const& partitionBdd, std::pair<storm::expressions::Variable, storm::expressions::Variable> const& blockVariables, uint64_t nextFreeBlockIndex) : preservationInformation(preservationInformation), partition(partitionBdd), blockVariables(blockVariables), nextFreeBlockIndex(nextFreeBlockIndex) {
// Intentionally left empty.
}
template<storm::dd::DdType DdType, typename ValueType>
bool Partition<DdType, ValueType>::operator==(Partition<DdType, ValueType> const& other) {
return this->partition == other.partition && this->blockVariable == other.blockVariable && this->nextFreeBlockIndex == other.nextFreeBlockIndex;
return this->partition == other.partition && this->blockVariables == other.blockVariables && this->nextFreeBlockIndex == other.nextFreeBlockIndex;
}
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::replacePartition(storm::dd::Add<DdType, ValueType> const& newPartitionAdd, uint64_t nextFreeBlockIndex) const {
return Partition<DdType, ValueType>(newPartitionAdd, blockVariable, nextFreeBlockIndex);
return Partition<DdType, ValueType>(preservationInformation, newPartitionAdd, blockVariables, nextFreeBlockIndex);
}
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::replacePartition(storm::dd::Bdd<DdType> const& newPartitionBdd, uint64_t nextFreeBlockIndex) const {
return Partition<DdType, ValueType>(newPartitionBdd, blockVariable, nextFreeBlockIndex);
return Partition<DdType, ValueType>(preservationInformation, newPartitionBdd, blockVariables, nextFreeBlockIndex);
}
template<storm::dd::DdType DdType, typename ValueType>
@ -38,15 +47,57 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::create(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::string> const& labels) {
std::shared_ptr<PreservationInformation> preservationInformation = std::make_shared<PreservationInformation>();
std::vector<storm::expressions::Expression> expressions;
for (auto const& label : labels) {
preservationInformation->addLabel(label);
expressions.push_back(model.getExpression(label));
}
return create(model, expressions);
return create(model, expressions, preservationInformation);
}
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::create(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<storm::expressions::Expression> const& expressions) {
std::shared_ptr<PreservationInformation> preservationInformation = std::make_shared<PreservationInformation>();
for (auto const& expression : expressions) {
preservationInformation->addExpression(expression);
}
return create(model, expressions, preservationInformation);
}
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::create(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
if (formulas.empty()) {
return create(model);
}
std::shared_ptr<PreservationInformation> preservationInformation = std::make_shared<PreservationInformation>();
std::set<std::string> labels;
std::set<storm::expressions::Expression> expressions;
for (auto const& formula : formulas) {
for (auto const& expressionFormula : formula->getAtomicExpressionFormulas()) {
expressions.insert(expressionFormula->getExpression());
preservationInformation->addExpression(expressionFormula->getExpression());
}
for (auto const& labelFormula : formula->getAtomicLabelFormulas()) {
std::string const& label = labelFormula->getLabel();
STORM_LOG_THROW(model.hasLabel(label), storm::exceptions::InvalidPropertyException, "Property refers to illegal label '" << label << "'.");
preservationInformation->addLabel(label);
expressions.insert(model.getExpression(label));
}
}
std::vector<storm::expressions::Expression> expressionVector;
for (auto const& expression : expressions) {
expressionVector.emplace_back(expression);
}
return create(model, expressionVector, preservationInformation);
}
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::create(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<storm::expressions::Expression> const& expressions, std::shared_ptr<PreservationInformation> const& preservationInformation) {
storm::dd::DdManager<DdType>& manager = model.getManager();
std::vector<storm::dd::Bdd<DdType>> stateSets;
@ -54,14 +105,20 @@ namespace storm {
stateSets.emplace_back(model.getStates(expression));
}
storm::expressions::Variable blockVariable = createBlockVariable(manager, model.getReachableStates().getNonZeroCount());
std::pair<storm::dd::Bdd<DdType>, uint64_t> partitionBddAndBlockCount = createPartitionBdd(manager, model, stateSets, blockVariable);
uint64_t numberOfDdVariables = 0;
for (auto const& metaVariable : model.getRowVariables()) {
auto const& ddMetaVariable = manager.getMetaVariable(metaVariable);
numberOfDdVariables += ddMetaVariable.getNumberOfDdVariables();
}
std::pair<storm::expressions::Variable, storm::expressions::Variable> blockVariables = createBlockVariables(manager, numberOfDdVariables);
std::pair<storm::dd::Bdd<DdType>, uint64_t> partitionBddAndBlockCount = createPartitionBdd(manager, model, stateSets, blockVariables.first);
// Store the partition as an ADD only in the case of CUDD.
if (DdType == storm::dd::DdType::CUDD) {
return Partition<DdType, ValueType>(partitionBddAndBlockCount.first.template toAdd<ValueType>(), blockVariable, partitionBddAndBlockCount.second);
return Partition<DdType, ValueType>(preservationInformation, partitionBddAndBlockCount.first.template toAdd<ValueType>(), blockVariables, partitionBddAndBlockCount.second);
} else {
return Partition<DdType, ValueType>(partitionBddAndBlockCount.first, blockVariable, partitionBddAndBlockCount.second);
return Partition<DdType, ValueType>(preservationInformation, partitionBddAndBlockCount.first, blockVariables, partitionBddAndBlockCount.second);
}
}
@ -92,7 +149,12 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType>
storm::expressions::Variable const& Partition<DdType, ValueType>::getBlockVariable() const {
return blockVariable;
return blockVariables.first;
}
template<storm::dd::DdType DdType, typename ValueType>
storm::expressions::Variable const& Partition<DdType, ValueType>::getPrimedBlockVariable() const {
return blockVariables.second;
}
template<storm::dd::DdType DdType, typename ValueType>
@ -109,6 +171,11 @@ namespace storm {
}
}
template<storm::dd::DdType DdType, typename ValueType>
PreservationInformation const& Partition<DdType, ValueType>::getPreservationInformation() const {
return *preservationInformation;
}
template<storm::dd::DdType DdType>
void enumerateBlocksRec(std::vector<storm::dd::Bdd<DdType>> const& stateSets, storm::dd::Bdd<DdType> const& currentStateSet, uint64_t offset, storm::expressions::Variable const& blockVariable, std::function<void (storm::dd::Bdd<DdType> const&)> const& callback) {
if (currentStateSet.isZero()) {
@ -125,34 +192,33 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType>
std::pair<storm::dd::Bdd<DdType>, uint64_t> Partition<DdType, ValueType>::createPartitionBdd(storm::dd::DdManager<DdType> const& manager, storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<storm::dd::Bdd<DdType>> const& stateSets, storm::expressions::Variable const& blockVariable) {
uint64_t blockCount = 0;
storm::dd::Bdd<DdType> partitionAdd = manager.getBddZero();
storm::dd::Bdd<DdType> partitionBdd = manager.getBddZero();
// Enumerate all realizable blocks.
enumerateBlocksRec<DdType>(stateSets, model.getReachableStates(), 0, blockVariable, [&manager, &partitionAdd, &blockVariable, &blockCount](storm::dd::Bdd<DdType> const& stateSet) {
stateSet.template toAdd<ValueType>().exportToDot("states_" + std::to_string(blockCount) + ".dot");
partitionAdd |= (stateSet && manager.getEncoding(blockVariable, blockCount, false));
enumerateBlocksRec<DdType>(stateSets, model.getReachableStates(), 0, blockVariable, [&manager, &partitionBdd, &blockVariable, &blockCount](storm::dd::Bdd<DdType> const& stateSet) {
partitionBdd |= (stateSet && manager.getEncoding(blockVariable, blockCount, false));
blockCount++;
} );
// Move the partition over to the primed variables.
partitionAdd = partitionAdd.swapVariables(model.getRowColumnMetaVariablePairs());
return std::make_pair(partitionAdd, blockCount);
partitionBdd = partitionBdd.swapVariables(model.getRowColumnMetaVariablePairs());
return std::make_pair(partitionBdd, blockCount);
}
template<storm::dd::DdType DdType, typename ValueType>
storm::expressions::Variable Partition<DdType, ValueType>::createBlockVariable(storm::dd::DdManager<DdType>& manager, uint64_t numberOfStates) {
storm::expressions::Variable blockVariable;
std::pair<storm::expressions::Variable, storm::expressions::Variable> Partition<DdType, ValueType>::createBlockVariables(storm::dd::DdManager<DdType>& manager, uint64_t numberOfDdVariables) {
std::vector<storm::expressions::Variable> blockVariables;
if (manager.hasMetaVariable("blocks")) {
int64_t counter = 0;
while (manager.hasMetaVariable("block" + std::to_string(counter))) {
++counter;
}
blockVariable = manager.addMetaVariable("blocks" + std::to_string(counter), 0, numberOfStates, 1).front();
blockVariables = manager.addBitVectorMetaVariable("blocks" + std::to_string(counter), numberOfDdVariables, 2);
} else {
blockVariable = manager.addMetaVariable("blocks", 0, numberOfStates, 1).front();
blockVariables = manager.addBitVectorMetaVariable("blocks", numberOfDdVariables, 2);
}
return blockVariable;
return std::make_pair(blockVariables[0], blockVariables[1]);
}
template class Partition<storm::dd::DdType::CUDD, double>;

81
src/storm/storage/dd/bisimulation/Partition.h

@ -1,5 +1,8 @@
#pragma once
#include <vector>
#include <memory>
#include <boost/variant.hpp>
#include "storm/storage/dd/DdType.h"
@ -9,38 +12,20 @@
#include "storm/models/symbolic/Model.h"
namespace storm {
namespace logic {
class Formula;
}
namespace dd {
namespace bisimulation {
class PreservationInformation;
template<storm::dd::DdType DdType, typename ValueType>
class Partition {
public:
Partition() = default;
/*!
* Creates a new partition from the given data.
*
* @param partitionAdd An ADD that maps encoding over the state/row variables and the block variable to
* one iff the state is in the block.
* @param blockVariable The variable to use for the block encoding. Its range must be [0, x] where x is
* the number of states in the partition.
* @param nextFreeBlockIndex The next free block index. The existing blocks must be encoded with indices
* between 0 and this number.
*/
Partition(storm::dd::Add<DdType, ValueType> const& partitionAdd, storm::expressions::Variable const& blockVariable, uint64_t nextFreeBlockIndex);
/*!
* Creates a new partition from the given data.
*
* @param partitionBdd A BDD that maps encoding over the state/row variables and the block variable to
* true iff the state is in the block.
* @param blockVariable The variable to use for the block encoding. Its range must be [0, x] where x is
* the number of states in the partition.
* @param nextFreeBlockIndex The next free block index. The existing blocks must be encoded with indices
* between 0 and this number.
*/
Partition(storm::dd::Bdd<DdType> const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t nextFreeBlockIndex);
bool operator==(Partition<DdType, ValueType> const& other);
Partition<DdType, ValueType> replacePartition(storm::dd::Add<DdType, ValueType> const& newPartitionAdd, uint64_t nextFreeBlockIndex) const;
@ -62,6 +47,11 @@ namespace storm {
*/
static Partition create(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<storm::expressions::Expression> const& expressions);
/*!
* Creates a partition from the given model that preserves the given formulas.
*/
static Partition create(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas);
uint64_t getNumberOfBlocks() const;
bool storedAsAdd() const;
@ -71,21 +61,56 @@ namespace storm {
storm::dd::Bdd<DdType> const& asBdd() const;
storm::expressions::Variable const& getBlockVariable() const;
storm::expressions::Variable const& getPrimedBlockVariable() const;
uint64_t getNextFreeBlockIndex() const;
uint64_t getNodeCount() const;
PreservationInformation const& getPreservationInformation() const;
private:
/*!
* Creates a new partition from the given data.
*
* @param preservationInformation Informatin about which labels/expressions this partition preserves.
* @param partitionAdd An ADD that maps encoding over the state/row variables and the block variable to
* one iff the state is in the block.
* @param blockVariables The variables to use for the block encoding. Its range must be [0, x] where x is
* greater or equal than the number of states in the partition.
* @param nextFreeBlockIndex The next free block index. The existing blocks must be encoded with indices
* between 0 and this number.
*/
Partition(std::shared_ptr<PreservationInformation> preservationInformation, storm::dd::Add<DdType, ValueType> const& partitionAdd, std::pair<storm::expressions::Variable, storm::expressions::Variable> const& blockVariables, uint64_t nextFreeBlockIndex);
/*!
* Creates a new partition from the given data.
*
* @param preservationInformation Informatin about which labels/expressions this partition preserves.
* @param partitionBdd A BDD that maps encoding over the state/row variables and the block variable to
* true iff the state is in the block.
* @param blockVariables The variables to use for the block encoding. Their range must be [0, x] where x is
* greater or equal than the number of states in the partition.
* @param nextFreeBlockIndex The next free block index. The existing blocks must be encoded with indices
* between 0 and this number.
*/
Partition(std::shared_ptr<PreservationInformation> preservationInformation, storm::dd::Bdd<DdType> const& partitionBdd, std::pair<storm::expressions::Variable, storm::expressions::Variable> const& blockVariables, uint64_t nextFreeBlockIndex);
/*!
* Creates a partition from the given model that respects the given expressions.
*/
static Partition create(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<storm::expressions::Expression> const& expressions, std::shared_ptr<PreservationInformation> const& preservationInformation);
static std::pair<storm::dd::Bdd<DdType>, uint64_t> createPartitionBdd(storm::dd::DdManager<DdType> const& manager, storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<storm::dd::Bdd<DdType>> const& stateSets, storm::expressions::Variable const& blockVariable);
static storm::expressions::Variable createBlockVariable(storm::dd::DdManager<DdType>& manager, uint64_t numberOfStates);
static std::pair<storm::expressions::Variable, storm::expressions::Variable> createBlockVariables(storm::dd::DdManager<DdType>& manager, uint64_t numberOfDdVariables);
std::shared_ptr<PreservationInformation> preservationInformation;
/// The DD representing the partition. The DD is over the row variables of the model and the block variable.
boost::variant<storm::dd::Bdd<DdType>, storm::dd::Add<DdType, ValueType>> partition;
/// The meta variable used to encode the block of each state in this partition.
storm::expressions::Variable blockVariable;
/// The meta variables used to encode the block of each state in this partition.
std::pair<storm::expressions::Variable, storm::expressions::Variable> blockVariables;
/// The next free block index.
uint64_t nextFreeBlockIndex;

24
src/storm/storage/dd/bisimulation/PreservationInformation.cpp

@ -0,0 +1,24 @@
#include "storm/storage/dd/bisimulation/PreservationInformation.h"
namespace storm {
namespace dd {
namespace bisimulation {
void PreservationInformation::addLabel(std::string const& label) {
labels.insert(label);
}
void PreservationInformation::addExpression(storm::expressions::Expression const& expression) {
expressions.insert(expression);
}
std::set<std::string> const& PreservationInformation::getLabels() const {
return labels;
}
std::set<storm::expressions::Expression> const& PreservationInformation::getExpressions() const {
return expressions;
}
}
}
}

30
src/storm/storage/dd/bisimulation/PreservationInformation.h

@ -0,0 +1,30 @@
#pragma once
#include <set>
#include <string>
#include "storm/storage/expressions/Expression.h"
namespace storm {
namespace dd {
namespace bisimulation {
class PreservationInformation {
public:
PreservationInformation() = default;
void addLabel(std::string const& label);
void addExpression(storm::expressions::Expression const& expression);
std::set<std::string> const& getLabels() const;
std::set<storm::expressions::Expression> const& getExpressions() const;
private:
std::set<std::string> labels;
std::set<storm::expressions::Expression> expressions;
};
}
}
}

161
src/storm/storage/dd/bisimulation/QuotientExtractor.cpp

@ -0,0 +1,161 @@
#include "storm/storage/dd/bisimulation/QuotientExtractor.h"
#include "storm/storage/dd/DdManager.h"
#include "storm/models/symbolic/Dtmc.h"
#include "storm/models/symbolic/Ctmc.h"
#include "storm/models/symbolic/StandardRewardModel.h"
#include "storm/storage/dd/bisimulation/PreservationInformation.h"
#include "storm/settings/SettingsManager.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/NotSupportedException.h"
namespace storm {
namespace dd {
namespace bisimulation {
template<storm::dd::DdType DdType, typename ValueType>
QuotientExtractor<DdType, ValueType>::QuotientExtractor() : useRepresentatives(false) {
auto const& settings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>();
this->useRepresentatives = settings.isUseRepresentativesSet();
this->quotientFormat = settings.getQuotientFormat();
}
template<storm::dd::DdType DdType, typename ValueType>
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition) {
auto start = std::chrono::high_resolution_clock::now();
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result;
if (quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Sparse) {
result = extractSparseQuotient(model, partition);
} else {
result = extractDdQuotient(model, partition);
}
auto end = std::chrono::high_resolution_clock::now();
STORM_LOG_TRACE("Quotient extraction completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms.");
return result;
}
template<storm::dd::DdType DdType, typename ValueType>
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition) {
return nullptr;
}
template<storm::dd::DdType DdType, typename ValueType>
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition) {
return extractQuotientUsingBlockVariables(model, partition);
}
template<storm::dd::DdType DdType, typename ValueType>
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition) {
auto modelType = model.getType();
if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc) {
std::set<storm::expressions::Variable> blockVariableSet = {partition.getBlockVariable()};
std::set<storm::expressions::Variable> blockPrimeVariableSet = {partition.getPrimedBlockVariable()};
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {std::make_pair(partition.getBlockVariable(), partition.getPrimedBlockVariable())};
storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero();
if (useRepresentatives) {
storm::dd::Bdd<DdType> partitionAsBddOverPrimedBlockVariable = partitionAsBdd.renameVariables(blockVariableSet, blockPrimeVariableSet);
storm::dd::Bdd<DdType> representativePartition = partitionAsBddOverPrimedBlockVariable.existsAbstractRepresentative(model.getColumnVariables()).renameVariables(model.getColumnVariables(), blockVariableSet);
partitionAsBdd = (representativePartition && partitionAsBddOverPrimedBlockVariable).existsAbstract(blockPrimeVariableSet);
}
storm::dd::Add<DdType, ValueType> partitionAsAdd = partitionAsBdd.template toAdd<ValueType>();
storm::dd::Add<DdType, ValueType> quotientTransitionMatrix = model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(blockVariableSet, blockPrimeVariableSet), model.getColumnVariables());
quotientTransitionMatrix = quotientTransitionMatrix.multiplyMatrix(partitionAsAdd.renameVariables(model.getColumnVariables(), model.getRowVariables()), model.getRowVariables());
storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.notZero();
storm::dd::Bdd<DdType> partitionAsBddOverRowVariables = partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables());
storm::dd::Bdd<DdType> reachableStates = partitionAsBdd.existsAbstract(model.getColumnVariables());
storm::dd::Bdd<DdType> initialStates = (model.getInitialStates() && partitionAsBddOverRowVariables).existsAbstract(model.getRowVariables());
storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(blockPrimeVariableSet) && reachableStates;
std::map<std::string, storm::dd::Bdd<DdType>> preservedLabelBdds;
for (auto const& label : partition.getPreservationInformation().getLabels()) {
preservedLabelBdds.emplace(label, (model.getStates(label) && partitionAsBddOverRowVariables).existsAbstract(model.getRowVariables()));
}
for (auto const& expression : partition.getPreservationInformation().getExpressions()) {
std::stringstream stream;
stream << expression;
std::string expressionAsString = stream.str();
auto it = preservedLabelBdds.find(expressionAsString);
if (it != preservedLabelBdds.end()) {
STORM_LOG_WARN("Duplicate label '" << expressionAsString << "', dropping second label definition.");
} else {
preservedLabelBdds.emplace(stream.str(), (model.getStates(expression) && partitionAsBddOverRowVariables).existsAbstract(model.getRowVariables()));
}
}
if (modelType == storm::models::ModelType::Dtmc) {
return std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, {}));
} else {
return std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, {}));
}
} else {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot exctract quotient for this model type.");
}
}
template<storm::dd::DdType DdType, typename ValueType>
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition) {
auto modelType = model.getType();
if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc) {
std::set<storm::expressions::Variable> blockVariableSet = {partition.getBlockVariable()};
std::set<storm::expressions::Variable> blockPrimeVariableSet = {partition.getPrimedBlockVariable()};
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {std::make_pair(partition.getBlockVariable(), partition.getPrimedBlockVariable())};
storm::dd::Add<DdType, ValueType> partitionAsAdd = partition.storedAsBdd() ? partition.asBdd().template toAdd<ValueType>() : partition.asAdd();
storm::dd::Add<DdType, ValueType> quotientTransitionMatrix = model.getTransitionMatrix().multiplyMatrix(partitionAsAdd, model.getColumnVariables());
quotientTransitionMatrix = quotientTransitionMatrix.renameVariables(blockVariableSet, model.getColumnVariables());
quotientTransitionMatrix = quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables());
quotientTransitionMatrix = quotientTransitionMatrix.renameVariables(blockVariableSet, model.getRowVariables());
storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.notZero();
storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero();
storm::dd::Bdd<DdType> partitionAsBddOverRowVariables = partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables());
storm::dd::Bdd<DdType> reachableStates = partitionAsBdd.existsAbstract(model.getColumnVariables()).renameVariables(blockVariableSet, model.getRowVariables());
storm::dd::Bdd<DdType> initialStates = (model.getInitialStates() && partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables())).existsAbstract(model.getRowVariables()).renameVariables(blockVariableSet, model.getRowVariables());
storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(model.getColumnVariables()) && reachableStates;
std::map<std::string, storm::dd::Bdd<DdType>> preservedLabelBdds;
for (auto const& label : partition.getPreservationInformation().getLabels()) {
preservedLabelBdds.emplace(label, (model.getStates(label) && partitionAsBddOverRowVariables).existsAbstract(model.getRowVariables()));
}
for (auto const& expression : partition.getPreservationInformation().getExpressions()) {
std::stringstream stream;
stream << expression;
std::string expressionAsString = stream.str();
auto it = preservedLabelBdds.find(expressionAsString);
if (it != preservedLabelBdds.end()) {
STORM_LOG_WARN("Duplicate label '" << expressionAsString << "', dropping second label definition.");
} else {
preservedLabelBdds.emplace(stream.str(), (model.getStates(expression) && partitionAsBddOverRowVariables).existsAbstract(model.getRowVariables()));
}
}
if (modelType == storm::models::ModelType::Dtmc) {
return std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, {}));
} else {
return std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, {}));
}
} else {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot exctract quotient for this model type.");
}
}
template class QuotientExtractor<storm::dd::DdType::CUDD, double>;
template class QuotientExtractor<storm::dd::DdType::Sylvan, double>;
template class QuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber>;
template class QuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalFunction>;
}
}
}

37
src/storm/storage/dd/bisimulation/QuotientExtractor.h

@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include "storm/storage/dd/DdType.h"
#include "storm/models/symbolic/Model.h"
#include "storm/storage/dd/bisimulation/Partition.h"
#include "storm/settings/modules/BisimulationSettings.h"
namespace storm {
namespace dd {
namespace bisimulation {
template<storm::dd::DdType DdType, typename ValueType>
class QuotientExtractor {
public:
QuotientExtractor();
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition);
private:
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition);
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition);
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition);
std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition);
bool useRepresentatives;
storm::settings::modules::BisimulationSettings::QuotientFormat quotientFormat;
};
}
}
}

5
src/storm/utility/storm.h

@ -192,10 +192,9 @@ namespace storm {
}
if (storm::settings::getModule<storm::settings::modules::GeneralSettings>().isBisimulationSet()) {
storm::dd::BisimulationDecomposition<LibraryType, ValueType> decomposition(*result);
storm::dd::BisimulationDecomposition<LibraryType, ValueType> decomposition(*result, formulas);
decomposition.compute();
// TODO build quotient and return it.
result = decomposition.getQuotient();
}
return result;

Loading…
Cancel
Save