Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
storm-dft.cpp
Go to the documentation of this file.
2
3#include <memory>
4#include <vector>
5
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#ifdef STORM_HAVE_SYLVAN
29 if (calculateMttf) {
30 if (mttfAlgorithmName == "proceeding") {
31 std::cout << "The numerically approximated MTTF is " << storm::dft::utility::MTTFHelperProceeding(dft, mttfStepsize, mttfPrecision) << '\n';
32 } else if (mttfAlgorithmName == "variableChange") {
33 std::cout << "The numerically approximated MTTF is " << storm::dft::utility::MTTFHelperVariableChange(dft, mttfStepsize) << '\n';
34 }
35 }
36
37 if (useModularisation && calculateProbability) {
39 if (chunksize == 1) {
40 for (auto const& timebound : timepoints) {
41 auto const probability{checker.getProbabilityAtTimebound(timebound)};
42 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
43 }
44 } else {
45 auto const probabilities{checker.getProbabilitiesAtTimepoints(timepoints, chunksize)};
46 for (size_t i{0}; i < timepoints.size(); ++i) {
47 auto const timebound{timepoints[i]};
48 auto const probability{probabilities[i]};
49 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
50 }
51 }
52 if (!properties.empty()) {
53 auto const probabilities{checker.check(properties, chunksize)};
54 for (size_t i{0}; i < probabilities.size(); ++i) {
55 std::cout << "Property \"" << properties.at(i)->toString() << "\" has result " << probabilities.at(i) << '\n';
56 }
57 }
58 return;
59 } else {
60 STORM_LOG_THROW(dft->nrDynamicElements() == 0, storm::exceptions::NotSupportedException,
61 "DFT is dynamic. "
62 "Bdds can only be used on static fault trees. "
63 "Try modularisation.");
64 }
65
66 auto sylvanBddManager{std::make_shared<storm::dft::storage::SylvanBddManager>()};
67 sylvanBddManager->execute([&]() {
68 storm::dft::utility::RelevantEvents relevantEvents{additionalRelevantEventNames.begin(), additionalRelevantEventNames.end()};
69 storm::dft::adapters::SFTBDDPropertyFormulaAdapter adapter{dft, properties, relevantEvents, sylvanBddManager};
70 auto checker{adapter.getSFTBDDChecker()};
71
72 if (exportToDot) {
73 checker->exportBddToDot(filename);
74 }
75
76 if (calculateMCS) {
77 auto const minimalCutSets{checker->getMinimalCutSetsAsIndices()};
78 auto const sylvanBddManager{checker->getSylvanBddManager()};
79
80 std::cout << "{\n";
81 for (auto const& minimalCutSet : minimalCutSets) {
82 std::cout << '{';
83 for (auto const& be : minimalCutSet) {
84 std::cout << sylvanBddManager->getName(be) << ' ';
85 }
86 std::cout << "},\n";
87 }
88 std::cout << "}\n";
89 }
90
91 if (calculateProbability) {
92 if (chunksize == 1) {
93 for (auto const& timebound : timepoints) {
94 auto const probability{checker->getProbabilityAtTimebound(timebound)};
95 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
96 }
97 } else {
98 auto const probabilities{checker->getProbabilitiesAtTimepoints(timepoints, chunksize)};
99 for (size_t i{0}; i < timepoints.size(); ++i) {
100 auto const timebound{timepoints[i]};
101 auto const probability{probabilities[i]};
102 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
103 }
104 }
105
106 if (!properties.empty()) {
107 auto const probabilities{adapter.check(chunksize)};
108 for (size_t i{0}; i < probabilities.size(); ++i) {
109 std::cout << "Property \"" << properties.at(i)->toString() << "\" has result " << probabilities.at(i) << '\n';
110 }
111 }
112 }
113
114 if (importanceMeasureName != "" && timepoints.size() == 1) {
115 auto const bes{dft->getBasicElements()};
116 std::vector<double> values{};
117 if (importanceMeasureName == "MIF") {
118 values = checker->getAllBirnbaumFactorsAtTimebound(timepoints[0]);
119 }
120 if (importanceMeasureName == "CIF") {
121 values = checker->getAllCIFsAtTimebound(timepoints[0]);
122 }
123 if (importanceMeasureName == "DIF") {
124 values = checker->getAllDIFsAtTimebound(timepoints[0]);
125 }
126 if (importanceMeasureName == "RAW") {
127 values = checker->getAllRAWsAtTimebound(timepoints[0]);
128 }
129 if (importanceMeasureName == "RRW") {
130 values = checker->getAllRRWsAtTimebound(timepoints[0]);
131 }
132
133 for (size_t i{0}; i < bes.size(); ++i) {
134 std::cout << importanceMeasureName << " for the basic event " << bes[i]->name() << " at timebound " << timepoints[0] << " is " << values[i]
135 << '\n';
136 }
137 } else if (importanceMeasureName != "") {
138 auto const bes{dft->getBasicElements()};
139 std::vector<std::vector<double>> values{};
140 if (importanceMeasureName == "MIF") {
141 values = checker->getAllBirnbaumFactorsAtTimepoints(timepoints, chunksize);
142 }
143 if (importanceMeasureName == "CIF") {
144 values = checker->getAllCIFsAtTimepoints(timepoints, chunksize);
145 }
146 if (importanceMeasureName == "DIF") {
147 values = checker->getAllDIFsAtTimepoints(timepoints, chunksize);
148 }
149 if (importanceMeasureName == "RAW") {
150 values = checker->getAllRAWsAtTimepoints(timepoints, chunksize);
151 }
152 if (importanceMeasureName == "RRW") {
153 values = checker->getAllRRWsAtTimepoints(timepoints, chunksize);
154 }
155 for (size_t i{0}; i < bes.size(); ++i) {
156 for (size_t j{0}; j < timepoints.size(); ++j) {
157 std::cout << importanceMeasureName << " for the basic event " << bes[i]->name() << " at timebound " << timepoints[j] << " is "
158 << values[i][j] << '\n';
159 }
160 }
161 }
162 });
163#else
164 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
165 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
166 "version of Storm with Sylvan support.");
167#endif
168}
169
170template<>
171void analyzeDFTBdd(std::shared_ptr<storm::dft::storage::DFT<storm::RationalFunction>> const& dft, bool const exportToDot, std::string const& filename,
172 bool const calculateMttf, double const mttfPrecision, double const mttfStepsize, std::string const mttfAlgorithmName,
173 bool const calculateMCS, bool const calculateProbability, bool const useModularisation, std::string const importanceMeasureName,
174 std::vector<double> const& timepoints, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
175 std::vector<std::string> const& additionalRelevantEventNames, size_t const chunksize) {
176 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "BDD analysis is not supported for this data type.");
177}
178
179template<typename ValueType>
183
184template<typename ValueType>
186 std::stringstream stream;
188 return stream.str();
189}
190
191template<>
192void exportDFTToSMT(storm::dft::storage::DFT<double> const& dft, std::string const& file) {
194 asfChecker.convert();
195 asfChecker.toFile(file);
196}
197
198template<>
199void exportDFTToSMT(storm::dft::storage::DFT<storm::RationalFunction> const& dft, std::string const& file) {
200 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to SMT does not support this data type.");
201}
202
203template<>
204void analyzeDFTSMT(storm::dft::storage::DFT<double> const& dft, bool printOutput) {
205 uint64_t solverTimeout = 10;
206
208 smtChecker.toSolver();
209 // Removed bound computation etc. here
210 smtChecker.setSolverTimeout(solverTimeout);
211 smtChecker.checkTleNeverFailed();
212 smtChecker.unsetSolverTimeout();
213}
214
215template<>
217 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Analysis by SMT not supported for this data type.");
218}
219
220template<>
221std::pair<std::shared_ptr<storm::gspn::GSPN>, uint64_t> transformToGSPN(storm::dft::storage::DFT<double> const& dft) {
222 storm::dft::settings::modules::FaultTreeSettings const& ftSettings = storm::settings::getModule<storm::dft::settings::modules::FaultTreeSettings>();
223 storm::dft::settings::modules::DftGspnSettings const& dftGspnSettings = storm::settings::getModule<storm::dft::settings::modules::DftGspnSettings>();
224
225 // Set Don't Care elements
226 std::set<uint64_t> dontCareElements;
227 if (!ftSettings.isDisableDC()) {
228 // Insert all elements as Don't Care elements
229 for (std::size_t i = 0; i < dft.nrElements(); i++) {
230 dontCareElements.insert(dft.getElement(i)->id());
231 }
232 }
233
234 // Transform to GSPN
236 auto priorities = gspnTransformator.computePriorities(dftGspnSettings.isExtendPriorities());
237 gspnTransformator.transform(priorities, dontCareElements, !dftGspnSettings.isDisableSmartTransformation(), dftGspnSettings.isMergeDCFailed(),
238 dftGspnSettings.isExtendPriorities());
239 std::shared_ptr<storm::gspn::GSPN> gspn(gspnTransformator.obtainGSPN());
240 return std::make_pair(gspn, gspnTransformator.toplevelFailedPlaceId());
241}
242
243template<>
244std::pair<std::shared_ptr<storm::gspn::GSPN>, uint64_t> transformToGSPN(storm::dft::storage::DFT<storm::RationalFunction> const& dft) {
245 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Transformation to GSPN not supported for this data type.");
246}
247
248std::shared_ptr<storm::jani::Model> transformToJani(storm::gspn::GSPN const& gspn, uint64_t toplevelFailedPlace) {
249 // Build Jani model
251 std::shared_ptr<storm::jani::Model> model(builder.build("dft_gspn"));
252
253 // Build properties
254 std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn.getExpressionManager();
255 storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace);
256 storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression();
257 // Add variable for easier access to 'failed' state
258 builder.addTransientVariable(model.get(), "failed", targetExpression);
259 auto failedFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression);
260 auto properties = builder.getStandardProperties(model.get(), failedFormula, "Failed", "a failed state", true);
261
262 // Export Jani to file
263 storm::dft::settings::modules::DftGspnSettings const& dftGspnSettings = storm::settings::getModule<storm::dft::settings::modules::DftGspnSettings>();
264 if (dftGspnSettings.isWriteToJaniSet()) {
265 auto const& jani = storm::settings::getModule<storm::settings::modules::JaniExportSettings>();
266 storm::api::exportJaniToFile(*model, properties, dftGspnSettings.getWriteToJaniFilename(), jani.isCompactJsonSet());
267 }
268
269 return model;
270}
271
272storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
273 std::vector<std::string> const& additionalRelevantEventNames) {
274 storm::dft::utility::RelevantEvents events(additionalRelevantEventNames.begin(), additionalRelevantEventNames.end());
275 events.insertNamesFromProperties(properties.begin(), properties.end());
276 return events;
277}
278
279// Explicitly instantiate methods
280template void exportDFTToJsonFile(storm::dft::storage::DFT<double> const&, std::string const&);
282
285
286} // namespace api
287} // 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
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:189
size_t nrElements() const
Definition DFT.h:95
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...