Documentation

MiscMath.Computability.RedBluePebbleGame

Hong and Kung's red-blue pebble game: the key lemma, the FFT and matrix multiplication #

Informal statement #

The red-blue pebble game models a computation run with S words of fast memory and unlimited slow memory. It is played on a directed graph whose vertices are values and whose edges run from each value to the ones computed from it. A red pebble on a vertex is its value held in fast memory, a blue pebble its value held in slow memory. There are five moves:

A load or a store costs one I/O operation; the other moves are free. A complete calculation starts with blue pebbles on exactly the inputs and ends with blue pebbles on exactly the outputs and no red pebble, never holding more than S red pebbles at once. The minimum I/O time Q is the least cost of a complete calculation.

The key lemma. A computation DAG is a finite directed graph with no cycle, whose inputs are exactly its vertices with no predecessor, whose outputs include every vertex with no successor, and in which no vertex is both an input and an output.

For every computation DAG:

  1. Theorem 3.1, corrected (exists_partition_of_hasCompleteCalculation). Every complete calculation with at most S red pebbles, costing q, comes with a 2S-partition into h sets, S h ≥ q ≥ S (h − 1).
  2. Lemma 3.1 (io_lower_bound_of_parts). If every 2S-partition has at least h₀ sets, every complete calculation with at most S red pebbles costs q ≥ S (h₀ − 1).
  3. Lemma 3.1 as the paper states it (minIOTime_lower_bound). Wherever a complete calculation exists, Q ≥ S (P(2S) − 1).

The FFT. The n-point FFT graph, n = 2^k, has a vertex (l, i) for each level l = 0, …, k and each lane i = 0, …, n − 1. Each vertex below the top level has edges to (l + 1, i) and (l + 1, i xor 2^l). The inputs are level 0 and the outputs level k. For it:

  1. Theorem 4.1, with its constant (fft_parts_lower_bound). For S ≥ 1, every S-dominator partition has h sets with n (log₂ n + 1) ≤ h S log₂ (2S).
  2. Theorem 4.1 as the paper states it (fft_parts_lower_bound_isBigO): P_D(S) = Ω(n log n / (S log S)), with one constant for every n ≥ 2 and every S ≥ 2.
  3. Feasibility (fft_complete_iff). For k ≥ 1, a complete calculation exists exactly when S ≥ 3.
  4. The two bounds the direct argument gives (fft_io_bounds). For k ≥ 1 and S ≥ 1, every complete calculation costs q ≥ 2n, and q ≥ n (log₂ n + 1) / (2 log₂ (4S)) − S.
  5. Corollary 4.1, with its constant (fft_io_lower_bound). For k ≥ 1 and S ≥ 3, every complete calculation satisfies n log₂ n ≤ 5 q log₂ S.
  6. Corollary 4.1 as the paper states it (fft_io_lower_bound_isBigO): Q · log S = Ω(n log n), with one constant for every n ≥ 2 and every S ≥ 3.

Matrix multiplication. The ordinary algorithm for the product of an m × k matrix A by a k × n matrix B forms the m k n products A i l · B l j, and adds up the k products of each entry (i, j) of the result. A computation DAG evaluates it (IsMatMulEvaluation) if some of its vertices can be labelled so that:

How the products are then combined, and in what order, are left free, as is anything else the graph computes, subject to the third condition. For such graphs:

  1. Feasibility, and non-vacuity (exists_isMatMulEvaluation). For all m, k, n ≥ 1, some such graph has a complete calculation exactly when S ≥ 3.
  2. The two bounds the argument gives (matMul_io_bounds). For k ≥ 1 and S ≥ 1, every complete calculation costs q ≥ m k + k n + m n, and q ≥ m k n / √(2S) − S.
  3. Corollary 6.2, with its constant (matMul_io_lower_bound). Every complete calculation with at most S red pebbles, costing q, has m k n ≤ 2 q √S.
  4. Corollary 6.2 as the paper states it (matMul_io_lower_bound_isBigO): Q · √S = Ω(m k n). Over any collection of such graphs, one constant serves every graph of the collection and every S at which that graph has a complete calculation.

