import Spa.Analysis.Forward import Spa.Lattice.Bool import Spa.Showable namespace Spa open Forward instance : Showable Bool := ⟨fun b => if b then "true" else "false"⟩ abbrev DefSet (prog : Program) : Type := FiniteMap prog.State Bool prog.states namespace ReachingAnalysis variable (prog : Program) def genSet (s : prog.State) : DefSet prog := FiniteMap.updating (⊥ : DefSet prog) [s] (fun _ => true) def eval (s : prog.State) : BasicStmt → VariableValues (DefSet prog) prog → VariableValues (DefSet prog) prog | .assign k _, vs => FiniteMap.generalizedUpdate id (fun _ _ => genSet prog s) [k] vs | .noop, vs => vs theorem eval_mono (s : prog.State) (bs : BasicStmt) : Monotone (eval prog s bs) := by cases bs with | assign k e => exact FiniteMap.generalizedUpdate_monotone monotone_id (fun _ => monotone_const) | noop => exact monotone_id instance stmtEvaluator : StmtEvaluator (DefSet prog) prog := ⟨eval prog, eval_mono prog⟩ def output : String := show' (result (DefSet prog) prog) end ReachingAnalysis end Spa