NIM paper · interactive edition Interactive edition · paper, explanations and Lean proofs.

Section 2.1, paragraph 6A one-step recurrence h_{r+1}=h_r⊕x_r accumulates parity over an arbitrarily long stream

Checked theorem Lean checks a formal statement corresponding to this claim.

1 Paper text

A bound on the number of preceding states consulted by one update is insufficient: even hr+1=hr⊕xrh_{r+1}=h_r\oplus x_r can accumulate parity over an arbitrarily long stream. Section 5.5 exploits precisely this distinction by allowing the number of recurrent updates to grow with the number of rows.

Generated from paper_jmlr.tex, lines 311–311.

2 Explain this

A recurrent update that looks only at its previous state is still very powerful if it is allowed to run for many steps. The update hr+1=hr⊕xrh_{r+1}=h_r\oplus x_r consults one previous state, yet after nn steps hnh_n is the parity of all inputs, which no AC0 circuit computes.

So the right restriction for the simulation theorem is on the total number of unrolled steps TT, not on how far back each update looks. Section 5.5 uses exactly this loophole on purpose: it lets the number of updates grow with the number of heaps.

3 How this is formalised

scan_invariant proves that folding XOR over a list of rows from an initial value gives that value XOR the nim-sum of the rows, for any length: a one-step dependency accumulates the global XOR. A single update is shallow: Recurrent.circuit_resources bounds one recurrent update by depth 4 and size 28B+828B+8. The bounded-unrolling restriction under which the simulation theorem does apply is Definition A.2.

Coverage record
Paper anchorc-window-insufficient (website anchor; the manuscript has no label here)
Displayed asSection 2.1, paragraph 6
ClaimA one-step recurrence h_{r+1}=h_r⊕x_r accumulates parity over an arbitrarily long stream
Coverage categoryChecked theorem
Statement sourcepaper_jmlr.tex lines 311–311; SHA-256 of the normalised block source 48c9b9aa622c4a84…
Lean declarations
Depends onProposition 5.13, Definition A.2
Explanationsexplain/c-window-insufficient, formal/c-window-insufficient
Build evidencefresh isolated rebuild, audit report

4 Lean statement and source

Principal declarations

theorem scan_invariant

Module NimCore (lean/NimCore.lean, lines 26–32) · file SHA-256 b07db6c505210d5a… Axioms reported by the fresh build: propext, Quot.sound

Statement as elaborated and printed by Lean 4.26.0

∀ (rows : List ℕ) (initial : ℕ), NimAudit.scan initial rows = initial ^^^ NimAudit.nimSum rows
Exact source text, lines 26–32
26theorem scan_invariant (rows : List Nat) (initial : Nat) :27    scan initial rows = initial ^^^ nimSum rows := by28  induction rows generalizing initial with29  | nil => simp [scan, nimSum]30  | cons h t ih =>31    change scan (initial ^^^ h) t = initial ^^^ (h ^^^ nimSum t)32    rw [ih, Nat.xor_assoc]

Project declarations in the statement: nimSum, scan

Project declarations used by the proof or definition body

nimSum, scan

theorem Recurrent.circuit_resources

Module NimRecurrent (lean/phase3/NimRecurrent.lean, lines 491–498) · file SHA-256 1f2994aefc75e7f5… Axioms reported by the fresh build: propext, Quot.sound

Per-update circuit resources: depth ≤ 4, total size ≤ 28 B + 8 for all state and output bits (constant depth, O(B) size).

Statement as elaborated and printed by Lean 4.26.0

∀ (B k : ℕ),
  (NimAudit.Recurrent.accC B k).depth ≤ 4 ∧
    (NimAudit.Recurrent.prevC B k).depth ≤ 4 ∧
      (NimAudit.Recurrent.validC B).depth ≤ 4 ∧
        (NimAudit.Recurrent.diffC B k).depth ≤ 4 ∧
          (NimAudit.Recurrent.diffValidC B).depth ≤ 4 ∧
            (NimAudit.Recurrent.accC B k).size + (NimAudit.Recurrent.prevC B k).size +
                  (NimAudit.Recurrent.diffC B k).size ≤
                28 ∧
              (NimAudit.Recurrent.validC B).size + (NimAudit.Recurrent.diffValidC B).size ≤ 8
