2026-06-09 20:14:53 -07:00
|
|
|
|
import Spa.Analysis.Forward.Lattices
|
|
|
|
|
|
import Spa.Analysis.Forward.Evaluation
|
|
|
|
|
|
import Spa.Analysis.Forward.Adapters
|
|
|
|
|
|
import Spa.Fixedpoint
|
|
|
|
|
|
|
|
|
|
|
|
namespace Spa
|
|
|
|
|
|
|
2026-06-24 13:54:37 -05:00
|
|
|
|
namespace Forward
|
|
|
|
|
|
|
2026-06-25 18:42:28 -05:00
|
|
|
|
variable {L : Type} [FiniteHeightLattice L] {prog : Program} [E : StmtEvaluator L prog]
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-27 16:29:16 -05:00
|
|
|
|
def evalStmtOrNone (s : prog.State) (o : Option BasicStmt) (hco : prog.code s = o)
|
|
|
|
|
|
(vs : VariableValues L prog) : VariableValues L prog :=
|
|
|
|
|
|
o.elimEq vs (fun bs h => E.eval s bs (hco.trans h))
|
|
|
|
|
|
|
|
|
|
|
|
lemma evalStmtOrNone_mono (s : prog.State) (o : Option BasicStmt)
|
|
|
|
|
|
(hco : prog.code s = o) : Monotone (evalStmtOrNone (L := L) s o hco) :=
|
|
|
|
|
|
elimEq_self_mono o (fun bs h vs => E.eval s bs (hco.trans h) vs)
|
|
|
|
|
|
(fun bs h => E.eval_mono s bs (hco.trans h))
|
|
|
|
|
|
|
2026-06-09 20:14:53 -07:00
|
|
|
|
def updateVariablesForState (s : prog.State) (sv : StateVariables L prog) :
|
|
|
|
|
|
VariableValues L prog :=
|
2026-06-27 16:29:16 -05:00
|
|
|
|
evalStmtOrNone s (prog.code s) rfl (variablesAt s sv)
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-25 13:59:08 -05:00
|
|
|
|
lemma updateVariablesForState_mono (s : prog.State) :
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
Monotone (updateVariablesForState (L := L) s) := fun _ _ hle =>
|
2026-06-27 16:29:16 -05:00
|
|
|
|
evalStmtOrNone_mono s (prog.code s) rfl (variablesAt_le hle s)
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
|
|
|
|
|
def updateAll (sv : StateVariables L prog) : StateVariables L prog :=
|
2026-06-23 11:44:50 -05:00
|
|
|
|
FiniteMap.generalizedUpdate id updateVariablesForState
|
2026-06-09 20:14:53 -07:00
|
|
|
|
prog.states sv
|
|
|
|
|
|
|
2026-06-25 13:59:08 -05:00
|
|
|
|
lemma updateAll_mono : Monotone (updateAll (L := L) (prog := prog)) :=
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
FiniteMap.generalizedUpdate_monotone monotone_id updateVariablesForState_mono
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-25 13:59:08 -05:00
|
|
|
|
lemma updateAll_mem_eq {s : prog.State} {vs : VariableValues L prog}
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
{sv : StateVariables L prog} (hmem : (s, vs) ∈ updateAll sv) :
|
|
|
|
|
|
vs = updateVariablesForState s sv :=
|
2026-06-09 20:14:53 -07:00
|
|
|
|
FiniteMap.generalizedUpdate_mem_eq (prog.states_complete s) hmem
|
|
|
|
|
|
|
2026-06-25 13:59:08 -05:00
|
|
|
|
lemma variablesAt_updateAll (s : prog.State) (sv : StateVariables L prog) :
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
variablesAt s (updateAll sv) = updateVariablesForState s sv :=
|
|
|
|
|
|
updateAll_mem_eq (variablesAt_mem s (updateAll sv))
|
|
|
|
|
|
|
2026-06-09 20:14:53 -07:00
|
|
|
|
def analyze (sv : StateVariables L prog) : StateVariables L prog :=
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
updateAll (joinAll sv)
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-25 13:59:08 -05:00
|
|
|
|
lemma analyze_mono : Monotone (analyze (L := L) (prog := prog)) := fun _ _ hle =>
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
updateAll_mono (joinAll_mono hle)
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
variable [DecidableEq L]
|
|
|
|
|
|
|
|
|
|
|
|
variable (L prog) in
|
2026-06-09 20:14:53 -07:00
|
|
|
|
def result : StateVariables L prog :=
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
Fixedpoint.aFix analyze analyze_mono
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
variable (L prog) in
|
2026-06-25 13:59:08 -05:00
|
|
|
|
lemma result_eq : result L prog = analyze (result L prog) :=
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
Fixedpoint.aFix_eq analyze analyze_mono
|
|
|
|
|
|
|
2026-06-25 13:59:08 -05:00
|
|
|
|
lemma joinForKey_initialState :
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
joinForKey prog.initialState (result L prog) = botV L prog := by
|
|
|
|
|
|
rw [joinForKey, prog.incoming_initialState_eq_nil]
|
|
|
|
|
|
rfl
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-27 16:29:16 -05:00
|
|
|
|
class ValidStateEvaluator (L : Type) [FiniteHeightLattice L] (prog : Program)
|
|
|
|
|
|
[E : StmtEvaluator L prog] [S : StateInterp L prog] where
|
|
|
|
|
|
step : (s : prog.State) → {ρ₁ ρ₂ : Env} → {bs : BasicStmt} →
|
|
|
|
|
|
prog.code s = some bs → EvalBasicStmt ρ₁ bs ρ₂ → S.St ρ₁ → S.St ρ₂
|
|
|
|
|
|
valid : ∀ (s : prog.State) {ρ₁ ρ₂ : Env} {bs : BasicStmt}
|
|
|
|
|
|
{vs : VariableValues L prog} {st : S.St ρ₁},
|
|
|
|
|
|
(hcode : prog.code s = some bs) → (hbs : EvalBasicStmt ρ₁ bs ρ₂) → ⟦ vs ⟧ ρ₁ st →
|
|
|
|
|
|
⟦ E.eval s bs hcode vs ⟧ ρ₂ (step s hcode hbs st)
|
|
|
|
|
|
botV_init : ⟦ botV L prog ⟧ [] S.init
|
|
|
|
|
|
|
|
|
|
|
|
instance [LatticeInterpretation L] [ValidStmtEvaluator L prog] :
|
|
|
|
|
|
ValidStateEvaluator L prog where
|
|
|
|
|
|
step := by intro _ _ _ _ _ _ _; exact PUnit.unit
|
|
|
|
|
|
valid := by intro _ _ _ _ _ _ hcode hbs hvs; exact ValidStmtEvaluator.valid hcode hbs hvs
|
|
|
|
|
|
botV_init := by intro k l _ v hmem; cases hmem
|
|
|
|
|
|
|
|
|
|
|
|
section
|
|
|
|
|
|
variable [S : StateInterp L prog] [V : ValidStateEvaluator L prog]
|
|
|
|
|
|
|
|
|
|
|
|
noncomputable def stepStmtOrNone (s : prog.State) {ρ₁ ρ₂ : Env} :
|
|
|
|
|
|
(o : Option BasicStmt) → prog.code s = o → EvalBasicStmtOpt ρ₁ o ρ₂ →
|
|
|
|
|
|
S.St ρ₁ → S.St ρ₂
|
|
|
|
|
|
| none, _, .none, st => st
|
|
|
|
|
|
| some _, hco, .some hbs, st => V.step s hco hbs st
|
|
|
|
|
|
|
|
|
|
|
|
noncomputable def stepNode (s : prog.State) {ρ₁ ρ₂ : Env}
|
|
|
|
|
|
(h : EvalBasicStmtOpt ρ₁ (prog.code s) ρ₂) (st : S.St ρ₁) : S.St ρ₂ :=
|
|
|
|
|
|
stepStmtOrNone s (prog.code s) rfl h st
|
|
|
|
|
|
|
|
|
|
|
|
noncomputable def stepTraceState :
|
|
|
|
|
|
{s₁ s₂ : prog.State} → {ρ₁ ρ₂ : Env} →
|
|
|
|
|
|
Trace prog.cfg s₁ s₂ ρ₁ ρ₂ → S.St ρ₁ → S.St ρ₂
|
|
|
|
|
|
| s₁, _, _, _, .single hnode, st => stepNode s₁ hnode st
|
|
|
|
|
|
| s₁, _, _, _, .edge hnode _ subtr, st =>
|
|
|
|
|
|
stepTraceState subtr (stepNode s₁ hnode st)
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-25 18:42:28 -05:00
|
|
|
|
omit [DecidableEq L] in
|
2026-06-27 16:29:16 -05:00
|
|
|
|
lemma evalStmtOrNone_valid {s : prog.State} {ρ₁ ρ₂ : Env} {st : S.St ρ₁}
|
|
|
|
|
|
{vs : VariableValues L prog} (o : Option BasicStmt) (hco : prog.code s = o)
|
|
|
|
|
|
(he : EvalBasicStmtOpt ρ₁ o ρ₂) (hvs : ⟦ vs ⟧ ρ₁ st) :
|
|
|
|
|
|
⟦ evalStmtOrNone s o hco vs ⟧ ρ₂ (stepStmtOrNone s o hco he st) := by
|
|
|
|
|
|
cases he with
|
|
|
|
|
|
| none => exact hvs
|
|
|
|
|
|
| some hbs => exact V.valid s hco hbs hvs
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-25 18:42:28 -05:00
|
|
|
|
omit [DecidableEq L] in
|
2026-06-25 13:59:08 -05:00
|
|
|
|
lemma updateAll_matches {s : prog.State} {sv : StateVariables L prog}
|
2026-06-27 16:29:16 -05:00
|
|
|
|
{ρ₁ ρ₂ : Env} {st : S.St ρ₁}
|
|
|
|
|
|
(hnode : EvalBasicStmtOpt ρ₁ (prog.code s) ρ₂)
|
|
|
|
|
|
(hvs : ⟦ variablesAt s sv ⟧ ρ₁ st) :
|
|
|
|
|
|
⟦ variablesAt s (updateAll sv) ⟧ ρ₂ (stepNode s hnode st) := by
|
2026-06-09 20:14:53 -07:00
|
|
|
|
rw [variablesAt_updateAll]
|
2026-06-27 16:29:16 -05:00
|
|
|
|
exact evalStmtOrNone_valid (prog.code s) rfl hnode hvs
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-27 16:29:16 -05:00
|
|
|
|
lemma stepTrace {s₁ : prog.State} {ρ₁ ρ₂ : Env} {st : S.St ρ₁}
|
|
|
|
|
|
(hjoin : ⟦ joinForKey s₁ (result L prog) ⟧ ρ₁ st)
|
|
|
|
|
|
(hnode : EvalBasicStmtOpt ρ₁ (prog.code s₁) ρ₂) :
|
|
|
|
|
|
⟦ variablesAt s₁ (result L prog) ⟧ ρ₂ (stepNode s₁ hnode st) := by
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
rw [result_eq L prog]
|
2026-06-27 16:29:16 -05:00
|
|
|
|
refine updateAll_matches hnode ?_
|
2026-06-09 20:14:53 -07:00
|
|
|
|
rw [variablesAt_joinAll]
|
|
|
|
|
|
exact hjoin
|
|
|
|
|
|
|
2026-06-27 16:29:16 -05:00
|
|
|
|
lemma walkTrace {s₁ s₂ : prog.State} {ρ₁ ρ₂ : Env} {st₁ : S.St ρ₁}
|
|
|
|
|
|
(hjoin : ⟦ joinForKey s₁ (result L prog) ⟧ ρ₁ st₁)
|
2026-06-25 09:45:30 -05:00
|
|
|
|
(tr : Trace prog.cfg s₁ s₂ ρ₁ ρ₂) :
|
2026-06-27 16:29:16 -05:00
|
|
|
|
⟦ variablesAt s₂ (result L prog) ⟧ ρ₂ (stepTraceState tr st₁) := by
|
2026-06-09 20:14:53 -07:00
|
|
|
|
induction tr with
|
2026-06-27 16:29:16 -05:00
|
|
|
|
| single hnode => exact stepTrace hjoin hnode
|
|
|
|
|
|
| @edge _ ρ' _ i₁ i₂ _ hnode hedge _ ih =>
|
|
|
|
|
|
have hstep : ⟦ variablesAt i₁ (result L prog) ⟧ ρ' (stepNode i₁ hnode st₁) :=
|
|
|
|
|
|
stepTrace hjoin hnode
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
have hmem : variablesAt i₁ (result L prog)
|
|
|
|
|
|
∈ (result L prog).valuesAt (prog.incoming i₂) :=
|
2026-06-09 20:14:53 -07:00
|
|
|
|
FiniteMap.mem_valuesAt prog.states_nodup
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
(prog.mem_incoming_of_edge hedge) (variablesAt_mem i₁ (result L prog))
|
2026-06-23 13:29:54 -05:00
|
|
|
|
exact ih (interp_foldr hstep hmem)
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-27 16:29:16 -05:00
|
|
|
|
variable (L prog) in
|
|
|
|
|
|
theorem analyze_correct_state {ρ : Env} (hrun : EvalStmt [] prog.rootStmt ρ) :
|
|
|
|
|
|
⟦ variablesAt prog.finalState (result L prog) ⟧ ρ
|
|
|
|
|
|
(stepTraceState (prog.trace hrun) S.init) := by
|
|
|
|
|
|
refine walkTrace ?_ (prog.trace hrun)
|
2026-06-09 20:14:53 -07:00
|
|
|
|
rw [joinForKey_initialState]
|
2026-06-27 16:29:16 -05:00
|
|
|
|
exact ValidStateEvaluator.botV_init
|
|
|
|
|
|
|
|
|
|
|
|
end
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
Lean migration: typeclass-based parameter passing, as in the Agda original
The port had flattened Agda's instance arguments ({{flA}}, {{evaluator}},
{{latticeInterpretation}}, {{validEvaluator}}) into explicitly threaded
values (fhL, E, I, hE). Restore them as typeclasses:
- Spa.FiniteHeightLattice: now actually used — Fixedpoint takes the
instance instead of a FixedHeight value; FiniteMap gets the missing
instance (height = ks.length * height B), so varsFixedHeight /
statesFixedHeight / signFixedHeight / constFixedHeight plumbing
disappears (instance bottoms are defeq to the old ones)
- Spa.Analysis.Forward.Evaluation: StmtEvaluator/ExprEvaluator become
classes; the Valid* Props become Prop-classes, as in Agda
- Spa.Analysis.Forward.Adapters: the expr→stmt adapter and its validity
are instances (Agda: the ExprToStmtAdapter instances)
- LatticeInterpretation is a class; sign/const interpretations,
evaluators and validity proofs are instances; use sites read like the
Agda module applications: result SignLattice prog
Proof simplifications (same theorems, proofs factored):
- Spa.Lattice.AboveBelow.monotone₂_of_strict: any ⊥-strict/⊤-dominated
operation on a flat lattice is monotone — replaces the four near-
identical case bashes per analysis (postulates in Agda)
- Spa.Lattice.AboveBelow.interp_sup_of/interp_inf_of: the shared flat-
lattice interpretation case analysis, making interpSign_sup/inf and
interpConst_sup/inf one-liners
lake build green with zero warnings; lake exe spa output verified
byte-identical (diff) to the previous, Agda-verified output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:32:38 -07:00
|
|
|
|
variable (L prog) in
|
2026-06-27 16:29:16 -05:00
|
|
|
|
theorem analyze_correct [LatticeInterpretation L] [ValidStmtEvaluator L prog]
|
|
|
|
|
|
{ρ : Env} (hrun : EvalStmt [] prog.rootStmt ρ) :
|
|
|
|
|
|
⟦ variablesAt prog.finalState (result L prog) ⟧ ρ () :=
|
|
|
|
|
|
analyze_correct_state L prog hrun
|
2026-06-09 20:14:53 -07:00
|
|
|
|
|
2026-06-24 13:54:37 -05:00
|
|
|
|
end Forward
|
|
|
|
|
|
|
2026-06-09 20:14:53 -07:00
|
|
|
|
end Spa
|