2026-06-09 19:30:42 -07:00
|
|
|
|
import Spa.Language.Base
|
|
|
|
|
|
import Spa.Language.Semantics
|
|
|
|
|
|
import Spa.Language.Graphs
|
|
|
|
|
|
import Spa.Language.Traces
|
|
|
|
|
|
import Spa.Language.Properties
|
|
|
|
|
|
import Mathlib.Data.Finset.Sort
|
|
|
|
|
|
import Mathlib.Data.String.Basic
|
|
|
|
|
|
|
|
|
|
|
|
namespace Spa
|
|
|
|
|
|
|
|
|
|
|
|
structure Program where
|
|
|
|
|
|
rootStmt : Stmt
|
|
|
|
|
|
|
|
|
|
|
|
namespace Program
|
|
|
|
|
|
|
|
|
|
|
|
variable (p : Program)
|
|
|
|
|
|
|
2026-06-25 09:45:30 -05:00
|
|
|
|
def cfg : Graph := Graph.wrap p.rootStmt.cfg
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
2026-06-25 09:45:30 -05:00
|
|
|
|
abbrev State : Type := p.cfg.Index
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
2026-06-25 09:45:30 -05:00
|
|
|
|
def initialState : p.State := p.rootStmt.cfg.wrapInput
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
2026-06-25 09:45:30 -05:00
|
|
|
|
def finalState : p.State := p.rootStmt.cfg.wrapOutput
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
|
|
|
|
|
theorem trace {ρ : Env} (h : EvalStmt [] p.rootStmt ρ) :
|
2026-06-25 09:45:30 -05:00
|
|
|
|
Trace p.cfg p.initialState p.finalState [] ρ := by
|
|
|
|
|
|
obtain ⟨i₁, h₁, i₂, h₂, tr⟩ := EndToEndTrace.wrap (Stmt.cfg_sufficient h)
|
2026-06-09 19:30:42 -07:00
|
|
|
|
rw [Graph.wrap_inputs, List.mem_singleton] at h₁
|
|
|
|
|
|
rw [Graph.wrap_outputs, List.mem_singleton] at h₂
|
|
|
|
|
|
subst h₁; subst h₂
|
|
|
|
|
|
exact tr
|
|
|
|
|
|
|
|
|
|
|
|
def vars : List String := p.rootStmt.vars.sort (· ≤ ·)
|
|
|
|
|
|
|
|
|
|
|
|
theorem vars_nodup : p.vars.Nodup := Finset.sort_nodup _ _
|
|
|
|
|
|
|
2026-06-25 09:45:30 -05:00
|
|
|
|
def states : List p.State := p.cfg.indices
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
2026-06-25 09:45:30 -05:00
|
|
|
|
theorem states_complete (s : p.State) : s ∈ p.states := p.cfg.mem_indices s
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
2026-06-25 09:45:30 -05:00
|
|
|
|
theorem states_nodup : p.states.Nodup := p.cfg.nodup_indices
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
2026-06-25 09:45:30 -05:00
|
|
|
|
def code (st : p.State) : List BasicStmt := p.cfg.nodes st
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
2026-06-25 09:45:30 -05:00
|
|
|
|
def incoming (s : p.State) : List p.State := p.cfg.predecessors s
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
|
|
|
|
|
theorem incoming_initialState_eq_nil : p.incoming p.initialState = [] :=
|
2026-06-25 09:45:30 -05:00
|
|
|
|
Graph.wrap_predecessors_eq_nil p.rootStmt.cfg p.initialState
|
2026-06-09 19:30:42 -07:00
|
|
|
|
(by rw [Graph.wrap_inputs]; exact List.mem_singleton_self _)
|
|
|
|
|
|
|
|
|
|
|
|
theorem mem_incoming_of_edge {s₁ s₂ : p.State}
|
2026-06-25 09:45:30 -05:00
|
|
|
|
(h : (s₁, s₂) ∈ p.cfg.edges) : s₁ ∈ p.incoming s₂ :=
|
|
|
|
|
|
p.cfg.mem_predecessors_of_edge h
|
2026-06-09 19:30:42 -07:00
|
|
|
|
|
|
|
|
|
|
end Program
|
|
|
|
|
|
|
|
|
|
|
|
end Spa
|