You can encode ordinals in Coq as
Inductive ord := O | S (n: ord) | Lim (s: nat -> ord).
Suppose you use the following encoding instead
CoInductive stream A := {
head: A ;
tail: stream A ;
}.
Inductive ord := O | S (n: ord) | Sup (s: stream ord).
Can you make an induction principle go through?
I tried in both Coq and Agda but the obvious induction principle doesn't seem to work
{-# OPTIONS --guardedness #-}
module ord where
record stream (A : Set) : Set where
coinductive
constructor _::_
field
head : A
tail : stream A
record Forall {A : Set} (P : A → Set) (x : stream A) : Set where
coinductive
constructor _:>_
field
forhead : P (stream.head x)
fortail : Forall P (stream.tail x)
data ord : Set where
o : ord
s : ord → ord
sup : stream ord → ord
open stream
open Forall
ind : (P : ord → Set) → P o → ((x : ord) → P x → P (s x)) → ((x : stream ord) → Forall P x → P (sup x)) → (x : ord) → P x
ind P onO onS onSup = loop where
loop : (x : ord) → P x
loop o = onO
loop (s x) = onS x (loop x)
loop (sup x) = onSup x (gen x) where
gen : (y : stream ord) → Forall P y
forhead (gen y) = loop (head y)
fortail (gen y) = gen (tail y)
(Agda termination checker complains about the recusive calls to gen
and loop
.)