72 std::shared_ptr<storm::models::ModelBase>
model;
73 boost::optional<std::vector<std::shared_ptr<storm::logic::Formula const>>>
formulas;
76template<
typename ValueType>
77std::vector<storm::storage::ParameterRegion<ValueType>>
parseRegions(std::shared_ptr<storm::models::ModelBase>
const& model) {
78 std::vector<storm::storage::ParameterRegion<ValueType>> result;
80 if (regionSettings.isRegionSet()) {
81 result = storm::api::parseRegions<ValueType>(regionSettings.getRegionString(), *model);
82 }
else if (regionSettings.isRegionBoundSet()) {
83 result = storm::api::createRegion<ValueType>(regionSettings.getRegionBoundString(), *model);
88template<
typename ValueType>
89std::shared_ptr<storm::models::ModelBase>
eliminateScc(std::shared_ptr<storm::models::ModelBase>
const& model) {
91 std::shared_ptr<storm::models::ModelBase> result;
96 auto backwardsTransitionMatrix = matrix.transpose();
103 for (
size_t i = 0; i < decomposition.size(); ++i) {
104 auto scc = decomposition.getBlock(i);
105 if (scc.size() > 1) {
106 auto statesScc = scc.getStates();
107 std::vector<uint_fast64_t> entryStates;
108 for (
auto state : statesScc) {
109 auto row = backwardsTransitionMatrix.getRow(state);
111 for (
auto backState : row) {
112 if (!scc.containsState(backState.getColumn())) {
117 entryStates.push_back(state);
118 selfLoopStates.
set(state);
120 selectedStates.
set(state);
124 if (entryStates.size() != 1) {
125 STORM_LOG_THROW(entryStates.size() > 1, storm::exceptions::NotImplementedException,
126 "state elimination not implemented for scc with more than 1 entry points");
133 auto actionRewards = std::vector<ValueType>(matrix.getRowCount(), storm::utility::zero<ValueType>());
136 for (
auto state : selectedStates) {
139 for (
auto state : selfLoopStates) {
140 auto row = flexibleMatrix.
getRow(state);
144 auto keptRows = matrix.getRowFilter(selectedStates);
147 result = std::make_shared<storm::models::sparse::Dtmc<ValueType>>(std::move(newTransitionMatrix),
148 sparseModel->getStateLabeling().getSubLabeling(selectedStates));
150 eliminationWatch.
stop();
151 STORM_PRINT(
"\nTime for scc elimination: " << eliminationWatch <<
".\n\n");
152 result->printModelInformationToStream(std::cout);
155 "Unable to perform SCC elimination for monotonicity analysis on MDP: Not mplemented");
157 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Unable to perform monotonicity analysis on the provided model type.");
162template<
typename ValueType>
165 std::shared_ptr<storm::models::ModelBase> result;
171 STORM_LOG_THROW(formulas.begin() != formulas.end(), storm::exceptions::NotSupportedException,
"Only one formula at the time supported");
173 if (!simplifier.
simplify(*(formulas[0]))) {
174 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Simplifying the model was not successfull.");
182 STORM_LOG_THROW(formulas.begin() != formulas.end(), storm::exceptions::NotSupportedException,
"Only one formula at the time supported");
184 if (!simplifier.
simplify(*(formulas[0]))) {
185 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Simplifying the model was not successfull.");
189 STORM_LOG_THROW(
false, storm::exceptions::InvalidOperationException,
"Unable to perform monotonicity analysis on the provided model type.");
192 simplifyingWatch.
stop();
193 STORM_PRINT(
"\nTime for model simplification: " << simplifyingWatch <<
".\n\n");
194 result->printModelInformationToStream(std::cout);
198template<
typename ValueType>
210 STORM_LOG_THROW(!input.
properties.empty(), storm::exceptions::InvalidSettingsException,
"Simplification requires property to be specified");
211 result.
model = storm::pars::simplifyModel<ValueType>(result.
model, input);
226 if (parametricSettings.isLinearToSimpleEnabled()) {
233 if (parametricSettings.isTimeTravellingEnabled()) {
237 result.
model = std::make_shared<storm::models::sparse::Dtmc<RationalFunction>>(
244 auto eliminationResult =
247 result.
model = eliminationResult.first;
249 result.
formulas = eliminationResult.second;
253 if (parametricSettings.transformContinuousModel() &&
257 result.
model = transformResult.first;
259 result.
formulas = transformResult.second;
263 if (monSettings.isSccEliminationSet()) {
265 result.
model = storm::pars::eliminateScc<ValueType>(result.
model);
272template<storm::dd::DdType DdType,
typename ValueType>
287 if (sparsePreprocessingResult.
changed) {
288 result.
model = sparsePreprocessingResult.
model;
295 bisimulationSettings, mpi);
302template<storm::dd::DdType DdType,
typename ValueType>
308 if (model->isSparseModel()) {
321template<
typename ValueType>
325 STORM_LOG_THROW(regions.size() == 1, storm::exceptions::NotSupportedException,
"Region verification is supported for a (single) region only.");
327 STORM_LOG_THROW(input.
properties.size() == 1, storm::exceptions::NotSupportedException,
"Region verification is supported for a (single) property only.");
328 auto const&
property = input.
properties.front();
331 auto engine = rvs.getRegionCheckEngine();
332 bool generateSplitEstimates = rvs.isSplittingThresholdSet();
333 std::optional<uint64_t> maxSplitsPerStep = generateSplitEstimates ? std::make_optional(rvs.getSplittingThreshold()) : std::nullopt;
335 if (storm::api::verifyRegion<ValueType>(model, *(property.getRawFormula()), region, engine, monotonicitySettings, generateSplitEstimates,
344template<
typename ValueType>
348 uint64_t monThresh = 0) {
349 STORM_LOG_ASSERT(!regions.empty(),
"Can not analyze an empty set of regions.");
350 STORM_LOG_THROW(regions.size() == 1, storm::exceptions::NotSupportedException,
"Region refinement is not supported for multiple initial regions.");
351 STORM_LOG_THROW(input.
properties.size() == 1, storm::exceptions::NotSupportedException,
"Region verification is supported for a (single) property only.");
352 auto const&
property = input.
properties.front();
358 ValueType refinementThreshold = storm::utility::convertNumber<ValueType>(partitionSettings.getCoverageThreshold());
359 boost::optional<uint64_t> optionalDepthLimit;
360 if (partitionSettings.isDepthLimitSet()) {
361 optionalDepthLimit = partitionSettings.getDepthLimit();
367 auto engine = rvs.getRegionCheckEngine();
369 if (monotonicitySettings.useMonotonicity) {
374 << (1.0 - partitionSettings.getCoverageThreshold()) * 100.0 <<
"% is covered."
375 << (partitionSettings.isDepthLimitSet() ?
" Depth limit is " + std::to_string(partitionSettings.getDepthLimit()) +
"." :
"") <<
'\n');
379 std::unique_ptr<storm::modelchecker::CheckResult> result = storm::api::checkAndRefineRegionWithSparseEngine<ValueType>(
380 model, storm::api::createTask<ValueType>((property.getRawFormula()),
true), regions.front(), engine, refinementThreshold, optionalDepthLimit,
383 printInitialStatesResult<ValueType>(result, &watch);
385 if (parametricSettings.exportResultToFile()) {
386 storm::api::exportRegionCheckResultToFile<ValueType>(result, parametricSettings.exportResultPath());
390template<storm::dd::DdType DdType,
typename ValueType>
399 storm::exceptions::InvalidSettingsException,
"The selected engine is not supported for parametric models.");
400 STORM_LOG_THROW(parSettings.hasOperationModeBeenSet(), storm::exceptions::InvalidSettingsException,
"An operation mode must be selected with --mode");
401 std::shared_ptr<storm::models::ModelBase> model;
402 if (!buildSettings.isNoBuildModelSet()) {
403 model = storm::cli::buildModel<DdType, ValueType>(input, ioSettings, mpi);
406 STORM_LOG_THROW(model, storm::exceptions::InvalidSettingsException,
"No input model.");
408 model->printModelInformationToStream(std::cout);
413 std::set<RationalFunctionVariable> omittedParameters;
416 auto preprocessingResult = storm::pars::preprocessModel<DdType, ValueType>(model, input, mpi);
417 if (preprocessingResult.changed) {
420 auto const currentParams =
422 for (
auto const& variable : previousParams) {
423 if (!currentParams.count(variable)) {
424 omittedParameters.insert(variable);
428 model = preprocessingResult.model;
430 if (preprocessingResult.formulas) {
431 std::vector<storm::jani::Property> newProperties;
432 for (
size_t i = 0; i < preprocessingResult.formulas.get().size(); ++i) {
433 auto formula = preprocessingResult.formulas.get().at(i);
436 newProperties.push_back(
storm::jani::Property(property.getName(), formula, property.getUndefinedConstants(), property.getComment()));
440 model->printModelInformationToStream(std::cout);
444 std::vector<storm::storage::ParameterRegion<ValueType>> regions = parseRegions<ValueType>(model);
448 storm::cli::exportModel<DdType, ValueType>(model, input);
453 uint64_t monThresh = monSettings.getMonotonicityThreshold();
455 auto mode = parSettings.getOperationMode();
458 STORM_LOG_THROW(regions.empty(), storm::exceptions::InvalidSettingsException,
459 "Solution function computations cannot be restricted to specific regions");
461 if (model->isSparseModel()) {
468 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Monotonicity analysis is only supported on sparse models.");
472 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Feasibility analysis is only supported on sparse models.");
474 STORM_LOG_THROW(formulas.size() == 1, storm::exceptions::InvalidSettingsException,
475 "Feasibility analysis is only supported for single-objective properties.");
476 auto formula = formulas[0];
482 "Verification analysis is only supported for single-objective properties.");
483 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Verification analysis is only supported on sparse models.");
488 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
489 "Parameter space partitioning is only supported on sparse models.");
490 STORM_LOG_THROW(regions.size() == 1, storm::exceptions::InvalidSettingsException,
"Partitioning requires a (single) initial region.");
501 STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::InvalidSettingsException,
"Sampling analysis is currently only supported on sparse models.");
504 std::string samplesAsString = sampleSettings.getSamples();
506 if (!samplesAsString.empty()) {
507 samples = parseSamples<ValueType>(model, samplesAsString, sampleSettings.isSamplesAreGraphPreservingSet());
508 samples.
exact = sampleSettings.isSampleExactSet();
510 if (!samples.
empty()) {
527 auto engine = coreSettings.getEngine();
530 "The selected DD library does not support parametric models. Switching to Sylvan...");
536 processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, storm::RationalFunction>(symbolicInput, mpi);
544int main(
const int argc,
const char** argv) {
548 STORM_LOG_ERROR(
"An exception caused Storm-pars to terminate. The message of the exception is: " << exception.
what());
550 }
catch (std::exception
const& exception) {
551 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(uint_fast64_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_THROW(cond, exception, message)
#define STORM_PRINT_AND_LOG(message)
#define STORM_PRINT(message)
Define the macros that print information and optionally also log it.
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::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
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)
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)
std::set< storm::RationalFunctionVariable > getAllParameters(Model< storm::RationalFunction > const &model)
Get all parameters (probability, rewards, and rates) occurring in the model.
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)
void processInputWithValueTypeAndDdlib(cli::SymbolicInput &input, storm::cli::ModelProcessingInformation const &mpi)
void computeSolutionFunctionsWithSymbolicEngine(std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &model, cli::SymbolicInput const &input)
PreprocessResult preprocessDdModel(std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &model, cli::SymbolicInput const &input, storm::cli::ModelProcessingInformation const &mpi)
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 computeSolutionFunctionsWithSparseEngine(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, cli::SymbolicInput const &input)
void initializeParsSettings(std::string const &name, std::string const &executableName)
SettingsType const & getModule()
Get module.
int main(const int argc, const char **argv)
Main entry point of the executable storm-pars.
bool useOnlyGlobalMonotonicity
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