Exact source text, lines 491–498
491/-- Per-update circuit resources: depth ≤ 4, total size ≤ 28 B + 8 for all492    state and output bits (constant depth, O(B) size). -/493theorem circuit_resources (B k : Nat) :494    depth (accC B k) ≤ 4 ∧ depth (prevC B k) ≤ 4 ∧ depth (validC B) ≤ 4 ∧495    depth (diffC B k) ≤ 4 ∧ depth (diffValidC B) ≤ 4 ∧496    size (accC B k) + size (prevC B k) + size (diffC B k) ≤ 28 ∧497    size (validC B) + size (diffValidC B) ≤ 8 := by498  simp [accC, prevC, validC, diffC, diffValidC, xorC, listMax]

Project declarations in the statement: AC0.Circ.depth, AC0.Circ.size, Recurrent.accC, Recurrent.diffC, Recurrent.diffValidC, Recurrent.prevC, Recurrent.validC

Project declarations used by the proof or definition body

AC0.Circ, AC0.Circ.and, AC0.Circ.depth, AC0.Circ.depth_and, AC0.Circ.depth_input, AC0.Circ.depth_not, AC0.Circ.depth_or, AC0.Circ.input, AC0.Circ.listMax, AC0.Circ.not, AC0.Circ.or, AC0.Circ.size, AC0.Circ.size_and, AC0.Circ.size_input, AC0.Circ.size_not, AC0.Circ.size_or

Definitions these statements use

def scan

Module NimCore (lean/NimCore.lean, lines 11–12) · file SHA-256 b07db6c505210d5a…

Statement as elaborated and printed by Lean 4.26.0

ℕ → List ℕ → ℕ
Exact source text, lines 11–12
11def scan (initial : Nat) (rows : List Nat) : Nat :=12  rows.foldl (fun acc row => acc ^^^ row) initial

Project declarations in the statement: none

Project declarations used by the proof or definition body

none

def nimSum

Module NimCore (lean/NimCore.lean, lines 7–9) · file SHA-256 b07db6c505210d5a…

Statement as elaborated and printed by Lean 4.26.0

List ℕ → ℕ
Exact source text, lines 7–9
7def nimSum : List Nat → Nat8  | [] => 09  | h :: t => h ^^^ nimSum t

Project declarations in the statement: none

Project declarations used by the proof or definition body

none

def AC0.Circ.depth

Module Circuit (lean/phase3/Circuit.lean, lines 61–66) · file SHA-256 af97cc0eec7d8464…

Statement as elaborated and printed by Lean 4.26.0

NimAudit.AC0.Circ → ℕ
Exact source text, lines 61–66
61def depth : Circ → Nat62  | input _ => 063  | const _ => 064  | not c => depth c + 165  | and cs => listMax (cs.attach.map (fun ⟨c, _⟩ => depth c)) + 166  | or cs => listMax (cs.attach.map (fun ⟨c, _⟩ => depth c)) + 1

Project declarations in the statement: AC0.Circ

Project declarations used by the proof or definition body

AC0.Circ, AC0.Circ.and, AC0.Circ.casesOn, AC0.Circ.const, AC0.Circ.input, AC0.Circ.listMax, AC0.Circ.not, AC0.Circ.or, AC0.Circ.rec, AC0.Circ.rec_1

def AC0.Circ.size

Module Circuit (lean/phase3/Circuit.lean, lines 51–56) · file SHA-256 af97cc0eec7d8464…

Statement as elaborated and printed by Lean 4.26.0

NimAudit.AC0.Circ → ℕ
Exact source text, lines 51–56
51def size : Circ → Nat52  | input _ => 153  | const _ => 154  | not c => size c + 155  | and cs => (cs.attach.map (fun ⟨c, _⟩ => size c)).sum + 156  | or cs => (cs.attach.map (fun ⟨c, _⟩ => size c)).sum + 1

