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

Section 5.4, “The initialisation boundary for restoration”Matching deltas preserves nim(Q); a completed matching-delta policy loses from the winning position (2)

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

1 Paper text

The initialisation boundary for restoration. Matching two successive differences yields nim⁡(R)=nim⁡(Q)\operatorname{nim}(R)=\operatorname{nim}(Q), whether or not that value is zero. Thus Proposition 5.5 does not supply a classifier for an arbitrary starting position. For example, complete a matching-delta policy by subtracting one from the first nonempty heap whenever no matching response exists or no previous frame is available. Starting from (2)(2), it plays (2)→(1)→(0)(2)\to(1)\to(0) and the first player loses, although (2)(2) is winning. The fallback after the first move is needed because its delta is 2⊕1=32\oplus1=3, which cannot be realised from (1)(1). This counterexample does not rule out every possible verifier construction; it shows that conditional restoration and an unspecified fallback do not establish one. We make no universal-verifier claim. Initial winning-move selection can instead use the multi-channel construction above or the growing recurrent scan in Section 5.5.

Generated from paper_jmlr.tex, lines 781–784.

2 Explain this

Matching the last difference only says nim⁡(R)=nim⁡(Q)\operatorname{nim}(R)=\operatorname{nim}(Q). If QQ did not have nim-sum zero, neither does RR. So restoration cannot, by itself, tell whether an arbitrary starting position is winning.

Counterexample. Complete a matching-delta policy by "subtract one from the first nonempty heap" whenever no matching reply exists or no previous frame is available. From (2)(2), a winning position, the first player plays (2)→(1)(2)\to(1) (no previous frame). The opponent's reply from (1)(1) is computed by the same policy: the difference to match is 2⊕1=32\oplus1=3, which cannot be realised from (1)(1), so it falls back and plays (1)→(0)(1)\to(0). The first player has lost from a winning position.

What it shows: conditional restoration plus an unspecified fallback is not a verifier. It does not rule out every possible verifier. Initial moves can come from the multi-channel construction or the recurrent scan instead.

3 How this is formalised

  • Misc.init_counterexample checks the counterexample step by step: (2)(2) is winning; the completed policy Misc.mdPolicy plays (2)→(1)(2)\to(1); no move from (1)(1) cancels 2⊕12\oplus1; the fallback plays (1)→(0)(1)\to(0); (1)(1) is winning and (0)(0) is losing.
  • Rollout.matching_deltas_do_not_force_zero: the universal statement "matching deltas forces nim-sum zero" is false without the zero promise; no_zero_without_zero_promise is the concrete instance 1⊕3=3⊕11\oplus3=3\oplus1 with 1≠01\ne0.
Coverage record
Paper anchorpar-the-initialisation-boundary-for-restoration-p1 (website anchor; the manuscript has no label here)
Displayed asSection 5.4, “The initialisation boundary for restoration”
ClaimMatching deltas preserves nim(Q); a completed matching-delta policy loses from the winning position (2)
Coverage categoryChecked theorem
Statement sourcepaper_jmlr.tex lines 781–784; SHA-256 of the normalised block source 0044397e1e8f5fe7…
Lean declarations
Depends onProposition 5.5
Explanationsexplain/c-init-boundary, formal/c-init-boundary
Build evidencefresh isolated rebuild, audit report

4 Lean statement and source

Principal declarations

theorem Misc.init_counterexample

Module Misc (lean/phase6/Misc.lean, lines 707–714) · file SHA-256 07766c03566dbfca… Axioms reported by the fresh build: propext, Quot.sound

From the winning position (2) the completed matching-delta policy plays (2) → (1) and then (as the next mover, delta 2 ⊕ 1 = 3 is not realisable from (1)) (1) → (0): the first player loses although (2) is winning.

Statement as elaborated and printed by Lean 4.26.0

NimAudit.Game.Win [2] ∧
  NimAudit.Misc.mdPolicy none [2] = some [1] ∧
    NimAudit.Game.cancelFirst (NimAudit.nimSum [2] ^^^ NimAudit.nimSum [1]) [1] = none ∧
      NimAudit.Misc.mdPolicy (some [2]) [1] = some [0] ∧
        NimAudit.Game.Win [1] ∧ NimAudit.Game.Lose [0]
Exact source text, lines 707–714
707/-- From the winning position (2) the completed matching-delta policy plays (2) → (1) and708    then (as the next mover, delta 2 ⊕ 1 = 3 is not realisable from (1)) (1) → (0): the709    first player loses although (2) is winning. -/710theorem init_counterexample :711    Win [2] ∧ mdPolicy none [2] = some [1] ∧ cancelFirst (nimSum [2] ^^^ nimSum [1]) [1] = none ∧712    mdPolicy (some [2]) [1] = some [0] ∧ Win [1] ∧ Lose [0] := by713  refine ⟨(win_iff _).2 (by decide), by decide, by decide, by decide, (win_iff _).2 (by decide),714    (lose_iff _).2 (by decide)⟩

