Library hydras.Epsilon0.T1

A type for ordinals terms in Cantor Normal Form
After Manolios and Vroon's work on ACL2

From Coq Require Import Arith Max Bool Lia Compare_dec Relations Ensembles
     Wellfounded Bool RelationClasses Operators_Properties ArithRing
     Logic.Eqdep_dec.

From Coq Require PArith.
From hydras Require Import More_Arith Restriction DecPreOrder.
From hydras Require Import OrdNotations.
From hydras Require Export Prelude.Comparable.
From hydras Require Export STDPP_compat.

Create HintDb T1.

Set Implicit Arguments.

Declare Scope t1_scope.
Delimit Scope t1_scope with t1.
Open Scope t1_scope.

Coercion is_true: bool >-> Sortclass.

Definitions

A type of terms (not necessarily in normal form)

cons a n b is intended to represent the ordinal omega^a × (S n) + b
Note that T1 contains terms which are not in Cantor normal form. This issue is solved later which the help of the predicate nf


Inductive T1 : Set :=
| zero
| cons (alpha : T1) (n : nat) (beta : T1) .


Basic functions and predicates on T1


The (S n)-th ordinal
Notation FS n := (cons zero n zero).

Notation one := (FS 0).

the n-th (finite) ordinal

Definition T1nat (n:nat) := match n with 0 ⇒ zero | S pFS p end.

Notation "\F n" := (T1nat n) (at level 29): t1_scope.

Coercion T1nat : nat >-> T1.

Example ten : T1 := 10.

#[deprecated(note="use T1nat" )]
 Notation fin := T1nat (only parsing).


Notation T1omega := (cons (cons zero 0 zero) 0 zero).


#[deprecated(note="use T1omega")]
 Notation omega := T1omega (only parsing).


Successor and limits (syntactic definitions)


Fixpoint T1is_succ alpha :=
  match alpha with
    | zerofalse
    | cons zero _ _true
    | cons _alpha _n betaT1is_succ beta
  end.

Fixpoint T1limit alpha :=
  match alpha with
    | zerofalse
    | cons zero _ _false
    | cons _ _ zerotrue
    | cons _ _ betaT1limit beta
  end.





#[deprecated(note="use T1is_succ")]
  Notation succb := T1is_succ (only parsing).

#[deprecated(note="use T1limit")]
  Notation limitb := T1limit (only parsing).

Exponential of base omega


Notation phi0 alpha := (cons alpha 0 zero).


multiples of phi0 alpha

Definition omega_term (alpha:T1)(k:nat) :=
  cons alpha k zero.

omega towers

Fixpoint omega_tower (height:nat) : T1 :=
  match height with
  | 0 ⇒ one
  | S hphi0 (omega_tower h)
  end.


Additive principal ordinals

Inductive ap : T1 Prop :=
  ap_intro : a, ap (phi0 a).

A linear strict order on T1


