Inductive Ordinal : Type :=
  | ordS : Ordinal -> Ordinal
  | ord_sup: forall {I:Type}, (I->Ordinal) -> Ordinal.Inductive Ordinal : Type :=
  | ordS : Ordinal -> Ordinal
  | ord_sup: forall {I:Type}, (I->Ordinal) -> Ordinal.Inductive Ordinal : Type :=
  | ordS : Ordinal -> Ordinal
  | ord_sup: forall {I:Type}, (I->Ordinal) -> Ordinal.(*
Fixpoint ord_le (alpha beta:Ordinal) : Prop :=
  match alpha with
  | ordS alpha => 
                  (fix gt_alpha (beta:Ordinal) : Prop :=
                  match beta with
                  | ordS beta => ord_le alpha beta
                  | ord_sup J beta => exists j:J,
                    gt_alpha (beta j)
                  end) beta
  | ord_sup I0 alpha => forall i:I0, ord_le (alpha i) beta
  end.
*)

Inductive ord_le : Ordinal -> Ordinal -> Prop :=
  | ord_le_respects_succ: forall alpha beta:Ordinal,
    ord_le alpha beta -> ord_le (ordS alpha) (ordS beta)
  | ord_le_S_sup: forall (alpha:Ordinal) (J:Type)
    (beta:J->Ordinal) (j:J), ord_le (ordS alpha) (beta j) ->
    ord_le (ordS alpha) (ord_sup beta)
  | ord_sup_minimal: forall (I:Type) (alpha:I->Ordinal)
    (beta:Ordinal), (forall i:I, ord_le (alpha i) beta) ->
                    ord_le (ord_sup alpha) beta.(*
Fixpoint ord_le (alpha beta:Ordinal) : Prop :=
  match alpha with
  | ordS alpha => 
                  (fix gt_alpha (beta:Ordinal) : Prop :=
                  match beta with
                  | ordS beta => ord_le alpha beta
                  | ord_sup J beta => exists j:J,
                    gt_alpha (beta j)
                  end) beta
  | ord_sup I0 alpha => forall i:I0, ord_le (alpha i) beta
  end.
*)

Inductive ord_le : Ordinal -> Ordinal -> Prop :=
  | ord_le_respects_succ: forall alpha beta:Ordinal,
    ord_le alpha beta -> ord_le (ordS alpha) (ordS beta)
  | ord_le_S_sup: forall (alpha:Ordinal) (J:Type)
    (beta:J->Ordinal) (j:J), ord_le (ordS alpha) (beta j) ->
    ord_le (ordS alpha) (ord_sup beta)
  | ord_sup_minimal: forall (I:Type) (alpha:I->Ordinal)
    (beta:Ordinal), (forall i:I, ord_le (alpha i) beta) ->
                    ord_le (ord_sup alpha) beta.(*
Fixpoint ord_le (alpha beta:Ordinal) : Prop :=
  match alpha with
  | ordS alpha => 
                  (fix gt_alpha (beta:Ordinal) : Prop :=
                  match beta with
                  | ordS beta => ord_le alpha beta
                  | ord_sup J beta => exists j:J,
                    gt_alpha (beta j)
                  end) beta
  | ord_sup I0 alpha => forall i:I0, ord_le (alpha i) beta
  end.
*)

Inductive ord_le : Ordinal -> Ordinal -> Prop :=
  | ord_le_respects_succ: forall alpha beta:Ordinal,
    ord_le alpha beta -> ord_le (ordS alpha) (ordS beta)
  | ord_le_S_sup: forall (alpha:Ordinal) (J:Type)
    (beta:J->Ordinal) (j:J), ord_le (ordS alpha) (beta j) ->
    ord_le (ordS alpha) (ord_sup beta)
  | ord_sup_minimal: forall (I:Type) (alpha:I->Ordinal)
    (beta:Ordinal), (forall i:I, ord_le (alpha i) beta) ->
                    ord_le (ord_sup alpha) beta.(*
Fixpoint ord_le (alpha beta:Ordinal) : Prop :=
  match alpha with
  | ordS alpha => 
                  (fix gt_alpha (beta:Ordinal) : Prop :=
                  match beta with
                  | ordS beta => ord_le alpha beta
                  | ord_sup J beta => exists j:J,
                    gt_alpha (beta j)
                  end) beta
  | ord_sup I0 alpha => forall i:I0, ord_le (alpha i) beta
  end.
*)

