Research source · Plain text
PrincipalCover.lean
formalizations/frontier-derivative/FrontierDerivative/PrincipalCover.lean
212 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: 2cf9180b2c401596bc399567540462618eb3c046974d60f32febd2569363da6a
import FrontierDerivative.Basic
import FPRDTransfer.Compile
/-!
# Stationary principal derivative covers
A cover represents every frontier component as a fixed finite union of
principal right ideals `v · B_j`. The variable prefixes `v` are the stacks of
the already verified letter-synchronous `FPRD.StackMachine`; active flags and
basis indices live in its control. Exact initialization, one-symbol update,
and readout are explicit fields, so per-prefix existence cannot masquerade as
a stationary construction.
-/
namespace FrontierDerivative
/-- A language of stack words. -/
abbrev StackLang (Γ : Type) := List Γ → Prop
/-- Left prefixing of a stack language. -/
def prefixLang {Γ : Type} (v : List Γ) (B : StackLang Γ) : StackLang Γ :=
fun z => ∃ b, B b ∧ z = v ++ b
/-- Left derivative by one stack symbol. -/
def leftDerivative {Γ : Type} (X : Γ) (B : StackLang Γ) : StackLang Γ :=
fun tail => B (X :: tail)
/-- A basis carrying an exact finite-index action for one-symbol derivatives.
Finiteness of `J` is imposed at the mathematical LMR boundary, not by this
operational Lean structure. -/
structure DerivativeBasis (J : Type) (Γ : Type) where
lang : J → StackLang Γ
deriv : J → Γ → J
deriv_exact : ∀ j X tail, lang (deriv j X) tail ↔ lang j (X :: tail)
/-- Derivating an unprefixed basis element stays inside the basis. -/
theorem principalDerivative_nil {J : Type} {Γ : Type}
(B : DerivativeBasis J Γ) (j : J) (X : Γ) :
leftDerivative X (prefixLang [] (B.lang j)) = B.lang (B.deriv j X) := by
funext tail
simp [leftDerivative, prefixLang, B.deriv_exact]
/-- A matching derivative removes exactly one symbol from the variable prefix. -/
theorem principalDerivative_cons_eq {Γ : Type} (B : StackLang Γ)
(X : Γ) (v : List Γ) :
leftDerivative X (prefixLang (X :: v) B) = prefixLang v B := by
funext tail
simp [leftDerivative, prefixLang]
/-- A mismatched derivative annihilates a principal summand. -/
theorem principalDerivative_cons_ne {Γ : Type} (B : StackLang Γ)
{X Y : Γ} (v : List Γ) (hXY : X ≠ Y) :
leftDerivative X (prefixLang (Y :: v) B) = fun _ => False := by
funext tail
simp [leftDerivative, prefixLang, hXY]
/-- A semantic frontier relation indexed by source control state. -/
abbrev FrontierRel (Q : Type) (Γ : Type) := Q → List Γ → Prop
/-- The exact one-symbol derivative of an arbitrary represented frontier. -/
def frontierDerivative {Q : Type} {Input : Type} {Γ : Type}
(P : Machine Q Input Γ) (R : FrontierRel Q Γ) (a : Input) :
FrontierRel Q Γ :=
fun q' z' =>
∃ q X tail t,
R q (X :: tail) ∧
t ∈ P.transitions ∧
t.source = q ∧
t.input = a ∧
t.top = X ∧
q' = t.target ∧
z' = t.replacement ++ tail
theorem frontierDerivative_congr {Q : Type} {Input : Type}
{Γ : Type} (P : Machine Q Input Γ) {R S : FrontierRel Q Γ}
(h : ∀ q z, R q z ↔ S q z) (a : Input) (q : Q) (z : List Γ) :
frontierDerivative P R a q z ↔ frontierDerivative P S a q z := by
simp only [frontierDerivative, h]
theorem frontier_append_singleton_as_derivative {Q : Type}
{Input : Type} {Γ : Type}
[DecidableEq Q] [DecidableEq Input] [DecidableEq Γ]
(P : Machine Q Input Γ) (u : List Input) (a : Input) (q : Q)
(z : List Γ) :
P.Frontier (u ++ [a]) q z ↔
frontierDerivative P (P.Frontier u) a q z := by
exact Machine.frontier_append_singleton_iff P u a q z
/-- Fixed cover coordinates. Slot `i` represents
`stack_i · basis_(meta_i)` when its metadata is active. -/
structure CoverCoordinates (Ctrl : Type) (Q : Type) (J : Type)
(Γ : Type) (s : Nat) where
basis : DerivativeBasis J Γ
owner : Fin s → Q
slotBasis : Ctrl → Fin s → Option J
namespace CoverCoordinates
variable {Ctrl : Type} {Q : Type} {J : Type} {Γ : Type}
variable {s : Nat}
/-- The frontier relation denoted by one synchronous-stack configuration. -/
def Rep (D : CoverCoordinates Ctrl Q J Γ s) (c : FPRD.Config Ctrl Γ s) :
FrontierRel Q Γ :=
fun q z =>
∃ i j b,
D.owner i = q ∧
D.slotBasis c.ctrl i = some j ∧
D.basis.lang j b ∧
z = c.stacks i ++ b
end CoverCoordinates
/--
A stationary principal cover for `P` executed by `C`.
`step_exact` is the canonicalizer obligation: one fixed synchronous transition
must compute the exact semantic derivative, not merely a bounded cover that is
chosen afresh at each prefix or horizon.
-/
structure PrincipalCover {Q : Type} {Input : Type} {Γ : Type}
[DecidableEq Q] [DecidableEq Input] [DecidableEq Γ]
{Ctrl : Type} {s : Nat} (P : Machine Q Input Γ)
(C : FPRD.StackMachine Input Ctrl Γ s) (J : Type) where
coordinates : CoverCoordinates Ctrl Q J Γ s
valid : FPRD.Config Ctrl Γ s → Prop
init_valid : valid C.initConfig
step_valid : ∀ c a, valid c → valid (C.stepConfig c a)
init_exact : ∀ q z,
coordinates.Rep C.initConfig q z ↔ P.Frontier [] q z
step_exact : ∀ c a, valid c → ∀ q z,
coordinates.Rep (C.stepConfig c a) q z ↔
frontierDerivative P (coordinates.Rep c) a q z
readout_exact : ∀ c, valid c → (
C.accept c.ctrl = true ↔
∃ q z, coordinates.Rep c q z ∧ P.final q = true)
namespace PrincipalCover
variable {Q : Type} {Input : Type} {Γ : Type}
variable {J : Type} {Ctrl : Type} {s : Nat}
variable [DecidableEq Q] [DecidableEq Input] [DecidableEq Γ]
variable {P : Machine Q Input Γ} {C : FPRD.StackMachine Input Ctrl Γ s}
/-- Reverse-list induction, kept local so the run proof follows prefix growth. -/
theorem list_snoc_induction {α : Type} {motive : List α → Prop}
(hnil : motive [])
(hsnoc : ∀ xs x, motive xs → motive (xs ++ [x])) :
∀ xs, motive xs := by
intro xs
have hreverse : ∀ ys : List α, motive ys.reverse := by
intro ys
induction ys with
| nil => simpa using hnil
| cons x ys ih =>
simpa only [List.reverse_cons] using hsnoc ys.reverse x ih
simpa using hreverse xs.reverse
/-- The stationary cover denotes the exact semantic frontier after every word. -/
theorem cover_run_valid (K : PrincipalCover P C J) (w : List Input) :
K.valid (C.run w) := by
have hall : ∀ w : List Input, K.valid (C.run w) := by
apply list_snoc_induction
· exact K.init_valid
· intro w a ih
rw [FPRD.StackMachine.run_append]
exact K.step_valid (C.run w) a ih
exact hall w
/-- The stationary cover denotes the exact semantic frontier after every word. -/
theorem cover_run_exact (K : PrincipalCover P C J) (w : List Input)
(q : Q) (z : List Γ) :
K.coordinates.Rep (C.run w) q z ↔ P.Frontier w q z := by
have hall : ∀ w : List Input, ∀ q z,
K.coordinates.Rep (C.run w) q z ↔ P.Frontier w q z := by
apply list_snoc_induction
· intro q z
exact K.init_exact q z
· intro w a ih q z
rw [FPRD.StackMachine.run_append]
rw [K.step_exact (C.run w) a (K.cover_run_valid w)]
rw [frontier_append_singleton_as_derivative]
exact frontierDerivative_congr P (fun q z => ih q z) a q z
exact hall w q z
/-- The cover executor accepts exactly the normalized frontier machine. -/
theorem cover_decides_iff (K : PrincipalCover P C J) (w : List Input) :
C.decides w = true ↔ P.Accepts w := by
rw [FPRD.StackMachine.decides]
have hread := K.readout_exact (C.run w) (K.cover_run_valid w)
rw [hread]
rw [Machine.accepts_iff_final_frontier]
constructor
· rintro ⟨q, z, hrep, hfinal⟩
exact ⟨q, z, (K.cover_run_exact w q z).1 hrep, hfinal⟩
· rintro ⟨q, z, hfrontier, hfinal⟩
exact ⟨q, z, (K.cover_run_exact w q z).2 hfrontier, hfinal⟩
/--
The already verified persistent-stack compiler turns the cover executor into a
scaffolding automaton with the same language. LMR's external Theorem 16 then
places the reversal of this language in PEL when all carriers are finite.
-/
theorem compiled_cover_decides_iff (K : PrincipalCover P C J)
(w : List Input) :
(FPRD.compile C).decides w = true ↔ P.Accepts w := by
rw [FPRD.compile_decides]
exact K.cover_decides_iff w
end PrincipalCover
end FrontierDerivative