Research source · Plain text
CoverExamples.lean
formalizations/frontier-derivative/FrontierDerivative/CoverExamples.lean
409 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: 1607c43a266064866b29e7e26faca6de5f51fa314f34516b722813ff14a59bfc
import FrontierDerivative.PrincipalCover
namespace FrontierDerivative.CoverExamples
inductive VisibleSymbol where
| bottom
| mark
deriving DecidableEq, Repr
inductive VisibleLetter where
| call
| ret
| stay
deriving DecidableEq, Repr
inductive VisibleBasisIndex where
| bottom
| epsilon
| empty
deriving DecidableEq, Repr
open VisibleSymbol VisibleLetter
@[simp] theorem exists_eq_pair {A B : Type} (a : A) (b : B)
(R : A → B → Prop) :
(∃ x y, (x = a ∧ y = b) ∧ R x y) ↔ R a b := by
constructor
· rintro ⟨x, y, ⟨hx, hy⟩, hR⟩
subst x
subst y
exact hR
· intro hR
exact ⟨a, b, ⟨rfl, rfl⟩, hR⟩
@[simp] theorem active_keep_decomposition (active : Prop)
(s z : List VisibleSymbol) :
(∃ X tail,
(active ∧ X :: tail = s ++ [bottom]) ∧
(bottom = X ∧ z = bottom :: tail ∨
mark = X ∧ z = mark :: tail)) ↔
active ∧ z = s ++ [bottom] := by
constructor
· rintro ⟨X, tail, ⟨ha, hstack⟩, hmove⟩
refine ⟨ha, ?_⟩
rcases hmove with ⟨hX, hz⟩ | ⟨hX, hz⟩
· subst X
subst z
exact hstack
· subst X
subst z
exact hstack
· rintro ⟨ha, hz⟩
subst z
cases s with
| nil =>
exact ⟨bottom, [], ⟨ha, rfl⟩, Or.inl ⟨rfl, rfl⟩⟩
| cons X tail =>
cases X
· exact ⟨bottom, tail ++ [bottom], ⟨ha, rfl⟩,
Or.inl ⟨rfl, rfl⟩⟩
· exact ⟨mark, tail ++ [bottom], ⟨ha, rfl⟩,
Or.inr ⟨rfl, rfl⟩⟩
def visibleBasisLang (j : VisibleBasisIndex) : StackLang VisibleSymbol :=
fun z =>
match j with
| .bottom => z = [bottom]
| .epsilon => z = []
| .empty => False
def visibleBasisDeriv (j : VisibleBasisIndex) (X : VisibleSymbol) :
VisibleBasisIndex :=
match j, X with
| .bottom, .bottom => .epsilon
| _, _ => .empty
def visibleBasis : DerivativeBasis VisibleBasisIndex VisibleSymbol where
lang := visibleBasisLang
deriv := visibleBasisDeriv
deriv_exact := by
intro j X tail
cases j <;> cases X <;> cases tail <;>
simp [visibleBasisLang, visibleBasisDeriv]
def visibleFrontier : Machine Unit VisibleLetter VisibleSymbol where
transitions :=
[ ⟨(), call, bottom, (), [mark, bottom]⟩
, ⟨(), call, mark, (), [mark, mark]⟩
, ⟨(), ret, mark, (), []⟩
, ⟨(), stay, bottom, (), [bottom]⟩
, ⟨(), stay, mark, (), [mark]⟩
]
initial := ⟨(), [bottom]⟩
final := fun _ => true
def visibleStep (active : Bool) (a : VisibleLetter)
(tops : Fin 1 → Option VisibleSymbol) :
Bool × (Fin 1 → FPRD.StackOp VisibleSymbol) :=
if active then
match a with
| call => (true, fun _ => .push mark)
| stay => (true, fun _ => .keep)
| ret =>
match tops 0 with
| some mark => (true, fun _ => .pop)
| _ => (false, fun _ => .keep)
else
(false, fun _ => .keep)
def visibleExecutor : FPRD.StackMachine VisibleLetter Bool VisibleSymbol 1 where
step := visibleStep
init := true
accept := fun active => active
def visibleCoordinates :
CoverCoordinates Bool Unit VisibleBasisIndex VisibleSymbol 1 where
basis := visibleBasis
owner := fun _ => ()
slotBasis := fun active _ => if active then some .bottom else none
theorem visible_rep_iff (c : FPRD.Config Bool VisibleSymbol 1)
(z : List VisibleSymbol) :
visibleCoordinates.Rep c () z ↔
c.ctrl = true ∧ z = c.stacks 0 ++ [bottom] := by
cases hctrl : c.ctrl <;>
simp [CoverCoordinates.Rep, visibleCoordinates, hctrl, visibleBasis,
visibleBasisLang, Fin.exists_fin_one]
@[simp] theorem visible_rep_iff_any (c : FPRD.Config Bool VisibleSymbol 1)
(q : Unit) (z : List VisibleSymbol) :
visibleCoordinates.Rep c q z ↔
c.ctrl = true ∧ z = c.stacks 0 ++ [bottom] := by
cases q
exact visible_rep_iff c z
def visibleCover :
PrincipalCover visibleFrontier visibleExecutor VisibleBasisIndex where
coordinates := visibleCoordinates
valid := fun _ => True
init_valid := trivial
step_valid := by
intro c a h
trivial
init_exact := by
intro q z
cases q
rw [visible_rep_iff]
simp [visibleExecutor, visibleFrontier, FPRD.StackMachine.initConfig,
Machine.Frontier, Machine.run, Machine.runFrom]
step_exact := by
intro c a hvalid q z
cases q
cases hctrl : c.ctrl <;> cases a <;> cases hstack : c.stacks 0 <;>
simp [visible_rep_iff_any, frontierDerivative, visibleExecutor, visibleStep,
visibleFrontier, FPRD.StackMachine.stepConfig, exists_eq_pair, hctrl,
hstack]
all_goals
rename_i head tail
cases head <;>
simp
readout_exact := by
intro c hvalid
simp [visibleExecutor, visibleFrontier, visible_rep_iff_any]
/-! ## A finite parallel cover
The first `tick` keeps the left run and also activates a right run. The second
slot is maintained in sync before activation; `valid` records that reachable
invariant. This is the small case that motivates making exactness conditional
on a preserved invariant rather than arbitrary junk configurations.
-/
inductive BranchLetter where
| tick
deriving DecidableEq, Repr
structure BranchCtrl where
left : Bool
right : Bool
deriving DecidableEq, Repr
def branchFrontier : Machine Bool BranchLetter VisibleSymbol where
transitions :=
[ ⟨false, .tick, bottom, false, [bottom]⟩
, ⟨false, .tick, bottom, true, [bottom]⟩
, ⟨false, .tick, mark, false, [mark]⟩
, ⟨false, .tick, mark, true, [mark]⟩
, ⟨true, .tick, bottom, true, [bottom]⟩
, ⟨true, .tick, mark, true, [mark]⟩
]
initial := ⟨false, [bottom]⟩
final := fun q => q
def branchStep (ctrl : BranchCtrl) (_ : BranchLetter)
(_ : Fin 2 → Option VisibleSymbol) :
BranchCtrl × (Fin 2 → FPRD.StackOp VisibleSymbol) :=
(⟨ctrl.left, ctrl.left || ctrl.right⟩, fun _ => .keep)
def branchExecutor :
FPRD.StackMachine BranchLetter BranchCtrl VisibleSymbol 2 where
step := branchStep
init := ⟨true, false⟩
accept := fun ctrl => ctrl.right
def branchCoordinates :
CoverCoordinates BranchCtrl Bool VisibleBasisIndex VisibleSymbol 2 where
basis := visibleBasis
owner := fun i => if i = 0 then false else true
slotBasis := fun ctrl i =>
if i = 0 then
if ctrl.left then some .bottom else none
else
if ctrl.right then some .bottom else none
@[simp] theorem branch_rep_false_iff
(c : FPRD.Config BranchCtrl VisibleSymbol 2) (z : List VisibleSymbol) :
branchCoordinates.Rep c false z ↔
c.ctrl.left = true ∧ z = c.stacks 0 ++ [bottom] := by
rcases hc : c.ctrl with ⟨left, right⟩
cases left <;> cases right <;>
simp [CoverCoordinates.Rep, branchCoordinates, visibleBasis,
visibleBasisLang, hc]
@[simp] theorem branch_rep_true_iff
(c : FPRD.Config BranchCtrl VisibleSymbol 2) (z : List VisibleSymbol) :
branchCoordinates.Rep c true z ↔
c.ctrl.right = true ∧ z = c.stacks 1 ++ [bottom] := by
rcases hc : c.ctrl with ⟨left, right⟩
cases left <;> cases right <;>
simp [CoverCoordinates.Rep, branchCoordinates, visibleBasis,
visibleBasisLang, hc]
theorem branch_rep_not_nil (c : FPRD.Config BranchCtrl VisibleSymbol 2)
(q : Bool) : ¬branchCoordinates.Rep c q [] := by
cases q <;> simp
theorem branch_derivative_false_iff
(R : FrontierRel Bool VisibleSymbol)
(hne : ∀ q, ¬R q []) (z : List VisibleSymbol) :
frontierDerivative branchFrontier R .tick false z ↔ R false z := by
constructor
· rintro ⟨q, X, tail, t, hR, ht, hsource, hinput, htop, htarget, hz⟩
simp only [branchFrontier, List.mem_cons, List.not_mem_nil, or_false] at ht
rcases ht with rfl | rfl | rfl | rfl | rfl | rfl
· change false = q at hsource
change bottom = X at htop
change z = bottom :: tail at hz
subst q
subst X
subst z
exact hR
· change false = true at htarget
contradiction
· change false = q at hsource
change mark = X at htop
change z = mark :: tail at hz
subst q
subst X
subst z
exact hR
· change false = true at htarget
contradiction
· change false = true at htarget
contradiction
· change false = true at htarget
contradiction
· intro hR
cases z with
| nil => exact (hne false hR).elim
| cons X tail =>
cases X
· exact ⟨false, bottom, tail,
⟨false, .tick, bottom, false, [bottom]⟩,
hR, by simp [branchFrontier], rfl, rfl, rfl, rfl, rfl⟩
· exact ⟨false, mark, tail,
⟨false, .tick, mark, false, [mark]⟩,
hR, by simp [branchFrontier], rfl, rfl, rfl, rfl, rfl⟩
theorem branch_derivative_true_iff
(R : FrontierRel Bool VisibleSymbol)
(hne : ∀ q, ¬R q []) (z : List VisibleSymbol) :
frontierDerivative branchFrontier R .tick true z ↔
R false z ∨ R true z := by
constructor
· rintro ⟨q, X, tail, t, hR, ht, hsource, hinput, htop, htarget, hz⟩
simp only [branchFrontier, List.mem_cons, List.not_mem_nil, or_false] at ht
rcases ht with rfl | rfl | rfl | rfl | rfl | rfl
· change true = false at htarget
contradiction
· change false = q at hsource
change bottom = X at htop
change z = bottom :: tail at hz
subst q
subst X
subst z
exact Or.inl hR
· change true = false at htarget
contradiction
· change false = q at hsource
change mark = X at htop
change z = mark :: tail at hz
subst q
subst X
subst z
exact Or.inl hR
· change true = q at hsource
change bottom = X at htop
change z = bottom :: tail at hz
subst q
subst X
subst z
exact Or.inr hR
· change true = q at hsource
change mark = X at htop
change z = mark :: tail at hz
subst q
subst X
subst z
exact Or.inr hR
· intro hR
rcases hR with hR | hR
· cases z with
| nil => exact (hne false hR).elim
| cons X tail =>
cases X
· exact ⟨false, bottom, tail,
⟨false, .tick, bottom, true, [bottom]⟩,
hR, by simp [branchFrontier], rfl, rfl, rfl, rfl, rfl⟩
· exact ⟨false, mark, tail,
⟨false, .tick, mark, true, [mark]⟩,
hR, by simp [branchFrontier], rfl, rfl, rfl, rfl, rfl⟩
· cases z with
| nil => exact (hne true hR).elim
| cons X tail =>
cases X
· exact ⟨true, bottom, tail,
⟨true, .tick, bottom, true, [bottom]⟩,
hR, by simp [branchFrontier], rfl, rfl, rfl, rfl, rfl⟩
· exact ⟨true, mark, tail,
⟨true, .tick, mark, true, [mark]⟩,
hR, by simp [branchFrontier], rfl, rfl, rfl, rfl, rfl⟩
def branchCover :
PrincipalCover branchFrontier branchExecutor VisibleBasisIndex where
coordinates := branchCoordinates
valid := fun c => c.stacks 0 = c.stacks 1
init_valid := rfl
step_valid := by
intro c a hvalid
simpa [branchExecutor, branchStep, FPRD.StackMachine.stepConfig] using hvalid
init_exact := by
intro q z
cases q <;>
simp [branchExecutor, branchFrontier, FPRD.StackMachine.initConfig,
Machine.Frontier, Machine.run, Machine.runFrom]
step_exact := by
intro c a hvalid q z
cases a
cases q
· rw [branch_derivative_false_iff (branchCoordinates.Rep c)
(branch_rep_not_nil c)]
simp [branchExecutor, branchStep, FPRD.StackMachine.stepConfig]
· rw [branch_derivative_true_iff (branchCoordinates.Rep c)
(branch_rep_not_nil c)]
simp [branchExecutor, branchStep, FPRD.StackMachine.stepConfig,
or_and_right, hvalid]
readout_exact := by
intro c hvalid
simp [branchExecutor, branchFrontier]
#check principalDerivative_nil
#check principalDerivative_cons_eq
#check principalDerivative_cons_ne
#check PrincipalCover.cover_run_exact
#check PrincipalCover.cover_decides_iff
#check PrincipalCover.compiled_cover_decides_iff
example : (visibleExecutor.run [call, call, ret, stay]).stacks 0 = [mark] := by
decide
example : visibleExecutor.decides [ret] = false := by
decide
example : visibleExecutor.decides [call, ret, stay] = true := by
decide
example : visibleFrontier.Accepts [call, ret, stay] := by
exact (visibleCover.cover_decides_iff [call, ret, stay]).1 (by decide)
example :
(FPRD.compile visibleExecutor).decides [call, ret, stay] = true ↔
visibleFrontier.Accepts [call, ret, stay] :=
visibleCover.compiled_cover_decides_iff [call, ret, stay]
example : branchExecutor.decides [] = false := by
decide
example : branchExecutor.decides [.tick] = true := by
decide
example : branchFrontier.Accepts [.tick] := by
exact (branchCover.cover_decides_iff [.tick]).1 (by decide)
example :
(FPRD.compile branchExecutor).decides [.tick, .tick] = true ↔
branchFrontier.Accepts [.tick, .tick] :=
branchCover.compiled_cover_decides_iff [.tick, .tick]
end FrontierDerivative.CoverExamples