You are taught truth tables three times. Once in grade school, once in high school, once at university. Every time it is the same lesson: P, Q, AND, OR, a grid of trues and falses that proves some identity you forget by the next exam. Three passes at the same abstraction, and not one of them tells you what the thing is for.
Here is what it is for. A truth table is the most reliable algorithm-design tool you will ever hold — and “algorithm” here does not mean code. It means any procedure that has to handle every case without missing one: a support script, an inspection process, a business rule, a line of code. The truth table turns “did we handle everything?” from a hope into a question you can actually answer.
The method
It has six steps.
- Frame the problem as yes/no questions. Each question becomes a column. If a question isn't binary, split it until it is.
- Enumerate every combination. n questions give 2ⁿ rows, and those rows are every possible case — not the ones you thought of, all of them. Coverage is free the moment you finish counting. And order the columns by eliminating power: the biggest factor first — the question that, answered one way, collapses the largest block of rows at once. Get that order right and the table almost prunes itself.
- Eliminate — and watch the table shrink. Answer the first question the collapsing way and every question downstream of it goes moot — either because reality can't produce an answer, or because a rule already settled the outcome. Mark those columns
-, and the whole block of rows redacts to a single case. Each slice visibly shrinks the table; that shrink is the method working. - Solve each surviving case. One outcome apiece, stated plainly. If a case has no obvious outcome, you just found a gap that would otherwise have shipped as a bug.
- Draw the flowchart. Start to end, one branch per question, in the eliminator-first order. The surviving cases are its leaves; the outcomes are where they land.
- Code it — or write the script, or the SOP. Full coverage in, provably complete procedure out. There is no untested case, because there is no unlisted case.
A worked example: the receiving dock
Take a real one. A warehouse takes in products from suppliers and manufacturers. Before anything moves on to the showrooms and retail stores, a sample from each batch is barcode-checked at the dock. Two standing rules govern that dock: no barcode, we generate our own internal one; any mismatch is the vendor's fault, so the whole shipment is rejected.
Four yes/no questions per sampled item, ordered biggest-eliminator-first:
- Barcode present? — the big factor; no barcode has a rule all its own.
- Scannable? — the label actually reads.
- Matches expected? — the scanned code equals what the vendor declared for that item.
- Registered? — the code is a known SKU in our system.
Write each yes as 1 and each no as 0 — that is all binary is. The number of possible cases is never a guess: it is always 2ⁿ, two to the number of questions. Four questions, 2⁴ = 16 cases, every time — and enumerating them is just counting in binary from 0000 to 1111. Sixteen rows, and not one of them took a judgment call — you just counted. Now slice, biggest eliminator first, redacting each collapsed block into the single row it really is:
Sixteen cases build by counting in binary, then collapse through four slices to five.
Slice 1 — Barcode = 0. No barcode: nothing to scan, match, or look up — and a rule of its own (generate an internal one). The last three columns go -, and the whole no-barcode block is not eight cases, it is one. One question, and half the table folded into a single line.
Slice 2 — Barcode = 1, Scan = 0. A label that won't read yields no value to match or look up — and an unreadable label is a vendor defect. Match and Known go -; the four unreadable rows redact to one.
Slice 3 — Barcode = 1, Scan = 1, Match = 0. Here is the subtler collapse. A mismatch rejects the whole shipment by rule — so whether the code happens to be Known changes nothing. Known isn't unanswerable here; it's simply irrelevant. Mark it -; the two mismatch rows redact to one.
Slice 4 — Barcode = 1, Scan = 1, Match = 1. Only now does Known earn its keep: a valid, matching barcode is either already a SKU we carry or a new one to onboard. Two rows, two real cases. Assign the outcomes and the table is resolved:
| Barcode | Scan | Match | Known | Outcome |
|---|---|---|---|---|
| 0 | – | – | – | A — Generate internal barcode; register; release to distribution |
| 1 | 0 | – | – | B — Reject shipment: unreadable label (vendor) |
| 1 | 1 | 0 | – | C — Reject shipment: barcode mismatch (vendor) |
| 1 | 1 | 1 | 0 | D — Onboard new SKU; register; release to distribution |
| 1 | 1 | 1 | 1 | E — Accept known SKU; release to distribution |
Sixteen combinations, five cases — three of them whole blocks a single question settled outright: no barcode, unreadable, mismatch. The flowchart falls straight out of the slices, biggest eliminator first: the two vendor faults converge on a single Reject shipment; the three accept paths each do their own bit, then merge into Release to distribution; and every path ends at one End. Only a clean, matching item reaches the last question.
Is this just brute force?
Now notice what just happened, because it looks like the exact thing worth avoiding. Enumerating all 2ⁿ combinations is brute force — the villain of an earlier post in this series, the move that skips the question a smarter structure would ask. So which is it?
Both, in the right places. You brute-force the problem — the case space is small, bounded, finite (2ⁿ over a handful of binary questions), so enumerating it costs almost nothing and buys total coverage. Then you solve structurally: reality and your own rules redact the settled rows, the eliminator-first ordering prunes the rest fast, and each surviving case gets a real answer. Brute force on the definition is cheap and honest. Brute force on the solution is the expensive kind. Enumerate the problem exhaustively; solve it with structure. It is the same move as defining a problem completely before reaching for the answer — the completeness is the point, and the truth table is just the tool that makes completeness checkable.
You were handed this three times and told it was a logic exercise. It was never a logic exercise. It was a way to never miss a case again.