Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
storm-dft.cpp
Go to the documentation of this file.
9#include "storm-dft/api/io.h"
21#include "storm/api/export.h"
30
37
40
41 // Analysis environment
42 auto& analysis = dftEnv.analysis();
43 analysis.setUseModularisation(ftSettings.useModularisation());
44#ifdef STORM_HAVE_Z3
45 analysis.setSolveWithSMT(ftSettings.solveWithSMT());
46#else
47 analysis.setSolveWithSMT(false);
48#endif
49 analysis.setChunksize(ftSettings.getChunksize());
50 analysis.setMttfPrecision(ftSettings.getMttfPrecision());
51 analysis.setMttfStepsize(ftSettings.getMttfStepsize());
52 analysis.setMttfAlgorithm(ftSettings.getMttfAlgorithm());
53 if (ftSettings.isApproximationErrorSet()) {
54 analysis.setApproximationError(ftSettings.getApproximationError());
55 }
56 analysis.setApproximationHeuristic(ftSettings.getApproximationHeuristic());
57
58 // Model builder environment
59 auto& modelBuilder = dftEnv.modelBuilder();
60 modelBuilder.setUseSymmetryReduction(ftSettings.useSymmetryReduction());
61 modelBuilder.setAllowDCForRelevantEvents(ftSettings.isAllowDCForRelevantEvents());
62 modelBuilder.setAddLabelsClaiming(ftSettings.isAddLabelsClaiming());
63 if (ftSettings.isMaxDepthSet()) {
64 modelBuilder.setMaxDepth(ftSettings.getMaxDepth());
65 }
66 modelBuilder.setTakeFirstDependency(ftSettings.isTakeFirstDependency());
67 modelBuilder.setUniqueFailedBE(ftSettings.isUniqueFailedBE());
68
69 // Transformation environment
70 auto& transformation = dftEnv.transformation();
72 transformation.setEliminateChains(transformationSettings.isChainEliminationSet());
73 transformation.setLabelBehavior(transformationSettings.getLabelBehavior());
74
75 return dftEnv;
76}
77
81template<typename ValueType>
88
89 // Build DFT from given file
90 std::shared_ptr<storm::dft::storage::DFT<ValueType>> dft;
91 if (dftIOSettings.isDftFileSet()) {
92 STORM_LOG_DEBUG("Loading DFT from Galileo file " << dftIOSettings.getDftFilename());
93 dft = storm::dft::api::loadDFTGalileoFile<ValueType>(dftIOSettings.getDftFilename());
94 } else if (dftIOSettings.isDftJsonFileSet()) {
95 STORM_LOG_DEBUG("Loading DFT from Json file " << dftIOSettings.getDftJsonFilename());
96 dft = storm::dft::api::loadDFTJsonFile<ValueType>(dftIOSettings.getDftJsonFilename());
97 } else {
98 STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No input model given.");
99 }
100
101 // Show statistics about DFT (number of gates, etc.)
102 if (dftIOSettings.isShowDftStatisticsSet()) {
103 dft->writeStatsToStream(std::cout);
104 std::cout << '\n';
105 }
106
107 // Export to json
108 if (dftIOSettings.isExportToJson()) {
109 storm::dft::api::exportDFTToJsonFile<ValueType>(*dft, dftIOSettings.getExportJsonFilename());
110 }
111
112 // Check well-formedness of DFT
113 auto wellFormedResult = storm::dft::api::isWellFormed(*dft, false);
114 STORM_LOG_THROW(wellFormedResult.first, storm::exceptions::UnmetRequirementException, "DFT is not well-formed: " << wellFormedResult.second << ".");
115 // Warn about potential modeling issues
116 auto modelingIssues = storm::dft::api::hasPotentialModelingIssues(*dft);
117 STORM_LOG_WARN_COND(!modelingIssues.first, modelingIssues.second);
118
119 // Transformation to GSPN
120 if (dftGspnSettings.isTransformToGspn()) {
122 std::pair<std::shared_ptr<storm::gspn::GSPN>, uint64_t> pair =
123 storm::dft::api::transformToGSPN(*dft, !faultTreeSettings.isDisableDC(), dftGspnSettings.isExtendPriorities(),
124 !dftGspnSettings.isDisableSmartTransformation(), dftGspnSettings.isMergeDCFailed());
125 std::shared_ptr<storm::gspn::GSPN> gspn = pair.first;
126 uint64_t toplevelFailedPlace = pair.second;
127
128 // Handle GSPN exports
129 if (gspnExportSettings.isWriteToDotSet()) {
130 storm::api::exportGspnToDot(*gspn, gspnExportSettings.getWriteToDotFilename());
131 }
132 if (gspnExportSettings.isWriteToPnproSet()) {
133 storm::api::exportGspnToPnpro(*gspn, gspnExportSettings.getWriteToPnproFilename());
134 }
135 if (gspnExportSettings.isWriteToPnmlSet()) {
136 storm::api::exportGspnToPnml(*gspn, gspnExportSettings.getWriteToPnmlFilename());
137 }
138 if (gspnExportSettings.isWriteToJsonSet()) {
139 storm::api::exportGspnToJson(*gspn, gspnExportSettings.getWriteToJsonFilename());
140 }
141 if (gspnExportSettings.isDisplayStatsSet()) {
142 std::cout << "============GSPN Statistics==============\n";
143 storm::api::printGspnStatsToStream(*gspn, std::cout);
144 std::cout << "=========================================\n";
145 }
146 if (gspnExportSettings.isWriteStatsToFileSet()) {
147 storm::api::exportGspnStatsToFile(*gspn, gspnExportSettings.getWriteStatsFilename());
148 }
149
150 // Transform to Jani
151 // TODO analyse Jani model
152 auto [model, properties] = storm::dft::api::transformToJani(*gspn, toplevelFailedPlace, gspnExportSettings.isAddJaniPropertiesSet());
153 if (gspnExportSettings.isWriteToJaniSet()) {
155 storm::api::exportJaniToFile(*model, properties, gspnExportSettings.getWriteToJaniFilename(), compactJson);
156 }
157 return;
158 }
159
160 // Export to SMT
161 if (dftIOSettings.isExportToSmt()) {
162 storm::dft::api::exportDFTToSMT<ValueType>(*dft, dftIOSettings.getExportSmtFilename());
163 return;
164 }
165
166 bool useSMT = false;
167 uint64_t solverTimeout = 10;
168#ifdef STORM_HAVE_Z3
169 if (dftEnv.analysis().isSolveWithSMT()) {
170 useSMT = true;
171 STORM_LOG_DEBUG("Use SMT for preprocessing");
172 }
173#endif
174
175 // Apply transformations
176 // TODO transform later before actual analysis
177 dft = storm::dft::api::applyTransformations(*dft, dftEnv.modelBuilder().isUniqueFailedBE(), true, false);
178 STORM_LOG_DEBUG(dft->getElementsString());
179
180 // Compute minimal number of BE failures leading to system failure and
181 // maximal number of BE failures not leading to system failure yet.
182 // TODO: always needed?
183 auto bounds = storm::dft::api::computeBEFailureBounds(*dft, useSMT, solverTimeout);
184 STORM_LOG_DEBUG("BE failure bounds: lower bound: " << bounds.first << ", upper bound: " << bounds.second << ".");
185
186#ifdef STORM_HAVE_Z3
187 if (useSMT) {
188 // Solve with SMT
189 STORM_LOG_DEBUG("Running DFT analysis with use of SMT.");
190 // Set dynamic behavior vector
192 }
193#endif
194
195 // BDD Analysis
196 if (dftIOSettings.isExportToBddDot() || dftIOSettings.isAnalyzeWithBdds() || dftIOSettings.isMinimalCutSets() || dftIOSettings.isImportanceMeasureSet()) {
197 bool const isImportanceMeasureSet{dftIOSettings.isImportanceMeasureSet()};
198 bool const isMinimalCutSets{dftIOSettings.isMinimalCutSets()};
199 bool const isMTTF{dftIOSettings.usePropExpectedTime()};
200 double const mttfPrecision{dftEnv.analysis().getMttfPrecision()};
201 double const mttfStepsize{dftEnv.analysis().getMttfStepsize()};
202 std::string const mttfAlgorithm{dftEnv.analysis().getMttfAlgorithm()};
203 bool const isExportToBddDot{dftIOSettings.isExportToBddDot()};
204 bool const isTimebound{dftIOSettings.usePropTimebound()};
205 bool const isTimepoints{dftIOSettings.usePropTimepoints()};
206
207 bool const probabilityAnalysis{ioSettings.isPropertySet() || !isImportanceMeasureSet};
208 size_t const chunksize{dftEnv.analysis().getChunksize()};
209 bool const isModularisation{dftEnv.analysis().isUseModularisation()};
210
211 std::vector<double> timepoints{};
212 if (isTimepoints) {
213 timepoints = dftIOSettings.getPropTimepoints();
214 }
215 if (isTimebound) {
216 timepoints.push_back(dftIOSettings.getPropTimebound());
217 }
218
219 std::string filename{""};
220 if (isExportToBddDot) {
221 filename = dftIOSettings.getExportBddDotFilename();
222 }
223
224 // gather manually inputted properties
225 std::vector<std::shared_ptr<storm::logic::Formula const>> manuallyInputtedProperties;
226 if (ioSettings.isPropertySet()) {
227 manuallyInputtedProperties = storm::api::extractFormulasFromProperties(storm::api::parseProperties(ioSettings.getProperty()));
228 }
229
230 std::string importanceMeasureName{""};
231 if (isImportanceMeasureSet) {
232 importanceMeasureName = dftIOSettings.getImportanceMeasure();
233 }
234
235 // Set variable ordering
236 if (dftIOSettings.isVariableOrderingFileSet()) {
237 auto beOrder = storm::dft::parser::BEOrderParser<ValueType>::parseBEOrder(dftIOSettings.getVariableOrderingFilename(), *dft);
238 dft->setBEOrder(beOrder);
239 }
240
241 auto const additionalRelevantEventNames{faultTreeSettings.getRelevantEvents()};
242 storm::dft::api::analyzeDFTBdd<ValueType>(dftEnv, dft, isExportToBddDot, filename, isMTTF, mttfPrecision, mttfStepsize, mttfAlgorithm, isMinimalCutSets,
243 probabilityAnalysis, isModularisation, importanceMeasureName, timepoints, manuallyInputtedProperties,
244 additionalRelevantEventNames, chunksize);
245
246 // don't perform other analysis if analyzeWithBdds is set
247 if (dftIOSettings.isAnalyzeWithBdds()) {
248 return;
249 }
250 }
251
252 // From now on we analyse the DFT via model checking
253
254 // Set min or max
255 std::string optimizationDirection = "min";
256 if (dftIOSettings.isComputeMaximalValue()) {
257 optimizationDirection = "max";
258 }
259
260 // Construct properties to analyse.
261 // We allow multiple properties to be checked at once.
262 std::vector<std::string> properties;
263 if (ioSettings.isPropertySet()) {
264 properties.push_back(ioSettings.getProperty());
265 }
266 if (dftIOSettings.usePropExpectedTime()) {
267 properties.push_back("T" + optimizationDirection + "=? [F \"failed\"]");
268 }
269 if (dftIOSettings.usePropProbability()) {
270 properties.push_back("P" + optimizationDirection + "=? [F \"failed\"]");
271 }
272 if (dftIOSettings.usePropTimebound()) {
273 std::stringstream stream;
274 stream << "P" << optimizationDirection << "=? [F<=" << dftIOSettings.getPropTimebound() << " \"failed\"]";
275 properties.push_back(stream.str());
276 }
277 if (dftIOSettings.usePropTimepoints()) {
278 for (double timepoint : dftIOSettings.getPropTimepoints()) {
279 std::stringstream stream;
280 stream << "P" << optimizationDirection << "=? [F<=" << timepoint << " \"failed\"]";
281 properties.push_back(stream.str());
282 }
283 }
284
285 // Build properties
286 std::vector<std::shared_ptr<storm::logic::Formula const>> props;
287 if (!properties.empty()) {
288 std::string propString;
289 for (size_t i = 0; i < properties.size(); ++i) {
290 propString += properties[i];
291 if (i + 1 < properties.size()) {
292 propString += ";";
293 }
294 }
296 }
297
298 // Set relevant event names
299 std::vector<std::string> additionalRelevantEventNames;
300 if (faultTreeSettings.areRelevantEventsSet()) {
301 // Possible clash of relevantEvents and disableDC was already considered in FaultTreeSettings::check().
302 additionalRelevantEventNames = faultTreeSettings.getRelevantEvents();
303 } else if (faultTreeSettings.isDisableDC()) {
304 // All events are relevant
305 additionalRelevantEventNames = {"all"};
306 }
308 storm::dft::api::computeRelevantEvents(props, additionalRelevantEventNames, dftEnv.modelBuilder().isAddLabelsClaiming());
309
310 // Analyze DFT by translation to CTMC/MA
312 STORM_LOG_DEBUG("DFT after preparation for Markov analysis:\n" << dft->getElementsString());
313
314 // Check which FDEPs actually introduce conflicts which need non-deterministic resolution
315 bool hasConflicts = storm::dft::api::computeDependencyConflicts(*dft, useSMT, solverTimeout);
316 if (hasConflicts) {
317 STORM_LOG_DEBUG("FDEP conflicts found.");
318 } else {
319 STORM_LOG_DEBUG("No FDEP conflicts found.");
320 }
321
322 // TODO allow building of state space even without properties
323 if (props.empty()) {
324 STORM_LOG_WARN("No property given. No analysis will be performed.");
325 } else {
326 auto exportCallback = [&ioSettings](std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, bool isFinalModel) {
327 if (ioSettings.isExportExplicitSet()) {
328 std::vector<std::string> parameterNames;
329 storm::api::exportSparseModelAsDrn(model, ioSettings.getExportExplicitFilename(), parameterNames,
330 !ioSettings.isExplicitExportPlaceholdersDisabled());
331 }
332 if (isFinalModel && ioSettings.isExportDotSet()) {
333 storm::api::exportSparseModelAsDot(model, ioSettings.getExportDotFilename(), ioSettings.getExportDotMaxWidth());
334 }
335 };
336 storm::dft::api::analyzeDFT<ValueType>(dftEnv, *dft, props, relevantEvents, true, exportCallback);
337 }
338}
339
340void process() {
342 if (generalSettings.isParametricSet()) {
344 } else if (generalSettings.isExactSet()) {
345 STORM_LOG_WARN("Exact solving over rational numbers is not implemented. Performing exact solving using rational functions instead.");
347 } else {
349 }
350}
351
361
369int main(const int argc, const char** argv) {
370 try {
371 return storm::cli::process("Storm-dft", "storm-dft", initializeDftCliSettings, process, argc, argv);
372 } catch (storm::exceptions::BaseException const& exception) {
373 STORM_LOG_ERROR("An exception caused Storm-DFT to terminate. The message of the exception is: " << exception.what());
374 return 1;
375 } catch (std::exception const& exception) {
376 STORM_LOG_ERROR("An unexpected exception occurred and caused Storm-DFT to terminate. The message of this exception is: " << exception.what());
377 return 2;
378 }
379}
std::string const & getMttfAlgorithm() const
Environment for storm-dft.
AnalysisEnvironment & analysis()
ModelBuilderEnvironment & modelBuilder()
TransformationEnvironment & transformation()
storm::Environment & core()
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.
static storm::Environment buildEnvironment()
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:35
#define STORM_LOG_DEBUG(message)
Definition logging.h:28
#define STORM_LOG_ERROR(message)
Definition logging.h:36
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:54
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
void exportJaniToFile(storm::jani::Model const &model, std::vector< storm::jani::Property > const &properties, std::string const &filename, bool compact)
void exportGspnToPnpro(storm::gspn::GSPN const &gspn, std::string const &filename)
void exportGspnToPnml(storm::gspn::GSPN const &gspn, std::string const &filename)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
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 exportGspnToJson(storm::gspn::GSPN const &gspn, std::string const &filename)
void exportGspnToDot(storm::gspn::GSPN const &gspn, std::string const &filename)
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 exportGspnStatsToFile(storm::gspn::GSPN const &gspn, std::string const &filename)
std::vector< storm::jani::Property > parseProperties(storm::parser::FormulaParser &formulaParser, std::string const &inputString, boost::optional< std::set< std::string > > const &propertyFilter)
void printGspnStatsToStream(storm::gspn::GSPN const &gspn, std::ostream &out)
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:96
std::shared_ptr< storm::dft::storage::DFT< ValueType > > prepareForMarkovAnalysis(storm::dft::storage::DFT< ValueType > const &dft)
Apply transformations to make DFT feasible for Markovian analysis.
std::pair< uint64_t, uint64_t > computeBEFailureBounds(storm::dft::storage::DFT< ValueType > const &dft, bool useSMT, double solverTimeout)
Definition analysis.cpp:217
std::pair< std::shared_ptr< storm::gspn::GSPN >, uint64_t > transformToGSPN(storm::dft::storage::DFT< double > const &dft, bool enableDC, bool extendPriorities, bool enableSmartTransformation, bool mergeDCFailed)
void exportDFTToJsonFile(storm::dft::storage::DFT< ValueType > const &dft, std::string const &file)
Export DFT to JSON file.
Definition io.cpp:29
std::pair< std::shared_ptr< storm::jani::Model >, std::vector< storm::jani::Property > > transformToJani(storm::gspn::GSPN const &gspn, uint64_t toplevelFailedPlace, bool addDeadlockProperties)
Transform GSPN to Jani model.
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.
std::shared_ptr< storm::dft::storage::DFT< ValueType > > loadDFTGalileoFile(std::string const &file)
Load DFT from Galileo file.
Definition io.cpp:14
storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector< std::shared_ptr< storm::logic::Formula const > > const &properties, std::vector< std::string > const &additionalRelevantEventNames, bool addLabelsClaiming)
Get relevant event ids from given relevant event names and labels in properties.
Definition analysis.cpp:19
std::shared_ptr< storm::dft::storage::DFT< ValueType > > loadDFTJsonFile(std::string const &file)
Load DFT from JSON file.
Definition io.cpp:24
std::pair< bool, std::string > isWellFormed(storm::dft::storage::DFT< ValueType > const &dft, bool validForMarkovianAnalysis)
Check whether the DFT is well-formed.
void analyzeDFTBdd(storm::dft::DftEnvironment const &env, std::shared_ptr< storm::dft::storage::DFT< double > > const &dft, bool const exportToDot, std::string const &filename, bool const calculateMttf, double const mttfPrecision, double const mttfStepsize, std::string const mttfAlgorithmName, bool const calculateMCS, bool const calculateProbability, bool const useModularisation, std::string const importanceMeasureName, std::vector< double > const &timepoints, std::vector< std::shared_ptr< storm::logic::Formula const > > const &properties, std::vector< std::string > const &additionalRelevantEventNames, size_t const chunksize)
Definition analysis.cpp:41
void exportDFTToSMT(storm::dft::storage::DFT< double > const &dft, std::string const &file)
Definition io.cpp:41
void analyzeDFTSMT(storm::dft::storage::DFT< double > const &dft, bool printOutput)
Definition analysis.cpp:200
std::pair< bool, std::string > hasPotentialModelingIssues(storm::dft::storage::DFT< ValueType > const &dft)
Check whether the DFT has potential modeling issues.
storm::dft::modelchecker::DFTModelChecker< ValueType >::dft_results analyzeDFT(storm::dft::DftEnvironment const &env, storm::dft::storage::DFT< ValueType > const &dft, std::vector< std::shared_ptr< storm::logic::Formula const > > const &properties, storm::dft::utility::RelevantEvents const &relevantEvents, bool printOutput, typename storm::dft::modelchecker::DFTModelChecker< ValueType >::ModelExportCallback const &exportCallback)
Compute the exact or approximate analysis result of the given DFT according to the given properties.
Definition analysis.cpp:27
bool computeDependencyConflicts(storm::dft::storage::DFT< ValueType > &dft, bool useSMT, double solverTimeout)
Definition analysis.cpp:224
void initializeDftSettings(std::string const &name, std::string const &executableName)
SettingsType const & getModule()
Get module.
void addModule(bool doRegister=true)
Add new module to use for the settings.
void processOptions()
Process commandline options and start computations.
Definition storm-dft.cpp:82
void process()
void initializeDftCliSettings(std::string const &name, std::string const &executableName)
Register the settings modules relevant for the Storm-DFT CLI.
storm::dft::DftEnvironment createDftEnvironmentFromSettings()
Create the DFT environment from the commandline arguments.
Definition storm-dft.cpp:34
int main(const int argc, const char **argv)
Entry point for Storm-DFT.