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