Research source · Plain text
Neighbourhood.lean
site/public/formal/persistent-stacks/lean/FPRDTransfer/Theorem16/Invariants/Neighbourhood.lean
608 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: caae28cc2886d5bd8fa91d21d0a83a54df65f71333adebfe35682196dd788aaa
import FPRDTransfer.Theorem16.Invariants.Path
namespace FPRD
namespace Theorem16
universe u uName uSymbol uItem
variable {Sym Q : Type} {Gamma : Type u} {d k : Nat}
variable [FiniteEnum Sym] [DecidableEq Sym]
variable [FiniteEnum Q] [DecidableEq Q]
variable [FiniteEnum Gamma] [DecidableEq Gamma]
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem exactMatch_seq {Name : Type uName} {Symbol : Type uSymbol}
{G : Grammar Name Symbol} {left right : Expr Name Symbol}
{input : List Symbol} {leftCondition rightCondition : Prop}
(hleft : ExactMatch G left input leftCondition)
(hright : ExactMatch G right input rightCondition) :
ExactMatch G (.seq left right) input (leftCondition ∧ rightCondition) := by
apply exactMatch_of_cases
· rintro ⟨hleftCondition, hrightCondition⟩
exact Eval.seqOk (hleft.ok_iff.mpr hleftCondition)
(hright.ok_iff.mpr hrightCondition)
· intro hcondition
by_cases hleftCondition : leftCondition
· exact Eval.seqOk (hleft.ok_iff.mpr hleftCondition)
(hright.err_iff.mpr (by
intro hrightCondition
exact hcondition ⟨hleftCondition, hrightCondition⟩))
· exact Eval.seqErr (hleft.err_iff.mpr hleftCondition)
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem seqAll_map_exact {Name : Type uName} {Symbol : Type uSymbol}
{Item : Type uItem} {G : Grammar Name Symbol} (items : List Item)
(expression : Item → Expr Name Symbol) (input : List Symbol)
(predicate : Item → Prop)
(hall : ∀ item, item ∈ items →
ExactMatch G (expression item) input (predicate item)) :
ExactMatch G (Expr.seqAll (items.map expression)) input
(∀ item, item ∈ items → predicate item) := by
induction items with
| nil =>
apply exactMatch_of_cases
· intro _
exact Eval.eps
· simp
| cons item items ih =>
change ExactMatch G
(.seq (expression item) (Expr.seqAll (items.map expression))) input _
have hhead := hall item (by simp)
have htail := ih (fun other hother => hall other (by simp [hother]))
have hseq := exactMatch_seq hhead htail
refine ⟨hseq.ok_iff.trans ?_, hseq.err_iff.trans (not_congr ?_)⟩
· simp
· simp
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem observeAt_viewAt (S : Scaffold d Gamma) (depth vertex : Nat)
(ports : List (Fin d)) (hlength : ports.length ≤ depth) :
observeAt depth (S.viewAt depth vertex) ports hlength =
match S.follow vertex ports with
| none => none
| some endpoint => some (S.label endpoint) := by
induction depth generalizing vertex ports with
| zero =>
cases ports with
| nil => rfl
| cons port ports => simp at hlength
| succ depth ih =>
cases ports with
| nil => rfl
| cons port ports =>
simp only [Scaffold.follow_cons]
cases hedge : S.edge vertex port with
| none => simp [Scaffold.viewAt, observeAt, hedge]
| some endpoint =>
simpa [Scaffold.viewAt, observeAt, hedge] using
ih endpoint ports (Nat.le_of_succ_le_succ hlength)
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem observe_viewAt (S : Scaffold d Gamma) (vertex : Nat)
(path : BoundedPath d k) :
observe (S.viewAt k vertex) path =
match S.follow vertex path.elems with
| none => none
| some endpoint => some (S.label endpoint) := by
exact observeAt_viewAt S k vertex path.elems path.length_le
def pathPresentAt (A : Automaton Sym Q Gamma d k) (word : List Sym)
(position : Nat) (path : BoundedPath d k) : Prop :=
∃ endpoint, (A.run (word.take position)).2.follow
(A.run (word.take position)).2.top path.elems = some endpoint
def pathLabelledAt (A : Automaton Sym Q Gamma d k) (word : List Sym)
(position : Nat) (path : BoundedPath d k) (label : Gamma) : Prop :=
∃ endpoint, (A.run (word.take position)).2.follow
(A.run (word.take position)).2.top path.elems = some endpoint ∧
(A.run (word.take position)).2.label endpoint = some label
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem foldl_step_label_old (A : Automaton Sym Q Gamma d k) :
∀ (suffix : List Sym) (config : Q × Scaffold d Gamma) (source : Nat),
source ≤ config.2.top →
(suffix.foldl A.step config).2.label source = config.2.label source := by
intro suffix
induction suffix with
| nil => intro config source _; rfl
| cons symbol suffix ih =>
intro config source hsource
simp only [List.foldl_cons]
rw [ih (A.step config symbol) source]
· unfold Automaton.step
apply Scaffold.append_label_old
omega
· simp [Automaton.step]
omega
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem run_append_label_old (A : Automaton Sym Q Gamma d k)
(initial suffix : List Sym) (source : Nat) (hsource : source ≤ initial.length) :
(A.run (initial ++ suffix)).2.label source =
(A.run initial).2.label source := by
have htop : source ≤ (A.run initial).2.top := by
rw [Automaton.run_top]
exact hsource
unfold Automaton.run
rw [List.foldl_append]
exact foldl_step_label_old A suffix _ source htop
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem run_take_label_old (A : Automaton Sym Q Gamma d k)
(word : List Sym) {earlier later : Nat} (hearlier : earlier ≤ later)
(hlater : later ≤ word.length) :
(A.run (word.take later)).2.label earlier =
(A.run (word.take earlier)).2.label earlier := by
have htake : (word.take later).take earlier = word.take earlier := by
simp [List.take_take, Nat.min_eq_left hearlier]
have hlength : earlier ≤ ((word.take later).take earlier).length := by
rw [List.length_take, List.length_take]
apply (Nat.le_min).2
exact ⟨Nat.le_refl _, (Nat.le_min).2
⟨hearlier, Nat.le_trans hearlier hlater⟩⟩
calc
(A.run (word.take later)).2.label earlier =
(A.run ((word.take later).take earlier ++
(word.take later).drop earlier)).2.label earlier := by
rw [List.take_append_drop]
_ = (A.run ((word.take later).take earlier)).2.label earlier :=
run_append_label_old A _ _ earlier hlength
_ = (A.run (word.take earlier)).2.label earlier := by rw [htake]
/-- I4 needs path exactness at the current prefix and label exactness at every
possible endpoint, including the current endpoint reached through `SELF`. -/
structure NeighbourhoodContext (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length) : Prop where
path : ∀ bounded, PathExact A hdistance word position hposition bounded
label : ∀ endpoint, endpoint ≤ position → ∀ target,
LabelExact A hdistance (word.take endpoint) target
omit [DecidableEq Sym] in
theorem path_pos_exact (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length)
(hcontext : NeighbourhoodContext A hdistance word position hposition)
(path : BoundedPath d k) :
ExactMatch (rawGrammar A hdistance) (.pos (.nonterm (.path path)))
(word.take position).reverse (pathPresentAt A word position path) := by
let S := (A.run (word.take position)).2
have hpath := hcontext.path path
apply exactMatch_of_cases
· rintro ⟨endpoint, hfollow⟩
apply pos_ok_of_ok
apply (hpath.ok_iff (word.take endpoint).reverse).mpr
exact ⟨endpoint, hfollow,
path_endpoint_le A word position hposition path endpoint hfollow, rfl⟩
· intro hmissing
apply pos_err_of_err
apply hpath.err_iff.mpr
cases hfollow : S.follow S.top path.elems with
| none => rfl
| some endpoint =>
exact (hmissing ⟨endpoint, by simpa [S] using hfollow⟩).elim
omit [DecidableEq Sym] in
theorem path_label_body_ok (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length)
(hcontext : NeighbourhoodContext A hdistance word position hposition)
(path : BoundedPath d k) (label : Gamma)
(hlabelled : pathLabelledAt A word position path label) :
∃ rest, Eval (rawGrammar A hdistance)
(.seq (.nonterm (.path path)) (.nonterm (.label label)))
(word.take position).reverse (.ok rest) := by
rcases hlabelled with ⟨endpoint, hfollow, hlabel⟩
have hle := path_endpoint_le A word position hposition path endpoint hfollow
have hendpointWord : endpoint ≤ word.length := Nat.le_trans hle hposition
have hlabel' : (A.run (word.take endpoint)).2.label
(A.run (word.take endpoint)).2.top = some label := by
rw [Automaton.run_top, List.length_take,
Nat.min_eq_left hendpointWord, ← run_take_label_old A word hle hposition]
exact hlabel
refine ⟨(word.take endpoint).reverse, ?_⟩
exact Eval.seqOk (middle := (word.take endpoint).reverse)
(((hcontext.path path).ok_iff _).mpr ⟨endpoint, hfollow, hle, rfl⟩)
(((hcontext.label endpoint hle label).ok_iff).mpr hlabel')
omit [DecidableEq Sym] in
theorem path_label_body_err (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length)
(hcontext : NeighbourhoodContext A hdistance word position hposition)
(path : BoundedPath d k) (label : Gamma)
(hnot : ¬pathLabelledAt A word position path label) :
Eval (rawGrammar A hdistance)
(.seq (.nonterm (.path path)) (.nonterm (.label label)))
(word.take position).reverse .err := by
let S := (A.run (word.take position)).2
cases hfollow : S.follow S.top path.elems with
| none =>
apply Eval.seqErr
apply (hcontext.path path).err_iff.mpr
simpa [S] using hfollow
| some endpoint =>
have hfollow' : (A.run (word.take position)).2.follow
(A.run (word.take position)).2.top path.elems = some endpoint := by
simpa [S] using hfollow
have hle := path_endpoint_le A word position hposition path endpoint hfollow'
apply Eval.seqOk
· exact ((hcontext.path path).ok_iff _).mpr
⟨endpoint, hfollow', hle, rfl⟩
· apply (hcontext.label endpoint hle label).err_iff.mpr
intro hlabel
have hendpointWord : endpoint ≤ word.length := Nat.le_trans hle hposition
have hlabelEarly : (A.run (word.take endpoint)).2.label endpoint =
some label := by
simpa [Automaton.run_top, List.length_take,
Nat.min_eq_left hendpointWord] using hlabel
have hlabel' : (A.run (word.take position)).2.label endpoint =
some label := by
rw [run_take_label_old A word hle hposition]
exact hlabelEarly
exact hnot ⟨endpoint, hfollow', hlabel'⟩
omit [DecidableEq Sym] in
theorem path_label_pos_exact (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length)
(hcontext : NeighbourhoodContext A hdistance word position hposition)
(path : BoundedPath d k) (label : Gamma) :
ExactMatch (rawGrammar A hdistance)
(.pos (.seq (.nonterm (.path path)) (.nonterm (.label label))))
(word.take position).reverse (pathLabelledAt A word position path label) := by
apply exactMatch_of_cases
· intro hlabelled
rcases path_label_body_ok A hdistance word position hposition hcontext path
label hlabelled with ⟨rest, heval⟩
exact pos_ok_of_ok heval
· intro hnot
exact pos_err_of_err
(path_label_body_err A hdistance word position hposition hcontext path label hnot)
omit [DecidableEq Sym] in
theorem path_label_not_exact (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length)
(hcontext : NeighbourhoodContext A hdistance word position hposition)
(path : BoundedPath d k) (label : Gamma) :
ExactMatch (rawGrammar A hdistance)
(.notP (.seq (.nonterm (.path path)) (.nonterm (.label label))))
(word.take position).reverse
(¬pathLabelledAt A word position path label) := by
classical
apply exactMatch_of_cases
· intro hnot
exact Eval.notErr
(path_label_body_err A hdistance word position hposition hcontext path label hnot)
· intro hnnot
by_cases hlabelled : pathLabelledAt A word position path label
· rcases path_label_body_ok A hdistance word position hposition hcontext path
label hlabelled with ⟨rest, heval⟩
exact Eval.notOk heval
· exact (hnnot hlabelled).elim
omit [DecidableEq Sym] in
theorem path_not_exact (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length)
(hcontext : NeighbourhoodContext A hdistance word position hposition)
(path : BoundedPath d k) :
ExactMatch (rawGrammar A hdistance) (.notP (.nonterm (.path path)))
(word.take position).reverse (¬pathPresentAt A word position path) := by
classical
apply exactMatch_of_cases
· intro hnot
apply Eval.notErr
apply (hcontext.path path).err_iff.mpr
let S := (A.run (word.take position)).2
cases hfollow : S.follow S.top path.elems with
| none => rfl
| some endpoint =>
exact (hnot ⟨endpoint, by simpa [S] using hfollow⟩).elim
· intro hnnot
by_cases hpresent : pathPresentAt A word position path
· rcases hpresent with ⟨endpoint, hfollow⟩
apply Eval.notOk
exact ((hcontext.path path).ok_iff _).mpr
⟨endpoint, hfollow,
path_endpoint_le A word position hposition path endpoint hfollow, rfl⟩
· exact (hnnot hpresent).elim
omit [DecidableEq Sym] in
theorem path_unlabelled_exact (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length)
(hcontext : NeighbourhoodContext A hdistance word position hposition)
(path : BoundedPath d k) :
ExactMatch (rawGrammar A hdistance)
(.seq (.pos (.nonterm (.path path)))
(Expr.seqAll ((FiniteEnum.elems (α := Gamma)).map fun label =>
.notP (.seq (.nonterm (.path path)) (.nonterm (.label label))))))
(word.take position).reverse
(pathPresentAt A word position path ∧
∀ label, ¬pathLabelledAt A word position path label) := by
have hpresent := path_pos_exact A hdistance word position hposition hcontext path
have hlabels := seqAll_map_exact (FiniteEnum.elems (α := Gamma))
(fun label => Expr.notP
(.seq (.nonterm (NT.path path)) (.nonterm (.label label))))
(word.take position).reverse
(fun label => ¬pathLabelledAt A word position path label)
(fun label _ => path_label_not_exact A hdistance word position hposition
hcontext path label)
have hseq := exactMatch_seq hpresent hlabels
refine ⟨hseq.ok_iff.trans ?_, hseq.err_iff.trans (not_congr ?_)⟩
· constructor
· rintro ⟨hpath, hall⟩
exact ⟨hpath, fun label => hall label (FiniteEnum.complete label)⟩
· rintro ⟨hpath, hall⟩
exact ⟨hpath, fun label _ => hall label⟩
· constructor
· rintro ⟨hpath, hall⟩
exact ⟨hpath, fun label => hall label (FiniteEnum.complete label)⟩
· rintro ⟨hpath, hall⟩
exact ⟨hpath, fun label _ => hall label⟩
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem path_unlabelled_iff_observe (A : Automaton Sym Q Gamma d k)
(word : List Sym) (position : Nat) (path : BoundedPath d k) :
(pathPresentAt A word position path ∧
∀ label, ¬pathLabelledAt A word position path label) ↔
observe ((A.run (word.take position)).2.viewAt k
(A.run (word.take position)).2.top) path = some none := by
let S := (A.run (word.take position)).2
rw [observe_viewAt]
cases hfollow : S.follow S.top path.elems with
| none => simp [pathPresentAt, pathLabelledAt, S, hfollow]
| some endpoint =>
cases hlabel : S.label endpoint with
| none => simp [pathPresentAt, pathLabelledAt, S, hfollow, hlabel]
| some label =>
constructor
· rintro ⟨_, hall⟩
exact (hall label ⟨endpoint, by simpa [S] using hfollow,
by simpa [S] using hlabel⟩).elim
· intro himpossible
simp only [Option.some.injEq] at himpossible
have hlabel' : (A.run (word.take position)).2.label endpoint =
some label := by simpa [S] using hlabel
rw [hlabel'] at himpossible
contradiction
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem path_labelled_iff_observe (A : Automaton Sym Q Gamma d k)
(word : List Sym) (position : Nat) (path : BoundedPath d k)
(label : Gamma) :
pathLabelledAt A word position path label ↔
observe ((A.run (word.take position)).2.viewAt k
(A.run (word.take position)).2.top) path = some (some label) := by
let S := (A.run (word.take position)).2
rw [observe_viewAt]
cases hfollow : S.follow S.top path.elems with
| none => simp [pathLabelledAt, S, hfollow]
| some endpoint =>
simp [pathLabelledAt, S, hfollow]
omit [FiniteEnum Sym] [DecidableEq Sym] [FiniteEnum Q] [DecidableEq Q]
[FiniteEnum Gamma] [DecidableEq Gamma] in
theorem path_absent_iff_observe (A : Automaton Sym Q Gamma d k)
(word : List Sym) (position : Nat) (path : BoundedPath d k) :
(¬pathPresentAt A word position path) ↔
observe ((A.run (word.take position)).2.viewAt k
(A.run (word.take position)).2.top) path = none := by
let S := (A.run (word.take position)).2
rw [observe_viewAt]
cases hfollow : S.follow S.top path.elems with
| none => simp [pathPresentAt, S, hfollow]
| some endpoint => simp [pathPresentAt, S, hfollow]
omit [DecidableEq Sym] in
theorem observationFact_exact (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length)
(hcontext : NeighbourhoodContext A hdistance word position hposition)
(neighbourhood : Unfold d Gamma k) (path : BoundedPath d k) :
ExactMatch (rawGrammar A hdistance)
(observationFact (Q := Q) (Sym := Sym) neighbourhood path)
(word.take position).reverse
(observe neighbourhood path =
observe ((A.run (word.take position)).2.viewAt k
(A.run (word.take position)).2.top) path) := by
unfold observationFact
cases hobs : observe neighbourhood path with
| none =>
have hexact := path_not_exact A hdistance word position hposition hcontext path
refine ⟨hexact.ok_iff.trans ?_, hexact.err_iff.trans (not_congr ?_)⟩
· simpa [hobs, eq_comm] using
(path_absent_iff_observe A word position path)
· simpa [hobs, eq_comm] using
(path_absent_iff_observe A word position path)
| some observation =>
cases observation with
| none =>
have hexact := path_unlabelled_exact A hdistance word position hposition
hcontext path
refine ⟨hexact.ok_iff.trans ?_, hexact.err_iff.trans (not_congr ?_)⟩
· simpa [hobs, eq_comm] using
(path_unlabelled_iff_observe A word position path)
· simpa [hobs, eq_comm] using
(path_unlabelled_iff_observe A word position path)
| some label =>
have hexact := path_label_pos_exact A hdistance word position hposition
hcontext path label
refine ⟨hexact.ok_iff.trans ?_, hexact.err_iff.trans (not_congr ?_)⟩
· simpa [hobs, eq_comm] using
(path_labelled_iff_observe A word position path label)
· simpa [hobs, eq_comm] using
(path_labelled_iff_observe A word position path label)
omit [DecidableEq Sym] in
/-- Conditional I4: exact paths at the current prefix plus exact labels at all
reachable endpoints make the finite observation conjunction extensional. -/
theorem neighbourhood_exact (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length)
(hcontext : NeighbourhoodContext A hdistance word position hposition)
(neighbourhood : Unfold d Gamma k) :
NeighbourhoodExact A hdistance (word.take position) neighbourhood := by
let actual := (A.run (word.take position)).2.viewAt k
(A.run (word.take position)).2.top
have hsequence := seqAll_map_exact
(FiniteEnum.elems (α := BoundedPath d k))
(observationFact (Q := Q) (Sym := Sym) neighbourhood)
(word.take position).reverse
(fun path => observe neighbourhood path = observe actual path)
(fun path _ => observationFact_exact A hdistance word position hposition
hcontext neighbourhood path)
have hcondition :
(∀ path, path ∈ FiniteEnum.elems (α := BoundedPath d k) →
observe neighbourhood path = observe actual path) ↔
actual = neighbourhood := by
constructor
· intro hall
symm
apply (unfold_eq_iff_observe_all neighbourhood actual).2
intro path
exact hall path (FiniteEnum.complete path)
· intro heq path _
rw [heq]
have hnontermOk := eval_nonterm_iff (rawGrammar A hdistance)
(NT.neighbourhood neighbourhood) (word.take position).reverse
(.ok (word.take position).reverse)
have hnontermErr := eval_nonterm_iff (rawGrammar A hdistance)
(NT.neighbourhood neighbourhood) (word.take position).reverse .err
refine ⟨?_, ?_⟩
· simpa [rawGrammar, neighbourhoodRule, actual] using
hnontermOk.trans (hsequence.ok_iff.trans hcondition)
· simpa [rawGrammar, neighbourhoodRule, actual] using
hnontermErr.trans (hsequence.err_iff.trans (not_congr hcondition))
/-- The four exact invariants at one prefix of one ambient word. -/
structure PrefixExactAt (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length) : Prop where
state : ∀ control, StateExact A hdistance (word.take position) control
label : ∀ target, LabelExact A hdistance (word.take position) target
neighbourhood : ∀ shape,
NeighbourhoodExact A hdistance (word.take position) shape
path : ∀ bounded, PathExact A hdistance word position hposition bounded
/-- Simultaneous strong-prefix closure in dependency order: state and label at
the current position, path using strictly earlier guards, then neighbourhood
using current paths and labels at every endpoint. -/
theorem prefix_exact_at (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) (position : Nat)
(hposition : position ≤ word.length) :
PrefixExactAt A hdistance word position hposition := by
cases position with
| zero =>
have hstate : ∀ control, StateExact A hdistance (word.take 0) control := by
intro control
simpa using state_nil_exact A hdistance control
have hlabel : ∀ target, LabelExact A hdistance (word.take 0) target := by
intro target
simpa using label_nil_exact A hdistance target
have hearlier : EarlierGuardContext A hdistance word 0 := by
refine ⟨?_⟩
intro earlier hearlier
omega
have hpath : ∀ bounded,
PathExact A hdistance word 0 hposition bounded := by
intro bounded
exact path_exact A hdistance word 0 hposition hearlier bounded
have hneighbourhoodContext :
NeighbourhoodContext A hdistance word 0 hposition := by
refine ⟨hpath, ?_⟩
intro endpoint hendpoint target
·
have : endpoint = 0 := Nat.eq_zero_of_le_zero hendpoint
subst endpoint
exact hlabel target
have hneighbourhood : ∀ shape,
NeighbourhoodExact A hdistance (word.take 0) shape := by
intro shape
exact neighbourhood_exact A hdistance word 0 hposition
hneighbourhoodContext shape
exact ⟨hstate, hlabel, hneighbourhood, hpath⟩
| succ predecessor =>
have hpredecessor : predecessor < word.length := by omega
have hpast := prefix_exact_at A hdistance word predecessor
(Nat.le_of_lt hpredecessor)
have hguard : PrefixGuardContext A hdistance
(word.take predecessor) := ⟨hpast.state, hpast.neighbourhood⟩
have hprefix : word.take (predecessor + 1) =
word.take predecessor ++ [word[predecessor]] :=
List.take_succ_eq_append_getElem hpredecessor
have hstate : ∀ control,
StateExact A hdistance (word.take (predecessor + 1)) control := by
intro control
rw [hprefix]
exact state_step_exact A hdistance (word.take predecessor)
word[predecessor] hguard control
have hlabel : ∀ target,
LabelExact A hdistance (word.take (predecessor + 1)) target := by
intro target
rw [hprefix]
exact label_step_exact A hdistance (word.take predecessor)
word[predecessor] hguard target
have hearlier : EarlierGuardContext A hdistance word
(predecessor + 1) := by
refine ⟨?_⟩
intro earlier hearlier
·
have hearlierWord : earlier ≤ word.length :=
Nat.le_trans (Nat.le_of_lt hearlier) hposition
have hexact := prefix_exact_at A hdistance word earlier hearlierWord
exact ⟨hexact.state, hexact.neighbourhood⟩
have hpath : ∀ bounded,
PathExact A hdistance word (predecessor + 1) hposition bounded := by
intro bounded
exact path_exact A hdistance word (predecessor + 1) hposition
hearlier bounded
have hneighbourhoodContext : NeighbourhoodContext A hdistance word
(predecessor + 1) hposition := by
refine ⟨hpath, ?_⟩
intro endpoint hendpoint target
·
by_cases hcurrent : endpoint = predecessor + 1
· subst endpoint
exact hlabel target
· have hearlier : endpoint < predecessor + 1 :=
Nat.lt_of_le_of_ne hendpoint hcurrent
have hendpointWord : endpoint ≤ word.length :=
Nat.le_trans hendpoint hposition
exact (prefix_exact_at A hdistance word endpoint hendpointWord).label target
have hneighbourhood : ∀ shape,
NeighbourhoodExact A hdistance (word.take (predecessor + 1)) shape := by
intro shape
exact neighbourhood_exact A hdistance word (predecessor + 1) hposition
hneighbourhoodContext shape
exact ⟨hstate, hlabel, hneighbourhood, hpath⟩
termination_by position
/-- Unconditional all-prefix I1--I4 package at a complete word. -/
theorem prefix_exact (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (word : List Sym) :
PrefixExactAt A hdistance word word.length (Nat.le_refl _) :=
prefix_exact_at A hdistance word word.length (Nat.le_refl _)
omit [DecidableEq Sym] in
/-- Named Task-5c fixture: the impossible top-level missing neighbourhood still
rejects because the exhaustive conjunction starts with `!Path([])`. -/
theorem top_missing_neighbourhood_err (A : Automaton Sym Q Gamma d k)
(hdistance : A.DistanceOk) (input : List Sym) :
Eval (rawGrammar A hdistance)
(.nonterm (.neighbourhood (.missing : Unfold d Gamma k))) input .err :=
neighbourhood_missing_err A hdistance input
end Theorem16
end FPRD