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
16
17namespace storm::dft {
18namespace api {
19
20storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
21 std::vector<std::string> const& additionalRelevantEventNames) {
22 storm::dft::utility::RelevantEvents events(additionalRelevantEventNames.begin(), additionalRelevantEventNames.end());
23 events.insertNamesFromProperties(properties.begin(), properties.end());
24 return events;
25}
26
27template<typename ValueType>
29 storm::dft::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred,
30 bool allowModularisation, storm::dft::utility::RelevantEvents const& relevantEvents, bool allowDCForRelevant, double approximationError,
31 storm::dft::builder::ApproximationHeuristic approximationHeuristic, bool eliminateChains, storm::transformer::EliminationLabelBehavior labelBehavior,
32 bool printOutput) {
35 modelChecker.check(dft, properties, symred, allowModularisation, relevantEvents, allowDCForRelevant, approximationError, approximationHeuristic,
36 eliminateChains, labelBehavior);
37 if (printOutput) {
38 modelChecker.printTimings();
39 modelChecker.printResults(results);
40 }
41 return results;
42}
43
44template<>
45void analyzeDFTBdd(std::shared_ptr<storm::dft::storage::DFT<double>> const& dft, bool const exportToDot, std::string const& filename, bool const calculateMttf,
46 double const mttfPrecision, double const mttfStepsize, std::string const mttfAlgorithmName, bool const calculateMCS,
47 bool const calculateProbability, bool const useModularisation, std::string const importanceMeasureName,
48 std::vector<double> const& timepoints, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
49 std::vector<std::string> const& additionalRelevantEventNames, size_t const chunksize) {
50#ifdef STORM_HAVE_SYLVAN
51 if (calculateMttf) {
52 if (mttfAlgorithmName == "proceeding") {
53 std::cout << "The numerically approximated MTTF is " << storm::dft::utility::MTTFHelperProceeding(dft, mttfStepsize, mttfPrecision) << '\n';
54 } else if (mttfAlgorithmName == "variableChange") {
55 std::cout << "The numerically approximated MTTF is " << storm::dft::utility::MTTFHelperVariableChange(dft, mttfStepsize) << '\n';
56 }
57 }
58
59 if (useModularisation && calculateProbability) {
61 if (chunksize == 1) {
62 for (auto const& timebound : timepoints) {
63 auto const probability{checker.getProbabilityAtTimebound(timebound)};
64 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
65 }
66 } else {
67 auto const probabilities{checker.getProbabilitiesAtTimepoints(timepoints, chunksize)};
68 for (size_t i{0}; i < timepoints.size(); ++i) {
69 auto const timebound{timepoints[i]};
70 auto const probability{probabilities[i]};
71 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
72 }
73 }
74 if (!properties.empty()) {
75 auto const probabilities{checker.check(properties, chunksize)};
76 for (size_t i{0}; i < probabilities.size(); ++i) {
77 std::cout << "Property \"" << properties.at(i)->toString() << "\" has result " << probabilities.at(i) << '\n';
78 }
79 }
80 return;
81 } else {
82 STORM_LOG_THROW(dft->nrDynamicElements() == 0, storm::exceptions::NotSupportedException,
83 "DFT is dynamic. "
84 "Bdds can only be used on static fault trees. "
85 "Try modularisation.");
86 }
87
89 sylvanBddManager->execute([&]() {
90 storm::dft::utility::RelevantEvents relevantEvents{additionalRelevantEventNames.begin(), additionalRelevantEventNames.end()};
91 storm::dft::adapters::SFTBDDPropertyFormulaAdapter adapter{dft, properties, sylvanBddManager, relevantEvents};
92 auto checker{adapter.getSFTBDDChecker()};
93
94 if (exportToDot) {
95 checker->exportBddToDot(filename);
96 }
97
98 if (calculateMCS) {
99 auto const minimalCutSets{checker->getMinimalCutSetsAsIndices()};
100 auto const sylvanBddManager{checker->getSylvanBddManager()};
101
102 std::cout << "{\n";
103 for (auto const& minimalCutSet : minimalCutSets) {
104 std::cout << '{';
105 for (auto const& be : minimalCutSet) {
106 std::cout << sylvanBddManager->getName(be) << ' ';
107 }
108 std::cout << "},\n";
109 }
110 std::cout << "}\n";
111 }
112
113 if (calculateProbability) {
114 if (chunksize == 1) {
115 for (auto const& timebound : timepoints) {
116 auto const probability{checker->getProbabilityAtTimebound(timebound)};
117 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
118 }
119 } else {
120 auto const probabilities{checker->getProbabilitiesAtTimepoints(timepoints, chunksize)};
121 for (size_t i{0}; i < timepoints.size(); ++i) {
122 auto const timebound{timepoints[i]};
123 auto const probability{probabilities[i]};
124 std::cout << "System failure probability at timebound " << timebound << " is " << probability << '\n';
125 }
126 }
127
128 if (!properties.empty()) {
129 auto const probabilities{adapter.check(chunksize)};
130 for (size_t i{0}; i < probabilities.size(); ++i) {
131 std::cout << "Property \"" << properties.at(i)->toString() << "\" has result " << probabilities.at(i) << '\n';
132 }
133 }
134 }
135
136 if (importanceMeasureName != "" && timepoints.size() == 1) {
137 auto const bes{dft->getBasicElements()};
138 std::vector<double> values{};
139 if (importanceMeasureName == "MIF") {
140 values = checker->getAllBirnbaumFactorsAtTimebound(timepoints[0]);
141 }
142 if (importanceMeasureName == "CIF") {
143 values = checker->getAllCIFsAtTimebound(timepoints[0]);
144 }
145 if (importanceMeasureName == "DIF") {
146 values = checker->getAllDIFsAtTimebound(timepoints[0]);
147 }
148 if (importanceMeasureName == "RAW") {
149 values = checker->getAllRAWsAtTimebound(timepoints[0]);
150 }
151 if (importanceMeasureName == "RRW") {
152 values = checker->getAllRRWsAtTimebound(timepoints[0]);
153 }
154
155 for (size_t i{0}; i < bes.size(); ++i) {
156 std::cout << importanceMeasureName << " for the basic event " << bes[i]->name() << " at timebound " << timepoints[0] << " is " << values[i]
157 << '\n';
158 }
159 } else if (importanceMeasureName != "") {
160 auto const bes{dft->getBasicElements()};
161 std::vector<std::vector<double>> values{};
162 if (importanceMeasureName == "MIF") {
163 values = checker->getAllBirnbaumFactorsAtTimepoints(timepoints, chunksize);
164 }
165 if (importanceMeasureName == "CIF") {
166 values = checker->getAllCIFsAtTimepoints(timepoints, chunksize);
167 }
168 if (importanceMeasureName == "DIF") {
169 values = checker->getAllDIFsAtTimepoints(timepoints, chunksize);
170 }
171 if (importanceMeasureName == "RAW") {
172 values = checker->getAllRAWsAtTimepoints(timepoints, chunksize);
173 }
174 if (importanceMeasureName == "RRW") {
175 values = checker->getAllRRWsAtTimepoints(timepoints, chunksize);
176 }
177 for (size_t i{0}; i < bes.size(); ++i) {
178 for (size_t j{0}; j < timepoints.size(); ++j) {
179 std::cout << importanceMeasureName << " for the basic event " << bes[i]->name() << " at timebound " << timepoints[j] << " is "
180 << values[i][j] << '\n';
181 }
182 }
183 }
184 });
185#else
186 STORM_LOG_THROW(false, storm::exceptions::MissingLibraryException,
187 "This version of Storm was compiled without support for Sylvan. Yet, a method was called that requires this support. Please choose a "
188 "version of Storm with Sylvan support.");
189#endif
190}
191
192template<>
193void analyzeDFTBdd(std::shared_ptr<storm::dft::storage::DFT<storm::RationalFunction>> const& dft, bool const exportToDot, std::string const& filename,
194 bool const calculateMttf, double const mttfPrecision, double const mttfStepsize, std::string const mttfAlgorithmName,
195 bool const calculateMCS, bool const calculateProbability, bool const useModularisation, std::string const importanceMeasureName,
196 std::vector<double> const& timepoints, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
197 std::vector<std::string> const& additionalRelevantEventNames, size_t const chunksize) {
198 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "BDD analysis is not supported for this data type.");
199}
200
201template<>
202void analyzeDFTSMT(storm::dft::storage::DFT<double> const& dft, bool printOutput) {
203 uint64_t solverTimeout = 10;
204
206 smtChecker.toSolver();
207 // Removed bound computation etc. here
208 smtChecker.setSolverTimeout(solverTimeout);
209 smtChecker.checkTleNeverFailed();
210 smtChecker.unsetSolverTimeout();
211}
212
213template<>
215 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Analysis by SMT not supported for this data type.");
216}
217
218template<typename ValueType>
219std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<ValueType> const& dft, bool useSMT, double solverTimeout) {
220 uint64_t lowerBEBound = storm::dft::utility::FailureBoundFinder::getLeastFailureBound(dft, useSMT, solverTimeout);
221 uint64_t upperBEBound = storm::dft::utility::FailureBoundFinder::getAlwaysFailedBound(dft, useSMT, solverTimeout);
222 return std::make_pair(lowerBEBound, upperBEBound);
223}
224
225template<typename ValueType>
226bool computeDependencyConflicts(storm::dft::storage::DFT<ValueType>& dft, bool useSMT, double solverTimeout) {
227 std::vector<std::pair<uint64_t, uint64_t>> fdepConflicts =
229
230 for (auto const& pair : fdepConflicts) {
231 STORM_LOG_DEBUG("Conflict between " << dft.getElement(pair.first)->name() << " and " << dft.getElement(pair.second)->name());
232 }
233
234 // Set the conflict map of the dft
235 std::set<uint64_t> conflict_set;
236 for (auto const& conflict : fdepConflicts) {
237 conflict_set.insert(conflict.first);
238 conflict_set.insert(conflict.second);
239 }
240 for (size_t depId : dft.getDependencies()) {
241 if (!conflict_set.contains(depId)) {
242 dft.setDependencyNotInConflict(depId);
243 }
244 }
245 return !fdepConflicts.empty();
246}
247
248// Explicitly instantiate methods
250 std::vector<std::shared_ptr<storm::logic::Formula const>> const&,
251 bool, bool, storm::dft::utility::RelevantEvents const&, bool,
254template std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<double> const&, bool, double);
256
258 storm::dft::storage::DFT<storm::RationalFunction> const&, std::vector<std::shared_ptr<storm::logic::Formula const>> const&, bool, bool,
260 bool);
261template std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<storm::RationalFunction> const&, bool, double);
263
264} // namespace api
265} // namespace storm::dft
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.
std::vector< boost::variant< ValueType, approximation_result > > dft_results
dft_results check(storm::dft::storage::DFT< ValueType > const &origDft, property_vector const &properties, bool symred=true, bool allowModularisation=true, storm::dft::utility::RelevantEvents const &relevantEvents={}, bool allowDCForRelevant=false, double approximationError=0.0, storm::dft::builder::ApproximationHeuristic approximationHeuristic=storm::dft::builder::ApproximationHeuristic::DEPTH, bool eliminateChains=false, storm::transformer::EliminationLabelBehavior labelBehavior=storm::transformer::EliminationLabelBehavior::KeepLabels)
Main method for checking DFTs.
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:49
static std::shared_ptr< SylvanBddManager > createWithDefaultEnvironment()
Creates a new manager that is configured according to a default environment.
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)
Add relevant event names required by the labels in properties of a range.
#define STORM_LOG_DEBUG(message)
Definition logging.h:21
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
std::pair< uint64_t, uint64_t > computeBEFailureBounds(storm::dft::storage::DFT< ValueType > const &dft, bool useSMT, double solverTimeout)
Definition analysis.cpp:219
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
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 analyzeDFTSMT(storm::dft::storage::DFT< double > const &dft, bool printOutput)
Definition analysis.cpp:202
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
ApproximationHeuristic
Enum representing the heuristic used for deciding which states to expand.
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...
EliminationLabelBehavior
Specify criteria whether a state can be eliminated and how its labels should be treated.