Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
storm-dft.cpp
Go to the documentation of this file.
2
7
8#include <memory>
9#include <vector>
18
19namespace storm::dft {
20namespace api {
21
22template<>
23void analyzeDFTBdd(std::shared_ptr<storm::dft::storage::DFT<double>> const& dft, bool const exportToDot, std::string const& filename, bool const calculateMttf,
24 double const mttfPrecision, double const mttfStepsize, std::string const mttfAlgorithmName, bool const calculateMCS,
25 bool const calculateProbability, bool const useModularisation, std::string const importanceMeasureName,
26 std::vector<double> const& timepoints, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
27 std::vector<std::string> const& additionalRelevantEventNames, size_t const chunksize) {
28 if (calculateMttf) {
29 if (mttfAlgorithmName == "proceeding") {
30 std::cout << "The numerically approximated MTTF is " << storm::dft::utility::MTTFHelperProceeding(dft, mttfStepsize, mttfPrecision) << '\n';
31 } else if (mttfAlgorithmName == "variableChange") {
32 std::cout << "The numerically approximated MTTF is " << storm::dft::utility::MTTFHelperVariableChange(dft, mttfStepsize) << '\n';
33 }
34 }
35
36 if (useModularisation && calculateProbability) {
38 if (chunksize == 1) {
39 for (auto const& timebound : timepoints) {
40 auto const probability{checker.getProbabilityAtTimebound(timebound)};
41 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
42 }
43 } else {
44 auto const probabilities{checker.getProbabilitiesAtTimepoints(timepoints, chunksize)};
45 for (size_t i{0}; i < timepoints.size(); ++i) {
46 auto const timebound{timepoints[i]};
47 auto const probability{probabilities[i]};
48 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
49 }
50 }
51 if (!properties.empty()) {
52 auto const probabilities{checker.check(properties, chunksize)};
53 for (size_t i{0}; i < probabilities.size(); ++i) {
54 std::cout << "Property \"" << properties.at(i)->toString() << "\" has result " << probabilities.at(i) << '\n';
55 }
56 }
57 return;
58 } else {
59 STORM_LOG_THROW(dft->nrDynamicElements() == 0, storm::exceptions::NotSupportedException,
60 "DFT is dynamic. "
61 "Bdds can only be used on static fault trees. "
62 "Try modularisation.");
63 }
64
65 auto sylvanBddManager{std::make_shared<storm::dft::storage::SylvanBddManager>()};
66 sylvanBddManager->execute([&]() {
67 storm::dft::utility::RelevantEvents relevantEvents{additionalRelevantEventNames.begin(), additionalRelevantEventNames.end()};
68 storm::dft::adapters::SFTBDDPropertyFormulaAdapter adapter{dft, properties, relevantEvents, sylvanBddManager};
69 auto checker{adapter.getSFTBDDChecker()};
70
71 if (exportToDot) {
72 checker->exportBddToDot(filename);
73 }
74
75 if (calculateMCS) {
76 auto const minimalCutSets{checker->getMinimalCutSetsAsIndices()};
77 auto const sylvanBddManager{checker->getSylvanBddManager()};
78
79 std::cout << "{\n";
80 for (auto const& minimalCutSet : minimalCutSets) {
81 std::cout << '{';
82 for (auto const& be : minimalCutSet) {
83 std::cout << sylvanBddManager->getName(be) << ' ';
84 }
85 std::cout << "},\n";
86 }
87 std::cout << "}\n";
88 }
89
90 if (calculateProbability) {
91 if (chunksize == 1) {
92 for (auto const& timebound : timepoints) {
93 auto const probability{checker->getProbabilityAtTimebound(timebound)};
94 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
95 }
96 } else {
97 auto const probabilities{checker->getProbabilitiesAtTimepoints(timepoints, chunksize)};
98 for (size_t i{0}; i < timepoints.size(); ++i) {
99 auto const timebound{timepoints[i]};
100 auto const probability{probabilities[i]};
101 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
102 }
103 }
104
105 if (!properties.empty()) {
106 auto const probabilities{adapter.check(chunksize)};
107 for (size_t i{0}; i < probabilities.size(); ++i) {
108 std::cout << "Property \"" << properties.at(i)->toString() << "\" has result " << probabilities.at(i) << '\n';
109 }
110 }
111 }
112
113 if (importanceMeasureName != "" && timepoints.size() == 1) {
114 auto const bes{dft->getBasicElements()};
115 std::vector<double> values{};
116 if (importanceMeasureName == "MIF") {
117 values = checker->getAllBirnbaumFactorsAtTimebound(timepoints[0]);
118 }
119 if (importanceMeasureName == "CIF") {
120 values = checker->getAllCIFsAtTimebound(timepoints[0]);
121 }
122 if (importanceMeasureName == "DIF") {
123 values = checker->getAllDIFsAtTimebound(timepoints[0]);
124 }
125 if (importanceMeasureName == "RAW") {
126 values = checker->getAllRAWsAtTimebound(timepoints[0]);
127 }
128 if (importanceMeasureName == "RRW") {
129 values = checker->getAllRRWsAtTimebound(timepoints[0]);
130 }
131
132 for (size_t i{0}; i < bes.size(); ++i) {
133 std::cout << importanceMeasureName << " for the basic event " << bes[i]->name() << " at timebound " << timepoints[0] << " is " << values[i]
134 << '\n';
135 }
136 } else if (importanceMeasureName != "") {
137 auto const bes{dft->getBasicElements()};
138 std::vector<std::vector<double>> values{};
139 if (importanceMeasureName == "MIF") {
140 values = checker->getAllBirnbaumFactorsAtTimepoints(timepoints, chunksize);
141 }
142 if (importanceMeasureName == "CIF") {
143 values = checker->getAllCIFsAtTimepoints(timepoints, chunksize);
144 }
145 if (importanceMeasureName == "DIF") {
146 values = checker->getAllDIFsAtTimepoints(timepoints, chunksize);
147 }
148 if (importanceMeasureName == "RAW") {
149 values = checker->getAllRAWsAtTimepoints(timepoints, chunksize);
150 }
151 if (importanceMeasureName == "RRW") {
152 values = checker->getAllRRWsAtTimepoints(timepoints, chunksize);
153 }
154 for (size_t i{0}; i < bes.size(); ++i) {
155 for (size_t j{0}; j < timepoints.size(); ++j) {
156 std::cout << importanceMeasureName << " for the basic event " << bes[i]->name() << " at timebound " << timepoints[j] << " is "
157 << values[i][j] << '\n';
158 }
159 }
160 }
161 });
162}
163
164template<>
165void analyzeDFTBdd(std::shared_ptr<storm::dft::storage::DFT<storm::RationalFunction>> const& dft, bool const exportToDot, std::string const& filename,
166 bool const calculateMttf, double const mttfPrecision, double const mttfStepsize, std::string const mttfAlgorithmName,
167 bool const calculateMCS, bool const calculateProbability, bool const useModularisation, std::string const importanceMeasureName,
168 std::vector<double> const& timepoints, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
169 std::vector<std::string> const& additionalRelevantEventNames, size_t const chunksize) {
170 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "BDD analysis is not supportet for this data type.");
171}
172
173template<typename ValueType>
177
178template<typename ValueType>
180 std::stringstream stream;
182 return stream.str();
183}
184
185template<>
186void exportDFTToSMT(storm::dft::storage::DFT<double> const& dft, std::string const& file) {
188 asfChecker.convert();
189 asfChecker.toFile(file);
190}
191
192template<>
193void exportDFTToSMT(storm::dft::storage::DFT<storm::RationalFunction> const& dft, std::string const& file) {
194 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to SMT does not support this data type.");
195}
196
197template<>
198void analyzeDFTSMT(storm::dft::storage::DFT<double> const& dft, bool printOutput) {
199 uint64_t solverTimeout = 10;
200
202 smtChecker.toSolver();
203 // Removed bound computation etc. here
204 smtChecker.setSolverTimeout(solverTimeout);
205 smtChecker.checkTleNeverFailed();
206 smtChecker.unsetSolverTimeout();
207}
208
209template<>
211 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Analysis by SMT not supported for this data type.");
212}
213
214template<>
215std::pair<std::shared_ptr<storm::gspn::GSPN>, uint64_t> transformToGSPN(storm::dft::storage::DFT<double> const& dft) {
218
219 // Set Don't Care elements
220 std::set<uint64_t> dontCareElements;
221 if (!ftSettings.isDisableDC()) {
222 // Insert all elements as Don't Care elements
223 for (std::size_t i = 0; i < dft.nrElements(); i++) {
224 dontCareElements.insert(dft.getElement(i)->id());
225 }
226 }
227
228 // Transform to GSPN
230 auto priorities = gspnTransformator.computePriorities(dftGspnSettings.isExtendPriorities());
231 gspnTransformator.transform(priorities, dontCareElements, !dftGspnSettings.isDisableSmartTransformation(), dftGspnSettings.isMergeDCFailed(),
232 dftGspnSettings.isExtendPriorities());
233 std::shared_ptr<storm::gspn::GSPN> gspn(gspnTransformator.obtainGSPN());
234 return std::make_pair(gspn, gspnTransformator.toplevelFailedPlaceId());
235}
236
237template<>
238std::pair<std::shared_ptr<storm::gspn::GSPN>, uint64_t> transformToGSPN(storm::dft::storage::DFT<storm::RationalFunction> const& dft) {
239 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Transformation to GSPN not supported for this data type.");
240}
241
242std::shared_ptr<storm::jani::Model> transformToJani(storm::gspn::GSPN const& gspn, uint64_t toplevelFailedPlace) {
243 // Build Jani model
245 std::shared_ptr<storm::jani::Model> model(builder.build("dft_gspn"));
246
247 // Build properties
248 std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn.getExpressionManager();
249 storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace);
250 storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression();
251 // Add variable for easier access to 'failed' state
252 builder.addTransientVariable(model.get(), "failed", targetExpression);
253 auto failedFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression);
254 auto properties = builder.getStandardProperties(model.get(), failedFormula, "Failed", "a failed state", true);
255
256 // Export Jani to file
258 if (dftGspnSettings.isWriteToJaniSet()) {
260 storm::api::exportJaniToFile(*model, properties, dftGspnSettings.getWriteToJaniFilename(), jani.isCompactJsonSet());
261 }
262
263 return model;
264}
265
266storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
267 std::vector<std::string> const& additionalRelevantEventNames) {
268 storm::dft::utility::RelevantEvents events(additionalRelevantEventNames.begin(), additionalRelevantEventNames.end());
269 events.insertNamesFromProperties(properties.begin(), properties.end());
270 return events;
271}
272
273// Explicitly instantiate methods
274template void exportDFTToJsonFile(storm::dft::storage::DFT<double> const&, std::string const&);
276
279
280} // namespace api
281} // namespace storm::dft
storm::jani::Model * build(std::string const &automatonName="gspn_automaton")
std::vector< storm::jani::Property > getStandardProperties(storm::jani::Model *model, std::shared_ptr< storm::logic::AtomicExpressionFormula > atomicFormula, std::string name, std::string description, bool maximal)
Get standard properties (reachability, time bounded reachability, expected time) for a given atomic f...
storm::jani::Variable const & getPlaceVariable(uint64_t placeId) const
storm::jani::Variable const & addTransientVariable(storm::jani::Model *model, std::string name, storm::expressions::Expression expression)
Add transient variable representing given expression.
std::shared_ptr< storm::dft::modelchecker::SFTBDDChecker > getSFTBDDChecker() const noexcept
void setSolverTimeout(uint_fast64_t milliseconds)
Set the timeout of the solver.
void convert()
Generate general variables and constraints for the DFT and store them in the corresponding maps and v...
void toSolver()
Generates a new solver instance and prepares it for SMT checking of the DFT.
void unsetSolverTimeout()
Unset the timeout for the solver.
storm::solver::SmtSolver::CheckResult checkTleNeverFailed()
Check if the TLE of the DFT never fails.
ValueType getProbabilityAtTimebound(ValueType const timebound)
Calculate the probability of failure for the given time bound.
This class represents the settings for operations concerning the DFT to GSPN transformation.
bool isExtendPriorities() const
Retrieves whether the experimental setting of priorities should be used.
bool isDisableSmartTransformation() const
Retrieves whether the smart transformation should be disabled.
bool isWriteToJaniSet() const
Retrieves whether the GSPN should be exported as a Jani file.
bool isMergeDCFailed() const
Retrieves whether the DC and failed place should be merged.
std::string getWriteToJaniFilename() const
Retrieves the jani filename for export.
This class represents the settings for DFT model checking.
bool isDisableDC() const
Retrieves whether the option to disable Dont Care propagation is set.
Represents a Dynamic Fault Tree.
Definition DFT.h:52
DFTElementCPointer getElement(size_t index) const
Get a pointer to an element in the DFT.
Definition DFT.h:188
size_t nrElements() const
Definition DFT.h:94
static void toFile(storm::dft::storage::DFT< ValueType > const &dft, std::string const &filepath)
Export DFT to given file.
static void toStream(storm::dft::storage::DFT< ValueType > const &dft, std::ostream &os)
Export DFT to given stream.
void transform(std::map< uint64_t, uint64_t > const &priorities, std::set< uint64_t > const &dontCareElements, bool smart=true, bool mergeDCFailed=true, bool extendPriorities=false)
Transform the DFT to a GSPN.
uint64_t toplevelFailedPlaceId()
Get failed place id of top level element.
std::map< uint64_t, uint64_t > computePriorities(bool extendedPrio)
Compute priorities used for GSPN transformation.
void insertNamesFromProperties(ForwardIt first, ForwardIt last)
Add relevant event names required by the labels in properties of a range.
storm::expressions::Expression getExpression() const
Retrieves an expression that represents the variable.
Definition Variable.cpp:34
std::shared_ptr< storm::expressions::ExpressionManager > const & getExpressionManager() const
Obtain the expression manager used for expressions over GSPNs.
Definition GSPN.cpp:138
storm::expressions::Variable const & getExpressionVariable() const
Retrieves the associated expression variable.
Definition Variable.cpp:26
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
void exportJaniToFile(storm::jani::Model const &model, std::vector< storm::jani::Property > const &properties, std::string const &filename, bool compact)
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.
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 storm-dft.cpp:23
std::pair< std::shared_ptr< storm::gspn::GSPN >, uint64_t > transformToGSPN(storm::dft::storage::DFT< double > const &dft)
std::string exportDFTToJsonString(storm::dft::storage::DFT< ValueType > const &dft)
Export DFT to JSON string.
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 exportDFTToSMT(storm::dft::storage::DFT< double > const &dft, std::string const &file)
void analyzeDFTSMT(storm::dft::storage::DFT< double > const &dft, bool printOutput)
double MTTFHelperVariableChange(std::shared_ptr< storm::dft::storage::DFT< double > > const dft, double const stepsize)
Tries to numerically approximate the mttf of the given dft by integrating 1 - cdf(dft) by changing th...
double MTTFHelperProceeding(std::shared_ptr< storm::dft::storage::DFT< double > > const dft, double const stepsize, double const precision)
Tries to numerically approximate the mttf of the given dft by integrating 1 - cdf(dft) with Simpson's...
SettingsType const & getModule()
Get module.