Ordinal notation #
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, exponentiation)
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 a 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 we
make it a separate definition NF
.
Instances For
Notation for 0
Equations
- ONote.instZero = { zero := ONote.zero }
Notation for 1
Equations
- ONote.instOne = { one := ONote.oadd 0 1 0 }
The ordinal denoted by a notation
Equations
- ONote.zero.repr = 0
- (e.oadd n a).repr = Ordinal.omega0 ^ e.repr * ↑↑n + a.repr
Instances For
Print an ordinal notation
Equations
- ONote.zero.toString = "0"
- (e.oadd n ONote.zero).toString = ONote.toString_aux e (↑n) e.toString
- (e.oadd n a).toString = ONote.toString_aux e (↑n) e.toString ++ " + " ++ a.toString
Instances For
Print an ordinal notation
Equations
- One or more equations did not get rendered due to their size.
- ONote.repr' prec ONote.zero = Std.Format.text "0"
Instances For
Equations
- ONote.instToString = { toString := ONote.toString }
Equations
- ONote.instRepr = { reprPrec := fun (o : ONote) (prec : ℕ) => ONote.repr' prec o }
Equations
- ONote.instWellFoundedRelation = { rel := fun (x1 x2 : ONote) => x1 < x2, wf := ONote.instWellFoundedRelation.proof_1 }
Alias of ONote.omega0_le_oadd
.
Comparison of ordinal notations:
ω ^ e₁ * n₁ + a₁
is less than ω ^ e₂ * n₂ + a₂
when either e₁ < e₂
, or e₁ = e₂
and
n₁ < n₂
, or e₁ = e₂
, n₁ = n₂
, and a₁ < a₂
.
Equations
- ONote.zero.cmp ONote.zero = Ordering.eq
- x.cmp ONote.zero = Ordering.gt
- ONote.zero.cmp x = Ordering.lt
- (e₁.oadd n₁ a₁).cmp (e₂.oadd n₂ a₂) = (e₁.cmp e₂).then ((cmp ↑n₁ ↑n₂).then (a₁.cmp a₂))
Instances For
NFBelow o b
says that o
is a normal form ordinal notation satisfying repr o < ω ^ b
.
- zero: ∀ {b : Ordinal.{0}}, ONote.NFBelow 0 b
- oadd': ∀ {e : ONote} {n : ℕ+} {a : ONote} {eb b : Ordinal.{0}}, e.NFBelow eb → a.NFBelow e.repr → e.repr < b → (e.oadd n a).NFBelow b
Instances For
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.
- out : Exists o.NFBelow
Instances
Alias of ONote.NF.of_dvd_omega0_opow
.
Alias of ONote.NF.of_dvd_omega0
.
TopBelow 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
.
Equations
- b.TopBelow ONote.zero = True
- b.TopBelow (e.oadd n a) = (e.cmp b = Ordering.lt)
Instances For
Equations
- One or more equations did not get rendered due to their size.
Equations
- ONote.zero.decidableNF = isTrue ONote.NF.zero
- (e.oadd n a).decidableNF = decidable_of_iff (e.NF ∧ a.NF ∧ e.TopBelow a) ⋯
Auxiliary definition for add
Equations
- e.addAux n ONote.zero = e.oadd n 0
- e.addAux n (e'.oadd n' a') = match e.cmp e' with | Ordering.lt => e'.oadd n' a' | Ordering.eq => e.oadd (n + n') a' | Ordering.gt => e.oadd n (e'.oadd n' a')
Instances For
Subtraction of ordinal notations (correct only for normal input)
Equations
- One or more equations did not get rendered due to their size.
- ONote.zero.sub x = 0
- x.sub ONote.zero = x
Instances For
scale x o
is the ordinal notation for ω ^ x * o
.
Equations
- x.scale ONote.zero = 0
- x.scale (e.oadd n a) = (x + e).oadd n (x.scale a)
Instances For
Auxiliary definition to compute the ordinal notation for the ordinal exponentiation in opow
Equations
Instances For
Auxiliary definition to compute the ordinal notation for the ordinal exponentiation in opow
Equations
- One or more equations did not get rendered due to their size.
- o₂.opowAux2 (ONote.zero, 0) = if o₂ = 0 then 1 else 0
- o₂.opowAux2 (ONote.zero, 1) = 1
- o₂.opowAux2 (ONote.zero, m.succ) = match o₂.split' with | (b', k) => b'.oadd (m.succPNat ^ k) 0
Instances For
Equations
- ⋯ = ⋯
Given an ordinal, returns:
inl none
for0
inl (some a)
fora + 1
inr f
for a limit ordinala
, wheref i
is a sequence converging toa
Equations
- One or more equations did not get rendered due to their size.
- ONote.zero.fundamentalSequence = Sum.inl none
Instances For
The property satisfied by fundamentalSequence o
:
inl none
meanso = 0
inl (some a)
meanso = succ a
inr f
meanso
is a limit ordinal andf
is a strictly increasing sequence which converges too
Equations
- o.FundamentalSequenceProp (Sum.inl none) = (o = 0)
- o.FundamentalSequenceProp (Sum.inl (some a)) = (o.repr = Order.succ a.repr ∧ (o.NF → a.NF))
- o.FundamentalSequenceProp (Sum.inr f) = (o.repr.IsLimit ∧ (∀ (i : ℕ), f i < f (i + 1) ∧ f i < o ∧ (o.NF → (f i).NF)) ∧ ∀ a < o.repr, ∃ (i : ℕ), a < (f i).repr)
Instances For
The fast growing hierarchy for ordinal notations < ε₀
. This is a sequence of functions ℕ → ℕ
indexed by ordinals, with the definition:
f_0(n) = n + 1
f_(α + 1)(n) = f_α^[n](n)
f_α(n) = f_(α[n])(n)
whereα
is a limit ordinal andα[i]
is the fundamental sequence converging toα
Equations
- One or more equations did not get rendered due to their size.
Instances For
We can extend the fast growing hierarchy one more step to ε₀
itself, using ω ^ (ω ^ (⋯ ^ ω))
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.fastGrowingε₀ i = ((fun (a : ONote) => a.oadd 1 0)^[i] 0).fastGrowing i
Instances For
Equations
- instDecidableEqNONote = id inferInstance
The ordinal represented by an ordinal notation.
This function is noncomputable because ordinal arithmetic is noncomputable. In computational
applications NONote
can be used exclusively without reference to Ordinal
, but this function
allows for correctness results to be stated.
Equations
- o.repr = (↑o).repr
Instances For
Equations
- NONote.instToString = { toString := fun (x : NONote) => (↑x).toString }
Equations
- NONote.instRepr = { reprPrec := fun (x : NONote) (prec : ℕ) => ONote.repr' prec ↑x }
Equations
- NONote.instZero = { zero := ⟨0, ONote.NF.zero⟩ }
Equations
- NONote.instInhabited = { default := 0 }
Equations
- NONote.instWellFoundedRelation = { rel := fun (x1 x2 : NONote) => x1 < x2, wf := NONote.lt_wf }
Asserts that repr a < ω ^ repr b
. Used in NONote.recOn
.
Equations
- a.below b = (↑a).NFBelow b.repr
Instances For
This is a recursor-like theorem for NONote
suggesting an inductive definition, which can't
actually be defined this way due to conflicting dependencies.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Addition of ordinal notations
Equations
- NONote.instAdd = { add := fun (x y : NONote) => NONote.mk (↑x + ↑y) }
Subtraction of ordinal notations
Equations
- NONote.instSub = { sub := fun (x y : NONote) => NONote.mk (↑x - ↑y) }
Multiplication of ordinal notations
Equations
- NONote.instMul = { mul := fun (x y : NONote) => NONote.mk (↑x * ↑y) }