Diagnostics · Hard Cases · Method
Three comfortable assumptions every diagnosis quietly makes — one cause, a fault that stays put, sensors that tell the truth — and what to do when each one breaks.
The sufficiency method assumed three things to stay clean: one fault, a fault that stays put, and honest sensors. Real systems break all three. Multiple faults add their symptoms together, so no single cause fits and the unexplained leftover is the tell. Intermittent faults hide between snapshots, so “rich enough” becomes a question of coverage — did you capture the fault in the operating corner that triggers it? — not count. And lying sensors turn a healthy system into a phantom fault, so before trusting a lone reading you must ask whether the gauge itself is broken. We take each in turn, in plain words, with worked EV examples — and fold all three back into the sufficiency gate.
Every tidy diagnosis leans on three quiet assumptions. Naming them is the first defense, because each failure leaves a recognizable fingerprint.
The tell: no single cause explains everything. The best single-fault story leaves an orphan symptom it cannot account for.
The tell: “we can’t reproduce it.” The fault hides between snapshots, or only appears in one corner of the operating range.
The tell: a contradiction that traces to a single reading — a phantom fault from a bad gauge, or a real one a dead sensor is hiding.
None of these replaces the sufficiency method from the prequel — each is a specific way its checks fire, and each has a specific remedy. We use one running system throughout: an EV thermal-management loop (coolant pump, radiator, fan, and the flow and temperature sensors that watch them), complaining of overheating.
Part A — Multiple Simultaneous Faults
Symptoms do not come labelled by cause. When two faults overlap, their signs add together into a pattern that matches neither alone — and the search for a single culprit quietly fails.
The pack is overheating on long climbs. Two things are actually wrong: a weakening coolant pump (less flow) and a partly fouled radiator (less heat rejection). Either alone would be a mild, in-spec nuisance. Together they cross the limit.
Now look at the symptoms. Low coolant flow points at the pump — but the pump being weak does not explain why the radiator outlet runs hot. The hot radiator outlet points at the radiator — but that does not explain the low flow. No single fault covers both. A one-cause search keeps finding a suspect that leaves something unexplained.
This is why coverage is a sufficiency check. “My best cause explains almost everything” is not a near-win — it is a flag. The unexplained remainder is information: usually a second fault, occasionally the wrong fault.
Once you accept there may be more than one fault, the question changes from “which part?” to “which set of parts?” There is a clean, classic way to do this without checking every combination.
It rests on one idea: a conflict is a group of components that cannot all be healthy given what you observed. Each symptom generates a conflict. A diagnosis is then any set of suspected-faulty parts that “hits” every conflict — picks at least one culprit from each. The smallest such sets are the minimal diagnoses.
{pump, radiator} — both plausible, both degrading with age — wins.input conflicts — each a set of components that can’t all be healthy
output minimal sets of faulty parts that explain every symptom
D ← { {} } # start with the empty diagnosis
for each conflict C:
D ← { d ∪ {c} : d ∈ D, c ∈ C } # add one culprit from C
drop non-minimal sets from D # keep only the smallest
return sort(D) by prior fault probability # likeliest combination first
Two cautions. First, prefer the simplest explanation, but do not force it. A single fault is more likely than two independent ones, so always test single-fault diagnoses first — but when every single fault leaves an orphan, the simplest explanation that actually fits is the double. Occam’s razor cuts toward the simplest adequate story, not the simplest imaginable one.
Second, the number of possible combinations explodes (N parts give 2ᴾ subsets). Three things keep it tractable: only ever enumerate minimal diagnoses; use independent fault priors, which make multi-fault combinations exponentially unlikely unless the evidence demands them; and let structure help — parts that cannot interact cannot co-explain a symptom.
Part B — Intermittent Faults & Coverage
A fault you never observed under the condition that triggers it is a fault you have no data about — no matter how many gigabytes of the wrong condition you logged.
The overheating only ever happens on a long, steep climb in hot weather. On the bench, at idle, in a cool shop, the system looks perfect — and ten thousand idle logs say exactly nothing about the fault.
Think of every condition the system runs in as a map — the operating envelope. For the thermal loop, two axes that matter are load (how hard the powertrain is working) and ambient temperature. The fault lives in one corner: high load, high heat. If all your logged data sits in the other corners, your dataset is large and empty where it counts.
Intermittency is the same problem in time instead of condition. A fault that flickers on for a second every few minutes is invisible to a snapshot taken between flickers. You can sample forever and miss it if you are not sampling when it happens.
If richness is coverage, then collecting data becomes a targeting problem: go to the corner where the fault lives, or arm a trap that fires when it arrives.
Two moves, depending on whether you can summon the condition:
And the sufficiency rule gains a clause: you are not done collecting until your coverage actually includes the suspected trigger region.
input envelope (the operating map) · logs · suspected trigger region
output COVERED, or a targeted collection plan
covered ← region of envelope where logs are dense
if trigger ⊆ covered: return COVERED # we have seen it happen
else:
gap ← trigger − covered
if can_command(gap): return REPRODUCE(gap) # drive/HIL into the corner
else: return ARM_TRIGGER(gap) # freeze-frame on next event
“We have tons of data” is not an answer to “is it enough?” until you can point to data taken while the fault was happening. Until then, the honest status is inconclusive — go capture the event.
Part C — Sensors That Lie
Every measurement is two things stacked together: the real quantity, and the instrument that reports it. When they part ways, a healthy system can look sick — and a sick one can look fine.
The coolant-temperature sensor reads 110 °C — alarming. But is the coolant actually that hot, or is the sensor wrong? Same reading, two very different worlds. This is observational equivalence again, except the fault has moved into the measurement chain.
You resolve it the same way you resolve any equivalence: with a measurement the two stories disagree on. For sensors there are three cheap, standard ones.
Plausibility and rate checks. A reading outside what physics allows, or one that jumps faster than the real quantity ever could, is the sensor. Coolant with real thermal mass cannot rise 40 °C in a fifth of a second — so a reading that does is a wiring or sensor fault, full stop.
Hardware redundancy (voting). If two other independent sensors read normal and one reads high, the odd one out is almost certainly lying — the classic two-out-of-three vote.
Analytical redundancy. Even with one sensor, a model can predict what it should read from other signals (inlet temperature, flow, current). A large gap between predicted and measured, when the other signals agree with each other, points at the sensor.
input suspect reading y · redundant sources R · model M
output SENSOR_FAULT · SYSTEM_FAULT · UNDETERMINED
if y outside physical limits or rate(y) impossible:
return SENSOR_FAULT # plausibility — cheapest check
ŷ ← estimate(R, M) # hardware + analytical redundancy
if |y − ŷ| small: return SYSTEM_FAULT # sensor agrees → fault is real
if R mutually agree and disagree with y:
return SENSOR_FAULT # outvoted
return UNDETERMINED # add a redundant source
In the running example, the 110 °C reading fails the rate check and is outvoted by a model expecting 85 °C — a phantom. Replace the sensor and the alarm vanishes. But note the trap: had we trusted it, we would have “diagnosed” an overheat that never existed and missed the real, slower fault underneath.
None of this is a separate method. Each hard case is a new guard in front of the sufficiency gate — a question to ask before you are allowed to conclude.
Run through the whole EV case with the guards on: the 110 °C alarm is caught as a sensor phantom (§06) and set aside; the real overheat is reproduced only after a targeted hot-climb capture (§05); and the leftover — low flow and hot outlet — refuses to collapse into one cause, forcing the two-fault diagnosis of a weak pump plus a fouled radiator (§03). All three hard cases, in one investigation, each handled by its guard.
“Explains almost everything” is a red flag, not a near-win. The remainder is usually a concurrent fault.
Prefer the simplest explanation that actually fits. When every single fault leaves an orphan, the double is the parsimonious answer.
Generate candidates from conflicts and keep the smallest. Independent fault priors keep multi-fault combinations rare unless the evidence demands them.
Ask where in the operating envelope your data sits. If it never touches the trigger corner, it is empty where it matters.
Drive the system into the trigger condition, or arm a freeze-frame to catch the next occurrence. One capture beats endless idle logs.
Plausibility, rate, a redundant sensor, or a model estimate — run the alarm through one before trusting it.
Sensor voting, analytical-redundancy relations, and trigger-based recorders turn all three hard cases from detective work into routine checks.
Entry points, grouped by the hard case they speak to.
J. de Kleer & B. C. Williams, “Diagnosing Multiple Faults” (1987). Generating candidate diagnoses from conflicts; reasoning about more than one fault at once. The direct source for §03.
R. Reiter, “A Theory of Diagnosis from First Principles” (1987). Diagnoses as minimal hitting sets of conflicts — the formal backbone of “diagnose the set, not the suspect.”
W. Hamscher, L. Console & J. de Kleer (eds.), Readings in Model-Based Diagnosis (1992). The collected foundations of model-based, multiple-fault diagnosis.
R. Isermann, Fault-Diagnosis Systems (2006). Plausibility checks, analytical redundancy, and sensor/actuator/process fault distinctions — the practical engine behind Parts B and C.
J. Gertler, Fault Detection and Diagnosis in Engineering Systems (1998). Parity relations and structured residuals for isolating which signal is at fault.
A. S. Willsky, “A Survey of Design Methods for Failure Detection in Dynamic Systems” (Automatica, 1976). The classic survey of residual-based detection — and the sequential tests that catch intermittent events.
M. Blanke, M. Kinnaert, J. Lunze & M. Staroswiecki, Diagnosis and Fault-Tolerant Control (Springer). Analytical redundancy relations and structural methods for sensor and actuator faults.
A. Avižienis, J.-C. Laprie, B. Randell & C. Landwehr, “Basic Concepts and Taxonomy of Dependable and Secure Computing” (2004). The vocabulary of redundancy and voting (e.g. triple-modular redundancy) behind “is the gauge broken?”
R. Patton, P. Frank & R. Clark (eds.), Issues of Fault Diagnosis for Dynamic Systems (2000). A broad engineering reference on model-based FDI, including sensor-fault isolation.
These are orientation points into large literatures, not the specific source of any single claim here. Titles and years are given so you can find them.