Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
DftValidator.cpp
Go to the documentation of this file.
1#include "DftValidator.h"
2
4
5namespace storm::dft {
6namespace utility {
7
8template<typename ValueType>
10 // Checking the constraints of a well-formed DFT (Def. 2.15 in PhD thesis)
11
12 // 1. DFT is acyclic
13 // was already checked in DFTBuilder::topologicalVisit()
14
15 // 2. Exactly the BEs have no children
16 // was already checked in DFTBuilder::addGate()
17
18 // 3. Valid threshold for VOT
19 // was already checked in DFTBuilder::addVotingGate()
20
21 // 4. TLE is neither SEQ nor PDEP
22 auto const& tle = dft.getTopLevelElement();
23 if (tle->isDependency()) {
24 stream << "Top level element " << *tle << " should not be a dependency.";
25 return false;
26 }
27 if (tle->isRestriction()) {
28 stream << "Top level element " << *tle << " should not be a restriction.";
29 return false;
30 }
31 // 5. SEQ and PDEP have no parents
32 // was already checked in DFTBuilder::build()
33
34 // 6. SEQ and PDEP are at least binary
35 // was already checked in DFTBuilder::addRestriction() and DFTBuilder::addDependency()
36 return true;
37}
38
39template<typename ValueType>
41 // Checking the constraints of a conventional DFT (Def. 2.19 in PhD thesis)
42
44 // DFT is not even well-formed
45 // Output of isDftWellFormed() is enough
46 return false;
47 }
48
49 // 7. Restriction to exponential distributions
51 stream << "DFT has BE distributions which are neither exponential nor constant failed/failsafe.";
52 return false;
53 }
54
55 // 8. Independence of spare modules
56 auto spareModules = dft.getSpareModules();
57 // TODO: comparing one element of each spare module sufficient?
58 // We do not check overlap with the top module as this makes no difference (because we are using early claiming, early activation)
59 for (auto module1 = spareModules.begin(); module1 != spareModules.end(); ++module1) {
60 auto const& module1Elements = module1->getElements();
61 if (!module1Elements.empty()) {
62 // Empty modules are allowed for the primary module of a spare gate
63 size_t firstElement = *module1Elements.begin();
64 for (auto module2 = std::next(module1); module2 != spareModules.end(); ++module2) {
65 auto const& module2Elements = module2->getElements();
66 if (std::find(module2Elements.begin(), module2Elements.end(), firstElement) != module2Elements.end()) {
67 stream << "Spare modules of '" << dft.getElement(module1->getRepresentative())->name() << "' and '"
68 << dft.getElement(module2->getRepresentative())->name() << "' should not overlap.";
69 return false;
70 }
71 }
72 }
73 }
74
75 // Collect primary modules (used for 9. and 10.)
76 std::vector<size_t> primaryModuleIds;
77 for (size_t spareId : dft.getSpareIndices()) {
78 primaryModuleIds.push_back(dft.getGate(spareId)->children()[0]->id());
79 }
80 // 9. No constant failed events in primary module
81 for (size_t primaryModuleId : primaryModuleIds) {
82 for (size_t elementId : dft.module(primaryModuleId).getElements()) {
83 if (dft.isBasicElement(elementId)) {
84 auto const& be = dft.getBasicElement(elementId);
86 auto beConst = std::static_pointer_cast<storm::dft::storage::elements::BEConst<ValueType> const>(be);
87 if (beConst->canFail()) {
88 stream << "Spare module of '" << dft.getElement(primaryModuleId)->name() << "' contains a constant failed BE '" << beConst->name()
89 << "'.";
90 return false;
91 }
92 }
93 }
94 }
95 }
96
97 // 10. No sharing of primary modules
98 for (auto module1It = primaryModuleIds.begin(); module1It != primaryModuleIds.end(); ++module1It) {
99 for (auto module2It = std::next(module1It); module2It != primaryModuleIds.end(); ++module2It) {
100 if (*module1It == *module2It) {
101 stream << "Module of '" << dft.getElement(*module1It)->name() << "' is shared primary module of multiple SPAREs.";
102 return false;
103 }
104 }
105 }
106
107 // 11. Dependent events of PDEPs are BEs
108 // was already checked in DFTBuilder::build()
109
110 // 12. Unique constant failed BE
112 stream << "DFT has more than one constant failed BE.";
113 return false;
114 }
115
116 // Dependencies must be binary
118 stream << "DFT has dependency with more than one dependent event.";
119 return false;
120 }
121
122 return true;
123}
124
125// Explicitly instantiate the class.
126template class DftValidator<double>;
127template class DftValidator<RationalFunction>;
128
129} // namespace utility
130} // namespace storm::dft
Represents a Dynamic Fault Tree.
Definition DFT.h:52
std::shared_ptr< storm::dft::storage::elements::DFTBE< ValueType > const > getBasicElement(size_t index) const
Definition DFT.h:209
DFTElementCPointer getElement(size_t index) const
Get a pointer to an element in the DFT.
Definition DFT.h:188
DFTElementCPointer getTopLevelElement() const
Definition DFT.h:214
std::shared_ptr< storm::dft::storage::elements::DFTGate< ValueType > const > getGate(size_t index) const
Definition DFT.h:218
std::vector< size_t > getSpareIndices() const
Definition DFT.h:118
std::vector< storm::dft::storage::DftModule > getSpareModules() const
Definition DFT.h:133
storm::dft::storage::DftModule const & module(size_t representativeId) const
Definition DFT.h:128
bool isBasicElement(size_t index) const
Definition DFT.h:193
std::set< size_t > const & getElements() const
Return elements of module.
Definition DftModule.h:39
Transformer for operations on DFT.
static bool isDftValidForMarkovianAnalysis(storm::dft::storage::DFT< ValueType > const &dft, std::ostream &stream)
Check whether the DFT can be analysed by translation to a Markov model.
static bool isDftWellFormed(storm::dft::storage::DFT< ValueType > const &dft, std::ostream &stream)
Check whether the DFT is well-formed.