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>
This commit is contained in:
2026-06-09 23:32:38 -07:00
parent b26d6b5acd
commit b16f14fdfd
12 changed files with 338 additions and 407 deletions

View File

@@ -118,7 +118,10 @@ def FixedHeight.cast {α : Type*} [Preorder α] {m n : } (h : m = n)
@[simp] theorem FixedHeight.cast_bot {α : Type*} [Preorder α] {m n : }
(h : m = n) (fh : FixedHeight α m) : (fh.cast h).bot = fh.bot := rfl
/-- Agda: `IsFiniteHeightLattice` / `FiniteHeightLattice` (bundled). -/
/-- Agda: `IsFiniteHeightLattice` / `FiniteHeightLattice` (bundled). Like the
Agda code (which took `IsFiniteHeightLattice` as an instance argument `⦃·⦄`),
this is a typeclass; downstream modules pick it up by instance resolution
rather than threading a `FixedHeight` value. -/
class FiniteHeightLattice (α : Type*) [Lattice α] where
height :
fixedHeight : FixedHeight α height
@@ -150,4 +153,16 @@ theorem bot_le (fh : FixedHeight α h) : fh.KnownBot := by
end FixedHeight
namespace FiniteHeightLattice
variable (α : Type*) [Lattice α] [FiniteHeightLattice α]
/-- Agda: the `⊥` of `Chain.Height`, with the type explicit. -/
def bot : α := (fixedHeight (α := α)).bot
/-- Agda: `⊥≼` for the instance bottom. -/
theorem bot_le (a : α) : bot α a := FixedHeight.bot_le _ a
end FiniteHeightLattice
end Spa