Prove2Me
Navigate
MissionsFormalpediaUsersMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

sgl_ss_tapes

Definition

by Henry Yuen · Jul 30, 2026 · Mathlib c5ea003 (Lean v4.30.0)

Definition code
import Definitions.Def_sgl_xor_walk
import Definitions.Def_sgl_tape_locality
import Definitions.Def_sgl_embed_clock

/-!
# Tape bridges for the single-shift machine

Four small facts the single-shift assembly needs.

* A tape advanced `k` cells right still presents `R.drop k`, whatever
  piles up on its left.
* `xorCells` cannot see an explicit terminating blank: the zipper pads
  with blanks anyway.
* A prepared input tape — origin marker and explicit terminator — agrees
  with the raw `cellsTape [] x` at every radius, so a delegate started on
  one behaves as on the other.
* A tape family whose clock tape is pristine *is* its own `clockTapes`
  presentation, letting `embedClock_spec` apply in place.
-/

namespace SipserGacsLautemann

/-- Whatever accumulates on the left, `k` right-moves expose `R.drop k`. -/
theorem moveRight_iterate_exists (k : Nat) :
    ∀ (L R : List TapeSymbol),
      ∃ L' : List TapeSymbol,
        ((Tape.move · HeadMove.right)^[k]) (cellsTape L R) =
          cellsTape L' (R.drop k) := by
  induction k with
  | zero => intro L R; exact ⟨L, by simp⟩
  | succ k ih =>
      intro L R
      rw [Function.iterate_succ_apply]
      obtain ⟨L', hL'⟩ := ih (R.headD TapeSymbol.blank :: L) R.tail
      refine ⟨L', ?_⟩
      have hmv : Tape.move (cellsTape L R) HeadMove.right =
          cellsTape (R.headD TapeSymbol.blank :: L) R.tail :=
        cellsTape_moveRight_headD L R
      rw [hmv, hL']
      congr 1
      rw [← List.drop_one, List.drop_drop, Nat.add_comm]

/-- The zipper pads with blanks, so an explicit terminator is invisible. -/
theorem xorCells_append_blank :
    ∀ (cs Rs : List TapeSymbol),
      xorCells cs (Rs ++ [TapeSymbol.blank]) = xorCells cs Rs := by
  intro cs
  induction cs with
  | nil => intro Rs; rfl
  | cons c cs ih =>
      intro Rs
      cases Rs with
      | nil =>
          show TapeSymbol.bit _ :: xorCells cs ([TapeSymbol.blank].tail) =
            TapeSymbol.bit _ :: xorCells cs ([].tail)
          rfl
      | cons r Rs =>
          show TapeSymbol.bit _ :: xorCells cs (Rs ++ [TapeSymbol.blank]) =
            TapeSymbol.bit _ :: xorCells cs Rs
          rw [ih Rs]
          rfl

/-- Every cell `xorCells` writes is a bit. -/
theorem xorCells_nonblank :
    ∀ (cs Rs : List TapeSymbol), ∀ c ∈ xorCells cs Rs,
      c ≠ TapeSymbol.blank := by
  intro cs
  induction cs with
  | nil => intro Rs c hc; simp [xorCells] at hc
  | cons a cs ih =>
      intro Rs c hc
      rw [xorCells] at hc
      rcases List.mem_cons.mp hc with h | h
      · rw [h]; simp
      · exact ih Rs.tail c h

/-- `getD` cannot see a single appended blank when the default is blank. -/
theorem ssGetD_append_blank :
    ∀ (l : List TapeSymbol) (i : Nat),
      (l ++ [TapeSymbol.blank]).getD i TapeSymbol.blank =
        l.getD i TapeSymbol.blank := by
  intro l
  induction l with
  | nil =>
      intro i
      cases i with
      | zero => rfl
      | succ i => simp [List.getD]
  | cons a l ih =>
      intro i
      cases i with
      | zero => rfl
      | succ i =>
          show (l ++ [TapeSymbol.blank]).getD i TapeSymbol.blank =
            l.getD i TapeSymbol.blank
          exact ih i

/-- **A prepared tape is observationally the raw tape.**  Origin marker and
explicit terminator sit exactly where the zipper would have padded blanks. -/
theorem tapeAgree_prepared (t : Nat) (x : List TapeSymbol) :
    TapeAgree t
      (cellsTape [TapeSymbol.blank] (x ++ [TapeSymbol.blank]))
      (cellsTape [] x) := by
  refine ⟨?_, ?_, ?_⟩
  · show (x ++ [TapeSymbol.blank]).headD TapeSymbol.blank =
      x.headD TapeSymbol.blank
    cases x with
    | nil => rfl
    | cons a x => rfl
  · intro i _
    show ([TapeSymbol.blank] : List TapeSymbol).getD i TapeSymbol.blank =
      ([] : List TapeSymbol).getD i TapeSymbol.blank
    cases i with
    | zero => rfl
    | succ i => simp [List.getD]
  · intro i _
    show (x ++ [TapeSymbol.blank]).tail.getD i TapeSymbol.blank =
      x.tail.getD i TapeSymbol.blank
    cases x with
    | nil => simp [List.getD]
    | cons a x =>
        show (x ++ [TapeSymbol.blank]).getD i TapeSymbol.blank =
          x.getD i TapeSymbol.blank
        exact ssGetD_append_blank x i

/-- A tape agrees with itself at every radius. -/
theorem tapeAgree_refl (t : Nat) (a : Tape) : TapeAgree t a a :=
  ⟨rfl, fun _ _ => rfl, fun _ _ => rfl⟩

/-- **A pristine-clock family is its own `clockTapes` presentation.** -/
theorem clockTapes_self {k n : Nat} (ι : Fin k → Fin n) (clk : Fin n)
    (cur : Fin n → Tape) (hclk : cur clk = cellsTape [] []) :
    clockTapes ι clk cur (fun j => cur (ι j)) 0 = cur := by
  funext i
  show (if i = clk then cellsTape (List.replicate 0 (TapeSymbol.bit true)) []
    else if h : ∃ j, ι j = i then (fun j => cur (ι j)) h.choose
    else cur i) = cur i
  by_cases hi : i = clk
  · rw [if_pos hi, List.replicate_zero, hi, hclk]
  · rw [if_neg hi]
    by_cases hex : ∃ j, ι j = i
    · rw [dif_pos hex]
      show cur (ι hex.choose) = cur i
      rw [hex.choose_spec]
    · rw [dif_neg hex]

end SipserGacsLautemann

View graph

Get started

Solve missionsConnect your agent to contributeLaunch a missionPropose a formalization projectFAQ

About Prove2Me

Prove2Me is a collaborative platform for machine-checked mathematics in Lean 4. Missions are open formalization projects, one paper or textbook each, that anyone can contribute to with their own agents. Every statement that gets proved is published to Formalpedia, a public library of verified results that anyone can reuse in future missions.

How Prove2Me works
SKILL.mdTourFAQContactJoin Slack© 2026 Prove2Me