← Documentation
ADS-IDAC Engine 5.0.0
quantifier.cpp
Go to the documentation of this file.
2
6
7#include <sstream>
8#include <vector>
9
10namespace faulttree {
11
12namespace {
13
14// State indices for every variable in the compiled network. Index 0 is the
15// failure state, matching the crew BBN's convention.
16constexpr std::size_t kFailed = 0;
17constexpr std::size_t kWorking = 1;
18
20bool gateFails(const Node &node, std::size_t failed_inputs, std::size_t n) {
21 switch (node.type) {
22 case GateType::And: return failed_inputs == n;
23 case GateType::Or: return failed_inputs > 0;
24 case GateType::KofN:
25 return failed_inputs >= static_cast<std::size_t>(node.k);
26 case GateType::Not: return failed_inputs == 0;
27 case GateType::Basic: break;
28 }
29 throw FaultTreeError("gate '" + node.name + "' has no deterministic table");
30}
31
32} // namespace
33
34Quantifier::Quantifier(const FaultTree &tree) : tree_(tree) {
36 build();
37}
38
39Quantifier::~Quantifier() = default;
40
42 graph_ = std::make_unique<bncore::Graph>();
43 var_of_node_.clear();
44
45 // One binary variable per fault tree node.
46 for (const auto &node : tree_.nodes()) {
47 const auto id = graph_->add_variable(node.name, {"Failed", "Working"});
48 var_of_node_.emplace(node.name, static_cast<std::size_t>(id));
49 }
50
51 // Each input is a parent of the gate it feeds. Insertion order here fixes
52 // the parent order BNCore uses to index conditional tables, so the tables
53 // below must enumerate inputs in this same order.
54 for (const auto &node : tree_.nodes()) {
55 for (const auto &input : node.children) {
56 graph_->add_edge(static_cast<bncore::NodeId>(var_of_node_.at(input)),
57 static_cast<bncore::NodeId>(var_of_node_.at(node.name)));
58 }
59 }
60
61 for (const auto &node : tree_.nodes()) {
62 const auto id = static_cast<bncore::NodeId>(var_of_node_.at(node.name));
63
64 if (node.type == GateType::Basic) {
65 graph_->set_cpt(id, {node.probability, 1.0 - node.probability});
66 continue;
67 }
68
69 const std::size_t n = node.children.size();
70 if (n > kMaxGateInputs) {
71 std::ostringstream out;
72 out << "gate '" << node.name << "' has " << n << " inputs, above the "
73 << kMaxGateInputs << " this quantifier will tabulate";
74 throw FaultTreeError(out.str());
75 }
76
77 // BNCore lays a conditional table out row-major over
78 // [parent 0, ..., parent n-1, self], so `self` varies fastest and parent 0
79 // is the most significant bit of the parent configuration.
80 const std::size_t combinations = std::size_t{1} << n;
81 std::vector<double> cpt(combinations * 2);
82 for (std::size_t combo = 0; combo < combinations; ++combo) {
83 std::size_t failed_inputs = 0;
84 for (std::size_t i = 0; i < n; ++i) {
85 const std::size_t state = (combo >> (n - 1 - i)) & 1u;
86 if (state == kFailed) { ++failed_inputs; }
87 }
88 const bool fails = gateFails(node, failed_inputs, n);
89 cpt[combo * 2 + kFailed] = fails ? 1.0 : 0.0;
90 cpt[combo * 2 + kWorking] = fails ? 0.0 : 1.0;
91 }
92 graph_->set_cpt(id, cpt);
93 }
94
96 engine_ = std::make_unique<bncore::BatchExecutionEngine>(*junction_tree_, 1, 1);
97}
98
99double Quantifier::probabilityOf(const std::string &name) const {
100 auto it = var_of_node_.find(name);
101 if (it == var_of_node_.end()) {
102 throw FaultTreeError("no fault tree node named '" + name + "'");
103 }
104
105 const std::size_t num_vars = tree_.size();
106 std::vector<int> evidence(num_vars, -1); // no hard evidence
107 double marginal[2] = {0.0, 0.0};
108 engine_->evaluate(evidence.data(), 1, num_vars, marginal, it->second);
109 return marginal[kFailed];
110}
111
113 return probabilityOf(tree_.top());
114}
115
116void Quantifier::setBasicEventProbability(const std::string &name,
117 double probability) {
118 tree_.setBasicEventProbability(name, probability);
119 // Only a number changed, so the junction tree structure still holds: update
120 // the prior in place and drop the cached workspace so the next query rebuilds
121 // its potentials from the new table.
122 graph_->set_cpt(static_cast<bncore::NodeId>(var_of_node_.at(name)),
123 {probability, 1.0 - probability});
124 engine_->invalidate_workspace_cache();
125}
126
127std::vector<std::string> Quantifier::basicEventNames() const {
128 return tree_.basicEventNames();
129}
130
131bool Quantifier::isDefined(const std::string &name) const {
132 return tree_.hasNode(name);
133}
134
135} // namespace faulttree
static std::unique_ptr< JunctionTree > compile(const Graph &graph, const std::string &heuristic="min_fill")
Compiles a junction tree.
Definition: compiler.cpp:53
Exception type of the fault tree model, the .fta reader and the quantifier.
Definition: fault_tree.hpp:37
A fault tree: nodes keyed by name, plus a designated top event.
Definition: fault_tree.hpp:78
void setBasicEventProbability(const std::string &name, double probability)
Definition: fault_tree.cpp:72
const std::string & top() const
Name of the top event.
Definition: fault_tree.cpp:59
bool hasNode(const std::string &name) const
Tests whether a node of this name has been added.
Definition: fault_tree.cpp:32
std::vector< std::string > basicEventNames() const
Definition: fault_tree.cpp:64
void validate() const
Definition: fault_tree.cpp:88
std::size_t size() const
Number of nodes (basic events plus gates).
Definition: fault_tree.hpp:106
const std::vector< Node > & nodes() const
All nodes, basic events and gates, in the order they were added.
Definition: fault_tree.hpp:103
bool isDefined(const std::string &name) const
Definition: quantifier.cpp:131
double probabilityOf(const std::string &name) const
Definition: quantifier.cpp:99
std::unordered_map< std::string, std::size_t > var_of_node_
node name to BNCore variable id
Definition: quantifier.hpp:114
std::vector< std::string > basicEventNames() const
Names of the basic events, in definition order.
Definition: quantifier.cpp:127
std::unique_ptr< bncore::Graph > graph_
one binary variable per node
Definition: quantifier.hpp:111
std::unique_ptr< bncore::BatchExecutionEngine > engine_
refers to junction_tree_
Definition: quantifier.hpp:113
FaultTree tree_
validated private copy of the model
Definition: quantifier.hpp:110
void setBasicEventProbability(const std::string &name, double probability)
Definition: quantifier.cpp:116
std::unique_ptr< bncore::JunctionTree > junction_tree_
points at graph_
Definition: quantifier.hpp:112
Quantifier(const FaultTree &tree)
Definition: quantifier.cpp:34
double topEventProbability() const
Definition: quantifier.cpp:112
bncore::JunctionTreeCompiler, which turns a Graph into the JunctionTree that the inference engine run...
bncore::BatchExecutionEngine, the query interface of BNCore: exact posterior marginals and MAP states...
bncore::Graph, the discrete Bayesian network model: variables, their states, directed edges and condi...
std::uint32_t NodeId
Handle of a variable within one Graph.
Definition: node.hpp:20
@ Or
fails when any input fails (.fta type 1)
@ KofN
fails when at least k inputs fail (.fta type 6)
@ Basic
basic event, quantified by probability
@ Not
fails when its single input does not (.fta type 7)
@ And
fails when every input fails (.fta type 0)
constexpr std::size_t kMaxGateInputs
Largest number of inputs a single gate may have.
Definition: quantifier.hpp:44
Exact fault tree quantification: faulttree::Quantifier compiles a FaultTree into a BNCore Bayesian ne...