|
| 1 | +/- |
| 2 | +Copyright (c) 2024 Violeta Hernández Palacios. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Violeta Hernández Palacios |
| 5 | +-/ |
| 6 | +import Mathlib.SetTheory.Ordinal.FixedPoint |
| 7 | + |
| 8 | +/-! |
| 9 | +# Veblen hierarchy |
| 10 | +
|
| 11 | +We define the two-arguments Veblen function, which satisfies `veblen 0 a = ω ^ a` and that for |
| 12 | +`o ≠ 0`, `veblen o` enumerates the common fixed points of `veblen o'` for `o' < o`. |
| 13 | +
|
| 14 | +## Main definitions |
| 15 | +
|
| 16 | +* `veblenWith`: The Veblen hierarchy with a specified initial function. |
| 17 | +* `veblen`: The Veblen hierarchy starting with `ω ^ ·`. |
| 18 | +
|
| 19 | +## TODO |
| 20 | +
|
| 21 | +- Define the epsilon numbers and gamma numbers. |
| 22 | +- Prove that `ε₀` and `Γ₀` are countable. |
| 23 | +- Prove that the exponential principal ordinals are the epsilon ordinals (and 0, 1, 2, ω). |
| 24 | +- Prove that the ordinals principal under `veblen` are the gamma ordinals (and 0). |
| 25 | +-/ |
| 26 | + |
| 27 | +noncomputable section |
| 28 | + |
| 29 | +universe u |
| 30 | + |
| 31 | +namespace Ordinal |
| 32 | + |
| 33 | +variable {f : Ordinal.{u} → Ordinal.{u}} {o o₁ o₂ a b : Ordinal.{u}} |
| 34 | + |
| 35 | +/-! ### Veblen function with a given starting function -/ |
| 36 | + |
| 37 | +section veblenWith |
| 38 | + |
| 39 | +/-- `veblenWith f o` is the `o`-th function in the Veblen hierarchy starting with `f`. This is |
| 40 | +defined so that |
| 41 | +
|
| 42 | +- `veblenWith f 0 = f`. |
| 43 | +- `veblenWith f o` for `o ≠ 0` enumerates the common fixed points of `veblenWith f o'` over all |
| 44 | + `o' < o`. |
| 45 | +-/ |
| 46 | +@[pp_nodot] |
| 47 | +def veblenWith (f : Ordinal.{u} → Ordinal.{u}) (o : Ordinal.{u}) : Ordinal.{u} → Ordinal.{u} := |
| 48 | + if o = 0 then f else derivFamily fun (⟨x, _⟩ : Set.Iio o) ↦ veblenWith f x |
| 49 | +termination_by o |
| 50 | + |
| 51 | +@[simp] |
| 52 | +theorem veblenWith_zero (f : Ordinal → Ordinal) : veblenWith f 0 = f := by |
| 53 | + rw [veblenWith, if_pos rfl] |
| 54 | + |
| 55 | +theorem veblenWith_of_ne_zero (f : Ordinal → Ordinal) (h : o ≠ 0) : |
| 56 | + veblenWith f o = derivFamily fun x : Set.Iio o ↦ veblenWith f x.1 := by |
| 57 | + rw [veblenWith, if_neg h] |
| 58 | + |
| 59 | +/-- `veblenWith f o` is always normal for `o ≠ 0`. See `isNormal_veblenWith` for a version which |
| 60 | +assumes `IsNormal f`. -/ |
| 61 | +theorem isNormal_veblenWith' (f : Ordinal → Ordinal) (h : o ≠ 0) : IsNormal (veblenWith f o) := by |
| 62 | + rw [veblenWith_of_ne_zero f h] |
| 63 | + exact isNormal_derivFamily _ |
| 64 | + |
| 65 | +variable (hf : IsNormal f) |
| 66 | +include hf |
| 67 | + |
| 68 | +/-- `veblenWith f o` is always normal whenever `f` is. See `isNormal_veblenWith'` for a version |
| 69 | +which does not assume `IsNormal f`. -/ |
| 70 | +theorem isNormal_veblenWith (o : Ordinal) : IsNormal (veblenWith f o) := by |
| 71 | + obtain rfl | h := eq_or_ne o 0 |
| 72 | + · rwa [veblenWith_zero] |
| 73 | + · exact isNormal_veblenWith' f h |
| 74 | + |
| 75 | +protected alias IsNormal.veblenWith := isNormal_veblenWith |
| 76 | + |
| 77 | +theorem veblenWith_veblenWith_of_lt (h : o₁ < o₂) (a : Ordinal) : |
| 78 | + veblenWith f o₁ (veblenWith f o₂ a) = veblenWith f o₂ a := by |
| 79 | + let x : Set.Iio _ := ⟨o₁, h⟩ |
| 80 | + rw [veblenWith_of_ne_zero f h.bot_lt.ne', |
| 81 | + derivFamily_fp (f := fun y : Set.Iio o₂ ↦ veblenWith f y.1) (i := x)] |
| 82 | + exact hf.veblenWith x |
| 83 | + |
| 84 | +theorem veblenWith_succ (o : Ordinal) : veblenWith f (Order.succ o) = deriv (veblenWith f o) := by |
| 85 | + rw [deriv_eq_enumOrd (hf.veblenWith o), veblenWith_of_ne_zero f (succ_ne_zero _), |
| 86 | + derivFamily_eq_enumOrd] |
| 87 | + · apply congr_arg |
| 88 | + ext a |
| 89 | + rw [Set.mem_iInter] |
| 90 | + use fun ha ↦ ha ⟨o, Order.lt_succ o⟩ |
| 91 | + rintro (ha : _ = _) ⟨b, hb : b < _⟩ |
| 92 | + obtain rfl | hb := Order.lt_succ_iff_eq_or_lt.1 hb |
| 93 | + · rw [Function.mem_fixedPoints_iff, ha] |
| 94 | + · rw [← ha] |
| 95 | + exact veblenWith_veblenWith_of_lt hf hb _ |
| 96 | + · exact fun o ↦ hf.veblenWith o.1 |
| 97 | + |
| 98 | +theorem veblenWith_right_strictMono (o : Ordinal) : StrictMono (veblenWith f o) := |
| 99 | + (hf.veblenWith o).strictMono |
| 100 | + |
| 101 | +@[simp] |
| 102 | +theorem veblenWith_lt_veblenWith_iff_right : veblenWith f o a < veblenWith f o b ↔ a < b := |
| 103 | + (veblenWith_right_strictMono hf o).lt_iff_lt |
| 104 | + |
| 105 | +@[simp] |
| 106 | +theorem veblenWith_le_veblenWith_iff_right : veblenWith f o a ≤ veblenWith f o b ↔ a ≤ b := |
| 107 | + (veblenWith_right_strictMono hf o).le_iff_le |
| 108 | + |
| 109 | +theorem veblenWith_injective (o : Ordinal) : Function.Injective (veblenWith f o) := |
| 110 | + (veblenWith_right_strictMono hf o).injective |
| 111 | + |
| 112 | +@[simp] |
| 113 | +theorem veblenWith_inj : veblenWith f o a = veblenWith f o b ↔ a = b := |
| 114 | + (veblenWith_injective hf o).eq_iff |
| 115 | + |
| 116 | +theorem right_le_veblenWith (o a : Ordinal) : a ≤ veblenWith f o a := |
| 117 | + (veblenWith_right_strictMono hf o).le_apply |
| 118 | + |
| 119 | +theorem veblenWith_left_monotone (a : Ordinal) : Monotone (veblenWith f · a) := by |
| 120 | + rw [monotone_iff_forall_lt] |
| 121 | + intro o₁ o₂ h |
| 122 | + rw [← veblenWith_veblenWith_of_lt hf h] |
| 123 | + exact (veblenWith_right_strictMono hf o₁).monotone (right_le_veblenWith hf o₂ a) |
| 124 | + |
| 125 | +theorem veblenWith_pos (hp : 0 < f 0) : 0 < veblenWith f o a := by |
| 126 | + have H (b) : 0 < veblenWith f 0 b := by |
| 127 | + rw [veblenWith_zero] |
| 128 | + exact hp.trans_le (hf.monotone (Ordinal.zero_le _)) |
| 129 | + obtain rfl | h := Ordinal.eq_zero_or_pos o |
| 130 | + · exact H a |
| 131 | + · rw [← veblenWith_veblenWith_of_lt hf h] |
| 132 | + exact H _ |
| 133 | + |
| 134 | +theorem veblenWith_zero_strictMono (hp : 0 < f 0) : StrictMono (veblenWith f · 0) := by |
| 135 | + intro o₁ o₂ h |
| 136 | + dsimp only |
| 137 | + rw [← veblenWith_veblenWith_of_lt hf h, veblenWith_lt_veblenWith_iff_right hf] |
| 138 | + exact veblenWith_pos hf hp |
| 139 | + |
| 140 | +theorem veblenWith_zero_lt_veblenWith_zero (hp : 0 < f 0) : |
| 141 | + veblenWith f o₁ 0 < veblenWith f o₂ 0 ↔ o₁ < o₂ := |
| 142 | + (veblenWith_zero_strictMono hf hp).lt_iff_lt |
| 143 | + |
| 144 | +theorem veblenWith_zero_le_veblenWith_zero (hp : 0 < f 0) : |
| 145 | + veblenWith f o₁ 0 ≤ veblenWith f o₂ 0 ↔ o₁ ≤ o₂ := |
| 146 | + (veblenWith_zero_strictMono hf hp).le_iff_le |
| 147 | + |
| 148 | +theorem veblenWith_zero_inj (hp : 0 < f 0) : veblenWith f o₁ 0 = veblenWith f o₂ 0 ↔ o₁ = o₂ := |
| 149 | + (veblenWith_zero_strictMono hf hp).injective.eq_iff |
| 150 | + |
| 151 | +theorem left_le_veblenWith (hp : 0 < f 0) (o a : Ordinal) : o ≤ veblenWith f o a := |
| 152 | + (veblenWith_zero_strictMono hf hp).le_apply.trans <| |
| 153 | + (veblenWith_right_strictMono hf _).monotone (Ordinal.zero_le _) |
| 154 | + |
| 155 | +theorem IsNormal.veblenWith_zero (hp : 0 < f 0) : IsNormal (veblenWith f · 0) := by |
| 156 | + rw [isNormal_iff_strictMono_limit] |
| 157 | + refine ⟨veblenWith_zero_strictMono hf hp, fun o ho a IH ↦ ?_⟩ |
| 158 | + rw [veblenWith_of_ne_zero f ho.pos.ne', derivFamily_zero] |
| 159 | + apply nfpFamily_le fun l ↦ ?_ |
| 160 | + suffices ∃ b < o, List.foldr _ 0 l ≤ veblenWith f b 0 by |
| 161 | + obtain ⟨b, hb, hb'⟩ := this |
| 162 | + exact hb'.trans (IH b hb) |
| 163 | + induction l with |
| 164 | + | nil => use 0; simp [ho.pos] |
| 165 | + | cons a l IH => |
| 166 | + obtain ⟨b, hb, hb'⟩ := IH |
| 167 | + refine ⟨_, ho.succ_lt (max_lt a.2 hb), ((veblenWith_right_strictMono hf _).monotone <| |
| 168 | + hb'.trans <| veblenWith_left_monotone hf _ <| |
| 169 | + (le_max_right a.1 b).trans (Order.le_succ _)).trans ?_⟩ |
| 170 | + rw [veblenWith_veblenWith_of_lt hf] |
| 171 | + rw [Order.lt_succ_iff] |
| 172 | + exact le_max_left _ b |
| 173 | + |
| 174 | +theorem cmp_veblenWith : |
| 175 | + cmp (veblenWith f o₁ a) (veblenWith f o₂ b) = |
| 176 | + match cmp o₁ o₂ with |
| 177 | + | .eq => cmp a b |
| 178 | + | .lt => cmp a (veblenWith f o₂ b) |
| 179 | + | .gt => cmp (veblenWith f o₁ a) b := by |
| 180 | + obtain h | rfl | h := lt_trichotomy o₁ o₂ |
| 181 | + on_goal 2 => simp [(veblenWith_right_strictMono hf _).cmp_map_eq] |
| 182 | + all_goals |
| 183 | + conv_lhs => rw [← veblenWith_veblenWith_of_lt hf h] |
| 184 | + simp [h.cmp_eq_lt, h.cmp_eq_gt, h.ne, h.ne', (veblenWith_right_strictMono hf _).cmp_map_eq] |
| 185 | + |
| 186 | +/-- `veblenWith f o₁ a < veblenWith f o₂ b` iff one of the following holds: |
| 187 | +* `o₁ = o₂` and `a < b` |
| 188 | +* `o₁ < o₂` and `a < veblenWith f o₂ b` |
| 189 | +* `o₁ > o₂` and `veblenWith f o₁ a < b` -/ |
| 190 | +theorem veblenWith_lt_veblenWith_iff : |
| 191 | + veblenWith f o₁ a < veblenWith f o₂ b ↔ |
| 192 | + o₁ = o₂ ∧ a < b ∨ o₁ < o₂ ∧ a < veblenWith f o₂ b ∨ o₂ < o₁ ∧ veblenWith f o₁ a < b := by |
| 193 | + rw [← cmp_eq_lt_iff, cmp_veblenWith hf] |
| 194 | + aesop (add simp lt_asymm) |
| 195 | + |
| 196 | +/-- `veblenWith f o₁ a ≤ veblenWith f o₂ b` iff one of the following holds: |
| 197 | +* `o₁ = o₂` and `a ≤ b` |
| 198 | +* `o₁ < o₂` and `a ≤ veblenWith f o₂ b` |
| 199 | +* `o₁ > o₂` and `veblenWith f o₁ a ≤ b` -/ |
| 200 | +theorem veblenWith_le_veblenWith_iff : |
| 201 | + veblenWith f o₁ a ≤ veblenWith f o₂ b ↔ |
| 202 | + o₁ = o₂ ∧ a ≤ b ∨ o₁ < o₂ ∧ a ≤ veblenWith f o₂ b ∨ o₂ < o₁ ∧ veblenWith f o₁ a ≤ b := by |
| 203 | + rw [← not_lt, ← cmp_eq_gt_iff, cmp_veblenWith hf] |
| 204 | + aesop (add simp [not_lt_of_le, lt_asymm]) |
| 205 | + |
| 206 | +/-- `veblenWith f o₁ a = veblenWith f o₂ b` iff one of the following holds: |
| 207 | +* `o₁ = o₂` and `a = b` |
| 208 | +* `o₁ < o₂` and `a = veblenWith f o₂ b` |
| 209 | +* `o₁ > o₂` and `veblenWith f o₁ a = b` -/ |
| 210 | +theorem veblenWith_eq_veblenWith_iff : |
| 211 | + veblenWith f o₁ a = veblenWith f o₂ b ↔ |
| 212 | + o₁ = o₂ ∧ a = b ∨ o₁ < o₂ ∧ a = veblenWith f o₂ b ∨ o₂ < o₁ ∧ veblenWith f o₁ a = b := by |
| 213 | + rw [← cmp_eq_eq_iff, cmp_veblenWith hf] |
| 214 | + aesop (add simp lt_asymm) |
| 215 | + |
| 216 | +end veblenWith |
| 217 | + |
| 218 | +/-! ### Veblen function -/ |
| 219 | + |
| 220 | +section veblen |
| 221 | + |
| 222 | +/-- `veblen o` is the `o`-th function in the Veblen hierarchy starting with `ω ^ ·`. That is: |
| 223 | +
|
| 224 | +- `veblen 0 a = ω ^ a`. |
| 225 | +- `veblen o` for `o ≠ 0` enumerates the fixed points of `veblen o'` for `o' < o`. |
| 226 | +-/ |
| 227 | +@[pp_nodot] |
| 228 | +def veblen : Ordinal.{u} → Ordinal.{u} → Ordinal.{u} := |
| 229 | + veblenWith (ω ^ ·) |
| 230 | + |
| 231 | +@[simp] |
| 232 | +theorem veblen_zero : veblen 0 = fun a ↦ ω ^ a := by |
| 233 | + rw [veblen, veblenWith_zero] |
| 234 | + |
| 235 | +theorem veblen_zero_apply (a : Ordinal) : veblen 0 a = ω ^ a := by |
| 236 | + rw [veblen_zero] |
| 237 | + |
| 238 | +theorem veblen_of_ne_zero (h : o ≠ 0) : veblen o = derivFamily fun x : Set.Iio o ↦ veblen x.1 := |
| 239 | + veblenWith_of_ne_zero _ h |
| 240 | + |
| 241 | +theorem isNormal_veblen (o : Ordinal) : IsNormal (veblen o) := |
| 242 | + (isNormal_opow one_lt_omega0).veblenWith o |
| 243 | + |
| 244 | +theorem veblen_veblen_of_lt (h : o₁ < o₂) (a : Ordinal) : veblen o₁ (veblen o₂ a) = veblen o₂ a := |
| 245 | + veblenWith_veblenWith_of_lt (isNormal_opow one_lt_omega0) h a |
| 246 | + |
| 247 | +theorem veblen_succ (o : Ordinal) : veblen (Order.succ o) = deriv (veblen o) := |
| 248 | + veblenWith_succ (isNormal_opow one_lt_omega0) o |
| 249 | + |
| 250 | +theorem veblen_right_strictMono (o : Ordinal) : StrictMono (veblen o) := |
| 251 | + veblenWith_right_strictMono (isNormal_opow one_lt_omega0) o |
| 252 | + |
| 253 | +@[simp] |
| 254 | +theorem veblen_lt_veblen_iff_right : veblen o a < veblen o b ↔ a < b := |
| 255 | + veblenWith_lt_veblenWith_iff_right (isNormal_opow one_lt_omega0) |
| 256 | + |
| 257 | +@[simp] |
| 258 | +theorem veblen_le_veblen_iff_right : veblen o a ≤ veblen o b ↔ a ≤ b := |
| 259 | + veblenWith_le_veblenWith_iff_right (isNormal_opow one_lt_omega0) |
| 260 | + |
| 261 | +theorem veblen_injective (o : Ordinal) : Function.Injective (veblen o) := |
| 262 | + veblenWith_injective (isNormal_opow one_lt_omega0) o |
| 263 | + |
| 264 | +@[simp] |
| 265 | +theorem veblen_inj : veblen o a = veblen o b ↔ a = b := |
| 266 | + (veblen_injective o).eq_iff |
| 267 | + |
| 268 | +theorem right_le_veblen (o a : Ordinal) : a ≤ veblen o a := |
| 269 | + right_le_veblenWith (isNormal_opow one_lt_omega0) o a |
| 270 | + |
| 271 | +theorem veblen_left_monotone (o : Ordinal) : Monotone (veblen · o) := |
| 272 | + veblenWith_left_monotone (isNormal_opow one_lt_omega0) o |
| 273 | + |
| 274 | +@[simp] |
| 275 | +theorem veblen_pos : 0 < veblen o a := |
| 276 | + veblenWith_pos (isNormal_opow one_lt_omega0) (by simp) |
| 277 | + |
| 278 | +theorem veblen_zero_strictMono : StrictMono (veblen · 0) := |
| 279 | + veblenWith_zero_strictMono (isNormal_opow one_lt_omega0) (by simp) |
| 280 | + |
| 281 | +@[simp] |
| 282 | +theorem veblen_zero_lt_veblen_zero : veblen o₁ 0 < veblen o₂ 0 ↔ o₁ < o₂ := |
| 283 | + veblen_zero_strictMono.lt_iff_lt |
| 284 | + |
| 285 | +@[simp] |
| 286 | +theorem veblen_zero_le_veblen_zero : veblen o₁ 0 ≤ veblen o₂ 0 ↔ o₁ ≤ o₂ := |
| 287 | + veblen_zero_strictMono.le_iff_le |
| 288 | + |
| 289 | +@[simp] |
| 290 | +theorem veblen_zero_inj : veblen o₁ 0 = veblen o₂ 0 ↔ o₁ = o₂ := |
| 291 | + veblen_zero_strictMono.injective.eq_iff |
| 292 | + |
| 293 | +theorem left_le_veblen (o a : Ordinal) : o ≤ veblen o a := |
| 294 | + left_le_veblenWith (isNormal_opow one_lt_omega0) (by simp) o a |
| 295 | + |
| 296 | +theorem isNormal_veblen_zero : IsNormal (veblen · 0) := |
| 297 | + (isNormal_opow one_lt_omega0).veblenWith_zero (by simp) |
| 298 | + |
| 299 | +theorem cmp_veblen : cmp (veblen o₁ a) (veblen o₂ b) = |
| 300 | + match cmp o₁ o₂ with |
| 301 | + | .eq => cmp a b |
| 302 | + | .lt => cmp a (veblen o₂ b) |
| 303 | + | .gt => cmp (veblen o₁ a) b := |
| 304 | + cmp_veblenWith (isNormal_opow one_lt_omega0) |
| 305 | + |
| 306 | +/-- `veblen o₁ a < veblen o₂ b` iff one of the following holds: |
| 307 | +* `o₁ = o₂` and `a < b` |
| 308 | +* `o₁ < o₂` and `a < veblen o₂ b` |
| 309 | +* `o₁ > o₂` and `veblen o₁ a < b` -/ |
| 310 | +theorem veblen_lt_veblen_iff : |
| 311 | + veblen o₁ a < veblen o₂ b ↔ |
| 312 | + o₁ = o₂ ∧ a < b ∨ o₁ < o₂ ∧ a < veblen o₂ b ∨ o₂ < o₁ ∧ veblen o₁ a < b := |
| 313 | + veblenWith_lt_veblenWith_iff (isNormal_opow one_lt_omega0) |
| 314 | + |
| 315 | +/-- `veblen o₁ a ≤ veblen o₂ b` iff one of the following holds: |
| 316 | +* `o₁ = o₂` and `a ≤ b` |
| 317 | +* `o₁ < o₂` and `a ≤ veblen o₂ b` |
| 318 | +* `o₁ > o₂` and `veblen o₁ a ≤ b` -/ |
| 319 | +theorem veblen_le_veblen_iff : |
| 320 | + veblen o₁ a ≤ veblen o₂ b ↔ |
| 321 | + o₁ = o₂ ∧ a ≤ b ∨ o₁ < o₂ ∧ a ≤ veblen o₂ b ∨ o₂ < o₁ ∧ veblen o₁ a ≤ b := |
| 322 | + veblenWith_le_veblenWith_iff (isNormal_opow one_lt_omega0) |
| 323 | + |
| 324 | +/-- `veblen o₁ a ≤ veblen o₂ b` iff one of the following holds: |
| 325 | +* `o₁ = o₂` and `a = b` |
| 326 | +* `o₁ < o₂` and `a = veblen o₂ b` |
| 327 | +* `o₁ > o₂` and `veblen o₁ a = b` -/ |
| 328 | +theorem veblen_eq_veblen_iff : |
| 329 | + veblen o₁ a = veblen o₂ b ↔ |
| 330 | + o₁ = o₂ ∧ a = b ∨ o₁ < o₂ ∧ a = veblen o₂ b ∨ o₂ < o₁ ∧ veblen o₁ a = b := |
| 331 | + veblenWith_eq_veblenWith_iff (isNormal_opow one_lt_omega0) |
| 332 | + |
| 333 | +end veblen |
| 334 | +end Ordinal |
0 commit comments