diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index 3667d0af2..c279dc742 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -322,43 +322,47 @@ namespace storm { } } - template - std::shared_ptr> preprocessDdModelBisimulation(std::shared_ptr> const& model, SymbolicInput const& input, storm::settings::modules::BisimulationSettings const& bisimulationSettings) { + template + std::shared_ptr> preprocessDdModelBisimulation(std::shared_ptr> const& model, SymbolicInput const& input, storm::settings::modules::BisimulationSettings const& bisimulationSettings) { STORM_LOG_WARN_COND(!bisimulationSettings.isWeakBisimulationSet(), "Weak bisimulation is currently not supported on DDs. Falling back to strong bisimulation."); STORM_LOG_INFO("Performing bisimulation minimization..."); - return storm::api::performBisimulationMinimization(model, createFormulasToRespect(input.properties), storm::storage::BisimulationType::Strong, bisimulationSettings.getSignatureMode()); + return storm::api::performBisimulationMinimization(model, createFormulasToRespect(input.properties), storm::storage::BisimulationType::Strong, bisimulationSettings.getSignatureMode()); } - template + template std::pair, bool> preprocessDdModel(std::shared_ptr> const& model, SymbolicInput const& input) { auto bisimulationSettings = storm::settings::getModule(); auto generalSettings = storm::settings::getModule(); - std::pair>, bool> result = std::make_pair(model, false); + std::pair>, bool> intermediateResult = std::make_pair(model, false); if (model->isOfType(storm::models::ModelType::MarkovAutomaton)) { - result.first = preprocessDdMarkovAutomaton(result.first->template as>()); - result.second = true; + intermediateResult.first = preprocessDdMarkovAutomaton(intermediateResult.first->template as>()); + intermediateResult.second = true; } + std::unique_ptr>, bool>> result; + auto symbolicModel = intermediateResult.first->template as>(); if (generalSettings.isBisimulationSet()) { - result.first = preprocessDdModelBisimulation(model, input, bisimulationSettings); - result.second = true; + std::shared_ptr> newModel = preprocessDdModelBisimulation(symbolicModel, input, bisimulationSettings); + result = std::make_unique>, bool>>(newModel, true); + } else { + result = std::make_unique>, bool>>(symbolicModel->template toValueType(), !std::is_same::value); } - return result; + return *result; } - template + template std::pair, bool> preprocessModel(std::shared_ptr const& model, SymbolicInput const& input) { storm::utility::Stopwatch preprocessingWatch(true); std::pair, bool> result = std::make_pair(model, false); if (model->isSparseModel()) { - result = preprocessSparseModel(result.first->as>(), input); + result = preprocessSparseModel(result.first->as>(), input); } else { STORM_LOG_ASSERT(model->isSymbolicModel(), "Unexpected model type."); - result = preprocessDdModel(result.first->as>(), input); + result = preprocessDdModel(result.first->as>(), input); } preprocessingWatch.stop(); @@ -639,13 +643,13 @@ namespace storm { } } - template + template std::shared_ptr buildPreprocessExportModelWithValueTypeAndDdlib(SymbolicInput const& input, storm::settings::modules::CoreSettings::Engine engine) { auto ioSettings = storm::settings::getModule(); auto buildSettings = storm::settings::getModule(); std::shared_ptr model; if (!buildSettings.isNoBuildModelSet()) { - model = buildModel(engine, input, ioSettings); + model = buildModel(engine, input, ioSettings); } if (model) { @@ -655,12 +659,12 @@ namespace storm { STORM_LOG_THROW(model || input.properties.empty(), storm::exceptions::InvalidSettingsException, "No input model."); if (model) { - auto preprocessingResult = preprocessModel(model, input); + auto preprocessingResult = preprocessModel(model, input); if (preprocessingResult.second) { model = preprocessingResult.first; model->printModelInformationToStream(std::cout); } - exportModel(model, input); + exportModel(model, input); } return model; } @@ -678,17 +682,9 @@ namespace storm { } else if (engine == storm::settings::modules::CoreSettings::Engine::Exploration) { verifyWithExplorationEngine(input); } else { - std::shared_ptr model = buildPreprocessExportModelWithValueTypeAndDdlib(input, engine); + std::shared_ptr model = buildPreprocessExportModelWithValueTypeAndDdlib(input, engine); if (model) { - if (!std::is_same::value) { - if (model->isSymbolicModel()) { - STORM_LOG_INFO("Converting symbolic model value type to fit the verification value type."); - auto symbolicModel = model->as>(); - model = symbolicModel->template toValueType(); - } - } - if (coreSettings.isCounterexampleSet()) { auto ioSettings = storm::settings::getModule(); generateCounterexamples(model, input); @@ -713,7 +709,7 @@ namespace storm { STORM_LOG_INFO("Switching to DD library sylvan to allow for rational arithmetic."); processInputWithValueTypeAndDdlib(input); } else if (coreSettings.getDdLibraryType() == storm::dd::DdType::CUDD) { - processInputWithValueTypeAndDdlib(input); + processInputWithValueTypeAndDdlib(input); } else { STORM_LOG_ASSERT(coreSettings.getDdLibraryType() == storm::dd::DdType::Sylvan, "Unknown DD library."); processInputWithValueTypeAndDdlib(input); diff --git a/src/storm/api/bisimulation.h b/src/storm/api/bisimulation.h index 9ad43f9bd..dc7181e87 100644 --- a/src/storm/api/bisimulation.h +++ b/src/storm/api/bisimulation.h @@ -55,8 +55,8 @@ namespace storm { } } - template - typename std::enable_if::value, std::shared_ptr>>::type performBisimulationMinimization(std::shared_ptr> const& model, std::vector> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { + template + typename std::enable_if::value, std::shared_ptr>>::type performBisimulationMinimization(std::shared_ptr> const& model, std::vector> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { STORM_LOG_THROW(model->isOfType(storm::models::ModelType::Dtmc) || model->isOfType(storm::models::ModelType::Ctmc) || model->isOfType(storm::models::ModelType::Mdp) || model->isOfType(storm::models::ModelType::MarkovAutomaton), storm::exceptions::NotSupportedException, "Symbolic bisimulation minimization is currently only available for DTMCs, CTMCs, MDPs and MAs."); STORM_LOG_THROW(bisimulationType == storm::storage::BisimulationType::Strong, storm::exceptions::NotSupportedException, "Currently only strong bisimulation is supported."); @@ -64,13 +64,13 @@ namespace storm { // Try to get rid of non state-rewards to easy bisimulation computation. model->reduceToStateBasedRewards(); - storm::dd::BisimulationDecomposition decomposition(*model, formulas, bisimulationType); + storm::dd::BisimulationDecomposition decomposition(*model, formulas, bisimulationType); decomposition.compute(mode); return decomposition.getQuotient(); } - template - typename std::enable_if::value, std::shared_ptr>>::type performBisimulationMinimization(std::shared_ptr> const& model, std::vector> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { + template + typename std::enable_if::value, std::shared_ptr>>::type performBisimulationMinimization(std::shared_ptr> const& model, std::vector> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Symbolic bisimulation minimization is not supported for this combination of DD library and value type."); return nullptr; } diff --git a/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h b/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h index 9af7c3a8b..4fe5af95f 100644 --- a/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h +++ b/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h @@ -11,7 +11,7 @@ namespace storm { } namespace dd { - template + template class BisimulationDecomposition; } @@ -47,7 +47,7 @@ namespace storm { ModelType const& model; /// The bisimulation object that maintains and refines the model. - std::unique_ptr> bisimulation; + std::unique_ptr> bisimulation; /// Maintains the last abstract model that was returned. std::shared_ptr> lastAbstractModel; diff --git a/src/storm/models/symbolic/Model.cpp b/src/storm/models/symbolic/Model.cpp index 71897fded..ee90118cb 100644 --- a/src/storm/models/symbolic/Model.cpp +++ b/src/storm/models/symbolic/Model.cpp @@ -6,6 +6,7 @@ #include "storm/models/symbolic/Ctmc.h" #include "storm/models/symbolic/Mdp.h" #include "storm/models/symbolic/MarkovAutomaton.h" +#include "storm/models/symbolic/StochasticTwoPlayerGame.h" #include "storm/exceptions/IllegalArgumentException.h" #include "storm/exceptions/InvalidOperationException.h" @@ -384,7 +385,9 @@ namespace storm { template template - std::shared_ptr> Model::toValueType() const { + typename std::enable_if::value, std::shared_ptr>>::type Model::toValueType() const { + STORM_LOG_TRACE("Converting value type of symbolic model from " << typeid(ValueType).name() << " to " << typeid(NewValueType).name() << "."); + // Make a huge branching here as we cannot make a templated function virtual. if (this->getType() == storm::models::ModelType::Dtmc) { return this->template as>()->template toValueType(); @@ -394,6 +397,28 @@ namespace storm { return this->template as>()->template toValueType(); } else if (this->getType() == storm::models::ModelType::MarkovAutomaton) { return this->template as>()->template toValueType(); + } else if (this->getType() == storm::models::ModelType::S2pg) { + return this->template as>()->template toValueType(); + } + + STORM_LOG_WARN("Could not convert value type of model."); + return nullptr; + } + + template + template + typename std::enable_if::value, std::shared_ptr>>::type Model::toValueType() const { + // Make a huge branching here as we cannot make a templated function virtual. + if (this->getType() == storm::models::ModelType::Dtmc) { + return std::make_shared>(*this->template as>()); + } else if (this->getType() == storm::models::ModelType::Ctmc) { + return std::make_shared>(*this->template as>()); + } else if (this->getType() == storm::models::ModelType::Mdp) { + return std::make_shared>(*this->template as>()); + } else if (this->getType() == storm::models::ModelType::MarkovAutomaton) { + return std::make_shared>(*this->template as>()); + } else if (this->getType() == storm::models::ModelType::S2pg) { + return std::make_shared>(*this->template as>()); } STORM_LOG_WARN("Could not convert value type of model."); @@ -403,9 +428,14 @@ namespace storm { // Explicitly instantiate the template class. template class Model; template class Model; - + + template typename std::enable_if::value, std::shared_ptr>>::type Model::toValueType() const; + template class Model; - template std::shared_ptr> Model::toValueType() const; + template typename std::enable_if::value, std::shared_ptr>>::type Model::toValueType() const; + template typename std::enable_if::value, std::shared_ptr>>::type Model::toValueType() const; + template typename std::enable_if::value, std::shared_ptr>>::type Model::toValueType() const; + template typename std::enable_if::value, std::shared_ptr>>::type Model::toValueType() const; template class Model; } // namespace symbolic } // namespace models diff --git a/src/storm/models/symbolic/Model.h b/src/storm/models/symbolic/Model.h index e194dfabc..1dca3dc6d 100644 --- a/src/storm/models/symbolic/Model.h +++ b/src/storm/models/symbolic/Model.h @@ -328,8 +328,11 @@ namespace storm { std::set const& getParameters() const; template - std::shared_ptr> toValueType() const; + typename std::enable_if::value, std::shared_ptr>>::type toValueType() const; + template + typename std::enable_if::value, std::shared_ptr>>::type toValueType() const; + protected: /*! * Sets the transition matrix of the model. diff --git a/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp b/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp index b4b59e934..677d80912 100644 --- a/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp +++ b/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp @@ -82,11 +82,30 @@ namespace storm { return player2Variables; } + template + template + std::shared_ptr> StochasticTwoPlayerGame::toValueType() const { + typedef typename NondeterministicModel::RewardModelType NewRewardModelType; + std::unordered_map newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared>(this->getManagerAsSharedPointer(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getPlayer1Variables(), this->getPlayer2Variables(), this->getNondeterminismVariables(), newLabelToBddMap, newRewardModels); + + } + // Explicitly instantiate the template class. template class StochasticTwoPlayerGame; template class StochasticTwoPlayerGame; #ifdef STORM_HAVE_CARL template class StochasticTwoPlayerGame; + template std::shared_ptr> StochasticTwoPlayerGame::toValueType() const; template class StochasticTwoPlayerGame; #endif diff --git a/src/storm/models/symbolic/StochasticTwoPlayerGame.h b/src/storm/models/symbolic/StochasticTwoPlayerGame.h index d3f009593..569d258dd 100644 --- a/src/storm/models/symbolic/StochasticTwoPlayerGame.h +++ b/src/storm/models/symbolic/StochasticTwoPlayerGame.h @@ -117,6 +117,9 @@ namespace storm { */ storm::dd::Bdd getIllegalPlayer2Mask() const; + template + std::shared_ptr> toValueType() const; + private: /*! * Prepare all illegal masks. diff --git a/src/storm/storage/dd/BisimulationDecomposition.cpp b/src/storm/storage/dd/BisimulationDecomposition.cpp index 682f5602d..d43dd9c65 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.cpp +++ b/src/storm/storage/dd/BisimulationDecomposition.cpp @@ -31,31 +31,31 @@ namespace storm { } } - template - BisimulationDecomposition::BisimulationDecomposition(storm::models::symbolic::Model const& model, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model), refiner(createRefiner(model, Partition::create(model, bisimulationType, preservationInformation))) { + template + BisimulationDecomposition::BisimulationDecomposition(storm::models::symbolic::Model const& model, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model), refiner(createRefiner(model, Partition::create(model, bisimulationType, preservationInformation))) { this->initialize(); } - template - BisimulationDecomposition::BisimulationDecomposition(storm::models::symbolic::Model const& model, storm::storage::BisimulationType const& bisimulationType, bisimulation::PreservationInformation const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, Partition::create(model, bisimulationType, preservationInformation))) { + template + BisimulationDecomposition::BisimulationDecomposition(storm::models::symbolic::Model const& model, storm::storage::BisimulationType const& bisimulationType, bisimulation::PreservationInformation const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, Partition::create(model, bisimulationType, preservationInformation))) { this->initialize(); } - template - BisimulationDecomposition::BisimulationDecomposition(storm::models::symbolic::Model const& model, std::vector> const& formulas, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model, formulas), refiner(createRefiner(model, Partition::create(model, bisimulationType, formulas))) { + template + BisimulationDecomposition::BisimulationDecomposition(storm::models::symbolic::Model const& model, std::vector> const& formulas, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model, formulas), refiner(createRefiner(model, Partition::create(model, bisimulationType, formulas))) { this->initialize(); } - template - BisimulationDecomposition::BisimulationDecomposition(storm::models::symbolic::Model const& model, Partition const& initialPartition, bisimulation::PreservationInformation const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, initialPartition)) { + template + BisimulationDecomposition::BisimulationDecomposition(storm::models::symbolic::Model const& model, Partition const& initialPartition, bisimulation::PreservationInformation const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, initialPartition)) { this->initialize(); } - template - BisimulationDecomposition::~BisimulationDecomposition() = default; + template + BisimulationDecomposition::~BisimulationDecomposition() = default; - template - void BisimulationDecomposition::initialize() { + template + void BisimulationDecomposition::initialize() { auto const& generalSettings = storm::settings::getModule(); verboseProgress = generalSettings.isVerboseSet(); showProgressDelay = generalSettings.getShowProgressDelay(); @@ -69,8 +69,8 @@ namespace storm { STORM_LOG_TRACE("Initial partition has " << refiner->getStatePartition().getNodeCount() << " nodes."); } - template - void BisimulationDecomposition::compute(bisimulation::SignatureMode const& mode) { + template + void BisimulationDecomposition::compute(bisimulation::SignatureMode const& mode) { STORM_LOG_ASSERT(refiner, "No suitable refiner."); STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet."); @@ -96,8 +96,8 @@ namespace storm { STORM_LOG_INFO("Partition refinement completed in " << std::chrono::duration_cast(end - start).count() << "ms (" << iterations << " iterations, signature: " << std::chrono::duration_cast(refiner->getTotalSignatureTime()).count() << "ms, refinement: " << std::chrono::duration_cast(refiner->getTotalRefinementTime()).count() << "ms)."); } - template - bool BisimulationDecomposition::compute(uint64_t steps, bisimulation::SignatureMode const& mode) { + template + bool BisimulationDecomposition::compute(uint64_t steps, bisimulation::SignatureMode const& mode) { STORM_LOG_ASSERT(refiner, "No suitable refiner."); STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet."); STORM_LOG_ASSERT(steps > 0, "Can only perform positive number of steps."); @@ -123,24 +123,24 @@ namespace storm { return !refined; } - template - bool BisimulationDecomposition::getReachedFixedPoint() const { + template + bool BisimulationDecomposition::getReachedFixedPoint() const { return this->refiner->getStatus() == Status::FixedPoint; } - template - std::shared_ptr> BisimulationDecomposition::getQuotient() const { - std::shared_ptr> quotient; + template + std::shared_ptr> BisimulationDecomposition::getQuotient() const { + std::shared_ptr> quotient; if (this->refiner->getStatus() == Status::FixedPoint) { STORM_LOG_INFO("Starting full quotient extraction."); - QuotientExtractor extractor; + QuotientExtractor extractor; quotient = extractor.extract(model, refiner->getStatePartition(), preservationInformation); } else { STORM_LOG_THROW(model.getType() == storm::models::ModelType::Dtmc || model.getType() == storm::models::ModelType::Mdp, storm::exceptions::InvalidOperationException, "Can only extract partial quotient for discrete-time models."); STORM_LOG_INFO("Starting partial quotient extraction."); if (!partialQuotientExtractor) { - partialQuotientExtractor = std::make_unique>(model); + partialQuotientExtractor = std::make_unique>(model); } quotient = partialQuotientExtractor->extract(refiner->getStatePartition(), preservationInformation); @@ -150,8 +150,8 @@ namespace storm { return quotient; } - template - void BisimulationDecomposition::refineWrtRewardModels() { + template + void BisimulationDecomposition::refineWrtRewardModels() { for (auto const& rewardModelName : this->preservationInformation.getRewardModelNames()) { auto const& rewardModel = this->model.getRewardModel(rewardModelName); refiner->refineWrtRewardModel(rewardModel); @@ -162,6 +162,7 @@ namespace storm { template class BisimulationDecomposition; template class BisimulationDecomposition; + template class BisimulationDecomposition; template class BisimulationDecomposition; } diff --git a/src/storm/storage/dd/BisimulationDecomposition.h b/src/storm/storage/dd/BisimulationDecomposition.h index b5a088ca2..1a552c497 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.h +++ b/src/storm/storage/dd/BisimulationDecomposition.h @@ -29,11 +29,11 @@ namespace storm { template class PartitionRefiner; - template + template class PartialQuotientExtractor; } - template + template class BisimulationDecomposition { public: BisimulationDecomposition(storm::models::symbolic::Model const& model, storm::storage::BisimulationType const& bisimulationType); @@ -64,7 +64,7 @@ namespace storm { /*! * Retrieves the quotient model after the bisimulation decomposition was computed. */ - std::shared_ptr> getQuotient() const; + std::shared_ptr> getQuotient() const; private: void initialize(); @@ -80,7 +80,7 @@ namespace storm { std::unique_ptr> refiner; // A quotient extractor that is used when the fixpoint has not been reached yet. - mutable std::unique_ptr> partialQuotientExtractor; + mutable std::unique_ptr> partialQuotientExtractor; // A flag indicating whether progress is reported. bool verboseProgress; diff --git a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp index 9e5e34b54..fea92c755 100644 --- a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp @@ -15,18 +15,18 @@ namespace storm { namespace dd { namespace bisimulation { - template - PartialQuotientExtractor::PartialQuotientExtractor(storm::models::symbolic::Model const& model) : model(model) { + template + PartialQuotientExtractor::PartialQuotientExtractor(storm::models::symbolic::Model const& model) : model(model) { auto const& settings = storm::settings::getModule(); this->quotientFormat = settings.getQuotientFormat(); STORM_LOG_THROW(this->quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Dd, storm::exceptions::NotSupportedException, "Only DD-based partial quotient extraction is currently supported."); } - template - std::shared_ptr> PartialQuotientExtractor::extract(Partition const& partition, PreservationInformation const& preservationInformation) { + template + std::shared_ptr> PartialQuotientExtractor::extract(Partition const& partition, PreservationInformation const& preservationInformation) { auto start = std::chrono::high_resolution_clock::now(); - std::shared_ptr> result; + std::shared_ptr> result; STORM_LOG_THROW(this->quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Dd, storm::exceptions::NotSupportedException, "Only DD-based partial quotient extraction is currently supported."); result = extractDdQuotient(partition, preservationInformation); @@ -38,8 +38,8 @@ namespace storm { return result; } - template - std::shared_ptr> PartialQuotientExtractor::extractDdQuotient(Partition const& partition, PreservationInformation const& preservationInformation) { + template + std::shared_ptr> PartialQuotientExtractor::extractDdQuotient(Partition const& partition, PreservationInformation const& preservationInformation) { auto modelType = model.getType(); if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Mdp) { @@ -122,16 +122,19 @@ namespace storm { end = std::chrono::high_resolution_clock::now(); STORM_LOG_TRACE("Reward models extracted in " << std::chrono::duration_cast(end - start).count() << "ms."); + std::shared_ptr> result; if (modelType == storm::models::ModelType::Dtmc) { - return std::make_shared>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), preservedLabelBdds, quotientRewardModels); + result = std::make_shared>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), preservedLabelBdds, quotientRewardModels); } else if (modelType == storm::models::ModelType::Mdp) { std::set allNondeterminismVariables; std::set_union(model.getRowVariables().begin(), model.getRowVariables().end(), model.getNondeterminismVariables().begin(), model.getNondeterminismVariables().end(), std::inserter(allNondeterminismVariables, allNondeterminismVariables.begin())); - return std::make_shared>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), model.getNondeterminismVariables(), allNondeterminismVariables, preservedLabelBdds, quotientRewardModels); + result = std::make_shared>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), model.getNondeterminismVariables(), allNondeterminismVariables, preservedLabelBdds, quotientRewardModels); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unsupported quotient type."); } + + return result->template toValueType(); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract partial quotient for this model type."); } @@ -142,6 +145,7 @@ namespace storm { #ifdef STORM_HAVE_CARL template class PartialQuotientExtractor; + template class PartialQuotientExtractor; template class PartialQuotientExtractor; #endif diff --git a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h index 26ae033e6..d5c638c2a 100644 --- a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h +++ b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h @@ -16,15 +16,15 @@ namespace storm { namespace dd { namespace bisimulation { - template + template class PartialQuotientExtractor { public: PartialQuotientExtractor(storm::models::symbolic::Model const& model); - std::shared_ptr> extract(Partition const& partition, PreservationInformation const& preservationInformation); + std::shared_ptr> extract(Partition const& partition, PreservationInformation const& preservationInformation); private: - std::shared_ptr> extractDdQuotient(Partition const& partition, PreservationInformation const& preservationInformation); + std::shared_ptr> extractDdQuotient(Partition const& partition, PreservationInformation const& preservationInformation); // The model for which to compute the partial quotient. storm::models::symbolic::Model const& model; diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index 108164a2a..25075a0e9 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -222,10 +222,10 @@ namespace storm { spp::sparse_hash_map visitedNodes; }; - template + template class InternalSparseQuotientExtractor; - template + template class InternalSparseQuotientExtractorBase { public: InternalSparseQuotientExtractorBase(storm::models::symbolic::Model const& model, storm::dd::Bdd const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t numberOfBlocks, storm::dd::Bdd const& representatives) : model(model), manager(model.getManager()), isNondeterministic(false), partitionBdd(partitionBdd), numberOfBlocks(numberOfBlocks), blockVariable(blockVariable), representatives(representatives), matrixEntriesCreated(false) { @@ -259,23 +259,23 @@ namespace storm { virtual ~InternalSparseQuotientExtractorBase() = default; - storm::storage::SparseMatrix extractTransitionMatrix(storm::dd::Add const& transitionMatrix) { + storm::storage::SparseMatrix extractTransitionMatrix(storm::dd::Add const& transitionMatrix) { return extractMatrixInternal(transitionMatrix); } - std::vector extractStateVector(storm::dd::Add const& vector) { + std::vector extractStateVector(storm::dd::Add const& vector) { return extractVectorInternal(vector, this->rowVariablesCube, this->odd); } - std::vector extractStateActionVector(storm::dd::Add const& vector) { + std::vector extractStateActionVector(storm::dd::Add const& vector) { if (!this->isNondeterministic) { return extractStateVector(vector); } else { STORM_LOG_ASSERT(!this->rowPermutation.empty(), "Expected proper row permutation."); - std::vector valueVector = extractVectorInternal(vector, this->allSourceVariablesCube, this->nondeterminismOdd); + std::vector valueVector = extractVectorInternal(vector, this->allSourceVariablesCube, this->nondeterminismOdd); // Reorder the values according to the known row permutation. - std::vector reorderedValues(valueVector.size()); + std::vector reorderedValues(valueVector.size()); for (uint64_t pos = 0; pos < valueVector.size(); ++pos) { reorderedValues[pos] = valueVector[rowPermutation[pos]]; } @@ -292,14 +292,14 @@ namespace storm { } protected: - virtual storm::storage::SparseMatrix extractMatrixInternal(storm::dd::Add const& matrix) = 0; + virtual storm::storage::SparseMatrix extractMatrixInternal(storm::dd::Add const& matrix) = 0; - virtual std::vector extractVectorInternal(storm::dd::Add const& vector, storm::dd::Bdd const& variablesCube, storm::dd::Odd const& odd) = 0; + virtual std::vector extractVectorInternal(storm::dd::Add const& vector, storm::dd::Bdd const& variablesCube, storm::dd::Odd const& odd) = 0; - storm::storage::SparseMatrix createMatrixFromEntries() { + storm::storage::SparseMatrix createMatrixFromEntries() { for (auto& row : matrixEntries) { std::sort(row.begin(), row.end(), - [] (storm::storage::MatrixEntry const& a, storm::storage::MatrixEntry const& b) { + [] (storm::storage::MatrixEntry const& a, storm::storage::MatrixEntry const& b) { return a.getColumn() < b.getColumn(); }); } @@ -312,7 +312,7 @@ namespace storm { uint64_t rowCounter = 0; uint64_t lastState = this->isNondeterministic ? rowToState[rowPermutation.front()] : 0; - storm::storage::SparseMatrixBuilder builder(matrixEntries.size(), this->numberOfBlocks, 0, true, this->isNondeterministic); + storm::storage::SparseMatrixBuilder builder(matrixEntries.size(), this->numberOfBlocks, 0, true, this->isNondeterministic); if (this->isNondeterministic) { builder.newRowGroup(0); } @@ -343,7 +343,7 @@ namespace storm { return builder.build(); } - void addMatrixEntry(uint64_t row, uint64_t column, ValueType const& value) { + void addMatrixEntry(uint64_t row, uint64_t column, ExportValueType const& value) { this->matrixEntries[row].emplace_back(column, value); } @@ -390,7 +390,7 @@ namespace storm { bool matrixEntriesCreated; // The entries of the quotient matrix that is built. - std::vector>> matrixEntries; + std::vector>> matrixEntries; // A vector storing for each row which state it belongs to. std::vector rowToState; @@ -621,33 +621,33 @@ namespace storm { spp::sparse_hash_map blockToOffset; }; - template - class InternalSparseQuotientExtractor : public InternalSparseQuotientExtractorBase { + template + class InternalSparseQuotientExtractor : public InternalSparseQuotientExtractorBase { public: - InternalSparseQuotientExtractor(storm::models::symbolic::Model const& model, storm::dd::Bdd const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t numberOfBlocks, storm::dd::Bdd const& representatives) : InternalSparseQuotientExtractorBase(model, partitionBdd, blockVariable, numberOfBlocks, representatives) { + InternalSparseQuotientExtractor(storm::models::symbolic::Model const& model, storm::dd::Bdd const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t numberOfBlocks, storm::dd::Bdd const& representatives) : InternalSparseQuotientExtractorBase(model, partitionBdd, blockVariable, numberOfBlocks, representatives) { this->createBlockToOffsetMapping(); } private: - virtual storm::storage::SparseMatrix extractMatrixInternal(storm::dd::Add const& matrix) override { + virtual storm::storage::SparseMatrix extractMatrixInternal(storm::dd::Add const& matrix) override { this->createMatrixEntryStorage(); extractTransitionMatrixRec(matrix.getInternalAdd().getSylvanMtbdd().GetMTBDD(), this->isNondeterministic ? this->nondeterminismOdd : this->odd, 0, this->partitionBdd.getInternalBdd().getSylvanBdd().GetBDD(), this->representatives.getInternalBdd().getSylvanBdd().GetBDD(), this->allSourceVariablesCube.getInternalBdd().getSylvanBdd().GetBDD(), this->nondeterminismVariablesCube.getInternalBdd().getSylvanBdd().GetBDD(), this->isNondeterministic ? &this->odd : nullptr, 0); return this->createMatrixFromEntries(); } - virtual std::vector extractVectorInternal(storm::dd::Add const& vector, storm::dd::Bdd const& variablesCube, storm::dd::Odd const& odd) override { - std::vector result(odd.getTotalOffset()); + virtual std::vector extractVectorInternal(storm::dd::Add const& vector, storm::dd::Bdd const& variablesCube, storm::dd::Odd const& odd) override { + std::vector result(odd.getTotalOffset()); extractVectorRec(vector.getInternalAdd().getSylvanMtbdd().GetMTBDD(), this->representatives.getInternalBdd().getSylvanBdd().GetBDD(), variablesCube.getInternalBdd().getSylvanBdd().GetBDD(), odd, 0, result); return result; } - void extractVectorRec(MTBDD vector, BDD representativesNode, BDD variables, storm::dd::Odd const& odd, uint64_t offset, std::vector& result) { + void extractVectorRec(MTBDD vector, BDD representativesNode, BDD variables, storm::dd::Odd const& odd, uint64_t offset, std::vector& result) { if (representativesNode == sylvan_false || mtbdd_iszero(vector)) { return; } if (sylvan_isconst(variables)) { - result[offset] = storm::dd::InternalAdd::getValue(vector); + result[offset] = storm::utility::convertNumber(storm::dd::InternalAdd::getValue(vector)); } else { MTBDD vectorT; MTBDD vectorE; @@ -723,7 +723,7 @@ namespace storm { // If we have moved through all source variables, we must have arrived at a target block encoding. if (sylvan_isconst(variables)) { STORM_LOG_ASSERT(mtbdd_isleaf(transitionMatrixNode), "Expected constant node."); - this->addMatrixEntry(sourceOffset, blockToOffset.at(targetPartitionNode), storm::dd::InternalAdd::getValue(transitionMatrixNode)); + this->addMatrixEntry(sourceOffset, blockToOffset.at(targetPartitionNode), storm::utility::convertNumber(storm::dd::InternalAdd::getValue(transitionMatrixNode))); if (stateOdd) { this->assignRowToState(sourceOffset, stateOffset); } @@ -817,18 +817,18 @@ namespace storm { spp::sparse_hash_map blockToOffset; }; - template - QuotientExtractor::QuotientExtractor() : useRepresentatives(false) { + template + QuotientExtractor::QuotientExtractor() : useRepresentatives(false) { auto const& settings = storm::settings::getModule(); this->useRepresentatives = settings.isUseRepresentativesSet(); this->useOriginalVariables = settings.isUseOriginalVariablesSet(); this->quotientFormat = settings.getQuotientFormat(); } - template - std::shared_ptr> QuotientExtractor::extract(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { + template + std::shared_ptr> QuotientExtractor::extract(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { auto start = std::chrono::high_resolution_clock::now(); - std::shared_ptr> result; + std::shared_ptr> result; if (quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Sparse) { result = extractSparseQuotient(model, partition, preservationInformation); } else { @@ -842,8 +842,8 @@ namespace storm { return result; } - template - std::shared_ptr> QuotientExtractor::extractSparseQuotient(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { + template + std::shared_ptr> QuotientExtractor::extractSparseQuotient(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { auto states = partition.getStates().swapVariables(model.getRowColumnMetaVariablePairs()); storm::dd::Bdd partitionAsBdd = partition.storedAsAdd() ? partition.asAdd().toBdd() : partition.asBdd(); @@ -853,8 +853,8 @@ namespace storm { auto representatives = InternalRepresentativeComputer(partitionAsBdd, model.getRowVariables()).getRepresentatives(); STORM_LOG_ASSERT(representatives.getNonZeroCount() == partition.getNumberOfBlocks(), "Representatives size does not match that of the partition: " << representatives.getNonZeroCount() << " vs. " << partition.getNumberOfBlocks() << "."); STORM_LOG_ASSERT((representatives && partitionAsBdd).existsAbstract(model.getRowVariables()) == partitionAsBdd.existsAbstract(model.getRowVariables()), "Representatives do not cover all blocks."); - InternalSparseQuotientExtractor sparseExtractor(model, partitionAsBdd, partition.getBlockVariable(), partition.getNumberOfBlocks(), representatives); - storm::storage::SparseMatrix quotientTransitionMatrix = sparseExtractor.extractTransitionMatrix(model.getTransitionMatrix()); + InternalSparseQuotientExtractor sparseExtractor(model, partitionAsBdd, partition.getBlockVariable(), partition.getNumberOfBlocks(), representatives); + storm::storage::SparseMatrix quotientTransitionMatrix = sparseExtractor.extractTransitionMatrix(model.getTransitionMatrix()); auto end = std::chrono::high_resolution_clock::now(); STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast(end - start).count() << "ms."); @@ -881,47 +881,47 @@ namespace storm { STORM_LOG_INFO("Quotient labels extracted in " << std::chrono::duration_cast(end - start).count() << "ms."); start = std::chrono::high_resolution_clock::now(); - std::unordered_map> quotientRewardModels; + std::unordered_map> quotientRewardModels; for (auto const& rewardModelName : preservationInformation.getRewardModelNames()) { auto const& rewardModel = model.getRewardModel(rewardModelName); - boost::optional> quotientStateRewards; + boost::optional> quotientStateRewards; if (rewardModel.hasStateRewards()) { quotientStateRewards = sparseExtractor.extractStateVector(rewardModel.getStateRewardVector()); } - boost::optional> quotientStateActionRewards; + boost::optional> quotientStateActionRewards; if (rewardModel.hasStateActionRewards()) { quotientStateActionRewards = sparseExtractor.extractStateActionVector(rewardModel.getStateActionRewardVector()); } - quotientRewardModels.emplace(rewardModelName, storm::models::sparse::StandardRewardModel(std::move(quotientStateRewards), std::move(quotientStateActionRewards), boost::none)); + quotientRewardModels.emplace(rewardModelName, storm::models::sparse::StandardRewardModel(std::move(quotientStateRewards), std::move(quotientStateActionRewards), boost::none)); } end = std::chrono::high_resolution_clock::now(); STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast(end - start).count() << "ms."); - std::shared_ptr> result; + std::shared_ptr> result; if (model.getType() == storm::models::ModelType::Dtmc) { - result = std::make_shared>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + result = std::make_shared>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); } else if (model.getType() == storm::models::ModelType::Ctmc) { - result = std::make_shared>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + result = std::make_shared>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); } else if (model.getType() == storm::models::ModelType::Mdp) { - result = std::make_shared>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + result = std::make_shared>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); } else if (model.getType() == storm::models::ModelType::MarkovAutomaton) { storm::models::symbolic::MarkovAutomaton const& markovAutomaton = *model.template as>(); boost::optional markovianStates = sparseExtractor.extractSetExists(markovAutomaton.getMarkovianStates()); - storm::storage::sparse::ModelComponents modelComponents(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels), false, std::move(markovianStates)); + storm::storage::sparse::ModelComponents modelComponents(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels), false, std::move(markovianStates)); modelComponents.exitRates = sparseExtractor.extractStateVector(markovAutomaton.getExitRateVector()); - result = std::make_shared>(std::move(modelComponents)); + result = std::make_shared>(std::move(modelComponents)); } return result; } - template - std::shared_ptr> QuotientExtractor::extractDdQuotient(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { + template + std::shared_ptr> QuotientExtractor::extractDdQuotient(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { if (this->useOriginalVariables) { return extractQuotientUsingOriginalVariables(model, partition, preservationInformation); @@ -930,8 +930,8 @@ namespace storm { } } - template - std::shared_ptr> QuotientExtractor::extractQuotientUsingBlockVariables(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { + template + std::shared_ptr> QuotientExtractor::extractQuotientUsingBlockVariables(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { auto modelType = model.getType(); bool useRepresentativesForThisExtraction = this->useRepresentatives; @@ -1028,22 +1028,25 @@ namespace storm { end = std::chrono::high_resolution_clock::now(); STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast(end - start).count() << "ms."); + std::shared_ptr> result; if (modelType == storm::models::ModelType::Dtmc) { - return std::shared_ptr>(new storm::models::symbolic::Dtmc(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr>(new storm::models::symbolic::Dtmc(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Ctmc) { - return std::shared_ptr>(new storm::models::symbolic::Ctmc(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr>(new storm::models::symbolic::Ctmc(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Mdp) { - return std::shared_ptr>(new storm::models::symbolic::Mdp(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr>(new storm::models::symbolic::Mdp(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } else { - return std::shared_ptr>(new storm::models::symbolic::MarkovAutomaton(model.getManager().asSharedPointer(), model. template as>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr>(new storm::models::symbolic::MarkovAutomaton(model.getManager().asSharedPointer(), model. template as>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } + + return result->template toValueType(); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); } } - template - std::shared_ptr> QuotientExtractor::extractQuotientUsingOriginalVariables(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { + template + std::shared_ptr> QuotientExtractor::extractQuotientUsingOriginalVariables(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation) { auto modelType = model.getType(); bool useRepresentativesForThisExtraction = this->useRepresentatives; @@ -1146,15 +1149,18 @@ namespace storm { end = std::chrono::high_resolution_clock::now(); STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast(end - start).count() << "ms."); + std::shared_ptr> result; if (modelType == storm::models::ModelType::Dtmc) { - return std::shared_ptr>(new storm::models::symbolic::Dtmc(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr>(new storm::models::symbolic::Dtmc(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Ctmc) { - return std::shared_ptr>(new storm::models::symbolic::Ctmc(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr>(new storm::models::symbolic::Ctmc(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Mdp) { - return std::shared_ptr>(new storm::models::symbolic::Mdp(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr>(new storm::models::symbolic::Mdp(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } else { - return std::shared_ptr>(new storm::models::symbolic::MarkovAutomaton(model.getManager().asSharedPointer(), model. template as>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr>(new storm::models::symbolic::MarkovAutomaton(model.getManager().asSharedPointer(), model. template as>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } + + return result->template toValueType(); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); } @@ -1164,6 +1170,7 @@ namespace storm { template class QuotientExtractor; template class QuotientExtractor; + template class QuotientExtractor; template class QuotientExtractor; } diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.h b/src/storm/storage/dd/bisimulation/QuotientExtractor.h index b75b27b08..422453bf7 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.h +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.h @@ -16,19 +16,19 @@ namespace storm { namespace dd { namespace bisimulation { - template + template class QuotientExtractor { public: QuotientExtractor(); - std::shared_ptr> extract(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); + std::shared_ptr> extract(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); private: - std::shared_ptr> extractSparseQuotient(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); + std::shared_ptr> extractSparseQuotient(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); - std::shared_ptr> extractDdQuotient(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); - std::shared_ptr> extractQuotientUsingBlockVariables(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); - std::shared_ptr> extractQuotientUsingOriginalVariables(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); + std::shared_ptr> extractDdQuotient(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); + std::shared_ptr> extractQuotientUsingBlockVariables(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); + std::shared_ptr> extractQuotientUsingOriginalVariables(storm::models::symbolic::Model const& model, Partition const& partition, PreservationInformation const& preservationInformation); bool useRepresentatives; bool useOriginalVariables;