# Decision tables

A decision table is a grid: one row per combination of input
conditions, one column per condition, one final column for the
decision. Writing the table forces enumeration of every case;
*missing* rows become visible at a glance. The implementation
becomes a lookup against the table. This is the lowest-cost
formal method in the catalog; the technique requires no
specialist notation beyond a labeled grid. Hillel Wayne's *Decision
Tables* is a clear, accessible introduction (Wayne 2018)[^wayne2018b].

## What it catches

- **Missing rows in decision logic.** Three boolean conditions
  produce eight rows; eligibility logic that handles seven of them
  ships a policy gap.
- **Inconsistent rows.** Two rows that match the same inputs but
  prescribe different decisions are a contradiction; the table
  surfaces them as duplicates.
- **Dead conditions.** A condition that never affects the outcome
  shows up as a column whose values don't change the result. Often
  a sign of dead code or over-specification.
- **Stakeholder ambiguity.** Product, legal, compliance, ops can
  read a table where they cannot read source code. Decision tables
  are often the one formal method non-engineers will engage with.
- **Drift between policy and code.** When the table is the source
  of truth, the implementation tests against the table; any
  divergence is a code bug, not a policy bug.

On a markdown table or spreadsheet these checks are done by eye at
review time; on a table in DMN (Decision Model and Notation) format
they can be run automatically: dmn-check statically flags missing
and overlapping rules, and an in-source enumeration hands the
completeness check to the compiler.

Decision tables catch nothing outside the case space they enumerate.

## Tools

The right form depends on who needs to read and edit the table.

- **A markdown table in the repo.** The recommended baseline. The
  PR review surfaces missing rows; the table lives next to the
  code that implements it.
- **A spreadsheet (Excel, Google Sheets).** When stakeholders
  outside engineering need to read or edit the table. A CSV export
  carries the rows back to the test suite or into a markdown doc.
- **DMN** — an Object Management Group (OMG) standard for decision
  tables; used by rule engines and business-process-management (BPM)
  platforms.
- **[Drools](https://www.drools.org/)**, **[OpenL Tablets](https://openl-tablets.org/)**,
  and **[Operaton](https://operaton.org/)**: open-source rule engines that
  execute DMN tables directly. Operaton is the Apache-2.0,
  community-owned fork of Camunda 7; the commercial Camunda 8
  platform's DMN engine does the same job. Useful when business
  analysts own the rules.
- **[dmn-check](https://github.com/red6/dmn-check)** — static analysis for DMN files:
  detects missing rules (completeness gaps), overlapping or
  conflicting rules, and type errors, and merges redundant rows.
  Runs in CI or as a Camunda Modeler plugin.
- **In-source enumerations.** A typed sum type that enumerates the
  rows, plus an exhaustive `match` / `switch`, gives the same
  guarantees the table does, and the type checker enforces them.

## When to use, when not

**Use:**

- For any feature whose decision combines two to five conditions.
  The cost is minutes, and a missing combination shows up as a
  missing row.
- For regulated decisions where stakeholders outside engineering
  must read and approve the rules. The table is the contract.
- When porting eligibility or pricing logic across implementations.
  The table is the durable artifact; the code is not.
- As an entry point to formal methods on a team that has none.
  The notation is a labeled grid, nothing more.

**Don't:**

- When the case space is large. Past ~5 binary inputs the table
  has 32+ rows and is no longer scannable. Use a rule engine or
  hierarchical decision tables.
- For continuous conditions. Bucket the range first (e.g., "age <
  18", "18–64", "65+") and write the table over the buckets.
- For control-flow decisions that have state. Use
  [state machines](https://quality.stereobooster.com/state-machines.md) instead.

## Evidence

Empirical literature directly comparing teams that adopt decision
tables to teams that don't is sparse: the technique is too small
and pre-dates the modern empirical-SE era. The case rests on the
definitional point that the table is exhaustive by construction.

## Related

**Exhaustive enumeration of a bounded input space, compressed several ways**

These methods all exhaustively enumerate a bounded input space; each compresses
the exponential blow-up a different way. Decision
tables compress *losslessly*: a "don't-care"
entry folds together combinations that share an outcome, so every case still
maps to one rule, and the row carries its own expected decision. [Combinatorial
and pairwise testing](https://quality.stereobooster.com/combinatorial-testing.md) *sample*: a
covering array keeps every *t*-way interaction and drops the higher-order ones,
with the oracle supplied separately. [Bounded-exhaustive property
testing](https://quality.stereobooster.com/property-based-testing.md) *bounds the size*: it
enumerates every value up to a depth/size *k* (SmallCheck), relying on the
small-scope hypothesis that faults surface small. [Exhaustive
coverage](https://quality.stereobooster.com/exhaustive-coverage.md) runs from MCC (the full 2ⁿ
truth table) down to MC/DC's *n*+1 independence criterion, and audits an
existing suite rather than generating one. Type systems reach the same
completeness by construction: an exhaustiveness check on a `match` / `switch`
over a sum type has the compiler verify every variant is handled, with no case
written by hand. State-, path-, and schedule-space
enumerators such as model checking, symbolic execution, and systematic
concurrency testing share the idea over a different space; see the reachability
clusters.

## Classification

- **Quality dimensions:** Functionality: conformance (a regulated rule set is a declared standard, and the table is the artifact stakeholders outside engineering read and approve).
- **Area:** Eligibility rules, pricing, access control, regulatory rules, insurance and tax logic, feature-flag decisions, anywhere business logic combines several conditions into one decision.
- **Guarantee:** Exhaustive — by construction, no case is missing.

## Referenced by

- [Guarantee](https://quality.stereobooster.com/guarantee.md) · The axes
- [Exhaustive coverage (MC/DC, MCC)](https://quality.stereobooster.com/exhaustive-coverage.md) · Methods
- [Formal methods](https://quality.stereobooster.com/formal.md) · Methods
- [Model checking](https://quality.stereobooster.com/model-checking.md) · Methods
- [Requirements quality checking](https://quality.stereobooster.com/requirements-quality-checking.md) · Methods
- [State machines and statecharts](https://quality.stereobooster.com/state-machines.md) · Methods
- [How AI fits into software quality](https://quality.stereobooster.com/ai.md) · AI
- [Choosing methods](https://quality.stereobooster.com/choosing.md) · Overview

## References

[^wayne2018b]: Wayne, Hillel. 2018. *[Decision Tables](https://www.hillelwayne.com/post/decision-tables/)*. <https://www.hillelwayne.com/post/decision-tables/>.

## Acronyms

- BPM — business process management
- DMN — Decision Model and Notation
- MC/DC — modified condition/decision coverage
- MCC — multiple-condition coverage