Inductive ord_le : Ordinal -> Ordinal -> Prop :=
  | ord_le_respects_succ: forall alpha beta:Ordinal,
    ord_le alpha beta -> ord_le (ordS alpha) (ordS beta)
  | ord_le_S_sup: forall (alpha:Ordinal) (J:Type)
    (beta:J->Ordinal) (j:J), ord_le (ordS alpha) (beta j) ->
    ord_le (ordS alpha) (ord_sup beta)
  | ord_sup_minimal: forall (I:Type) (alpha:I->Ordinal)
    (beta:Ordinal), (forall i:I, ord_le (alpha i) beta) ->
                    ord_le (ord_sup alpha) beta.Definition ord_lt (alpha beta:Ordinal) :=
  ord_le (ordS alpha) beta.Definition ord_eq (alpha beta:Ordinal) :=
  ord_le alpha beta /\ ord_le beta alpha.Definition ord_ge (alpha beta:Ordinal) :=
  ord_le beta alpha.Definition ord_gt (alpha beta:Ordinal) :=
  ord_lt beta alpha.Notation "alpha < beta" := (ord_lt alpha beta) : ordinal_scope.Notation "alpha <= beta" := (ord_le alpha beta) : ordinal_scope.Notation "alpha == beta" := (ord_eq alpha beta)
  (at level 70) : ordinal_scope.Notation "alpha > beta" := (ord_gt alpha beta) : ordinal_scope.Notation "alpha >= beta" := (ord_ge alpha beta) : ordinal_scope.

(* Specifications: *)
Lemma ord_le_respects_succ_converse: forall alpha beta:Ordinal, ordS alpha <= ordS beta -> alpha <= beta.
Lemma ord_le_S_sup_converse: forall (alpha:Ordinal) (J:Type) (beta:J->Ordinal), ordS alpha <= ord_sup beta -> exists j:J, ordS alpha <= beta j.
Lemma ord_sup_minimal_converse: forall (I:Type) (alpha:I->Ordinal) (beta:Ordinal), ord_sup alpha <= beta -> forall i:I, alpha i <= beta.
Lemma ord_le_trans: forall alpha beta gamma:Ordinal, alpha <= beta -> beta <= gamma -> alpha <= gamma.
Lemma ord_le_sup: forall (I:Type) (alpha:I->Ordinal) (i:I), alpha i <= ord_sup alpha.
Lemma ord_le_refl: forall alpha:Ordinal, alpha <= alpha.
Lemma ord_le_S: forall alpha:Ordinal, alpha <= ordS alpha.
Lemma ord_lt_le: forall alpha beta:Ordinal, alpha < beta -> alpha <= beta.
Lemma ord_lt_le_trans: forall alpha beta gamma:Ordinal, alpha < beta -> beta <= gamma -> alpha < gamma.
Lemma ord_le_lt_trans: forall alpha beta gamma:Ordinal, alpha <= beta -> beta < gamma -> alpha < gamma.
Lemma ord_lt_trans: forall alpha beta gamma:Ordinal, alpha < beta -> beta < gamma -> alpha < gamma.
Lemma ord_lt_respects_succ: forall alpha beta:Ordinal, alpha < beta -> ordS alpha < ordS beta.
Lemma ord_total_order: forall alpha beta:Ordinal, alpha < beta \/ alpha == beta \/ alpha > beta.
Lemma ordinals_well_founded: well_founded ord_lt.
Lemma ord_lt_irrefl: forall alpha:Ordinal, ~(alpha < alpha).