Switch steps to not redundantly include code

This commit is contained in:
2026-10-06 19:30:35 -05:00
parent 234d17394e
commit 655b7de684
2 changed files with 24 additions and 23 deletions

View File

@@ -40,20 +40,20 @@ instance stmtEvaluator : StmtEvaluator (DefSet prog) prog :=
def output : String :=
show' (result (DefSet prog) prog)
/-- The statements a trace executed, paired with the state each executed at,
most recent first (matching `LastAssign`, which scans for the most recent
assignment). This is `Path.steps` (chronological) reversed, so facts about
concatenating traces reduce to mathlib's `List.append`/`List.reverse` lemmas. -/
abbrev Run (prog : Program) : Type := List (prog.State × BasicStmt)
/-- Executed nodes, most recent first. Instructions are read from `prog.code`.
This is `Path.steps` (chronological) reversed, so facts about concatenating
traces reduce to mathlib's `List.append`/`List.reverse` lemmas. -/
abbrev Run (prog : Program) : Type := List prog.State
/-- The first node in a newest-first history whose instruction assigns `x`. -/
@[aesop unsafe cases]
inductive LastAssign (prog : Program) (x : String) : Run prog → prog.State → Prop
| here (s : prog.State) (e : Expr) (rest : Run prog) :
LastAssign prog x ((s, .assign x e) :: rest) s
| there (s : prog.State) (bs : BasicStmt) (hc : prog.code s = some bs)
(rest : Run prog) {n : prog.State} :
(∀ e, bs ≠ .assign x e) → LastAssign prog x rest n →
LastAssign prog x ((s, bs) :: rest) n
| here (s : prog.State) (e : Expr) (rest : Run prog)
(hc : prog.code s = some (.assign x e)) :
LastAssign prog x (s :: rest) s
| there (s : prog.State) (rest : Run prog) {n : prog.State} :
(∀ e, prog.code s ≠ some (.assign x e)) → LastAssign prog x rest n →
LastAssign prog x (s :: rest) n
def runOfPath {a b : Configuration prog.cfg} (p : Path prog.cfg a b) : Run prog :=
p.steps.reverse
@@ -97,16 +97,16 @@ private lemma valid_step (s : prog.State) {ρ₁ ρ₂ : Env}
cases hbs with
| noop =>
simp [eval, hcode, EvalBasicStmtOpt.steps]
intro x assigners hmem n hla; aesop
intro x assigners hmem n hla; aesop (add simp hcode)
| assign x e v hev =>
simp [eval, hcode, EvalBasicStmtOpt.steps]; intro k assigners hmem n hla
by_cases hx : k = x
· subst hx
have hd := FiniteMap.generalizedUpdate_mem_eq (List.mem_singleton.mpr rfl) hmem
rcases hla <;> simp [hd] <;> aesop
rcases hla <;> simp [hd] <;> aesop (add simp hcode)
· have hmem' := FiniteMap.generalizedUpdate_not_mem_backward
(fun hc => hx (List.mem_singleton.mp hc)) hmem
aesop
aesop (add simp hcode)
instance validStateEvaluator : ValidStateEvaluator (DefSet prog) prog where
valid := by

View File

@@ -186,27 +186,28 @@ instance {g : Graph} {idx₁ idx₂ : g.Index} {ρ₁ ρ₂ ρ₃ : Env} :
HAppend (Traceₗ g idx₁ idx₂ ρ₁ ρ₂) (EvalBasicStmtOpt ρ₂ (g.nodes idx₂) ρ₃)
(Trace g idx₁ idx₂ ρ₁ ρ₃) := ⟨Traceₗ.appendStep⟩
/-- The (index, statement) pairs executed by a single optional-statement step. -/
/-- The node executed by an optional-statement step; empty nodes are omitted. -/
def EvalBasicStmtOpt.steps {α : Type*} (idx : α) {ρ₁ ρ₂ : Env} {obs : Option BasicStmt} :
EvalBasicStmtOpt ρ₁ obs ρ₂ → List (α × BasicStmt)
EvalBasicStmtOpt ρ₁ obs ρ₂ → List α
| .none => []
| .some (bs := bs) _ => [(idx, bs)]
| .some _ => [idx]
def Step.steps {g : Graph} {a b : Configuration g} : Step g a b → List (g.Index × BasicStmt)
def Step.steps {g : Graph} {a b : Configuration g} : Step g a b → List g.Index
| .execute (i := i) h => h.steps i
| .edge _ => []
/-- Executed statements in chronological order; edges and empty nodes contribute nothing. -/
def Path.steps {g : Graph} {a b : Configuration g} : Path g a b → List (g.Index × BasicStmt)
/-- Executed nodes in chronological order; edges and empty nodes contribute nothing.
The instruction at each node is given by `g.nodes`, rather than copied into the history. -/
def Path.steps {g : Graph} {a b : Configuration g} : Path g a b → List g.Index
| .nil => []
| .cons s p => s.steps ++ p.steps
abbrev Trace.steps {g : Graph} {i j : g.Index} {ρ₁ ρ₂ : Env}
(p : Trace g i j ρ₁ ρ₂) : List (g.Index × BasicStmt) := Path.steps p
(p : Trace g i j ρ₁ ρ₂) : List g.Index := Path.steps p
abbrev Traceₗ.steps {g : Graph} {i j : g.Index} {ρ₁ ρ₂ : Env}
(p : Traceₗ g i j ρ₁ ρ₂) : List (g.Index × BasicStmt) := Path.steps p
(p : Traceₗ g i j ρ₁ ρ₂) : List g.Index := Path.steps p
abbrev Traceᵣ.steps {g : Graph} {i j : g.Index} {ρ₁ ρ₂ : Env}
(p : Traceᵣ g i j ρ₁ ρ₂) : List (g.Index × BasicStmt) := Path.steps p
(p : Traceᵣ g i j ρ₁ ρ₂) : List g.Index := Path.steps p
@[simp] lemma Path.steps_append {g : Graph} {a b c : Configuration g}
(p : Path g a b) (q : Path g b c) :