Storm 1.13.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 <filesystem>
4#include <type_traits>
5
6#include "storm/api/storm.h"
7
8#include "AutomaticSettings.h"
16#include "storm/io/file.h"
36#include "storm/storage/Qvbs.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
166
167 // A flag which is set to true, if the settings were detected to be compatible.
168 // If this is false, it could be that the query can not be handled.
170};
171
174
175 STORM_LOG_THROW(input.model.is_initialized(), storm::exceptions::InvalidArgumentException, "Automatic engine requires a JANI input model.");
176 STORM_LOG_THROW(input.model->isJaniModel(), storm::exceptions::InvalidArgumentException, "Automatic engine requires a JANI input model.");
177 std::vector<storm::jani::Property> const& properties =
178 input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties;
179 STORM_LOG_THROW(!properties.empty(), storm::exceptions::InvalidArgumentException, "Automatic engine requires a property.");
180 STORM_LOG_WARN_COND(properties.size() == 1,
181 "Automatic engine does not support decisions based on multiple properties. Only the first property will be considered.");
182
184 if (hints.isNumberStatesSet()) {
185 as.predict(input.model->asJaniModel(), properties.front(), hints.getNumberStates());
186 } else {
187 as.predict(input.model->asJaniModel(), properties.front());
188 }
189
190 mpi.engine = as.getEngine();
191 if (as.enableBisimulation()) {
192 mpi.applyBisimulation = true;
193 }
196 }
197 STORM_PRINT_AND_LOG("Automatic engine picked the following settings: \n"
198 << "\tengine=" << mpi.engine << std::boolalpha << "\t bisimulation=" << mpi.applyBisimulation
199 << "\t exact=" << (mpi.verificationValueType != ModelProcessingInformation::ValueType::FinitePrecision) << std::noboolalpha << '\n');
200}
201
208 std::shared_ptr<SymbolicInput> const& transformedJaniInput = nullptr) {
214
215 // Set the engine.
216 mpi.engine = coreSettings.getEngine();
217
218 // Set whether bisimulation is to be used.
219 mpi.applyBisimulation = generalSettings.isBisimulationSet();
220
221 // Set the value type used for numeric values
222 if (generalSettings.isParametricSet()) {
224 } else if (generalSettings.isExactSet()) {
226 } else {
228 }
229 auto originalVerificationValueType = mpi.verificationValueType;
230
231 // Since the remaining settings could depend on the ones above, we need apply the automatic engine now.
232 bool useAutomatic = input.model.is_initialized() && mpi.engine == storm::utility::Engine::Automatic;
233 if (useAutomatic) {
234 if (input.model->isJaniModel()) {
235 // 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
236 // bisimulation or disable exact arithmetic)
238 } else {
239 // Transform Prism to jani first
240 STORM_LOG_ASSERT(input.model->isPrismProgram(), "Unexpected type of input.");
241 SymbolicInput janiInput;
242 janiInput.properties = input.properties;
243 storm::prism::Program const& prog = input.model.get().asPrismProgram();
244 auto modelAndProperties = prog.toJani(input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties);
245 janiInput.model = modelAndProperties.first;
246 if (!modelAndProperties.second.empty()) {
247 janiInput.preprocessedProperties = std::move(modelAndProperties.second);
248 }
249 // 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
250 // bisimulation or disable exact arithmetic)
252 if (transformedJaniInput) {
253 // We cache the transformation result.
254 *transformedJaniInput = std::move(janiInput);
255 }
256 }
257 }
258
259 // Check whether these settings are compatible with the provided input.
260 if (input.model) {
261 auto checkCompatibleSettings = [&mpi, &input] {
262 switch (mpi.verificationValueType) {
265 mpi.engine, input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties, input.model.get());
268 mpi.engine, input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties, input.model.get());
269 break;
272 mpi.engine, input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties, input.model.get());
273 }
274 return false;
275 };
276 mpi.isCompatible = checkCompatibleSettings();
277 if (!mpi.isCompatible) {
278 if (useAutomatic) {
280 STORM_LOG_WARN("The settings picked by the automatic engine (engine="
281 << mpi.engine << ", bisim=" << mpi.applyBisimulation << ", exact=" << useExact
282 << ") are incompatible with this model. Falling back to default settings.");
284 mpi.applyBisimulation = false;
285 mpi.verificationValueType = originalVerificationValueType;
286 // Retry check with new settings
287 mpi.isCompatible = checkCompatibleSettings();
288 }
289 }
290 } else {
291 // If there is no input model, nothing has to be done, actually
292 mpi.isCompatible = true;
293 }
294
295 // Set whether a transformation to jani is required or necessary
296 mpi.transformToJani = ioSettings.isPrismToJaniSet();
297 if (input.model) {
298 auto builderType = storm::utility::getBuilderType(mpi.engine);
299 bool transformToJaniForDdMA = (builderType == storm::builder::BuilderType::Dd) &&
300 (input.model->getModelType() == storm::storage::SymbolicModelDescription::ModelType::MA) && (!input.model->isJaniModel());
301 STORM_LOG_WARN_COND(mpi.transformToJani || !transformToJaniForDdMA,
302 "Dd-based model builder for Markov Automata is only available for JANI models, automatically converting the input model.");
303 mpi.transformToJani |= transformToJaniForDdMA;
304 }
305
306 // Set the Valuetype used during model building
308 if (bisimulationSettings.useExactArithmeticInDdBisimulation()) {
312 }
313 } else {
314 STORM_LOG_WARN("Requested using exact arithmetic in Dd bisimulation but no dd bisimulation is applied.");
315 }
316 }
317
318 // Set the Dd library
319 mpi.ddType = coreSettings.getDdLibraryType();
320 if (mpi.ddType == storm::dd::DdType::CUDD && coreSettings.isDdLibraryTypeSetFromDefaultValue()) {
323 STORM_LOG_INFO("Switching to DD library sylvan to allow for rational arithmetic.");
325 }
326 }
327 return mpi;
328}
329
330auto castAndApply(std::shared_ptr<storm::models::ModelBase> const& model, auto const& callback) {
331 STORM_LOG_ASSERT(model, "Tried to cast a model that does not exist.");
332
333 // Helper to actually perform the cast once value type and model representation type is known
334 auto castAndApplyImpl = [&model, &callback]<typename TargetModelType> {
335 auto res = model->template as<TargetModelType>();
336 STORM_LOG_ASSERT(res, "Casting model pointer failed unexpectedly.");
337 return callback(res);
338 };
339
340 // Helper to branch on type of model representation
341 auto castAndApplyVT = [&]<typename ValueType> {
342 if (model->isSparseModel()) {
343 return castAndApplyImpl.template operator()<storm::models::sparse::Model<ValueType>>();
344 } else {
345 auto ddType = model->getDdType();
346 STORM_LOG_ASSERT(model->isSymbolicModel() && ddType.has_value(), "Unexpected model representation");
347 if constexpr (storm::IsIntervalType<ValueType>) {
348 // Avoiding a couple of unnecessary template instantiations
349 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Symbolic interval models are currently not supported.");
350 } else {
351 using enum storm::dd::DdType;
352 if (*ddType == CUDD) {
353 if constexpr (std::is_same_v<ValueType, double>) {
354 return castAndApplyImpl.template operator()<storm::models::symbolic::Model<CUDD, ValueType>>();
355 }
356 }
357 STORM_LOG_ASSERT(*ddType == Sylvan, "Unexpected Dd type");
358 return castAndApplyImpl.template operator()<storm::models::symbolic::Model<Sylvan, ValueType>>();
359 }
360 }
361 };
362
363 // branch on type of value representation
364 if (model->supportsParameters()) {
365 return castAndApplyVT.template operator()<storm::RationalFunction>();
366 } else if (model->supportsUncertainty()) {
367 if (model->isExact()) {
368 return castAndApplyVT.template operator()<storm::RationalInterval>();
369 } else {
370 return castAndApplyVT.template operator()<storm::Interval>();
371 }
372 } else {
373 if (model->isExact()) {
374 return castAndApplyVT.template operator()<storm::RationalNumber>();
375 } else {
376 return castAndApplyVT.template operator()<double>();
377 }
378 }
379}
380
383 switch (vt) {
384 case FinitePrecision:
385 return callback.template operator()<double>();
386 case Exact:
387 return callback.template operator()<storm::RationalNumber>();
388 case Parametric:
389 return callback.template operator()<storm::RationalFunction>();
390 }
391 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected value type.");
392}
393
395 using enum storm::dd::DdType;
397 switch (dd) {
398 case CUDD:
399 STORM_LOG_THROW(vt == FinitePrecision, storm::exceptions::UnexpectedException, "Unexpected value type for DD library Cudd.");
400 return callback.template operator()<CUDD, double>();
401 case Sylvan:
402 switch (vt) {
403 case FinitePrecision:
404 return callback.template operator()<Sylvan, double>();
405 case Exact:
406 return callback.template operator()<Sylvan, storm::RationalNumber>();
407 case Parametric:
408 return callback.template operator()<Sylvan, storm::RationalFunction>();
409 }
410 }
411 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected DDType or value type.");
412}
413
414inline void ensureNoUndefinedPropertyConstants(std::vector<storm::jani::Property> const& properties) {
415 // Make sure there are no undefined constants remaining in any property.
416 for (auto const& property : properties) {
417 std::set<storm::expressions::Variable> usedUndefinedConstants = property.getUndefinedConstants();
418 if (!usedUndefinedConstants.empty()) {
419 std::vector<std::string> undefinedConstantsNames;
420 for (auto const& constant : usedUndefinedConstants) {
421 undefinedConstantsNames.emplace_back(constant.getName());
422 }
424 false, storm::exceptions::InvalidArgumentException,
425 "The property '" << property << " still refers to the undefined constants " << boost::algorithm::join(undefinedConstantsNames, ",") << ".");
426 }
427 }
428}
429
430inline std::pair<SymbolicInput, ModelProcessingInformation> preprocessSymbolicInput(SymbolicInput const& input) {
432
433 SymbolicInput output = input;
434
435 // Preprocess properties (if requested)
436 if (ioSettings.isPropertiesAsMultiSet()) {
437 STORM_LOG_THROW(!input.properties.empty(), storm::exceptions::InvalidArgumentException,
438 "Can not translate properties to multi-objective formula because no properties were specified.");
439 // If we come from storm-pars, the following fails as multiObjectiveSettings are not loaded
441 output.properties = {storm::api::createMultiObjectiveProperty(output.properties, multiObjSettings.isLexicographicModelCheckingSet())};
442 }
443
444 // Substitute constant definitions in symbolic input.
445 std::string constantDefinitionString = ioSettings.getConstantDefinitionString();
446 std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions;
447 if (output.model) {
448 constantDefinitions = output.model.get().parseConstantDefinitions(constantDefinitionString);
449 output.model = output.model.get().preprocess(constantDefinitions);
450 }
451 if (!output.properties.empty()) {
452 output.properties = storm::api::substituteConstantsInProperties(output.properties, constantDefinitions);
453 }
455 auto transformedJani = std::make_shared<SymbolicInput>();
456 ModelProcessingInformation mpi = getModelProcessingInformation(output, transformedJani);
457
458 // Check whether conversion for PRISM to JANI is requested or necessary.
459 if (output.model && output.model.get().isPrismProgram()) {
460 if (mpi.transformToJani) {
461 if (transformedJani->model) {
462 // Use the cached transformation if possible
463 output = std::move(*transformedJani);
464 } else {
465 storm::prism::Program const& model = output.model.get().asPrismProgram();
466 auto modelAndProperties = model.toJani(output.properties);
467
468 output.model = modelAndProperties.first;
469
470 if (!modelAndProperties.second.empty()) {
471 output.preprocessedProperties = std::move(modelAndProperties.second);
472 }
473 }
474 }
475 }
476
477 if (output.model && output.model.get().isJaniModel()) {
479 storm::api::simplifyJaniModel(output.model.get().asJaniModel(), output.properties, supportedFeatures);
480
482 if (buildSettings.isLocationEliminationSet()) {
483 auto locationHeuristic = buildSettings.getLocationEliminationLocationHeuristic();
484 auto edgesHeuristic = buildSettings.getLocationEliminationEdgesHeuristic();
485 output.model->setModel(storm::jani::JaniLocalEliminator::eliminateAutomatically(output.model.get().asJaniModel(), output.properties,
486 locationHeuristic, edgesHeuristic));
487 }
488 }
489
490 return {output, mpi};
491}
492
493inline void exportSymbolicInput(SymbolicInput const& input) {
495 if (input.model && input.model.get().isJaniModel()) {
496 storm::storage::SymbolicModelDescription const& model = input.model.get();
497 if (ioSettings.isExportJaniDotSet()) {
498 storm::api::exportJaniModelAsDot(model.asJaniModel(), ioSettings.getExportJaniDotFilename());
499 }
500 }
501}
502
503inline std::vector<std::shared_ptr<storm::logic::Formula const>> createFormulasToRespect(std::vector<storm::jani::Property> const& properties) {
504 std::vector<std::shared_ptr<storm::logic::Formula const>> result = storm::api::extractFormulasFromProperties(properties);
505
506 for (auto const& property : properties) {
507 if (!property.getFilter().getStatesFormula()->isInitialFormula()) {
508 result.push_back(property.getFilter().getStatesFormula());
509 }
510 }
511
512 return result;
513}
514
515template<storm::dd::DdType DdType, typename ValueType>
516std::shared_ptr<storm::models::ModelBase> buildModelDd(SymbolicInput const& input) {
517 if (DdType == storm::dd::DdType::Sylvan) {
518 auto numThreads = storm::settings::getModule<storm::settings::modules::SylvanSettings>().getNumberOfThreads();
519 STORM_PRINT_AND_LOG("Using Sylvan with " << numThreads << " parallel threads.\n");
520 }
522 return storm::api::buildSymbolicModel<DdType, ValueType>(input.model.get(), createFormulasToRespect(input.properties), buildSettings.isBuildFullModelSet(),
523 !buildSettings.isApplyNoMaximumProgressAssumptionSet());
524}
525
529 options.setBuildChoiceLabels(options.isBuildChoiceLabelsSet() || buildSettings.isBuildChoiceLabelsSet());
530 options.setBuildStateValuations(options.isBuildStateValuationsSet() || buildSettings.isBuildStateValuationsSet());
531 options.setBuildAllLabels(options.isBuildAllLabelsSet() || buildSettings.isBuildAllLabelsSet());
532 options.setBuildObservationValuations(options.isBuildObservationValuationsSet() || buildSettings.isBuildObservationValuationsSet());
533 bool buildChoiceOrigins = options.isBuildChoiceOriginsSet() || buildSettings.isBuildChoiceOriginsSet();
536 if (counterexampleGeneratorSettings.isCounterexampleSet()) {
537 buildChoiceOrigins |= counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet();
538 }
539 }
540 options.setBuildChoiceOrigins(buildChoiceOrigins);
541
542 if (buildSettings.isApplyNoMaximumProgressAssumptionSet()) {
544 }
545
546 if (buildSettings.isExplorationChecksSet()) {
547 options.setExplorationChecks();
548 }
549 options.setReservedBitsForUnboundedVariables(buildSettings.getBitsForUnboundedVariables());
550
551 options.setAddOutOfBoundsState(buildSettings.isBuildOutOfBoundsStateSet());
552 if (buildSettings.isBuildFullModelSet()) {
553 options.clearTerminalStates();
555 options.setBuildAllLabels(true);
556 options.setBuildAllRewardModels(true);
557 }
558
559 if (buildSettings.isAddOverlappingGuardsLabelSet()) {
560 options.setAddOverlappingGuardsLabel(true);
561 }
562
564 if (ioSettings.isComputeExpectedVisitingTimesSet() || ioSettings.isComputeSteadyStateDistributionSet()) {
565 options.clearTerminalStates();
566 }
567 return options;
568}
569
570template<typename ValueType>
571std::shared_ptr<storm::models::ModelBase> buildModelSparse(SymbolicInput const& input, storm::builder::BuilderOptions const& options) {
572 // If the input is an interval model, we might need to change the ValueType to an interval type.
573 if (!storm::IsIntervalType<ValueType> && input.model.is_initialized() && input.model->isPrismProgram() &&
574 input.model->asPrismProgram().hasIntervalUpdates()) {
575 // Get the right interval type for the given ValueType
576 bool constexpr IsDoubleInterval = std::is_same_v<ValueType, storm::IntervalBaseType<storm::Interval>>;
577 bool constexpr IsRationalInterval = std::is_same_v<ValueType, storm::IntervalBaseType<storm::RationalInterval>>;
578 STORM_LOG_THROW(IsDoubleInterval || IsRationalInterval, storm::exceptions::NotSupportedException,
579 "Can not build interval model for the provided value type.");
580 using IntervalType = std::conditional_t<IsDoubleInterval, storm::Interval, storm::RationalInterval>;
581 return storm::api::buildSparseModel<IntervalType>(input.model.get(), options);
582 } else {
583 return storm::api::buildSparseModel<ValueType>(input.model.get(), options);
584 }
585}
586
587template<typename ValueType>
588std::shared_ptr<storm::models::ModelBase> buildModelExplicit(storm::settings::modules::IOSettings const& ioSettings,
589 storm::settings::modules::BuildSettings const& buildSettings) {
590 std::shared_ptr<storm::models::ModelBase> result;
591 if (ioSettings.isExplicitSet()) {
593 ioSettings.getTransitionFilename(), ioSettings.getLabelingFilename(),
594 ioSettings.isStateRewardsSet() ? boost::optional<std::string>(ioSettings.getStateRewardsFilename()) : boost::none,
595 ioSettings.isTransitionRewardsSet() ? boost::optional<std::string>(ioSettings.getTransitionRewardsFilename()) : boost::none,
596 ioSettings.isChoiceLabelingSet() ? boost::optional<std::string>(ioSettings.getChoiceLabelingFilename()) : boost::none);
597 } else if (ioSettings.isExplicitDRNSet()) {
599 options.buildChoiceLabeling = buildSettings.isBuildChoiceLabelsSet();
602 if constexpr (std::is_same_v<ValueType, double>) {
603 valueType = Double;
604 } else if constexpr (std::is_same_v<ValueType, storm::RationalNumber>) {
605 valueType = Rational;
606 } else {
607 static_assert(std::is_same_v<ValueType, storm::RationalFunction>, "Unexpected value type.");
608 valueType = Parametric;
609 }
610 result = storm::api::buildExplicitDRNModel(ioSettings.getExplicitDRNFilename(), valueType, options);
611 } else if (ioSettings.isExplicitUmbSet()) {
613 options.buildChoiceLabeling = buildSettings.isBuildChoiceLabelsSet();
614 options.buildStateValuations = buildSettings.isBuildStateValuationsSet();
615 if constexpr (std::is_same_v<ValueType, storm::RationalFunction>) {
616 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "RationalFunction currently not supported for UMB models.");
617 } else if constexpr (std::is_same_v<ValueType, storm::RationalNumber>) {
618 options.valueType = umb::ImportOptions::ValueType::Rational;
619 } else {
620 static_assert(std::is_same_v<ValueType, double>, "Unhandled value type.");
621 options.valueType = umb::ImportOptions::ValueType::Double;
622 }
623 result = storm::api::buildExplicitUmbModel(ioSettings.getExplicitUmbFilename(), options);
624 } else {
625 STORM_LOG_THROW(ioSettings.isExplicitIMCASet(), storm::exceptions::InvalidSettingsException, "Unexpected explicit model input type.");
627 }
628 return result;
629}
630
631inline std::shared_ptr<storm::models::ModelBase> buildModel(SymbolicInput const& input, storm::settings::modules::IOSettings const& ioSettings,
632 ModelProcessingInformation const& mpi) {
633 storm::utility::Stopwatch modelBuildingWatch(true);
634
635 std::shared_ptr<storm::models::ModelBase> result;
636 if (input.model) {
637 auto builderType = storm::utility::getBuilderType(mpi.engine);
638 if (builderType == storm::builder::BuilderType::Dd) {
639 result = applyDdLibValueType(mpi.ddType, mpi.buildValueType, [&input]<storm::dd::DdType DD, typename VT>() { return buildModelDd<DD, VT>(input); });
640 } else if (builderType == storm::builder::BuilderType::Explicit) {
641 result = applyValueType(mpi.buildValueType, [&input]<typename VT>() {
642 auto options = createBuildOptionsSparseFromSettings(input);
643 return buildModelSparse<VT>(input, options);
644 });
645 }
646 } else if (ioSettings.isExplicitSet() || ioSettings.isExplicitDRNSet() || ioSettings.isExplicitUmbSet() || ioSettings.isExplicitIMCASet()) {
647 STORM_LOG_THROW(mpi.engine == storm::utility::Engine::Sparse, storm::exceptions::InvalidSettingsException,
648 "Can only use sparse engine with explicit input.");
649 result = applyValueType(mpi.buildValueType, [&ioSettings]<typename VT>() {
650 return buildModelExplicit<VT>(ioSettings, storm::settings::getModule<storm::settings::modules::BuildSettings>());
651 });
652 }
653
654 modelBuildingWatch.stop();
655 if (result) {
656 STORM_PRINT("Time for model construction: " << modelBuildingWatch << ".\n\n");
657 }
658
659 return result;
660}
661
662template<typename ValueType>
663std::shared_ptr<storm::models::sparse::Model<ValueType>> preprocessSparseMarkovAutomaton(
664 std::shared_ptr<storm::models::sparse::MarkovAutomaton<ValueType>> const& model) {
667
668 std::shared_ptr<storm::models::sparse::Model<ValueType>> result = model;
669 model->close();
670 STORM_LOG_WARN_COND(!debugSettings.isAdditionalChecksSet() || !model->containsZenoCycle(),
671 "MA contains a Zeno cycle. Model checking results cannot be trusted.");
672
673 if (model->isConvertibleToCtmc()) {
674 STORM_LOG_WARN_COND(false, "MA is convertible to a CTMC, consider using a CTMC instead.");
675 result = model->convertToCtmc();
676 }
677
678 if (transformationSettings.isChainEliminationSet()) {
679 if constexpr (storm::IsIntervalType<ValueType>) {
680 // Currently not enabling this for interval models, as this would require a number of additional template instantiations.
681 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Chain elimination not supported for interval models.");
682 } else {
683 // TODO: we should also transform the properties at this point.
685 transformationSettings.getLabelBehavior())
686 .first;
687 }
688 }
689
690 return result;
691}
692
693template<typename ValueType>
694std::shared_ptr<storm::models::sparse::Model<ValueType>> preprocessSparseModelBisimulation(
695 std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input,
696 storm::settings::modules::BisimulationSettings const& bisimulationSettings, bool graphPreserving = true) {
698 if (bisimulationSettings.isWeakBisimulationSet()) {
700 }
701
702 STORM_LOG_INFO("Performing bisimulation minimization...");
703 return storm::api::performBisimulationMinimization<ValueType>(model, createFormulasToRespect(input.properties), bisimType, graphPreserving);
704}
705
706template<typename ValueType>
707std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model,
708 SymbolicInput const& input, ModelProcessingInformation const& mpi) {
709 STORM_LOG_THROW(mpi.buildValueType == mpi.verificationValueType, storm::exceptions::NotSupportedException,
710 "Converting value types for sparse engine is not supported.");
714
715 std::pair<std::shared_ptr<storm::models::sparse::Model<ValueType>>, bool> result = std::make_pair(model, false);
716
717 if (auto order = transformationSettings.getModelPermutation(); order.has_value()) {
718 auto seed = transformationSettings.getModelPermutationSeed();
719 STORM_PRINT_AND_LOG("Permuting model states using " << storm::utility::permutation::orderKindtoString(order.value()) << " order"
720 << (seed.has_value() ? " with seed " + std::to_string(seed.value()) : "") << ".\n");
721 result.first = storm::api::permuteModelStates(result.first, order.value(), seed);
722 result.second = true;
723 STORM_PRINT_AND_LOG("Transition matrix hash after permuting: " << result.first->getTransitionMatrix().hash() << ".\n");
724 }
725
726 if (result.first->isOfType(storm::models::ModelType::MarkovAutomaton)) {
728 result.second = true;
729 }
730
731 if (mpi.applyBisimulation) {
732 if constexpr (storm::IsIntervalType<ValueType>) {
733 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Bisimulation not supported for interval models.");
734 } else {
735 result.first = preprocessSparseModelBisimulation(result.first, input, bisimulationSettings);
736 result.second = true;
737 }
738 }
739
740 if (transformationSettings.isToDiscreteTimeModelSet()) {
741 if constexpr (storm::IsIntervalType<ValueType>) {
742 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Transformation to discrete time model not supported for interval models.");
743 } else {
744 // TODO: we should also transform the properties at this point.
746 !model->hasRewardModel("_time"),
747 "Scheduled transformation to discrete time model, but a reward model named '_time' is already present in this model. We might take "
748 "the wrong reward model later.");
749 result.first =
751 .first;
752 result.second = true;
753 }
754 }
755
756 if (transformationSettings.isToNondeterministicModelSet()) {
757 result.first = storm::api::transformToNondeterministicModel<ValueType>(std::move(*result.first));
758 result.second = true;
759 }
760
761 return result;
762}
763
764template<typename ValueType>
765void exportModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input) {
767
768 if (ioSettings.isExportBuildSet()) {
769 storm::utility::Stopwatch modelExportWatch;
770 modelExportWatch.start();
771 STORM_PRINT("\nExporting model to '" << ioSettings.getExportBuildFilename() << "'.\n");
772 switch (ioSettings.getExportBuildFormat()) {
774 storm::api::exportSparseModelAsDot(model, ioSettings.getExportBuildFilename(), ioSettings.getExportDotMaxWidth());
775 break;
778 options.allowPlaceholders = !ioSettings.isExplicitExportPlaceholdersDisabled();
779 options.compression = ioSettings.getCompressionMode();
780 if (ioSettings.isExportDigitsSet()) {
781 options.outputPrecision = ioSettings.getExportDigits();
782 }
783 storm::api::exportSparseModelAsDrn(model, ioSettings.getExportBuildFilename(), options,
784 input.model ? input.model.get().getParameterNames() : std::vector<std::string>());
785 break;
786 }
788 storm::api::exportSparseModelAsJson(model, ioSettings.getExportBuildFilename());
789 break;
792 options.compression = ioSettings.getCompressionMode();
793 storm::api::exportSparseModelAsUmb(model, ioSettings.getExportBuildFilename(), options);
794 break;
795 }
796 default:
797 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
798 "Exporting sparse models in " << storm::io::toString(ioSettings.getExportBuildFormat()) << " format is not supported.");
799 }
800 modelExportWatch.stop();
801 STORM_PRINT("Time for model export: " << modelExportWatch << ".\n\n");
802 }
803
804 // TODO: The following options are depreciated and shall be removed at some point:
805
806 if (ioSettings.isExportExplicitSet()) {
807 storm::api::exportSparseModelAsDrn(model, ioSettings.getExportExplicitFilename(),
808 input.model ? input.model.get().getParameterNames() : std::vector<std::string>(),
809 !ioSettings.isExplicitExportPlaceholdersDisabled());
810 }
811
812 if (ioSettings.isExportDdSet()) {
813 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Exporting in drdd format is only supported for DDs.");
814 }
815
816 if (ioSettings.isExportDotSet()) {
817 storm::api::exportSparseModelAsDot(model, ioSettings.getExportDotFilename(), ioSettings.getExportDotMaxWidth());
818 }
819}
820
821template<storm::dd::DdType DdType, typename ValueType>
824
825 if (ioSettings.isExportBuildSet()) {
826 switch (ioSettings.getExportBuildFormat()) {
828 storm::api::exportSymbolicModelAsDot(model, ioSettings.getExportBuildFilename());
829 break;
831 storm::api::exportSymbolicModelAsDrdd(model, ioSettings.getExportBuildFilename());
832 break;
833 default:
834 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
835 "Exporting symbolic models in " << storm::io::toString(ioSettings.getExportBuildFormat()) << " format is not supported.");
836 }
837 }
838
839 // TODO: The following options are depreciated and shall be removed at some point:
840
841 if (ioSettings.isExportExplicitSet()) {
842 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Exporting in drn format is only supported for sparse models.");
843 }
844
845 if (ioSettings.isExportDdSet()) {
846 storm::api::exportSymbolicModelAsDrdd(model, ioSettings.getExportDdFilename());
847 }
848
849 if (ioSettings.isExportDotSet()) {
850 storm::api::exportSymbolicModelAsDot(model, ioSettings.getExportDotFilename());
851 }
852}
853
854template<storm::dd::DdType DdType, typename ValueType>
855typename std::enable_if<DdType != storm::dd::DdType::Sylvan && !std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type
857 return model;
858}
859
860template<storm::dd::DdType DdType, typename ValueType>
861typename std::enable_if<DdType == storm::dd::DdType::Sylvan || std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type
863 auto ma = model->template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>();
864 if (!ma->isClosed()) {
865 return std::make_shared<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(ma->close());
866 } else {
867 return model;
868 }
869}
870
871template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType>
872std::shared_ptr<storm::models::Model<ExportValueType>> preprocessDdModelBisimulation(
873 std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input,
874 storm::settings::modules::BisimulationSettings const& bisimulationSettings, ModelProcessingInformation const& mpi) {
875 STORM_LOG_WARN_COND(!bisimulationSettings.isWeakBisimulationSet(),
876 "Weak bisimulation is currently not supported on DDs. Falling back to strong bisimulation.");
877
878 auto quotientFormat = bisimulationSettings.getQuotientFormat();
880 bisimulationSettings.isQuotientFormatSetFromDefaultValue()) {
881 STORM_LOG_INFO("Setting bisimulation quotient format to 'sparse'.");
883 }
884 STORM_LOG_INFO("Performing bisimulation minimization...");
886 model, createFormulasToRespect(input.properties), storm::storage::BisimulationType::Strong, bisimulationSettings.getSignatureMode(), quotientFormat);
887}
888
889template<typename ExportValueType, storm::dd::DdType DdType, typename ValueType>
890std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessDdModelImpl(
891 std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input, ModelProcessingInformation const& mpi) {
893 std::pair<std::shared_ptr<storm::models::Model<ValueType>>, bool> intermediateResult = std::make_pair(model, false);
894
895 if (model->isOfType(storm::models::ModelType::MarkovAutomaton)) {
896 intermediateResult.first = preprocessDdMarkovAutomaton(intermediateResult.first->template as<storm::models::symbolic::Model<DdType, ValueType>>());
897 intermediateResult.second = true;
898 }
899
900 std::unique_ptr<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>> result;
901 auto symbolicModel = intermediateResult.first->template as<storm::models::symbolic::Model<DdType, ValueType>>();
902 if (mpi.applyBisimulation) {
903 std::shared_ptr<storm::models::Model<ExportValueType>> newModel =
904 preprocessDdModelBisimulation<DdType, ValueType, ExportValueType>(symbolicModel, input, bisimulationSettings, mpi);
905 result = std::make_unique<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>>(newModel, true);
906 } else {
907 result = std::make_unique<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>>(
908 symbolicModel->template toValueType<ExportValueType>(), !std::is_same<ValueType, ExportValueType>::value);
909 }
910
911 if (result && result->first->isSymbolicModel() && mpi.engine == storm::utility::Engine::DdSparse) {
912 // Mark as changed.
913 result->second = true;
914
915 std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> symbolicModel =
916 result->first->template as<storm::models::symbolic::Model<DdType, ExportValueType>>();
917 std::vector<std::shared_ptr<storm::logic::Formula const>> formulas;
918 for (auto const& property : input.properties) {
919 formulas.emplace_back(property.getRawFormula());
920 }
921 result->first = storm::api::transformSymbolicToSparseModel(symbolicModel, formulas);
922 STORM_LOG_THROW(result, storm::exceptions::NotSupportedException, "The translation to a sparse model is not supported for the given model type.");
923 }
924
925 return *result;
926}
927
928template<storm::dd::DdType DdType, typename ValueType>
929std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessModel(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model,
930 SymbolicInput const& input, ModelProcessingInformation const& mpi) {
931 return applyValueType(mpi.verificationValueType, [&model, &input, &mpi]<typename VT>() -> std::pair<std::shared_ptr<storm::models::ModelBase>, bool> {
932 // To safe a few template instantiations, we only consider those combinations that actually occur in the CLI
933 if constexpr (std::is_same_v<ValueType, VT> ||
934 (DdType == storm::dd::DdType::Sylvan && std::is_same_v<ValueType, storm::RationalNumber> && std::is_same_v<VT, double>)) {
935 return preprocessDdModelImpl<VT>(model, input, mpi);
936 } else {
937 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException,
938 "Unexpected combination of DD library, build value type, and verification value type.");
939 }
940 });
941}
942
944 STORM_PRINT("Computing counterexample for property " << *property.getRawFormula() << " ...\n");
945}
946
947inline void printCounterexample(std::shared_ptr<storm::counterexamples::Counterexample> const& counterexample, storm::utility::Stopwatch* watch = nullptr) {
948 if (counterexample) {
949 STORM_PRINT(*counterexample << '\n');
950 if (watch) {
951 STORM_PRINT("Time for computation: " << *watch << ".\n");
952 }
953 } else {
954 STORM_PRINT(" failed.\n");
955 }
956}
957
958template<typename ModelType>
959 requires(!std::derived_from<ModelType, storm::models::sparse::Model<double>>)
960inline void generateCounterexamples(std::shared_ptr<ModelType> const&, SymbolicInput const&) {
961 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Counterexample generation is not supported for this data-type.");
962}
963
964template<typename ModelType>
965 requires(std::derived_from<ModelType, storm::models::sparse::Model<double>>)
966inline void generateCounterexamples(std::shared_ptr<ModelType> const& sparseModel, SymbolicInput const& input) {
967 using ValueType = typename ModelType::ValueType;
968
969 for (auto& rewModel : sparseModel->getRewardModels()) {
970 rewModel.second.reduceToStateBasedRewards(sparseModel->getTransitionMatrix(), true);
971 }
972
973 STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Dtmc) || sparseModel->isOfType(storm::models::ModelType::Mdp),
974 storm::exceptions::NotSupportedException, "Counterexample is currently only supported for discrete-time models.");
975
977 if (counterexampleSettings.isMinimalCommandSetGenerationSet()) {
978 bool useMilp = counterexampleSettings.isUseMilpBasedMinimalCommandSetGenerationSet();
979 for (auto const& property : input.properties) {
980 std::shared_ptr<storm::counterexamples::Counterexample> counterexample;
982 storm::utility::Stopwatch watch(true);
983 if (useMilp) {
984 STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException,
985 "Counterexample generation using MILP is currently only supported for MDPs.");
987 input.model.get(), sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula());
988 } else {
989 STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Dtmc) || sparseModel->isOfType(storm::models::ModelType::Mdp),
990 storm::exceptions::NotSupportedException,
991 "Counterexample generation using MaxSAT is currently only supported for discrete-time models.");
992
993 if (sparseModel->isOfType(storm::models::ModelType::Dtmc)) {
995 input.model.get(), sparseModel->template as<storm::models::sparse::Dtmc<ValueType>>(), property.getRawFormula());
996 } else {
998 input.model.get(), sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula());
999 }
1000 }
1001 watch.stop();
1002 printCounterexample(counterexample, &watch);
1003 }
1004 } else if (counterexampleSettings.isShortestPathGenerationSet()) {
1005 for (auto const& property : input.properties) {
1006 std::shared_ptr<storm::counterexamples::Counterexample> counterexample;
1008 storm::utility::Stopwatch watch(true);
1009 STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Dtmc), storm::exceptions::NotSupportedException,
1010 "Counterexample generation using shortest paths is currently only supported for DTMCs.");
1012 property.getRawFormula(), counterexampleSettings.getShortestPathMaxK());
1013 watch.stop();
1014 printCounterexample(counterexample, &watch);
1015 }
1016 } else {
1017 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The selected counterexample formalism is unsupported.");
1018 }
1019}
1020
1021template<typename ValueType>
1023void printFilteredResult(std::unique_ptr<storm::modelchecker::CheckResult> const& result, storm::modelchecker::FilterType ft) {
1024 if (result->isQuantitative()) {
1026 STORM_PRINT(*result);
1027 } else {
1028 ValueType resultValue;
1029 switch (ft) {
1031 resultValue = result->asQuantitativeCheckResult<ValueType>().sum();
1032 break;
1034 resultValue = result->asQuantitativeCheckResult<ValueType>().average();
1035 break;
1037 resultValue = result->asQuantitativeCheckResult<ValueType>().getMin();
1038 break;
1040 resultValue = result->asQuantitativeCheckResult<ValueType>().getMax();
1041 break;
1044 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Outputting states is not supported.");
1048 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Filter type only defined for qualitative results.");
1049 default:
1050 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Unhandled filter type.");
1051 }
1053 STORM_PRINT(resultValue << " (approx. " << storm::utility::convertNumber<double>(resultValue) << ")");
1054 } else {
1055 STORM_PRINT(resultValue);
1056 }
1057 }
1058 } else {
1059 switch (ft) {
1061 STORM_PRINT(*result << '\n');
1062 break;
1064 STORM_PRINT(result->asQualitativeCheckResult().existsTrue());
1065 break;
1067 STORM_PRINT(result->asQualitativeCheckResult().forallTrue());
1068 break;
1070 STORM_PRINT(result->asQualitativeCheckResult().count());
1071 break;
1074 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Outputting states is not supported.");
1079 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Filter type only defined for quantitative results.");
1080 }
1081 }
1082 STORM_PRINT('\n');
1083}
1084
1086 STORM_PRINT("\nModel checking property \"" << property.getName() << "\": " << *property.getRawFormula() << " ...\n");
1087}
1088
1089template<typename ValueType>
1091void printResult(std::unique_ptr<storm::modelchecker::CheckResult> const& result, storm::logic::Formula const& filterStatesFormula,
1092 storm::modelchecker::FilterType const& filterType, storm::utility::Stopwatch* watch = nullptr) {
1093 if (result) {
1094 std::stringstream ss;
1095 ss << "'" << filterStatesFormula << "'";
1096 STORM_PRINT((storm::utility::resources::isTerminate() ? "Result till abort" : "Result")
1097 << " (for " << (filterStatesFormula.isInitialFormula() ? "initial" : ss.str()) << " states): ");
1098 printFilteredResult<ValueType>(result, filterType);
1099 if (watch) {
1100 STORM_PRINT("Time for model checking: " << *watch << ".\n");
1101 }
1102 } else {
1103 STORM_LOG_ERROR("Property is unsupported by selected engine/settings.\n");
1104 }
1105}
1106
1107template<typename ValueType>
1108void printResult(std::unique_ptr<storm::modelchecker::CheckResult> const& result, storm::jani::Property const& property,
1109 storm::utility::Stopwatch* watch = nullptr) {
1110 printResult<ValueType>(result, *property.getFilter().getStatesFormula(), property.getFilter().getFilterType(), watch);
1111}
1112
1113using VerificationCallbackType = std::function<std::unique_ptr<storm::modelchecker::CheckResult>(std::shared_ptr<storm::logic::Formula const> const& formula,
1114 std::shared_ptr<storm::logic::Formula const> const& states)>;
1115using PostprocessingCallbackType = std::function<void(std::unique_ptr<storm::modelchecker::CheckResult> const&)>;
1116
1118 void operator()(std::unique_ptr<storm::modelchecker::CheckResult> const&) {
1119 // Intentionally left empty.
1120 }
1121};
1122
1129template<typename ValueType>
1130std::unique_ptr<storm::modelchecker::CheckResult> verifyProperty(std::shared_ptr<storm::logic::Formula const> const& formula,
1131 std::shared_ptr<storm::logic::Formula const> const& statesFilter,
1132 VerificationCallbackType const& verificationCallback) {
1134
1135 try {
1136 if constexpr (storm::IsIntervalType<ValueType>) {
1137 STORM_LOG_ASSERT(!transformationSettings.isChainEliminationSet() && !transformationSettings.isToNondeterministicModelSet(),
1138 "Unsupported transformation has been invoked.");
1139 return verificationCallback(formula, statesFilter);
1140 }
1141 if (transformationSettings.isChainEliminationSet() && !storm::transformer::NonMarkovianChainTransformer<ValueType>::preservesFormula(*formula)) {
1142 STORM_LOG_WARN("Property is not preserved by elimination of non-markovian states.");
1143 } else if (transformationSettings.isToDiscreteTimeModelSet()) {
1145 auto transformedStatesFilter = storm::api::checkAndTransformContinuousToDiscreteTimeFormula<ValueType>(*statesFilter);
1146 if (transformedFormula && transformedStatesFilter) {
1147 // invoke verification algorithm on transformed formulas
1148 return verificationCallback(transformedFormula, transformedStatesFilter);
1149 } else {
1150 STORM_LOG_WARN("Property is not preserved by transformation to discrete time model.");
1151 }
1152 } else {
1153 // invoke verification algorithm on given formulas
1154 return verificationCallback(formula, statesFilter);
1155 }
1156 } catch (storm::exceptions::BaseException const& ex) {
1157 STORM_LOG_WARN("Cannot handle property: " << ex.what());
1158 }
1159 return nullptr;
1160}
1161
1168template<typename ValueType>
1169void verifyProperties(SymbolicInput const& input, VerificationCallbackType const& verificationCallback,
1170 PostprocessingCallbackType const& postprocessingCallback = PostprocessingIdentity()) {
1171 auto const& properties = input.preprocessedProperties ? input.preprocessedProperties.get() : input.properties;
1172 for (auto const& property : properties) {
1174 storm::utility::Stopwatch watch(true);
1175 auto result = verifyProperty<ValueType>(property.getRawFormula(), property.getFilter().getStatesFormula(), verificationCallback);
1176 watch.stop();
1177 if (result) {
1178 postprocessingCallback(result);
1179 }
1180 printResult<storm::IntervalBaseType<ValueType>>(result, property, &watch);
1181 }
1182}
1183
1193template<typename ValueType>
1194void computeStateValues(std::string const& description, std::function<std::unique_ptr<storm::modelchecker::CheckResult>()> const& computationCallback,
1195 SymbolicInput const& input, VerificationCallbackType const& verificationCallback,
1196 PostprocessingCallbackType const& postprocessingCallback = PostprocessingIdentity()) {
1197 // First compute the state values for all the states by invoking the computationCallback
1198 storm::utility::Stopwatch watch(true);
1199 STORM_PRINT("\nComputing " << description << " ...\n");
1200 std::unique_ptr<storm::modelchecker::CheckResult> result;
1201 try {
1202 result = computationCallback();
1203 } catch (storm::exceptions::BaseException const& ex) {
1204 STORM_LOG_ERROR("Cannot compute " << description << ": " << ex.what());
1205 }
1206 if (!result) {
1207 STORM_LOG_ERROR("Computation had no result.");
1208 return;
1209 }
1210 // Now process the (potentially filtered) result
1211 if (input.properties.empty()) {
1212 // Do not apply any filtering, consider result for *all* states
1213 postprocessingCallback(result);
1215 } else {
1216 // Each property identifies a subset of states to which we restrict (aka filter) the state-value result to
1217 auto const& properties = input.preprocessedProperties ? input.preprocessedProperties.get() : input.properties;
1218 for (uint64_t propertyIndex = 0; propertyIndex < properties.size(); ++propertyIndex) {
1219 auto const& property = properties[propertyIndex];
1220 // As the property serves as filter, it should (a) be qualitative and should (b) not consider a filter itself.
1221 if (!property.getRawFormula()->hasQualitativeResult()) {
1222 STORM_LOG_ERROR("Property '" << *property.getRawFormula()
1223 << "' can not be used for filtering states as it does not have a qualitative result.");
1224 continue;
1225 }
1226
1227 // Invoke verification algorithm on filtering property
1228 auto propertyFilter = verifyProperty<ValueType>(property.getRawFormula(), storm::logic::Formula::getTrueFormula(), verificationCallback);
1229
1230 if (propertyFilter) {
1231 // Filter and process result
1232 std::unique_ptr<storm::modelchecker::CheckResult> filteredResult = result->clone();
1233 filteredResult->filter(propertyFilter->asQualitativeCheckResult());
1234 postprocessingCallback(filteredResult);
1235 printResult<ValueType>(filteredResult, *property.getRawFormula(), property.getFilter().getFilterType(),
1236 propertyIndex == properties.size() - 1 ? &watch : nullptr);
1237 }
1238 }
1239 }
1240}
1241
1242inline std::vector<storm::expressions::Expression> parseConstraints(storm::expressions::ExpressionManager const& expressionManager,
1243 std::string const& constraintsString) {
1244 std::vector<storm::expressions::Expression> constraints;
1245
1246 std::vector<std::string> constraintsAsStrings;
1247 boost::split(constraintsAsStrings, constraintsString, boost::is_any_of(","));
1248
1249 storm::parser::ExpressionParser expressionParser(expressionManager);
1250 std::unordered_map<std::string, storm::expressions::Expression> variableMapping;
1251 for (auto const& variableTypePair : expressionManager) {
1252 variableMapping[variableTypePair.first.getName()] = variableTypePair.first;
1253 }
1254 expressionParser.setIdentifierMapping(variableMapping);
1255
1256 for (auto const& constraintString : constraintsAsStrings) {
1257 if (constraintString.empty()) {
1258 continue;
1259 }
1260
1261 storm::expressions::Expression constraint = expressionParser.parseFromString(constraintString);
1262 STORM_LOG_TRACE("Adding special (user-provided) constraint " << constraint << ".");
1263 constraints.emplace_back(constraint);
1264 }
1265
1266 return constraints;
1267}
1268
1269inline std::vector<std::vector<storm::expressions::Expression>> parseInjectedRefinementPredicates(
1270 storm::expressions::ExpressionManager const& expressionManager, std::string const& refinementPredicatesString) {
1271 std::vector<std::vector<storm::expressions::Expression>> injectedRefinementPredicates;
1272
1273 storm::parser::ExpressionParser expressionParser(expressionManager);
1274 std::unordered_map<std::string, storm::expressions::Expression> variableMapping;
1275 for (auto const& variableTypePair : expressionManager) {
1276 variableMapping[variableTypePair.first.getName()] = variableTypePair.first;
1277 }
1278 expressionParser.setIdentifierMapping(variableMapping);
1279
1280 std::vector<std::string> predicateGroupsAsStrings;
1281 boost::split(predicateGroupsAsStrings, refinementPredicatesString, boost::is_any_of(";"));
1282
1283 if (!predicateGroupsAsStrings.empty()) {
1284 for (auto const& predicateGroupString : predicateGroupsAsStrings) {
1285 if (predicateGroupString.empty()) {
1286 continue;
1287 }
1288
1289 std::vector<std::string> predicatesAsStrings;
1290 boost::split(predicatesAsStrings, predicateGroupString, boost::is_any_of(":"));
1291
1292 if (!predicatesAsStrings.empty()) {
1293 injectedRefinementPredicates.emplace_back();
1294 for (auto const& predicateString : predicatesAsStrings) {
1295 storm::expressions::Expression predicate = expressionParser.parseFromString(predicateString);
1296 STORM_LOG_TRACE("Adding special (user-provided) refinement predicate " << predicateString << ".");
1297 injectedRefinementPredicates.back().emplace_back(predicate);
1298 }
1299
1300 STORM_LOG_THROW(!injectedRefinementPredicates.back().empty(), storm::exceptions::InvalidArgumentException,
1301 "Expecting non-empty list of predicates to inject for each (mentioned) refinement step.");
1302
1303 // Finally reverse the list, because we take the predicates from the back.
1304 std::reverse(injectedRefinementPredicates.back().begin(), injectedRefinementPredicates.back().end());
1305 }
1306 }
1307
1308 // Finally reverse the list, because we take the predicates from the back.
1309 std::reverse(injectedRefinementPredicates.begin(), injectedRefinementPredicates.end());
1310 }
1311
1312 return injectedRefinementPredicates;
1313}
1314
1315template<storm::dd::DdType DdType, typename ValueType>
1317 STORM_LOG_ASSERT(input.model, "Expected symbolic model description.");
1320 parseConstraints(input.model->getManager(), abstractionSettings.getConstraintString()),
1321 parseInjectedRefinementPredicates(input.model->getManager(), abstractionSettings.getInjectedRefinementPredicates()));
1322
1323 verifyProperties<ValueType>(input, [&input, &options, &mpi](std::shared_ptr<storm::logic::Formula const> const& formula,
1324 std::shared_ptr<storm::logic::Formula const> const& states) {
1325 STORM_LOG_THROW(states->isInitialFormula(), storm::exceptions::NotSupportedException, "Abstraction-refinement can only filter initial states.");
1327 storm::api::createTask<ValueType>(formula, true), options);
1328 });
1329}
1330
1331template<typename ValueType>
1333 STORM_LOG_ASSERT(input.model, "Expected symbolic model description.");
1334 STORM_LOG_THROW((std::is_same<ValueType, double>::value), storm::exceptions::NotSupportedException,
1335 "Exploration does not support other data-types than floating points.");
1337 input, [&input, &mpi](std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
1338 STORM_LOG_THROW(states->isInitialFormula(), storm::exceptions::NotSupportedException, "Exploration can only filter initial states.");
1340 });
1341}
1342
1343template<typename ValueType>
1344void verifyModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& sparseModel, SymbolicInput const& input,
1345 ModelProcessingInformation const& mpi) {
1347 auto verificationCallback = [&sparseModel, &ioSettings, &mpi](std::shared_ptr<storm::logic::Formula const> const& formula,
1348 std::shared_ptr<storm::logic::Formula const> const& states) {
1349 auto createTask = [&ioSettings](auto const& f, bool onlyInitialStates) {
1350 if constexpr (storm::IsIntervalType<ValueType>) {
1351 STORM_LOG_THROW(ioSettings.isUncertaintyResolutionModeSet(), storm::exceptions::InvalidSettingsException,
1352 "Uncertainty resolution mode required for uncertain (interval) models.");
1353 return storm::api::createTask<ValueType>(f, storm::solver::convert(ioSettings.getUncertaintyResolutionMode()), onlyInitialStates);
1354 } else {
1355 (void)ioSettings; // suppress unused lambda capture warning. [[maybe_unused]] doesn't work for lambda captures.
1356 return storm::api::createTask<ValueType>(f, onlyInitialStates);
1357 }
1358 };
1359 bool const filterForInitialStates = states->isInitialFormula();
1360 auto task = createTask(formula, filterForInitialStates);
1361 if (ioSettings.isExportSchedulerSet()) {
1362 task.setProduceSchedulers(true);
1363 }
1364 std::unique_ptr<storm::modelchecker::CheckResult> result = storm::api::verifyWithSparseEngine<ValueType>(mpi.env, sparseModel, task);
1365
1366 std::unique_ptr<storm::modelchecker::CheckResult> filter;
1367 if (filterForInitialStates) {
1368 using SolutionType = storm::IntervalBaseType<ValueType>;
1369 filter = std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult<SolutionType>>(sparseModel->getInitialStates());
1370 } else if (!states->isTrueFormula()) { // No need to apply filter if it is the formula 'true'
1371 filter = storm::api::verifyWithSparseEngine<ValueType>(mpi.env, sparseModel, createTask(states, false));
1372 }
1373 if (result && filter) {
1374 result->filter(filter->asQualitativeCheckResult());
1375 }
1376 return result;
1377 };
1378 uint64_t exportCount = 0; // this number will be prepended to the export file name of schedulers and/or check results in case of multiple properties.
1379 auto postprocessingCallback = [&sparseModel, &ioSettings, &input, &exportCount](std::unique_ptr<storm::modelchecker::CheckResult> const& result) {
1380 // Scheduler export
1381 STORM_LOG_WARN_COND(!ioSettings.isExportSchedulerSet() || result->hasScheduler(), "Scheduler requested but could not be generated.");
1382 if (ioSettings.isExportSchedulerSet() && result->hasScheduler()) {
1383 std::filesystem::path schedulerExportPath = ioSettings.getExportSchedulerFilename();
1384 if (exportCount > 0) {
1385 STORM_LOG_WARN("Prepending " << exportCount << " to scheduler file name for this property because there are multiple properties.");
1386 schedulerExportPath.replace_filename(std::to_string(exportCount) + schedulerExportPath.filename().string());
1387 }
1388 STORM_PRINT_AND_LOG("Exporting scheduler ... ");
1389 if (input.model) {
1390 STORM_LOG_WARN_COND(sparseModel->hasStateValuations(),
1391 "No information of state valuations available. The scheduler output will use internal state ids. You might be "
1392 "interested in building the model with state valuations using --buildstateval.");
1394 sparseModel->hasChoiceLabeling() || sparseModel->hasChoiceOrigins(),
1395 "No symbolic choice information is available. The scheduler output will use internal choice ids. You might be interested in "
1396 "building the model with choice labels or choice origins using --buildchoicelab or --buildchoiceorig.");
1397 STORM_LOG_WARN_COND(sparseModel->hasChoiceLabeling() && !sparseModel->hasChoiceOrigins(),
1398 "Only partial choice information is available. You might want to build the model with choice origins using "
1399 "--buildchoicelab or --buildchoiceorig.");
1400 }
1401 if (result->isExplicitQuantitativeCheckResult()) {
1402 if constexpr (storm::IsIntervalType<ValueType>) {
1403 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Scheduler export for interval models is not supported.");
1404 } else {
1405 storm::api::exportScheduler(sparseModel, result->template asExplicitQuantitativeCheckResult<ValueType>().getScheduler(),
1406 schedulerExportPath.string());
1407 }
1408 } else if (result->isExplicitParetoCurveCheckResult()) {
1409 if constexpr (std::is_same_v<ValueType, storm::RationalFunction> || storm::IsIntervalType<ValueType>) {
1410 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Scheduler export for models of this value type is not supported.");
1411 } else {
1412 auto const& paretoRes = result->template asExplicitParetoCurveCheckResult<ValueType>();
1413 storm::api::exportParetoScheduler(sparseModel, paretoRes.getPoints(), paretoRes.getSchedulers(), schedulerExportPath.string());
1414 }
1415 } else if (result->isExplicitQualitativeCheckResult()) {
1416 if constexpr (storm::IsIntervalType<ValueType>) {
1417 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Scheduler export for interval models is not supported.");
1418 } else {
1419 storm::api::exportScheduler(sparseModel, result->template asExplicitQualitativeCheckResult<ValueType>().getScheduler(),
1420 schedulerExportPath.string());
1421 }
1422 } else {
1423 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Scheduler export not supported for this value type.");
1424 }
1425 }
1426
1427 // Result export
1428 if (ioSettings.isExportCheckResultSet()) {
1429 if constexpr (storm::IsIntervalType<ValueType>) {
1430 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Result export for interval models is not supported.");
1431 } else {
1432 std::filesystem::path resultExportPath = ioSettings.getExportCheckResultFilename();
1433 if (exportCount > 0) {
1434 STORM_LOG_WARN("Prepending " << exportCount << " to result file name for this property because there are multiple properties.");
1435 resultExportPath.replace_filename(std::to_string(exportCount) + resultExportPath.filename().string());
1436 }
1437 STORM_LOG_WARN_COND(sparseModel->hasStateValuations(),
1438 "No information of state valuations available. The result output will use internal state ids. You might be interested in "
1439 "building the model with state valuations using --buildstateval.");
1440 storm::api::exportCheckResultToJson(sparseModel, result, resultExportPath);
1441 }
1442 }
1443 ++exportCount;
1444 };
1445 if (!(ioSettings.isComputeSteadyStateDistributionSet() || ioSettings.isComputeExpectedVisitingTimesSet())) {
1446 verifyProperties<ValueType>(input, verificationCallback, postprocessingCallback);
1447 }
1448 if (ioSettings.isComputeSteadyStateDistributionSet()) {
1449 if constexpr (storm::IsIntervalType<ValueType>) {
1450 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Computing steady state distribution is not supported for interval models.");
1451 } else {
1453 "steady-state probabilities",
1454 [&mpi, &sparseModel]() { return storm::api::computeSteadyStateDistributionWithSparseEngine<ValueType>(mpi.env, sparseModel); }, input,
1455 verificationCallback, postprocessingCallback);
1456 }
1457 }
1458 if (ioSettings.isComputeExpectedVisitingTimesSet()) {
1459 if constexpr (storm::IsIntervalType<ValueType>) {
1460 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Computing expected visiting times is not supported for interval models.");
1461 } else {
1463 "expected visiting times",
1464 [&mpi, &sparseModel]() { return storm::api::computeExpectedVisitingTimesWithSparseEngine<ValueType>(mpi.env, sparseModel); }, input,
1465 verificationCallback, postprocessingCallback);
1466 }
1467 }
1468}
1469
1470template<storm::dd::DdType DdType, typename ValueType>
1471void verifyWithHybridEngine(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& symbolicModel, SymbolicInput const& input,
1472 ModelProcessingInformation const& mpi) {
1474 input, [&symbolicModel, &mpi](std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
1475 bool filterForInitialStates = states->isInitialFormula();
1476 auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates);
1477
1478 std::unique_ptr<storm::modelchecker::CheckResult> result = storm::api::verifyWithHybridEngine<DdType, ValueType>(mpi.env, symbolicModel, task);
1479
1480 std::unique_ptr<storm::modelchecker::CheckResult> filter;
1481 if (filterForInitialStates) {
1482 filter = std::make_unique<storm::modelchecker::SymbolicQualitativeCheckResult<DdType>>(symbolicModel->getReachableStates(),
1483 symbolicModel->getInitialStates());
1484 } else if (!states->isTrueFormula()) { // No need to apply filter if it is the formula 'true'
1486 }
1487 if (result && filter) {
1488 result->filter(filter->asQualitativeCheckResult());
1489 }
1490 return result;
1491 });
1492}
1493
1494template<storm::dd::DdType DdType, typename ValueType>
1495void verifyWithDdEngine(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& symbolicModel, SymbolicInput const& input,
1496 ModelProcessingInformation const& mpi) {
1498 input, [&symbolicModel, &mpi](std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
1499 bool filterForInitialStates = states->isInitialFormula();
1500 auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates);
1501
1502 std::unique_ptr<storm::modelchecker::CheckResult> result =
1504
1505 std::unique_ptr<storm::modelchecker::CheckResult> filter;
1506 if (filterForInitialStates) {
1507 filter = std::make_unique<storm::modelchecker::SymbolicQualitativeCheckResult<DdType>>(symbolicModel->getReachableStates(),
1508 symbolicModel->getInitialStates());
1509 } else if (!states->isTrueFormula()) { // No need to apply filter if it is the formula 'true'
1511 }
1512 if (result && filter) {
1513 result->filter(filter->asQualitativeCheckResult());
1514 }
1515 return result;
1516 });
1517}
1518
1519template<storm::dd::DdType DdType, typename ValueType>
1521 ModelProcessingInformation const& mpi) {
1523 input, [&symbolicModel, &mpi](std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
1524 STORM_LOG_THROW(states->isInitialFormula(), storm::exceptions::NotSupportedException, "Abstraction-refinement can only filter initial states.");
1526 storm::api::createTask<ValueType>(formula, true));
1527 });
1528}
1529
1530template<storm::dd::DdType DdType, typename ValueType>
1531typename std::enable_if<DdType != storm::dd::DdType::CUDD || std::is_same<ValueType, double>::value, void>::type verifyModel(
1532 std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& symbolicModel, SymbolicInput const& input,
1533 ModelProcessingInformation const& mpi) {
1535 verifyWithHybridEngine<DdType, ValueType>(symbolicModel, input, mpi);
1536 } else if (mpi.engine == storm::utility::Engine::Dd) {
1537 verifyWithDdEngine<DdType, ValueType>(symbolicModel, input, mpi);
1538 } else {
1540 }
1541}
1542
1543template<storm::dd::DdType DdType, typename ValueType>
1544typename std::enable_if<DdType == storm::dd::DdType::CUDD && !std::is_same<ValueType, double>::value, void>::type verifySymbolicModel(
1545 std::shared_ptr<storm::models::ModelBase> const&, SymbolicInput const&, ModelProcessingInformation const&) {
1546 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "CUDD does not support the selected data-type.");
1547}
1548
1549inline std::shared_ptr<storm::models::ModelBase> buildPreprocessModel(SymbolicInput const& input, ModelProcessingInformation const& mpi) {
1552
1553 std::shared_ptr<storm::models::ModelBase> model;
1554 if (!buildSettings.isNoBuildModelSet()) {
1555 model = buildModel(input, ioSettings, mpi);
1556 }
1557 if (!model) {
1558 STORM_LOG_THROW(input.properties.empty(), storm::exceptions::InvalidSettingsException, "No input model.");
1559 return nullptr;
1560 }
1561 model->printModelInformationToStream(std::cout);
1562
1563 storm::utility::Stopwatch preprocessingWatch(true);
1564 auto preprocessingResult = castAndApply(model, [&input, &mpi](auto const& m) { return preprocessModel(m, input, mpi); });
1565 preprocessingWatch.stop();
1566 if (preprocessingResult.second) {
1567 STORM_PRINT("\nTime for model preprocessing: " << preprocessingWatch << ".\n\n");
1568 model = preprocessingResult.first;
1569 model->printModelInformationToStream(std::cout);
1570 }
1571
1572 return model;
1573}
1574
1575inline std::shared_ptr<storm::models::ModelBase> buildPreprocessExportModel(SymbolicInput const& input, ModelProcessingInformation const& mpi) {
1576 auto model = buildPreprocessModel(input, mpi);
1577 if (model) {
1578 castAndApply(model, [&input](auto const& m) { exportModel(m, input); });
1579 }
1580 return model;
1581}
1582
1583inline void processInput(SymbolicInput const& input, ModelProcessingInformation const& mpi) {
1586
1587 // For several engines, no model building step is performed, but the verification is started right away.
1589 abstractionSettings.getAbstractionRefinementMethod() == storm::settings::modules::AbstractionSettings::Method::Games) {
1591 [&input, &mpi]<storm::dd::DdType DD, typename VT>() { verifyWithAbstractionRefinementEngine<DD, VT>(input, mpi); });
1592 } else if (mpi.engine == storm::utility::Engine::Exploration) {
1593 applyValueType(mpi.verificationValueType, [&input, &mpi]<typename VT>() { verifyWithExplorationEngine<VT>(input, mpi); });
1594 } else {
1595 std::shared_ptr<storm::models::ModelBase> model = buildPreprocessExportModel(input, mpi);
1596 if (model) {
1597 if (counterexampleSettings.isCounterexampleSet()) {
1598 castAndApply(model, [&input](auto const& m) { generateCounterexamples(m, input); });
1599 } else {
1600 castAndApply(model, [&input, &mpi](auto const& m) { verifyModel(m, input, mpi); });
1601 }
1602 }
1603 }
1604}
1605} // namespace cli
1606} // namespace storm
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 & 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 & setBuildObservationValuations(bool newValue=true)
Should a observation valuation mapping be built?
BuilderOptions & setAddOverlappingGuardsLabel(bool newValue=true)
Should a state be labelled for overlapping guards.
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 is responsible for managing a set of typed variables and all expressions using these varia...
std::shared_ptr< storm::logic::Formula const > const & getStatesFormula() const
Definition Property.h:52
storm::modelchecker::FilterType getFilterType() const
Definition Property.h:56
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
FilterExpression const & getFilter() const
Definition Property.cpp:88
static std::shared_ptr< Formula const > getTrueFormula()
Definition Formula.cpp:213
This class represents a discrete-time Markov chain.
Definition Dtmc.h:13
This class represents a Markov automaton.
This class represents a (discrete-time) Markov decision process.
Definition Mdp.h:13
Base class for all sparse models.
Definition Model.h:30
Base class for all symbolic models.
Definition Model.h:42
storm::expressions::Expression parseFromString(std::string const &expressionString, bool ignoreError=false) const
Parses an expression from the given string.
void setIdentifierMapping(qi::symbols< char, storm::expressions::Expression > const *identifiers_)
Sets an identifier mapping that is used to determine valid variables in the expression.
storm::jani::Model toJani(bool allVariablesGlobal=true, std::string suffix="") const
Converts the PRISM model into an equivalent JANI model.
Definition Program.cpp:2340
This class represents the settings for the abstraction procedures.
std::string getInjectedRefinementPredicates() const
Retrieves a string containing refinement predicates to inject (if there are any).
std::string getConstraintString() const
Retrieves the string that specifies additional constraints.
This class represents the bisimulation settings.
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.
bool isQuotientFormatSetFromDefaultValue() const
Retrieves whether the format in which the quotient is to be extracted has been set from its default v...
bool isWeakBisimulationSet() const
Retrieves whether weak bisimulation is to be used.
bool isBuildStateValuationsSet() const
Retrieves whether the choice labels should be build.
bool isBuildChoiceLabelsSet() const
Retrieves whether the choice labels should be build.
This class represents the markov chain settings.
Definition IOSettings.h:21
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:17
std::string const & getJaniFile(uint64_t instanceIndex=0) const
Definition Qvbs.cpp:107
std::string getInfo(uint64_t instanceIndex=0, boost::optional< std::vector< std::string > > propertyFilter=boost::none) const
Definition Qvbs.cpp:118
std::string const & getConstantDefinition(uint64_t instanceIndex=0) const
Definition Qvbs.cpp:112
storm::jani::Model const & asJaniModel() const
static bool preservesFormula(storm::logic::Formula const &formula)
Check if the property specified by the given formula is preserved by the transformation.
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:14
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:24
#define STORM_LOG_WARN(message)
Definition logging.h:25
#define STORM_LOG_TRACE(message)
Definition logging.h:12
#define STORM_LOG_ERROR(message)
Definition logging.h:26
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:38
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
#define STORM_PRINT_AND_LOG(message)
Definition macros.h:68
#define STORM_PRINT(message)
Define the macros that print information and optionally also log it.
Definition macros.h:62
std::unique_ptr< storm::modelchecker::CheckResult > verifyWithHybridEngine(storm::Environment const &env, std::shared_ptr< storm::models::symbolic::Dtmc< DdType, ValueType > > const &dtmc, storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const &task)
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildSparseModel(storm::storage::SymbolicModelDescription const &model, storm::builder::BuilderOptions const &options)
Definition builder.h:109
void exportScheduler(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, storm::storage::Scheduler< ValueType > const &scheduler, std::string const &filename)
Definition export.h:80
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)
std::shared_ptr< storm::models::sparse::Model< ValueType > > transformToNondeterministicModel(storm::models::sparse::Model< ValueType > &&model)
storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > createTask(std::shared_ptr< const storm::logic::Formula > const &formula, bool onlyInitialStatesRelevant=false)
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
storm::prism::Program parseProgram(std::string const &filename, bool prismCompatibility, bool simplify)
std::shared_ptr< storm::models::symbolic::Model< LibraryType, ValueType > > buildSymbolicModel(storm::storage::SymbolicModelDescription const &model, std::vector< std::shared_ptr< storm::logic::Formula const > > const &formulas, bool buildFullModel=false, bool applyMaximumProgress=true)
Definition builder.h:36
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::counterexamples::Counterexample > computeHighLevelCounterexampleMilp(storm::storage::SymbolicModelDescription const &symbolicModel, std::shared_ptr< storm::models::sparse::Mdp< double > > mdp, std::shared_ptr< storm::logic::Formula const > const &formula)
std::unique_ptr< storm::modelchecker::CheckResult > verifyWithExplorationEngine(storm::Environment const &env, storm::storage::SymbolicModelDescription const &model, storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const &task)
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::pair< storm::jani::Model, std::vector< storm::jani::Property > > parseJaniModel(std::string const &filename, boost::optional< std::vector< std::string > > const &propertyFilter)
void exportJaniModelAsDot(storm::jani::Model const &model, std::string const &filename)
Definition export.cpp:7
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 > > 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::unique_ptr< storm::modelchecker::CheckResult > computeExpectedVisitingTimesWithSparseEngine(storm::Environment const &env, std::shared_ptr< storm::models::sparse::Dtmc< ValueType > > const &dtmc)
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
std::unique_ptr< storm::modelchecker::CheckResult > verifyWithDdEngine(storm::Environment const &env, std::shared_ptr< storm::models::symbolic::Dtmc< DdType, ValueType > > const &dtmc, storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const &task)
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::storage::BisimulationType type=storm::storage::BisimulationType::Strong, bool graphPreserving=true)
std::shared_ptr< storm::logic::Formula const > checkAndTransformContinuousToDiscreteTimeFormula(storm::logic::Formula const &formula, std::string const &timeRewardName="_time")
std::shared_ptr< storm::counterexamples::Counterexample > computeHighLevelCounterexampleMaxSmt(storm::storage::SymbolicModelDescription const &symbolicModel, std::shared_ptr< storm::models::sparse::Model< double > > model, std::shared_ptr< storm::logic::Formula const > const &formula)
std::vector< storm::jani::Property > parsePropertiesForSymbolicModelDescription(std::string const &inputString, storm::storage::SymbolicModelDescription const &modelDescription, boost::optional< std::set< std::string > > const &propertyFilter)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
void simplifyJaniModel(storm::jani::Model &model, std::vector< storm::jani::Property > &properties, storm::jani::ModelFeatures const &supportedFeatures)
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildExplicitDRNModel(std::string const &drnFile, storm::parser::DirectEncodingParserOptions const &options=storm::parser::DirectEncodingParserOptions())
boost::optional< std::set< std::string > > parsePropertyFilter(std::string const &propertyFilter)
storm::jani::ModelFeatures getSupportedJaniFeatures(storm::builder::BuilderType const &builderType)
Definition builder.h:31
std::shared_ptr< storm::models::sparse::Model< ValueType > > buildExplicitIMCAModel(std::string const &imcaFile)
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
void exportCheckResultToJson(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, std::unique_ptr< storm::modelchecker::CheckResult > const &checkResult, std::string const &filename)
Definition export.h:127
std::shared_ptr< storm::counterexamples::Counterexample > computeKShortestPathCounterexample(std::shared_ptr< storm::models::sparse::Model< double > > model, std::shared_ptr< storm::logic::Formula const > const &formula, size_t maxK)
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
void exportParetoScheduler(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, std::vector< PointType > const &points, std::vector< storm::storage::Scheduler< ValueType > > const &schedulers, std::string const &baseFilenameStr)
Definition export.h:94
std::unique_ptr< storm::modelchecker::CheckResult > verifyWithSparseEngine(storm::Environment const &env, std::shared_ptr< storm::models::sparse::Dtmc< ValueType > > const &dtmc, storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const &task)
std::vector< storm::jani::Property > substituteConstantsInProperties(std::vector< storm::jani::Property > const &properties, std::map< storm::expressions::Variable, storm::expressions::Expression > const &substitution)
std::unique_ptr< storm::modelchecker::CheckResult > computeSteadyStateDistributionWithSparseEngine(storm::Environment const &env, std::shared_ptr< storm::models::sparse::Dtmc< ValueType > > const &dtmc)
void exportModel(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, SymbolicInput const &input)
void exportSymbolicInput(SymbolicInput const &input)
void parseSymbolicModelDescription(storm::settings::modules::IOSettings const &ioSettings, SymbolicInput &input)
void verifyWithAbstractionRefinementEngine(SymbolicInput const &input, ModelProcessingInformation const &mpi)
std::shared_ptr< storm::models::ModelBase > buildModelExplicit(storm::settings::modules::IOSettings const &ioSettings, storm::settings::modules::BuildSettings const &buildSettings)
std::enable_if< DdType==storm::dd::DdType::CUDD &&!std::is_same< ValueType, double >::value, void >::type verifySymbolicModel(std::shared_ptr< storm::models::ModelBase > const &, SymbolicInput const &, ModelProcessingInformation const &)
void verifyModel(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &sparseModel, SymbolicInput const &input, ModelProcessingInformation const &mpi)
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)
void verifyWithExplorationEngine(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, bool graphPreserving=true)
void printResult(std::unique_ptr< storm::modelchecker::CheckResult > const &result, storm::logic::Formula const &filterStatesFormula, storm::modelchecker::FilterType const &filterType, storm::utility::Stopwatch *watch=nullptr)
auto applyValueType(ModelProcessingInformation::ValueType vt, auto const &callback)
std::shared_ptr< storm::models::ModelBase > buildPreprocessExportModel(SymbolicInput const &input, ModelProcessingInformation const &mpi)
void verifyProperties(SymbolicInput const &input, VerificationCallbackType const &verificationCallback, PostprocessingCallbackType const &postprocessingCallback=PostprocessingIdentity())
Verifies all (potentially preprocessed) properties given in input.
std::vector< storm::expressions::Expression > parseConstraints(storm::expressions::ExpressionManager const &expressionManager, std::string const &constraintsString)
std::vector< std::vector< storm::expressions::Expression > > parseInjectedRefinementPredicates(storm::expressions::ExpressionManager const &expressionManager, std::string const &refinementPredicatesString)
SymbolicInput parseSymbolicInput()
void verifyWithDdEngine(std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &symbolicModel, SymbolicInput const &input, ModelProcessingInformation const &mpi)
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::function< std::unique_ptr< storm::modelchecker::CheckResult >(std::shared_ptr< storm::logic::Formula const > const &formula, std::shared_ptr< storm::logic::Formula const > const &states)> VerificationCallbackType
void printFilteredResult(std::unique_ptr< storm::modelchecker::CheckResult > const &result, storm::modelchecker::FilterType ft)
void computeStateValues(std::string const &description, std::function< std::unique_ptr< storm::modelchecker::CheckResult >()> const &computationCallback, SymbolicInput const &input, VerificationCallbackType const &verificationCallback, PostprocessingCallbackType const &postprocessingCallback=PostprocessingIdentity())
Computes values for each state (such as the steady-state probability distribution).
std::function< void(std::unique_ptr< storm::modelchecker::CheckResult > const &)> PostprocessingCallbackType
void printCounterexample(std::shared_ptr< storm::counterexamples::Counterexample > const &counterexample, storm::utility::Stopwatch *watch=nullptr)
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)
void verifyWithHybridEngine(std::shared_ptr< storm::models::symbolic::Model< DdType, ValueType > > const &symbolicModel, SymbolicInput const &input, ModelProcessingInformation const &mpi)
ModelProcessingInformation getModelProcessingInformation(SymbolicInput const &input, std::shared_ptr< SymbolicInput > const &transformedJaniInput=nullptr)
Sets the model processing information based on the given input.
void printComputingCounterexample(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)
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)
storm::builder::BuilderOptions createBuildOptionsSparseFromSettings(SymbolicInput const &input)
void processInput(SymbolicInput const &input, ModelProcessingInformation const &mpi)
void ensureNoUndefinedPropertyConstants(std::vector< storm::jani::Property > const &properties)
void generateCounterexamples(std::shared_ptr< ModelType > const &, SymbolicInput const &)
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::shared_ptr< storm::models::ModelBase > buildModelDd(SymbolicInput const &input)
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)
std::unique_ptr< storm::modelchecker::CheckResult > verifyProperty(std::shared_ptr< storm::logic::Formula const > const &formula, std::shared_ptr< storm::logic::Formula const > const &statesFilter, VerificationCallbackType const &verificationCallback)
Verifies the given formula plus a filter formula to identify relevant states and warns the user in ca...
std::enable_if<!std::is_same< ValueType, storm::RationalFunction >::value, std::unique_ptr< storm::modelchecker::CheckResult > >::type verifyWithAbstractionRefinementEngine(storm::Environment const &env, storm::storage::SymbolicModelDescription const &model, storm::modelchecker::CheckTask< storm::logic::Formula, ValueType > const &task, AbstractionRefinementOptions const &options=AbstractionRefinementOptions())
std::string toString(CompressionMode const &input)
SettingsType const & getModule()
Get module.
SettingsManager const & manager()
Retrieves the settings manager.
OptimizationDirection convert(OptimizationDirectionSetting s)
std::string orderKindtoString(OrderKind order)
Converts the given order to a string.
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
bool isConstant(ValueType const &)
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 &)
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
typename detail::IntervalMetaProgrammingHelper< ValueType >::BaseType IntervalBaseType
Helper to access the type in which interval boundaries are stored.
static const bool IsExact
void operator()(std::unique_ptr< storm::modelchecker::CheckResult > const &)
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 buildStateValuations
Controls building of state valuations.