Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
analysis.cpp
Go to the documentation of this file.
1#include "analysis.h"
2
3#include <memory>
4#include <vector>
5
15
16namespace storm::dft {
17namespace api {
18
19storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
20 std::vector<std::string> const& additionalRelevantEventNames, bool addLabelsClaiming) {
21 storm::dft::utility::RelevantEvents events(additionalRelevantEventNames.begin(), additionalRelevantEventNames.end());
22 events.insertNamesFromProperties(properties.begin(), properties.end(), addLabelsClaiming);
23 return events;
24}
25
26template<typename ValueType>
29 std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, storm::dft::utility::RelevantEvents const& relevantEvents, bool printOutput,
31 storm::dft::modelchecker::DFTModelChecker<ValueType> modelChecker(printOutput, exportCallback);
32 typename storm::dft::modelchecker::DFTModelChecker<ValueType>::dft_results results = modelChecker.check(env, dft, properties, relevantEvents);
33 if (printOutput) {
34 modelChecker.printTimings();
35 modelChecker.printResults(results);
36 }
37 return results;
38}
39
40template<>
41void analyzeDFTBdd(storm::dft::DftEnvironment const& env, std::shared_ptr<storm::dft::storage::DFT<double>> const& dft, bool const exportToDot,
42 std::string const& filename, bool const calculateMttf, double const mttfPrecision, double const mttfStepsize,
43 std::string const mttfAlgorithmName, bool const calculateMCS, bool const calculateProbability, bool const useModularisation,
44 std::string const importanceMeasureName, std::vector<double> const& timepoints,
45 std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, std::vector<std::string> const& additionalRelevantEventNames,
46 size_t const chunksize) {
47#ifdef STORM_HAVE_SYLVAN
48 if (calculateMttf) {
49 if (mttfAlgorithmName == "proceeding") {
50 std::cout << "The numerically approximated MTTF is " << storm::dft::utility::MTTFHelperProceeding(env, dft, mttfStepsize, mttfPrecision) << '\n';
51 } else if (mttfAlgorithmName == "variableChange") {
52 std::cout << "The numerically approximated MTTF is " << storm::dft::utility::MTTFHelperVariableChange(env, dft, mttfStepsize) << '\n';
53 }
54 }
55
56 if (useModularisation && calculateProbability) {
58 if (chunksize == 1) {
59 for (auto const& timebound : timepoints) {
60 auto const probability{checker.getProbabilityAtTimebound(timebound)};
61 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
62 }
63 } else {
64 auto const probabilities{checker.getProbabilitiesAtTimepoints(timepoints, chunksize)};
65 for (size_t i{0}; i < timepoints.size(); ++i) {
66 auto const timebound{timepoints[i]};
67 auto const probability{probabilities[i]};
68 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
69 }
70 }
71 if (!properties.empty()) {
72 auto const probabilities{checker.check(properties, chunksize)};
73 for (size_t i{0}; i < probabilities.size(); ++i) {
74 std::cout << "Property \"" << properties.at(i)->toString() << "\" has result " << probabilities.at(i) << '\n';
75 }
76 }
77 return;
78 } else {
79 STORM_LOG_THROW(dft->nrDynamicElements() == 0, storm::exceptions::NotSupportedException,
80 "DFT is dynamic. "
81 "Bdds can only be used on static fault trees. "
82 "Try modularisation.");
83 }
84
85 auto sylvanBddManager{std::make_shared<storm::dft::storage::SylvanBddManager>(env.core())};
86 sylvanBddManager->execute([&]() {
87 storm::dft::utility::RelevantEvents relevantEvents{additionalRelevantEventNames.begin(), additionalRelevantEventNames.end()};
88 storm::dft::adapters::SFTBDDPropertyFormulaAdapter adapter{dft, properties, sylvanBddManager, relevantEvents};
89 auto checker{adapter.getSFTBDDChecker()};
90
91 if (exportToDot) {
92 checker->exportBddToDot(filename);
93 }
94
95 if (calculateMCS) {
96 auto const minimalCutSets{checker->getMinimalCutSetsAsIndices()};
97 auto const sylvanBddManager{checker->getSylvanBddManager()};
98
99 std::cout << "{\n";
100 for (auto const& minimalCutSet : minimalCutSets) {
101 std::cout << '{';
102 for (auto const& be : minimalCutSet) {
103 std::cout << sylvanBddManager->getName(be) << ' ';
104 }
105 std::cout << "},\n";
106 }
107 std::cout << "}\n";
108 }
109
110 if (calculateProbability) {
111 if (chunksize == 1) {
112 for (auto const& timebound : timepoints) {
113 auto const probability{checker->getProbabilityAtTimebound(timebound)};
114 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
115 }
116 } else {
117 auto const probabilities{checker->getProbabilitiesAtTimepoints(timepoints, chunksize)};
118 for (size_t i{0}; i < timepoints.size(); ++i) {
119 auto const timebound{timepoints[i]};
120 auto const probability{probabilities[i]};
121 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
122 }
123 }
124
125 if (!properties.empty()) {
126 auto const probabilities{adapter.check(chunksize)};
127 for (size_t i{0}; i < probabilities.size(); ++i) {
128 std::cout << "Property \"" << properties.at(i)->toString() << "\" has result " << probabilities.at(i) << '\n';
129 }
130 }
131 }
132
133 if (importanceMeasureName != "" && timepoints.size() == 1) {
134 auto const bes{dft->getBasicElements()};
135 std::vector<double> values{};
136 if (importanceMeasureName == "MIF") {
137 values = checker->getAllBirnbaumFactorsAtTimebound(timepoints[0]);
138 }
139 if (importanceMeasureName == "CIF") {
140 values = checker->getAllCIFsAtTimebound(timepoints[0]);
141 }
142 if (importanceMeasureName == "DIF") {
143 values = checker->getAllDIFsAtTimebound(timepoints[0]);
144 }
145 if (importanceMeasureName == "RAW") {
146 values = checker->getAllRAWsAtTimebound(timepoints[0]);
147 }
148 if (importanceMeasureName == "RRW") {
149 values = checker->getAllRRWsAtTimebound(timepoints[0]);
150 }
151
152 for (size_t i{0}; i < bes.size(); ++i) {
153 std::cout << importanceMeasureName << " for the basic event " << bes[i]->name() << " at timebound " << timepoints[0] << " is " << values[i]
154 << '\n';
155 }
156 } else if (importanceMeasureName != "") {
157 auto const bes{dft->getBasicElements()};
158 std::vector<std::vector<double>> values{};
159 if (importanceMeasureName == "MIF") {
160 values = checker->getAllBirnbaumFactorsAtTimepoints(timepoints, chunksize);
161 }
162 if (importanceMeasureName == "CIF") {
163 values = checker->getAllCIFsAtTimepoints(timepoints, chunksize);
164 }
165 if (importanceMeasureName == "DIF") {
166 values = checker->getAllDIFsAtTimepoints(timepoints, chunksize);
167 }
168 if (importanceMeasureName == "RAW") {
169 values = checker->getAllRAWsAtTimepoints(timepoints, chunksize);
170 }
171 if (importanceMeasureName == "RRW") {
172 values = checker->getAllRRWsAtTimepoints(timepoints, chunksize);
173 }
174 for (size_t i{0}; i < bes.size(); ++i) {
175 for (size_t j{0}; j < timepoints.size(); ++j) {
176 std::cout << importanceMeasureName << " for the basic event " << bes[i]->name() << " at timebound " << timepoints[j] << " is "
177 << values[i][j] << '\n';
178 }
179 }
180 }
181 });
182#else
183 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
184 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
185 "version of Storm with Sylvan support.");
186#endif
187}
188
189template<>
190void analyzeDFTBdd(storm::dft::DftEnvironment const&, std::shared_ptr<storm::dft::storage::DFT<storm::RationalFunction>> const& dft, bool const exportToDot,
191 std::string const& filename, bool const calculateMttf, double const mttfPrecision, double const mttfStepsize,
192 std::string const mttfAlgorithmName, bool const calculateMCS, bool const calculateProbability, bool const useModularisation,
193 std::string const importanceMeasureName, std::vector<double> const& timepoints,
194 std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, std::vector<std::string> const& additionalRelevantEventNames,
195 size_t const chunksize) {
196 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "BDD analysis is not supported for this data type.");
197}
198
199template<>
200void analyzeDFTSMT(storm::dft::storage::DFT<double> const& dft, bool printOutput) {
201 uint64_t solverTimeout = 10;
202
204 smtChecker.toSolver();
205 // Removed bound computation etc. here
206 smtChecker.setSolverTimeout(solverTimeout);
207 smtChecker.checkTleNeverFailed();
208 smtChecker.unsetSolverTimeout();
209}
210
211template<>
213 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Analysis by SMT not supported for this data type.");
214}
215
216template<typename ValueType>
217std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<ValueType> const& dft, bool useSMT, double solverTimeout) {
218 uint64_t lowerBEBound = storm::dft::utility::FailureBoundFinder::getLeastFailureBound(dft, useSMT, solverTimeout);
219 uint64_t upperBEBound = storm::dft::utility::FailureBoundFinder::getAlwaysFailedBound(dft, useSMT, solverTimeout);
220 return std::make_pair(lowerBEBound, upperBEBound);
221}
222
223template<typename ValueType>
224bool computeDependencyConflicts(storm::dft::storage::DFT<ValueType>& dft, bool useSMT, double solverTimeout) {
225 std::vector<std::pair<uint64_t, uint64_t>> fdepConflicts =
227
228 for (auto const& pair : fdepConflicts) {
229 STORM_LOG_DEBUG("Conflict between " << dft.getElement(pair.first)->name() << " and " << dft.getElement(pair.second)->name());
230 }
231
232 // Set the conflict map of the dft
233 std::set<uint64_t> conflict_set;
234 for (auto const& conflict : fdepConflicts) {
235 conflict_set.insert(conflict.first);
236 conflict_set.insert(conflict.second);
237 }
238 for (size_t depId : dft.getDependencies()) {
239 if (!conflict_set.contains(depId)) {
240 dft.setDependencyNotInConflict(depId);
241 }
242 }
243 return !fdepConflicts.empty();
244}
245
246// Explicitly instantiate methods
248 storm::dft::DftEnvironment const&, storm::dft::storage::DFT<double> const&, std::vector<std::shared_ptr<storm::logic::Formula const>> const&,
250template std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<double> const&, bool, double);
252
255 std::vector<std::shared_ptr<storm::logic::Formula const>> const&, storm::dft::utility::RelevantEvents const&, bool,
257template std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<storm::RationalFunction> const&, bool, double);
259
260} // namespace api
261} // namespace storm::dft
Environment for storm-dft.
storm::Environment & core()
std::shared_ptr< storm::dft::modelchecker::SFTBDDChecker > getSFTBDDChecker() const
std::vector< ValueType > check(size_t const chunksize=0)
Calculate the properties specified by the formulas.
void setSolverTimeout(uint_fast64_t milliseconds)
Set the timeout of the solver.
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.
dft_results check(storm::dft::DftEnvironment const &env, storm::dft::storage::DFT< ValueType > const &origDft, property_vector const &properties, storm::dft::utility::RelevantEvents const &relevantEvents={})
Main method for checking DFTs.
std::vector< boost::variant< ExtendedValueType, approximation_result > > dft_results
std::function< void(std::shared_ptr< storm::models::sparse::Model< ValueType > > const &model, bool isFinal)> ModelExportCallback
Callback invoked whenever a model has been built and is available for export.
void printResults(dft_results const &results, std::ostream &os=std::cout) const
Print result to stream.
void printTimings(std::ostream &os=std::cout) const
Print timings of all operations to stream.
ValueType getProbabilityAtTimebound(ValueType const timebound)
Calculate the probability of failure for the given time bound.
std::vector< ValueType > getProbabilitiesAtTimepoints(std::vector< ValueType > const &timepoints, size_t chunksize=0)
Calculate the probability of failure for the given time points.
std::vector< ValueType > check(FormulaVector const &formulas, size_t chunksize=0)
Calculate the properties specified by the formulas.
Represents a Dynamic Fault Tree.
Definition DFT.h:50
static std::vector< std::pair< uint64_t, uint64_t > > getDependencyConflicts(storm::dft::storage::DFT< ValueType > const &dft, bool useSMT=false, uint_fast64_t timeout=10)
Get a vector of index pairs of FDEPs in the DFT which are conflicting.
static uint64_t getLeastFailureBound(storm::dft::storage::DFT< double > const &dft, bool useSMT=false, uint_fast64_t timeout=10)
Get the minimal number of BEs necessary for the TLE to fail (lower bound for number of failures to ch...
static uint64_t getAlwaysFailedBound(storm::dft::storage::DFT< double > const &dft, bool useSMT=false, uint_fast64_t timeout=10)
Get the number of BE failures for which the TLE always fails (upper bound for number of failures to c...
void insertNamesFromProperties(ForwardIt first, ForwardIt last, bool addLabelsClaiming)
Add relevant event names required by the labels in properties of a range.
#define STORM_LOG_DEBUG(message)
Definition logging.h:28
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
std::pair< uint64_t, uint64_t > computeBEFailureBounds(storm::dft::storage::DFT< ValueType > const &dft, bool useSMT, double solverTimeout)
Definition analysis.cpp:217
storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector< std::shared_ptr< storm::logic::Formula const > > const &properties, std::vector< std::string > const &additionalRelevantEventNames, bool addLabelsClaiming)
Get relevant event ids from given relevant event names and labels in properties.
Definition analysis.cpp:19
void analyzeDFTBdd(storm::dft::DftEnvironment const &env, 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:41
void analyzeDFTSMT(storm::dft::storage::DFT< double > const &dft, bool printOutput)
Definition analysis.cpp:200
storm::dft::modelchecker::DFTModelChecker< ValueType >::dft_results analyzeDFT(storm::dft::DftEnvironment const &env, storm::dft::storage::DFT< ValueType > const &dft, std::vector< std::shared_ptr< storm::logic::Formula const > > const &properties, storm::dft::utility::RelevantEvents const &relevantEvents, bool printOutput, typename storm::dft::modelchecker::DFTModelChecker< ValueType >::ModelExportCallback const &exportCallback)
Compute the exact or approximate analysis result of the given DFT according to the given properties.
Definition analysis.cpp:27
bool computeDependencyConflicts(storm::dft::storage::DFT< ValueType > &dft, bool useSMT, double solverTimeout)
Definition analysis.cpp:224
double MTTFHelperProceeding(storm::dft::DftEnvironment const &env, 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...
double MTTFHelperVariableChange(storm::dft::DftEnvironment const &env, 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...