Skip to content

Commit 98aefd7

Browse files
committed
fix: right-recursive _⊕_ + Phase 1.3 right-monotonicity lemmas (issue #34)
Switches Ordinal.Brouwer.Arithmetic._⊕_ from left-recursive to right-recursive. The left-recursive form made ⊕-mono-<-right unprovable at limit α: the counterexample ω ⊕ oz <′ ω ⊕ osuc oz requires a witness Σ k. ω ≤′ nat-to-ord k which does not exist. Right-recursive _⊕_ aligns with _≤′_'s second-argument structure, making ⊕-mono-<-right provable by structural induction on γ. Arithmetic.agda: - Flip _⊕_ equations: α ⊕ oz = α / α ⊕ osuc β = osuc (α ⊕ β) / α ⊕ olim f = olim (λ n → α ⊕ f n) - Replace ⊕-oz-left (left-unit, now propositional) with ⊕-oz-right (right-unit, now definitional) - Update module comment to reference issue #34 Phase13.agda: - Add import of _⊕_ from Arithmetic - Add ≤′-self-osuc : ∀ x → x ≤′ osuc x - Add ≤′-weaken-osuc : x ≤′ y → x ≤′ osuc y - Add ⊕-left-≤-sum : α ≤′ α ⊕ γ - Add ⊕-mono-<-right and ⊕-mono-≤-right (mutual) closing issue #34; unblocks rank-mono in RankBrouwer for <ᵇʳᶠ-ψα and <ᵇʳᶠ-+2 cases Smoke.agda: - Replace ⊕-oz-left with ⊕-oz-right in import list Locally typechecked: agda -i proofs/agda proofs/agda/All.agda passes.
1 parent f630edb commit 98aefd7

3 files changed

Lines changed: 94 additions & 26 deletions

File tree

proofs/agda/Ordinal/Brouwer/Arithmetic.agda

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,16 @@
33
-- Phase 1.2 of the Option B programme (see `docs/buchholz-plan.adoc`).
44
--
55
-- Ordinal arithmetic on Brouwer notations: *definitions* only.
6-
-- All non-trivial monotonicity proofs are scheduled for Phase 1.3,
7-
-- where they may drive a small redesign of `_≤_` in the base
8-
-- `Ordinal.Brouwer` module (the current data-type axiomatisation
9-
-- proves key lemmas like `osuc-mono-≤` only with some care, and
10-
-- the Phase 1.3 work will decide whether to add constructors or
11-
-- switch to a recursive `_≤_`).
6+
-- All non-trivial monotonicity proofs are in Phase 1.3 (Phase13.agda).
127
--
138
-- Contents:
149
--
15-
-- * `_⊕_` — left-recursive naive ordinal sum. Not Hessenberg; the
16-
-- full natural-sum definition (commutative + bi-monotonic) needs
17-
-- more machinery than pays off for the rank we actually need.
18-
-- This is the cheapest sum that still lets `psi-rank` propagate
19-
-- ordinal-argument descent via right-monotonicity, which is the
20-
-- only direction we need for Phase 2.2.
10+
-- * `_⊕_` — right-recursive ordinal sum. Recursion is on the right
11+
-- argument, mirroring `_≤′_`'s second-argument structure, so that
12+
-- `⊕-mono-<-right` and `⊕-mono-≤-right` are provable by structural
13+
-- induction on `γ` (see issue #34 for the counterexample that ruled
14+
-- out the original left-recursive form). Right-unit `α ⊕ oz = α` is
15+
-- definitional; left-unit `oz ⊕ β = β` is propositional (Phase 1.3).
2116
-- * `nat-to-ord` — the standard successor-stack encoding of ℕ.
2217
-- * `ω-rank : OmegaIndex → Ord` — rank for Ω-markers. `fin n` maps
2318
-- to `osuc^(n+1) oz`, `ω` maps to the canonical Brouwer ω.
@@ -35,19 +30,20 @@ open import Ordinal.OmegaMarkers using (OmegaIndex; fin; ω)
3530
open import Ordinal.Brouwer using (Ord; oz; osuc; olim)
3631

3732
----------------------------------------------------------------------------
38-
-- Naive ordinal sum
33+
-- Ordinal sum (right-recursive)
3934
----------------------------------------------------------------------------
4035

41-
-- Left-recursive: zero on the left is the unit definitionally,
42-
-- successor on the left lifts the successor past the sum, limit on
43-
-- the left distributes under the sum.
36+
-- Right-recursive: right-unit `α ⊕ oz = α` is definitional; successor
37+
-- on the right lifts past the sum; limit on the right distributes.
38+
-- This direction aligns with `_≤′_`'s second-argument recursion and
39+
-- makes `⊕-mono-<-right` provable by induction on γ (Phase 1.3).
4440

4541
infixl 6 _⊕_
4642

4743
_⊕_ : Ord Ord Ord
48-
oz ⊕ β = β
49-
osuc α ⊕ β = osuc (α ⊕ β)
50-
olim f ⊕ β = olim (λ n f n ⊕ β)
44+
α ⊕ oz = α
45+
α ⊕ osuc β = osuc (α ⊕ β)
46+
α ⊕ olim f = olim (λ n α ⊕ f n)
5147

5248
----------------------------------------------------------------------------
5349
-- Rank target for Ω-indices
@@ -95,10 +91,7 @@ open import Ordinal.Brouwer using (one; two)
9591
ω-rank-fin1 : ω-rank (fin 1) ≡ two
9692
ω-rank-fin1 = refl
9793

98-
-- `psi-rank ν oz = osuc (ω-rank ν ⊕ oz)`. Since `⊕`'s right-identity
99-
-- is only up to `≤` (proved in Phase 1.3), we don't state `≡` here.
94+
-- Right-unit of `⊕` is definitional.
10095

101-
-- Left-unit of `⊕` is definitional.
102-
103-
⊕-oz-left : β oz ⊕ β ≡ β
104-
⊕-oz-left _ = refl
96+
⊕-oz-right : α α ⊕ oz ≡ α
97+
⊕-oz-right _ = refl

proofs/agda/Ordinal/Brouwer/Phase13.agda

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
-- on `Ord` mirroring `Ordinal.Brouwer.wf-<`. Predecessor lemmas
3131
-- `pred-of-osuc-<′` and `pred-of-olim-<′` reduce through the
3232
-- computed shape of `_<′_` rather than constructor pattern-match.
33+
-- * `≤′-self-osuc` — every ordinal is below its successor: x ≤′ osuc x.
34+
-- * `≤′-weaken-osuc` — weakening: x ≤′ y → x ≤′ osuc y.
35+
-- * `⊕-left-≤-sum` — left addend ≤ sum: α ≤′ α ⊕ γ.
36+
-- * `⊕-mono-≤-right` — `_⊕_` is monotone on the right w.r.t. `≤′`.
37+
-- * `⊕-mono-<-right` — `_⊕_` is strictly monotone on the right
38+
-- w.r.t. `<′`. Closes the `<ᵇʳᶠ-ψα` and `<ᵇʳᶠ-+2` cases of
39+
-- `rank-mono` in `Ordinal.Buchholz.RankBrouwer` (issue #34).
3340
--
3441
-- ## Closure of the original obstacle
3542
--
@@ -49,6 +56,7 @@ open import Data.Empty using (⊥; ⊥-elim)
4956
open import Induction.WellFounded using (Acc; acc; WellFounded)
5057

5158
open import Ordinal.Brouwer using (Ord; oz; osuc; olim)
59+
open import Ordinal.Brouwer.Arithmetic using (_⊕_)
5260

5361
----------------------------------------------------------------------------
5462
-- Recursive `_≤′_` per the Echidna SA recommendation
@@ -189,3 +197,69 @@ wf-<′ : WellFounded _<′_
189197
wf-<′ oz = acc (λ {β} ())
190198
wf-<′ (osuc α) = acc (pred-of-osuc-<′ (wf-<′ α))
191199
wf-<′ (olim f) = acc (pred-of-olim-<′ (λ n wf-<′ (f n)))
200+
201+
----------------------------------------------------------------------------
202+
-- x ≤′ osuc x (every ordinal is strictly below its successor)
203+
----------------------------------------------------------------------------
204+
205+
-- Structural recursion on x. The `olim f` case uses f-in-lim′ to
206+
-- route through the branch: f n ≤′ osuc (f n) ≤′ osuc (olim f).
207+
-- The last step holds because `osuc (f n) ≤′ osuc (olim f)` reduces
208+
-- definitionally to `f n ≤′ olim f`, which is f-in-lim′.
209+
210+
≤′-self-osuc : x x ≤′ osuc x
211+
≤′-self-osuc oz = tt
212+
≤′-self-osuc (osuc x) = ≤′-self-osuc x
213+
≤′-self-osuc (olim f) = λ n
214+
≤′-trans {f n} {osuc (f n)} {osuc (olim f)}
215+
(≤′-self-osuc (f n))
216+
(f-in-lim′ f n)
217+
218+
-- Weakening: x ≤′ y → x ≤′ osuc y. One-liner via transitivity and
219+
-- ≤′-self-osuc; no case analysis needed.
220+
221+
≤′-weaken-osuc : {x y} x ≤′ y x ≤′ osuc y
222+
≤′-weaken-osuc {x} {y} p = ≤′-trans {x} {y} {osuc y} p (≤′-self-osuc y)
223+
224+
----------------------------------------------------------------------------
225+
-- α ≤′ α ⊕ γ (left addend is always ≤ the sum)
226+
----------------------------------------------------------------------------
227+
228+
-- Structural recursion on γ. Right-recursive `_⊕_` is essential:
229+
-- each case of γ reduces `α ⊕ γ` to a form whose `_≤′_` target is
230+
-- immediately dischargeable.
231+
232+
⊕-left-≤-sum : {α} γ α ≤′ α ⊕ γ
233+
⊕-left-≤-sum {α} oz = ≤′-refl {α}
234+
⊕-left-≤-sum {α} (osuc γ') = ≤′-weaken-osuc {α} {α ⊕ γ'} (⊕-left-≤-sum {α} γ')
235+
⊕-left-≤-sum {α} (olim g) =
236+
≤′-trans {α} {α ⊕ g 0} {α ⊕ olim g}
237+
(⊕-left-≤-sum {α} (g 0))
238+
(f-in-lim′ (λ n α ⊕ g n) 0)
239+
240+
----------------------------------------------------------------------------
241+
-- Right monotonicity of `_⊕_` (issue #34 fix)
242+
----------------------------------------------------------------------------
243+
244+
-- `⊕-mono-<-right` and `⊕-mono-≤-right` are mutually recursive.
245+
-- Both induct primarily on γ (for <) or β (for ≤), with the other
246+
-- position decreasing in cross-calls. Agda's termination checker
247+
-- accepts the lex pair (β, γ) as the measure.
248+
--
249+
-- Right-recursive `_⊕_` is the enabling change: each constructor of
250+
-- γ in `⊕-mono-<-right` matches exactly one clause of `_≤′_`'s
251+
-- second-argument computation, giving a direct proof path.
252+
253+
mutual
254+
255+
⊕-mono-<-right : {α β γ} β <′ γ α ⊕ β <′ α ⊕ γ
256+
⊕-mono-<-right {_} {_} {oz} ()
257+
⊕-mono-<-right {α} {β} {osuc γ'} p = ⊕-mono-≤-right {α} {β} {γ'} p
258+
⊕-mono-<-right {α} {β} {olim g} (n , p) = n , ⊕-mono-<-right {α} {β} {g n} p
259+
260+
⊕-mono-≤-right : {α β γ} β ≤′ γ α ⊕ β ≤′ α ⊕ γ
261+
⊕-mono-≤-right {α} {oz} {γ} _ = ⊕-left-≤-sum {α} γ
262+
⊕-mono-≤-right {_} {osuc _} {oz} ()
263+
⊕-mono-≤-right {α} {osuc β'} {osuc γ'} p = ⊕-mono-≤-right {α} {β'} {γ'} p
264+
⊕-mono-≤-right {α} {osuc β'} {olim g} (n , p) = n , ⊕-mono-<-right {α} {β'} {g n} p
265+
⊕-mono-≤-right {α} {olim f} {γ} p = λ n ⊕-mono-≤-right {α} {f n} {γ} (p n)

proofs/agda/Smoke.agda

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ open import Ordinal.Brouwer.Arithmetic using
260260
; nat-to-ord
261261
; ω-rank
262262
; psi-rank
263-
; ⊕-oz-left
263+
; ⊕-oz-right
264264
; ω-rank-fin0
265265
; ω-rank-fin1
266266
)
@@ -432,3 +432,4 @@ open import Ordinal.Buchholz.WellFormed using
432432
; psi-OmegaOmega
433433
; psi-OmegaOmega-wf
434434
)
435+

0 commit comments

Comments
 (0)