#[global] Instance compare_T1 : Compare T1 :=
 fix cmp (alpha beta:T1) :=
  match alpha, beta with
  | zero, zeroEq
  | zero, cons a' n' b'Lt
  | _ , zeroGt
  | (cons a n b),(cons a' n' b') ⇒
      (match cmp a a' with
       | LtLt
       | GtGt
       | Eq ⇒ (match n ?= n' with
                | Eqcmp b b'
                | compcomp
                end)
       end)
  end.

Definition lt (alpha beta : T1) : Prop :=
  compare alpha beta = Lt.

Notation le := (leq lt).

Example E1 : lt (cons T1omega 56 zero) (omega_tower 3).

Example E2 : ¬ lt (omega_tower 3) (cons T1omega 5 (omega_tower 3))%t1.

Properties of compare


Lemma compare_cons :
  a n b a' n' b',
 compare (cons a n b) (cons a' n' b') =
 match compare a a' with
 | LtLt
 | GtGt
 | Eq ⇒ (match n ?= n' with
        | Eqcompare b b'
        | compcomp
        end)
 end.


Lemma compare_rev :
   (alpha beta : T1),
  compare beta alpha = CompOpp (compare alpha beta).
Lemma compare_reflect :
   alpha beta,
    match compare alpha beta with
    | Ltlt alpha beta
    | Eqalpha = beta
    | Gtlt beta alpha
    end.

Lemma compare_correct (alpha beta: T1):
  CompSpec eq lt alpha beta (compare alpha beta).

Properties of Eq


Lemma compare_refl :
   alpha : T1, compare alpha alpha = Eq.

Lemma compare_eq_iff (a b : T1) :
  compare a b = Eq a = b.

Properties of lt


Theorem not_lt_zero alpha : ¬ lt alpha zero.

#[global] Hint Resolve not_lt_zero : T1.

Lemma compare_lt_impl a b :
  compare a b = Lt lt a b.

Lemma compare_lt_iff a b :
  compare a b = Lt lt a b.

Properties of lt inv

Inductive lt_cases (a b : T1) (n :nat) (a' b':T1) (n':nat) : Type :=
  | lt_left (H : lt a a')
  | lt_middle (H : a = a')(H1 : (n < n')%nat)
  | lt_right (H : a = a')(H1 : n = n')(H2 : lt b b').

Lemma lt_inv_strong :
   a n b a' n' b',
  lt (cons a n b) (cons a' n' b')
  lt_cases a b n a' b' n'.

Theorem lt_irrefl (alpha: T1):
  ¬ lt alpha alpha.

Theorem lt_inv :
   a n b a' n' b',
  lt (cons a n b) (cons a' n' b')
  lt a a'
  a = a' (n < n')%nat
  a = a' n = n' lt b b'.

Lemma lt_inv_coeff:
   a n n' b b',
  lt (cons a n b) (cons a n' b') n n'.

Lemma lt_inv_coeff_dec :
   a n n' b b',
  lt (cons a n b) (cons a n' b')
  {(n < n')%nat} + { n = n' lt b b'}.

Lemma lt_inv_tail :
   a n b b',
  lt (cons a n b) (cons a n b') lt b b'.

Lemma head_lt :
   alpha alpha' n n' beta beta',
       lt alpha alpha'
       lt (cons alpha n beta) (cons alpha' n' beta').

Lemma coeff_lt :
   alpha n n' beta beta',
  (n < n')%nat lt (cons alpha n beta) (cons alpha n' beta').

Lemma tail_lt :
   alpha n beta beta',
  lt beta beta'
  lt (cons alpha n beta) (cons alpha n beta').

Lemma compare_fin_rw (n n1: nat) :
  compare (T1nat n) (T1nat n1) = (n ?= n1).

Lemma lt_fin_iff (i j : nat): lt (T1nat i) (T1nat j) Nat.lt i j.

Theorem lt_trans:
   alpha beta gamma: T1,
  lt alpha beta lt beta gamma lt alpha gamma.


#[global] Instance t1_strorder: StrictOrder lt.
#[global] Instance: Comparable lt compare.

Lemma lt_inv_head :
   a n b a' n' b',
    lt (cons a n b) (cons a' n' b') leq lt a a'.

The predicate "to be in normal form"

Cantor normal form needs the exponents of omega to be in strict decreasing order

#[ global ] Instance lt_dec : RelDecision lt :=
fun alpha betadecide (compare alpha beta = Lt).

Fixpoint nf_b (alpha : T1) : bool :=
  match alpha with
  | zerotrue
  | cons a n zeronf_b a
  | cons a n ((cons a' n' b') as b) ⇒
      (nf_b a && nf_b b && (bool_decide (lt a' a)))%bool
  end.

Definition nf alpha :Prop := nf_b alpha.


Example bad_term: T1 := cons 1 1 (cons T1omega 2 zero).


epsilon0 as a set

Definition epsilon_0 : Ensemble T1 := nf.

Arithmetic functions

Successor


Fixpoint succ (a: T1) : T1 :=
  match a with
  | zeroT1nat 1
  | cons zero n _cons zero (S n) zero
  | cons b n ccons b n (succ c)
  end.

Predecessor (partial function


Fixpoint pred (c:T1) : option T1 :=
  match c with zeroNone
  | cons zero 0 _Some zero
  | cons zero (S n) _Some (cons zero n zero)
  | cons a n b
      match (pred b) with
      | NoneNone
      | Some cSome (cons a n c)
      end
  end.

Addition



Fixpoint T1add (a b : T1) :T1 :=
  match a, b with
  | zero, yy
  | x, zerox
  | cons a n b, cons a' n' b'
      (match compare a a' with
       | Ltcons a' n' b'
       | Gt ⇒ (cons a n (T1add b (cons a' n' b')))
       | Eq ⇒ (cons a (S (n+n')) b')
       end)
  end
where "alpha + beta" := (T1add alpha beta) : t1_scope.

#[deprecated(note="use T1add")]
  Notation plus := T1add (only parsing).

multiplication



Fixpoint T1mul (a b : T1) :T1 :=
  match a, b with
  | zero, _zero
  | _, zerozero
  | cons zero n _, cons zero n' b'
      cons zero (Peano.pred((S n) × (S n'))) b'
  | cons a n b, cons zero n' _
      cons a (Peano.pred ((S n) × (S n'))) b
  | cons a n b, cons a' n' b'
      cons (a + a') n' ((cons a n b) × b')
  end
where "a * b" := (T1mul a b) : t1_scope.

#[deprecated(note="use T1mul")]
  Notation mult := T1mul (only parsing).

Substraction (used as a helper for exponentiation)


Fixpoint minus (alpha beta : T1) :T1 :=
  match alpha,beta with
 | zero, yzero
 | cons zero n _, cons zero n' _
     if (le_lt_dec n n')
     then zero
     else cons zero (Peano.pred (n-n')) zero
 | cons zero n _, zerocons zero n zero
 | cons zero _ _, _zero
 | cons a n b, zerocons a n b
 | cons a n b, cons a' n' b'
     (match compare a a' with
      | Ltzero
      | Gtcons a n b
      | Eq ⇒ (match Nat.compare n n' with
               | Ltzero
               | Gt ⇒ (cons a (Peano.pred (n - n')) b')
               | Eqb - b'
               end)
       end)
 end
 where "alpha - beta" := (minus alpha beta):t1_scope.

exponentiation functions


Fixpoint exp_F (alpha : T1)(n : nat) :T1 :=
 match n with
 | 0 ⇒ FS 0
 | S palpha × (exp_F alpha p)
 end.

Fixpoint exp (alpha beta : T1) :T1 :=
  match alpha ,beta with
 | _, zerocons zero 0 zero
 | cons zero 0 _ , _cons zero 0 zero
 | zero, _zero
 | x , cons zero n' _exp_F x (S n')
 | cons zero n _, cons (cons zero 0 zero) n' b'
        ((cons (cons zero n' zero) 0 zero) ×
                ((cons zero n zero) ^ b'))
 | cons zero n _, cons a' n' b'
            (omega_term
                    (omega_term (a' - 1) n')
                    0) ×
                 ((cons zero n zero) ^ b')
 | cons a n b, cons a' n' b'
    ((omega_term (a × (cons a' n' zero))
                            0) ×
            ((cons a n b) ^ b'))
end
where "alpha ^ beta " := (exp alpha beta) : t1_scope.

Lemmas


Lemma compare_of_phi0 alpha beta:
  compare (phi0 alpha) (phi0 beta) = compare alpha beta.

Lemma zero_lt : alpha n beta, lt zero (cons alpha n beta).

#[global] Hint Resolve zero_lt head_lt coeff_lt tail_lt : T1.

Open Scope t1_scope.

Lemma zero_nf : nf zero.

Lemma single_nf :
   a n, nf a nf (cons a n zero).

Lemma cons_nf :
   a n a' n' b,
  lt a' a
  nf a
  nf(cons a' n' b)
  nf(cons a n (cons a' n' b)).

#[global] Hint Resolve zero_nf single_nf cons_nf: T1.

Lemma nf_inv1 :
   a n b, nf (cons a n b) nf a.

Lemma nf_inv2 :
   a n b, nf (cons a n b) nf b.

Lemma nf_inv3 :
   a n a' n' b',
  nf (cons a n (cons a' n' b')) lt a' a.

Lemma nf_cons_inv a n b : nf (cons a n b) nf a nf b lt b (phi0 a).

Lemma nf_cons_iff a n b : nf (cons a n b) nf a nf b lt b (phi0 a).

already in Stdlib ?

Lemma bool_eq_iff (b b':bool) : (b = b') (b b').

Lemma nf_b_cons_eq a n b : nf_b (cons a n b) =
                           nf_b a && nf_b b && bool_decide (lt b (phi0 a)).


Ltac nf_decomp H :=
  let nf0 := fresh "nf"
  in let nf1 := fresh "nf"
     in let Hlp := fresh "lt"
     in
     match type of H with
     | nf (cons ?t ?n zero) ⇒ assert (nf0:= nf_inv1 H)
     | nf (cons ?t1 ?n (cons ?t2 ?p ?t3))
       ⇒ assert (nf0 := nf_inv1 H); assert(nf1 := nf_inv2 H);
          assert (lt := nf_inv3 H)
     | nf (cons ?t1 ?n ?t2) ⇒ assert (nf0 := nf_inv1 H); assert(nf1 := nf_inv2 H)
     end.

lt alpha (phi0 beta)
Inductive lt_a_phi0_b : T1 T1 Prop :=
| lt_a_phi0_b_z : alpha, lt_a_phi0_b zero alpha
| lt_a_phi0_b_c : alpha alpha' n' beta',
                  lt alpha' alpha
                  lt_a_phi0_b (cons alpha' n' beta') alpha.

#[global] Hint Constructors lt_a_phi0_b : T1.

Reserved Notation "x '<_phi0' y" (at level 70, no associativity).
Infix "<_phi0" := lt_a_phi0_b.


Definition get_decomposition : c:T1, lt zero c
                           {a:T1 & {n:nat & {b:T1 | c = cons a n b}}}.

Ltac decomp_exhib H a n b e:=
 let Ha := fresh in
 let Hn := fresh in
 let Hb := fresh in
  match type of H
  with lt zero ?c
    case (get_decomposition H);
     intros a Ha;
     case Ha;intros n Hn; case Hn; intros b e;
     clear Ha Hn
  end.

Lemma nf_FS : n:nat, nf (FS n).

Lemma nf_fin : n:nat, nf (T1nat n).

Successors, limits and zero

Second part on lt and le


Lemma finite_lt :
   n p : nat, (n < p)%nat lt (FS n) (FS p).

Lemma finite_ltR :
   n p : nat,
  lt (FS n) (FS p) (n < p)%nat.

Lemma le_eq_lt_dec alpha beta:
  leq lt alpha beta
  {alpha = beta} + {lt alpha beta}.

Lemma lt_succ (alpha : T1) : lt alpha (succ alpha).

Lemma lt_a_phi0_a :
   a, lt a (phi0 a).

Lemma phi0_lt :
   a b, lt a b lt (phi0 a) (phi0 b).

Lemma phi0_ltR :
   a b, lt (phi0 a) (phi0 b) lt a b.

Lemma nf_of_finite :
   n b,
  nf (cons zero n b) b = zero.

Theorem zero_le :
   a, leq lt zero a.

Theorem le_inv :
   a n b a' n' b',
  leq lt (cons a n b) (cons a' n' b')
  lt a a'
  a = a' (n < n')%nat
  a = a' n = n' leq lt b b'.

Arguments le_inv [a n b a' n' b'] _.

Lemma lt_a_phi0_b_inv :
   a n b a', lt (cons a n b) (phi0 a') lt a a'.

Theorem le_zero_inv :
   a, leq lt a zero a = zero.

Theorem le_tail :
   a n b b',
  leq lt b b'
  leq lt (cons a n b) (cons a n b').

#[global] Hint Resolve zero_le le_tail : T1.

Theorem le_phi0 :
   a n b, leq lt (phi0 a) (cons a n b).

Lemma head_lt_cons :
   a n b, lt a (cons a n b).

#[export] Hint Resolve head_lt_cons: T1.

Definition T1_eq_dec (alpha beta : T1):
{alpha = beta} + {alpha beta}.

Definition lt_eq_lt_dec :
   alpha beta : T1,
  {lt alpha beta} + {alpha = beta} + {lt beta alpha}.

Definition lt_le_dec (alpha beta : T1) :
  {lt alpha beta} + {leq lt beta alpha}.

#[ global ] Instance epsilon0_pre_order : TotalPreOrder (leq lt).

#[ global ] Instance epsilon0_dec : RelDecision (leq lt).

Ltac auto_nf :=
  match goal with
    |- nf ?alpha
    ( repeat (apply cons_nf || apply single_nf || apply zero_nf))
    || (eapply nf_inv1 || eapply nf_inv2); eauto
  end.

Lemma nf_tail_lt_nf b b':
  lt b' b nf b'
   a n, nf (cons a n b) nf (cons a n b').

Lemma tail_lt_cons :
   b n a,
  nf (cons a n b) lt b (cons a n b).

Lemma lt_a_phi0_b_inv1 :
   a n b a', cons a n b <_phi0 a' lt a a'.

Lemma nf_intro :
   a n b, nf a nf b b <_phi0 a
                nf (cons a n b).

Lemma nf_intro' :
   a n b,
  nf a
  nf b
  lt b (cons a 0 zero)
  nf (cons a n b).

Lemma lt_a_phi0_b_intro :
   a n b, nf (cons a n b) b <_phi0 a.

Lemma nf_coeff_irrelevance :
   a b n p, nf (cons a n b) nf (cons a p b).

Lemma lt_a_phi0_b_phi0 :
   a b, b <_phi0 a lt b ( phi0 a).

Lemma lt_a_phi0_b_phi0R :
   a b, lt b (phi0 a) b <_phi0 a.

Lemma lt_a_phi0_b_def :
   a b, b <_phi0 a lt b (phi0 a).

Lemma lt_a_phi0_b_iff :
   a b, nf a nf b
              (b <_phi0 a n, nf (cons a n b)).

Lemma nf_omega_tower : n, nf (omega_tower n).

A strong induction scheme for nf

Definition nf_rect : P : T1 Type,
    P zero
    ( n: nat, P (cons zero n zero))
    ( a n b n' b', nf (cons a n b)
                         P (cons a n b)
                         lt b' (phi0 (cons a n b))
                         nf b'
                         P b'
                         P (cons (cons a n b) n' b'))
     a: T1, nf a P a.

Properties of compare: second part


Theorem compare_reflectR ( alpha beta : T1) :
  (match lt_eq_lt_dec alpha beta with
   | inleft (left _) ⇒ Lt
   | inleft (right _) ⇒ Eq
   | inright _Gt
   end)
  = compare alpha beta.

Properties of max

Lemma max_nf (alpha beta : T1) :
  nf alpha nf beta nf (max alpha beta).

Restriction of lt and le to terms in normal form

Reserved Notation "x 't1<' y" (at level 70, no associativity).
Reserved Notation "x 't1<=' y" (at level 70, no associativity).
Reserved Notation "x 't1>=' y" (at level 70, no associativity).
Reserved Notation "x 't1>' y" (at level 70, no associativity).

Reserved Notation "x 't1<=' y 't1<=' z" (at level 70, y at next level).
Reserved Notation "x 't1<=' y 't1<' z" (at level 70, y at next level).
Reserved Notation "x 't1<' y 't1<' z" (at level 70, y at next level).
Reserved Notation "x 't1<' y 't1<=' z" (at level 70, y at next level).


Definition LT := restrict nf lt.
Infix "t1<" := LT : t1_scope.

Definition LE := restrict nf (leq lt).
Infix "t1<=" := LE : t1_scope.


Notation "alpha t1< beta t1< gamma" :=
  (LT alpha beta LT beta gamma) : t1_scope.

Definition Elements alpha : Ensemble T1 :=
  fun betabeta t1< alpha.

Coercion Elements : T1 >-> Ensemble.

Lemma LT_nf_l : alpha beta , alpha t1< beta nf alpha.

Lemma LT_nf_r : alpha beta , alpha t1< beta nf beta.

Lemma LT_lt alpha beta : alpha t1< beta lt alpha beta.

Lemma LE_nf_l : alpha beta , alpha t1 beta nf alpha.

Lemma LE_nf_r : alpha beta , alpha t1 beta nf beta.

Lemma LE_le alpha beta : alpha t1 beta leq lt alpha beta.

#[global] Hint Resolve LT_nf_r LT_nf_l LT_lt LE_nf_r LE_nf_l LE_le : T1.

Lemma not_zero_gt_0 (alpha:T1) : alpha zero lt zero alpha.

Lemma not_zero_lt (alpha: T1): nf alpha alpha zero
                               zero t1< alpha.

Lemma LE_zero : alpha, nf alpha zero t1 alpha.

Lemma LE_refl : alpha, nf alpha alpha t1 alpha.

Lemma LT_trans : a b c:T1, a t1< b b t1< c a t1< c.

Theorem LE_trans (alpha beta gamma: T1):
          alpha t1 beta beta t1 gamma alpha t1 gamma.

Lemma LE_antisym (alpha beta : T1): alpha t1 beta
                                     beta t1 alpha
                                     alpha = beta.

Lemma LT1 : alpha n beta, nf (cons alpha n beta)
                                 zero t1< cons alpha n beta.

Lemma LT2 : alpha alpha' n n' beta beta',
    nf (cons alpha n beta)
    nf (cons alpha' n' beta')
    alpha t1< alpha'
    cons alpha n beta t1< cons alpha' n' beta'.

Lemma LT3 : alpha n n' beta beta',
    nf (cons alpha n beta)
    nf (cons alpha n' beta')
    n < n'
    cons alpha n beta t1< cons alpha n' beta'.

Lemma LT4 : alpha n beta beta',
    nf (cons alpha n beta)
    nf (cons alpha n beta')
    beta t1< beta'
    cons alpha n beta t1< cons alpha n beta'.

#[global] Hint Resolve LT1 LT2 LT3 LT4: T1.

Lemma LT_irrefl (alpha : T1) :
  ¬ alpha t1< alpha.

Lemma LE_LT_trans :
   alpha beta gamma,
  alpha t1 beta beta t1< gamma alpha t1< gamma.

Lemma LT_LE_trans (alpha beta gamma : T1) : alpha t1< beta
                                            beta t1 gamma
                                            alpha t1< gamma.

Lemma not_LT_zero :
   alpha, ¬ alpha t1< zero.

#[ global ] Instance LT_St : StrictOrder LT.

Lemma nf_cons_LT :
   (a : T1) (n : nat) (a' : T1) (n' : nat) (b : T1),
  a' t1< a
  nf a nf (cons a' n' b) nf (cons a n (cons a' n' b)).

#[global] Hint Resolve nf_cons_LT: T1.

#[global] Hint Resolve nf_inv1 nf_inv2 nf_inv3 : T1.

Lemma head_LT_cons :
   alpha n beta,
  nf (cons alpha n beta)
  alpha t1< cons alpha n beta.

Lemma tail_LT_cons :
   alpha n beta,
  nf (cons alpha n beta)
  beta t1< cons alpha n beta.

Lemma LT_inv : a n b a' n' b',
    cons a n b t1< cons a' n' b'
    a t1< a'
    a = a' (n < n' n = n' b t1< b').

Inductive LT_cases (a b : T1) (n :nat) (a' b':T1) (n':nat) : Type :=
| LT_left (H : a t1< a')
| LT_middle (H : a = a')(H1 : n < n')
| LT_right (H : a = a')(H1 : n = n')(H2 : b t1< b').

Lemma LT_inv_strong :
   a b n a' b' n',
  cons a n b t1< cons a' n' b' LT_cases a b n a' b' n'.

Lemma remove_first_sumand :
   a n b b',
    cons a n b t1< cons a n b' b t1< b'.

Lemma LT_cons_0 :
   a n b a' b',
  cons a n b t1< cons a' 0 b' a t1< a' n = 0 a = a' b t1< b'.

Lemma LE_phi0 :
   a n b, nf (cons a n b) phi0 a t1 cons a n b.

Lemma nf_tail_lt alpha n beta gamma :
  nf (cons alpha n beta) gamma t1< beta
  nf (cons alpha n gamma).

Well foundedness of LT


Module Direct_proof.
  Section well_foundedness_proof.
    #[local] Hint Unfold restrict LT: T1.

    Lemma Acc_zero : Acc LT zero.



    Section First_attempt.

      Lemma wf_LT : alpha: T1, nf alpha Acc LT alpha.
    End First_attempt.

Strong accessibility (inspired by Tait's proof)


    Let Acc_strong (alpha:T1) :=
       n beta,
        nf (cons alpha n beta) Acc LT (cons alpha n beta).

    Remark acc_impl {A} {R: A A Prop} (a b:A) :
      R a b Acc R b Acc R a.


    Lemma Acc_strong_stronger : alpha,
        nf alpha Acc_strong alpha Acc LT alpha.



    Lemma Acc_implies_Acc_strong : alpha,
        Acc LT alpha Acc_strong alpha.

A (last) structural induction



    Theorem nf_Acc (alpha : T1): nf alpha Acc LT alpha.

  End well_foundedness_proof.
End Direct_proof.

Definition nf_Acc := Direct_proof.nf_Acc.

Corollary nf_Wf : well_founded_restriction _ nf lt.


Corollary T1_wf : well_founded LT.
Definition transfinite_recursor_lt :
   (P:T1 Type),
    ( x:T1,
        ( y:T1, nf x nf y lt y x P y) P x)
     alpha: T1, P alpha.


Definition transfinite_recursor := well_founded_induction_type T1_wf.

Check transfinite_recursor.


Import Direct_proof.

Ltac transfinite_induction_lt alpha :=
  pattern alpha; apply transfinite_recursor_lt.


Ltac transfinite_induction alpha :=
  pattern alpha; apply transfinite_recursor.


Properties of successor



Lemma succ_nf : alpha : T1 , nf alpha nf (succ alpha).

properties of addition


Lemma plus_zero alpha: zero + alpha = alpha.

Lemma plus_zero_r alpha: alpha + zero = alpha.


Lemma succ_is_plus_one (a : T1) : succ a = a + 1.

Lemma succ_of_plus_finite :
   a (H: nf a) (i:nat) , succ (a + i) = a + S i.

plus and LT


Lemma plus_cons_cons_rw1 :
   a n b a' n' b',
  lt a a'
  cons a n b + cons a' n' b' = cons a' n' b'.

Lemma plus_cons_cons_rw2 :
   a n b n' b',
  nf (cons a n b)
  nf (cons a n' b')
  cons a n b + cons a n' b' = cons a (S (n + n')) b'.

Lemma plus_cons_cons_rw3 :
   a n b a' n' b',
  lt a' a
  nf (cons a n b)
  nf (cons a' n' b')
  cons a n b + cons a' n' b'=
  cons a n (b + (cons a' n' b')).

On additive principal ordinals


Lemma ap_plus : a,
    ap a
     b c,
      nf b nf c lt b a lt c a lt (b + c) a.

Lemma ap_plusR :
   c,
  nf c
  c zero
  ( a b, nf a nf b lt a c lt b c lt (a + b) c)
  ap c.

Technical lemma for proving plus_nf

Lemma plus_nf0 :
   a, nf a
   b c,
    lt b (phi0 a)
    lt c (phi0 a)
    nf b nf c
    nf (b + c).


Lemma plus_nf:
   a, nf a b, nf b nf (a + b).

Lemma omega_term_plus_rw:
   a n b,
    nf (cons a n b)
    omega_term a n + b = cons a n b.


Lemma plus_is_zero alpha beta :
  nf alpha nf beta
  alpha + beta = zero alpha = zero beta = zero.

Lemma T1add_not_monotonous_l :
   a b c : T1, a t1< b a + c = b + c.

Lemma T1mul_not_monotonous :
   a b c : T1, c zero a t1< b a × c = b × c.

monotonicity of succ


Lemma succ_strict_mono :
   a b,
    lt a b nf a nf b
    lt (succ a) (succ b).

Lemma succ_strict_mono_LT :
   alpha beta,
  alpha t1< beta succ alpha t1< succ beta.

Lemma succ_mono :
   a b,
  nf a nf b
  leq lt a b leq lt (succ a) (succ b).

Lemma lt_succ_le_R :
   a, nf a b, nf b
  leq lt (succ a) b lt a b .

Lemma le_lt_LT alpha beta :
  nf alpha nf beta leq lt alpha beta leq LT alpha beta.

Lemma LT_succ_LE_R :
   alpha beta,
    nf alpha
    succ alpha t1 beta alpha t1< beta.

Lemma lt_succ_le_2 :
   a,
  nf a b, nf b
  lt a (succ b) leq lt a b.

TODO: bulletize this proof !

Lemma lt_succ_le :
   a,
    nf a b, nf b
                      lt a b leq lt (succ a) b.

Lemma LT_succ_LE :
   alpha beta ,
  alpha t1< beta succ alpha t1 beta.

Lemma LT_succ_LE_2:
   alpha beta : T1, nf beta
    alpha t1< succ beta alpha t1 beta.

Lemma succ_strict_monoR :
   alpha beta,
    nf alpha nf beta
      lt (succ alpha) (succ beta) lt alpha beta.

Lemma succ_monomorphism :
   alpha (H:nf alpha) beta (H' : nf beta),
    lt alpha beta lt (succ alpha) (succ beta).

Lemma succ_injective :
   alpha (H:nf alpha) beta (H' : nf beta),
    succ alpha = succ beta alpha = beta.

Lemma succ_compatS :
   n:nat, succ (FS n) = FS (S n).

Lemma succ_compat (n:nat) :
  succ (T1nat n) = FS n.

monotonicity of phi0


Lemma phi0_mono_strict :
   a b, lt a b lt (phi0 a) (phi0 b).

Lemma phi0_mono_strict_LT :
   alpha beta,
    alpha t1< beta phi0 alpha t1< phi0 beta.

Lemma phi0_mono :
   a b, leq lt a b leq lt (phi0 a) ( phi0 b).

Lemma plus_left_absorb :
   a n b c,
  lt c (phi0 a) c + cons a n b = cons a n b.

Lemma plus_compat:
   n p, FS n + FS p = FS (S n + p).

Multiplication


Lemma mult_fin_omega :
   n: nat,
    FS n × T1omega = T1omega.

Lemma phi0_plus_mult :
   a b, nf a nf b phi0 (a + b) = phi0 a × phi0 b.

Lemma mult_compat :
   n p, FS n × FS p = FS (n × p + n + p)%nat.

Lemma mult_a_0 :
   a, a × zero = zero.

Lemma mult_1_a :
   a, nf a 1 × a = a.

Lemma mult_a_1 :
   a, nf a a × 1 = a.

Lemma mult_nf_fin alpha n: nf alpha nf (alpha × T1nat n).

About minus


Lemma minus_lt :
   a b, lt a b a - b = zero.

Lemma minus_a_a : a, a - a = zero.

Lemma minus_le : a b, leq lt a b a - b = zero.

Exponential


Lemma exp_fin_omega : n, FS (S n) ^ T1omega = T1omega.

Relations between cons, phi0 and +

The next three lemmas express the consistency between the intuitive meaning given to the constructor cons and its derivates : phi0, omega-term, and the arithmetic operations on ordinals which belong to epsilon0

Lemma phi0_eq_bad : alpha, T1omega ^ alpha = phi0 alpha.

Lemma phi0_eq : alpha, nf alpha T1omega ^ alpha = phi0 alpha.

Lemma omega_term_def :
   a n, nf a omega_term a n = T1omega ^ a × FS n.

Lemma cons_def :
   a n b,
  nf(cons a n b) cons a n b = T1omega ^ a × FS n + b.

Theorem unique_decomposition :
   a n b a' n' b',
    nf (cons a n b) nf (cons a' n' b')
    T1omega ^ a × FS n + b =
    T1omega ^ a' × FS n' + b'
    a = a' n = n' b = b'.

Theorem Cantor_normal_form :
   o, lt zero o nf o
            {a:T1 & {n: nat & {b : T1 |
                                o = T1omega ^ a × FS n + b
                                nf (cons a n b) }}}.


Lemma LT_one alpha :
  alpha t1< one alpha = zero.
Lemma lt_omega_inv :
   alpha,
  alpha t1< T1omega alpha = zero n, alpha = FS n.

Ltac T1_inversion H :=
  match type of H with lt _ zerodestruct (not_lt_zero H)
                  | Nat.lt _ 0 ⇒ destruct (Nat.nlt_0_r _ H)
                  | Nat.lt ?x ?xdestruct (Nat.lt_irrefl _ H)
                  | lt ?x ?xdestruct (lt_irrefl H)
                  | lt (cons _ _ _) (cons _ _ _) ⇒
                    destruct (lt_inv H)
                  | nf (cons zero ?n ?y) ⇒ let e := fresh "e" in
                                             generalize (nf_of_finite H);
                                             intros e
  end.

Lemma LT_of_finite :
   alpha n, alpha t1< FS n alpha = zero
                                   p, p < n alpha = FS p.

Lemma nf_omega : nf T1omega.


Theorem nf_phi0 alpha : nf alpha nf (phi0 alpha).

#[global] Hint Resolve nf_phi0 : T1.

Definition omega_omega := phi0 T1omega.

Lemma nf_omega_omega : nf omega_omega.

Lemma mult_0_a : a, zero × a = zero.

Lemma mult_Sn_add (alpha : T1) n :
  nf alpha
  alpha × (FS (S n)) = alpha × FS n + alpha.

Lemma cases_for_mult (alpha : T1) :
  nf alpha
  alpha = zero
  ( n : nat, alpha = FS n)
  ( a n, a zero alpha = cons a n zero)
  ( a n b, a zero b zero alpha = cons a n b).

Lemma L03 alpha n beta p :
  alpha zero
  (cons alpha n beta × FS p) = cons alpha (p + n × S p) beta.

Lemma L05 a n b c p d :
  a zero c zero
  (cons a n b × cons c p d) =
  cons (a + c) p (cons a n b × d).

Lemma nf_LT_iff :
   alpha n beta, nf (cons alpha n beta)
                       nf alpha nf beta
                        beta t1< phi0 alpha.

Lemma lt_plus_l:
   {a b c : T1} {n:nat}, lt a (a + cons b n c).

Lemma lt_plus_r:
   {a b c : T1} {n:nat}, ¬ lt (a + cons b n c) a.

Lemma reduce_lt_plus:
   a b c: T1,
  lt (a+ b) (a + c) lt b c.

Lemma plus_smono_LT_r (alpha:T1) :
   beta gamma, nf alpha beta t1< gamma alpha + beta t1< alpha + gamma.

Lemma LT_add (alpha beta : T1): nf alpha nf beta beta zero
                                alpha t1< alpha + beta.

Section Proof_of_mult_nf.

  Variable alpha : T1.
  Hypothesis Halpha : nf alpha.

  Let P (beta : T1) :=
    nf beta nf (alpha × beta)
               (alpha zero
                 gamma, gamma t1< beta
                              alpha × gamma t1< alpha × beta).
  Section Induction.

    Variable beta : T1.
    Hypothesis Hbeta : nf beta.
    Hypothesis IHbeta : delta, delta t1< beta P delta.

    Lemma L1 : alpha = zero P beta.

    Lemma L2 : beta = zero P beta.

    Lemma L3 n p : alpha = FS n beta = FS p P beta.

    Lemma L4 : a n b p, a zero
                               alpha = cons a n b beta = FS p
                               P beta.

    Lemma L5 a n b c p : a zero c zero
                         (cons a n b) × (cons c p zero) =
                         cons (a + c) p zero.

    Lemma L6 n c p d : c zero FS n × cons c p d = cons c p (FS n × d).

    Lemma L7 n c p : c zero FS n × cons c p zero = cons c p zero.

    Lemma L8 n c p : alpha = FS n beta = cons c p zero c zero
                      P beta.

    Lemma L9 : n c, nf c c zero FS n × c zero.

    Lemma L10 : a n b c, nf c nf (cons a n b)
                                a zero c zero
                                cons a n b × c zero.

    Lemma L11 n c p d :
      alpha = FS n beta = cons c p d c zero
      d zero P beta.

    Lemma L12 : a n b c p d , a zero c zero
                                     alpha = cons a n b
                                     beta = cons c p d
                                     P beta.

    Lemma L13 : P beta.

  End Induction.

  Lemma L14 beta : nf beta P beta.

End Proof_of_mult_nf.

Theorem mult_nf alpha beta : nf alpha nf beta
                             nf (alpha × beta).

Theorem mult_mono alpha beta gamma : nf alpha alpha zero
                                     beta t1< gamma alpha × beta t1< alpha × gamma.

Lemma nf_exp_F alpha n : nf alpha nf (exp_F alpha n).

Lemma exp_F_eq alpha n : nf alpha (exp_F alpha n = alpha ^ n)%t1.

Lemma T1limit_cases : alpha n beta,
    nf (cons alpha n beta)
    T1limit (cons alpha n beta)
    { alpha zero beta = zero} +
    {alpha zero T1limit beta }.

Lemma pred_of_succ : beta, nf beta pred (succ beta) = Some beta.

Lemma pred_of_limit : alpha, nf alpha
                                    T1limit alpha
                                    pred alpha = None.

Definition zero_limit_succ_dec :
   alpha, nf alpha
                ({alpha = zero} + {T1limit alpha }) +
                {beta : T1 | nf beta alpha = succ beta} .

Lemma pred_of_limitR : alpha, nf alpha alpha zero
                                     pred alpha = None T1limit alpha.

Lemma pred_LT : alpha beta, nf alpha pred alpha = Some beta
                                   beta t1< alpha .

Lemma pred_nf : alpha beta, nf alpha pred alpha = Some beta
                                   nf beta.

Lemma T1limit_succ : alpha, nf alpha ¬ T1limit (succ alpha) .

Lemma LT_succ : alpha, nf alpha alpha t1< succ alpha.

Lemma T1limit_not_zero : alpha, nf alpha T1limit alpha
                                        alpha zero.

#[global] Hint Resolve T1limit_not_zero : T1.

Lemma T1limit_succ_tail :
   alpha n beta, nf beta ¬ T1limit (cons alpha n (succ beta)).

Lemma succ_not_limit : alpha:T1, T1is_succ alpha T1limit alpha = false.

Lemma T1is_succ_def alpha (Halpha : nf alpha) :
  T1is_succ alpha {beta | nf beta alpha = succ beta}.

Lemma T1is_succ_iff alpha (Halpha : nf alpha) :
  T1is_succ alpha beta : T1, nf beta alpha = succ beta.

Lemma LE_r : alpha beta, alpha t1< beta alpha t1 beta.

Lemma LE_LT_eq_dec :
   alpha beta, alpha t1 beta
  {alpha t1< beta} + {alpha = beta}.

Lemma LT_eq_LT_dec : alpha beta,
    nf alpha nf beta
    {alpha t1< beta} + {alpha = beta} + {beta t1< alpha}.

Lemma lt_cons_phi0_inv alpha n beta gamma :
  cons alpha n beta t1< phi0 gamma beta t1< phi0 alpha alpha t1< gamma.

Lemma nf_LT_right : alpha n beta beta',
    nf (cons alpha n beta)
    beta' t1< beta
    nf (cons alpha n beta').

Lemma eq_succ_LT : alpha beta, nf beta alpha = succ beta
                                      beta t1< alpha.

Lemma eq_succ_lt : alpha beta, nf beta alpha = succ beta
                                      lt beta alpha.

Definition strict_lub (s : nat T1) (lambda : T1) :=
  ( i, s i t1< lambda)
  ( alpha, ( i, s i t1 alpha) lambda t1 alpha).

Definition strict_lub_lub : s l alpha, strict_lub s l
                                               ( i, s i t1 alpha)
                                               l t1 alpha.

Definition strict_lub_maj : s l , strict_lub s l
                                           i, s i t1< l.

Lemma strict_lub_unique : s l l', strict_lub s l
                                         strict_lub s l'
                                         l = l'.

Lemma strict_lub_T1limit : (alpha :T1)(s : nat T1),
    nf alpha strict_lub s alpha T1limit alpha.

Lemma lt_one (alpha:T1) : lt alpha one alpha = zero.

Lemma omega_limit : strict_lub T1nat T1omega.

Lemma LT_succ_LT_eq_dec :
   alpha beta, nf alpha nf beta
                     alpha t1< succ beta {alpha t1< beta} + {alpha = beta}.

Lemma lt_succ_le_2':
   a : T1, nf a b : T1, nf b a t1< succ b
                                        a t1< b a = b.

Lemma succ_lt_limit alpha (Halpha : nf alpha)(H : T1limit alpha ):
   beta, beta t1< alpha succ beta t1< alpha.

Lemma succ_cons alpha n beta : beta zero nf (cons alpha n beta)
                                succ (cons alpha n beta) =
                                cons alpha n (succ beta).

Lemma succ_cons' alpha i beta : alpha zero nf (cons alpha i beta)
                               succ (cons alpha i beta) =
                               cons alpha i (succ beta).

Lemma succ_rw1 : alpha n beta, alpha zero
                                      succ (cons alpha n beta)=
                                      cons alpha n (succ beta).

Lemma plus_cons_cons_eqn a n b a' n' b':
  (cons a n b) + (cons a' n' b') =
  match compare a a' with
  | Eqcons a (S (n + n')) b'
  | Ltcons a' n' b'
  | Gtcons a n (T1add b (cons a' n' b'))
  end.

Lemma T1addA (x y z :T1) : x + (y + z) = (x + y) + z.

#[global] Instance T1addAssoc : Assoc eq T1add.

Section Proof_of_dist.

   Let P (b: T1) :=
      a c, nf a nf b nf c
    a × (b + c) = a × b + a × c.


 #[local] Ltac rewrite_ind Hind b :=
    pose proof (Hind b) as ->; [ | try apply tail_LT_cons| | | ];
    eauto with T1.

 Lemma L0 : p, P p.

  Theorem mult_plus_distr_l (a b c: T1) :
    nf a nf b nf c
    a × (b + c) = a × b + a × c.

End Proof_of_dist.

An abstract syntax for ordinals in Cantor normal form


Declare Scope ppT1_scope.
Delimit Scope ppT1_scope with pT1.

Inductive ppT1 :=
| PP_fin (_ : nat)
| PP_add (_ _ : ppT1)
| PP_mult (_ : ppT1) (_ : nat)
| PP_exp (_ _ : ppT1)
| PP_omega.

Coercion PP_fin : nat >-> ppT1.

Notation "alpha + beta" := (PP_add alpha beta) : ppT1_scope.

Notation "alpha * n" := (PP_mult alpha n) : ppT1_scope.

Notation "alpha ^ beta" := (PP_exp alpha beta) : ppT1_scope.

Notation ω := PP_omega.

Check (ω ^ ω × 2 + 1)%pT1.


Fixpoint pp0 (alpha : T1) : ppT1 :=
  match alpha with
  | zeroPP_fin 0
  | cons zero n zeroPP_fin (S n)
  | cons one 0 zeroω
  | cons one 0 beta ⇒ (ω + pp0 beta)%pT1
  | cons one n zero ⇒ (ω × (S n))%pT1
  | cons one n beta ⇒ (ω × (S n) + pp0 beta)%pT1
  | cons alpha 0 zero ⇒ (ω ^ pp0 alpha)%pT1
  | cons alpha 0 beta ⇒ (ω ^ pp0 alpha + pp0 beta)%pT1
  | cons alpha n zero ⇒ (ω ^ pp0 alpha × (S n))%pT1
  | cons alpha n beta ⇒ (ω ^ pp0 alpha × (S n) + pp0 beta)%pT1
  end.

Fixpoint eval_pp (e : ppT1) : T1 :=
  match e with
    PP_fin 0 ⇒ zero
  | PP_fin nn
  | PP_add e f ⇒ ( (eval_pp e) + (eval_pp f))%t1
  | PP_mult e n ⇒ ( (eval_pp e) × (S n))%t1
  | PP_exp e f ⇒ ((eval_pp e) ^ (eval_pp f))%t1
  | ωT1omega
  end.




Fixpoint reassoc (exp : ppT1) (fuel :nat) : ppT1 :=
  match exp, fuel with
  | exp, 0 ⇒ exp
  | PP_add e (PP_add f g), S n
    reassoc (PP_add (PP_add (reassoc e n) (reassoc f n))
                   (reassoc g n)) n
  | PP_add e f , S nPP_add (reassoc e n) (reassoc f n)
  | PP_mult e i , S nPP_mult (reassoc e n) i
  | PP_exp e f , S nPP_exp (reassoc e n) (reassoc f n)
  | e, _e
  end.

Fixpoint pp_size (exp : ppT1) : nat :=
  match exp with
    PP_add e f | PP_exp e f ⇒ (S ((pp_size e) + (pp_size f)))%nat
  | PP_mult e _S (pp_size e)
  | _ ⇒ 1%nat
  end.

Definition pp (e: T1) : ppT1 := let t := pp0 e in reassoc t (pp_size t).




Eval simpl in fun n:nat
                 (pp (T1omega ^ (T1omega ^ T1omega × n + T1omega ^ n + T1omega + 1)))%t1 .

Ltac is_closed alpha :=
  match alpha with
    zeroidtac
  | 0 ⇒ idtac
  | S ?nis_closed n
  |cons ?a ?n ?bis_closed a ; is_closed n ; is_closed b
  | ?otherfail
  end.

Ltac pp0tac alpha :=
  match alpha with
  | zeroexact 0
  | cons zero ?n zeroexact (S n)
  | cons one 0 zeroexact T1omega
  | cons one 0 ?betaexact (T1omega + ltac :(pp0tac beta))%pT1
  | cons one ?n zeroexact (T1omega × (S n))%pT1
  | cons one ?n ?betaexact (T1omega × (S n) + ltac: (pp0tac beta))%pT1
  | cons ?alpha 0 zeroexact (T1omega ^ ltac: (pp0tac alpha))%pT1
  | cons ?alpha 0 ?beta
    exact (T1omega ^ ltac :(pp0tac alpha) + ltac: (pp0tac beta))%pT1
  | cons ?alpha ?n zero
    exact (T1omega ^ ltac: (pp0tac alpha) × (S n))%pT1
  | cons ?alpha ?n ?beta
    exact (T1omega ^ ltac: (pp0tac alpha) × (S n) +
                   ltac : (pp0tac beta)%pT1)
  end.

Ltac pptac term :=
  let t := eval cbn in term
    in tryif is_closed t then exact (pp t)
      else exact term.

Section essai.
  Variable n : nat.



End essai.

Check (phi0 (phi0 (FS 6))).




Examples




Example Ex1 : 42 + T1omega = T1omega.

Example Ex2 : T1omega t1< T1omega + 42.

Example Ex3 : 5 × T1omega = T1omega.

Example Ex4 : T1omega t1< T1omega × 5.


Example Ex5 : T1limit (T1omega ^ (T1omega + 5)).



Example alpha_0 : T1 :=
  cons (cons (cons zero 0 zero)
               0
               zero)
        0
        (cons (cons zero 2 zero)
               4
               (cons zero 1 zero)).














Example alpha_0_eq : alpha_0 = phi0 T1omega +
                               phi0 3 × 5 + 2.