(**************************************)
(** * The set of von Neuman numerals  *)
(**************************************)

(** The set omega of von Neumann numerals is represented as the
    pointed graph ((opt nat), OMEGA, (none nat)) whose edge
    relation OMEGA : (Rel (opt nat)) is defined by the following
    two clauses:

    1. Delocation of the strict ordering "lt"

         if (wf_nat n), (wf_nat m) and (lt n m),
         then (OMEGA (some nat n) (some nat m))

    2. Connecting wf_nat's to the new root:

         if (wf_nat n), then (OMEGA (some nat n) (none nat)).

    As usual, we define it via a second-order encoding: *)

Definition OMEGA : Rel (opt nat) :=
  fun z' z =>
  forall E : Prop,
  (forall n n' : nat,
   eq (opt nat) z (some nat n) ->
   eq (opt nat) z' (some nat n') -> wf_nat n -> wf_nat n' -> lt n' n -> E) ->
  (forall n' : nat,
   eq (opt nat) z (none nat) ->
   eq (opt nat) z' (some nat n') -> wf_nat n' -> E) -> E.

(* Specifications: *)
Lemma OMEGA_in : forall n : nat, wf_nat n -> forall m : nat, wf_nat m -> lt n m -> OMEGA (some nat n) (some nat m).
Lemma OMEGA_rt : forall n : nat, wf_nat n -> OMEGA (some nat n) (none nat).
Lemma OMEGA_ZERO : EQV (opt nat) OMEGA (some nat O) unit ZERO id.
Lemma OMEGA_SUCC : forall n : nat, wf_nat n -> EQV (opt nat) OMEGA (some nat (S n)) (opt (opt nat)) (SUCC (opt nat) OMEGA (some nat n)) (none (opt nat)).
Theorem omega_zero : ELT unit ZERO id (opt nat) OMEGA (none nat).
Theorem omega_succ : forall (X : Typ1) (A : Rel X) (a : X), ELT X A a (opt nat) OMEGA (none nat) -> ELT (opt X) (SUCC X A a) (none X) (opt nat) OMEGA (none nat).
Theorem omega_ind : (* If P is a compatible predicate such that: *) forall P : PRED, Compat P -> (* 1. P holds for zero *) P unit ZERO id -> (* 2. If P holds for an element of omega, then P holds for the successor of this element *) (forall (X : Typ1) (A : Rel X) (a : X), ELT X A a (opt nat) OMEGA (none nat) -> P X A a -> P (opt X) (SUCC X A a) (none X)) -> (* Then: P holds for any element of omega *) forall (X : Typ1) (A : Rel X) (a : X), ELT X A a (opt nat) OMEGA (none nat) -> P X A a.