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
921module Ordinal.Brouwer where
1022
11- open import Data.Empty using (⊥; ⊥-elim)
23+ open import Data.Empty using (⊥; ⊥-elim)
1224open import Data.Nat.Base using (ℕ; zero; suc)
13- open import Data.Product using (∃; _,_)
14- open import Data.Unit using (⊤; tt)
1525open import Induction.WellFounded using (Acc; acc; WellFounded; wf⇒asym)
1626open 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
3141infix 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
0 commit comments