THE SHRINKING a huge failing input is a bad bug report; shrink it to the atom
A random test finds a 4,000-character input that crashes your parser. Useless — you cannot see why. Shrinking (delta-debugging) takes the failing input and mechanically reduces it — halving, dropping, simplifying — while it still fails, until it reaches the minimal case that fails. The minimal counterexample is the actual bug, stripped of everything irrelevant. On a monotone failure it is a binary search for the boundary: the smallest input that still breaks.
THE TECHNIQUE reduce a failing input while it still fails → the minimal counterexample
Start from a large failing input and shrink toward the boundary. Here fails(n) = n ≥ T; the shrinker bisects from 1000 down to the smallest n that still fails — the minimal counterexample: live demo
HISTORY & CREDIT Hildebrandt & Zeller, 2000
“A counterexample is a counterexample — size does not matter.” — it matters enormously. A 1-line minimal case names the bug; a 1000-line one hides it. Shrinking is the difference between “something in here breaks it” and “this breaks it” — the reduction is where the diagnosis actually lives. cited
2000 · Hildebrandt & Zeller — ddmin, the delta-debugging minimization algorithm (ISSTA, “Simplifying Failure-Inducing Input”): systematically remove input chunks, keep what preserves the failure. 2000 · Claessen & Hughes — QuickCheck introduces lightweight property-based random testing; it notes the idea of shrinking only in passing (credited to Andy Gill). Automatic shrinking arrives later, in QuickCheck 2 (popularized by QuviQ, mid-2000s). 2002 · Zeller & Hildebrandt — the extended journal version (IEEE TSE) adds the isolating variant of ddmin. now · every serious fuzzer/property tester reduces its finds; C-Reduce shrinks compiler-crashing programs to a few lines.
The minimal counterexample is the honest artifact: nothing left in it is innocent. Remove any part and the failure vanishes — so every part is guilty. That is a diagnosis, not a symptom. ddmin 2000
RECOMMEND FOR I-13 minimal failing input by bisection, computed
On the canonical compiler, with fails(n)=n≥42, shrinking a failing input of 1000 bisects down to the smallest input that still fails:
$ i13 run shrink.i13 # fails(n)=n>=42 ; shrink from a failing 1000
minimal = 42 -- the boundary: 42 fails, 41 passes. the minimal counterexample.
Recommend: shrinking is LIT for I-13 — verified that a failing input of 1000 reduces to the minimal counterexample 42 by bisecting the failure boundary (halved with >>, since i13's / is float). The result is not just a refuter but the smallest one — the bug with all coincidence removed.