Have LatticeInterpretation extend Interp

LatticeInterpretation now extends Interp L (Value → Prop), so each analysis
defines only its LatticeInterpretation instance and gets the ⟦⟧ notation for
free. Drops the standalone per-analysis Interp instances (signInterp and the
anonymous constInterp). The Interp class is kept for other uses.

The interp*_mk_disjoint bootstrap lemmas now state on the raw interp function
since they feed the instance and run before any Interp instance exists; the
trivial sup/inf wrappers are inlined into the instance.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 13:01:53 -05:00
parent 6afa7df444
commit 8ce6e5e4e4
3 changed files with 11 additions and 31 deletions

View File

@@ -42,27 +42,17 @@ def interpConst : ConstLattice → Value → Prop
| .top, _ => True
| .mk z, v => v = .int z
instance : Interp ConstLattice (Value Prop) := interpConst
theorem interpConst_mk_disjoint {z₁ z₂ : } (hne : z₁ z₂) {v : Value} :
¬((.mk z₁ : ConstLattice) v (.mk z₂ : ConstLattice) v) := by
¬(interpConst (.mk z₁) v interpConst (.mk z₂) v) := by
rintro h₁, h₂
rw [h₁] at h₂
injection h₂ with hz
exact hne hz
theorem interpConst_sup {s₁ s₂ : ConstLattice} (v : Value)
(h : s₁ v s₂ v) : s₁ s₂ v :=
AboveBelow.interp_sup_of (fun _ h => h) (fun _ => trivial) v h
theorem interpConst_inf {s₁ s₂ : ConstLattice} (v : Value)
(h : s₁ v s₂ v) : s₁ s₂ v :=
AboveBelow.interp_inf_of (fun hne _ => interpConst_mk_disjoint hne) v h
instance constInterpretation : LatticeInterpretation ConstLattice where
interp := interpConst
interp_sup := fun {l₁ l₂} v h => interpConst_sup (s₁ := l₁) (s₂ := l) v h
interp_inf := fun {l₁ l₂} v h => interpConst_inf (s₁ := l₁) (s₂ := l₂) v h
interp_sup := fun v h => AboveBelow.interp_sup_of (fun _ h => h) (fun _ => trivial) v h
interp_inf := fun v h => AboveBelow.interp_inf_of (fun hne _ => interpConst_mk_disjoint hne) v h
variable (prog : Program)