Ordinal notation #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
Constructive ordinal arithmetic for ordinals below ε₀.
We define a type onote, with constructors 0 : onote and onote.oadd e n a representing
ω ^ e * n + a.
We say that o is in Cantor normal form - onote.NF o - if either o = 0 or
o = ω ^ e * n + a with a < ω ^ e and a in Cantor normal form.
The type nonote is the type of ordinals below ε₀ in Cantor normal form.
Various operations (addition, subtraction, multiplication, power function)
are defined on onote and nonote.
Recursive definition of an ordinal notation. zero denotes the
ordinal 0, and oadd e n a is intended to refer to ω^e * n + a.
For this to be valid Cantor normal form, we must have the exponents
decrease to the right, but we can't state this condition until we've
defined repr, so it is a separate definition NF.
Instances for onote
Notation for 0
Equations
Equations
- onote.inhabited = {default := 0}
Equations
Equations
Convert a nat into an ordinal
Equations
- onote.of_nat n.succ = 0.oadd n.succ_pnat 0
- onote.of_nat 0 = 0
Instances for onote.of_nat
A normal form ordinal notation has the form
ω ^ a₁ * n₁ + ω ^ a₂ * n₂ + ... ω ^ aₖ * nₖ
where a₁ > a₂ > ... > aₖ and all the aᵢ are
also in normal form.
We will essentially only be interested in normal form ordinal notations, but to avoid complicating the algorithms we define everything over general ordinal notations and only prove correctness with normal form as an invariant.
Instances of this typeclass
Instances of other typeclasses for onote.NF
top_below b o asserts that the largest exponent in o, if
it exists, is less than b. This is an auxiliary definition
for decidability of NF.
Instances for onote.top_below
Equations
- onote.decidable_top_below = id (λ (b o : onote), o.cases_on (id decidable.true) (λ (o_ᾰ : onote) (o_ᾰ_1 : ℕ+) (o_ᾰ_2 : onote), id (ordering.decidable_eq (o_ᾰ.cmp b) ordering.lt)))
Equations
- onote.decidable_NF (e.oadd n a) = decidable_of_iff (onote.NF e ∧ onote.NF a ∧ e.top_below a) _
- onote.decidable_NF 0 = decidable.is_true onote.NF.zero
Addition of ordinal notations (correct only for normal input)
Equations
- (e.oadd n a).add o = onote.add._match_1 e n (a.add o)
- 0.add o = o
- onote.add._match_1 e n (e'.oadd n' a') = onote.add._match_2 e n e' n' a' (e.cmp e')
- onote.add._match_1 e n 0 = e.oadd n 0
- onote.add._match_2 e n e' n' a' ordering.gt = e.oadd n (e'.oadd n' a')
- onote.add._match_2 e n e' n' a' ordering.eq = e.oadd (n + n') a'
- onote.add._match_2 e n e' n' a' ordering.lt = e'.oadd n' a'
Equations
- onote.has_add = {add := onote.add}
Subtraction of ordinal notations (correct only for normal input)
Equations
- (e₁.oadd n₁ a₁).sub (e₂.oadd n₂ a₂) = onote.sub._match_1 e₁ n₁ a₁ n₂ (a₁.sub a₂) (e₁.cmp e₂)
- (ᾰ.oadd ᾰ_1 ᾰ_2).sub 0 = ᾰ.oadd ᾰ_1 ᾰ_2
- 0.sub (ᾰ.oadd ᾰ_1 ᾰ_2) = 0
- 0.sub onote.zero = 0
- onote.sub._match_1 e₁ n₁ a₁ n₂ _f_1 ordering.gt = e₁.oadd n₁ a₁
- onote.sub._match_1 e₁ n₁ a₁ n₂ _f_1 ordering.eq = onote.sub._match_2 e₁ n₁ a₁ n₂ _f_1 (↑n₁ - ↑n₂)
- onote.sub._match_1 e₁ n₁ a₁ n₂ _f_1 ordering.lt = 0
- onote.sub._match_2 e₁ n₁ a₁ n₂ _f_1 k.succ = e₁.oadd k.succ_pnat a₁
- onote.sub._match_2 e₁ n₁ a₁ n₂ _f_1 0 = ite (n₁ = n₂) _f_1 0
Equations
- onote.has_sub = {sub := onote.sub}
Multiplication of ordinal notations (correct only for normal input)
Equations
- onote.has_mul = {mul := onote.mul}
Equations
- onote.mul_zero_class = {mul := has_mul.mul onote.has_mul, zero := 0, zero_mul := onote.mul_zero_class._proof_1, mul_zero := onote.mul_zero_class._proof_2}
Auxiliary definition to compute the ordinal notation for the ordinal
exponentiation in opow
Equations
Instances for onote.opow_aux
opow o₁ o₂ calculates the ordinal notation for
the ordinal exponential o₁ ^ o₂.
Equations
- o₁.opow o₂ = onote.opow._match_1 o₂ o₁.split
- onote.opow._match_1 o₂ (a0.oadd _x _x_1, m) = onote.opow._match_3 a0 _x _x_1 m o₂.split
- onote.opow._match_1 o₂ (0, m + 1) = onote.opow._match_2 m o₂.split'
- onote.opow._match_1 o₂ (0, 1) = 1
- onote.opow._match_1 o₂ (0, 0) = ite (o₂ = 0) 1 0
- onote.opow._match_3 a0 _x _x_1 m (b, k + 1) = let eb : onote := a0 * b in (eb + a0.mul_nat k).scale (a0.oadd _x _x_1) + eb.opow_aux a0 ((a0.oadd _x _x_1).mul_nat m) k m
- onote.opow._match_3 a0 _x _x_1 m (b, 0) = (a0 * b).oadd 1 0
- onote.opow._match_2 m (b', k) = b'.oadd (m.succ_pnat ^ k) 0
Equations
- onote.has_pow = {pow := onote.opow}
Given an ordinal, returns inl none for 0, inl (some a) for a+1, and
inr f for a limit ordinal a, where f i is a sequence converging to a.
Equations
- (a.oadd m b).fundamental_sequence = onote.fundamental_sequence._match_1 a m a.fundamental_sequence b.fundamental_sequence
- onote.zero.fundamental_sequence = sum.inl option.none
- onote.fundamental_sequence._match_1 a m _f_1 (sum.inr f) = sum.inr (λ (i : ℕ), a.oadd m (f i))
- onote.fundamental_sequence._match_1 a m _f_1 (sum.inl (option.some b')) = sum.inl (option.some (a.oadd m b'))
- onote.fundamental_sequence._match_1 a m _f_1 (sum.inl option.none) = onote.fundamental_sequence._match_2 a _f_1 m.nat_pred
- onote.fundamental_sequence._match_2 a (sum.inr f) (m + 1) = sum.inr (λ (i : ℕ), a.oadd m.succ_pnat ((f i).oadd 1 onote.zero))
- onote.fundamental_sequence._match_2 a (sum.inr f) 0 = sum.inr (λ (i : ℕ), (f i).oadd 1 onote.zero)
- onote.fundamental_sequence._match_2 a (sum.inl (option.some a')) (m + 1) = sum.inr (λ (i : ℕ), a.oadd m.succ_pnat (a'.oadd i.succ_pnat onote.zero))
- onote.fundamental_sequence._match_2 a (sum.inl (option.some a')) 0 = sum.inr (λ (i : ℕ), a'.oadd i.succ_pnat onote.zero)
- onote.fundamental_sequence._match_2 a (sum.inl option.none) (m + 1) = sum.inl (option.some (onote.zero.oadd m.succ_pnat onote.zero))
- onote.fundamental_sequence._match_2 a (sum.inl option.none) 0 = sum.inl (option.some onote.zero)
The property satisfied by fundamental_sequence o:
inl nonemeanso = 0inl (some a)meanso = succ ainr fmeansois a limit ordinal andfis a strictly increasing sequence which converges too
Equations
- o.fundamental_sequence_prop (sum.inr f) = (o.repr.is_limit ∧ (∀ (i : ℕ), f i < f (i + 1) ∧ f i < o ∧ (onote.NF o → onote.NF (f i))) ∧ ∀ (a : ordinal), a < o.repr → (∃ (i : ℕ), a < (f i).repr))
- o.fundamental_sequence_prop (sum.inl (option.some a)) = (o.repr = order.succ a.repr ∧ (onote.NF o → onote.NF a))
- o.fundamental_sequence_prop (sum.inl option.none) = (o = 0)
The fast growing hierarchy for ordinal notations < ε₀. This is a sequence of
functions ℕ → ℕ indexed by ordinals, with the definition:
f_0(n) = n + 1f_(α+1)(n) = f_α^[n](n)f_α(n) = f_(α[n])(n)whereαis a limit ordinal andα[i]is the fundamental sequence converging toα
Equations
- o.fast_growing = onote.fast_growing._match_1 o (λ (a : onote) (h : o.fundamental_sequence_prop (sum.inl (option.some a))) (this : a < o), a.fast_growing) (λ (f : ℕ → onote) (h : o.fundamental_sequence_prop (sum.inr f)) (i : ℕ) (this : f i < o), (f i).fast_growing i) o.fundamental_sequence _
- onote.fast_growing._match_1 o _f_1 _f_2 (sum.inr f) h = λ (i : ℕ), have this : f i < o, from _, _f_2 f h i this
- onote.fast_growing._match_1 o _f_1 _f_2 (sum.inl (option.some a)) h = have this : a < o, from _, λ (i : ℕ), _f_1 a h this^[i] i
- onote.fast_growing._match_1 o _f_1 _f_2 (sum.inl option.none) _x = nat.succ
We can extend the fast growing hierarchy one more step to ε₀ itself,
using ω^(ω^...^ω^0) as the fundamental sequence converging to ε₀ (which is not an onote).
Extending the fast growing hierarchy beyond this requires a definition of fundamental sequence
for larger ordinals.
Equations
- onote.fast_growing_ε₀ i = ((λ (a : onote), a.oadd 1 0)^[i] 0).fast_growing i
Equations
- nonote.decidable_eq = nonote.decidable_eq._proof_1.mpr (λ (a b : {o // onote.NF o}), subtype.decidable_eq a b)
Equations
- nonote.has_zero = {zero := ⟨0, onote.NF.zero⟩}
Equations
- nonote.inhabited = {default := 0}
Equations
Convert a natural number to an ordinal notation
Equations
- nonote.of_nat n = ⟨onote.of_nat n, _⟩
This is a recursor-like theorem for nonote suggesting an
inductive definition, which can't actually be defined this
way due to conflicting dependencies.