50 std::shared_ptr<storm::models::ModelBase>
model;
51 boost::optional<std::vector<std::shared_ptr<storm::logic::Formula const>>>
formulas;
54template<
typename ValueType>
55std::vector<storm::storage::ParameterRegion<ValueType>>
parseRegions(std::shared_ptr<storm::models::ModelBase>
const& model) {
56 std::vector<storm::storage::ParameterRegion<ValueType>> result;
58 if (regionSettings.isRegionSet()) {
60 }
else if (regionSettings.isRegionBoundSet()) {
63 if (regionSettings.isAssumeGraphPreservingSet()) {
67 for (
auto const& region : result) {
68 for (
auto const& variable : region.getVariables()) {
74 <<
" appears to not preserve the graph structure of the parametric model. If this is the case, set --assume-graph-preserving false.");
83template<
typename ValueType>
84std::shared_ptr<storm::models::ModelBase>
eliminateScc(std::shared_ptr<storm::models::ModelBase>
const& model) {
86 std::shared_ptr<storm::models::ModelBase> result;
91 auto backwardsTransitionMatrix = matrix.transpose();
98 for (
size_t i = 0; i < decomposition.size(); ++i) {
99 auto scc = decomposition.getBlock(i);
100 if (scc.size() > 1) {
101 auto statesScc = scc.getStates();
102 std::vector<uint_fast64_t> entryStates;
103 for (
auto state : statesScc) {
104 auto row = backwardsTransitionMatrix.getRow(state);
106 for (
auto backState : row) {
107 if (!scc.containsState(backState.getColumn())) {
112 entryStates.push_back(state);
113 selfLoopStates.
set(state);
115 selectedStates.
set(state);
119 if (entryStates.size() != 1) {
120 STORM_LOG_THROW(entryStates.size() > 1, storm::exceptions::NotImplementedException,
121 "State elimination not implemented for scc with more than 1 entry points.");
131 for (
auto state : selectedStates) {
134 for (
auto state : selfLoopStates) {
135 auto row = flexibleMatrix.
getRow(state);
139 auto keptRows = matrix.getRowFilter(selectedStates);
142 result = std::make_shared<storm::models::sparse::Dtmc<ValueType>>(std::move(newTransitionMatrix),
143 sparseModel->getStateLabeling().getSubLabeling(selectedStates));
145 eliminationWatch.
stop();
146 STORM_PRINT(
"\nTime for scc elimination: " << eliminationWatch <<
".\n\n");
147 result->printModelInformationToStream(std::cout);
150 "Unable to perform SCC elimination for monotonicity analysis on MDP: Not implemented.");
152 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Unable to perform monotonicity analysis on the provided model type.");
157template<
typename ValueType>
160 std::shared_ptr<storm::models::ModelBase> result;
166 STORM_LOG_THROW(formulas.begin() != formulas.end(), storm::exceptions::NotSupportedException,
"Only one formula at the time supported.");
168 STORM_LOG_THROW(simplifier.
simplify(*(formulas[0])), storm::exceptions::UnexpectedException,
"Simplifying the model was not successfull.");
175 STORM_LOG_THROW(formulas.begin() != formulas.end(), storm::exceptions::NotSupportedException,
"Only one formula at the time supported.");
177 STORM_LOG_THROW(simplifier.
simplify(*(formulas[0])), storm::exceptions::UnexpectedException,
"Simplifying the model was not successfull.");
180 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Unable to perform monotonicity analysis on the provided model type.");
183 simplifyingWatch.
stop();
184 STORM_PRINT(
"\nTime for model simplification: " << simplifyingWatch <<
".\n\n");
185 result->printModelInformationToStream(std::cout);
189template<
typename ValueType>
202 STORM_LOG_THROW(!input.
properties.empty(), storm::exceptions::InvalidSettingsException,
"Simplification requires property to be specified.");
214 bisimulationSettings, regionSettings.isAssumeGraphPreservingSet());
218 if (parametricSettings.isLinearToSimpleEnabled()) {
225 if (parametricSettings.isBigStepEnabled()) {
230 result.
model = std::make_shared<storm::models::sparse::Dtmc<RationalFunction>>(bigStepResult.first);
234 bisimulationSettings, regionSettings.isAssumeGraphPreservingSet());
241 auto eliminationResult =
244 result.
model = eliminationResult.first;
246 result.
formulas = eliminationResult.second;
250 if (parametricSettings.transformContinuousModel() &&
254 result.
model = transformResult.first;
256 result.
formulas = transformResult.second;
260 if (monSettings.isSccEliminationSet()) {
269template<storm::dd::DdType DdType,
typename ValueType>
284 if (sparsePreprocessingResult.
changed) {
285 result.
model = sparsePreprocessingResult.
model;
292 bisimulationSettings, mpi);
299template<storm::dd::DdType DdType,
typename ValueType>
305 if (model->isSparseModel()) {
318template<
typename ValueType>
322 STORM_LOG_THROW(regions.size() == 1, storm::exceptions::NotSupportedException,
"Region verification is supported for a (single) region only.");
324 STORM_LOG_THROW(input.
properties.size() == 1, storm::exceptions::NotSupportedException,
"Region verification is supported for a (single) property only.");
325 auto const&
property = input.
properties.front();
330 auto engine = rvs.getRegionCheckEngine();
331 bool graphPreserving = regionSettings.isAssumeGraphPreservingSet();
334 "Selected region verification engine (--regionverif:engine) requires the assumption that the region is graph-preserving "
335 "(--assume-graph-preserving true).");
339 splittingStrategy.heuristic = rvs.getRegionSplittingHeuristic();
340 splittingStrategy.estimateKind = rvs.getRegionSplittingEstimateMethod();
341 if (rvs.isSplittingThresholdSet()) {
342 splittingStrategy.maxSplitDimensions = rvs.getSplittingThreshold();
346 std::set<typename storm::storage::ParameterRegion<ValueType>::VariableType> discreteVariables(parsedDiscreteVars.begin(), parsedDiscreteVars.end());
352 *(
property.getRawFormula()),
355 monotonicitySettings,
370template<
typename ValueType>
374 uint64_t monThresh = 0) {
375 STORM_LOG_ASSERT(!regions.empty(),
"Can not analyze an empty set of regions.");
376 STORM_LOG_THROW(regions.size() == 1, storm::exceptions::NotSupportedException,
"Region refinement is not supported for multiple initial regions.");
377 STORM_LOG_THROW(input.
properties.size() == 1, storm::exceptions::NotSupportedException,
"Region verification is supported for a (single) property only.");
378 auto const&
property = input.
properties.front();
386 std::optional<uint64_t> optionalDepthLimit;
387 if (partitionSettings.isDepthLimitSet()) {
388 optionalDepthLimit = partitionSettings.getDepthLimit();
394 auto engine = rvs.getRegionCheckEngine();
399 splittingStrategy.heuristic = rvs.getRegionSplittingHeuristic();
400 splittingStrategy.estimateKind = rvs.getRegionSplittingEstimateMethod();
401 if (rvs.isSplittingThresholdSet()) {
402 splittingStrategy.maxSplitDimensions = rvs.getSplittingThreshold();
405 bool graphPreserving = regionSettings.isAssumeGraphPreservingSet();
408 std::set<typename storm::storage::ParameterRegion<ValueType>::VariableType> discreteVariables(parsedDiscreteVars.begin(), parsedDiscreteVars.end());
411 if (monotonicitySettings.useMonotonicity) {
416 << (1.0 - partitionSettings.getCoverageThreshold()) * 100.0 <<
"% is covered."
417 << (partitionSettings.isDepthLimitSet() ?
" Depth limit is " + std::to_string(partitionSettings.getDepthLimit()) +
"." :
"") <<
'\n');
427 monotonicitySettings,
438 if (parametricSettings.exportResultToFile()) {
452 storm::exceptions::InvalidSettingsException,
"The selected engine is not supported for parametric models.");
453 STORM_LOG_THROW(parSettings.hasOperationModeBeenSet(), storm::exceptions::InvalidSettingsException,
"An operation mode must be selected with --mode.");
454 std::shared_ptr<storm::models::ModelBase> model;
455 if (!buildSettings.isNoBuildModelSet()) {
459 STORM_LOG_THROW(model, storm::exceptions::InvalidSettingsException,
"No input model.");
461 model->printModelInformationToStream(std::cout);
466 STORM_LOG_THROW(model->supportsParameters(), storm::exceptions::UnexpectedException,
"Expected a parametric model.");
467 STORM_LOG_THROW(model->isSparseModel() || model->getDdType().value() == DdType, storm::exceptions::UnexpectedException,
468 "Expected type of model representation.");
472 std::set<RationalFunctionVariable> omittedParameters;
476 if (preprocessingResult.changed) {
479 auto const currentParams =
481 for (
auto const& variable : previousParams) {
482 if (!currentParams.count(variable)) {
483 omittedParameters.insert(variable);
487 model = preprocessingResult.model;
489 if (preprocessingResult.formulas) {
490 std::vector<storm::jani::Property> newProperties;
491 for (
size_t i = 0; i < preprocessingResult.formulas.get().size(); ++i) {
492 auto formula = preprocessingResult.formulas.get().at(i);
495 newProperties.push_back(
storm::jani::Property(property.getName(), formula, property.getUndefinedConstants(), property.getComment()));
499 model->printModelInformationToStream(std::cout);
512 uint64_t monThresh = monSettings.getMonotonicityThreshold();
514 auto mode = parSettings.getOperationMode();
517 STORM_LOG_THROW(regions.empty(), storm::exceptions::InvalidSettingsException,
518 "Solution function computations cannot be restricted to specific regions.");
519 STORM_LOG_ERROR_COND(!regionSettings.isAssumeGraphPreservingSet(),
"Solution function computations assume graph preservation.");
521 if (model->isSparseModel()) {
528 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Monotonicity analysis is only supported on sparse models.");
532 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Feasibility analysis is only supported on sparse models.");
534 STORM_LOG_THROW(formulas.size() == 1, storm::exceptions::InvalidSettingsException,
535 "Feasibility analysis is only supported for single-objective properties.");
536 auto formula = formulas[0];
542 "Verification analysis is only supported for single-objective properties.");
543 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Verification analysis is only supported on sparse models.");
548 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
549 "Parameter space partitioning is only supported on sparse models.");
550 STORM_LOG_THROW(regions.size() == 1, storm::exceptions::InvalidSettingsException,
"Partitioning requires a (single) initial region.");
561 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Sampling analysis is currently only supported on sparse models.");
564 std::string samplesAsString = sampleSettings.getSamples();
566 if (!samplesAsString.empty()) {
568 samples.
exact = sampleSettings.isSampleExactSet();
570 if (!samples.
empty()) {
573 if (sampleSettings.isSampleDerivativeSet()) {
597 auto engine = coreSettings.getEngine();
600 "The selected DD library does not support parametric models. Switching to Sylvan...");
617int main(
const int argc,
const char** argv) {
621 STORM_LOG_ERROR(
"An exception caused Storm-pars to terminate. The message of the exception is: " << exception.
what());
623 }
catch (std::exception
const& exception) {
624 STORM_LOG_ERROR(
"An unexpected exception occurred and caused Storm-pars to terminate. The message of this exception is: " << exception.
what());
This class represents the base class of all exception classes.
virtual const char * what() const noexcept override
Retrieves the message associated with this exception.
This class represents a discrete-time Markov chain.
This class represents a Markov automaton.
This class represents a (discrete-time) Markov decision process.
Base class for all sparse models.
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Base class for all symbolic models.
void eliminateLoop(uint64_t row)
void eliminateState(storm::storage::sparse::state_type state, bool removeForwardTransitions)
A bit vector that is internally represented as a vector of 64-bit values.
void complement()
Negates all bits in the bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
The flexible sparse matrix is used during state elimination.
storm::storage::SparseMatrix< ValueType > createSparseMatrix()
Creates a sparse matrix from the flexible sparse matrix.
row_type & getRow(index_type)
Returns an object representing the given row.
A class that holds a possibly non-square matrix in the compressed row storage format.
This class represents the decomposition of a graph-like structure into its strongly connected compone...
A class that provides convenience operations to display run times.
void stop()
Stop stopwatch and add measured time to total time.
#define STORM_LOG_INFO(message)
#define STORM_LOG_WARN(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ERROR(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_ERROR_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
void exportRegionCheckResultToFile(std::unique_ptr< storm::modelchecker::CheckResult > const &checkResult, std::string const &filename, bool onlyConclusiveResults=false)
std::vector< storm::storage::ParameterRegion< ValueType > > parseRegions(std::string const &inputString, std::set< typename storm::storage::ParameterRegion< ValueType >::VariableType > const &consideredVariables)
storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > createTask(std::shared_ptr< const storm::logic::Formula > const &formula, bool onlyInitialStatesRelevant=false)
std::pair< std::shared_ptr< storm::models::sparse::Model< ValueType > >, std::vector< std::shared_ptr< storm::logic::Formula const > > > eliminateNonMarkovianChains(std::shared_ptr< storm::models::sparse::MarkovAutomaton< ValueType > > const &ma, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas, storm::transformer::EliminationLabelBehavior labelBehavior)
Eliminates chains of non-Markovian states from a given Markov Automaton.
std::shared_ptr< storm::models::sparse::Model< ValueType > > transformSymbolicToSparseModel(std::shared_ptr< storm::models::symbolic::Model< Type, ValueType > > const &symbolicModel, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas=std::vector< std::shared_ptr< storm::logic::Formula const > >())
Transforms the given symbolic model to a sparse model.
std::pair< std::shared_ptr< storm::models::sparse::Model< ValueType > >, std::vector< std::shared_ptr< storm::logic::Formula const > > > transformContinuousToDiscreteTimeSparseModel(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas)
Transforms the given continuous model to a discrete time model.
std::unique_ptr< storm::modelchecker::RegionRefinementCheckResult< ValueType > > checkAndRefineRegionWithSparseEngine(RefinementOptions< ValueType > settings, storm::storage::ParameterRegion< ValueType > const ®ion, std::optional< ValueType > const &coverageThreshold, std::optional< uint64_t > const &refinementDepthThreshold=std::nullopt, storm::modelchecker::RegionResultHypothesis hypothesis=storm::modelchecker::RegionResultHypothesis::Unknown, uint64_t monThresh=0)
Checks and iteratively refines the given region with the sparse engine.
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
storm::pars::modelchecker::MonotonicityOptions MonotonicitySetting
std::vector< typename storm::storage::ParameterRegion< ValueType >::VariableType > parseVariableList(std::string const &inputString, std::set< typename storm::storage::ParameterRegion< ValueType >::VariableType > const &consideredVariables)
bool verifyRegion(RefinementOptions< ValueType > settings, storm::storage::ParameterRegion< ValueType > const ®ion)
Verifies whether a region satisfies a property.
storm::storage::ParameterRegion< ValueType > createRegion(std::string const &inputString, std::set< typename storm::storage::ParameterRegion< ValueType >::VariableType > const &consideredVariables)
storm::pars::modelchecker::RegionRefinementOptions< ValueType > RefinementOptions
void exportModel(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, SymbolicInput const &input)
auto castAndApply(std::shared_ptr< storm::models::ModelBase > const &model, auto const &callback)
std::shared_ptr< storm::models::sparse::Model< ValueType > > preprocessSparseModelBisimulation(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, SymbolicInput const &input, storm::settings::modules::BisimulationSettings const &bisimulationSettings, bool graphPreserving=true)
SymbolicInput parseSymbolicInput()
int process(std::string const &name, std::string const &executableName, std::function< void(std::string const &, std::string const &)> initSettingsFunc, std::function< void(void)> processOptionsFunc, const int argc, const char **argv)
Processes the options and returns the exit code.
std::shared_ptr< storm::models::sparse::Model< ValueType > > preprocessSparseMarkovAutomaton(std::shared_ptr< storm::models::sparse::MarkovAutomaton< ValueType > > const &model)
std::pair< SymbolicInput, ModelProcessingInformation > preprocessSymbolicInput(SymbolicInput const &input)
std::shared_ptr< storm::models::ModelBase > buildModel(SymbolicInput const &input, storm::settings::modules::IOSettings const &ioSettings, ModelProcessingInformation const &mpi)
void printModelCheckingProperty(storm::jani::Property const &property)
std::shared_ptr< storm::models::Model< ExportValueType > > preprocessDdModelBisimulation(std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &model, SymbolicInput const &input, storm::settings::modules::BisimulationSettings const &bisimulationSettings, ModelProcessingInformation const &mpi)
@ RobustParameterLifting
Parameter lifting approach based on robust markov models instead of generating nondeterminism.
std::set< storm::RationalFunctionVariable > getAllParameters(Model< storm::RationalFunction > const &model)
Get all parameters (probability, rewards, and rates) occurring in the model.
void performFeasibility(std::shared_ptr< storm::models::sparse::Model< ValueType > > model, std::shared_ptr< storm::pars::FeasibilitySynthesisTask const > const &task, boost::optional< std::set< RationalFunctionVariable > > omittedParameters, storm::api::MonotonicitySetting monotonicitySettings)
std::shared_ptr< storm::models::ModelBase > simplifyModel(std::shared_ptr< storm::models::ModelBase > const &model, cli::SymbolicInput const &input)
void parameterSpacePartitioningWithSparseEngine(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, std::vector< storm::storage::ParameterRegion< ValueType > > const ®ions, storm::api::MonotonicitySetting monotonicitySettings=storm::api::MonotonicitySetting(), uint64_t monThresh=0)
void analyzeMonotonicity(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, std::vector< storm::storage::ParameterRegion< ValueType > > const ®ions)
PreprocessResult preprocessSparseModel(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, storm::cli::ModelProcessingInformation const &mpi)
std::shared_ptr< storm::models::ModelBase > eliminateScc(std::shared_ptr< storm::models::ModelBase > const &model)
PreprocessResult preprocessDdModel(std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &model, cli::SymbolicInput const &input, storm::cli::ModelProcessingInformation const &mpi)
SampleInformation< ValueType > parseSamples(std::shared_ptr< storm::models::ModelBase > const &model, std::string const &sampleString, bool graphPreserving)
void verifyPropertiesAtSamplePointsWithSparseEngineDerivatives(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, SampleInformation< ValueType > const &samples)
void verifyPropertiesAtSamplePointsWithSparseEngine(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, SampleInformation< ValueType > const &samples)
void printInitialStatesResult(std::unique_ptr< storm::modelchecker::CheckResult > const &result, storm::utility::Stopwatch *watch, const storm::utility::parametric::Valuation< ValueType > *valuation)
void computeSolutionFunctionsWithSparseEngine(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, storm::cli::SymbolicInput const &input)
void processInput(cli::SymbolicInput &&input, storm::cli::ModelProcessingInformation const &mpi)
void computeSolutionFunctionsWithSymbolicEngine(std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &model, storm::cli::SymbolicInput const &input)
PreprocessResult preprocessModel(std::shared_ptr< storm::models::ModelBase > const &model, cli::SymbolicInput const &input, storm::cli::ModelProcessingInformation const &mpi)
void verifyRegionWithSparseEngine(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, std::vector< storm::storage::ParameterRegion< ValueType > > const ®ions, storm::api::MonotonicitySetting monotonicitySettings=storm::api::MonotonicitySetting())
std::vector< storm::storage::ParameterRegion< ValueType > > parseRegions(std::shared_ptr< storm::models::ModelBase > const &model)
std::shared_ptr< FeasibilitySynthesisTask const > createFeasibilitySynthesisTaskFromSettings(std::shared_ptr< storm::logic::Formula const > const &formula, std::vector< storm::storage::ParameterRegion< storm::RationalFunction > > const ®ions)
void initializeParsSettings(std::string const &name, std::string const &executableName)
SettingsType const & getModule()
Get module.
TargetType convertNumber(SourceType const &number)
carl::RationalFunction< Polynomial, true > RationalFunction
#define STORM_PRINT_AND_LOG(message)
#define STORM_PRINT(message)
Define the macros that print information to stdout and optionally also log it.
int main(const int argc, const char **argv)
Main entry point of the executable storm-pars.
boost::optional< std::vector< std::shared_ptr< storm::logic::Formula const > > > formulas
PreprocessResult(std::shared_ptr< storm::models::ModelBase > const &model, bool changed)
std::shared_ptr< storm::models::ModelBase > model
bool useOnlyGlobalMonotonicity