Project declarations in the statement: AC0.Circ

Project declarations used by the proof or definition body

AC0.Circ, AC0.Circ.and, AC0.Circ.casesOn, AC0.Circ.const, AC0.Circ.input, AC0.Circ.not, AC0.Circ.or, AC0.Circ.rec, AC0.Circ.rec_1

def Recurrent.accC

Module NimRecurrent (lean/phase3/NimRecurrent.lean, lines 388–388) · file SHA-256 1f2994aefc75e7f5…

Statement as elaborated and printed by Lean 4.26.0

ℕ → ℕ → NimAudit.AC0.Circ
Exact source text, lines 388–388
388def accC (B k : Nat) : Circ := and [input (2 * B + 1), xorC (input k) (input (2 * B + 2 + k))]

Project declarations in the statement: AC0.Circ

Project declarations used by the proof or definition body

AC0.Circ, AC0.Circ.and, AC0.Circ.input, Recurrent.xorC

def Recurrent.diffC

Module NimRecurrent (lean/phase3/NimRecurrent.lean, lines 392–392) · file SHA-256 1f2994aefc75e7f5…

Statement as elaborated and printed by Lean 4.26.0

ℕ → ℕ → NimAudit.AC0.Circ
Exact source text, lines 392–392
392def diffC (B k : Nat) : Circ := xorC (input (B + k)) (input k)

Project declarations in the statement: AC0.Circ

Project declarations used by the proof or definition body

AC0.Circ.input, Recurrent.xorC

def Recurrent.diffValidC

Module NimRecurrent (lean/phase3/NimRecurrent.lean, lines 393–393) · file SHA-256 1f2994aefc75e7f5…

Statement as elaborated and printed by Lean 4.26.0

ℕ → NimAudit.AC0.Circ
Exact source text, lines 393–393
393def diffValidC (B : Nat) : Circ := and [input (2 * B), not (input (2 * B + 1))]

Project declarations in the statement: AC0.Circ

Project declarations used by the proof or definition body

AC0.Circ, AC0.Circ.and, AC0.Circ.input, AC0.Circ.not

def Recurrent.prevC

Module NimRecurrent (lean/phase3/NimRecurrent.lean, lines 389–390) · file SHA-256 1f2994aefc75e7f5…

Statement as elaborated and printed by Lean 4.26.0

ℕ → ℕ → NimAudit.AC0.Circ
Exact source text, lines 389–390
389def prevC (B k : Nat) : Circ :=390  or [and [input (2 * B + 1), input (B + k)], and [not (input (2 * B + 1)), input k]]

Project declarations in the statement: AC0.Circ

Project declarations used by the proof or definition body

AC0.Circ, AC0.Circ.and, AC0.Circ.input, AC0.Circ.not, AC0.Circ.or

def Recurrent.validC

Module NimRecurrent (lean/phase3/NimRecurrent.lean, lines 391–391) · file SHA-256 1f2994aefc75e7f5…

Statement as elaborated and printed by Lean 4.26.0

ℕ → NimAudit.AC0.Circ
Exact source text, lines 391–391
391def validC (B : Nat) : Circ := or [input (2 * B), not (input (2 * B + 1))]

Project declarations in the statement: AC0.Circ

Project declarations used by the proof or definition body

AC0.Circ, AC0.Circ.input, AC0.Circ.not, AC0.Circ.or

Full modules

ModuleFileLinesImports
Circuitlean/phase3/Circuit.lean1151NimProbability
NimCorelean/NimCore.lean139Std
NimRecurrentlean/phase3/NimRecurrent.lean555NimAttain, Circuit

Build evidence: fresh isolated rebuild of all 38 bundled modules with Lean (version 4.26.0, started 2026-10-10T15:21:56Z, finished 2026-10-10T15:27:00Z: 38/38 modules compiled, 1588 axiom reports, no errors. See Build for the commands and the independent audit of 2026-10-10 (dated evidence).