Research source · Plain text
FixtureAudit.lean
site/public/formal/persistent-stacks/lean/FPRDTransfer/Theorem16/FixtureAudit.lean
195 lines. Source is displayed for inspection; it is not executed by this page.
File fingerprint
SHA-256: b4a45adca183d683d58828478db430ddef2011ee1d51cd33f08b62031866ee4b
import FPRDTransfer.PEG.TableEval
import FPRDTransfer.Theorem16.Grammar
/-!
# Executable anti-vacuity fixtures for LMR Theorem 16
These fixtures are deliberately hand-built at degree one and depth two. They
exercise the generated grammar through the rank-ordered table evaluator without
using either compiler or an automaton decision procedure inside `evalTable`.
-/
namespace FPRD.Theorem16.FixtureAudit
abbrev FixtureAutomaton := Automaton Bool Bool Unit 1 2
/-- A nontrivial control-only language: words with odd Boolean parity. -/
def controlMachine : FixtureAutomaton where
delta control symbol _ := (Bool.xor control symbol, (), fun _ => .missing)
init := false
accept control := control
theorem controlDistance : controlMachine.DistanceOk := by
intro control symbol neighbourhood port path hpath
simp [controlMachine] at hpath
/-- The same parity language, with every appended edge using `SELF`. -/
def selfMachine : FixtureAutomaton where
delta control symbol _ := (Bool.xor control symbol, (), fun _ => .self)
init := false
accept control := control
theorem selfDistance : selfMachine.DistanceOk := by
intro control symbol neighbourhood port path hpath
simp [selfMachine] at hpath
/-- Detect whether the sole child is a present node rather than `missing`. -/
def childPresent (neighbourhood : Unfold 1 Unit 2) : Bool :=
match neighbourhood.child 0 with
| .missing => false
| .node _ _ => true
/-- The next control observes whether the preceding node points to the
present-but-unlabelled base. The current symbol chooses whether the new edge
will expose that distinction to the following transition. -/
def neighbourhoodMachine : FixtureAutomaton where
delta _ symbol neighbourhood :=
(childPresent neighbourhood, (), fun _ =>
if symbol = true then .path [] else .missing)
init := false
accept control := control
theorem neighbourhoodDistance : neighbourhoodMachine.DistanceOk := by
intro control symbol neighbourhood port path hpath
simp [neighbourhoodMachine] at hpath
split at hpath <;> simp_all
abbrev FixtureNT := Fin (FiniteEnum.card (NT Bool Unit 1 2))
def grammarResult (machine : FixtureAutomaton)
(hdistance : machine.DistanceOk) (word : List Bool) : Result Bool :=
evalTable (canonicalGrammar machine hdistance)
(canonicalGrammar_rankSchedule machine hdistance) word.reverse
/-- All Boolean words of one exact length. -/
def boolWordsExact : Nat → List (List Bool)
| 0 => [[]]
| length + 1 =>
(boolWordsExact length).flatMap fun word =>
[false :: word, true :: word]
/-- All Boolean words through the inclusive length bound. -/
def boolWordsUpTo (bound : Nat) : List (List Bool) :=
(List.range (bound + 1)).flatMap boolWordsExact
structure FixtureCounts where
accepted : Nat := 0
rejected : Nat := 0
partialSuccesses : Nat := 0
mismatches : Nat := 0
deriving Repr, DecidableEq
def tally (expected : Bool) (result : Result Bool)
(counts : FixtureCounts) : FixtureCounts :=
match result with
| .ok [] =>
if expected = true then
{ counts with accepted := counts.accepted + 1 }
else
{ counts with mismatches := counts.mismatches + 1 }
| .ok (_ :: _) =>
{ counts with partialSuccesses := counts.partialSuccesses + 1 }
| .err =>
if expected = false then
{ counts with rejected := counts.rejected + 1 }
else
{ counts with mismatches := counts.mismatches + 1 }
def auditFixture (machine : FixtureAutomaton)
(hdistance : machine.DistanceOk) (bound : Nat) : FixtureCounts :=
(boolWordsUpTo bound).foldl
(fun counts word => tally (machine.decides word)
(grammarResult machine hdistance word) counts)
{}
def controlGrammar : Grammar FixtureNT Bool :=
canonicalGrammar controlMachine controlDistance
def controlSchedule : RankSchedule controlGrammar :=
canonicalGrammar_rankSchedule controlMachine controlDistance
def directMissingName : FixtureNT :=
canonicalEquiv
(.neighbourhood (.missing : Unfold 1 Unit 2))
/-- Direct table-evaluator outcome for the impossible top-level missing
neighbourhood. This is `some err` only because `Path([])` is epsilon. -/
def directMissingResult : Option (Result Bool) :=
TableEval.lookup (TableEval.fillSuffixes controlGrammar controlSchedule [])
[] directMissingName
theorem directMissingResult_eq : directMissingResult = some .err := by decide
structure CorpusReport where
bound : Nat
wordsPerFixture : Nat
languageCases : Nat
alphabetCarrier : Nat
controlCarrier : Nat
labelCarrier : Nat
unfoldDepth0 : Nat
unfoldDepth1 : Nat
unfoldDepth2 : Nat
boundedPaths : Nat
nonterminals : Nat
maxSuffixes : Nat
maxTableCells : Nat
directMissingPassed : Bool
control : FixtureCounts
selfEdge : FixtureCounts
neighbourhood : FixtureCounts
deriving Repr, DecidableEq
def auditCorpus (bound : Nat) : CorpusReport :=
let words := boolWordsUpTo bound
let nonterminals := FiniteEnum.card (NT Bool Unit 1 2)
{
bound
wordsPerFixture := words.length
languageCases := 3 * words.length
alphabetCarrier := FiniteEnum.card Bool
controlCarrier := FiniteEnum.card Bool
labelCarrier := FiniteEnum.card Unit
unfoldDepth0 := FiniteEnum.card (Unfold 1 Unit 0)
unfoldDepth1 := FiniteEnum.card (Unfold 1 Unit 1)
unfoldDepth2 := FiniteEnum.card (Unfold 1 Unit 2)
boundedPaths := FiniteEnum.card (BoundedPath 1 2)
nonterminals
maxSuffixes := bound + 1
maxTableCells := (bound + 1) * nonterminals
directMissingPassed := directMissingResult == some .err
control := auditFixture controlMachine controlDistance bound
selfEdge := auditFixture selfMachine selfDistance bound
neighbourhood := auditFixture neighbourhoodMachine neighbourhoodDistance bound
}
def emitFixtureRow (name : String) (counts : FixtureCounts) : IO Unit :=
IO.println s!"LMR16_FIXTURE_V1 name={name} accepted={counts.accepted} rejected={counts.rejected} partial={counts.partialSuccesses} mismatches={counts.mismatches}"
/-- Emit carrier and maximum-table dimensions without evaluating a language
fixture. This lets the audit harness evaluate the three independent fixtures
concurrently and combine their named rows deterministically. -/
def emitCorpusHeader (bound : Nat) : IO Unit := do
let wordsPerFixture := (boolWordsUpTo bound).length
let nonterminals := FiniteEnum.card (NT Bool Unit 1 2)
IO.println s!"LMR16_CORPUS_V1 bound={bound} words_per_fixture={wordsPerFixture} language_cases={3 * wordsPerFixture} alphabet={FiniteEnum.card Bool} controls={FiniteEnum.card Bool} labels={FiniteEnum.card Unit} unfold0={FiniteEnum.card (Unfold 1 Unit 0)} unfold1={FiniteEnum.card (Unfold 1 Unit 1)} unfold2={FiniteEnum.card (Unfold 1 Unit 2)} paths={FiniteEnum.card (BoundedPath 1 2)} nonterminals={nonterminals} max_suffixes={bound + 1} max_table_cells={(bound + 1) * nonterminals} direct_missing={directMissingResult == some .err}"
def emitControlReport (bound : Nat) : IO Unit :=
emitFixtureRow "control" (auditFixture controlMachine controlDistance bound)
def emitSelfReport (bound : Nat) : IO Unit :=
emitFixtureRow "self" (auditFixture selfMachine selfDistance bound)
def emitNeighbourhoodReport (bound : Nat) : IO Unit :=
emitFixtureRow "neighbourhood"
(auditFixture neighbourhoodMachine neighbourhoodDistance bound)
/-- Emit a deterministic, versioned, line-oriented report for the Python
benchmark and mutation harness. -/
def emitCorpusReport (bound : Nat) : IO Unit := do
emitCorpusHeader bound
emitControlReport bound
emitSelfReport bound
emitNeighbourhoodReport bound
end FPRD.Theorem16.FixtureAudit