Project declarations in the statement: Game.Lose, Game.Win, Game.cancelFirst, Misc.mdPolicy, nimSum

Project declarations used by the proof or definition body

Game.Lose, Game.Win, Game.cancelFirst, Game.lose_iff, Game.win_iff, Misc.mdPolicy, nimSum

theorem Rollout.matching_deltas_do_not_force_zero

Module NimRollout (lean/NimRollout.lean, lines 318–323) · file SHA-256 1a99428d71573d31… Axioms reported by the fresh build: propext

Matching deltas alone never force a zero result: the universal statement is false.

Statement as elaborated and printed by Lean 4.26.0

¬∀ (q q' r : ℕ), q ^^^ q' = q' ^^^ r → r = 0
Exact source text, lines 318–323
318/-- Matching deltas alone never force a zero result: the universal statement is false. -/319theorem matching_deltas_do_not_force_zero :320    ¬ ∀ q q' r : Nat, q ^^^ q' = q' ^^^ r → r = 0 := by321  intro h322  have := h 1 3 1 (by decide)323  exact absurd this (by decide)

Project declarations in the statement: none

Project declarations used by the proof or definition body

none

theorem no_zero_without_zero_promise

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

Statement as elaborated and printed by Lean 4.26.0

1 ^^^ 3 = 3 ^^^ 1 ∧ 1 ≠ 0
Exact source text, lines 72–73
72theorem no_zero_without_zero_promise :73    (1 ^^^ 3 = 3 ^^^ 1) ∧ (1 : Nat) ≠ 0 := by decide

Project declarations in the statement: none

Project declarations used by the proof or definition body

none

Definitions these statements use

def Misc.mdPolicy

Module Misc (lean/phase6/Misc.lean, lines 698–705) · file SHA-256 07766c03566dbfca…

The matching-delta policy completed by "subtract one from the first nonempty heap" whenever there is no previous frame or no matching response.

Statement as elaborated and printed by Lean 4.26.0

Option (List ℕ) → List ℕ → Option (List ℕ)
Exact source text, lines 698–705
698/-- The matching-delta policy completed by "subtract one from the first nonempty heap"699    whenever there is no previous frame or no matching response. -/700def mdPolicy (prev : Option (List Nat)) (cur : List Nat) : Option (List Nat) :=701  match prev with702  | none => subFirstPos cur703  | some Q => match cancelFirst (nimSum Q ^^^ nimSum cur) cur with704    | some R => some R705    | none => subFirstPos cur

Project declarations in the statement: none

Project declarations used by the proof or definition body

Game.cancelFirst, Rollout.subFirstPos, nimSum

inductive Game.Lose

Module NimGame (lean/phase2/NimGame.lean, lines 39–40) · file SHA-256 23df6bb87ecfd344…

Statement as elaborated and printed by Lean 4.26.0

List ℕ → Prop
Exact source text, lines 39–40
39inductive Lose : List Nat → Prop40  | intro (p : List Nat) : (∀ q, Move p q → Win q) → Lose p

Project declarations in the statement: none

Project declarations used by the proof or definition body

Game.Move, Game.Win

inductive Game.Win

Module NimGame (lean/phase2/NimGame.lean, lines 37–38) · file SHA-256 23df6bb87ecfd344…

Statement as elaborated and printed by Lean 4.26.0

List ℕ → Prop
Exact source text, lines 37–38
37inductive Win : List Nat → Prop38  | intro (p q : List Nat) : Move p q → Lose q → Win p

Project declarations in the statement: none

Project declarations used by the proof or definition body

Game.Lose, Game.Move

def Game.cancelFirst

Module NimGame (lean/phase2/NimGame.lean, lines 244–247) · file SHA-256 23df6bb87ecfd344…

Replace the first heap x with x ^^^ s < x by x ^^^ s.

Statement as elaborated and printed by Lean 4.26.0

ℕ → List ℕ → Option (List ℕ)
Exact source text, lines 244–247
244/-- Replace the first heap x with x ^^^ s < x by x ^^^ s. -/245def cancelFirst (s : Nat) : List Nat → Option (List Nat)246  | [] => none247  | x :: t => if x ^^^ s < x then some ((x ^^^ s) :: t) else (cancelFirst s t).map (x :: ·)

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

Full modules

ModuleFileLinesImports
Misclean/phase6/Misc.lean912Bypass
NimCorelean/NimCore.lean139Std
NimGamelean/phase2/NimGame.lean634NimRollout
NimRolloutlean/NimRollout.lean349NimCore

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).