/- Port of `Analysis/Forward/Adapters.agda` (`ExprToStmtAdapter`). Correspondence: updateVariablesFromExpression ↦ updateVariablesFromExpression updateVariablesFromExpression-Mono ↦ updateVariablesFromExpression_mono (the -k∈ks-≡ / -k∉ks-backward renames ↦ used directly from FiniteMap) evalᵇ, evalᵇ-Monoʳ ↦ evalB, evalB_mono stmtEvaluator (instance) ↦ ExprEvaluator.toStmtEvaluator evalᵇ-valid, validStmtEvaluator ↦ ExprEvaluator.toStmtEvaluator_valid (the Agda `k ≟ˢ k'` case split is subsumed by `cases` on `Env.Mem`, whose `here` case forces `k' = k`) -/ import Spa.Analysis.Forward.Evaluation namespace Spa variable {L : Type} [Lattice L] {prog : Program} /-- Agda: `updateVariablesFromExpression` — set the single key `k` to the value of `e` (the `GeneralizedUpdate` with `ks = [k]`). -/ def updateVariablesFromExpression (E : ExprEvaluator L prog) (k : String) (e : Expr) (vs : VariableValues L prog) : VariableValues L prog := FiniteMap.generalizedUpdate id (fun _ vs => E.eval e vs) [k] vs /-- Agda: `updateVariablesFromExpression-Mono`. -/ theorem updateVariablesFromExpression_mono (E : ExprEvaluator L prog) (k : String) (e : Expr) : Monotone (updateVariablesFromExpression E k e) := FiniteMap.generalizedUpdate_monotone monotone_id (fun _ => E.eval_mono e) /-- Agda: `evalᵇ`. -/ def evalB (E : ExprEvaluator L prog) (_ : prog.State) (bs : BasicStmt) (vs : VariableValues L prog) : VariableValues L prog := match bs with | .assign k e => updateVariablesFromExpression E k e vs | .noop => vs /-- Agda: `evalᵇ-Monoʳ`. -/ theorem evalB_mono (E : ExprEvaluator L prog) (s : prog.State) (bs : BasicStmt) : Monotone (evalB E s bs) := by cases bs with | assign k e => exact updateVariablesFromExpression_mono E k e | noop => exact monotone_id /-- Agda: the `stmtEvaluator` instance of `ExprToStmtAdapter`. -/ def ExprEvaluator.toStmtEvaluator (E : ExprEvaluator L prog) : StmtEvaluator L prog := ⟨evalB E, evalB_mono E⟩ /-- Agda: `evalᵇ-valid` / the `validStmtEvaluator` instance. -/ theorem ExprEvaluator.toStmtEvaluator_valid (E : ExprEvaluator L prog) {I : LatticeInterpretation L} (hE : IsValidExprEvaluator E I) : IsValidStmtEvaluator E.toStmtEvaluator I := by intro s vs ρ₁ ρ₂ bs hbs hvs cases hbs with | noop => exact hvs | assign k e v hev => intro k' l hk'l v' hv' cases hv' with | here => have hk'l₀ : (k, l) ∈ FiniteMap.generalizedUpdate (ks := prog.vars) id (fun _ vs => E.eval e vs) [k] vs := hk'l have hl := FiniteMap.generalizedUpdate_mem_eq (f := id) (g := fun _ vs => E.eval e vs) (List.mem_singleton_self k) hk'l₀ rw [hl] exact hE hev hvs | there _ _ _ _ _ hne hmem' => have hk'l₀ : (k', l) ∈ FiniteMap.generalizedUpdate (ks := prog.vars) id (fun _ vs => E.eval e vs) [k] vs := hk'l have hk'l' : (k', l) ∈ (id vs : VariableValues L prog) := FiniteMap.generalizedUpdate_not_mem_backward (fun hmem => hne (List.mem_singleton.mp hmem)) hk'l₀ exact hvs _ _ hk'l' _ hmem' end Spa