78 lines
3.3 KiB
Lean4
78 lines
3.3 KiB
Lean4
|
|
/-
|
||
|
|
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
|