Browse Source

added distance-aware initial partition to dd-based bisimulation

tempestpy_adaptions
dehnert 7 years ago
parent
commit
c85e30dfd0
  1. 22
      src/storm-cli-utilities/model-handling.h
  2. 4
      src/storm/modelchecker/AbstractModelChecker.cpp
  3. 7
      src/storm/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp
  4. 17
      src/storm/settings/modules/BisimulationSettings.cpp
  5. 8
      src/storm/settings/modules/BisimulationSettings.h
  6. 2
      src/storm/storage/dd/BisimulationDecomposition.cpp
  7. 119
      src/storm/storage/dd/bisimulation/Partition.cpp
  8. 6
      src/storm/storage/dd/bisimulation/Partition.h

22
src/storm-cli-utilities/model-handling.h

@ -44,8 +44,11 @@ namespace storm {
// The symbolic model description. // The symbolic model description.
boost::optional<storm::storage::SymbolicModelDescription> model; boost::optional<storm::storage::SymbolicModelDescription> model;
// The properties to check.
// The original properties to check.
std::vector<storm::jani::Property> properties; std::vector<storm::jani::Property> properties;
// The preprocessed properties to check (in case they needed amendment).
boost::optional<std::vector<storm::jani::Property>> preprocessedProperties;
}; };
void parseSymbolicModelDescription(storm::settings::modules::IOSettings const& ioSettings, SymbolicInput& input) { void parseSymbolicModelDescription(storm::settings::modules::IOSettings const& ioSettings, SymbolicInput& input) {
@ -129,7 +132,7 @@ namespace storm {
for (auto const& property : output.properties) { for (auto const& property : output.properties) {
amendedProperties.emplace_back(property.substituteLabels(labelRenaming)); amendedProperties.emplace_back(property.substituteLabels(labelRenaming));
} }
output.properties = std::move(amendedProperties);
output.preprocessedProperties = std::move(amendedProperties);
} }
} }
} }
@ -474,7 +477,8 @@ namespace storm {
}; };
template<typename ValueType> template<typename ValueType>
void verifyProperties(std::vector<storm::jani::Property> const& properties, std::function<std::unique_ptr<storm::modelchecker::CheckResult>(std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states)> const& verificationCallback, std::function<void(std::unique_ptr<storm::modelchecker::CheckResult> const&)> const& postprocessingCallback = PostprocessingIdentity()) {
void verifyProperties(SymbolicInput const& input, std::function<std::unique_ptr<storm::modelchecker::CheckResult>(std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states)> const& verificationCallback, std::function<void(std::unique_ptr<storm::modelchecker::CheckResult> const&)> const& postprocessingCallback = PostprocessingIdentity()) {
auto const& properties = input.preprocessedProperties ? input.preprocessedProperties.get() : input.properties;
for (auto const& property : properties) { for (auto const& property : properties) {
printModelCheckingProperty(property); printModelCheckingProperty(property);
storm::utility::Stopwatch watch(true); storm::utility::Stopwatch watch(true);
@ -488,7 +492,7 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType> template <storm::dd::DdType DdType, typename ValueType>
void verifyWithAbstractionRefinementEngine(SymbolicInput const& input) { void verifyWithAbstractionRefinementEngine(SymbolicInput const& input) {
STORM_LOG_ASSERT(input.model, "Expected symbolic model description."); STORM_LOG_ASSERT(input.model, "Expected symbolic model description.");
verifyProperties<ValueType>(input.properties, [&input] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
verifyProperties<ValueType>(input, [&input] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
STORM_LOG_THROW(states->isInitialFormula(), storm::exceptions::NotSupportedException, "Abstraction-refinement can only filter initial states."); STORM_LOG_THROW(states->isInitialFormula(), storm::exceptions::NotSupportedException, "Abstraction-refinement can only filter initial states.");
return storm::api::verifyWithAbstractionRefinementEngine<DdType, ValueType>(input.model.get(), storm::api::createTask<ValueType>(formula, true)); return storm::api::verifyWithAbstractionRefinementEngine<DdType, ValueType>(input.model.get(), storm::api::createTask<ValueType>(formula, true));
}); });
@ -498,7 +502,7 @@ namespace storm {
void verifyWithExplorationEngine(SymbolicInput const& input) { void verifyWithExplorationEngine(SymbolicInput const& input) {
STORM_LOG_ASSERT(input.model, "Expected symbolic model description."); STORM_LOG_ASSERT(input.model, "Expected symbolic model description.");
STORM_LOG_THROW((std::is_same<ValueType, double>::value), storm::exceptions::NotSupportedException, "Exploration does not support other data-types than floating points."); STORM_LOG_THROW((std::is_same<ValueType, double>::value), storm::exceptions::NotSupportedException, "Exploration does not support other data-types than floating points.");
verifyProperties<ValueType>(input.properties, [&input] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
verifyProperties<ValueType>(input, [&input] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
STORM_LOG_THROW(states->isInitialFormula(), storm::exceptions::NotSupportedException, "Exploration can only filter initial states."); STORM_LOG_THROW(states->isInitialFormula(), storm::exceptions::NotSupportedException, "Exploration can only filter initial states.");
return storm::api::verifyWithExplorationEngine<ValueType>(input.model.get(), storm::api::createTask<ValueType>(formula, true)); return storm::api::verifyWithExplorationEngine<ValueType>(input.model.get(), storm::api::createTask<ValueType>(formula, true));
}); });
@ -507,7 +511,7 @@ namespace storm {
template <typename ValueType> template <typename ValueType>
void verifyWithSparseEngine(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) { void verifyWithSparseEngine(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) {
auto sparseModel = model->as<storm::models::sparse::Model<ValueType>>(); auto sparseModel = model->as<storm::models::sparse::Model<ValueType>>();
verifyProperties<ValueType>(input.properties,
verifyProperties<ValueType>(input,
[&sparseModel] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) { [&sparseModel] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
bool filterForInitialStates = states->isInitialFormula(); bool filterForInitialStates = states->isInitialFormula();
auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates); auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates);
@ -528,7 +532,7 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType> template <storm::dd::DdType DdType, typename ValueType>
void verifyWithHybridEngine(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) { void verifyWithHybridEngine(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) {
verifyProperties<ValueType>(input.properties, [&model] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
verifyProperties<ValueType>(input, [&model] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
bool filterForInitialStates = states->isInitialFormula(); bool filterForInitialStates = states->isInitialFormula();
auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates); auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates);
@ -550,7 +554,7 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType> template <storm::dd::DdType DdType, typename ValueType>
void verifyWithDdEngine(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) { void verifyWithDdEngine(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) {
verifyProperties<ValueType>(input.properties, [&model] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
verifyProperties<ValueType>(input, [&model] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
bool filterForInitialStates = states->isInitialFormula(); bool filterForInitialStates = states->isInitialFormula();
auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates); auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates);
@ -572,7 +576,7 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType> template <storm::dd::DdType DdType, typename ValueType>
void verifyWithAbstractionRefinementEngine(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) { void verifyWithAbstractionRefinementEngine(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) {
verifyProperties<ValueType>(input.properties, [&model] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
verifyProperties<ValueType>(input, [&model] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
STORM_LOG_THROW(states->isInitialFormula(), storm::exceptions::NotSupportedException, "Abstraction-refinement can only filter initial states."); STORM_LOG_THROW(states->isInitialFormula(), storm::exceptions::NotSupportedException, "Abstraction-refinement can only filter initial states.");
auto symbolicModel = model->as<storm::models::symbolic::Model<DdType, ValueType>>(); auto symbolicModel = model->as<storm::models::symbolic::Model<DdType, ValueType>>();
return storm::api::verifyWithAbstractionRefinementEngine<DdType, ValueType>(symbolicModel, storm::api::createTask<ValueType>(formula, true)); return storm::api::verifyWithAbstractionRefinementEngine<DdType, ValueType>(symbolicModel, storm::api::createTask<ValueType>(formula, true));

4
src/storm/modelchecker/AbstractModelChecker.cpp

@ -314,6 +314,10 @@ namespace storm {
template class AbstractModelChecker<storm::models::sparse::MarkovAutomaton<storm::RationalFunction>>; template class AbstractModelChecker<storm::models::sparse::MarkovAutomaton<storm::RationalFunction>>;
#endif #endif
// DD // DD
template class AbstractModelChecker<storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>>;
template class AbstractModelChecker<storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>>;
template class AbstractModelChecker<storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>>;
template class AbstractModelChecker<storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>>;
template class AbstractModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::CUDD, double>>; template class AbstractModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::CUDD, double>>;
template class AbstractModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, double>>; template class AbstractModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, double>>;
template class AbstractModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalNumber>>; template class AbstractModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalNumber>>;

7
src/storm/modelchecker/propositional/SymbolicPropositionalModelChecker.cpp

@ -55,20 +55,21 @@ namespace storm {
ModelType const& SymbolicPropositionalModelChecker<ModelType>::getModel() const { ModelType const& SymbolicPropositionalModelChecker<ModelType>::getModel() const {
return model; return model;
} }
// Explicitly instantiate the template class. // Explicitly instantiate the template class.
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::CUDD, double>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::CUDD, double>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, double>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, double>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalNumber>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalNumber>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, storm::RationalNumber>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, storm::RationalNumber>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction>>;
template class SymbolicPropositionalModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, storm::RationalFunction>>; template class SymbolicPropositionalModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, storm::RationalFunction>>;

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

@ -18,6 +18,7 @@ namespace storm {
const std::string BisimulationSettings::quotientFormatOptionName = "quot"; const std::string BisimulationSettings::quotientFormatOptionName = "quot";
const std::string BisimulationSettings::signatureModeOptionName = "sigmode"; const std::string BisimulationSettings::signatureModeOptionName = "sigmode";
const std::string BisimulationSettings::reuseOptionName = "reuse"; const std::string BisimulationSettings::reuseOptionName = "reuse";
const std::string BisimulationSettings::initialPartitionOptionName = "init";
BisimulationSettings::BisimulationSettings() : ModuleSettings(moduleName) { BisimulationSettings::BisimulationSettings() : ModuleSettings(moduleName) {
std::vector<std::string> types = { "strong", "weak" }; std::vector<std::string> types = { "strong", "weak" };
@ -36,6 +37,12 @@ namespace storm {
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("mode", "The mode to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(reuseModes)) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("mode", "The mode to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(reuseModes))
.setDefaultValueString("blocks").build()) .setDefaultValueString("blocks").build())
.build()); .build());
std::vector<std::string> initialPartitionModes = {"regular", "finer"};
this->addOption(storm::settings::OptionBuilder(moduleName, initialPartitionOptionName, true, "Sets which initial partition mode to use.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("mode", "The mode to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(initialPartitionModes))
.setDefaultValueString("finer").build())
.build());
} }
bool BisimulationSettings::isStrongBisimulationSet() const { bool BisimulationSettings::isStrongBisimulationSet() const {
@ -84,6 +91,16 @@ namespace storm {
return ReuseMode::BlockNumbers; return ReuseMode::BlockNumbers;
} }
BisimulationSettings::InitialPartitionMode BisimulationSettings::getInitialPartitionMode() const {
std::string initialPartitionModeAsString = this->getOption(initialPartitionOptionName).getArgumentByName("mode").getValueAsString();
if (initialPartitionModeAsString == "regular") {
return InitialPartitionMode::Regular;
} else if (initialPartitionModeAsString == "finer") {
return InitialPartitionMode::Finer;
}
return InitialPartitionMode::Finer;
}
bool BisimulationSettings::check() const { bool BisimulationSettings::check() const {
bool optionsSet = this->getOption(typeOptionName).getHasOptionBeenSet(); 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."); 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.");

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

@ -21,6 +21,8 @@ namespace storm {
enum class ReuseMode { None, BlockNumbers }; enum class ReuseMode { None, BlockNumbers };
enum class InitialPartitionMode { Regular, Finer };
/*! /*!
* Creates a new set of bisimulation settings. * Creates a new set of bisimulation settings.
*/ */
@ -62,6 +64,11 @@ namespace storm {
*/ */
ReuseMode getReuseMode() const; ReuseMode getReuseMode() const;
/*!
* Retrieves the initial partition mode.
*/
InitialPartitionMode getInitialPartitionMode() const;
virtual bool check() const override; virtual bool check() const override;
// The name of the module. // The name of the module.
@ -74,6 +81,7 @@ namespace storm {
static const std::string quotientFormatOptionName; static const std::string quotientFormatOptionName;
static const std::string signatureModeOptionName; static const std::string signatureModeOptionName;
static const std::string reuseOptionName; static const std::string reuseOptionName;
static const std::string initialPartitionOptionName;
}; };
} // namespace modules } // namespace modules
} // namespace settings } // namespace settings

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

@ -42,7 +42,7 @@ namespace storm {
} }
template <storm::dd::DdType DdType, typename ValueType> template <storm::dd::DdType DdType, typename ValueType>
BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model, formulas), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) {
BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model, formulas), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, formulas))) {
this->initialize(); this->initialize();
} }

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

@ -4,13 +4,17 @@
#include "storm/storage/dd/bisimulation/PreservationInformation.h" #include "storm/storage/dd/bisimulation/PreservationInformation.h"
#include "storm/logic/Formula.h"
#include "storm/logic/Formulas.h"
#include "storm/logic/AtomicExpressionFormula.h" #include "storm/logic/AtomicExpressionFormula.h"
#include "storm/logic/AtomicLabelFormula.h" #include "storm/logic/AtomicLabelFormula.h"
#include "storm/logic/FragmentSpecification.h"
#include "storm/models/symbolic/Mdp.h" #include "storm/models/symbolic/Mdp.h"
#include "storm/models/symbolic/StandardRewardModel.h" #include "storm/models/symbolic/StandardRewardModel.h"
#include "storm/modelchecker/propositional/SymbolicPropositionalModelChecker.h"
#include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h"
#include "storm/settings/SettingsManager.h" #include "storm/settings/SettingsManager.h"
#include "storm/settings/modules/BisimulationSettings.h" #include "storm/settings/modules/BisimulationSettings.h"
@ -52,6 +56,50 @@ namespace storm {
return Partition<DdType, ValueType>(newPartitionBdd, blockVariables, numberOfBlocks, nextFreeBlockIndex); return Partition<DdType, ValueType>(newPartitionBdd, blockVariables, numberOfBlocks, nextFreeBlockIndex);
} }
template<storm::dd::DdType DdType, typename ValueType>
boost::optional<std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>> Partition<DdType, ValueType>::extractConstraintTargetFormulas(storm::logic::Formula const& formula) {
boost::optional<std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>> result;
if (formula.isProbabilityOperatorFormula()) {
return extractConstraintTargetFormulas(formula.asProbabilityOperatorFormula().getSubformula());
} else if (formula.isRewardOperatorFormula()) {
return extractConstraintTargetFormulas(formula.asRewardOperatorFormula().getSubformula());
} else if (formula.isUntilFormula()) {
storm::logic::UntilFormula const& untilFormula = formula.asUntilFormula();
storm::logic::FragmentSpecification propositional = storm::logic::propositional();
if (untilFormula.getLeftSubformula().isInFragment(propositional) && untilFormula.getRightSubformula().isInFragment(propositional)) {
result = std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>();
result.get().first = untilFormula.getLeftSubformula().asSharedPointer();
result.get().second = untilFormula.getRightSubformula().asSharedPointer();
}
} else if (formula.isEventuallyFormula()) {
storm::logic::EventuallyFormula const& eventuallyFormula = formula.asEventuallyFormula();
storm::logic::FragmentSpecification propositional = storm::logic::propositional();
if (eventuallyFormula.getSubformula().isInFragment(propositional)) {
result = std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>();
result.get().first = std::make_shared<storm::logic::BooleanLiteralFormula>(true);
result.get().second = eventuallyFormula.getSubformula().asSharedPointer();
}
}
return result;
}
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::create(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
auto const& bisimulationSettings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>();
boost::optional<std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>> constraintTargetFormulas;
if (bisimulationSettings.getInitialPartitionMode() == storm::settings::modules::BisimulationSettings::InitialPartitionMode::Finer && formulas.size() == 1) {
constraintTargetFormulas = extractConstraintTargetFormulas(*formulas.front());
}
if (constraintTargetFormulas && bisimulationType == storm::storage::BisimulationType::Strong) {
return createDistanceBased(model, *constraintTargetFormulas.get().first, *constraintTargetFormulas.get().second);
} else {
return create(model, bisimulationType, PreservationInformation<DdType, ValueType>(model, formulas));
}
}
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::create(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, PreservationInformation<DdType, ValueType> const& preservationInformation) { Partition<DdType, ValueType> Partition<DdType, ValueType>::create(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, PreservationInformation<DdType, ValueType> const& preservationInformation) {
@ -64,15 +112,58 @@ namespace storm {
} }
template<storm::dd::DdType DdType, typename ValueType> 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, storm::storage::BisimulationType const& bisimulationType) {
STORM_LOG_THROW(bisimulationType == storm::storage::BisimulationType::Strong, storm::exceptions::NotSupportedException, "Currently only strong bisimulation is supported.");
Partition<DdType, ValueType> Partition<DdType, ValueType>::createDistanceBased(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::logic::Formula const& constraintFormula, storm::logic::Formula const& targetFormula) {
storm::modelchecker::SymbolicPropositionalModelChecker<storm::models::symbolic::Model<DdType, ValueType>> propositionalChecker(model);
std::unique_ptr<storm::modelchecker::CheckResult> subresult = propositionalChecker.check(constraintFormula);
storm::dd::Bdd<DdType> constraintStates = subresult->asSymbolicQualitativeCheckResult<DdType>().getTruthValuesVector();
subresult = propositionalChecker.check(targetFormula);
storm::dd::Bdd<DdType> targetStates = subresult->asSymbolicQualitativeCheckResult<DdType>().getTruthValuesVector();
return createDistanceBased(model, constraintStates, targetStates);
}
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::createDistanceBased(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Bdd<DdType> const& constraintStates, storm::dd::Bdd<DdType> const& targetStates) {
STORM_LOG_TRACE("Creating distance-based partition.");
std::pair<storm::expressions::Variable, storm::expressions::Variable> blockVariables = createBlockVariables(model);
// Set up the construction.
storm::dd::DdManager<DdType>& manager = model.getManager(); storm::dd::DdManager<DdType>& manager = model.getManager();
storm::dd::Bdd<DdType> partitionBdd = manager.getBddZero();
storm::dd::Bdd<DdType> transitionMatrixBdd = model.getTransitionMatrix().notZero().existsAbstract(model.getNondeterminismVariables());
storm::dd::Bdd<DdType> coveredStates = manager.getBddZero();
uint64_t blockCount = 0;
// Backward BFS.
storm::dd::Bdd<DdType> backwardFrontier = targetStates;
while (!backwardFrontier.isZero()) {
partitionBdd |= backwardFrontier && manager.getEncoding(blockVariables.first, blockCount++, false);
coveredStates |= backwardFrontier;
backwardFrontier = backwardFrontier.inverseRelationalProduct(transitionMatrixBdd, model.getRowVariables(), model.getColumnVariables()) && !coveredStates && constraintStates;
}
// If there are states that cannot reach the target states (via only constraint states) at all, put them in one block.
if (coveredStates != model.getReachableStates()) {
partitionBdd |= (model.getReachableStates() && !coveredStates) && manager.getEncoding(blockVariables.first, blockCount++, false);
}
std::vector<storm::dd::Bdd<DdType>> stateSets;
for (auto const& expression : expressions) {
stateSets.emplace_back(model.getStates(expression));
// Move the partition over to the primed variables.
partitionBdd = partitionBdd.swapVariables(model.getRowColumnMetaVariablePairs());
// Store the partition as an ADD only in the case of CUDD.
if (DdType == storm::dd::DdType::CUDD) {
return Partition<DdType, ValueType>(partitionBdd.template toAdd<ValueType>(), blockVariables, blockCount, blockCount);
} else {
return Partition<DdType, ValueType>(partitionBdd, blockVariables, blockCount, blockCount);
} }
}
template<storm::dd::DdType DdType, typename ValueType>
std::pair<storm::expressions::Variable, storm::expressions::Variable> Partition<DdType, ValueType>::createBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model) {
storm::dd::DdManager<DdType>& manager = model.getManager();
uint64_t numberOfDdVariables = 0; uint64_t numberOfDdVariables = 0;
for (auto const& metaVariable : model.getRowVariables()) { for (auto const& metaVariable : model.getRowVariables()) {
@ -87,8 +178,20 @@ namespace storm {
} }
} }
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);
return createBlockVariables(manager, numberOfDdVariables);
}
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, storm::storage::BisimulationType const& bisimulationType) {
STORM_LOG_THROW(bisimulationType == storm::storage::BisimulationType::Strong, storm::exceptions::NotSupportedException, "Currently only strong bisimulation is supported.");
std::pair<storm::expressions::Variable, storm::expressions::Variable> blockVariables = createBlockVariables(model);
std::vector<storm::dd::Bdd<DdType>> stateSets;
for (auto const& expression : expressions) {
stateSets.emplace_back(model.getStates(expression));
}
std::pair<storm::dd::Bdd<DdType>, uint64_t> partitionBddAndBlockCount = createPartitionBdd(model.getManager(), model, stateSets, blockVariables.first);
// Store the partition as an ADD only in the case of CUDD. // Store the partition as an ADD only in the case of CUDD.
if (DdType == storm::dd::DdType::CUDD) { if (DdType == storm::dd::DdType::CUDD) {

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

@ -35,6 +35,7 @@ namespace storm {
Partition<DdType, ValueType> replacePartition(storm::dd::Bdd<DdType> const& newPartitionBdd, uint64_t numberOfBlocks, uint64_t nextFreeBlockIndex) const; Partition<DdType, ValueType> replacePartition(storm::dd::Bdd<DdType> const& newPartitionBdd, uint64_t numberOfBlocks, uint64_t nextFreeBlockIndex) const;
static Partition create(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, PreservationInformation<DdType, ValueType> const& preservationInformation); static Partition create(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, PreservationInformation<DdType, ValueType> const& preservationInformation);
static Partition create(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas);
static Partition createTrivialChoicePartition(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, std::pair<storm::expressions::Variable, storm::expressions::Variable> const& blockVariables); static Partition createTrivialChoicePartition(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, std::pair<storm::expressions::Variable, storm::expressions::Variable> const& blockVariables);
uint64_t getNumberOfStates() const; uint64_t getNumberOfStates() const;
@ -85,8 +86,13 @@ namespace storm {
*/ */
static Partition create(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<storm::expressions::Expression> const& expressions, storm::storage::BisimulationType const& bisimulationType); static Partition create(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<storm::expressions::Expression> const& expressions, storm::storage::BisimulationType const& bisimulationType);
static Partition<DdType, ValueType> createDistanceBased(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::logic::Formula const& constraintFormula, storm::logic::Formula const& targetFormula);
static Partition<DdType, ValueType> createDistanceBased(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Bdd<DdType> const& constraintStates, storm::dd::Bdd<DdType> const& targetStates);
static boost::optional<std::pair<std::shared_ptr<storm::logic::Formula const>, std::shared_ptr<storm::logic::Formula const>>> extractConstraintTargetFormulas(storm::logic::Formula const& formula);
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 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 std::pair<storm::expressions::Variable, storm::expressions::Variable> createBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model);
static std::pair<storm::expressions::Variable, storm::expressions::Variable> createBlockVariables(storm::dd::DdManager<DdType>& manager, uint64_t numberOfDdVariables); static std::pair<storm::expressions::Variable, storm::expressions::Variable> createBlockVariables(storm::dd::DdManager<DdType>& manager, uint64_t numberOfDdVariables);
/// The DD representing the partition. The DD is over the row variables of the model and the block variable. /// The DD representing the partition. The DD is over the row variables of the model and the block variable.

Loading…
Cancel
Save