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