Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
model-handling.h
Go to the documentation of this file.
1#pragma once
2
3#include <boost/algorithm/string/join.hpp>
4#include <type_traits>
5
11#include "storm/api/storm.h"
17#include "storm/io/file.h"
47
48namespace storm {
49namespace cli {
50
52 // The symbolic model description.
53 boost::optional<storm::storage::SymbolicModelDescription> model;
54
55 // The original properties to check.
56 std::vector<storm::jani::Property> properties;
57
58 // The preprocessed properties to check (in case they needed amendment).
59 boost::optional<std::vector<storm::jani::Property>> preprocessedProperties;
60};
61
64 if (ioSettings.isPrismOrJaniInputSet()) {
65 storm::utility::Stopwatch modelParsingWatch(true);
66 if (ioSettings.isPrismInputSet()) {
67 input.model =
68 storm::api::parseProgram(ioSettings.getPrismInputFilename(), buildSettings.isPrismCompatibilityEnabled(), !buildSettings.isNoSimplifySet());
69 } else {
70 boost::optional<std::vector<std::string>> propertyFilter;
71 if (ioSettings.isJaniPropertiesSet()) {
72 if (ioSettings.areJaniPropertiesSelected()) {
73 propertyFilter = ioSettings.getSelectedJaniProperties();
74 } else {
75 propertyFilter = boost::none;
76 }
77 } else {
78 propertyFilter = std::vector<std::string>();
79 }
80 auto janiInput = storm::api::parseJaniModel(ioSettings.getJaniInputFilename(), propertyFilter);
81 input.model = std::move(janiInput.first);
82 if (ioSettings.isJaniPropertiesSet()) {
83 input.properties = std::move(janiInput.second);
84 }
85 }
86 modelParsingWatch.stop();
87 STORM_PRINT("Time for model input parsing: " << modelParsingWatch << ".\n\n");
88 }
89}
90
92 boost::optional<std::set<std::string>> const& propertyFilter) {
93 if (ioSettings.isPropertySet()) {
94 std::vector<storm::jani::Property> newProperties;
95 if (input.model) {
96 newProperties = storm::api::parsePropertiesForSymbolicModelDescription(ioSettings.getProperty(), input.model.get(), propertyFilter);
97 } else {
98 newProperties = storm::api::parseProperties(ioSettings.getProperty(), propertyFilter);
99 }
100
101 input.properties.insert(input.properties.end(), newProperties.begin(), newProperties.end());
102 }
103}
104
106 // Parse the model input
107 SymbolicInput input;
108 storm::storage::QvbsBenchmark benchmark(ioSettings.getQvbsModelName());
109 STORM_PRINT_AND_LOG(benchmark.getInfo(ioSettings.getQvbsInstanceIndex(), ioSettings.getQvbsPropertyFilter()));
110 storm::utility::Stopwatch modelParsingWatch(true);
111 auto janiInput = storm::api::parseJaniModel(benchmark.getJaniFile(ioSettings.getQvbsInstanceIndex()), ioSettings.getQvbsPropertyFilter());
112 input.model = std::move(janiInput.first);
113 input.properties = std::move(janiInput.second);
114 modelParsingWatch.stop();
115 STORM_PRINT("Time for model input parsing: " << modelParsingWatch << ".\n\n");
116
117 // Parse additional properties
118 boost::optional<std::set<std::string>> propertyFilter = storm::api::parsePropertyFilter(ioSettings.getPropertyFilter());
119 parseProperties(ioSettings, input, propertyFilter);
120
121 // Substitute constant definitions
122 auto constantDefinitions = input.model.get().parseConstantDefinitions(benchmark.getConstantDefinition(ioSettings.getQvbsInstanceIndex()));
123 input.model = input.model.get().preprocess(constantDefinitions);
124 if (!input.properties.empty()) {
125 input.properties = storm::api::substituteConstantsInProperties(input.properties, constantDefinitions);
126 }
127
128 return input;
129}
130
133 if (ioSettings.isQvbsInputSet()) {
134 return parseSymbolicInputQvbs(ioSettings);
135 } else {
136 // Parse the property filter, if any is given.
137 boost::optional<std::set<std::string>> propertyFilter = storm::api::parsePropertyFilter(ioSettings.getPropertyFilter());
138
139 SymbolicInput input;
140 parseSymbolicModelDescription(ioSettings, input);
141 parseProperties(ioSettings, input, propertyFilter);
142 return input;
143 }
144}
145
147 // The engine to use
149
150 // If set, bisimulation will be applied.
152
153 // If set, a transformation to Jani will be enforced
155
156 // Which data type is to be used for numbers ...
158 ValueType buildValueType; // ... during model building
159 ValueType verificationValueType; // ... during model verification
160
161 // The Dd library to be used
163
164 // The environment used during model checking.
165 // It is constructed explicitly in getModelProcessingInformation(), once the CLI settings are known to be finalized.
167
168 // A flag which is set to true, if the settings were detected to be compatible.
169 // If this is false, it could be that the query can not be handled.
171};
172
175
176 STORM_LOG_THROW(input.model.is_initialized(), storm::exceptions::InvalidArgumentException, "Automatic engine requires a JANI input model.");
177 STORM_LOG_THROW(input.model->isJaniModel(), storm::exceptions::InvalidArgumentException, "Automatic engine requires a JANI input model.");
178 std::vector<storm::jani::Property> const& properties =
179 input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties;
180 STORM_LOG_THROW(!properties.empty(), storm::exceptions::InvalidArgumentException, "Automatic engine requires a property.");
181 STORM_LOG_WARN_COND(properties.size() == 1,
182 "Automatic engine does not support decisions based on multiple properties. Only the first property will be considered.");
183
185 if (hints.isNumberStatesSet()) {
186 as.predict(input.model->asJaniModel(), properties.front(), hints.getNumberStates());
187 } else {
188 as.predict(input.model->asJaniModel(), properties.front());
189 }
190
191 mpi.engine = as.getEngine();
192 if (as.enableBisimulation()) {
193 mpi.applyBisimulation = true;
194 }
197 }
198 STORM_PRINT_AND_LOG("Automatic engine picked the following settings: \n"
199 << "\tengine=" << mpi.engine << std::boolalpha << "\t bisimulation=" << mpi.applyBisimulation
200 << "\t exact=" << (mpi.verificationValueType != ModelProcessingInformation::ValueType::FinitePrecision) << std::noboolalpha << '\n');
201}
202
209 std::shared_ptr<SymbolicInput> const& transformedJaniInput = nullptr) {
216
217 // Set the engine.
218 mpi.engine = coreSettings.getEngine();
219
220 // Set whether bisimulation is to be used.
221 mpi.applyBisimulation = generalSettings.isBisimulationSet();
222
223 // Set the value type used for numeric values
224 if (generalSettings.isParametricSet()) {
226 } else if (generalSettings.isExactSet()) {
228 } else {
230 }
231 auto originalVerificationValueType = mpi.verificationValueType;
232
233 // Since the remaining settings could depend on the ones above, we need apply the automatic engine now.
234 bool useAutomatic = input.model.is_initialized() && mpi.engine == storm::utility::Engine::Automatic;
235 if (useAutomatic) {
236 if (input.model->isJaniModel()) {
237 // This can potentially overwrite the settings above, but will not overwrite settings that were explicitly set by the user (e.g. we will not disable
238 // bisimulation or disable exact arithmetic)
240 } else {
241 // Transform Prism to jani first
242 STORM_LOG_ASSERT(input.model->isPrismProgram(), "Unexpected type of input.");
243 SymbolicInput janiInput;
244 janiInput.properties = input.properties;
245 storm::prism::Program const& prog = input.model.get().asPrismProgram();
246 auto modelAndProperties = prog.toJani(input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties);
247 janiInput.model = modelAndProperties.first;
248 if (!modelAndProperties.second.empty()) {
249 janiInput.preprocessedProperties = std::move(modelAndProperties.second);
250 }
251 // This can potentially overwrite the settings above, but will not overwrite settings that were explicitly set by the user (e.g. we will not disable
252 // bisimulation or disable exact arithmetic)
254 if (transformedJaniInput) {
255 // We cache the transformation result.
256 *transformedJaniInput = std::move(janiInput);
257 }
258 }
259 }
260
261 // Check whether these settings are compatible with the provided input.
262 if (input.model) {
263 auto checkCompatibleSettings = [&mpi, &input] {
264 switch (mpi.verificationValueType) {
267 mpi.engine, input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties, input.model.get());
270 mpi.engine, input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties, input.model.get());
271 break;
274 mpi.engine, input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties, input.model.get());
275 }
276 return false;
277 };
278 mpi.isCompatible = checkCompatibleSettings();
279 if (!mpi.isCompatible) {
280 if (useAutomatic) {
282 STORM_LOG_WARN("The settings picked by the automatic engine (engine="
283 << mpi.engine << ", bisim=" << mpi.applyBisimulation << ", exact=" << useExact
284 << ") are incompatible with this model. Falling back to default settings.");
286 mpi.applyBisimulation = false;
287 mpi.verificationValueType = originalVerificationValueType;
288 // Retry check with new settings
289 mpi.isCompatible = checkCompatibleSettings();
290 }
291 }
292 } else {
293 // If there is no input model, nothing has to be done, actually
294 mpi.isCompatible = true;
295 }
296
297 // Set whether a transformation to jani is required or necessary
298 mpi.transformToJani = ioSettings.isPrismToJaniSet();
299 if (input.model) {
300 auto builderType = storm::utility::getBuilderType(mpi.engine);
301 bool transformToJaniForDdMA = (builderType == storm::builder::BuilderType::Dd) &&
302 (input.model->getModelType() == storm::storage::SymbolicModelDescription::ModelType::MA) && (!input.model->isJaniModel());
303 STORM_LOG_WARN_COND(mpi.transformToJani || !transformToJaniForDdMA,
304 "Dd-based model builder for Markov Automata is only available for JANI models, automatically converting the input model.");
305 mpi.transformToJani |= transformToJaniForDdMA;
306 }
307
308 // Set the Valuetype used during model building
310 if (bisimulationSettings.useExactArithmeticInDdBisimulation()) {
314 }
315 } else {
316 STORM_LOG_WARN("Requested using exact arithmetic in Dd bisimulation but no dd bisimulation is applied.");
317 }
318 }
319
320 // Set the Dd library
321 mpi.ddType = coreSettings.getDdLibraryType();
322 if (mpi.ddType == storm::dd::DdType::CUDD && coreSettings.isDdLibraryTypeSetFromDefaultValue()) {
325 STORM_LOG_INFO("Switching to DD library sylvan to allow for rational arithmetic.");
327 }
328 }
329 return mpi;
330}
331
332auto castAndApply(std::shared_ptr<storm::models::ModelBase> const& model, auto const& callback) {
333 STORM_LOG_ASSERT(model, "Tried to cast a model that does not exist.");
334
335 // Helper to actually perform the cast once value type and model representation type is known
336 auto castAndApplyImpl = [&model, &callback]<typename TargetModelType> {
337 auto res = model->template as<TargetModelType>();
338 STORM_LOG_ASSERT(res, "Casting model pointer failed unexpectedly.");
339 return callback(res);
340 };
341
342 // Helper to branch on type of model representation
343 auto castAndApplyVT = [&]<typename ValueType> {
344 if (model->isSparseModel()) {
345 return castAndApplyImpl.template operator()<storm::models::sparse::Model<ValueType>>();
346 } else {
347 auto ddType = model->getDdType();
348 STORM_LOG_ASSERT(model->isSymbolicModel() && ddType.has_value(), "Unexpected model representation.");
349 if constexpr (storm::IsIntervalType<ValueType>) {
350 // Avoiding a couple of unnecessary template instantiations
351 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Symbolic interval models are currently not supported.");
352 } else {
353 using enum storm::dd::DdType;
354 if (*ddType == CUDD) {
355 if constexpr (std::is_same_v<ValueType, double>) {
356 return castAndApplyImpl.template operator()<storm::models::symbolic::Model<CUDD, ValueType>>();
357 }
358 }
359 STORM_LOG_ASSERT(*ddType == Sylvan, "Unexpected Dd type.");
360 return castAndApplyImpl.template operator()<storm::models::symbolic::Model<Sylvan, ValueType>>();
361 }
362 }
363 };
364
365 // branch on type of value representation
366 if (model->supportsParameters()) {
367 return castAndApplyVT.template operator()<storm::RationalFunction>();
368 } else if (model->supportsUncertainty()) {
369 if (model->isExact()) {
370 return castAndApplyVT.template operator()<storm::RationalInterval>();
371 } else {
372 return castAndApplyVT.template operator()<storm::Interval>();
373 }
374 } else {
375 if (model->isExact()) {
376 return castAndApplyVT.template operator()<storm::RationalNumber>();
377 } else {
378 return castAndApplyVT.template operator()<double>();
379 }
380 }
381}
382
385 switch (vt) {
386 case FinitePrecision:
387 return callback.template operator()<double>();
388 case Exact:
389 return callback.template operator()<storm::RationalNumber>();
390 case Parametric:
391 return callback.template operator()<storm::RationalFunction>();
392 }
393 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected value type.");
394}
395
397 using enum storm::dd::DdType;
399 switch (dd) {
400 case CUDD:
401 STORM_LOG_THROW(vt == FinitePrecision, storm::exceptions::UnexpectedException, "Unexpected value type for DD library Cudd.");
402 return callback.template operator()<CUDD, double>();
403 case Sylvan:
404 switch (vt) {
405 case FinitePrecision:
406 return callback.template operator()<Sylvan, double>();
407 case Exact:
408 return callback.template operator()<Sylvan, storm::RationalNumber>();
409 case Parametric:
410 return callback.template operator()<Sylvan, storm::RationalFunction>();
411 }
412 }
413 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected DDType or value type.");
414}
415
416inline void ensureNoUndefinedPropertyConstants(std::vector<storm::jani::Property> const& properties) {
417 // Make sure there are no undefined constants remaining in any property.
418 for (auto const& property : properties) {
419 std::set<storm::expressions::Variable> usedUndefinedConstants = property.getUndefinedConstants();
420 if (!usedUndefinedConstants.empty()) {
421 std::vector<std::string> undefinedConstantsNames;
422 for (auto const& constant : usedUndefinedConstants) {
423 undefinedConstantsNames.emplace_back(constant.getName());
424 }
426 false, storm::exceptions::InvalidArgumentException,
427 "The property '" << property << " still refers to the undefined constants " << boost::algorithm::join(undefinedConstantsNames, ",") << ".");
428 }
429 }
430}
431
432inline std::pair<SymbolicInput, ModelProcessingInformation> preprocessSymbolicInput(SymbolicInput const& input) {
434
435 SymbolicInput output = input;
436
437 // Preprocess properties (if requested)
438 if (ioSettings.isPropertiesAsMultiSet()) {
439 STORM_LOG_THROW(!input.properties.empty(), storm::exceptions::InvalidArgumentException,
440 "Can not translate properties to multi-objective formula because no properties were specified.");
441 // If we come from storm-pars, the following fails as multiObjectiveSettings are not loaded
444 }
445
446 // Substitute constant definitions in symbolic input.
447 std::string constantDefinitionString = ioSettings.getConstantDefinitionString();
448 std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions;
449 if (output.model) {
450 constantDefinitions = output.model.get().parseConstantDefinitions(constantDefinitionString);
451 output.model = output.model.get().preprocess(constantDefinitions);
452 }
453 if (!output.properties.empty()) {
454 output.properties = storm::api::substituteConstantsInProperties(output.properties, constantDefinitions);
455 }
457 auto transformedJani = std::make_shared<SymbolicInput>();
458 ModelProcessingInformation mpi = getModelProcessingInformation(output, transformedJani);
459
460 // Check whether conversion for PRISM to JANI is requested or necessary.
461 if (output.model && output.model.get().isPrismProgram()) {
462 if (mpi.transformToJani) {
463 if (transformedJani->model) {
464 // Use the cached transformation if possible
465 output = std::move(*transformedJani);
466 } else {
467 storm::prism::Program const& model = output.model.get().asPrismProgram();
468 auto modelAndProperties = model.toJani(output.properties);
469
470 output.model = modelAndProperties.first;
471
472 if (!modelAndProperties.second.empty()) {
473 output.preprocessedProperties = std::move(modelAndProperties.second);
474 }
475 }
476 }
477 }
478
479 if (output.model && output.model.get().isJaniModel()) {
481 storm::api::simplifyJaniModel(output.model.get().asJaniModel(), output.properties, supportedFeatures);
482
484 if (buildSettings.isLocationEliminationSet()) {
485 auto locationHeuristic = buildSettings.getLocationEliminationLocationHeuristic();
486 auto edgesHeuristic = buildSettings.getLocationEliminationEdgesHeuristic();
487 output.model->setModel(storm::jani::JaniLocalEliminator::eliminateAutomatically(output.model.get().asJaniModel(), output.properties,
488 locationHeuristic, edgesHeuristic));
489 }
490 }
491
492 return {output, mpi};
493}
494
495inline std::vector<std::shared_ptr<storm::logic::Formula const>> createFormulasToRespect(std::vector<storm::jani::Property> const& properties) {
496 std::vector<std::shared_ptr<storm::logic::Formula const>> result = storm::api::extractFormulasFromProperties(properties);
497
498 for (auto const& property : properties) {
499 if (!property.getFilter().getStatesFormula()->isInitialFormula()) {
500 result.push_back(property.getFilter().getStatesFormula());
501 }
502 }
503
504 return result;
505}
506
507template<storm::dd::DdType DdType, typename ValueType>
508std::shared_ptr<storm::models::ModelBase> buildModelDd(storm::Environment const& env, SymbolicInput const& input) {
509 if (DdType == storm::dd::DdType::Sylvan) {
510 auto numThreads = env.dd().sylvan().getNumberOfThreads();
511 STORM_PRINT_AND_LOG("Using Sylvan with " << numThreads << " parallel threads.\n");
512 }
515 buildSettings.isBuildFullModelSet(), !buildSettings.isApplyNoMaximumProgressAssumptionSet(),
516 !buildSettings.isDontFixDeadlocksSet());
517}
518
522 options.setBuildChoiceLabels(options.isBuildChoiceLabelsSet() || buildSettings.isBuildChoiceLabelsSet());
523 options.setBuildStateValuations(options.isBuildStateValuationsSet() || buildSettings.isBuildStateValuationsSet());
524 options.setBuildAllLabels(options.isBuildAllLabelsSet() || buildSettings.isBuildAllLabelsSet());
525 options.setBuildObservationValuations(options.isBuildObservationValuationsSet() || buildSettings.isBuildObservationValuationsSet());
526 bool buildChoiceOrigins = options.isBuildChoiceOriginsSet() || buildSettings.isBuildChoiceOriginsSet();
529 if (counterexampleGeneratorSettings.isCounterexampleSet()) {
530 buildChoiceOrigins |= counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet();
531 }
532 }
533 options.setBuildChoiceOrigins(buildChoiceOrigins);
534
535 if (buildSettings.isApplyNoMaximumProgressAssumptionSet()) {
537 }
538
539 if (buildSettings.isExplorationChecksSet()) {
540 options.setExplorationChecks();
541 }
542 options.setReservedBitsForUnboundedVariables(buildSettings.getBitsForUnboundedVariables());
543
544 options.setAddOutOfBoundsState(buildSettings.isBuildOutOfBoundsStateSet());
545 if (buildSettings.isBuildFullModelSet()) {
546 options.clearTerminalStates();
548 options.setBuildAllLabels(true);
549 options.setBuildAllRewardModels(true);
550 }
551
552 if (buildSettings.isAddOverlappingGuardsLabelSet()) {
553 options.setAddOverlappingGuardsLabel(true);
554 }
555
557 if (ioSettings.isComputeExpectedVisitingTimesSet() || ioSettings.isComputeSteadyStateDistributionSet()) {
558 options.clearTerminalStates();
559 }
560
562 options.setStochasticTolerance(generalSettings.getTolerance());
563 options.setShowProgress(generalSettings.isVerboseSet());
564 options.setShowProgressDelay(generalSettings.getShowProgressDelay());
565
566 return options;
567}
568
569template<typename ValueType>
573 explorationOptions.explorationOrder = buildSettings.getExplorationOrder();
574 explorationOptions.fixDeadlocks = !buildSettings.isDontFixDeadlocksSet();
575 if (buildSettings.isExplorationStateLimitSet()) {
576 explorationOptions.explorationStateLimit = buildSettings.getExplorationStateLimit();
577 }
578 return explorationOptions;
579}
580
581template<typename ValueType>
582std::shared_ptr<storm::models::ModelBase> buildModelSparse(SymbolicInput const& input, storm::builder::BuilderOptions const& options) {
583 // If the input is an interval model, we might need to change the ValueType to an interval type.
584 if (!storm::IsIntervalType<ValueType> && input.model.is_initialized() && input.model->isPrismProgram() &&
585 input.model->asPrismProgram().hasIntervalUpdates()) {
586 // Get the right interval type for the given ValueType
587 bool constexpr IsDoubleInterval = std::is_same_v<ValueType, storm::IntervalBaseType<storm::Interval>>;
588 bool constexpr IsRationalInterval = std::is_same_v<ValueType, storm::IntervalBaseType<storm::RationalInterval>>;
589 STORM_LOG_THROW(IsDoubleInterval || IsRationalInterval, storm::exceptions::NotSupportedException,
590 "Can not build interval model for the provided value type.");
591 using IntervalType = std::conditional_t<IsDoubleInterval, storm::Interval, storm::RationalInterval>;
593 } else {
595 }
596}
597
598template<typename ValueType>
599std::shared_ptr<storm::models::ModelBase> buildModelExplicit(storm::settings::modules::IOSettings const& ioSettings,
600 storm::settings::modules::BuildSettings const& buildSettings) {
601 std::shared_ptr<storm::models::ModelBase> result;
602 if (ioSettings.isExplicitSet()) {
603 storm::parser::ExplicitModelParserOptions explicitModelParserOptions;
604 explicitModelParserOptions.fixDeadlocks = !buildSettings.isDontFixDeadlocksSet();
605 explicitModelParserOptions.buildChoiceLabels = buildSettings.isBuildChoiceLabelsSet();
607 ioSettings.getTransitionFilename(), ioSettings.getLabelingFilename(),
608 ioSettings.isStateRewardsSet() ? boost::optional<std::string>(ioSettings.getStateRewardsFilename()) : boost::none,
609 ioSettings.isTransitionRewardsSet() ? boost::optional<std::string>(ioSettings.getTransitionRewardsFilename()) : boost::none,
610 ioSettings.isChoiceLabelingSet() ? boost::optional<std::string>(ioSettings.getChoiceLabelingFilename()) : boost::none, explicitModelParserOptions);
611 } else if (ioSettings.isExplicitDRNSet()) {
613 options.buildChoiceLabeling = buildSettings.isBuildChoiceLabelsSet();
616 if constexpr (std::is_same_v<ValueType, double>) {
617 valueType = Double;
618 } else if constexpr (std::is_same_v<ValueType, storm::RationalNumber>) {
619 valueType = Rational;
620 } else {
621 static_assert(std::is_same_v<ValueType, storm::RationalFunction>, "Unexpected value type.");
622 valueType = Parametric;
623 }
624 result = storm::api::buildExplicitDRNModel(ioSettings.getExplicitDRNFilename(), valueType, options);
625 } else if (ioSettings.isExplicitUmbSet()) {
627 options.buildChoiceLabeling = buildSettings.isBuildChoiceLabelsSet();
628 options.buildStateValuations = buildSettings.isBuildStateValuationsSet();
630 if constexpr (std::is_same_v<ValueType, storm::RationalFunction>) {
631 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "RationalFunction currently not supported for UMB models.");
632 } else if constexpr (std::is_same_v<ValueType, storm::RationalNumber>) {
633 options.valueType = umb::ImportOptions::ValueType::Rational;
634 } else {
635 static_assert(std::is_same_v<ValueType, double>, "Unhandled value type.");
636 options.valueType = umb::ImportOptions::ValueType::Double;
637 }
638 result = storm::api::buildExplicitUmbModel(ioSettings.getExplicitUmbFilename(), options);
639 } else {
640 STORM_LOG_THROW(ioSettings.isExplicitIMCASet(), storm::exceptions::InvalidSettingsException, "Unexpected explicit model input type.");
641 storm::parser::ExplicitModelParserOptions explicitModelParserOptions;
642 explicitModelParserOptions.fixDeadlocks = !buildSettings.isDontFixDeadlocksSet();
643 explicitModelParserOptions.buildChoiceLabels = buildSettings.isBuildChoiceLabelsSet();
644 result = storm::api::buildExplicitIMCAModel<ValueType>(ioSettings.getExplicitIMCAFilename(), explicitModelParserOptions);
645 }
646 return result;
647}
648
649inline std::shared_ptr<storm::models::ModelBase> buildModel(SymbolicInput const& input, storm::settings::modules::IOSettings const& ioSettings,
650 ModelProcessingInformation const& mpi) {
651 storm::utility::Stopwatch modelBuildingWatch(true);
652
653 std::shared_ptr<storm::models::ModelBase> result;
654 if (input.model) {
655 auto builderType = storm::utility::getBuilderType(mpi.engine);
656 if (builderType == storm::builder::BuilderType::Dd) {
657 result = applyDdLibValueType(mpi.ddType, mpi.buildValueType,
658 [&input, &mpi]<storm::dd::DdType DD, typename VT>() { return buildModelDd<DD, VT>(mpi.env, input); });
659 } else if (builderType == storm::builder::BuilderType::Explicit) {
660 result = applyValueType(mpi.buildValueType, [&input]<typename VT>() {
661 auto options = createBuildOptionsSparseFromSettings(input);
662 return buildModelSparse<VT>(input, options);
663 });
664 }
665 } else if (ioSettings.isExplicitSet() || ioSettings.isExplicitDRNSet() || ioSettings.isExplicitUmbSet() || ioSettings.isExplicitIMCASet()) {
666 STORM_LOG_THROW(mpi.engine == storm::utility::Engine::Sparse, storm::exceptions::InvalidSettingsException,
667 "Can only use sparse engine with explicit input.");
668 result = applyValueType(mpi.buildValueType, [&ioSettings]<typename VT>() {
669 return buildModelExplicit<VT>(ioSettings, storm::settings::getModule<storm::settings::modules::BuildSettings>());
670 });
671 }
672
673 modelBuildingWatch.stop();
674 if (result) {
675 STORM_PRINT("Time for model construction: " << modelBuildingWatch << ".\n\n");
676 }
677
678 return result;
679}
680
681template<typename ValueType>
682std::shared_ptr<storm::models::sparse::Model<ValueType>> preprocessSparseMarkovAutomaton(
683 std::shared_ptr<storm::models::sparse::MarkovAutomaton<ValueType>> const& model) {
686
687 std::shared_ptr<storm::models::sparse::Model<ValueType>> result = model;
688 model->close();
689 STORM_LOG_WARN_COND(!buildSettings.isCheckZenoSet() || !model->containsZenoCycle(), "MA contains a Zeno cycle. Model checking results cannot be trusted.");
690
691 if (model->isConvertibleToCtmc()) {
692 STORM_LOG_WARN_COND(false, "MA is convertible to a CTMC, consider using a CTMC instead.");
693 result = model->convertToCtmc();
694 }
695
696 if (transformationSettings.isChainEliminationSet()) {
697 if constexpr (storm::IsIntervalType<ValueType>) {
698 // Currently not enabling this for interval models, as this would require a number of additional template instantiations.
699 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Chain elimination not supported for interval models.");
700 } else {
701 // TODO: we should also transform the properties at this point.
703 transformationSettings.getLabelBehavior())
704 .first;
705 }
706 }
707
708 return result;
709}
710
711template<typename ValueType>
712std::shared_ptr<storm::models::sparse::Model<ValueType>> preprocessSparseModelBisimulation(
713 std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input,
714 storm::settings::modules::BisimulationSettings const& bisimulationSettings) {
716 options.bisimulationType =
718 if (bisimulationSettings.isToleranceSet() || !storm::NumberTraits<ValueType>::IsExact) {
720 } else {
722 }
723 options.actionSensitive = bisimulationSettings.isActionSensitiveSet();
724 STORM_LOG_INFO("Performing bisimulation minimization (type: "
725 << (options.bisimulationType == storm::bisimulation::BisimulationType::Weak ? "weak" : "strong")
726 << ", tolerance: " << options.tolerance.value() << (options.actionSensitive ? ", action-sensitive" : "") << ")...");
728}
729
730template<typename ValueType>
731std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model,
732 SymbolicInput const& input, ModelProcessingInformation const& mpi) {
733 STORM_LOG_THROW(mpi.buildValueType == mpi.verificationValueType, storm::exceptions::NotSupportedException,
734 "Converting value types for sparse engine is not supported.");
738
739 std::pair<std::shared_ptr<storm::models::sparse::Model<ValueType>>, bool> result = std::make_pair(model, false);
740
741 if (auto order = transformationSettings.getModelPermutation(); order.has_value()) {
742 auto seed = transformationSettings.getModelPermutationSeed();
743 STORM_PRINT_AND_LOG("Permuting model states using " << storm::utility::permutation::orderKindtoString(order.value()) << " order"
744 << (seed.has_value() ? " with seed " + std::to_string(seed.value()) : "") << ".\n");
745 result.first = storm::api::permuteModelStates(result.first, order.value(), seed);
746 result.second = true;
747 STORM_PRINT_AND_LOG("Transition matrix hash after permuting: " << result.first->getTransitionMatrix().hash() << ".\n");
748 }
749
750 // Merging of states should be done before applying bisimulation as this order leads to the smallest quotient
751 if (transformationSettings.isMergeEquivalentStatesSet()) {
752 if constexpr (storm::IsIntervalType<ValueType>) {
753 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Merging equivalent states not supported for interval models.");
754 } else {
755 auto formulas = createFormulasToRespect(input.properties);
756 if (formulas.size() == 1) {
757 auto mergedModel = storm::api::mergeEquivalentStatesForFormula<ValueType>(result.first, *formulas.front());
758 if (mergedModel) {
759 STORM_LOG_INFO("Merged equivalent states for the considered property '" << *formulas.front() << "'.");
760 result.first = mergedModel;
761 result.second = true;
762 } else {
763 STORM_LOG_WARN("Merging equivalent states is not supported for the considered " << result.first->getType() << " model and property '"
764 << *formulas.front() << "'.");
765 }
766 } else {
767 STORM_LOG_WARN("Skipping merging of equivalent states as it requires exactly one input property. " << formulas.size()
768 << " properties given instead.");
769 }
770 }
771 }
772
773 if (result.first->isOfType(storm::models::ModelType::MarkovAutomaton)) {
775 result.second = true;
776 }
777
778 if (mpi.applyBisimulation) {
779 if constexpr (storm::IsIntervalType<ValueType>) {
780 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Bisimulation not supported for interval models.");
781 } else {
782 result.first = preprocessSparseModelBisimulation(result.first, input, bisimulationSettings);
783 result.second = true;
784 }
785 }
786
787 if (transformationSettings.isToDiscreteTimeModelSet()) {
788 if constexpr (storm::IsIntervalType<ValueType>) {
789 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Transformation to discrete time model not supported for interval models.");
790 } else {
791 // TODO: we should also transform the properties at this point.
793 !model->hasRewardModel("_time"),
794 "Scheduled transformation to discrete time model, but a reward model named '_time' is already present in this model. We might take "
795 "the wrong reward model later.");
796 result.first =
798 .first;
799 result.second = true;
800 }
801 }
802
803 if (transformationSettings.isToNondeterministicModelSet()) {
804 result.first = storm::api::transformToNondeterministicModel<ValueType>(std::move(*result.first));
805 result.second = true;
806 }
807
808 return result;
809}
810
811template<typename ValueType>
812void exportModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input) {
814
815 if (ioSettings.isExportBuildSet()) {
816 storm::utility::Stopwatch modelExportWatch;
817 modelExportWatch.start();
818 STORM_PRINT("\nExporting model to '" << ioSettings.getExportBuildFilename() << "'.\n");
819 switch (ioSettings.getExportBuildFormat()) {
821 storm::api::exportSparseModelAsDot(model, ioSettings.getExportBuildFilename(), ioSettings.getExportDotMaxWidth());
822 break;
825 options.allowPlaceholders = !ioSettings.isExplicitExportPlaceholdersDisabled();
826 options.compression = ioSettings.getCompressionMode();
827 if (ioSettings.isExportDigitsSet()) {
828 options.outputPrecision = ioSettings.getExportDigits();
829 }
830 storm::api::exportSparseModelAsDrn(model, ioSettings.getExportBuildFilename(), options,
831 input.model ? input.model.get().getParameterNames() : std::vector<std::string>());
832 break;
833 }
835 storm::api::exportSparseModelAsJson(model, ioSettings.getExportBuildFilename());
836 break;
839 options.compression = ioSettings.getCompressionMode();
840 storm::api::exportSparseModelAsUmb(model, ioSettings.getExportBuildFilename(), options);
841 break;
842 }
843 default:
844 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
845 "Exporting sparse models in " << storm::io::toString(ioSettings.getExportBuildFormat()) << " format is not supported.");
846 }
847 modelExportWatch.stop();
848 STORM_PRINT("Time for model export: " << modelExportWatch << ".\n\n");
849 }
850
851 // TODO: The following options are depreciated and shall be removed at some point:
852
853 if (ioSettings.isExportExplicitSet()) {
854 storm::api::exportSparseModelAsDrn(model, ioSettings.getExportExplicitFilename(),
855 input.model ? input.model.get().getParameterNames() : std::vector<std::string>(),
856 !ioSettings.isExplicitExportPlaceholdersDisabled());
857 }
858
859 STORM_LOG_THROW(!ioSettings.isExportDdSet(), storm::exceptions::NotSupportedException, "Exporting in drdd format is only supported for DDs.");
860
861 if (ioSettings.isExportDotSet()) {
862 storm::api::exportSparseModelAsDot(model, ioSettings.getExportDotFilename(), ioSettings.getExportDotMaxWidth());
863 }
864}
865
866template<storm::dd::DdType DdType, typename ValueType>
869
870 if (ioSettings.isExportBuildSet()) {
871 switch (ioSettings.getExportBuildFormat()) {
873 storm::api::exportSymbolicModelAsDot(model, ioSettings.getExportBuildFilename());
874 break;
876 storm::api::exportSymbolicModelAsDrdd(model, ioSettings.getExportBuildFilename());
877 break;
878 default:
879 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
880 "Exporting symbolic models in " << storm::io::toString(ioSettings.getExportBuildFormat()) << " format is not supported.");
881 }
882 }
883
884 // TODO: The following options are depreciated and shall be removed at some point:
885
886 STORM_LOG_THROW(!ioSettings.isExportExplicitSet(), storm::exceptions::NotSupportedException,
887 "Exporting in drn format is only supported for sparse models.");
888
889 if (ioSettings.isExportDdSet()) {
890 storm::api::exportSymbolicModelAsDrdd(model, ioSettings.getExportDdFilename());
891 }
892
893 if (ioSettings.isExportDotSet()) {
894 storm::api::exportSymbolicModelAsDot(model, ioSettings.getExportDotFilename());
895 }
896}
897
898template<storm::dd::DdType DdType, typename ValueType>
899typename std::enable_if<DdType != storm::dd::DdType::Sylvan && !std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type
901 return model;
902}
903
904template<storm::dd::DdType DdType, typename ValueType>
905typename std::enable_if<DdType == storm::dd::DdType::Sylvan || std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type
907 auto ma = model->template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>();
908 if (!ma->isClosed()) {
909 return std::make_shared<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(ma->close());
910 } else {
911 return model;
912 }
913}
914
915template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType>
916std::shared_ptr<storm::models::Model<ExportValueType>> preprocessDdModelBisimulation(
917 std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input,
918 storm::settings::modules::BisimulationSettings const& bisimulationSettings, ModelProcessingInformation const& mpi) {
919 STORM_LOG_WARN_COND(!bisimulationSettings.isWeakBisimulationSet(),
920 "Weak bisimulation is currently not supported on DDs. Falling back to strong bisimulation.");
921
922 auto quotientFormat = bisimulationSettings.getQuotientFormat();
924 bisimulationSettings.isQuotientFormatSetFromDefaultValue()) {
925 STORM_LOG_INFO("Setting bisimulation quotient format to 'sparse'.");
927 }
928
930 ddBisimulationOptions.reuseMode = bisimulationSettings.getReuseMode();
931 ddBisimulationOptions.refinementMode = bisimulationSettings.getRefinementMode();
932 ddBisimulationOptions.initialPartitionMode = bisimulationSettings.getInitialPartitionMode();
933 ddBisimulationOptions.useRepresentatives = bisimulationSettings.isUseRepresentativesSet();
934 ddBisimulationOptions.useOriginalVariables = bisimulationSettings.isUseOriginalVariablesSet();
935
936 STORM_LOG_INFO("Performing bisimulation minimization...");
939 quotientFormat, ddBisimulationOptions);
940}
941
942template<typename ExportValueType, storm::dd::DdType DdType, typename ValueType>
943std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessDdModelImpl(
944 std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input, ModelProcessingInformation const& mpi) {
946 std::pair<std::shared_ptr<storm::models::Model<ValueType>>, bool> intermediateResult = std::make_pair(model, false);
947
948 if (model->isOfType(storm::models::ModelType::MarkovAutomaton)) {
949 intermediateResult.first = preprocessDdMarkovAutomaton(intermediateResult.first->template as<storm::models::symbolic::Model<DdType, ValueType>>());
950 intermediateResult.second = true;
951 }
952
953 std::unique_ptr<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>> result;
954 auto symbolicModel = intermediateResult.first->template as<storm::models::symbolic::Model<DdType, ValueType>>();
955 if (mpi.applyBisimulation) {
956 std::shared_ptr<storm::models::Model<ExportValueType>> newModel =
957 preprocessDdModelBisimulation<DdType, ValueType, ExportValueType>(symbolicModel, input, bisimulationSettings, mpi);
958 result = std::make_unique<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>>(newModel, true);
959 } else {
960 result = std::make_unique<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>>(
961 symbolicModel->template toValueType<ExportValueType>(), !std::is_same<ValueType, ExportValueType>::value);
962 }
963
964 if (result && result->first->isSymbolicModel() && mpi.engine == storm::utility::Engine::DdSparse) {
965 // Mark as changed.
966 result->second = true;
967
968 std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> symbolicModel =
969 result->first->template as<storm::models::symbolic::Model<DdType, ExportValueType>>();
970 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas;
971 for (auto const& property : input.properties) {
972 formulas.emplace_back(property.getRawFormula());
973 }
974 result->first = storm::api::transformSymbolicToSparseModel(symbolicModel, formulas);
975 STORM_LOG_THROW(result, storm::exceptions::NotSupportedException, "The translation to a sparse model is not supported for the given model type.");
976 }
977
978 return *result;
979}
980
981template<storm::dd::DdType DdType, typename ValueType>
982std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessModel(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model,
983 SymbolicInput const& input, ModelProcessingInformation const& mpi) {
984 return applyValueType(mpi.verificationValueType, [&model, &input, &mpi]<typename VT>() -> std::pair<std::shared_ptr<storm::models::ModelBase>, bool> {
985 // To safe a few template instantiations, we only consider those combinations that actually occur in the CLI
986 if constexpr (std::is_same_v<ValueType, VT> ||
987 (DdType == storm::dd::DdType::Sylvan && std::is_same_v<ValueType, storm::RationalNumber> && std::is_same_v<VT, double>)) {
988 return preprocessDdModelImpl<VT>(model, input, mpi);
989 } else {
990 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
991 "Unexpected combination of DD library, build value type, and verification value type.");
992 }
993 });
994}
995
997 STORM_PRINT("\nModel checking property \"" << property.getName() << "\": " << *property.getRawFormula() << " ...\n");
998}
999
1000inline std::shared_ptr<storm::models::ModelBase> buildPreprocessModel(SymbolicInput const& input, ModelProcessingInformation const& mpi) {
1003
1004 std::shared_ptr<storm::models::ModelBase> model;
1005 if (!buildSettings.isNoBuildModelSet()) {
1006 model = buildModel(input, ioSettings, mpi);
1007 }
1008 if (!model) {
1009 STORM_LOG_THROW(input.properties.empty(), storm::exceptions::InvalidSettingsException, "No input model.");
1010 return nullptr;
1011 }
1012 model->printModelInformationToStream(std::cout);
1013
1014 storm::utility::Stopwatch preprocessingWatch(true);
1015 auto preprocessingResult = castAndApply(model, [&input, &mpi](auto const& m) { return preprocessModel(m, input, mpi); });
1016 preprocessingWatch.stop();
1017 if (preprocessingResult.second) {
1018 STORM_PRINT("\nTime for model preprocessing: " << preprocessingWatch << ".\n\n");
1019 model = preprocessingResult.first;
1020 model->printModelInformationToStream(std::cout);
1021 }
1022
1023 return model;
1024}
1025
1026inline std::shared_ptr<storm::models::ModelBase> buildPreprocessExportModel(SymbolicInput const& input, ModelProcessingInformation const& mpi) {
1027 auto model = buildPreprocessModel(input, mpi);
1028 if (model) {
1029 castAndApply(model, [&input](auto const& m) { exportModel(m, input); });
1030 }
1031 return model;
1032}
1033} // namespace cli
1034} // namespace storm
SylvanDdManagerEnvironment & sylvan()
DdEnvironment & dd()
uint64_t getNumberOfThreads() const
Retrieves the number of threads used by Sylvan.
BuilderOptions & setBuildAllLabels(bool newValue=true)
Should all reward models be built?
BuilderOptions & setExplorationChecks(bool newValue=true)
Should extra checks be performed during exploration.
BuilderOptions & setAddOutOfBoundsState(bool newValue=true)
Should a state for out of bounds be constructed.
BuilderOptions & setReservedBitsForUnboundedVariables(uint64_t value)
Sets the number of bits that will be reserved for unbounded integer variables.
BuilderOptions & setBuildChoiceLabels(bool newValue=true)
Should the choice labels be built?
BuilderOptions & setBuildAllRewardModels(bool newValue=true)
Should all reward models be built?
BuilderOptions & setBuildChoiceOrigins(bool newValue=true)
Should the origins the different choices be built?
BuilderOptions & setShowProgressDelay(uint64_t newValue)
Sets the delay (in seconds) between progress reports during state space exploration.
BuilderOptions & setBuildStateValuations(bool newValue=true)
Should the state valuation mapping be built?
BuilderOptions & setApplyMaximalProgressAssumption(bool newValue=true)
Should the maximal progress assumption be applied when building a Markov Automaton?
BuilderOptions & setStochasticTolerance(double newValue)
Sets the tolerance used for checking whether a distribution sums to one.
BuilderOptions & setBuildObservationValuations(bool newValue=true)
Should a observation valuation mapping be built?
BuilderOptions & setAddOverlappingGuardsLabel(bool newValue=true)
Should a state be labelled for overlapping guards.
BuilderOptions & setShowProgress(bool newValue=true)
Sets whether the progress of state space exploration should be printed.
static Model eliminateAutomatically(const Model &model, std::vector< jani::Property > properties, uint64_t locationHeuristic, uint64_t edgesHeuristic)
std::shared_ptr< storm::logic::Formula const > getRawFormula() const
Definition Property.cpp:92
std::string const & getName() const
Get the provided name.
Definition Property.cpp:23
This class represents a Markov automaton.
Base class for all sparse models.
Definition Model.h:34
Base class for all symbolic models.
Definition Model.h:42
storm::jani::Model toJani(bool allVariablesGlobal=true, std::string suffix="") const
Converts the PRISM model into an equivalent JANI model.
Definition Program.cpp:2350
static storm::Environment buildEnvironment()
This class represents the bisimulation settings.
storm::dd::bisimulation::ReuseMode getReuseMode() const
Retrieves the selected reuse mode.
bool isActionSensitiveSet() const
Retrieves whether action-sensitive bisimulation is to be used, i.e., choices are only lumped together...
storm::dd::bisimulation::QuotientFormat getQuotientFormat() const
Retrieves the format in which the quotient is to be extracted.
storm::dd::bisimulation::SignatureMode getSignatureMode() const
Retrieves the mode to compute signatures.
double getTolerance() const
Retrieves the tolerance to use for bisimulation minimization.
bool isUseOriginalVariablesSet() const
Retrieves whether the extracted quotient model is supposed to use the same variables as the original ...
storm::dd::bisimulation::InitialPartitionMode getInitialPartitionMode() const
Retrieves the initial partition mode.
bool isQuotientFormatSetFromDefaultValue() const
Retrieves whether the format in which the quotient is to be extracted has been set from its default v...
bool isUseRepresentativesSet() const
Retrieves whether representatives for blocks are to be used instead of the block numbers.
storm::dd::bisimulation::RefinementMode getRefinementMode() const
Retrieves the refinement mode to use.
bool isWeakBisimulationSet() const
Retrieves whether weak bisimulation is to be used.
bool isToleranceSet() const
Retrieves whether the tolerance to use for (approximate) bisimulation minimization has been set expli...
bool isBuildStateValuationsSet() const
Retrieves whether the choice labels should be build.
bool isDontFixDeadlocksSet() const
Retrieves whether the dont-fix-deadlocks option was set.
bool isBuildObservationValuationsSet() const
Retrieves whether the observation valuations should be build.
bool isBuildChoiceLabelsSet() const
Retrieves whether the choice labels should be build.
This class represents the markov chain settings.
Definition IOSettings.h:20
bool isJaniPropertiesSet() const
Retrieves whether the jani-property option was set.
std::string getExplicitIMCAFilename() const
Retrieves the name of the file that contains the model in the IMCA format.
bool areJaniPropertiesSelected() const
Retrieves whether one or more jani-properties have been selected.
std::string getChoiceLabelingFilename() const
Retrieves the name of the file that contains the choice labeling if the model was given using the exp...
bool isStateRewardsSet() const
Retrieves whether the state reward option was set.
std::string getProperty() const
Retrieves the property specified with the property option.
std::string getJaniInputFilename() const
Retrieves the name of the file that contains the JANI model specification if the model was given usin...
bool isChoiceLabelingSet() const
Retrieves whether the choice labeling option was set.
bool isPrismOrJaniInputSet() const
Retrieves whether the JANI or PRISM input option was set.
std::string getPropertyFilter() const
Retrieves the property filter.
std::string getPrismInputFilename() const
Retrieves the name of the file that contains the PRISM model specification if the model was given usi...
bool isExplicitDRNSet() const
Retrieves whether the explicit option with DRN was set.
std::string getExplicitDRNFilename() const
Retrieves the name of the file that contains the model in the DRN format.
std::string getLabelingFilename() const
Retrieves the name of the file that contains the state labeling if the model was given using the expl...
boost::optional< std::vector< std::string > > getQvbsPropertyFilter() const
Retrieves the selected property names.
std::string getStateRewardsFilename() const
Retrieves the name of the file that contains the state rewards if the model was given using the expli...
bool isExplicitUmbSet() const
Retrieves whether the explicit option with UMB was set.
std::string getTransitionRewardsFilename() const
Retrieves the name of the file that contains the transition rewards if the model was given using the ...
bool isPropertySet() const
Retrieves whether the property option was set.
std::string getQvbsModelName() const
Retrieves the specified model (short-)name of the QVBS.
std::vector< std::string > getSelectedJaniProperties() const
std::string getTransitionFilename() const
Retrieves the name of the file that contains the transitions if the model was given using the explici...
uint64_t getQvbsInstanceIndex() const
Retrieves the selected model instance (file + open parameters of the model).
bool isExplicitIMCASet() const
Retrieves whether the explicit option with IMCA was set.
bool isPrismInputSet() const
Retrieves whether the PRISM language option was set.
bool isTransitionRewardsSet() const
Retrieves whether the transition reward option was set.
std::string getExplicitUmbFilename() const
Retrieves the name of the file that contains the model in the UMB format.
bool isExplicitSet() const
Retrieves whether the explicit option was set.
This class provides easy access to a benchmark of the Quantitative Verification Benchmark Set http://...
Definition Qvbs.h:18
std::string const & getJaniFile(uint64_t instanceIndex=0) const
Definition Qvbs.cpp:108
std::string getInfo(uint64_t instanceIndex=0, boost::optional< std::vector< std::string > > propertyFilter=boost::none) const
Definition Qvbs.cpp:119
std::string const & getConstantDefinition(uint64_t instanceIndex=0) const
Definition Qvbs.cpp:113
storm::utility::Engine getEngine() const
Retrieve "good" settings after calling predict.
void predict(storm::jani::Model const &model, storm::jani::Property const &property)
Predicts "good" settings for the provided model checking query.
A class that provides convenience operations to display run times.
Definition Stopwatch.h:13
void start()
Start stopwatch (again) and start measuring time.
Definition Stopwatch.cpp:48
void stop()
Stop stopwatch and add measured time to total time.
Definition Stopwatch.cpp:42
#define STORM_LOG_INFO(message)
Definition logging.h:34
#define STORM_LOG_WARN(message)
Definition logging.h:35
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:54
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
std::shared_ptr< storm::models::sparse::Model< ValueType > > transformToNondeterministicModel(storm::models::sparse::Model< ValueType > &&model)
std::shared_ptr< storm::models::sparse::Model< ValueType > > mergeEquivalentStatesForFormula(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, storm::logic::Formula const &formula)
Identifies states of the given model that are equivalent w.r.t.
void exportSymbolicModelAsDot(std::shared_ptr< storm::models::symbolic::Model< Type, ValueType > > const &model, std::string const &filename)
Definition export.h:75
void exportSparseModelAsUmb(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, std::string const &filename, storm::umb::ExportOptions const &options={})
Definition export.h:65
std::shared_ptr< storm::models::ModelBase > buildExplicitUmbModel(std::string const &umbLocation, storm::umb::ImportOptions const &options={})
std::shared_ptr< storm::models::sparse::Model< ValueType > > permuteModelStates(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, storm::utility::permutation::OrderKind order, std::optional< uint64_t > seed=std::nullopt)
Permutes the order of the states of the model according to the given order.
storm::jani::Property createMultiObjectiveProperty(std::vector< storm::jani::Property > const &properties, bool lexicographic)
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildExplicitIMCAModel(std::string const &imcaFile, storm::parser::ExplicitModelParserOptions const &options=storm::parser::ExplicitModelParserOptions())
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.
void exportSymbolicModelAsDrdd(std::shared_ptr< storm::models::symbolic::Model< Type, ValueType > > const &model, std::string const &filename)
Definition export.h:44
storm::prism::Program parseProgram(std::string const &filename, bool prismCompatibility, bool simplify)
std::shared_ptr< storm::models::symbolic::Model< LibraryType, ValueType > > buildSymbolicModel(storm::Environment const &env, storm::storage::SymbolicModelDescription const &model, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas, bool buildFullModel=false, bool applyMaximumProgress=true, bool fixDeadlocks=true)
Definition builder.h:37
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildSparseModel(storm::storage::SymbolicModelDescription const &model, storm::builder::BuilderOptions const &options, typename storm::builder::ExplicitModelBuilder< ValueType >::Options const &explorationOptions=typename storm::builder::ExplicitModelBuilder< ValueType >::Options())
Definition builder.h:117
boost::optional< std::set< std::string > > parsePropertyFilter(std::string const &propertyFilter)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildExplicitDRNModel(std::string const &drnFile, storm::parser::DirectEncodingParserOptions const &options=storm::parser::DirectEncodingParserOptions())
storm::jani::ModelFeatures getSupportedJaniFeatures(storm::builder::BuilderType const &builderType)
Definition builder.h:32
void exportSparseModelAsDrn(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, std::string const &filename, std::vector< std::string > const &parameterNames={}, bool allowPlaceholders=true)
Definition export.h:30
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildExplicitModel(std::string const &transitionsFile, std::string const &labelingFile, boost::optional< std::string > const &stateRewardsFile, boost::optional< std::string > const &transitionRewardsFile, boost::optional< std::string > const &choiceLabelingFile, storm::parser::ExplicitModelParserOptions const &options=storm::parser::ExplicitModelParserOptions())
void simplifyJaniModel(storm::jani::Model &model, std::vector< storm::jani::Property > &properties, storm::jani::ModelFeatures const &supportedFeatures)
std::vector< storm::jani::Property > parsePropertiesForSymbolicModelDescription(std::string const &inputString, storm::storage::SymbolicModelDescription const &modelDescription, boost::optional< std::set< std::string > > const &propertyFilter)
void exportSparseModelAsJson(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, std::string const &filename)
Definition export.h:57
void exportSparseModelAsDot(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, std::string const &filename, size_t maxWidth=30)
Definition export.h:49
std::vector< storm::jani::Property > parseProperties(storm::parser::FormulaParser &formulaParser, std::string const &inputString, boost::optional< std::set< std::string > > const &propertyFilter)
std::shared_ptr< storm::models::sparse::Model< ValueType > > performBisimulationMinimization(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas={}, storm::bisimulation::Options const &options={})
std::pair< storm::jani::Model, std::vector< storm::jani::Property > > parseJaniModel(std::string const &filename, boost::optional< std::vector< std::string > > const &propertyFilter)
std::vector< storm::jani::Property > substituteConstantsInProperties(std::vector< storm::jani::Property > const &properties, std::map< storm::expressions::Variable, storm::expressions::Expression > const &substitution)
void exportModel(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, SymbolicInput const &input)
void parseSymbolicModelDescription(storm::settings::modules::IOSettings const &ioSettings, SymbolicInput &input)
std::shared_ptr< storm::models::ModelBase > buildModelExplicit(storm::settings::modules::IOSettings const &ioSettings, storm::settings::modules::BuildSettings const &buildSettings)
auto castAndApply(std::shared_ptr< storm::models::ModelBase > const &model, auto const &callback)
SymbolicInput parseSymbolicInputQvbs(storm::settings::modules::IOSettings const &ioSettings)
void getModelProcessingInformationAutomatic(SymbolicInput const &input, ModelProcessingInformation &mpi)
auto applyValueType(ModelProcessingInformation::ValueType vt, auto const &callback)
std::shared_ptr< storm::models::ModelBase > buildPreprocessExportModel(SymbolicInput const &input, ModelProcessingInformation const &mpi)
SymbolicInput parseSymbolicInput()
std::shared_ptr< storm::models::ModelBase > buildModelSparse(SymbolicInput const &input, storm::builder::BuilderOptions const &options)
std::enable_if< DdType!=storm::dd::DdType::Sylvan &&!std::is_same< ValueType, double >::value, std::shared_ptr< storm::models::Model< ValueType > > >::type preprocessDdMarkovAutomaton(std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &model)
std::shared_ptr< storm::models::sparse::Model< ValueType > > preprocessSparseMarkovAutomaton(std::shared_ptr< storm::models::sparse::MarkovAutomaton< ValueType > > const &model)
std::shared_ptr< storm::models::ModelBase > buildModelDd(storm::Environment const &env, SymbolicInput const &input)
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)
void parseProperties(storm::settings::modules::IOSettings const &ioSettings, SymbolicInput &input, boost::optional< std::set< std::string > > const &propertyFilter)
ModelProcessingInformation getModelProcessingInformation(SymbolicInput const &input, std::shared_ptr< SymbolicInput > const &transformedJaniInput=nullptr)
Sets the model processing information based on the given input.
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)
auto applyDdLibValueType(storm::dd::DdType dd, ModelProcessingInformation::ValueType vt, auto const &callback)
std::shared_ptr< storm::models::ModelBase > buildPreprocessModel(SymbolicInput const &input, 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)
storm::builder::BuilderOptions createBuildOptionsSparseFromSettings(SymbolicInput const &input)
void ensureNoUndefinedPropertyConstants(std::vector< storm::jani::Property > const &properties)
std::vector< std::shared_ptr< storm::logic::Formula const > > createFormulasToRespect(std::vector< storm::jani::Property > const &properties)
std::pair< std::shared_ptr< storm::models::ModelBase >, bool > preprocessModel(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, SymbolicInput const &input, ModelProcessingInformation const &mpi)
std::pair< std::shared_ptr< storm::models::ModelBase >, bool > preprocessDdModelImpl(std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &model, SymbolicInput const &input, ModelProcessingInformation const &mpi)
storm::builder::ExplicitModelBuilder< ValueType >::Options createExplorationOptionsFromSettings()
std::string toString(CompressionMode const &input)
SettingsType const & getModule()
Get module.
SettingsManager const & manager()
Retrieves the settings manager.
std::string orderKindtoString(OrderKind order)
Converts the given order to a string.
bool canHandle< storm::RationalFunction >(storm::utility::Engine const &engine, storm::storage::SymbolicModelDescription::ModelType const &modelType, storm::modelchecker::CheckTask< storm::logic::Formula, storm::RationalFunction > const &checkTask)
Definition Engine.cpp:196
Engine
An enumeration of all engines.
Definition Engine.h:31
template bool canHandle< storm::RationalNumber >(storm::utility::Engine const &, std::vector< storm::jani::Property > const &, storm::storage::SymbolicModelDescription const &)
ValueType zero()
Definition constants.cpp:26
template bool canHandle< double >(storm::utility::Engine const &, std::vector< storm::jani::Property > const &, storm::storage::SymbolicModelDescription const &)
storm::builder::BuilderType getBuilderType(Engine const &engine)
Returns the builder type used for the given engine.
Definition Engine.cpp:78
TargetType convertNumber(SourceType const &number)
carl::Interval< storm::RationalNumber > RationalInterval
carl::Interval< double > Interval
Interval type.
constexpr bool IsIntervalType
Helper to check if a type is an interval.
carl::RationalFunction< Polynomial, true > RationalFunction
#define STORM_PRINT_AND_LOG(message)
Definition print.h:20
#define STORM_PRINT(message)
Define the macros that print information to stdout and optionally also log it.
Definition print.h:14
static const bool IsExact
BisimulationType bisimulationType
Definition Options.h:32
std::optional< storm::RationalNumber > tolerance
Definition Options.h:35
std::vector< storm::jani::Property > properties
boost::optional< storm::storage::SymbolicModelDescription > model
boost::optional< std::vector< storm::jani::Property > > preprocessedProperties
bool allowPlaceholders
Allow placeholders for rational functions in the exported DRN file.
storm::io::CompressionMode compression
The type of compression used for the exported DRN file.
std::optional< std::size_t > outputPrecision
If set, the output precision for floating point numbers in the exported DRN file is set to the given ...
storm::io::CompressionMode compression
The type of compression used for the exported UMB model.
bool buildChoiceLabeling
Controls building of choice labelings.
bool buildObservationValuations
Controls building of observation valuations.
bool buildStateValuations
Controls building of state valuations.