Research source · Plain text
CoverNormalization.lean
formalizations/frontier-derivative/FrontierDerivative/CoverNormalization.lean
191 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: 0418919b97f4fffe121da8540a19a27dd868f3a9ad0f2d77eea0562cd8105ef4
import FrontierDerivative.PrincipalCover
/-!
# Finite principal-cover derivative normalization
This module extends the stationary-cover substrate with list-valued derivative
tables. A basis derivative may expand into a finite principal cover. One-symbol
derivatives are therefore exposed locally once such a table is supplied.
The flattening calibration uses the one-element epsilon basis. It proves that
every finite list of stack words has an exact derivative-local cover. This
removes derivative access depth only by allowing one term per listed stack; it
does not bound cover width.
-/
namespace FrontierDerivative
namespace PrincipalCover
variable {Basis Γ : Type}
/-- One term denoting a concrete stem followed by a basis language. -/
structure Term (Basis Γ : Type) where
stem : List Γ
base : Basis
/-- A finite list of principal terms. -/
abbrev Cover (Basis Γ : Type) := List (Term Basis Γ)
/-- Semantics of one principal term. -/
def Term.denote (basis : Basis → StackLang Γ) (term : Term Basis Γ) :
StackLang Γ :=
prefixLang term.stem (basis term.base)
/-- Semantics of a finite principal cover. -/
def denote (basis : Basis → StackLang Γ) (cover : Cover Basis Γ) :
StackLang Γ :=
fun stack => ∃ term, term ∈ cover ∧ term.denote basis stack
/-- Pointwise union of two stack languages. -/
def unionLang (A B : StackLang Γ) : StackLang Γ :=
fun stack => A stack ∨ B stack
theorem denote_cons (basis : Basis → StackLang Γ) (term : Term Basis Γ)
(cover : Cover Basis Γ) :
denote basis (term :: cover) =
unionLang (term.denote basis) (denote basis cover) := by
funext stack
apply propext
simp [denote, unionLang]
/-- Structural append for covers. -/
def append : Cover Basis Γ → Cover Basis Γ → Cover Basis Γ
| [], right => right
| term :: left, right => term :: append left right
theorem denote_append (basis : Basis → StackLang Γ)
(left right : Cover Basis Γ) :
denote basis (append left right) =
unionLang (denote basis left) (denote basis right) := by
induction left with
| nil =>
funext stack
apply propext
simp [append, denote, unionLang]
| cons term left ih =>
rw [append, denote_cons, ih, denote_cons]
funext stack
apply propext
simp only [unionLang]
exact or_assoc.symm
/-- A finite list-valued table witnessing one-symbol derivative closure of a
basis. The basis carrier itself is not required to be finite here. -/
structure DerivBasis (Basis Γ : Type) where
lang : Basis → StackLang Γ
derive : Γ → Basis → Cover Basis Γ
sound : ∀ X b, leftDerivative X (lang b) = denote lang (derive X b)
/-- Differentiate one principal term. -/
def deriveTerm [DecidableEq Γ] (D : DerivBasis Basis Γ) (X : Γ)
(term : Term Basis Γ) : Cover Basis Γ :=
match term.stem with
| [] => D.derive X term.base
| Y :: rest =>
if X = Y then [{ stem := rest, base := term.base }] else []
/-- Differentiate a cover term by term. -/
def deriveCover [DecidableEq Γ] (D : DerivBasis Basis Γ) (X : Γ) :
Cover Basis Γ → Cover Basis Γ
| [] => []
| term :: cover =>
append (deriveTerm D X term) (deriveCover D X cover)
/-- One principal term is differentiated exactly. -/
theorem deriveTerm_sound [DecidableEq Γ] (D : DerivBasis Basis Γ)
(X : Γ) (term : Term Basis Γ) :
denote D.lang (deriveTerm D X term) =
leftDerivative X (term.denote D.lang) := by
cases term with
| mk stem base =>
cases stem with
| nil =>
rw [deriveTerm, ← D.sound X base]
funext stack
apply propext
simp [Term.denote, leftDerivative, prefixLang]
| cons Y rest =>
by_cases h : X = Y
· subst Y
funext stack
apply propext
simp [deriveTerm, denote, Term.denote, leftDerivative, prefixLang]
· funext stack
apply propext
simp [deriveTerm, h, denote, Term.denote, leftDerivative,
prefixLang]
/-- Every one-symbol derivative of a finite cover has an exact finite cover.
This normalization does not bound cover width. -/
theorem deriveCover_sound [DecidableEq Γ] (D : DerivBasis Basis Γ)
(X : Γ) (cover : Cover Basis Γ) :
denote D.lang (deriveCover D X cover) =
leftDerivative X (denote D.lang cover) := by
induction cover with
| nil =>
funext stack
apply propext
simp [deriveCover, denote, leftDerivative]
| cons term cover ih =>
rw [deriveCover, denote_append, deriveTerm_sound, ih, denote_cons]
rfl
/-- The one-element basis whose language is the singleton empty stack. -/
inductive EpsilonBasis where
| epsilon
deriving DecidableEq, Repr
/-- The singleton language containing only the empty stack. -/
def epsilonLang : EpsilonBasis → StackLang Γ :=
fun _ stack => stack = []
/-- Every derivative of the epsilon basis language has the empty cover. -/
def epsilonDerivBasis [DecidableEq Γ] : DerivBasis EpsilonBasis Γ where
lang := epsilonLang
derive := fun _ _ => []
sound := by
intro X b
funext stack
apply propext
constructor
· intro h
change X :: stack = [] at h
cases h
· intro h
rcases h with ⟨term, hmem, _⟩
cases hmem
/-- One epsilon-basis term for every listed stack. -/
def exactCover : List (List Γ) → Cover EpsilonBasis Γ
| [] => []
| stack :: stacks =>
{ stem := stack, base := .epsilon } :: exactCover stacks
theorem epsilonTerm_iff_eq (word stack : List Γ) :
Term.denote (epsilonLang (Γ := Γ))
{ stem := word, base := .epsilon } stack ↔
stack = word := by
constructor
· intro h
rcases h with ⟨rest, hrest, hstack⟩
change rest = [] at hrest
subst rest
simpa using hstack
· intro h
subst stack
exact ⟨[], rfl, by simp⟩
/-- Every finite listed frontier is represented exactly by its epsilon-basis
cover, before any optional deduplication. -/
theorem exactCover_iff_mem (stacks : List (List Γ)) (stack : List Γ) :
denote (epsilonLang (Γ := Γ)) (exactCover stacks) stack ↔
stack ∈ stacks := by
induction stacks with
| nil => simp [denote, exactCover]
| cons first rest ih =>
rw [exactCover, denote_cons]
simp only [unionLang, List.mem_cons]
rw [epsilonTerm_iff_eq, ih]
end PrincipalCover
end FrontierDerivative