Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
storm-dft.cpp
Go to the documentation of this file.
16
20template<typename ValueType>
22 auto const& dftIOSettings = storm::settings::getModule<storm::dft::settings::modules::DftIOSettings>();
23 auto const& faultTreeSettings = storm::settings::getModule<storm::dft::settings::modules::FaultTreeSettings>();
24 auto const& ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
25 auto const& dftGspnSettings = storm::settings::getModule<storm::dft::settings::modules::DftGspnSettings>();
26 auto const& transformationSettings = storm::settings::getModule<storm::settings::modules::TransformationSettings>();
27
28 // Build DFT from given file
29 std::shared_ptr<storm::dft::storage::DFT<ValueType>> dft;
30 if (dftIOSettings.isDftFileSet()) {
31 STORM_LOG_DEBUG("Loading DFT from Galileo file " << dftIOSettings.getDftFilename());
32 dft = storm::dft::api::loadDFTGalileoFile<ValueType>(dftIOSettings.getDftFilename());
33 } else if (dftIOSettings.isDftJsonFileSet()) {
34 STORM_LOG_DEBUG("Loading DFT from Json file " << dftIOSettings.getDftJsonFilename());
35 dft = storm::dft::api::loadDFTJsonFile<ValueType>(dftIOSettings.getDftJsonFilename());
36 } else {
37 STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No input model given.");
38 }
39
40 // Show statistics about DFT (number of gates, etc.)
41 if (dftIOSettings.isShowDftStatisticsSet()) {
42 dft->writeStatsToStream(std::cout);
43 std::cout << '\n';
44 }
45
46 // Export to json
47 if (dftIOSettings.isExportToJson()) {
48 storm::dft::api::exportDFTToJsonFile<ValueType>(*dft, dftIOSettings.getExportJsonFilename());
49 }
50
51 // Check well-formedness of DFT
52 auto wellFormedResult = storm::dft::api::isWellFormed(*dft, false);
53 STORM_LOG_THROW(wellFormedResult.first, storm::exceptions::UnmetRequirementException, "DFT is not well-formed: " << wellFormedResult.second);
54 // Warn about potential modeling issues
55 auto modelingIssues = storm::dft::api::hasPotentialModelingIssues(*dft);
56 STORM_LOG_WARN_COND(!modelingIssues.first, modelingIssues.second);
57
58 // Transformation to GSPN
59 if (dftGspnSettings.isTransformToGspn()) {
60 std::pair<std::shared_ptr<storm::gspn::GSPN>, uint64_t> pair = storm::dft::api::transformToGSPN(*dft);
61 std::shared_ptr<storm::gspn::GSPN> gspn = pair.first;
62 uint64_t toplevelFailedPlace = pair.second;
63
64 // Export
66
67 // Transform to Jani
68 // TODO analyse Jani model
69 std::shared_ptr<storm::jani::Model> model = storm::dft::api::transformToJani(*gspn, toplevelFailedPlace);
70 return;
71 }
72
73 // Export to SMT
74 if (dftIOSettings.isExportToSmt()) {
75 storm::dft::api::exportDFTToSMT<ValueType>(*dft, dftIOSettings.getExportSmtFilename());
76 return;
77 }
78
79 bool useSMT = false;
80 uint64_t solverTimeout = 10;
81#ifdef STORM_HAVE_Z3
82 if (faultTreeSettings.solveWithSMT()) {
83 useSMT = true;
84 STORM_LOG_DEBUG("Use SMT for preprocessing");
85 }
86#endif
87
88 // Apply transformations
89 // TODO transform later before actual analysis
90 dft = storm::dft::api::applyTransformations(*dft, faultTreeSettings.isUniqueFailedBE(), true, false);
91 STORM_LOG_DEBUG(dft->getElementsString());
92
93 // Compute minimal number of BE failures leading to system failure and
94 // maximal number of BE failures not leading to system failure yet.
95 // TODO: always needed?
96 auto bounds = storm::dft::api::computeBEFailureBounds(*dft, useSMT, solverTimeout);
97 STORM_LOG_DEBUG("BE failure bounds: lower bound: " << bounds.first << ", upper bound: " << bounds.second << ".");
98
99#ifdef STORM_HAVE_Z3
100 if (useSMT) {
101 // Solve with SMT
102 STORM_LOG_DEBUG("Running DFT analysis with use of SMT.");
103 // Set dynamic behavior vector
105 }
106#endif
107
108 // BDD Analysis
109 if (dftIOSettings.isExportToBddDot() || dftIOSettings.isAnalyzeWithBdds() || dftIOSettings.isMinimalCutSets() || dftIOSettings.isImportanceMeasureSet()) {
110 bool const isImportanceMeasureSet{dftIOSettings.isImportanceMeasureSet()};
111 bool const isMinimalCutSets{dftIOSettings.isMinimalCutSets()};
112 bool const isMTTF{dftIOSettings.usePropExpectedTime()};
113 double const mttfPrecision{faultTreeSettings.getMttfPrecision()};
114 double const mttfStepsize{faultTreeSettings.getMttfStepsize()};
115 std::string const mttfAlgorithm{faultTreeSettings.getMttfAlgorithm()};
116 bool const isExportToBddDot{dftIOSettings.isExportToBddDot()};
117 bool const isTimebound{dftIOSettings.usePropTimebound()};
118 bool const isTimepoints{dftIOSettings.usePropTimepoints()};
119
120 bool const probabilityAnalysis{ioSettings.isPropertySet() || !isImportanceMeasureSet};
121 size_t const chunksize{faultTreeSettings.getChunksize()};
122 bool const isModularisation{faultTreeSettings.useModularisation()};
123
124 std::vector<double> timepoints{};
125 if (isTimepoints) {
126 timepoints = dftIOSettings.getPropTimepoints();
127 }
128 if (isTimebound) {
129 timepoints.push_back(dftIOSettings.getPropTimebound());
130 }
131
132 std::string filename{""};
133 if (isExportToBddDot) {
134 filename = dftIOSettings.getExportBddDotFilename();
135 }
136
137 // gather manually inputted properties
138 std::vector<std::shared_ptr<storm::logic::Formula const>> manuallyInputtedProperties;
139 if (ioSettings.isPropertySet()) {
140 manuallyInputtedProperties = storm::api::extractFormulasFromProperties(storm::api::parseProperties(ioSettings.getProperty()));
141 }
142
143 std::string importanceMeasureName{""};
144 if (isImportanceMeasureSet) {
145 importanceMeasureName = dftIOSettings.getImportanceMeasure();
146 }
147
148 // Set variable ordering
149 if (dftIOSettings.isVariableOrderingFileSet()) {
150 auto beOrder = storm::dft::parser::BEOrderParser<ValueType>::parseBEOrder(dftIOSettings.getVariableOrderingFilename(), *dft);
151 dft->setBEOrder(beOrder);
152 }
153
154 auto const additionalRelevantEventNames{faultTreeSettings.getRelevantEvents()};
155 storm::dft::api::analyzeDFTBdd<ValueType>(dft, isExportToBddDot, filename, isMTTF, mttfPrecision, mttfStepsize, mttfAlgorithm, isMinimalCutSets,
156 probabilityAnalysis, isModularisation, importanceMeasureName, timepoints, manuallyInputtedProperties,
157 additionalRelevantEventNames, chunksize);
158
159 // don't perform other analysis if analyzeWithBdds is set
160 if (dftIOSettings.isAnalyzeWithBdds()) {
161 return;
162 }
163 }
164
165 // From now on we analyse the DFT via model checking
166
167 // Set min or max
168 std::string optimizationDirection = "min";
169 if (dftIOSettings.isComputeMaximalValue()) {
170 optimizationDirection = "max";
171 }
172
173 // Construct properties to analyse.
174 // We allow multiple properties to be checked at once.
175 std::vector<std::string> properties;
176 if (ioSettings.isPropertySet()) {
177 properties.push_back(ioSettings.getProperty());
178 }
179 if (dftIOSettings.usePropExpectedTime()) {
180 properties.push_back("T" + optimizationDirection + "=? [F \"failed\"]");
181 }
182 if (dftIOSettings.usePropProbability()) {
183 properties.push_back("P" + optimizationDirection + "=? [F \"failed\"]");
184 }
185 if (dftIOSettings.usePropTimebound()) {
186 std::stringstream stream;
187 stream << "P" << optimizationDirection << "=? [F<=" << dftIOSettings.getPropTimebound() << " \"failed\"]";
188 properties.push_back(stream.str());
189 }
190 if (dftIOSettings.usePropTimepoints()) {
191 for (double timepoint : dftIOSettings.getPropTimepoints()) {
192 std::stringstream stream;
193 stream << "P" << optimizationDirection << "=? [F<=" << timepoint << " \"failed\"]";
194 properties.push_back(stream.str());
195 }
196 }
197
198 // Build properties
199 std::vector<std::shared_ptr<storm::logic::Formula const>> props;
200 if (!properties.empty()) {
201 std::string propString;
202 for (size_t i = 0; i < properties.size(); ++i) {
203 propString += properties[i];
204 if (i + 1 < properties.size()) {
205 propString += ";";
206 }
207 }
209 }
210
211 // Set relevant event names
212 std::vector<std::string> additionalRelevantEventNames;
213 if (faultTreeSettings.areRelevantEventsSet()) {
214 // Possible clash of relevantEvents and disableDC was already considered in FaultTreeSettings::check().
215 additionalRelevantEventNames = faultTreeSettings.getRelevantEvents();
216 } else if (faultTreeSettings.isDisableDC()) {
217 // All events are relevant
218 additionalRelevantEventNames = {"all"};
219 }
220 storm::dft::utility::RelevantEvents relevantEvents = storm::dft::api::computeRelevantEvents(props, additionalRelevantEventNames);
221
222 // Analyze DFT by translation to CTMC/MA
223 dft = storm::dft::api::prepareForMarkovAnalysis<ValueType>(*dft);
224 STORM_LOG_DEBUG("DFT after preparation for Markov analysis:\n" << dft->getElementsString());
225
226 // Check which FDEPs actually introduce conflicts which need non-deterministic resolution
227 bool hasConflicts = storm::dft::api::computeDependencyConflicts(*dft, useSMT, solverTimeout);
228 if (hasConflicts) {
229 STORM_LOG_DEBUG("FDEP conflicts found.");
230 } else {
231 STORM_LOG_DEBUG("No FDEP conflicts found.");
232 }
233
234 // TODO allow building of state space even without properties
235 if (props.empty()) {
236 STORM_LOG_WARN("No property given. No analysis will be performed.");
237 } else {
238 double approximationError = 0.0;
239 if (faultTreeSettings.isApproximationErrorSet()) {
240 approximationError = faultTreeSettings.getApproximationError();
241 }
242 storm::dft::api::analyzeDFT<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), relevantEvents,
243 faultTreeSettings.isAllowDCForRelevantEvents(), approximationError,
244 faultTreeSettings.getApproximationHeuristic(), transformationSettings.isChainEliminationSet(),
245 transformationSettings.getLabelBehavior(), true);
246 }
247}
248
249void process() {
250 storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
251 if (generalSettings.isParametricSet()) {
252 processOptions<storm::RationalFunction>();
253 } else if (generalSettings.isExactSet()) {
254 STORM_LOG_WARN("Exact solving over rational numbers is not implemented. Performing exact solving using rational functions instead.");
255 processOptions<storm::RationalFunction>();
256 } else {
257 processOptions<double>();
258 }
259}
260
268int main(const int argc, const char** argv) {
269 try {
270 return storm::cli::process("Storm-dft", "storm-dft", storm::dft::settings::initializeDftSettings, process, argc, argv);
271 } catch (storm::exceptions::BaseException const& exception) {
272 STORM_LOG_ERROR("An exception caused Storm-DFT to terminate. The message of the exception is: " << exception.what());
273 return 1;
274 } catch (std::exception const& exception) {
275 STORM_LOG_ERROR("An unexpected exception occurred and caused Storm-DFT to terminate. The message of this exception is: " << exception.what());
276 return 2;
277 }
278}
static std::vector< size_t > parseBEOrder(std::string const &filename, storm::dft::storage::DFT< ValueType > const &dft)
Parse BE order from given file.
This class represents the base class of all exception classes.
virtual const char * what() const noexcept override
Retrieves the message associated with this exception.
This class represents the general settings.
bool isExactSet() const
Retrieves whether the option enabling exact model checking is set and we should use infinite precisio...
bool isParametricSet() const
Retrieves whether the option enabling parametric model checking is set.
#define STORM_LOG_WARN(message)
Definition logging.h:25
#define STORM_LOG_DEBUG(message)
Definition logging.h:18
#define STORM_LOG_ERROR(message)
Definition logging.h:26
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:38
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
std::vector< storm::jani::Property > parseProperties(storm::parser::FormulaParser &formulaParser, std::string const &inputString, boost::optional< std::set< std::string > > const &propertyFilter)
void handleGSPNExportSettings(storm::gspn::GSPN const &gspn, std::function< std::vector< storm::jani::Property >(storm::builder::JaniGSPNBuilder const &)> const &janiProperyGetter)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
int process(std::string const &name, std::string const &executableName, std::function< void(std::string const &, std::string const &)> initSettingsFunc, std::function< void(void)> processOptionsFunc, const int argc, const char **argv)
Processes the options and returns the exit code.
Definition cli.cpp:84
std::pair< uint64_t, uint64_t > computeBEFailureBounds(storm::dft::storage::DFT< ValueType > const &dft, bool useSMT, double solverTimeout)
Definition storm-dft.h:124
std::shared_ptr< storm::jani::Model > transformToJani(storm::gspn::GSPN const &gspn, uint64_t toplevelFailedPlace)
Transform GSPN to Jani model.
std::pair< bool, std::string > isWellFormed(storm::dft::storage::DFT< ValueType > const &dft, bool validForMarkovianAnalysis=true)
Check whether the DFT is well-formed.
Definition storm-dft.h:63
std::pair< std::shared_ptr< storm::gspn::GSPN >, uint64_t > transformToGSPN(storm::dft::storage::DFT< double > const &dft)
storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector< std::shared_ptr< storm::logic::Formula const > > const &properties, std::vector< std::string > const &additionalRelevantEventNames)
Get relevant event ids from given relevant event names and labels in properties.
std::pair< bool, std::string > hasPotentialModelingIssues(storm::dft::storage::DFT< ValueType > const &dft)
Check whether the DFT has potential modeling issues.
Definition storm-dft.h:81
void analyzeDFTSMT(storm::dft::storage::DFT< double > const &dft, bool printOutput)
std::shared_ptr< storm::dft::storage::DFT< ValueType > > applyTransformations(storm::dft::storage::DFT< ValueType > const &dft, bool uniqueBE, bool binaryFDEP, bool exponentialDistributions)
Apply transformations for DFT.
Definition storm-dft.h:97
bool computeDependencyConflicts(storm::dft::storage::DFT< ValueType > &dft, bool useSMT, double solverTimeout)
Definition storm-dft.h:131
void initializeDftSettings(std::string const &name, std::string const &executableName)
void processOptions()
Process commandline options and start computations.
Definition storm-dft.cpp:21
void process()
int main(const int argc, const char **argv)
Entry point for Storm-DFT.