How to read these statements #

The twelve definitions they are stated through are in RedBluePebbleGame/Spec.lean, and they are part of the read:

The FFT's inputs and outputs are written inline, as Finset.univ.filter (·.1 = 0) and Finset.univ.filter (·.1 = Fin.last k).

The game and the FFT.

The key lemma.

Matrix multiplication.

Source #

Hong Jia-Wei and H. T. Kung, I/O Complexity: The Red-Blue Pebble Game, Proceedings of the 13th Annual ACM Symposium on Theory of Computing (STOC '81), pp. 326–333, doi:10.1145/800076.802486; a scan is on H. T. Kung's page, https://www.eecs.harvard.edu/~htk/publication/1981-stoc-hong-kung.pdf. Where things are:

Later restatements of the model, for comparison:

Relation to Mathlib #

Mathlib has no pebble games and no I/O complexity, and its Digraph is a bare adjacency relation with no path API. The game, the key lemma and the matrix-multiplication graphs are therefore stated through twelve new definitions, in RedBluePebbleGame/Spec.lean, which are part of the read.

Everything else is Mathlib's:

No earlier formalisation of the game or of these bounds was found, in Lean, Coq, Isabelle or Prove2Me's Formalpedia (searched 2026-09-25).

Where this differs from the source #

Provenance #

Result selected and specified by George A. Constantinides, who has read its advertised statements on a best-effort basis, before any proof of them existed.

They are thirteen theorems:

They are stated through twelve definitions in RedBluePebbleGame/Spec.lean: Step, HasCompleteCalculation, fftEdge, minIOTime, IsComputationDAG, Dominates, IsDominatorPartition, IsPartition, minParts, minDominatorParts, IsMatMulLabelling and IsMatMulEvaluation.

The statements and their proofs were generated by Claude, and are kernel-verified and axiom-audited; no human has read the proofs. Every other lemma and definition here is proof, and may be read by no one. One machine read is on record, and its scope is stated exactly so that it is not taken for more. On 2026-09-27 an independent review of commit 0c9bac9 by an OpenAI Codex agent wrote down its own reading of the twelve definitions and thirteen statements before reading this docstring or the paper, then compared it with both (pp. 327–331). It re-ran the build, a fresh axiom audit, the import and convention guards, the frozen targets and their type check, and an equivalent of the audit self-test. It reproduced, by computations of its own, the two counterexamples to the printed Theorem 3.1, the exclusion of Strassen's algorithm and four of the examples showing that a hypothesis cannot be dropped. It read Spec.lean whole and selected declarations in six of the other ten modules under RedBluePebbleGame/, among them the repair of the paper's cover argument in Partition.lean, but not every proof. It reported no false advertised statement, no contradictory hypotheses and no unguarded junk value, and four errors in the prose, corrected since. It ran no second kernel, and its build reused cached artifacts. It is not a review, and a best-effort read is not one either — satisfy yourself that the statement says what you need before relying on it. See the repository README.

The statements were written, read back and read before any proof existed. They were frozen in three phases as Target/RedBluePebbleGame.lean:

Target/RedBluePebbleGame/TypeCheck.lean ascribes each frozen type to the theorem proved here, so the two cannot differ while it builds; it is built by CI and by lake build RedBluePebbleGameTypeCheck, not by lake build. Both read the definitions in Spec.lean, which were frozen with the statements; their text has not changed since. The module's imports were extended afterwards, for the Palomar submission: its Challenge restates the definitions, and Comparator requires both copies to elaborate to the same terms. That changed one instance argument in IsMatMulLabelling to a definitionally equal one, and no definition's meaning.

Before George's read, the advertised statements were read back blind. An agent was given them, and the definitions they are stated through, and nothing else — no informal statement, no source, no docstring. It rendered them into English, and the rendering was compared with the intended statements. Each phase had two rounds:

The points from Phases 2 and 3 are said above too. The renderings are kept verbatim in docs/readbacks/Computability/RedBluePebbleGame.md, with the model that wrote them and the date.

theorem MiscMath.Computability.exists_partition_of_hasCompleteCalculation {V : Type u_1} [DecidableEq V] [Finite V] {E : V → V → Prop} {I O : Finset V} {S q : ℕ} (hG : RedBluePebbleGame.IsComputationDAG E I O) (hq : RedBluePebbleGame.HasCompleteCalculation E I O S q) :
∃ (h : ℕ) (P : Fin h → Finset V), RedBluePebbleGame.IsPartition E I (2 * S) P ∧ q ≤ S * h ∧ S * h ≤ q + S

Hong and Kung's Theorem 3.1, corrected. Every complete calculation of a computation DAG with at most S red pebbles, charged q, comes with a 2S-partition of the graph into h parts, q ≤ S h ≤ q + S.

theorem MiscMath.Computability.io_lower_bound_of_parts {V : Type u_1} [DecidableEq V] [Finite V] {E : V → V → Prop} {I O : Finset V} {S q h₀ : ℕ} (hG : RedBluePebbleGame.IsComputationDAG E I O) (hparts : ∀ (h : ℕ) (P : Fin h → Finset V), RedBluePebbleGame.IsPartition E I (2 * S) P → h₀ ≤ h) (hq : RedBluePebbleGame.HasCompleteCalculation E I O S q) :
S * h₀ ≤ q + S

Hong and Kung's Lemma 3.1. If every 2S-partition of a computation DAG has at least h₀ parts, every complete calculation with at most S red pebbles is charged q ≥ S (h₀ − 1).

theorem MiscMath.Computability.minIOTime_lower_bound {V : Type u_1} [DecidableEq V] [Finite V] {E : V → V → Prop} {I O : Finset V} {S : ℕ} (hG : RedBluePebbleGame.IsComputationDAG E I O) (hcalc : ∃ (q : ℕ), RedBluePebbleGame.HasCompleteCalculation E I O S q) :
↑S * (↑(RedBluePebbleGame.minParts E I (2 * S)) - 1) ≤ ↑(RedBluePebbleGame.minIOTime E I O S)

Hong and Kung's Lemma 3.1 as stated: Q ≥ S (P(2S) − 1). For a computation DAG with a complete calculation using at most S red pebbles, with Q the minimum I/O time and P(2S) the least number of parts of a 2S-partition.

theorem MiscMath.Computability.fft_parts_lower_bound {k S h : ℕ} (hS : 1 ≤ S) {P : Fin h → Finset (Fin (k + 1) × Fin (2 ^ k))} (hP : RedBluePebbleGame.IsDominatorPartition (RedBluePebbleGame.fftEdge k) {x : Fin (k + 1) × Fin (2 ^ k) | x.1 = 0} S P) :
2 ^ k * (↑k + 1) ≤ ↑h * (↑S * Real.logb 2 (2 * ↑S))

Hong and Kung's Theorem 4.1, with its constant. Every S-dominator partition of the 2^k-point FFT graph, S ≥ 1, has h parts with (k + 1) 2^k ≤ h S log₂ (2S).

theorem MiscMath.Computability.fft_parts_lower_bound_isBigO :
(fun (p : ℕ × ℕ) => 2 ^ p.1 * Real.log (2 ^ p.1) / (↑p.2 * Real.log ↑p.2)) =O[Filter.principal {p : ℕ × ℕ | 1 ≤ p.1 ∧ 2 ≤ p.2}] fun (p : ℕ × ℕ) => ↑(RedBluePebbleGame.minDominatorParts (RedBluePebbleGame.fftEdge p.1) {x : Fin (p.1 + 1) × Fin (2 ^ p.1) | x.1 = 0} p.2)

Hong and Kung's Theorem 4.1 as stated: P_D(S) = Ω(n log n / (S log S)). With n = 2^k and P_D(S) the least number of parts of an S-dominator partition of the n-point FFT graph, n ln n / (S ln S) = O(P_D(S)) along the principal filter of {(k, S) : k ≥ 1, S ≥ 2}: one constant serves every such k and S.

theorem MiscMath.Computability.fft_complete_iff {k S : ℕ} (hk : 1 ≤ k) :
(∃ (q : ℕ), RedBluePebbleGame.HasCompleteCalculation (RedBluePebbleGame.fftEdge k) {x : Fin (k + 1) × Fin (2 ^ k) | x.1 = 0} {x : Fin (k + 1) × Fin (2 ^ k) | x.1 = Fin.last k} S q) ↔ 3 ≤ S

Feasibility. The 2^k-point FFT graph, k ≥ 1, has a complete calculation exactly when at least three red pebbles are available.

theorem MiscMath.Computability.fft_io_bounds {k S q : ℕ} (hk : 1 ≤ k) (hS : 1 ≤ S) (h : RedBluePebbleGame.HasCompleteCalculation (RedBluePebbleGame.fftEdge k) {x : Fin (k + 1) × Fin (2 ^ k) | x.1 = 0} {x : Fin (k + 1) × Fin (2 ^ k) | x.1 = Fin.last k} S q) :
2 ^ (k + 1) ≤ q ∧ 2 ^ k * (↑k + 1) / (2 * Real.logb 2 (4 * ↑S)) - ↑S ≤ ↑q

The two bounds the argument gives. For k ≥ 1 and S ≥ 1, every complete calculation of the 2^k-point FFT graph, charged q, loads each input and stores each output, so q ≥ 2^(k+1); and q ≥ 2^k (k + 1) / (2 log₂ (4S)) − S, which says nothing once S ≥ 2^(k-1).

theorem MiscMath.Computability.fft_io_lower_bound {k S q : ℕ} (hk : 1 ≤ k) (hS : 3 ≤ S) (h : RedBluePebbleGame.HasCompleteCalculation (RedBluePebbleGame.fftEdge k) {x : Fin (k + 1) × Fin (2 ^ k) | x.1 = 0} {x : Fin (k + 1) × Fin (2 ^ k) | x.1 = Fin.last k} S q) :
2 ^ k * ↑k ≤ 5 * ↑q * Real.logb 2 ↑S

Hong and Kung's Corollary 4.1, with its constant. For k ≥ 1, every complete calculation of the 2^k-point FFT graph with S ≥ 3 red pebbles, charged q, has 2^k · k ≤ 5 q log₂ S.

theorem MiscMath.Computability.fft_io_lower_bound_isBigO :
(fun (p : ℕ × ℕ) => 2 ^ p.1 * Real.log (2 ^ p.1)) =O[Filter.principal {p : ℕ × ℕ | 1 ≤ p.1 ∧ 3 ≤ p.2}] fun (p : ℕ × ℕ) => ↑(RedBluePebbleGame.minIOTime (RedBluePebbleGame.fftEdge p.1) {x : Fin (p.1 + 1) × Fin (2 ^ p.1) | x.1 = 0} {x : Fin (p.1 + 1) × Fin (2 ^ p.1) | x.1 = Fin.last p.1} p.2) * Real.log ↑p.2

Hong and Kung's Corollary 4.1 as stated: Q · log S = Ω(n log n). With n = 2^k and Q the minimum I/O time, n ln n = O(Q · ln S) along the principal filter of {(k, S) : k ≥ 1, S ≥ 3}: one constant serves every such k and S.

theorem MiscMath.Computability.exists_isMatMulEvaluation {m k n : ℕ} (hm : 1 ≤ m) (hk : 1 ≤ k) (hn : 1 ≤ n) :
∃ (V : Type) (x : DecidableEq V) (_ : Finite V) (E : V → V → Prop) (I : Finset V) (O : Finset V), RedBluePebbleGame.IsMatMulEvaluation m k n E I O ∧ ∀ (S : ℕ), (∃ (q : ℕ), RedBluePebbleGame.HasCompleteCalculation E I O S q) ↔ 3 ≤ S

Non-vacuity, and feasibility. For all m, k, n ≥ 1 some graph evaluates the ordinary product of an m × k matrix by a k × n matrix (IsMatMulEvaluation) and has a complete calculation exactly when at least three red pebbles are available. The graph the proof exhibits is the ordinary algorithm itself, each entry of the product summed left to right.

theorem MiscMath.Computability.matMul_io_bounds {V : Type u_1} [DecidableEq V] [Finite V] {E : V → V → Prop} {I O : Finset V} {m k n S q : ℕ} (hk : 1 ≤ k) (hS : 1 ≤ S) (hM : RedBluePebbleGame.IsMatMulEvaluation m k n E I O) (hq : RedBluePebbleGame.HasCompleteCalculation E I O S q) :
m * k + k * n + m * n ≤ q ∧ ↑m * ↑k * ↑n / √(2 * ↑S) - ↑S ≤ ↑q

The two bounds the argument gives. For k ≥ 1, every complete calculation of a graph that evaluates the ordinary product of an m × k matrix by a k × n matrix, charged q, loads each entry of the two matrices and stores an output for each entry of the product, so q ≥ m k + k n + m n; and for S ≥ 1 red pebbles, q ≥ m k n / √(2S) − S.

theorem MiscMath.Computability.matMul_io_lower_bound {V : Type u_1} [DecidableEq V] [Finite V] {E : V → V → Prop} {I O : Finset V} {m k n S q : ℕ} (hM : RedBluePebbleGame.IsMatMulEvaluation m k n E I O) (hq : RedBluePebbleGame.HasCompleteCalculation E I O S q) :
↑m * ↑k * ↑n ≤ 2 * ↑q * √↑S

Hong and Kung's Corollary 6.2, with its constant. Every complete calculation of a graph that evaluates the ordinary product of an m × k matrix by a k × n matrix (IsMatMulEvaluation), with at most S red pebbles and charged q, has m k n ≤ 2 q √S.

theorem MiscMath.Computability.matMul_io_lower_bound_isBigO {ι : Type u_1} {m k n : ι → ℕ} {W : ι → Type u_2} [(i : ι) → DecidableEq (W i)] [∀ (i : ι), Finite (W i)] {E : (i : ι) → W i → W i → Prop} {I O : (i : ι) → Finset (W i)} (hM : ∀ (i : ι), RedBluePebbleGame.IsMatMulEvaluation (m i) (k i) (n i) (E i) (I i) (O i)) :
(fun (x : ι × ℕ) => ↑(m x.1) * ↑(k x.1) * ↑(n x.1)) =O[Filter.principal {x : ι × ℕ | ∃ (q : ℕ), RedBluePebbleGame.HasCompleteCalculation (E x.1) (I x.1) (O x.1) x.2 q}] fun (x : ι × ℕ) => ↑(RedBluePebbleGame.minIOTime (E x.1) (I x.1) (O x.1) x.2) * √↑x.2

Hong and Kung's Corollary 6.2 as stated: Q · √S = Ω(m k n). For any collection of graphs, the i-th evaluating the ordinary product of an m i × k i matrix by a k i × n i matrix, and with Q the minimum I/O time, m k n = O(Q · √S) along the principal filter of the pairs (i, S) at which graph i has a complete calculation with S red pebbles: one constant serves every graph of the collection and every such S.

Sanity checks #

Guards against the ways a correct proof can still accompany a useless statement. These are examples: elaborated by the build, so one that stops holding breaks it, and exporting no names. They are not reached by the axiom audit, which walks the named declarations a module contributes to the environment, and an example contributes none. What covers them instead is the textual escape-hatch scan in scripts/check-conventions.sh, which reads the file rather than the environment. The private declarations of this file are audited under their mangled names.

What each one pins:

For the key lemma and Theorem 4.1:

For matrix multiplication:

The key lemma and Theorem 4.1 #

Each graph hypothesis of the key lemma carries weight #

Drop any one of the four fields of IsComputationDAG, keep the other three, and a small graph has a complete calculation for which the conclusion of Theorem 3.1 fails. All four fail the same way: a part's dominator must contain the part's inputs (mem_of_dominates_input), so an S-dominator partition with h parts has at most h S inputs (card_inputs_le), and here there are more inputs than 2 (q + S) (not_conclusion). The first is the paper's own setting, where the inputs may be any set containing the sources: it is why the printed Theorem 3.1 is false.

Matrix multiplication #