Lean migration cleanup: collapse FixedHeight struct into FiniteHeightLattice typeclass
The fable-based migration left a two-layer design (a standalone `FixedHeight α h` struct, height carried as a type index, plus a `FiniteHeightLattice` wrapper). This collapses it to the single `FiniteHeightLattice` typeclass (height as a plain field, `⊥`/`⊤` via `extends Bot`/`Top`), and fixes the fallout so the whole project builds again (`lake build` green). - Lattice: repair `FixedHeight.bot_le` (compute the `▸` motive via a forward `rw`, drop the leftover `fh.length_longestChain`) and the `bot_le` alias. - Isomorphism: transport rewritten directly onto `FiniteHeightLattice`, taking the source as an instance argument. - Lattice/Prod, AboveBelow: `FixedHeight`-producing def + wrapper instance collapsed into one `FiniteHeightLattice` instance. `head`/`last` proofs use term-mode `congrArg` to bridge the `Bot`/`Top` defeq through the under-construction instance projection (where `rw`+`rfl` cannot). - Lattice/IterProd: `fixedHeight` recursion now yields a `FiniteHeightLattice` (no height index, so the `.cast (by ring)` reassociations vanish); `bot_fixedHeight` reprojected onto the def's own `.bot`. - Lattice/FiniteMap: `fixedHeight`/`bot_contains_bots` go through transport with the IterProd instance resolved by typeclass search; `punitFixedHeight` replaced by the `PUnit` instance. - Analysis/Forward/Lattices: `botV` uses `⊥` instead of the deleted `FiniteHeightLattice.bot` accessor. - Analysis/Sign: `num` case used unimported `ring`; the goal is a pure ℕ→ℤ cast identity, closed with `norm_cast`. Also fixes the missing `show` in `AboveBelow.monotone₂_of_strict` that left un-beta-reduced redexes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,3 @@
|
||||
/-
|
||||
Port of `Lattice/Prod.agda`.
|
||||
|
||||
The component-wise lattice structure on `α × β` is lifted into mathlib
|
||||
(`Prod.instLattice`), as is decidability of equality. What remains custom is
|
||||
the fixed-height content:
|
||||
|
||||
unzip ↦ LTSeries.exists_unzip
|
||||
a,∙-Monotonic/∙,b-Monotonic ↦ Prod.mk_lt_mk_iff_right/left (strict mono of
|
||||
the two injections, used to map the chains)
|
||||
fixedHeight (h₁ + h₂) ↦ FixedHeight.prod
|
||||
isFiniteHeightLattice ↦ instance FiniteHeightLattice (α × β)
|
||||
-/
|
||||
import Spa.Lattice
|
||||
|
||||
namespace Spa
|
||||
@@ -19,8 +6,6 @@ section Unzip
|
||||
|
||||
variable {α β : Type*} [PartialOrder α] [PartialOrder β]
|
||||
|
||||
/-- Agda: `unzip` — a chain in the product splits into chains of the
|
||||
components whose lengths sum to at least the original length. -/
|
||||
theorem LTSeries.exists_unzip (c : LTSeries (α × β)) :
|
||||
∃ (c₁ : LTSeries α) (c₂ : LTSeries β),
|
||||
c₁.head = c.head.1 ∧ c₁.last = c.last.1 ∧
|
||||
@@ -78,35 +63,35 @@ section FixedHeight
|
||||
|
||||
variable {α β : Type*} [Lattice α] [Lattice β]
|
||||
|
||||
/-- Agda: `Lattice/Prod.agda`'s `fixedHeight` — the product of lattices of
|
||||
heights `h₁` and `h₂` has height `h₁ + h₂`. The longest chain climbs the first
|
||||
component (at `⊥₂`), then the second component (at `⊤₁`). -/
|
||||
def FixedHeight.prod {h₁ h₂ : ℕ} (fhA : FixedHeight α h₁) (fhB : FixedHeight β h₂) :
|
||||
FixedHeight (α × β) (h₁ + h₂) where
|
||||
bot := (fhA.bot, fhB.bot)
|
||||
top := (fhA.top, fhB.top)
|
||||
longestChain :=
|
||||
RelSeries.smash
|
||||
(fhA.longestChain.map (fun a => (a, fhB.bot))
|
||||
(fun _ _ h => Prod.mk_lt_mk_iff_left.mpr h))
|
||||
(fhB.longestChain.map (fun b => (fhA.top, b))
|
||||
(fun _ _ h => Prod.mk_lt_mk_iff_right.mpr h))
|
||||
(by simp [fhA.last_longestChain, fhB.head_longestChain])
|
||||
head_longestChain := by simp [fhA.head_longestChain]
|
||||
last_longestChain := by simp [fhB.last_longestChain]
|
||||
length_longestChain := by
|
||||
simp [fhA.length_longestChain, fhB.length_longestChain]
|
||||
bounded := fun c => by
|
||||
obtain ⟨c₁, c₂, -, -, -, -, hlen⟩ := LTSeries.exists_unzip c
|
||||
have h₁ := fhA.bounded c₁
|
||||
have h₂ := fhB.bounded c₂
|
||||
omega
|
||||
|
||||
/-- Agda: `Lattice/Prod.agda`'s `isFiniteHeightLattice`/`finiteHeightLattice`. -/
|
||||
instance [IA : FiniteHeightLattice α] [IB : FiniteHeightLattice β] :
|
||||
instance prod [A : FiniteHeightLattice α] [B : FiniteHeightLattice β] :
|
||||
FiniteHeightLattice (α × β) where
|
||||
height := IA.height + IB.height
|
||||
fixedHeight := IA.fixedHeight.prod IB.fixedHeight
|
||||
bot := ((⊥ : α), (⊥ : β))
|
||||
top := ((⊤ : α), (⊤ : β))
|
||||
height := A.height + B.height
|
||||
longest_chain :=
|
||||
{ series :=
|
||||
RelSeries.smash
|
||||
(A.longest_chain.series.map (fun a => (a, (⊥ : β)))
|
||||
(fun _ _ h => Prod.mk_lt_mk_iff_left.mpr h))
|
||||
(B.longest_chain.series.map (fun b => ((⊤ : α), b))
|
||||
(fun _ _ h => Prod.mk_lt_mk_iff_right.mpr h))
|
||||
(by simp [A.longest_chain.last_series, B.longest_chain.head_series])
|
||||
head_series :=
|
||||
(RelSeries.head_smash _).trans
|
||||
((LTSeries.head_map _ _ _).trans
|
||||
(congrArg (·, (⊥ : β)) A.longest_chain.head_series))
|
||||
last_series :=
|
||||
(RelSeries.last_smash _).trans
|
||||
((LTSeries.last_map _ _ _).trans
|
||||
(congrArg ((⊤ : α), ·) B.longest_chain.last_series))
|
||||
length_series := by
|
||||
show A.longest_chain.series.length + B.longest_chain.series.length = _
|
||||
rw [A.longest_chain.length_series, B.longest_chain.length_series] }
|
||||
chains_bounded := fun c => by
|
||||
obtain ⟨c₁, c₂, -, -, -, -, hlen⟩ := LTSeries.exists_unzip c
|
||||
have h₁ := A.chains_bounded c₁
|
||||
have h₂ := B.chains_bounded c₂
|
||||
omega
|
||||
|
||||
end FixedHeight
|
||||
|
||||
|
||||
Reference in New Issue
Block a user