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:
2026-06-22 18:33:48 -05:00
parent b16f14fdfd
commit 2ee32580a2
10 changed files with 115 additions and 457 deletions

View File

@@ -175,6 +175,7 @@ theorem monotone₂_of_strict {β γ : Type*} [DecidableEq β] [DecidableEq γ]
· rw [htopl y hy]; exact le_top' _
· exact le_rfl
· intro x a b hab
show f x a f x b
rcases le_cases hab with rfl | rfl | rfl
· rw [hbotr]; exact bot_le' _
· rcases eq_or_ne x bot with rfl | hx
@@ -264,25 +265,23 @@ theorem boundedChains : BoundedChains (AboveBelow α) 2 := fun c => by
have h2 : rank c.last 2 := by cases c.last <;> simp [rank]
omega
/-- Agda: `Plain.longestChain` and `Plain.fixedHeight` — the witness `x`
seeds the chain `⊥ ≺ [x] ≺ ` of length 2. -/
def plainFixedHeight (x : α) : FixedHeight (AboveBelow α) 2 where
/-- Agda: `Plain.longestChain`/`Plain.fixedHeight` and
`Plain.isFiniteHeightLattice`/`Plain.finiteHeightLattice` — the witness
(`default`, playing the role of the Agda module parameter `x`) seeds the chain
`⊥ ≺ [x] ≺ ` of length 2. -/
instance [Inhabited α] : FiniteHeightLattice (AboveBelow α) where
bot := bot
top := top
longestChain :=
((RelSeries.singleton _ bot).snoc (mk x)
(by rw [RelSeries.last_singleton]; exact bot_lt_mk x)).snoc top
(by rw [RelSeries.last_snoc]; exact mk_lt_top x)
head_longestChain := by simp
last_longestChain := by simp
length_longestChain := by simp [RelSeries.snoc, RelSeries.append]
bounded := boundedChains
/-- Agda: `Plain.isFiniteHeightLattice` / `Plain.finiteHeightLattice`
(`default` plays the role of the Agda module parameter `x`). -/
instance [Inhabited α] : FiniteHeightLattice (AboveBelow α) where
height := 2
fixedHeight := plainFixedHeight default
longest_chain :=
{ series :=
((RelSeries.singleton _ bot).snoc (mk default)
(by rw [RelSeries.last_singleton]; exact bot_lt_mk default)).snoc top
(by rw [RelSeries.last_snoc]; exact mk_lt_top default)
head_series := by simp
last_series := by simp
length_series := by simp [RelSeries.snoc, RelSeries.append] }
chains_bounded := boundedChains
end AboveBelow