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, 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
Notation for 0
Equations
- ONote.instZeroONote = { zero := ONote.zero }
Equations
- ONote.instInhabitedONote = { default := 0 }
Notation for 1
Equations
- ONote.instOneONote = { one := ONote.oadd 0 1 0 }
The ordinal denoted by a notation
Equations
- ONote.repr ONote.zero = 0
- ONote.repr (ONote.oadd e n a) = Ordinal.omega ^ ONote.repr e * ↑↑n + ONote.repr a
Instances For
Print an ordinal notation
Equations
- ONote.toString ONote.zero = "0"
- ONote.toString (ONote.oadd e n ONote.zero) = ONote.toStringAux1 e (↑n) (ONote.toString e)
- ONote.toString (ONote.oadd e n a) = ONote.toStringAux1 e (↑n) (ONote.toString e) ++ " + " ++ ONote.toString a
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.instToStringONote = { toString := ONote.toString }
Equations
- ONote.instReprONote = { reprPrec := fun (o : ONote) (prec : ℕ) => ONote.repr' prec o }
Equations
- ONote.instWellFoundedRelationONote = { rel := fun (x x_1 : ONote) => x < x_1, wf := ONote.instWellFoundedRelationONote.proof_1 }
Convert a Nat
into an ordinal
Equations
- ↑x = match x with | 0 => 0 | Nat.succ n => ONote.oadd 0 (Nat.succPNat n) 0
Instances For
Compare ordinal notations
Equations
- ONote.cmp ONote.zero ONote.zero = Ordering.eq
- ONote.cmp x ONote.zero = Ordering.gt
- ONote.cmp ONote.zero x = Ordering.lt
- ONote.cmp (ONote.oadd e₁ n₁ a₁) (ONote.oadd e₂ n₂ a₂) = Ordering.orElse (ONote.cmp e₁ e₂) (Ordering.orElse (cmp ↑n₁ ↑n₂) (ONote.cmp a₁ 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}}, ONote.NFBelow e eb → ONote.NFBelow a (ONote.repr e) → ONote.repr e < b → ONote.NFBelow (ONote.oadd e n a) 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 (ONote.NFBelow o)
Instances
Equations
- (_ : ONote.NF (ONote.oadd e n 0)) = (_ : ONote.NF (ONote.oadd e n 0))
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
- ONote.TopBelow b x = match x with | ONote.zero => True | ONote.oadd e a a_1 => ONote.cmp e b = Ordering.lt
Instances For
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
- ONote.decidableNF ONote.zero = isTrue ONote.NF.zero
Addition of ordinal notations (correct only for normal input)
Equations
- ONote.add ONote.zero x = x
- ONote.add (ONote.oadd e n a) x = ONote.addAux e n (ONote.add a x)
Instances For
Multiplication of ordinal notations (correct only for normal input)
Equations
- ONote.mul ONote.zero x = 0
- ONote.mul x ONote.zero = 0
- ONote.mul (ONote.oadd e₁ n₁ a₁) (ONote.oadd e₂ n₂ a₂) = if e₂ = 0 then ONote.oadd e₁ (n₁ * n₂) a₁ else ONote.oadd (e₁ + e₂) n₂ (ONote.mul (ONote.oadd e₁ n₁ a₁) a₂)
Instances For
Calculate division and remainder of o
mod ω.
split' o = (a, n)
means o = ω * a + n
.
Equations
- ONote.split' ONote.zero = (0, 0)
- ONote.split' (ONote.oadd e n a) = if e = 0 then (0, ↑n) else match ONote.split' a with | (a', m) => (ONote.oadd (e - 1) n a', m)
Instances For
Calculate division and remainder of o
mod ω.
split o = (a, n)
means o = a + n
, where ω ∣ a
.
Equations
- ONote.split ONote.zero = (0, 0)
- ONote.split (ONote.oadd e n a) = if e = 0 then (0, ↑n) else match ONote.split a with | (a', m) => (ONote.oadd e n a', m)
Instances For
scale x o
is the ordinal notation for ω ^ x * o
.
Equations
- ONote.scale x ONote.zero = 0
- ONote.scale x (ONote.oadd e n a) = ONote.oadd (x + e) n (ONote.scale x a)
Instances For
mulNat o n
is the ordinal notation for o * n
.
Equations
- ONote.mulNat x✝ x = match x✝, x with | ONote.zero, x => 0 | x, 0 => 0 | ONote.oadd e n a, Nat.succ m => ONote.oadd e (n * Nat.succPNat m) a
Instances For
Auxiliary definition to compute the ordinal notation for the ordinal
exponentiation in opow
Equations
- ONote.opowAux e a0 a x 0 = 0
- ONote.opowAux e a0 a 0 (Nat.succ m) = ONote.oadd e (Nat.succPNat m) 0
- ONote.opowAux e a0 a (Nat.succ k) x = ONote.scale (e + ONote.mulNat a0 k) a + ONote.opowAux e a0 a k x
Instances For
opow o₁ o₂
calculates the ordinal notation for
the ordinal exponential o₁ ^ o₂
.
Equations
- ONote.opow o₁ o₂ = ONote.opowAux2 o₂ (ONote.split o₁)
Instances For
Equations
- ONote.instPowONote = { pow := ONote.opow }
Equations
- (_ : ONote.NF (ONote.scale x o)) = (_ : ONote.NF (ONote.scale x o))
Equations
- (_ : ONote.NF (ONote.mulNat o n)) = (_ : ONote.NF (ONote.mulNat o n))
Equations
- (_ : ONote.NF (ONote.opowAux e a0 a k m)) = (_ : ONote.NF (ONote.opowAux e a0 a k m))
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
- One or more equations did not get rendered due to their size.
- ONote.fundamentalSequence ONote.zero = 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
- One or more equations did not get rendered due to their size.
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 ω^(ω^...^ω^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.
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
- NONote.repr o = ONote.repr ↑o
Instances For
Equations
- NONote.instToStringNONote = { toString := fun (x : NONote) => ONote.toString ↑x }
Equations
- NONote.instReprNONote = { reprPrec := fun (x : NONote) (prec : ℕ) => ONote.repr' prec ↑x }
Equations
- NONote.instZeroNONote = { zero := { val := 0, property := ONote.NF.zero } }
Equations
- NONote.instInhabitedNONote = { default := 0 }
Equations
- NONote.instWellFoundedLTNONoteToLTInstPreorderNONote = (_ : IsWellFounded NONote fun (x x_1 : NONote) => x < x_1)
Equations
- NONote.instWellFoundedRelationNONote = { rel := fun (x x_1 : NONote) => x < x_1, wf := NONote.lt_wf }
Convert a natural number to an ordinal notation
Equations
- NONote.ofNat n = { val := ↑n, property := (_ : ONote.NF ↑n) }
Instances For
Equations
- NONote.instIsWellOrderNONoteLtToLTInstPreorderNONote = (_ : IsWellOrder NONote fun (x x_1 : NONote) => x < x_1)
Asserts that repr a < ω ^ repr b
. Used in NONote.recOn
Equations
- NONote.below a b = ONote.NFBelow (↑a) (NONote.repr b)
Instances For
The oadd
pseudo-constructor for NONote
Equations
- NONote.oadd e n a h = { val := ONote.oadd (↑e) n ↑a, property := (_ : ONote.NF (ONote.oadd (↑e) n ↑a)) }
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.instAddNONote = { add := fun (x y : NONote) => NONote.mk (↑x + ↑y) }
Subtraction of ordinal notations
Equations
- NONote.instSubNONote = { sub := fun (x y : NONote) => NONote.mk (↑x - ↑y) }
Multiplication of ordinal notations
Equations
- NONote.instMulNONote = { mul := fun (x y : NONote) => NONote.mk (↑x * ↑y) }