@@ -31,17 +31,21 @@ The following notation is scoped to the `Ordinal` namespace.
3131- Prove that `ε₀` and `Γ₀` are countable.
3232- Prove that the exponential principal ordinals are the epsilon ordinals (and 0, 1, 2, ω).
3333- Prove that the ordinals principal under `veblen` are the gamma ordinals (and 0).
34+
35+ ## References
36+
37+ * [ Larry W. Miller, Normal functions and constructive ordinal notations ] [Miller_1976 ]
3438 -/
3539
3640noncomputable section
3741
38- open Order
42+ open Order Set
3943
4044universe u
4145
4246namespace Ordinal
4347
44- variable {f : Ordinal.{u} → Ordinal.{u}} {o o₁ o₂ a b : Ordinal.{u}}
48+ variable {f : Ordinal.{u} → Ordinal.{u}} {o o₁ o₂ a b x : Ordinal.{u}}
4549
4650/-! ### Veblen function with a given starting function -/
4751
@@ -56,15 +60,15 @@ defined so that
5660 -/
5761@[pp_nodot]
5862def veblenWith (f : Ordinal.{u} → Ordinal.{u}) (o : Ordinal.{u}) : Ordinal.{u} → Ordinal.{u} :=
59- if o = 0 then f else derivFamily fun (⟨x, _⟩ : Set. Iio o) ↦ veblenWith f x
63+ if o = 0 then f else derivFamily fun (⟨x, _⟩ : Iio o) ↦ veblenWith f x
6064termination_by o
6165
6266@[simp]
6367theorem veblenWith_zero (f : Ordinal → Ordinal) : veblenWith f 0 = f := by
6468 rw [veblenWith, if_pos rfl]
6569
6670theorem veblenWith_of_ne_zero (f : Ordinal → Ordinal) (h : o ≠ 0 ) :
67- veblenWith f o = derivFamily fun x : Set. Iio o ↦ veblenWith f x.1 := by
71+ veblenWith f o = derivFamily fun x : Iio o ↦ veblenWith f x.1 := by
6872 rw [veblenWith, if_neg h]
6973
7074/-- `veblenWith f o` is always normal for `o ≠ 0`. See `isNormal_veblenWith` for a version which
@@ -85,19 +89,34 @@ theorem isNormal_veblenWith (o : Ordinal) : IsNormal (veblenWith f o) := by
8589
8690protected alias IsNormal.veblenWith := isNormal_veblenWith
8791
92+ theorem mem_range_veblenWith (h : o ≠ 0 ) :
93+ a ∈ range (veblenWith f o) ↔ ∀ b < o, veblenWith f b a = a := by
94+ rw [veblenWith_of_ne_zero f h, mem_range_derivFamily (fun _ ↦ isNormal_veblenWith hf _)]
95+ exact Subtype.forall
96+
8897theorem veblenWith_veblenWith_of_lt (h : o₁ < o₂) (a : Ordinal) :
8998 veblenWith f o₁ (veblenWith f o₂ a) = veblenWith f o₂ a := by
90- let x : Set.Iio _ := ⟨o₁, h⟩
91- rw [veblenWith_of_ne_zero f h.bot_lt.ne',
92- derivFamily_fp (f := fun y : Set.Iio o₂ ↦ veblenWith f y.1 ) (i := x)]
93- exact hf.veblenWith x
99+ apply (mem_range_veblenWith hf h.ne_bot).1 _ _ h
100+ simp
101+
102+ theorem veblenWith_eq_self_of_le (h : o₁ ≤ o₂) (h' : veblenWith f o₂ a = a) :
103+ veblenWith f o₁ a = a := by
104+ obtain rfl | h := h.eq_or_lt
105+ · assumption
106+ · rw [← h', veblenWith_veblenWith_of_lt hf h]
107+
108+ theorem veblenWith_mem_range : veblenWith f o a ∈ range f := by
109+ obtain rfl | h := eq_zero_or_pos o
110+ · simp
111+ · rw [← veblenWith_veblenWith_of_lt hf h]
112+ simp
94113
95114theorem veblenWith_succ (o : Ordinal) : veblenWith f (succ o) = deriv (veblenWith f o) := by
96115 rw [deriv_eq_enumOrd (hf.veblenWith o), veblenWith_of_ne_zero f (succ_ne_zero _),
97116 derivFamily_eq_enumOrd]
98117 · apply congr_arg
99118 ext a
100- rw [Set. mem_iInter]
119+ rw [mem_iInter]
101120 use fun ha ↦ ha ⟨o, lt_succ o⟩
102121 rintro (ha : _ = _) ⟨b, hb : b < _⟩
103122 obtain rfl | hb := lt_succ_iff_eq_or_lt.1 hb
@@ -137,7 +156,7 @@ theorem veblenWith_pos (hp : 0 < f 0) : 0 < veblenWith f o a := by
137156 have H (b) : 0 < veblenWith f 0 b := by
138157 rw [veblenWith_zero]
139158 exact hp.trans_le (hf.monotone (Ordinal.zero_le _))
140- obtain rfl | h := Ordinal. eq_zero_or_pos o
159+ obtain rfl | h := eq_zero_or_pos o
141160 · exact H a
142161 · rw [← veblenWith_veblenWith_of_lt hf h]
143162 exact H _
@@ -182,6 +201,21 @@ theorem IsNormal.veblenWith_zero (hp : 0 < f 0) : IsNormal (veblenWith f · 0) :
182201 rw [lt_succ_iff]
183202 exact le_max_left _ b
184203
204+ theorem veblenWith_veblenWith_eq_veblenWith_iff (h : o₂ ≤ o₁) :
205+ veblenWith f o₁ (veblenWith f o₂ a) = veblenWith f o₂ a ↔ veblenWith f o₁ a = a := by
206+ grind [veblenWith_inj, → veblenWith_eq_self_of_le]
207+
208+ theorem veblenWith_lt_veblenWith_veblenWith_iff (h : o₂ ≤ o₁) :
209+ veblenWith f o₂ a < veblenWith f o₁ (veblenWith f o₂ a) ↔ a < veblenWith f o₁ a := by
210+ simp_rw [(right_le_veblenWith hf ..).lt_iff_ne', ne_eq,
211+ veblenWith_veblenWith_eq_veblenWith_iff hf h]
212+
213+ theorem veblenWith_apply_eq_apply_iff : veblenWith f o (f a) = f a ↔ veblenWith f o a = a := by
214+ simpa using veblenWith_veblenWith_eq_veblenWith_iff hf (zero_le o)
215+
216+ theorem apply_lt_veblenWith_apply_iff : f a < veblenWith f o (f a) ↔ a < veblenWith f o a := by
217+ simpa using veblenWith_lt_veblenWith_veblenWith_iff hf (zero_le o)
218+
185219theorem cmp_veblenWith :
186220 cmp (veblenWith f o₁ a) (veblenWith f o₂ b) =
187221 match cmp o₁ o₂ with
@@ -246,15 +280,24 @@ theorem veblen_zero : veblen 0 = fun a ↦ ω ^ a := by
246280theorem veblen_zero_apply (a : Ordinal) : veblen 0 a = ω ^ a := by
247281 rw [veblen_zero]
248282
249- theorem veblen_of_ne_zero (h : o ≠ 0 ) : veblen o = derivFamily fun x : Set. Iio o ↦ veblen x.1 :=
283+ theorem veblen_of_ne_zero (h : o ≠ 0 ) : veblen o = derivFamily fun x : Iio o ↦ veblen x.1 :=
250284 veblenWith_of_ne_zero _ h
251285
252286theorem isNormal_veblen (o : Ordinal) : IsNormal (veblen o) :=
253287 (isNormal_opow one_lt_omega0).veblenWith o
254288
289+ theorem mem_range_veblen (h : o ≠ 0 ) : a ∈ range (veblen o) ↔ ∀ b < o, veblen b a = a :=
290+ mem_range_veblenWith (isNormal_opow one_lt_omega0) h
291+
255292theorem veblen_veblen_of_lt (h : o₁ < o₂) (a : Ordinal) : veblen o₁ (veblen o₂ a) = veblen o₂ a :=
256293 veblenWith_veblenWith_of_lt (isNormal_opow one_lt_omega0) h a
257294
295+ theorem veblen_eq_self_of_le (h : o₁ ≤ o₂) (h' : veblen o₂ a = a) : veblen o₁ a = a :=
296+ veblenWith_eq_self_of_le (isNormal_opow one_lt_omega0) h h'
297+
298+ theorem veblen_mem_range_opow (o a : Ordinal) : veblen o a ∈ range (ω ^ · : Ordinal → Ordinal) :=
299+ veblenWith_mem_range (isNormal_opow one_lt_omega0)
300+
258301theorem veblen_succ (o : Ordinal) : veblen (succ o) = deriv (veblen o) :=
259302 veblenWith_succ (isNormal_opow one_lt_omega0) o
260303
@@ -307,6 +350,26 @@ theorem left_le_veblen (o a : Ordinal) : o ≤ veblen o a :=
307350theorem isNormal_veblen_zero : IsNormal (veblen · 0 ) :=
308351 (isNormal_opow one_lt_omega0).veblenWith_zero (by simp)
309352
353+ theorem veblen_veblen_eq_veblen_iff (h : o₂ ≤ o₁) :
354+ veblen o₁ (veblen o₂ a) = veblen o₂ a ↔ veblen o₁ a = a :=
355+ veblenWith_veblenWith_eq_veblenWith_iff (isNormal_opow one_lt_omega0) h
356+
357+ theorem veblen_lt_veblen_veblen_iff (h : o₂ ≤ o₁) :
358+ veblen o₂ a < veblen o₁ (veblen o₂ a) ↔ a < veblen o₁ a :=
359+ veblenWith_lt_veblenWith_veblenWith_iff (isNormal_opow one_lt_omega0) h
360+
361+ theorem veblen_opow_eq_opow_iff : veblen o (ω ^ a) = ω ^ a ↔ veblen o a = a :=
362+ veblenWith_apply_eq_apply_iff (isNormal_opow one_lt_omega0)
363+
364+ theorem opow_lt_veblen_opow_iff : ω ^ a < veblen o (ω ^ a) ↔ a < veblen o a :=
365+ apply_lt_veblenWith_apply_iff (isNormal_opow one_lt_omega0)
366+
367+ theorem lt_veblen (a : Ordinal) : a < veblen a a := by
368+ obtain rfl | h := eq_zero_or_pos a
369+ · simp
370+ · apply (left_le_veblen a 0 ).trans_lt
371+ simpa
372+
310373theorem cmp_veblen : cmp (veblen o₁ a) (veblen o₂ b) =
311374 match cmp o₁ o₂ with
312375 | .eq => cmp a b
@@ -343,6 +406,119 @@ theorem veblen_eq_veblen_iff :
343406
344407end veblen
345408
409+ /-! ### Inverse Veblen function -/
410+
411+ /-- For any given `x`, there exists a unique pair `(o, a)` such that `ω ^ x = veblen o a` and
412+ `a < ω ^ x`. `invVeblen₁ x` and `invVeblen₂ x` return the first and second entries of this pair,
413+ respectively. See `veblen_eq_opow_iff` for a proof.
414+
415+ Composing this function with `Ordinal.CNF` yields a predicative ordinal notation up to `Γ₀`. -/
416+ def invVeblen₁ (x : Ordinal) : Ordinal :=
417+ sInf {y | veblen y x ≠ x}
418+
419+ theorem veblen_eq_of_lt_invVeblen₁ (h : o < invVeblen₁ x) : veblen o x = x := by
420+ simpa using notMem_of_lt_csInf' h
421+
422+ theorem invVeblen₁_le (x : Ordinal) : invVeblen₁ x ≤ x :=
423+ csInf_le' (lt_veblen x).ne'
424+
425+ theorem lt_veblen_invVeblen₁ (x : Ordinal) : x < veblen (invVeblen₁ x) x :=
426+ (right_le_veblen ..).lt_of_ne' (csInf_mem (s := {y | veblen y x ≠ x}) ⟨x, (lt_veblen x).ne'⟩)
427+
428+ theorem lt_veblen_iff_invVeblen₁_le : a < veblen o a ↔ invVeblen₁ a ≤ o := by
429+ obtain h | h := lt_or_ge o (invVeblen₁ a)
430+ · rw [veblen_eq_of_lt_invVeblen₁ h]
431+ simpa
432+ · simpa [(lt_veblen_invVeblen₁ a).trans_le (veblen_left_monotone _ h)]
433+
434+ theorem mem_range_veblen_iff_le_invVeblen₁ : ω ^ x ∈ range (veblen o) ↔ o ≤ invVeblen₁ x := by
435+ obtain h | rfl | h := lt_trichotomy o (invVeblen₁ x)
436+ · exact iff_of_true ⟨_, veblen_opow_eq_opow_iff.2 <| veblen_eq_of_lt_invVeblen₁ h⟩ h.le
437+ · apply iff_of_true _ le_rfl
438+ by_cases h : invVeblen₁ x = 0
439+ · simp [h]
440+ · simp_rw [mem_range_veblen h, veblen_opow_eq_opow_iff]
441+ exact fun o ↦ veblen_eq_of_lt_invVeblen₁
442+ · apply iff_of_false _ h.not_ge
443+ rintro ⟨z, hz⟩
444+ have hz' := hz
445+ rw [← veblen_veblen_of_lt h, hz', veblen_opow_eq_opow_iff] at hz
446+ exact (lt_veblen_invVeblen₁ x).ne' hz
447+
448+ theorem invVeblen₁_veblen (h : a < veblen o a) : invVeblen₁ (veblen o a) = o := by
449+ apply le_antisymm
450+ · rwa [← lt_veblen_iff_invVeblen₁_le, veblen_lt_veblen_iff_right]
451+ · rw [← mem_range_veblen_iff_le_invVeblen₁]
452+ obtain rfl | ho := eq_zero_or_pos o
453+ · simp
454+ · rw [← veblen_zero_apply, veblen_veblen_of_lt ho]
455+ simp
456+
457+ theorem invVeblen₁_of_lt_opow (h : a < ω ^ a) : invVeblen₁ a = 0 := by
458+ rwa [← Ordinal.le_zero, ← lt_veblen_iff_invVeblen₁_le, veblen_zero]
459+
460+ @[simp]
461+ theorem invVeblen₁_zero : invVeblen₁ 0 = 0 :=
462+ invVeblen₁_of_lt_opow <| by simp
463+
464+ @[inherit_doc invVeblen₁]
465+ def invVeblen₂ (x : Ordinal) : Ordinal :=
466+ Classical.choose ((mem_range_veblen_iff_le_invVeblen₁ (x := x)).2 le_rfl)
467+
468+ @[simp]
469+ theorem veblen_invVeblen₁_invVeblen₂ (x : Ordinal) : veblen (invVeblen₁ x) (invVeblen₂ x) = ω ^ x :=
470+ Classical.choose_spec (mem_range_veblen_iff_le_invVeblen₁.2 le_rfl)
471+
472+ theorem invVeblen₂_eq_iff : invVeblen₂ x = a ↔ ω ^ x = veblen (invVeblen₁ x) a := by
473+ rw [← veblen_inj (o := x.invVeblen₁), veblen_invVeblen₁_invVeblen₂]
474+
475+ theorem invVeblen₂_lt_iff : invVeblen₂ x < a ↔ ω ^ x < veblen (invVeblen₁ x) a := by
476+ rw [← veblen_lt_veblen_iff_right (o := x.invVeblen₁), veblen_invVeblen₁_invVeblen₂]
477+
478+ theorem invVeblen₂_le_iff : invVeblen₂ x ≤ a ↔ ω ^ x ≤ veblen (invVeblen₁ x) a := by
479+ rw [← veblen_le_veblen_iff_right (o := x.invVeblen₁), veblen_invVeblen₁_invVeblen₂]
480+
481+ theorem lt_invVeblen₂_iff : a < invVeblen₂ x ↔ veblen (invVeblen₁ x) a < ω ^ x := by
482+ rw [← veblen_lt_veblen_iff_right (o := x.invVeblen₁), veblen_invVeblen₁_invVeblen₂]
483+
484+ theorem le_invVeblen₂_iff : a ≤ invVeblen₂ x ↔ veblen (invVeblen₁ x) a ≤ ω ^ x := by
485+ rw [← veblen_le_veblen_iff_right (o := x.invVeblen₁), veblen_invVeblen₁_invVeblen₂]
486+
487+ theorem invVeblen₂_lt (x : Ordinal) : invVeblen₂ x < ω ^ x := by
488+ rw [invVeblen₂_lt_iff, opow_lt_veblen_opow_iff]
489+ exact lt_veblen_invVeblen₁ x
490+
491+ theorem invVeblen₂_le (x : Ordinal) : invVeblen₂ x ≤ x := by
492+ obtain h | h := eq_zero_or_pos (invVeblen₁ x)
493+ · rw [invVeblen₂_le_iff, h, veblen_zero]
494+ · convert (invVeblen₂_lt x).le
495+ rw [← veblen_zero_apply, veblen_eq_of_lt_invVeblen₁ h]
496+
497+ theorem invVeblen₂_of_lt_opow (h : a < ω ^ a) : invVeblen₂ a = a := by
498+ rw [invVeblen₂_eq_iff, invVeblen₁_of_lt_opow h, veblen_zero_apply]
499+
500+ @[simp]
501+ theorem invVeblen₂_zero : invVeblen₂ 0 = 0 := by
502+ apply invVeblen₂_of_lt_opow
503+ simp
504+
505+ theorem invVeblen₂_veblen (ho : o ≠ 0 ) (h : a < veblen o a) : invVeblen₂ (veblen o a) = a := by
506+ rw [invVeblen₂_eq_iff, invVeblen₁_veblen h, ← veblen_zero_apply, veblen_veblen_of_lt]
507+ exact ho.bot_lt
508+
509+ theorem veblen_eq_opow_iff (h : a < veblen o a) :
510+ veblen o a = ω ^ x ↔ invVeblen₁ x = o ∧ invVeblen₂ x = a := by
511+ refine ⟨?_, fun ⟨hx, ha⟩ ↦ ?_⟩
512+ · obtain rfl | ho := eq_zero_or_pos o
513+ · rw [veblen_zero] at h
514+ have := invVeblen₁_of_lt_opow h
515+ have := invVeblen₂_of_lt_opow h
516+ aesop
517+ · rw [← veblen_veblen_of_lt ho, veblen_zero_apply, opow_right_inj one_lt_omega0]
518+ rintro rfl
519+ simp [invVeblen₁_veblen h, invVeblen₂_veblen ho.ne' h]
520+ · convert ← veblen_invVeblen₁_invVeblen₂ x
521+
346522/-! ### Epsilon function -/
347523
348524/-- The epsilon function enumerates the fixed points of `ω ^ ⬝`.
@@ -391,13 +567,19 @@ theorem natCast_lt_epsilon (n : ℕ) (o : Ordinal) : n < ε_ o :=
391567theorem epsilon_pos (o : Ordinal) : 0 < ε_ o :=
392568 veblen_pos
393569
570+ theorem invVeblen₁_epsilon (h : o < ε_ o) : invVeblen₁ (ε_ o) = 1 :=
571+ invVeblen₁_veblen h
572+
573+ theorem invVeblen₂_epsilon (h : o < ε_ o) : invVeblen₂ (ε_ o) = o :=
574+ invVeblen₂_veblen one_ne_zero h
575+
394576/-! ### Gamma function -/
395577
396578/-- The gamma function enumerates the fixed points of `veblen · 0`.
397579
398580Of particular importance is `Γ₀ = gamma 0`, the Feferman-Schütte ordinal. -/
399- def gamma (o : Ordinal) : Ordinal :=
400- deriv (veblen · 0 ) o
581+ def gamma : Ordinal → Ordinal :=
582+ deriv (veblen · 0 )
401583
402584@[inherit_doc]
403585scoped notation "Γ_ " => gamma
@@ -409,6 +591,9 @@ scoped notation "Γ₀" => Γ_ 0
409591theorem isNormal_gamma : IsNormal gamma :=
410592 isNormal_deriv _
411593
594+ theorem mem_range_gamma : o ∈ range Γ_ ↔ veblen o 0 = o :=
595+ isNormal_veblen_zero.mem_range_deriv
596+
412597theorem strictMono_gamma : StrictMono gamma :=
413598 isNormal_gamma.strictMono
414599
@@ -465,4 +650,28 @@ theorem natCast_lt_gamma (n : ℕ) : n < Γ_ o :=
465650theorem gamma_pos : 0 < Γ_ o :=
466651 natCast_lt_gamma 0
467652
653+ @[simp]
654+ theorem gamma_ne_zero : Γ_ o ≠ 0 :=
655+ gamma_pos.ne'
656+
657+ @[simp]
658+ theorem invVeblen₁_gamma (o : Ordinal) : invVeblen₁ (Γ_ o) = Γ_ o := by
659+ rw [← veblen_gamma_zero, invVeblen₁_veblen veblen_pos, veblen_gamma_zero]
660+
661+ @[simp]
662+ theorem invVeblen₂_gamma (o : Ordinal) : invVeblen₂ (Γ_ o) = 0 := by
663+ rw [← veblen_gamma_zero, invVeblen₂_veblen gamma_ne_zero veblen_pos]
664+
665+ theorem invVeblen₁_eq_iff : invVeblen₁ o = o ↔ o = 0 ∨ o ∈ range Γ_ := by
666+ constructor
667+ · rw [mem_range_gamma, or_iff_not_imp_left]
668+ refine fun h ho ↦ (left_le_veblen ..).antisymm' ?_
669+ conv_rhs => rw [← veblen_eq_of_lt_invVeblen₁ (h.trans_ne ho).bot_lt, bot_eq_zero,
670+ veblen_zero_apply, ← veblen_invVeblen₁_invVeblen₂, h]
671+ simp
672+ · aesop
673+
674+ theorem invVeblen₁_lt_iff : invVeblen₁ o < o ↔ o ≠ 0 ∧ o ∉ range Γ_ := by
675+ rw [(invVeblen₁_le o).lt_iff_ne, ne_eq, invVeblen₁_eq_iff, not_or]
676+
468677end Ordinal
0 commit comments