diff --git a/src/storm/cli/cli.cpp b/src/storm/cli/cli.cpp index f2fefff36..e36cd13c2 100644 --- a/src/storm/cli/cli.cpp +++ b/src/storm/cli/cli.cpp @@ -1,7 +1,4 @@ #include "storm/cli/cli.h" -#include "storm/cli/entrypoints.h" - -#include "storm/utility/storm.h" #include "storm/storage/SymbolicModelDescription.h" @@ -14,6 +11,8 @@ #include "storm/settings/modules/ResourceSettings.h" #include "storm/settings/modules/JaniExportSettings.h" +#include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" + #include "storm/utility/resources.h" #include "storm/utility/file.h" #include "storm/utility/storm-version.h" @@ -24,10 +23,12 @@ #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/ResourceSettings.h" - +#include "storm/settings/modules/ParametricSettings.h" #include +#include "storm/api/storm.h" + #include "storm/utility/macros.h" // Includes for the linked libraries and versions header. @@ -229,17 +230,6 @@ namespace storm { setFileLogging(); } - void rest(); - - boost::optional> parsePropertyFilter(storm::settings::modules::IOSettings const& ioSettings) { - boost::optional> propertyFilter; - std::string propertyFilterString = ioSettings.getPropertyFilter(); - if (propertyFilterString != "all") { - propertyFilter = storm::parsePropertyFilter(propertyFilterString); - } - return propertyFilter; - } - struct SymbolicInput { // The symbolic model description. boost::optional model; @@ -285,7 +275,7 @@ namespace storm { auto ioSettings = storm::settings::getModule(); // Parse the property filter, if any is given. - boost::optional> propertyFilter = parsePropertyFilter(ioSettings); + boost::optional> propertyFilter = storm::api::parsePropertyFilter(ioSettings.getPropertyFilter()); SymbolicInput input; parseSymbolicModelDescription(ioSettings, input); @@ -308,7 +298,7 @@ namespace storm { output.model.get().preprocess(constantDefinitions); } if (!output.properties.empty()) { - output.properties = substituteConstantsInProperties(output.properties, constantDefinitions); + output.properties = storm::api::substituteConstantsInProperties(output.properties, constantDefinitions); } // Check whether conversion for PRISM to JANI is requested or necessary. @@ -362,13 +352,13 @@ namespace storm { template std::shared_ptr buildModelDd(SymbolicInput const& input) { - return storm::api::buildSymbolicModel(input.model.get(), extractFormulasFromProperties(input.properties)); + return storm::api::buildSymbolicModel(input.model.get(), storm::api::extractFormulasFromProperties(input.properties)); } template std::shared_ptr buildModelSparse(SymbolicInput const& input, storm::settings::modules::IOSettings const& ioSettings) { auto counterexampleGeneratorSettings = storm::settings::getModule(); - return storm::api::buildSparseModel(input.model.get(), extractFormulasFromProperties(input.properties), ioSettings.isBuildChoiceLabelsSet(), counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet()); + return storm::api::buildSparseModel(input.model.get(), storm::api::extractFormulasFromProperties(input.properties), ioSettings.isBuildChoiceLabelsSet(), counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet()); } template @@ -424,7 +414,7 @@ namespace storm { } STORM_LOG_INFO("Performing bisimulation minimization..."); - return storm::api::performBisimulationMinimization(model, extractFormulasFromProperties(input.properties), bisimType); + return storm::api::performBisimulationMinimization(model, storm::api::extractFormulasFromProperties(input.properties), bisimType); } template @@ -661,9 +651,10 @@ namespace storm { return result; }, [&sparseModel] (std::unique_ptr const& result) { - if (std::is_same::value && sparseModel->isOfType(storm::models::ModelType::Dtmc) && storm::settings::getModule().exportResultToFile()) { + auto parametricSettings = storm::settings::getModule(); + if (std::is_same::value && sparseModel->isOfType(storm::models::ModelType::Dtmc) && parametricSettings.exportResultToFile()) { auto dtmc = sparseModel->template as>(); - storm::api::exportParametricResultToFile(result->asExplicitQuantitativeCheckResult()[*sparseModel->getInitialStates().begin()], storm::analysis::ConstraintCollector(*dtmc), storm::settings::getModule().exportResultPath()); + storm::api::exportParametricResultToFile(result->asExplicitQuantitativeCheckResult()[*sparseModel->getInitialStates().begin()], storm::analysis::ConstraintCollector(*dtmc), parametricSettings.exportResultPath()); } }); } diff --git a/src/storm/cli/entrypoints.h b/src/storm/cli/entrypoints.h deleted file mode 100644 index 001ec3992..000000000 --- a/src/storm/cli/entrypoints.h +++ /dev/null @@ -1,453 +0,0 @@ -#pragma once - -#include - -#include "storm/utility/storm.h" - -#include "storm/analysis/GraphConditions.h" -#include "storm/storage/SymbolicModelDescription.h" -#include "storm/utility/DirectEncodingExporter.h" -#include "storm/utility/Stopwatch.h" - -#include "storm/api/storm.h" - -#include "storm/exceptions/NotImplementedException.h" -#include "storm/exceptions/InvalidSettingsException.h" -#include "storm/exceptions/UnexpectedException.h" -#include "storm/exceptions/InvalidTypeException.h" - -namespace storm { - namespace cli { - - template - void applyFilterFunctionAndOutput(std::unique_ptr const& result, storm::modelchecker::FilterType ft) { - if (result->isQuantitative()) { - switch (ft) { - case storm::modelchecker::FilterType::VALUES: - STORM_PRINT_AND_LOG(*result); - break; - case storm::modelchecker::FilterType::SUM: - STORM_PRINT_AND_LOG(result->asQuantitativeCheckResult().sum()); - break; - case storm::modelchecker::FilterType::AVG: - STORM_PRINT_AND_LOG(result->asQuantitativeCheckResult().average()); - break; - case storm::modelchecker::FilterType::MIN: - STORM_PRINT_AND_LOG(result->asQuantitativeCheckResult().getMin()); - break; - case storm::modelchecker::FilterType::MAX: - STORM_PRINT_AND_LOG(result->asQuantitativeCheckResult().getMax()); - break; - case storm::modelchecker::FilterType::ARGMIN: - case storm::modelchecker::FilterType::ARGMAX: - STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Outputting states is not supported"); - case storm::modelchecker::FilterType::EXISTS: - case storm::modelchecker::FilterType::FORALL: - case storm::modelchecker::FilterType::COUNT: - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "FilterType only defined for qualitative results"); - } - } else { - switch (ft) { - case storm::modelchecker::FilterType::VALUES: - STORM_PRINT_AND_LOG(*result << std::endl); - break; - case storm::modelchecker::FilterType::EXISTS: - STORM_PRINT_AND_LOG(result->asQualitativeCheckResult().existsTrue()); - break; - case storm::modelchecker::FilterType::FORALL: - STORM_PRINT_AND_LOG(result->asQualitativeCheckResult().forallTrue()); - break; - case storm::modelchecker::FilterType::COUNT: - STORM_PRINT_AND_LOG(result->asQualitativeCheckResult().count()); - break; - - case storm::modelchecker::FilterType::ARGMIN: - case storm::modelchecker::FilterType::ARGMAX: - STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Outputting states is not supported"); - case storm::modelchecker::FilterType::SUM: - case storm::modelchecker::FilterType::AVG: - case storm::modelchecker::FilterType::MIN: - case storm::modelchecker::FilterType::MAX: - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "FilterType only defined for quantitative results"); - } - } - STORM_PRINT_AND_LOG(std::endl); - } - - template - void verifySparseModel(std::shared_ptr> model, std::vector const& properties, bool onlyInitialStatesRelevant = false) { - for (auto const& property : properties) { - STORM_PRINT_AND_LOG(std::endl << "Model checking property " << *property.getRawFormula() << " ..." << std::endl); - std::cout.flush(); - storm::utility::Stopwatch modelCheckingWatch(true); - std::unique_ptr result(storm::verifySparseModel(model, property.getFilter().getFormula(), onlyInitialStatesRelevant)); - modelCheckingWatch.stop(); - if (result) { - STORM_PRINT_AND_LOG("Result (initial states): "); - result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); - applyFilterFunctionAndOutput(result, property.getFilter().getFilterType()); - STORM_PRINT_AND_LOG("Time for model checking: " << modelCheckingWatch << "." << std::endl); - } else { - STORM_PRINT_AND_LOG(" skipped, because the modelling formalism is currently unsupported." << std::endl); - } - } - } - -#ifdef STORM_HAVE_CARL - template<> - inline void verifySparseModel(std::shared_ptr> model, std::vector const& properties, bool onlyInitialStatesRelevant) { - - for (auto const& property : properties) { - STORM_LOG_THROW(model->getType() == storm::models::ModelType::Dtmc || model->getType() == storm::models::ModelType::Ctmc, storm::exceptions::InvalidSettingsException, "Currently parametric verification is only available for DTMCs and CTMCs."); - STORM_PRINT_AND_LOG(std::endl << "Model checking property " << *property.getRawFormula() << " ..." << std::endl); - std::cout.flush(); - storm::utility::Stopwatch modelCheckingWatch(true); - std::unique_ptr result(storm::verifySparseModel(model, property.getFilter().getFormula(), onlyInitialStatesRelevant)); - modelCheckingWatch.stop(); - if (result) { - STORM_PRINT_AND_LOG("Result (initial states): "); - result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); - applyFilterFunctionAndOutput(result, property.getFilter().getFilterType()); - STORM_PRINT_AND_LOG("Time for model checking: " << modelCheckingWatch << "." << std::endl); - } else { - STORM_PRINT_AND_LOG(" skipped, because the modelling formalism is currently unsupported." << std::endl); - } - - if (storm::settings::getModule().exportResultToFile()) { - exportParametricResultToFile(result->asExplicitQuantitativeCheckResult()[*model->getInitialStates().begin()], storm::analysis::ConstraintCollector(*(model->template as>())), storm::settings::getModule().exportResultPath()); - } - } - } -#endif - - template - void verifySymbolicModelWithAbstractionRefinementEngine(storm::storage::SymbolicModelDescription const& model, std::vector const& properties, bool onlyInitialStatesRelevant = false) { - typedef double ValueType; - for (auto const& property : properties) { - STORM_PRINT_AND_LOG(std::endl << "Model checking property " << *property.getRawFormula() << " ..." << std::endl); - std::cout.flush(); - storm::utility::Stopwatch modelCheckingWatch(true); - std::unique_ptr result(storm::api::verifyWithAbstractionRefinementEngine(model, property.getFilter().getFormula(), onlyInitialStatesRelevant)); - modelCheckingWatch.stop(); - if (result) { - STORM_PRINT_AND_LOG("Result (initial states): "); - STORM_PRINT_AND_LOG(*result << std::endl); - STORM_PRINT_AND_LOG("Time for model checking: " << modelCheckingWatch << "." << std::endl); - } else { - STORM_PRINT_AND_LOG(" skipped, because the modelling formalism is currently unsupported." << std::endl); - } - } - } - - template - void verifySymbolicModelWithExplorationEngine(storm::storage::SymbolicModelDescription const& model, std::vector const& formulas, bool onlyInitialStatesRelevant = false) { - STORM_LOG_THROW(model.isPrismProgram(), storm::exceptions::InvalidSettingsException, "Exploration engine is currently only applicable to PRISM models."); - storm::prism::Program const& program = model.asPrismProgram(); - STORM_LOG_THROW(program.getModelType() == storm::prism::Program::ModelType::DTMC || program.getModelType() == storm::prism::Program::ModelType::MDP, storm::exceptions::InvalidSettingsException, "Currently exploration-based verification is only available for DTMCs and MDPs."); - - for (auto const& property : formulas) { - STORM_PRINT_AND_LOG(std::endl << "Model checking property " << *property.getRawFormula() << " ..." << std::endl); - std::cout.flush(); - bool formulaSupported = false; - std::unique_ptr result; - - storm::utility::Stopwatch modelCheckingWatch(false); - - if (program.getModelType() == storm::prism::Program::ModelType::DTMC) { - storm::modelchecker::SparseExplorationModelChecker> checker(program); - storm::modelchecker::CheckTask task(*property.getFilter().getFormula(), onlyInitialStatesRelevant); - - formulaSupported = checker.canHandle(task); - if (formulaSupported) { - modelCheckingWatch.start(); - result = checker.check(task); - modelCheckingWatch.stop(); - } - } else if (program.getModelType() == storm::prism::Program::ModelType::MDP) { - storm::modelchecker::SparseExplorationModelChecker> checker(program); - storm::modelchecker::CheckTask task(*property.getFilter().getFormula(), onlyInitialStatesRelevant); - - formulaSupported = checker.canHandle(task); - if (formulaSupported) { - modelCheckingWatch.start(); - result = checker.check(task); - modelCheckingWatch.stop(); - } - } else { - // Should be catched before. - assert(false); - } - if (!formulaSupported) { - STORM_PRINT_AND_LOG(" skipped, because the formula cannot be handled by the selected engine/method." << std::endl); - } - - if (result) { - STORM_PRINT_AND_LOG("Result (initial states): "); - applyFilterFunctionAndOutput(result, property.getFilter().getFilterType()); - STORM_PRINT_AND_LOG("Time for model checking: " << modelCheckingWatch << "." << std::endl); - } else { - STORM_PRINT_AND_LOG(" skipped, because the modelling formalism is currently unsupported." << std::endl); - } - } - } - -#ifdef STORM_HAVE_CARL - template<> - void verifySymbolicModelWithExplorationEngine(storm::storage::SymbolicModelDescription const& , std::vector const& , bool ) { - STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Exploration-based verification does currently not support parametric models."); - } -#endif - - template - void verifySymbolicModelWithHybridEngine(std::shared_ptr> model, std::vector const& formulas, bool onlyInitialStatesRelevant = false) { - for (auto const& property : formulas) { - STORM_PRINT_AND_LOG(std::endl << "Model checking property " << *property.getRawFormula() << " ..." << std::endl); - std::cout.flush(); - - storm::utility::Stopwatch modelCheckingWatch(true); - std::unique_ptr result(storm::verifySymbolicModelWithHybridEngine(model, property.getFilter().getFormula(), onlyInitialStatesRelevant)); - modelCheckingWatch.stop(); - - if (result) { - STORM_PRINT_AND_LOG("Result (initial states): "); - result->filter(storm::modelchecker::SymbolicQualitativeCheckResult(model->getReachableStates(), model->getInitialStates())); - applyFilterFunctionAndOutput(result, property.getFilter().getFilterType()); - STORM_PRINT_AND_LOG("Time for model checking: " << modelCheckingWatch << "." << std::endl); - } else { - STORM_PRINT_AND_LOG(" skipped, because the modelling formalism is currently unsupported." << std::endl); - } - } - } - - template - void verifySymbolicModelWithDdEngine(std::shared_ptr> model, std::vector const& formulas, bool onlyInitialStatesRelevant = false) { - for (auto const& property : formulas) { - STORM_PRINT_AND_LOG(std::endl << "Model checking property " << *property.getRawFormula() << " ..." << std::endl); - std::cout.flush(); - - storm::utility::Stopwatch modelCheckingWatch(true); - std::unique_ptr result(storm::verifySymbolicModelWithDdEngine(model, property.getFilter().getFormula(), onlyInitialStatesRelevant)); - modelCheckingWatch.stop(); - if (result) { - STORM_PRINT_AND_LOG("Result (initial states): "); - result->filter(storm::modelchecker::SymbolicQualitativeCheckResult(model->getReachableStates(), model->getInitialStates())); - applyFilterFunctionAndOutput(result, property.getFilter().getFilterType()); - STORM_PRINT_AND_LOG("Time for model checking: " << modelCheckingWatch << "." << std::endl); - } else { - STORM_PRINT_AND_LOG(" skipped, because the modelling formalism is currently unsupported." << std::endl); - } - } - } - -#define BRANCH_ON_MODELTYPE(result, model, value_type, dd_type, function, ...) \ - if (model->isSymbolicModel()) { \ - if (model->isOfType(storm::models::ModelType::Dtmc)) { \ - result = function>(model->as>(), __VA_ARGS__); \ - } else if (model->isOfType(storm::models::ModelType::Ctmc)) { \ - result = function>(model->as>(), __VA_ARGS__); \ - } else if (model->isOfType(storm::models::ModelType::Mdp)) { \ - result = function>(model->as>(), __VA_ARGS__); \ - } else { \ - STORM_LOG_ASSERT(false, "Unknown model type."); \ - } \ - } else { \ - STORM_LOG_ASSERT(model->isSparseModel(), "Unknown model type."); \ - if (model->isOfType(storm::models::ModelType::Dtmc)) { \ - result = function>(model->as>(), __VA_ARGS__); \ - } else if (model->isOfType(storm::models::ModelType::Ctmc)) { \ - result = function>(model->as>(), __VA_ARGS__); \ - } else if (model->isOfType(storm::models::ModelType::Mdp)) { \ - result = function>(model->as>(), __VA_ARGS__); \ - } else if (model->isOfType(storm::models::ModelType::MarkovAutomaton)) { \ - result = function>(model->as>(), __VA_ARGS__); \ - } else { \ - STORM_LOG_ASSERT(false, "Unknown model type."); \ - } \ - } - -#define BRANCH_ON_SPARSE_MODELTYPE(result, model, value_type, function, ...) \ - STORM_LOG_ASSERT(model->isSparseModel(), "Illegal model type."); \ - if (model->isOfType(storm::models::ModelType::Dtmc)) { \ - result = function>(model->template as>(), __VA_ARGS__); \ - } else if (model->isOfType(storm::models::ModelType::Ctmc)) { \ - result = function>(model->template as>(), __VA_ARGS__); \ - } else if (model->isOfType(storm::models::ModelType::Mdp)) { \ - result = function>(model->template as>(), __VA_ARGS__); \ - } else if (model->isOfType(storm::models::ModelType::MarkovAutomaton)) { \ - result = function>(model->template as>(), __VA_ARGS__); \ - } else { \ - STORM_LOG_ASSERT(false, "Unknown model type."); \ - } - - template - void buildAndCheckSymbolicModelWithSymbolicEngine(bool hybrid, storm::storage::SymbolicModelDescription const& model, std::vector const& properties, bool onlyInitialStatesRelevant = false) { - // Start by building the model. - storm::utility::Stopwatch modelBuildingWatch(true); - auto markovModel = storm::api::buildSymbolicModel(model, extractFormulasFromProperties(properties)); - modelBuildingWatch.stop(); - STORM_PRINT_AND_LOG("Time for model construction: " << modelBuildingWatch << "." << std::endl << std::endl); - - // Print some information about the model. - markovModel->printModelInformationToStream(std::cout); - - // Then select the correct engine. - if (hybrid) { - if (storm::settings::getModule().isParameterLiftingSet()) { - STORM_LOG_THROW(storm::settings::getModule().isParametricSet(), storm::exceptions::InvalidSettingsException, "Invoked parameter lifting without enabling the parametric engine."); - STORM_PRINT_AND_LOG("Transforming symbolic model to sparse model ..."); - auto sparseModel = storm::transformer::transformSymbolicToSparseModel(markovModel); - STORM_PRINT_AND_LOG(" done" << std::endl); - sparseModel->printModelInformationToStream(std::cout); - auto formulas = extractFormulasFromProperties(properties); - storm::performParameterLifting(sparseModel, formulas); - } else { - verifySymbolicModelWithHybridEngine(markovModel, properties, onlyInitialStatesRelevant); - } - } else { - verifySymbolicModelWithDdEngine(markovModel, properties, onlyInitialStatesRelevant); - } - } - - template - void buildAndCheckSymbolicModelWithSparseEngine(storm::storage::SymbolicModelDescription const& model, std::vector const& properties, bool onlyInitialStatesRelevant = false) { - auto formulas = extractFormulasFromProperties(properties); - // Start by building the model. - storm::utility::Stopwatch modelBuildingWatch(true); - std::shared_ptr markovModel = storm::api::buildSparseModel(model, formulas); - modelBuildingWatch.stop(); - STORM_PRINT_AND_LOG("Time for model construction: " << modelBuildingWatch << "." << std::endl << std::endl); - - STORM_LOG_THROW(markovModel, storm::exceptions::UnexpectedException, "The model was not successfully built."); - - // Print some information about the model. - markovModel->printModelInformationToStream(std::cout); - - // Preprocess the model. - BRANCH_ON_SPARSE_MODELTYPE(markovModel, markovModel, ValueType, preprocessModel, formulas); - - std::shared_ptr> sparseModel = markovModel->template as>(); - - // Finally, treat the formulas. - if (storm::settings::getModule().isCounterexampleSet()) { - generateCounterexamples(model, sparseModel, formulas); - } else if (storm::settings::getModule().isParameterLiftingSet()) { - STORM_LOG_THROW(storm::settings::getModule().isParametricSet(), storm::exceptions::InvalidSettingsException, "Invoked parameter lifting without enabling the parametric engine."); - storm::performParameterLifting(sparseModel, formulas); - } else { - verifySparseModel(sparseModel, properties, onlyInitialStatesRelevant); - } - - // And export if required. - if(storm::settings::getModule().isExportExplicitSet()) { - std::ofstream stream; - storm::utility::openFile(storm::settings::getModule().getExportExplicitFilename(), stream); - storm::exporter::explicitExportSparseModel(stream, sparseModel, model.getParameterNames()); - storm::utility::closeFile(stream); - } - - // And export DOT if required. - if(storm::settings::getModule().isExportDotSet()) { - std::ofstream stream; - storm::utility::openFile(storm::settings::getModule().getExportDotFilename(), stream); - sparseModel->writeDotToStream(stream); - storm::utility::closeFile(stream); - } - } - - template - void buildAndCheckSymbolicModel(storm::storage::SymbolicModelDescription const& model, std::vector const& formulas, bool onlyInitialStatesRelevant = false) { - if (storm::settings::getModule().getEngine() == storm::settings::modules::CoreSettings::Engine::AbstractionRefinement) { - STORM_LOG_THROW((std::is_same::value), storm::exceptions::InvalidTypeException, "The value type is not supported by abstraction refinement."); - auto ddlib = storm::settings::getModule().getDdLibraryType(); - if (ddlib == storm::dd::DdType::CUDD) { - verifySymbolicModelWithAbstractionRefinementEngine(model, formulas, onlyInitialStatesRelevant); - } else { - verifySymbolicModelWithAbstractionRefinementEngine(model, formulas, onlyInitialStatesRelevant); - } - } else if (storm::settings::getModule().getEngine() == storm::settings::modules::CoreSettings::Engine::Exploration) { - verifySymbolicModelWithExplorationEngine(model, formulas, onlyInitialStatesRelevant); - } else { - auto engine = storm::settings::getModule().getEngine(); - if (engine == storm::settings::modules::CoreSettings::Engine::Dd || engine == storm::settings::modules::CoreSettings::Engine::Hybrid) { - auto ddlib = storm::settings::getModule().getDdLibraryType(); - if (ddlib == storm::dd::DdType::CUDD) { - buildAndCheckSymbolicModelWithSymbolicEngine(engine == storm::settings::modules::CoreSettings::Engine::Hybrid, model, formulas, onlyInitialStatesRelevant); - } else { - buildAndCheckSymbolicModelWithSymbolicEngine(engine == storm::settings::modules::CoreSettings::Engine::Hybrid, model, formulas, onlyInitialStatesRelevant); - } - } else { - STORM_LOG_THROW(engine == storm::settings::modules::CoreSettings::Engine::Sparse, storm::exceptions::InvalidSettingsException, "Illegal engine."); - buildAndCheckSymbolicModelWithSparseEngine(model, formulas, onlyInitialStatesRelevant); - } - } - } - -#ifdef STORM_HAVE_CARL - template<> - void buildAndCheckSymbolicModel(storm::storage::SymbolicModelDescription const& model, std::vector const& formulas, bool onlyInitialStatesRelevant) { - auto engine = storm::settings::getModule().getEngine(); - if (engine == storm::settings::modules::CoreSettings::Engine::Dd || engine == storm::settings::modules::CoreSettings::Engine::Hybrid) { - auto ddlib = storm::settings::getModule().getDdLibraryType(); - STORM_LOG_THROW(ddlib == storm::dd::DdType::Sylvan, storm::exceptions::InvalidSettingsException, "This data-type is only available when selecting sylvan."); - buildAndCheckSymbolicModelWithSymbolicEngine(engine == storm::settings::modules::CoreSettings::Engine::Hybrid, model, formulas, onlyInitialStatesRelevant); - } else if (engine == storm::settings::modules::CoreSettings::Engine::Sparse) { - buildAndCheckSymbolicModelWithSparseEngine(model, formulas, onlyInitialStatesRelevant); - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Cannot use this data type with this engine."); - } - } - - template<> - void buildAndCheckSymbolicModel(storm::storage::SymbolicModelDescription const& model, std::vector const& formulas, bool onlyInitialStatesRelevant) { - auto engine = storm::settings::getModule().getEngine(); - if (engine == storm::settings::modules::CoreSettings::Engine::Dd || engine == storm::settings::modules::CoreSettings::Engine::Hybrid) { - auto ddlib = storm::settings::getModule().getDdLibraryType(); - STORM_LOG_THROW(ddlib == storm::dd::DdType::Sylvan, storm::exceptions::InvalidSettingsException, "This data-type is only available when selecting sylvan."); - buildAndCheckSymbolicModelWithSymbolicEngine(engine == storm::settings::modules::CoreSettings::Engine::Hybrid, model, formulas, onlyInitialStatesRelevant); - } else if (engine == storm::settings::modules::CoreSettings::Engine::Sparse) { - buildAndCheckSymbolicModelWithSparseEngine(model, formulas, onlyInitialStatesRelevant); - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Cannot use this data type with this engine."); - } - } -#endif - - template - void buildAndCheckExplicitModel(std::vector const& properties, bool onlyInitialStatesRelevant = false) { - storm::settings::modules::IOSettings const& settings = storm::settings::getModule(); - - STORM_LOG_THROW(settings.isExplicitSet() || settings.isExplicitDRNSet(), storm::exceptions::InvalidStateException, "Unable to build explicit model without model files."); - - storm::utility::Stopwatch modelBuildingWatch(true); - std::shared_ptr model; - if (settings.isExplicitSet()) { - model = api::buildExplicitModel(settings.getTransitionFilename(), settings.getLabelingFilename(), settings.isStateRewardsSet() ? boost::optional(settings.getStateRewardsFilename()) : boost::none, settings.isTransitionRewardsSet() ? boost::optional(settings.getTransitionRewardsFilename()) : boost::none, settings.isChoiceLabelingSet() ? boost::optional(settings.getChoiceLabelingFilename()) : boost::none); - } else { - model = api::buildExplicitDRNModel(settings.getExplicitDRNFilename()); - } - modelBuildingWatch.stop(); - STORM_PRINT_AND_LOG("Time for model construction: " << modelBuildingWatch << "." << std::endl); - - // Preprocess the model if needed. - BRANCH_ON_MODELTYPE(model, model, ValueType, storm::dd::DdType::CUDD, preprocessModel, extractFormulasFromProperties(properties)); - - // Print some information about the model. - model->printModelInformationToStream(std::cout); - - // Verify the model, if a formula was given. - if (!properties.empty()) { - STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidStateException, "Expected sparse model."); - verifySparseModel(model->as>(), properties, onlyInitialStatesRelevant); - } - - // Export DOT if required. - if(storm::settings::getModule().isExportDotSet()) { - std::ofstream stream; - storm::utility::openFile(storm::settings::getModule().getExportDotFilename(), stream); - model->as>()->writeDotToStream(stream); - storm::utility::closeFile(stream); - } - - } - } -}