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