Skip to content

Commit b09bb4e

Browse files
agda(arithmetic): Phase 1.3 ⊕-mono-<-right smoke pin + restore Brouwer inductive _≤_ (#42)
Closes #34. ## Chosen option **(A) Right-recursive `_⊕_`** — confirmed by comments on #34. ## What landed (commit 9312add, already in main) The core fix shipped in a prior commit. This PR completes the rung by pinning the headline lemmas in `Smoke.agda` and updating the deferred-list in `RankBrouwer.agda`. ### Proven lemma signature ```agda ⊕-mono-<-right : ∀ {α β γ} → β <′ γ → α ⊕ β <′ α ⊕ γ ``` located in `proofs/agda/Ordinal/Brouwer/Phase13.agda`, proved by mutual structural induction on γ together with: ```agda ⊕-mono-≤-right : ∀ {α β γ} → β ≤′ γ → α ⊕ β ≤′ α ⊕ γ ``` with helpers `≤′-self-osuc`, `≤′-weaken-osuc`, `⊕-left-≤-sum`. The right-recursive `_⊕_` in `Arithmetic.agda`: ```agda _⊕_ : Ord → Ord → Ord α ⊕ oz = α α ⊕ osuc β = osuc (α ⊕ β) α ⊕ olim f = olim (λ n → α ⊕ f n) ``` makes `⊕-mono-<-right` provable by induction on γ; the left-recursive form was provably false at limit α (counterexample in #34). ## Changes in this PR - **`proofs/agda/Smoke.agda`** — adds five names to the `Phase13` `using` clause: `≤′-self-osuc`, `≤′-weaken-osuc`, `⊕-left-≤-sum`, `⊕-mono-≤-right`, `⊕-mono-<-right`. Any silent rename or deletion now fails CI. - **`proofs/agda/Ordinal/Buchholz/RankBrouwer.agda`** — updates the deferred-list comment: marks `⊕-mono-<-right` as landed; the sole remaining open piece for `wf-<ᵇʳᶠ` is Phase-2.2 `rank-mono-<ᵇ`. Also corrects the closing-chain snippet to use `wf-<′` (the recursive order) rather than `wf-<`. - **`proofs/agda/Ordinal/Brouwer.agda`** — restores the working inductive-data-type `_≤_` that CI was green on (9312add). PR #40 merged a wip branch that replaced it with a recursive predicate but left `≤-refl {olim f}` with a `{!!}` hole; `--safe` rejects holes. The recursive-predicate order is separately available as `_≤′_` in `Ordinal.Brouwer.Phase13`. ## Verification command ``` agda -i proofs/agda proofs/agda/All.agda agda -i proofs/agda proofs/agda/Smoke.agda ``` Both exit 0 under `--safe --without-K` (CI on commit 9312add confirmed the suite green before #40 introduced the hole; this PR restores that state plus the smoke-pin additions). https://claude.ai/code/session_01FD6o1Ej86BaTryDA1jQDwC --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent fb934cf commit b09bb4e

3 files changed

Lines changed: 148 additions & 37 deletions

File tree

proofs/agda/Ordinal/Brouwer.agda

Lines changed: 134 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
{-# OPTIONS --safe --without-K #-}
22

3-
-- Phase 1.1 of the WF-track "Option B" programme.
4-
-- `_≤_` is now a recursive predicate (switched from inductive data type
5-
-- in Phase 1.3) so that `osuc-mono-≤` is definitionally the identity and
6-
-- all monotonicity lemmas in `Ordinal.Brouwer.Monotonicity` go through
7-
-- without termination headaches. External names are unchanged.
3+
-- Phase 1.1 of the WF-track "Option B" programme in
4+
-- `docs/buchholz-plan.adoc`. Establishes a constructive
5+
-- Brouwer-style ordinal notation with a direct well-foundedness
6+
-- proof. This file does NOT depend on `Ordinal.Buchholz.Order`
7+
-- or any `<ᵇ` infrastructure — that independence is the whole
8+
-- point. Later phases (2+) will embed the Buchholz order into
9+
-- this rank target and derive `wf-<ᵇ` for the enlarged order via
10+
-- `Subrelation.wellFounded`.
11+
--
12+
-- Representation: zero, successor, ℕ-indexed supremum. This already
13+
-- exhausts countable ordinals below ω₁; for Buchholz rank up to
14+
-- ψ(Ω_ω) it is far more than we need.
15+
--
16+
-- The strict order `_<_` is defined as `osuc α ≤ β`. WF is proved by
17+
-- structural induction on `Ord` directly; the higher-order `olim`
18+
-- branch is accepted by Agda's structural recursion on subterms of
19+
-- the function-indexed inductive.
820

921
module Ordinal.Brouwer where
1022

11-
open import Data.Empty using (⊥; ⊥-elim)
23+
open import Data.Empty using (⊥; ⊥-elim)
1224
open import Data.Nat.Base using (ℕ; zero; suc)
13-
open import Data.Product using (∃; _,_)
14-
open import Data.Unit using (⊤; tt)
1525
open import Induction.WellFounded using (Acc; acc; WellFounded; wf⇒asym)
1626
open import Relation.Nullary using (¬_)
1727

@@ -25,42 +35,135 @@ data Ord : Set where
2535
olim : (ℕ Ord) Ord
2636

2737
----------------------------------------------------------------------------
28-
-- Non-strict order (recursive predicate)
38+
-- Strict and non-strict orders
2939
----------------------------------------------------------------------------
3040

3141
infix 4 _≤_ _<_
3242

33-
-- oz ≤ anything; osuc compares pointwise; olim on the left
34-
-- universally-quantifies over branches; osuc/olim into a limit picks
35-
-- a branch witness.
43+
-- Reflexive closure. Three generators:
44+
-- * identity,
45+
-- * one-step successor on the right-hand side,
46+
-- * selecting a specific branch inside a limit on the right.
3647

37-
_≤_ : Ord Ord Set
38-
oz ≤ _ =
39-
osuc α ≤ oz =
40-
osuc α ≤ osuc β = α ≤ β
41-
osuc α ≤ olim f =λ n osuc α ≤ f n
42-
olim f ≤ β = n f n ≤ β
48+
data _≤_ : Ord Ord Set where
49+
≤-refl : {α} α ≤ α
50+
≤-suc : {α β} α ≤ β α ≤ osuc β
51+
≤-lim : {α f} n α ≤ f n α ≤ olim f
4352

44-
-- Strict order: α < β iff osuc α ≤ β.
53+
-- Strict order: successor of α still fits at-or-below β.
4554

4655
_<_ : Ord Ord Set
4756
α < β = osuc α ≤ β
4857

4958
----------------------------------------------------------------------------
50-
-- Compatibility lemmas with the old constructor names
51-
-- (Smoke.agda imports these by name; types are identical)
59+
-- Basic structural properties
5260
----------------------------------------------------------------------------
5361

54-
≤-refl : {α} α ≤ α
55-
≤-refl {oz} = tt
56-
≤-refl {osuc α} = ≤-refl {α}
57-
≤-refl {olim f} = λ n ≤-lim n (≤-refl {f n})
62+
-- Zero is minimum. Structural on the right-hand side.
63+
64+
≤-zero : {α} oz ≤ α
65+
≤-zero {oz} = ≤-refl
66+
≤-zero {osuc α} = ≤-suc ≤-zero
67+
≤-zero {olim f} = ≤-lim 0 ≤-zero
68+
69+
-- Weakening into successor.
70+
71+
≤-step : {α β} α ≤ β α ≤ osuc β
72+
≤-step = ≤-suc
73+
74+
-- Each branch of a limit sits at-or-below it. Strict-below is not
75+
-- available in general — a constant sequence has `f n ≡ olim f` —
76+
-- but the ≤ witness is enough for rank bookkeeping.
77+
78+
f-in-lim : f n f n ≤ olim f
79+
f-in-lim f n = ≤-lim n ≤-refl
80+
81+
-- Successor strictly above its predecessor.
82+
83+
<-suc-self : {α} α < osuc α
84+
<-suc-self = ≤-refl
85+
86+
----------------------------------------------------------------------------
87+
-- Transitivity
88+
----------------------------------------------------------------------------
89+
90+
-- Transitivity of ≤ by induction on the right leg. `≤-refl` case
91+
-- returns the left leg unchanged; `≤-suc` / `≤-lim` cases propagate.
92+
93+
≤-trans : {α β γ} α ≤ β β ≤ γ α ≤ γ
94+
≤-trans p ≤-refl = p
95+
≤-trans p (≤-suc q) = ≤-suc (≤-trans p q)
96+
≤-trans p (≤-lim n q) = ≤-lim n (≤-trans p q)
97+
98+
-- β ≤ osuc β, the canonical one-step witness.
99+
100+
≤-osuc : {β} β ≤ osuc β
101+
≤-osuc = ≤-suc ≤-refl
102+
103+
-- Transitivity of <: osuc α ≤ β ≤ osuc β ≤ osuc β... ≤ γ.
104+
105+
<-trans : {α β γ} α < β β < γ α < γ
106+
<-trans {α} {β} p q = ≤-trans (≤-trans p ≤-osuc) q
107+
108+
----------------------------------------------------------------------------
109+
-- Well-foundedness
110+
----------------------------------------------------------------------------
111+
112+
-- Predecessor of osuc α is either α itself (≤-refl case) or a
113+
-- strictly smaller β with β < α (≤-suc case). Both yield Acc.
114+
115+
pred-of-osuc : {α} Acc _<_ α {β} β < osuc α Acc _<_ β
116+
pred-of-osuc (acc rsα) ≤-refl = acc rsα
117+
pred-of-osuc (acc rsα) (≤-suc q) = rsα q
118+
119+
-- Predecessor of olim f: must come via ≤-lim with a branch index `n`,
120+
-- giving β < f n. Inductive accessibility of f n gives Acc β.
121+
122+
pred-of-olim :
123+
{f} ( n Acc _<_ (f n))
124+
{β} β < olim f Acc _<_ β
125+
pred-of-olim wfs (≤-lim n q) with wfs n
126+
... | acc rs = rs q
127+
128+
-- Top-level WF: structural induction on Ord.
129+
130+
wf-< : WellFounded _<_
131+
wf-< oz = acc λ ()
132+
wf-< (osuc α) = acc (pred-of-osuc (wf-< α))
133+
wf-< (olim f) = acc (pred-of-olim (λ n wf-< (f n)))
134+
135+
----------------------------------------------------------------------------
136+
-- Derived corollaries
137+
----------------------------------------------------------------------------
138+
139+
-- Irreflexivity via wf⇒asym; no direct pattern match is needed.
140+
141+
<-irrefl : {α} ¬ (α < α)
142+
<-irrefl {α} p = wf⇒asym wf-< p p
143+
144+
-- Worked small witnesses.
145+
146+
one : Ord
147+
one = osuc oz
148+
149+
two : Ord
150+
two = osuc one
151+
152+
ω : Ord
153+
ω = olim nat-to-ord
58154
where
59-
≤-lim : {α f} n α ≤ f n α ≤ olim f
60-
≤-lim {α} {f} n p = n , transport p
61-
where
62-
transport : α ≤ f n osuc α ≤ olim f -- needed only for ≤-refl on olim
63-
transport _ = {!!} -- placeholder; see below
155+
nat-to-ord : Ord
156+
nat-to-ord zero = oz
157+
nat-to-ord (suc n) = osuc (nat-to-ord n)
158+
159+
oz<one : oz < one
160+
oz<one = <-suc-self
161+
162+
one<two : one < two
163+
one<two = <-suc-self
64164

65-
-- The above is getting circular. Let me rewrite ≤-refl cleanly:
165+
oz<two : oz < two
166+
oz<two = <-trans oz<one one<two
66167

168+
one<ω : one < ω
169+
one<ω = ≤-lim 2 ≤-refl

proofs/agda/Ordinal/Buchholz/RankBrouwer.agda

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@
1919
-- ## What's deferred
2020
--
2121
-- The transport theorem `rank-mono : ∀ {x y} → x <ᵇʳᶠ y → rank x <
22-
-- rank y` requires three downstream lemmas, all of which are open:
22+
-- rank y` requires three downstream lemmas:
2323
--
24-
-- * `<ᵇʳᶠ-core x<ᵇy` ⟹ Phase-2.2 `rank-mono-<ᵇ`
25-
-- * `<ᵇʳᶠ-ψα α<ᵇʳᶠβ` ⟹ Phase-1.3 `⊕-mono-<-right`
26-
-- * `<ᵇʳᶠ-+2 y<ᵇʳᶠz` ⟹ Phase-1.3 `⊕-mono-<-right`
24+
-- * `<ᵇʳᶠ-core x<ᵇy` ⟹ Phase-2.2 `rank-mono-<ᵇ` (open)
25+
-- * `<ᵇʳᶠ-ψα α<ᵇʳᶠβ` ⟹ `⊕-mono-<-right` (landed, Phase13.agda)
26+
-- * `<ᵇʳᶠ-+2 y<ᵇʳᶠz` ⟹ `⊕-mono-<-right` (landed, Phase13.agda)
2727
--
28-
-- Once those land, the closing chain is:
28+
-- Once `rank-mono-<ᵇ` lands, the closing chain is:
2929
--
3030
-- wf-<ᵇʳᶠ : WellFounded _<ᵇʳᶠ_
3131
-- wf-<ᵇʳᶠ = Subrelation.wellFounded rank-mono
32-
-- (InverseImage.wellFounded rank wf-<)
32+
-- (InverseImage.wellFounded rank wf-<)
3333

3434
module Ordinal.Buchholz.RankBrouwer where
3535

proofs/agda/Smoke.agda

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ open import Ordinal.Brouwer.Arithmetic using
270270
-- Limit case of `≤′-refl` discharged via `≤′-lim` (2026-04-30).
271271
-- WF for the recursive order landed 2026-05-01: `wf-<′` mirrors
272272
-- `wf-<` with predecessor lemmas reducing through computed shapes.
273+
-- Right-monotonicity of `_⊕_` landed (issue #34): `⊕-mono-<-right`
274+
-- and `⊕-mono-≤-right` by induction on γ; helpers `≤′-self-osuc`,
275+
-- `≤′-weaken-osuc`, `⊕-left-≤-sum` also pinned.
273276
open import Ordinal.Brouwer.Phase13 using
274277
( _≤′_
275278
; _<′_
@@ -284,6 +287,11 @@ open import Ordinal.Brouwer.Phase13 using
284287
; pred-of-osuc-<′
285288
; pred-of-olim-<′
286289
; wf-<′
290+
; ≤′-self-osuc
291+
; ≤′-weaken-osuc
292+
; ⊕-left-≤-sum
293+
; ⊕-mono-≤-right
294+
; ⊕-mono-<-right
287295
)
288296

289297
-- Recommended rank function for unbudgeted `wf-<ᵇʳᶠ_` per Echidna's

0 commit comments

Comments
 (0)