Fault tree quantification (BNCore)
src/FaultTree/ quantifies GeNIe/SMILE .fta fault trees exactly, without SMILE or the rest of the HCL stack. It covers the fault-tree half of what HCL provides (BNCore covers the crew Bayesian network), and it is the prerequisite for support-system reliability branching. That branching is inactive: SupportSystemReliabilityUnit::updateFailureProbability() calls hclEngine.quantify() only under #ifdef ENABLE_HCL, and the constructor code that gives the HCL engine a fault-tree resolver is commented out. With ENABLE_HCL=OFF every support-system failure probability is 0.
The library is standalone and unit tested on its own. The engine does not link it.
What it does
| Piece | File | Role |
|---|---|---|
xml::parse | src/xml_lite.cpp | Minimal XML subset reader for .fta |
parseFtaFile | src/fta_parser.cpp | .fta XML to a FaultTree model |
FaultTree | src/fault_tree.cpp | Named DAG of gates and basic events, with validation |
Quantifier | src/quantifier.cpp | Compiles the model to a BNCore network and queries it |
Why a Bayesian network
Every node becomes a binary variable with states {Failed, Working} (index 0 is Failed, matching the crew BBN). Basic events get the prior {p, 1-p}; gates get a deterministic conditional table over their inputs. BNCore compiles a junction tree and returns the exact marginal.
The reason to go through the network rather than multiply gate probabilities directly is repeated events. A basic event that feeds several gates is one variable with several children, so the shared dependence is accounted for instead of double counted. The shipped Emergency AC Buses.fta contains exactly this case ("Bad mechanic", tagged "Common cause", feeds three gates), and the unit tests pin the difference: for OR(AND(A,B), AND(A,C)) with A shared, the exact answer is 0.29 while the independence approximation gives 0.32.
Semantics, and where they come from
The type codes and the identity rule are those of the HCL resolver (src/HCL/hcl/HCLFTResolver.cpp::parse), so that trees authored for HCL quantify identically:
.fta type | Meaning |
|---|---|
| 0 | AND gate |
| 1 | OR gate |
| 2, 3 | basic event, quantified by failureProbability |
| 4 | transfer gate: an AND over the referenced diagram |
| 5 | transfer-up bookkeeping marker, skipped (see below) |
| 6 | K/N gate, threshold from k |
| 7 | NOT gate |
Node identity is the <node name="..."> string, not the XML id. A node that appears several times in a file is defined once and referenced thereafter, which is precisely what shares repeated events.
Three deliberate departures from the HCL resolver:
- Type 5 is skipped. GeNIe emits a type 5 node listing a diagram's transfer-up children (
<tranferUpChild ref=...>, its spelling). The HCL resolver has no branch for it and falls through to the gate case with an uninitialised gate type.Emergency AC Buses.ftacontains one. - Unknown types are refused rather than quantified with an uninitialised type.
- A duplicated input to one gate is refused. It is idempotent for AND and OR and silently changes what
kmeans for a K/N gate, and it would put the same variable in a factor's scope twice. An event feeding several gates is the normal shared case and is fully supported.
Basic events linked to a BBN variable (<linkedBBN>) are rejected: that path belongs to the HCL hybrid model and has no equivalent here.
xml_lite exists because src/HCL/xmlParser is only built when ENABLE_HCL=ON (the macOS and HPC builds set it OFF) and is LGPL, a license this component does not take on.
Tests
unittests/FaultTree/ (ctest target FaultTree, 59 cases):
XmlLiteTest.cpp: the accepted subset and, mostly, what it rejects.FtaParserTest.cpp: type codes, identity and sharing, k, transfer gates, and the malformed-model refusals.QuantifierTest.cpp: closed-form checks for each gate type, the shared-event case,fixEventrequantification, and agreement with an independent exhaustive reference that enumerates every basic-event combination and evaluates the gate logic directly. The reference shares no code with the network path, so agreement is evidence and not a tautology.
Copies of both shipped trees are in unittests/FaultTree/data/, so the suite does not depend on study inputs. For both trees the tests require the junction tree and the exhaustive reference to agree within an absolute tolerance of 1e-9.
Not implemented
- Wiring into
SupportSystemReliabilityUnit(replace the#ifdef ENABLE_HCLbody ofupdateFailureProbability(), restore the constructor's resolver, and implement thebssa_success/bssa_failbranch pair thatControlPanel::executeRequestToPlantonly declares). - The same treatment for
HWReliabilityFTUnit, which has the identical#ifdef ENABLE_HCLfault-tree path. - Serialization of quantifier state across checkpoint/restart.
- The two shipped trees are not usable content:
Diesel Generator.ftais a toy (two trains at 0.3 and 0.2) andEmergency AC Buses.ftais the GeNIe demo car-brakes tree. Real trees have to be authored before any SBO study.