diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 0909b25de..758ac9a2a 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -236,15 +236,15 @@ namespace storm { if (settings.isSymbolicSet()) { #ifdef STORM_HAVE_CARL if (settings.isParametricSet()) { - buildAndCheckSymbolicModel(program.get(), formulas); + buildAndCheckSymbolicModel(program.get(), formulas, true); } else { #endif - buildAndCheckSymbolicModel(program.get(), formulas); + buildAndCheckSymbolicModel(program.get(), formulas, true); #ifdef STORM_HAVE_CARL } #endif } else if (settings.isExplicitSet()) { - buildAndCheckExplicitModel(formulas); + buildAndCheckExplicitModel(formulas, true); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No input model."); } diff --git a/src/cli/entrypoints.h b/src/cli/entrypoints.h index c93279179..bbb9d6404 100644 --- a/src/cli/entrypoints.h +++ b/src/cli/entrypoints.h @@ -9,10 +9,10 @@ namespace storm { namespace cli { template - void verifySparseModel(std::shared_ptr> model, std::vector> const& formulas) { + void verifySparseModel(std::shared_ptr> model, std::vector> const& formulas, bool onlyInitialStatesRelevant = false) { for (auto const& formula : formulas) { std::cout << std::endl << "Model checking property: " << *formula << " ..."; - std::unique_ptr result(storm::verifySparseModel(model, formula)); + std::unique_ptr result(storm::verifySparseModel(model, formula, onlyInitialStatesRelevant)); if (result) { std::cout << " done." << std::endl; std::cout << "Result (initial states): "; @@ -26,12 +26,12 @@ namespace storm { #ifdef STORM_HAVE_CARL template<> - inline void verifySparseModel(std::shared_ptr> model, std::vector> const& formulas) { + inline void verifySparseModel(std::shared_ptr> model, std::vector> const& formulas, bool onlyInitialStatesRelevant) { for (auto const& formula : formulas) { STORM_LOG_THROW(model->getType() == storm::models::ModelType::Dtmc, storm::exceptions::InvalidSettingsException, "Currently parametric verification is only available for DTMCs."); std::cout << std::endl << "Model checking property: " << *formula << " ..."; - std::unique_ptr result(storm::verifySparseModel(model, formula)); + std::unique_ptr result(storm::verifySparseModel(model, formula, onlyInitialStatesRelevant)); if (result) { std::cout << " done." << std::endl; std::cout << "Result (initial states): "; @@ -50,15 +50,15 @@ namespace storm { #endif template - void verifySymbolicModelWithAbstractionRefinementEngine(storm::prism::Program const& program, std::vector> const& formulas) { + void verifySymbolicModelWithAbstractionRefinementEngine(storm::prism::Program const& program, std::vector> const& formulas, bool onlyInitialStatesRelevant = false) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Abstraction Refinement is not yet implemented."); } template - void verifySymbolicModelWithHybridEngine(std::shared_ptr> model, std::vector> const& formulas) { + void verifySymbolicModelWithHybridEngine(std::shared_ptr> model, std::vector> const& formulas, bool onlyInitialStatesRelevant = false) { for (auto const& formula : formulas) { std::cout << std::endl << "Model checking property: " << *formula << " ..."; - std::unique_ptr result(storm::verifySymbolicModelWithHybridEngine(model, formula)); + std::unique_ptr result(storm::verifySymbolicModelWithHybridEngine(model, formula, onlyInitialStatesRelevant)); if (result) { std::cout << " done." << std::endl; @@ -72,10 +72,10 @@ namespace storm { } template - void verifySymbolicModelWithSymbolicEngine(std::shared_ptr> model, std::vector> const& formulas) { + void verifySymbolicModelWithSymbolicEngine(std::shared_ptr> model, std::vector> const& formulas, bool onlyInitialStatesRelevant = false) { for (auto const& formula : formulas) { std::cout << std::endl << "Model checking property: " << *formula << " ..."; - std::unique_ptr result(storm::verifySymbolicModelWithDdEngine(model, formula)); + std::unique_ptr result(storm::verifySymbolicModelWithDdEngine(model, formula, onlyInitialStatesRelevant)); if (result) { std::cout << " done." << std::endl; std::cout << "Result (initial states): "; @@ -114,12 +114,12 @@ namespace storm { } template - void buildAndCheckSymbolicModel(storm::prism::Program const& program, std::vector> const& formulas) { + void buildAndCheckSymbolicModel(storm::prism::Program const& program, std::vector> const& formulas, bool onlyInitialStatesRelevant = false) { storm::settings::modules::GeneralSettings const& settings = storm::settings::generalSettings(); if (settings.getEngine() == storm::settings::modules::GeneralSettings::Engine::AbstractionRefinement) { - verifySymbolicModelWithAbstractionRefinementEngine(program, formulas); + verifySymbolicModelWithAbstractionRefinementEngine(program, formulas, onlyInitialStatesRelevant); } else { storm::storage::ModelFormulasPair modelFormulasPair = buildSymbolicModel(program, formulas); STORM_LOG_THROW(modelFormulasPair.model != nullptr, storm::exceptions::InvalidStateException, @@ -133,7 +133,6 @@ namespace storm { // Verify the model, if a formula was given. if (!formulas.empty()) { - if (modelFormulasPair.model->isSparseModel()) { if (storm::settings::generalSettings().isCounterexampleSet()) { // If we were requested to generate a counterexample, we now do so for each formula. @@ -141,15 +140,15 @@ namespace storm { generateCounterexample(program, modelFormulasPair.model->as>(), formula); } } else { - verifySparseModel(modelFormulasPair.model->as>(), modelFormulasPair.formulas); + verifySparseModel(modelFormulasPair.model->as>(), modelFormulasPair.formulas, onlyInitialStatesRelevant); } } else if (modelFormulasPair.model->isSymbolicModel()) { if (storm::settings::generalSettings().getEngine() == storm::settings::modules::GeneralSettings::Engine::Hybrid) { verifySymbolicModelWithHybridEngine(modelFormulasPair.model->as>(), - modelFormulasPair.formulas); + modelFormulasPair.formulas, onlyInitialStatesRelevant); } else { verifySymbolicModelWithSymbolicEngine(modelFormulasPair.model->as>(), - modelFormulasPair.formulas); + modelFormulasPair.formulas, onlyInitialStatesRelevant); } } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Invalid input model type."); @@ -159,16 +158,16 @@ namespace storm { } template - void buildAndCheckSymbolicModel(storm::prism::Program const& program, std::vector> const& formulas) { + void buildAndCheckSymbolicModel(storm::prism::Program const& program, std::vector> const& formulas, bool onlyInitialStatesRelevant = false) { if (storm::settings::generalSettings().getDdLibraryType() == storm::dd::DdType::CUDD) { - buildAndCheckSymbolicModel(program, formulas); + buildAndCheckSymbolicModel(program, formulas, onlyInitialStatesRelevant); } else if (storm::settings::generalSettings().getDdLibraryType() == storm::dd::DdType::Sylvan) { - buildAndCheckSymbolicModel(program, formulas); + buildAndCheckSymbolicModel(program, formulas, onlyInitialStatesRelevant); } } template - void buildAndCheckExplicitModel(std::vector> const& formulas) { + void buildAndCheckExplicitModel(std::vector> const& formulas, bool onlyInitialStatesRelevant = false) { storm::settings::modules::GeneralSettings const& settings = storm::settings::generalSettings(); STORM_LOG_THROW(settings.isExplicitSet(), storm::exceptions::InvalidStateException, "Unable to build explicit model without model files."); @@ -183,7 +182,7 @@ namespace storm { // Verify the model, if a formula was given. if (!formulas.empty()) { STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidStateException, "Expected sparse model."); - verifySparseModel(model->as>(), formulas); + verifySparseModel(model->as>(), formulas, onlyInitialStatesRelevant); } } } diff --git a/src/modelchecker/CheckTask.h b/src/modelchecker/CheckTask.h index acd039b8b..cf66f4f06 100644 --- a/src/modelchecker/CheckTask.h +++ b/src/modelchecker/CheckTask.h @@ -28,8 +28,8 @@ namespace storm { /*! * Creates a task object with the default options for the given formula. */ - CheckTask(FormulaType const& formula) : formula(formula) { - this->onlyInitialStatesRelevant = false; + CheckTask(FormulaType const& formula, bool onlyInitialStatesRelevant = false) : formula(formula) { + this->onlyInitialStatesRelevant = onlyInitialStatesRelevant; this->produceStrategies = true; this->qualitative = false; diff --git a/src/utility/storm.h b/src/utility/storm.h index 86a43caab..d4a042bc6 100644 --- a/src/utility/storm.h +++ b/src/utility/storm.h @@ -236,23 +236,23 @@ namespace storm { #endif template - std::unique_ptr verifyModel(std::shared_ptr model, std::shared_ptr const& formula) { + std::unique_ptr verifyModel(std::shared_ptr model, std::shared_ptr const& formula, bool onlyInitialStatesRelevant) { storm::settings::modules::GeneralSettings const& settings = storm::settings::generalSettings(); switch(settings.getEngine()) { case storm::settings::modules::GeneralSettings::Engine::Sparse: { std::shared_ptr> sparseModel = model->template as>(); STORM_LOG_THROW(sparseModel != nullptr, storm::exceptions::InvalidArgumentException, "Sparse engine requires a sparse input model"); - return verifySparseModel(sparseModel, formula); + return verifySparseModel(sparseModel, formula, onlyInitialStatesRelevant); } case storm::settings::modules::GeneralSettings::Engine::Hybrid: { std::shared_ptr> ddModel = model->template as>(); STORM_LOG_THROW(ddModel != nullptr, storm::exceptions::InvalidArgumentException, "Hybrid engine requires a dd input model"); - return verifySymbolicModelWithHybridEngine(ddModel, formula); + return verifySymbolicModelWithHybridEngine(ddModel, formula, onlyInitialStatesRelevant); } case storm::settings::modules::GeneralSettings::Engine::Dd: { std::shared_ptr> ddModel = model->template as>(); STORM_LOG_THROW(ddModel != nullptr, storm::exceptions::InvalidArgumentException, "Dd engine requires a dd input model"); - return verifySymbolicModelWithDdEngine(ddModel, formula); + return verifySymbolicModelWithDdEngine(ddModel, formula, onlyInitialStatesRelevant); } case storm::settings::modules::GeneralSettings::Engine::AbstractionRefinement: { STORM_LOG_ASSERT(false, "This position should not be reached, as at this point no model has been built."); @@ -261,18 +261,19 @@ namespace storm { } template - std::unique_ptr verifySparseModel(std::shared_ptr> model, std::shared_ptr const& formula) { + std::unique_ptr verifySparseModel(std::shared_ptr> model, std::shared_ptr const& formula, bool onlyInitialStatesRelevant = false) { std::unique_ptr result; + storm::modelchecker::CheckTask task(*formula, onlyInitialStatesRelevant); if (model->getType() == storm::models::ModelType::Dtmc) { std::shared_ptr> dtmc = model->template as>(); storm::modelchecker::SparseDtmcPrctlModelChecker> modelchecker(*dtmc); - if (modelchecker.canHandle(*formula)) { - result = modelchecker.check(*formula); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); } else { storm::modelchecker::SparseDtmcEliminationModelChecker> modelchecker2(*dtmc); - if (modelchecker2.canHandle(*formula)) { - result = modelchecker2.check(*formula); + if (modelchecker2.canHandle(task)) { + result = modelchecker2.check(task); } } } else if (model->getType() == storm::models::ModelType::Mdp) { @@ -280,20 +281,20 @@ namespace storm { #ifdef STORM_HAVE_CUDA if (settings.isCudaSet()) { storm::modelchecker::TopologicalValueIterationMdpPrctlModelChecker modelchecker(*mdp); - result = modelchecker.check(*formula); + result = modelchecker.check(task); } else { storm::modelchecker::SparseMdpPrctlModelChecker> modelchecker(*mdp); - result = modelchecker.check(*formula); + result = modelchecker.check(task); } #else storm::modelchecker::SparseMdpPrctlModelChecker> modelchecker(*mdp); - result = modelchecker.check(*formula); + result = modelchecker.check(task); #endif } else if (model->getType() == storm::models::ModelType::Ctmc) { std::shared_ptr> ctmc = model->template as>(); storm::modelchecker::SparseCtmcCslModelChecker> modelchecker(*ctmc); - result = modelchecker.check(*formula); + result = modelchecker.check(task); } return result; @@ -317,13 +318,14 @@ namespace storm { } template<> - inline std::unique_ptr verifySparseModel(std::shared_ptr> model, std::shared_ptr const& formula) { + inline std::unique_ptr verifySparseModel(std::shared_ptr> model, std::shared_ptr const& formula, bool onlyInitialStatesRelevant) { std::unique_ptr result; std::shared_ptr> dtmc = model->template as>(); storm::modelchecker::SparseDtmcEliminationModelChecker> modelchecker(*dtmc); - if (modelchecker.canHandle(*formula)) { - result = modelchecker.check(*formula); + storm::modelchecker::CheckTask task(*formula, onlyInitialStatesRelevant); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "The parametric engine currently does not support this property."); } @@ -333,25 +335,26 @@ namespace storm { #endif template - std::unique_ptr verifySymbolicModelWithHybridEngine(std::shared_ptr> model, std::shared_ptr const& formula) { + std::unique_ptr verifySymbolicModelWithHybridEngine(std::shared_ptr> model, std::shared_ptr const& formula, bool onlyInitialStatesRelevant = false) { std::unique_ptr result; + storm::modelchecker::CheckTask task(*formula, onlyInitialStatesRelevant); if (model->getType() == storm::models::ModelType::Dtmc) { std::shared_ptr> dtmc = model->template as>(); storm::modelchecker::HybridDtmcPrctlModelChecker modelchecker(*dtmc); - if (modelchecker.canHandle(*formula)) { - result = modelchecker.check(*formula); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); } } else if (model->getType() == storm::models::ModelType::Ctmc) { std::shared_ptr> ctmc = model->template as>(); storm::modelchecker::HybridCtmcCslModelChecker modelchecker(*ctmc); - if (modelchecker.canHandle(*formula)) { - result = modelchecker.check(*formula); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); } } else if (model->getType() == storm::models::ModelType::Mdp) { std::shared_ptr> mdp = model->template as>(); storm::modelchecker::HybridMdpPrctlModelChecker modelchecker(*mdp); - if (modelchecker.canHandle(*formula)) { - result = modelchecker.check(*formula); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); } } else { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This functionality is not yet implemented."); @@ -361,19 +364,20 @@ namespace storm { template - std::unique_ptr verifySymbolicModelWithDdEngine(std::shared_ptr> model, std::shared_ptr const& formula) { + std::unique_ptr verifySymbolicModelWithDdEngine(std::shared_ptr> model, std::shared_ptr const& formula, bool onlyInitialStatesRelevant) { std::unique_ptr result; + storm::modelchecker::CheckTask task(*formula, onlyInitialStatesRelevant); if (model->getType() == storm::models::ModelType::Dtmc) { std::shared_ptr> dtmc = model->template as>(); storm::modelchecker::SymbolicDtmcPrctlModelChecker modelchecker(*dtmc); - if (modelchecker.canHandle(*formula)) { - result = modelchecker.check(*formula); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); } } else if (model->getType() == storm::models::ModelType::Mdp) { std::shared_ptr> mdp = model->template as>(); storm::modelchecker::SymbolicMdpPrctlModelChecker modelchecker(*mdp); - if (modelchecker.canHandle(*formula)) { - result = modelchecker.check(*formula); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); } } else { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This functionality is not yet implemented.");