diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index 1d71c3639..61a1eead1 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -42,6 +42,7 @@ #include "storm/settings/modules/AbstractionSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm/settings/modules/ModelCheckerSettings.h" +#include "storm/settings/modules/TransformationSettings.h" #include "storm/storage/Qvbs.h" #include "storm/utility/Stopwatch.h" @@ -350,11 +351,18 @@ namespace storm { auto generalSettings = storm::settings::getModule(); auto bisimulationSettings = storm::settings::getModule(); auto ioSettings = storm::settings::getModule(); + auto transformationSettings = storm::settings::getModule(); std::pair>, bool> result = std::make_pair(model, false); if (result.first->isOfType(storm::models::ModelType::MarkovAutomaton)) { result.first = preprocessSparseMarkovAutomaton(result.first->template as>()); + if (transformationSettings.isChainEliminationSet() && + result.first->isOfType(storm::models::ModelType::MarkovAutomaton)) { + result.first = storm::transformer::NonMarkovianChainTransformer::eliminateNonmarkovianStates( + result.first->template as>(), + !transformationSettings.isIgnoreLabelingSet()); + } result.second = true; } @@ -629,19 +637,31 @@ namespace storm { template void verifyProperties(SymbolicInput const& input, std::function(std::shared_ptr const& formula, std::shared_ptr const& states)> const& verificationCallback, std::function const&)> const& postprocessingCallback = PostprocessingIdentity()) { + auto transformationSettings = storm::settings::getModule(); auto const& properties = input.preprocessedProperties ? input.preprocessedProperties.get() : input.properties; for (auto const& property : properties) { printModelCheckingProperty(property); + bool ignored = false; storm::utility::Stopwatch watch(true); std::unique_ptr result; try { - result = verificationCallback(property.getRawFormula(), property.getFilter().getStatesFormula()); + auto rawFormula = property.getRawFormula(); + if (transformationSettings.isChainEliminationSet() && + !storm::transformer::NonMarkovianChainTransformer::preservesFormula(*rawFormula)) { + STORM_LOG_WARN("Property is not preserved by elimination of non-markovian states."); + ignored = true; + } else { + result = verificationCallback(property.getRawFormula(), + property.getFilter().getStatesFormula()); + } } catch (storm::exceptions::BaseException const& ex) { STORM_LOG_WARN("Cannot handle property: " << ex.what()); } watch.stop(); - postprocessingCallback(result); - printResult(result, property, &watch); + if (!ignored) { + postprocessingCallback(result); + printResult(result, property, &watch); + } } } diff --git a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp index 4af4c28c5..4a03692ab 100644 --- a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp +++ b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp @@ -8,7 +8,6 @@ #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/models/ModelType.h" -#include "storm/transformer/NonMarkovianChainTransformer.h" #include "storm-dft/builder/ExplicitDFTModelBuilder.h" #include "storm-dft/storage/dft/DFTIsomorphism.h" diff --git a/src/storm-pars-cli/storm-pars.cpp b/src/storm-pars-cli/storm-pars.cpp index fe5f50993..18b27627d 100644 --- a/src/storm-pars-cli/storm-pars.cpp +++ b/src/storm-pars-cli/storm-pars.cpp @@ -21,6 +21,7 @@ #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/IOSettings.h" #include "storm/settings/modules/BisimulationSettings.h" +#include "storm/settings/modules/TransformationSettings.h" #include "storm/exceptions/BaseException.h" #include "storm/exceptions/InvalidSettingsException.h" @@ -141,6 +142,7 @@ namespace storm { auto generalSettings = storm::settings::getModule(); auto bisimulationSettings = storm::settings::getModule(); auto parametricSettings = storm::settings::getModule(); + auto transformationSettings = storm::settings::getModule(); PreprocessResult result(model, false); @@ -153,6 +155,18 @@ namespace storm { result.model = storm::cli::preprocessSparseModelBisimulation(result.model->template as>(), input, bisimulationSettings); result.changed = true; } + + if (transformationSettings.isChainEliminationSet() && + model->isOfType(storm::models::ModelType::MarkovAutomaton)) { + auto eliminationResult = storm::api::eliminateNonMarkovianChains( + result.model->template as>(), + storm::api::extractFormulasFromProperties(input.properties), + transformationSettings.isIgnoreLabelingSet()); + result.model = eliminationResult.first; + // Set transformed properties as new properties in input + result.formulas = eliminationResult.second; + result.changed = true; + } if (parametricSettings.transformContinuousModel() && (model->isOfType(storm::models::ModelType::Ctmc) || model->isOfType(storm::models::ModelType::MarkovAutomaton))) { auto transformResult = storm::api::transformContinuousToDiscreteTimeSparseModel(std::move(*model->template as>()), storm::api::extractFormulasFromProperties(input.properties)); diff --git a/src/storm/api/transformation.h b/src/storm/api/transformation.h index 0fb25b2f2..4dcaf7f61 100644 --- a/src/storm/api/transformation.h +++ b/src/storm/api/transformation.h @@ -2,6 +2,7 @@ #include "storm/transformer/ContinuousToDiscreteTimeModelTransformer.h" #include "storm/transformer/SymbolicToSparseTransformer.h" +#include "storm/transformer/NonMarkovianChainTransformer.h" #include "storm/utility/macros.h" #include "storm/utility/builder.h" @@ -10,7 +11,30 @@ namespace storm { namespace api { - + + /*! + * Eliminates chains of non-Markovian states from a given Markov Automaton + */ + template + std::pair>, std::vector>> + eliminateNonMarkovianChains(std::shared_ptr> const &ma, + std::vector> const &formulas, + bool ignoreLabeling) { + + auto newFormulas = storm::transformer::NonMarkovianChainTransformer::checkAndTransformFormulas( + formulas); + STORM_LOG_WARN_COND(newFormulas.size() == formulas.size(), + "The state elimination does not preserve all properties."); + STORM_LOG_WARN_COND(!ignoreLabeling, + "Labels are ignored for the state elimination. This may cause incorrect results."); + return std::make_pair( + storm::transformer::NonMarkovianChainTransformer::eliminateNonmarkovianStates(ma, + !ignoreLabeling), + newFormulas); + + } + + /*! * Transforms the given continuous model to a discrete time model. * If such a transformation does not preserve one of the given formulas, a warning is issued.