module ordinals where
Ordinals in type theory.
(ii) Hancock (Russell'08 Proof Theory meets Type Theory, Swansea)
Church encodings of ordinals, and simulation of ordinal functions.
An interesting and powerful idea is their use of "lenses", which
allows to define rather large ordinals, in particular in the
presence of dependent types and universes. Another idea is to use
Church encodings of ordinals.
Here I do something more modest, without lenses, but still with
Church encodings. I explicitly define addition, multiplication and
exponentiation of ordinals, and there may be a small contribution
here.
In the Goedel system T fragment of Agda, these arithmetic
operations cannot be uniformly typed, but they still have neat
definitions. In particular, because of the non-uniform typing, we
can only dominate ordinals strictly below ε₀ - this is not a
limitation of our approach, but rather of system T.
Using dependent types (products in fact will be enough) and a
universe, we can get a uniform typing of the arithmetic
operations, and hence the ordinal ε₀ and much higher indeed. But I
will content myself with defining ε₀, which is not definable in
system T, as an illustration of what dependent types and universes
add in terms of expressivity. But it is easy to get higher using
what is defined here. If you want to get really high, then you
should study lenses: see Peter Hancock's web page.
We proceed in three steps to define addition, multiplication and
exponentiation, and hence ε₀ and much higher.
(1): We essentially use Goedel's system T and work with a type
O X = X → (X → X) → ((ℕ → X) → X) → X
of Church encodings of ordinal trees, where X is a parameter,
and define the basic arithmetic operations on ordinals with
the non-uniform types
add : O X → O X → O X
mul : O X → O(O X) → O X
exp : O(O X) → O(O X) → O X
These types are the best one can do in system T. With this we
can define ordinals abitrarily close to, and strictly below,
the ordinal ε₀.
(2): We use the first universe and dependent products to define
O' X = Π(n : ℕ) → Oⁿ⁺¹ X
and hence the arithmetic operations with uniform types
add', mul', exp' : O' X → O' X → O' X
from add, mul, exp defined in step (1). With this we can now
define ε₀, not only in O' X, but also in O X.
So you can see the type O' X as an auxiliary construction to
get more in O X.
(3): We inductively define a (standard) W-type of ordinal trees
(e.g. studied by Brouwer, by Howard in an extension of system T,
and mentioned by Martin-Loef in some of his papers), and show how
to define complex Brouwer ordinal trees *without* using
(structural) recursion on ordinals trees, using step (2).
All (primitive) recursions in the development of (1)-(3) are on
the set ℕ. This is followed by exercises, now using recursion and
induction on Brouwer ordinal trees.
--}
data ℕ : Set where
zero : ℕ
succ : ℕ → ℕ
rec : {X : Set} → X → (X → X) → (ℕ → X)
rec x f zero = x
rec x f (succ n) = f(rec x f n)
O : Set → Set
O X = X → (X → X) → ((ℕ → X) → X) → X
zer : {X : Set} → O X
zer = λ z → λ s → λ l → z
suc : {X : Set} → O X → O X
suc a = λ z → λ s → λ l → s(a z s l)
lim : {X : Set} → (ℕ → O X) → O X
lim as = λ z → λ s → λ l → l(λ i → as i z s l)
O-rec : {X : Set} → X → (X → X) → ((ℕ → X) → X) → O X → X
O-rec z s l x = x z s l
add : {X : Set} → O X → O X → O X
add a b = λ z → λ s → λ l → a (b z s l) s l
mul : {X : Set} → O X → O(O X) → O X
mul a = O-rec zer (λ r → add r a) lim
exp : {X : Set} → O(O X) → O(O X) → O X
exp a = O-rec (suc zer) (λ r → mul r a) lim
down : {X : Set} → O(O X) → O X
down = O-rec zer suc lim
finite : {X : Set} → ℕ → O X
finite = rec zer suc
ω : {X : Set} → O X
ω = lim finite
ω₁ : {X : Set} → O X
ω₁ = exp ω ω
ω₂ : {X : Set} → O X
ω₂ = exp ω ω₁
ω₃ : {X : Set} → O X
ω₃ = exp ω ω₂
step : {X : Set} → O(O X) → O X
step = exp ω
rec₁ : Set → (Set → Set) → ℕ → Set
rec₁ X F zero = X
rec₁ X F (succ n) = F(rec₁ X F n)
O' : Set → Set
O' X = (n : ℕ) → O(rec₁ X O n)
zer' : {X : Set} → O' X
zer' = λ n → zer
suc' : {X : Set} → O' X → O' X
suc' a = λ n → suc(a n)
lim' : {X : Set} → (ℕ → O' X) → O' X
lim' as = λ n → lim(λ i → as i n)
add' : {X : Set} → O' X → O' X → O' X
add' a b = λ n → add (a n) (b n)
mul' : {X : Set} → O' X → O' X → O' X
mul' a b = λ n → mul (a n) (b(succ n))
exp' : {X : Set} → O' X → O' X → O' X
exp' a b = λ n → exp (a(succ n)) (b(succ n))
ω' : {X : Set} → O' X
ω' = λ n → ω
ω-tower' : {X : Set} → ℕ → O' X
ω-tower' = rec ω' (exp' ω')
ε₀' : {X : Set} → O' X
ε₀' = lim' ω-tower'
O'↦O : {X : Set} → O' X → O X
O'↦O a = a zero
ε₀ : {X : Set} → O X
ε₀ = O'↦O ε₀'
data B : Set where
Z : B
S : B → B
L : (ℕ → B) → B
O↦B : O B → B
O↦B u = u Z S L
B-ε₀ : B
B-ε₀ = O↦B ε₀
B-rec : {X : Set} → X → (X → X) → ((ℕ → X) → X) → B → X
B-rec {X} z s l = h
where
h : B → X
h Z = z
h(S u) = s(h u)
h(L us) = l(λ i → h(us i))
B↦O : {X : Set} → B → O X
B↦O u s z l = B-rec s z l u
B-add : B → B → B
B-add u = B-rec u S L
B-mul : B → B → B
B-mul u = B-rec Z (λ r → B-add r u) L
B-exp : B → B → B
B-exp u = B-rec (S Z) (λ r → B-mul r u) L
B-finite : ℕ → B
B-finite = rec Z S
B-ω : B
B-ω = L B-finite
B-ω-tower : ℕ → B
B-ω-tower = rec B-ω (B-exp B-ω)
B-ε₀-alternative : B
B-ε₀-alternative = L B-ω-tower
data _≣_ : B → B → Set where
≣-Z : Z ≣ Z
≣-S : ∀(u v : B) → u ≣ v → S u ≣ S v
≣-L : ∀(us vs : ℕ → B) → (∀(i : ℕ) → us i ≣ vs i) → L us ≣ L vs
postulate Exercise₀ : B-ε₀ ≣ B-ε₀-alternative
postulate Exercise₁ : ∀(u v : B) → B-add u v ≣ O↦B(add (B↦O u) (B↦O v))
postulate Exercise₂ : ∀(u v : B) → B-mul u v ≣ O↦B(mul (B↦O u) (B↦O v))
postulate Exercise₃ : ∀(u v : B) → B-exp u v ≣ O↦B(exp (B↦O u) (B↦O v))
B↦O' : {X : Set} → B → O' X
B↦O' u = λ n → B↦O u
O'↦B : O' B → B
O'↦B a = O↦B(O'↦O a)
postulate Exercise₁' : ∀(u v : B) → B-add u v ≣ O'↦B(add' (B↦O' u) (B↦O' v))
postulate Exercise₂' : ∀(u v : B) → B-mul u v ≣ O'↦B(mul' (B↦O' u) (B↦O' v))
postulate Exercise₃' : ∀(u v : B) → B-exp u v ≣ O'↦B(exp' (B↦O' u) (B↦O' v))
B-induction : {A : B → Set} →
A Z →
(∀(u : B) → A u → A(S u)) →
(∀(us : ℕ → B) → (∀(i : ℕ) → A(us i)) → A(L us)) →
(∀(u : B) → A u)
B-induction {A} z s l = h
where
h : ∀(u : B) → A u
h Z = z
h(S u) = s u (h u)
h(L us) = l us (λ i → h(us i))