58 std::shared_ptr<storm::models::ModelBase>
model;
59 boost::optional<std::vector<std::shared_ptr<storm::logic::Formula const>>>
formulas;
62template<
typename ValueType>
63std::vector<storm::storage::ParameterRegion<ValueType>>
parseRegions(std::shared_ptr<storm::models::ModelBase>
const& model) {
64 std::vector<storm::storage::ParameterRegion<ValueType>> result;
66 if (regionSettings.isRegionSet()) {
68 }
else if (regionSettings.isRegionBoundSet()) {
74template<
typename ValueType>
75std::shared_ptr<storm::models::ModelBase>
eliminateScc(std::shared_ptr<storm::models::ModelBase>
const& model) {
77 std::shared_ptr<storm::models::ModelBase> result;
82 auto backwardsTransitionMatrix = matrix.transpose();
89 for (
size_t i = 0; i < decomposition.size(); ++i) {
90 auto scc = decomposition.getBlock(i);
92 auto statesScc = scc.getStates();
93 std::vector<uint_fast64_t> entryStates;
94 for (
auto state : statesScc) {
95 auto row = backwardsTransitionMatrix.getRow(state);
97 for (
auto backState : row) {
98 if (!scc.containsState(backState.getColumn())) {
103 entryStates.push_back(state);
104 selfLoopStates.
set(state);
106 selectedStates.
set(state);
110 if (entryStates.size() != 1) {
111 STORM_LOG_THROW(entryStates.size() > 1, storm::exceptions::NotImplementedException,
112 "State elimination not implemented for scc with more than 1 entry points.");
122 for (
auto state : selectedStates) {
125 for (
auto state : selfLoopStates) {
126 auto row = flexibleMatrix.
getRow(state);
130 auto keptRows = matrix.getRowFilter(selectedStates);
133 result = std::make_shared<storm::models::sparse::Dtmc<ValueType>>(std::move(newTransitionMatrix),
134 sparseModel->getStateLabeling().getSubLabeling(selectedStates));
136 eliminationWatch.
stop();
137 STORM_PRINT(
"\nTime for scc elimination: " << eliminationWatch <<
".\n\n");
138 result->printModelInformationToStream(std::cout);
141 "Unable to perform SCC elimination for monotonicity analysis on MDP: Not implemented.");
143 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Unable to perform monotonicity analysis on the provided model type.");
148template<
typename ValueType>
151 std::shared_ptr<storm::models::ModelBase> result;
157 STORM_LOG_THROW(formulas.begin() != formulas.end(), storm::exceptions::NotSupportedException,
"Only one formula at the time supported.");
159 STORM_LOG_THROW(simplifier.
simplify(*(formulas[0])), storm::exceptions::UnexpectedException,
"Simplifying the model was not successfull.");
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.");
171 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Unable to perform monotonicity analysis on the provided model type.");
174 simplifyingWatch.
stop();
175 STORM_PRINT(
"\nTime for model simplification: " << simplifyingWatch <<
".\n\n");
176 result->printModelInformationToStream(std::cout);
180template<
typename ValueType>
192 STORM_LOG_THROW(!input.
properties.empty(), storm::exceptions::InvalidSettingsException,
"Simplification requires property to be specified.");
208 if (parametricSettings.isLinearToSimpleEnabled()) {
215 if (parametricSettings.isBigStepEnabled()) {
220 result.
model = std::make_shared<storm::models::sparse::Dtmc<RationalFunction>>(bigStepResult.first);
224 bisimulationSettings);
231 auto eliminationResult =
234 result.
model = eliminationResult.first;
236 result.
formulas = eliminationResult.second;
240 if (parametricSettings.transformContinuousModel() &&
244 result.
model = transformResult.first;
246 result.
formulas = transformResult.second;
250 if (monSettings.isSccEliminationSet()) {
259template<storm::dd::DdType DdType,
typename ValueType>
274 if (sparsePreprocessingResult.
changed) {
275 result.
model = sparsePreprocessingResult.
model;
282 bisimulationSettings, mpi);
289template<storm::dd::DdType DdType,
typename ValueType>
295 if (model->isSparseModel()) {
308template<
typename ValueType>
312 STORM_LOG_THROW(regions.size() == 1, storm::exceptions::NotSupportedException,
"Region verification is supported for a (single) region only.");
314 STORM_LOG_THROW(input.
properties.size() == 1, storm::exceptions::NotSupportedException,
"Region verification is supported for a (single) property only.");
315 auto const&
property = input.
properties.front();
320 auto engine = rvs.getRegionCheckEngine();
321 auto const graphPreservationStatus =
326 splittingStrategy.heuristic = rvs.getRegionSplittingHeuristic();
327 splittingStrategy.estimateKind = rvs.getRegionSplittingEstimateMethod();
328 if (rvs.isSplittingThresholdSet()) {
329 splittingStrategy.maxSplitDimensions = rvs.getSplittingThreshold();
333 std::set<typename storm::storage::ParameterRegion<ValueType>::VariableType> discreteVariables(parsedDiscreteVars.begin(), parsedDiscreteVars.end());
339 *(
property.getRawFormula()),
342 monotonicitySettings,
345 graphPreservationStatus,
357template<
typename ValueType>
361 uint64_t monThresh = 0) {
362 STORM_LOG_ASSERT(!regions.empty(),
"Can not analyze an empty set of regions.");
363 STORM_LOG_THROW(regions.size() == 1, storm::exceptions::NotSupportedException,
"Region refinement is not supported for multiple initial regions.");
364 STORM_LOG_THROW(input.
properties.size() == 1, storm::exceptions::NotSupportedException,
"Region verification is supported for a (single) property only.");
365 auto const&
property = input.
properties.front();
373 std::optional<uint64_t> optionalDepthLimit;
374 if (partitionSettings.isDepthLimitSet()) {
375 optionalDepthLimit = partitionSettings.getDepthLimit();
381 auto engine = rvs.getRegionCheckEngine();
386 splittingStrategy.heuristic = rvs.getRegionSplittingHeuristic();
387 splittingStrategy.estimateKind = rvs.getRegionSplittingEstimateMethod();
388 if (rvs.isSplittingThresholdSet()) {
389 splittingStrategy.maxSplitDimensions = rvs.getSplittingThreshold();
392 auto const graphPreservationStatus =
396 std::set<typename storm::storage::ParameterRegion<ValueType>::VariableType> discreteVariables(parsedDiscreteVars.begin(), parsedDiscreteVars.end());
399 if (monotonicitySettings.useMonotonicity) {
404 << (1.0 - partitionSettings.getCoverageThreshold()) * 100.0 <<
"% is covered."
405 << (partitionSettings.isDepthLimitSet() ?
" Depth limit is " + std::to_string(partitionSettings.getDepthLimit()) +
"." :
"") <<
'\n');
415 monotonicitySettings,
418 graphPreservationStatus,
426 if (parametricSettings.exportResultToFile()) {
440 storm::exceptions::InvalidSettingsException,
"The selected engine is not supported for parametric models.");
441 STORM_LOG_THROW(parSettings.hasOperationModeBeenSet(), storm::exceptions::InvalidSettingsException,
"An operation mode must be selected with --mode.");
442 std::shared_ptr<storm::models::ModelBase> model;
443 if (!buildSettings.isNoBuildModelSet()) {
447 STORM_LOG_THROW(model, storm::exceptions::InvalidSettingsException,
"No input model.");
449 model->printModelInformationToStream(std::cout);
454 STORM_LOG_THROW(model->supportsParameters(), storm::exceptions::UnexpectedException,
"Expected a parametric model.");
455 STORM_LOG_THROW(model->isSparseModel() || model->getDdType().value() == DdType, storm::exceptions::UnexpectedException,
456 "Expected type of model representation.");
460 std::set<RationalFunctionVariable> omittedParameters;
464 if (preprocessingResult.changed) {
467 auto const currentParams =
469 for (
auto const& variable : previousParams) {
470 if (!currentParams.count(variable)) {
471 omittedParameters.insert(variable);
475 model = preprocessingResult.model;
477 if (preprocessingResult.formulas) {
478 std::vector<storm::jani::Property> newProperties;
479 for (
size_t i = 0; i < preprocessingResult.formulas.get().size(); ++i) {
480 auto formula = preprocessingResult.formulas.get().at(i);
483 newProperties.push_back(
storm::jani::Property(property.getName(), formula, property.getUndefinedConstants(), property.getComment()));
487 model->printModelInformationToStream(std::cout);
500 uint64_t monThresh = monSettings.getMonotonicityThreshold();
502 auto mode = parSettings.getOperationMode();
505 STORM_LOG_THROW(regions.empty(), storm::exceptions::InvalidSettingsException,
506 "Solution function computations cannot be restricted to specific regions.");
507 STORM_LOG_ERROR_COND(!regionSettings.isAssumeGraphPreservingSet(),
"Solution function computations assume graph preservation.");
509 if (model->isSparseModel()) {
516 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Monotonicity analysis is only supported on sparse models.");
520 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Feasibility analysis is only supported on sparse models.");
522 STORM_LOG_THROW(formulas.size() == 1, storm::exceptions::InvalidSettingsException,
523 "Feasibility analysis is only supported for single-objective properties.");
524 auto formula = formulas[0];
530 "Verification analysis is only supported for single-objective properties.");
531 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Verification analysis is only supported on sparse models.");
536 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
537 "Parameter space partitioning is only supported on sparse models.");
538 STORM_LOG_THROW(regions.size() == 1, storm::exceptions::InvalidSettingsException,
"Partitioning requires a (single) initial region.");
546 monotonicitySettings, monThresh);
549 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Sampling analysis is currently only supported on sparse models.");
552 std::string samplesAsString = sampleSettings.getSamples();
554 if (!samplesAsString.empty()) {
556 samples.
exact = sampleSettings.isSampleExactSet();
558 if (!samples.
empty()) {
561 if (sampleSettings.isSampleDerivativeSet()) {
586 auto engine = coreSettings.getEngine();
589 "The selected DD library does not support parametric models. Switching to Sylvan...");
606int main(
const int argc,
const char** argv) {
610 STORM_LOG_ERROR(
"An exception caused Storm-pars to terminate. The message of the exception is: " << exception.
what());
612 }
catch (std::exception
const& exception) {
613 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_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)
std::unique_ptr< storm::modelchecker::RegionRefinementCheckResult< ValueType > > checkAndRefineRegionWithSparseEngine(Environment const &env, 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.
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.
bool verifyRegion(Environment const &env, RefinementOptions< ValueType > settings, storm::storage::ParameterRegion< ValueType > const ®ion)
Verifies whether a region satisfies a property.
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)
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)
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)
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)
@ 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 parameterSpacePartitioningWithSparseEngine(storm::Environment const &env, 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)
std::shared_ptr< storm::models::ModelBase > simplifyModel(std::shared_ptr< storm::models::ModelBase > const &model, cli::SymbolicInput const &input)
PreprocessResult preprocessSparseModel(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, storm::cli::ModelProcessingInformation const &mpi)
void verifyRegionWithSparseEngine(storm::Environment const &env, 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::shared_ptr< storm::models::ModelBase > eliminateScc(std::shared_ptr< storm::models::ModelBase > const &model)
void verifyPropertiesAtSamplePointsWithSparseEngineDerivatives(storm::Environment const &env, std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, SampleInformation< ValueType > const &samples)
void computeSolutionFunctionsWithSparseEngine(storm::Environment const &env, std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, storm::cli::SymbolicInput const &input)
storm::pars::analysis::GraphPreservationStatus establishGraphPreservation(std::shared_ptr< storm::models::ModelBase > const &model, std::vector< storm::storage::ParameterRegion< ValueType > > const ®ions, bool graphPreservationRequired)
Determines to what extent the regions are known to be well-defined and graph-preserving.
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 analyzeMonotonicity(storm::Environment const &env, std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, std::vector< storm::storage::ParameterRegion< ValueType > > const ®ions)
void computeSolutionFunctionsWithSymbolicEngine(storm::Environment const &env, std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &model, storm::cli::SymbolicInput const &input)
void printInitialStatesResult(std::unique_ptr< storm::modelchecker::CheckResult > const &result, storm::utility::Stopwatch *watch, const storm::utility::parametric::Valuation< ValueType > *valuation)
void verifyPropertiesAtSamplePointsWithSparseEngine(storm::Environment const &env, std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input, SampleInformation< ValueType > const &samples)
void processInput(cli::SymbolicInput &&input, storm::cli::ModelProcessingInformation const &mpi)
void performFeasibility(storm::Environment const &env, 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)
PreprocessResult preprocessModel(std::shared_ptr< storm::models::ModelBase > const &model, cli::SymbolicInput const &input, storm::cli::ModelProcessingInformation const &mpi)
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