Library SN_CIC
Strong normalization of the model of CC+NAT in the type-based
termination presentation.
This is work in progress, several lemmas of this module are admitted.
Require Import List Bool Models.
Require SN_CC_Real.
Import ZFgrothendieck.
Import ZF ZFsum ZFnats ZFrelations ZFord ZFfix.
Require Import ZFfunext ZFfixrec ZFecc ZFind_nat.
Import SN_CC_Real.
Import SN_CC_Real.CCSN.
Import SN_CC_Real.SN.
Opaque Real.
Import Sat Sat.SatSet.
Lemma Real_intro x t T :
x ∈ El T ->
(x ∈ El T -> inSAT t (Real T x)) ->
[x,t] \real T.
Lemma Real_ax x t T R :
(∀ x x', x ∈ T -> x==x' -> eqSAT (R x) (R x')) ->
([x,t] \real mkTY T R <-> x ∈ T /\ inSAT t (R x)).
Lemma Real_intro2 x t T R :
(∀ x x', x ∈ T -> x==x' -> eqSAT (R x) (R x')) ->
x ∈ T ->
(x ∈ T -> inSAT t (R x)) ->
[x,t] \real mkTY T R.
Derived rules of the basic judgements
Lemma eq_typ_betar : ∀ e N T M,
typ e N T ->
T <> kind ->
eq_typ e (App (Abs T M) N) (subst N M).
Lemma typ_var0 : ∀ e n T,
match T, nth_error e n with
Some _, value T' => T' <> kind /\ sub_typ e (lift (S n) T') T
| _,_ => False end ->
typ e (Ref n) T.
Subtyping
Definition sub_typ_covariant : ∀ e U1 U2 V1 V2,
U1 <> kind ->
eq_typ e U1 U2 ->
sub_typ (U1::e) V1 V2 ->
sub_typ e (Prod U1 V1) (Prod U2 V2).
Qed.
Universes
Ordinals
Definition Ord (o:set) : trm :=
cst o Lc.K (fun _ _ => eq_refl) (fun _ _ _ => eq_refl).
Definition Ordt (o:set) : trm :=
cst (mkTY o (fun _ => snSAT)) Lc.K (fun _ _ => eq_refl) (fun _ _ _ => eq_refl).
Definition typ_ord_kind : ∀ e o, zero ∈ o -> typ e (Ordt o) kind.
Qed.
Definition typ_ord_ord : ∀ e o o',
o < o' -> typ e (Ord o) (Ordt o').
Qed.
Definition OSucc : trm -> trm.
intros o; left; exists (fun i => osucc (int i o)) (fun j => tm j o).
Defined.
Definition OSucct : trm -> trm.
intros o; left; exists (fun i => mkTY (osucc (int i o)) (fun _ => snSAT)) (fun j => tm j o).
Defined.
Lemma tyord_inv : ∀ e i j o o',
isOrd o' ->
typ e o (Ordt o') ->
val_ok e i j ->
isOrd (int i o) /\ int i o < o' /\ Lc.sn (tm j o).
Nat
Require Import SATnat.
Opaque cNAT.
Definition Nat : trm.
left; exists (fun _ => mkTY NAT cNAT) (fun _ => Lc.K).
Defined.
Definition NatI (O:trm) : trm.
left; exists (fun i => mkTY (NATi (int i O)) cNAT) (fun j => tm j O).
Defined.
Lemma typ_natI : ∀ e eps o,
isOrd eps ->
typ e o (Ordt eps) ->
typ e (NatI o) kind.
Lemma realNati_def x t i O :
isOrd (int i O) ->
([x,t] \real int i (NatI O) <->
x ∈ NATi (int i O) /\ inSAT t (cNAT x)).
Definition Zero : trm.
left; exists (fun _ => ZERO) (fun _ => ZE).
Defined.
Lemma typ_Zero : ∀ o e O,
isOrd o ->
typ e O (Ordt o) ->
typ e Zero (NatI (OSucc O)).
Definition Succ (o:trm): trm.
left; exists (fun i => lam (int i (NatI o)) SUCC) (fun _ => SU).
Defined.
Lemma El_prod A Ar B Br :
ext_fun A B ->
El (prod(mkTY A Ar) (fun x => mkTY (B x) (Br x))) ==
cc_prod A B.
Lemma typ_succi : ∀ e o i,
isOrd o ->
typ e i (Ordt o) ->
typ e (Succ i) (Prod (NatI i) (NatI (OSucc (lift 1 i)))).
Definition Natcase (fZ fS n : trm) : trm.
left; exists (fun i => NATCASE (int i fZ) (fun k => int (V.cons k i) fS) (int i n))
(fun j => NCASE (tm j fZ) (Lc.Abs (tm (Lc.ilift j) fS)) (tm j n)).
Defined.
Instance Natcase_morph :
Proper (eq_trm ==> eq_trm ==> eq_trm ==> eq_trm) Natcase.
Qed.
Notation "'int0' x y" := (int y x) (at level 10, x at level 9, y at level 9).
Lemma Natcase_succ : ∀ o O e n fZ fS,
isOrd o ->
typ e O (Ordt o) ->
typ e n (NatI O) ->
eq_typ e (Natcase fZ fS (App (Succ O) n)) (subst n fS).
Opaque cNAT.
Definition Nat : trm.
left; exists (fun _ => mkTY NAT cNAT) (fun _ => Lc.K).
Defined.
Definition NatI (O:trm) : trm.
left; exists (fun i => mkTY (NATi (int i O)) cNAT) (fun j => tm j O).
Defined.
Lemma typ_natI : ∀ e eps o,
isOrd eps ->
typ e o (Ordt eps) ->
typ e (NatI o) kind.
Lemma realNati_def x t i O :
isOrd (int i O) ->
([x,t] \real int i (NatI O) <->
x ∈ NATi (int i O) /\ inSAT t (cNAT x)).
Definition Zero : trm.
left; exists (fun _ => ZERO) (fun _ => ZE).
Defined.
Lemma typ_Zero : ∀ o e O,
isOrd o ->
typ e O (Ordt o) ->
typ e Zero (NatI (OSucc O)).
Definition Succ (o:trm): trm.
left; exists (fun i => lam (int i (NatI o)) SUCC) (fun _ => SU).
Defined.
Lemma El_prod A Ar B Br :
ext_fun A B ->
El (prod(mkTY A Ar) (fun x => mkTY (B x) (Br x))) ==
cc_prod A B.
Lemma typ_succi : ∀ e o i,
isOrd o ->
typ e i (Ordt o) ->
typ e (Succ i) (Prod (NatI i) (NatI (OSucc (lift 1 i)))).
Definition Natcase (fZ fS n : trm) : trm.
left; exists (fun i => NATCASE (int i fZ) (fun k => int (V.cons k i) fS) (int i n))
(fun j => NCASE (tm j fZ) (Lc.Abs (tm (Lc.ilift j) fS)) (tm j n)).
Defined.
Instance Natcase_morph :
Proper (eq_trm ==> eq_trm ==> eq_trm ==> eq_trm) Natcase.
Qed.
Notation "'int0' x y" := (int y x) (at level 10, x at level 9, y at level 9).
Lemma Natcase_succ : ∀ o O e n fZ fS,
isOrd o ->
typ e O (Ordt o) ->
typ e n (NatI O) ->
eq_typ e (Natcase fZ fS (App (Succ O) n)) (subst n fS).
Admitted:
Lemma NCASE_fNAT' o f g n k (A B:family) :
isOrd o ->
k ∈ NATi (osucc o) ->
inSAT n (fNAT A k) ->
inSAT f (B ZERO) ->
inSAT g (piNATi(fun m => prodSAT (A m) (B (SUCC m)))o) ->
inSAT (NCASE f g n) (B k).
Admitted.
Lemma typ_natcase : ∀ o e O P fZ fS n,
isOrd o ->
typ e O (Ordt o) ->
typ e fZ (App P Zero) ->
typ (NatI O :: e) fS (App (lift 1 P) (App (Succ (lift 1 O)) (Ref 0))) ->
typ e n (NatI (OSucc O)) ->
typ e (Natcase fZ fS n) (App P n).
Lemma typ_natcase' : ∀ o e O P fZ fS n T,
isOrd o ->
T <> kind ->
typ e O (Ordt o) ->
sub_typ e (App P n) T ->
typ e fZ (App P Zero) ->
typ (NatI O :: e) fS
(App (lift 1 P) (App (Succ (lift 1 O)) (Ref 0))) ->
typ e n (NatI (OSucc O)) ->
typ e (Natcase fZ fS n) T.
isOrd o ->
k ∈ NATi (osucc o) ->
inSAT n (fNAT A k) ->
inSAT f (B ZERO) ->
inSAT g (piNATi(fun m => prodSAT (A m) (B (SUCC m)))o) ->
inSAT (NCASE f g n) (B k).
Admitted.
Lemma typ_natcase : ∀ o e O P fZ fS n,
isOrd o ->
typ e O (Ordt o) ->
typ e fZ (App P Zero) ->
typ (NatI O :: e) fS (App (lift 1 P) (App (Succ (lift 1 O)) (Ref 0))) ->
typ e n (NatI (OSucc O)) ->
typ e (Natcase fZ fS n) (App P n).
Lemma typ_natcase' : ∀ o e O P fZ fS n T,
isOrd o ->
T <> kind ->
typ e O (Ordt o) ->
sub_typ e (App P n) T ->
typ e fZ (App P Zero) ->
typ (NatI O :: e) fS
(App (lift 1 P) (App (Succ (lift 1 O)) (Ref 0))) ->
typ e n (NatI (OSucc O)) ->
typ e (Natcase fZ fS n) T.
Occurrences
Definition noccur (f:nat->bool) (T:trm) : Prop :=
∀ i i',
(∀ n, if f n then True else i n == i' n) ->
int i T == int i' T.
Lemma noc_var : ∀ f n, f n = false -> noccur f (Ref n).
Lemma noc_kind : ∀ f, noccur f kind.
Lemma noc_prop : ∀ f, noccur f prop.
Lemma noc_app : ∀ f a b,
noccur f a -> noccur f b -> noccur f (App a b).
Judgements with variance
Module Beq.
Definition t := bool.
Definition eq := @eq bool.
Definition eq_equiv : Equivalence eq := eq_equivalence.
End Beq.
Module B := VarMap.Make(Beq).
Module OTeq.
Definition t := option trm.
Definition eq := @eq (option trm).
Definition eq_equiv : Equivalence eq := eq_equivalence.
End OTeq.
Module OT := VarMap.Make(OTeq).
Record fenv := {
tenv : env;
ords : B.map;
fixs : OT.map
}.
Definition tinj e :=
Build_fenv e (B.nil false) (OT.nil None).
Definition push_var e T :=
Build_fenv (T::tenv e) (B.cons false (ords e)) (OT.cons None (fixs e)).
Definition push_fun e dom rng :=
Build_fenv (Prod dom rng::tenv e)
(B.cons false (ords e)) (OT.cons (Some dom) (fixs e)).
Definition push_ord e T :=
Build_fenv (T::tenv e) (B.cons true (ords e)) (OT.cons None (fixs e)).
Definition val_mono (e:fenv) i j i' j' :=
val_ok (tenv e) i j /\
val_ok (tenv e) i' j' /\
∀ n,
if ords e n then i n ⊆ i' n
else match fixs e n with
Some T => ∀ x, x ∈ El(int (V.shift (S n) i) T) -> app (i n) x == app (i' n) x
| _ => i n == i' n
end.
Lemma val_mono_refl : ∀ e i j,
val_ok (tenv e) i j -> val_mono e i j i j.
Lemma val_push_var : ∀ e i j i' j' x t x' t' T,
val_mono e i j i' j' ->
x == x' ->
[x,t] \real int i T ->
[x',t'] \real int i' T ->
T <> kind ->
val_mono (push_var e T) (V.cons x i) (I.cons t j) (V.cons x' i') (I.cons t' j').
Lemma val_push_ord : ∀ e i j i' j' x t x' t' T,
val_mono e i j i' j' ->
x ⊆ x' ->
[x,t] \real int i T ->
[x',t'] \real int i' T ->
T <> kind ->
val_mono (push_ord e T) (V.cons x i) (I.cons t j) (V.cons x' i') (I.cons t' j').
Lemma val_push_fun : ∀ e i j i' j' f tf g tg T U,
val_mono e i j i' j' ->
[f,tf] \real prod (int i T) (fun x => int (V.cons x i) U) ->
[g,tg] \real prod (int i' T) (fun x => int (V.cons x i') U) ->
fcompat (El(int i T)) f g ->
val_mono (push_fun e T U) (V.cons f i) (I.cons tf j) (V.cons g i') (I.cons tg j').
Function Extension judgment
Definition fx_extends e dom M :=
∀ i i' j j', val_mono e i j i' j' ->
fcompat (El(int i dom)) (int i M) (int i' M).
∀ i i' j j', val_mono e i j i' j' ->
fcompat (El(int i dom)) (int i M) (int i' M).
Covariance judgment
Definition fx_sub e M :=
∀ i i' j j', val_mono e i j i' j' ->
∀ x t, [x,t] \real int i M -> [x,t] \real int i' M.
Definition fx_subval e M :=
∀ i i' j j', val_mono e i j i' j' -> int i M ⊆ int i' M.
∀ i i' j j', val_mono e i j i' j' ->
∀ x t, [x,t] \real int i M -> [x,t] \real int i' M.
Definition fx_subval e M :=
∀ i i' j j', val_mono e i j i' j' -> int i M ⊆ int i' M.
Invariance
Definition fx_equals e M :=
∀ i i' j j', val_mono e i j i' j' -> int i M == int i' M.
Definition spec_var e n :=
ords e n || match fixs e n with Some _ => true | _ => false end.
Lemma fx_eq_noc : ∀ e t,
noccur (spec_var e) t ->
fx_equals e t.
Lemma fx_eq_app : ∀ e u v,
fx_equals e u ->
fx_equals e v ->
fx_equals e (App u v).
Lemma fx_eq_abs : ∀ e T M,
T <> kind ->
fx_equals e T ->
fx_equals (push_var e T) M ->
fx_equals e (Abs T M).
Lemma fx_eq_rec_call : ∀ e n x T U,
ords e n = false ->
fixs e n = Some T ->
T <> kind ->
typ (tenv e) (Ref n) (Prod (lift (S n) T) U) ->
fx_equals e x ->
typ (tenv e) x (lift (S n) T) ->
fx_equals e (App (Ref n) x).
Lemma fx_equals_subval : ∀ e M, fx_equals e M -> fx_subval e M.
Lemma fx_equals_sub : ∀ e M, fx_equals e M -> fx_sub e M.
Lemma var_sub : ∀ e n,
ords e n = true ->
fx_subval e (Ref n).
Lemma fx_sub_prod : ∀ e T U,
T <> kind ->
fx_equals e T ->
fx_sub (push_var e T) U ->
fx_sub e (Prod T U).
Lemma NATi_sub : ∀ e o O,
isOrd o ->
typ (tenv e) O (Ordt o) ->
fx_subval e O ->
fx_sub e (NatI O).
Lemma OSucc_sub : ∀ e O,
fx_subval e O ->
fx_subval e (OSucc O).
Lemma fx_abs : ∀ e U T M,
T <> kind ->
fx_sub e T ->
fx_equals (push_var e T) M ->
typ (T::tenv e) M U ->
U <> kind ->
fx_extends e T (Abs T M).
∀ i i' j j', val_mono e i j i' j' -> int i M == int i' M.
Definition spec_var e n :=
ords e n || match fixs e n with Some _ => true | _ => false end.
Lemma fx_eq_noc : ∀ e t,
noccur (spec_var e) t ->
fx_equals e t.
Lemma fx_eq_app : ∀ e u v,
fx_equals e u ->
fx_equals e v ->
fx_equals e (App u v).
Lemma fx_eq_abs : ∀ e T M,
T <> kind ->
fx_equals e T ->
fx_equals (push_var e T) M ->
fx_equals e (Abs T M).
Lemma fx_eq_rec_call : ∀ e n x T U,
ords e n = false ->
fixs e n = Some T ->
T <> kind ->
typ (tenv e) (Ref n) (Prod (lift (S n) T) U) ->
fx_equals e x ->
typ (tenv e) x (lift (S n) T) ->
fx_equals e (App (Ref n) x).
Lemma fx_equals_subval : ∀ e M, fx_equals e M -> fx_subval e M.
Lemma fx_equals_sub : ∀ e M, fx_equals e M -> fx_sub e M.
Lemma var_sub : ∀ e n,
ords e n = true ->
fx_subval e (Ref n).
Lemma fx_sub_prod : ∀ e T U,
T <> kind ->
fx_equals e T ->
fx_sub (push_var e T) U ->
fx_sub e (Prod T U).
Lemma NATi_sub : ∀ e o O,
isOrd o ->
typ (tenv e) O (Ordt o) ->
fx_subval e O ->
fx_sub e (NatI O).
Lemma OSucc_sub : ∀ e O,
fx_subval e O ->
fx_subval e (OSucc O).
Lemma fx_abs : ∀ e U T M,
T <> kind ->
fx_sub e T ->
fx_equals (push_var e T) M ->
typ (T::tenv e) M U ->
U <> kind ->
fx_extends e T (Abs T M).
Recursor (without case analysis)
Definition NatFix (O M:trm) : trm.
left.
exists (fun i =>
NATREC (fun o' f => int (V.cons f (V.cons o' i)) M) (int i O))
(fun j => NATFIX (Lc.Abs (tm (Lc.ilift (I.cons (tm j O) j)) M))).
Defined.
Typing rules of NatFix
Section NatFixRules.
Variable infty : set.
Hypothesis infty_ord : isOrd infty.
Variable E : fenv.
Let e := tenv E.
Variable O U M : trm.
Hypothesis M_nk : ~ eq_trm M kind.
Hypothesis ty_O : typ e O (Ordt infty).
Hypothesis ty_M : typ (Prod (NatI (Ref 0)) U::OSucct O::e)
M (Prod (NatI (OSucc (Ref 1)))
(lift_rec 1 1 (subst_rec (OSucc (Ref 0)) 1 (lift_rec 1 2 U)))).
Hypothesis stab : fx_extends
(push_fun (push_ord E (OSucct O)) (NatI (Ref 0)) U)
(NatI (OSucc (Ref 1)))
M.
Let F i := fun o' f => int (V.cons f (V.cons o' i)) M.
Lemma morph_fix_body : ∀ i, morph2 (F i).
Lemma ext_fun_ty : ∀ o i,
ext_fun (NATi o) (fun x => int (V.cons x (V.cons o i)) U).
Hypothesis fx_sub_U :
fx_sub (push_var (push_ord E (OSucct O)) (NatI (OSucc (Ref 0)))) U.
Lemma ty_fix_body : ∀ i j o f,
val_ok e i j ->
o < osucc (int i O) ->
f ∈ cc_prod (NATi o) (fun x => El(int (V.cons x (V.cons o i)) U)) ->
F i o f ∈
cc_prod (NATi (osucc o)) (fun x => El(int (V.cons x (V.cons (osucc o) i)) U)).
Lemma fix_body_irrel : ∀ i j,
val_ok e i j ->
NAT_ord_irrel (int i O) (F i) (fun o' x => El(int (V.cons x (V.cons o' i)) U)).
Lemma fix_codom_mono : ∀ o o' x x' i j,
val_ok e i j ->
isOrd o' ->
o' ⊆ int i O ->
isOrd o ->
o ⊆ o' ->
x ∈ NATi o ->
x == x' ->
El (int (V.cons x (V.cons o i)) U) ⊆ El(int (V.cons x' (V.cons o' i)) U).
Hint Resolve morph_fix_body ext_fun_ty ty_fix_body fix_codom_mono fix_body_irrel.
Let fix_typ o i j:
val_ok e i j ->
isOrd o ->
isOrd (int i O) ->
o ⊆ int i O ->
NATREC (F i) o
∈ cc_prod (NATi o) (fun n => El (int (V.cons n (V.cons o i)) U)).
Qed.
Lemma fix_irr i j o o' x :
val_ok e i j ->
isOrd o ->
isOrd o' ->
isOrd (int i O) ->
o ⊆ o' ->
o' ⊆ int i O ->
x ∈ NATi o ->
cc_app (NATREC (F i) o) x == cc_app (NATREC (F i) o') x.
Lemma fix_eqn : ∀ i j o n,
val_ok e i j ->
isOrd o ->
isOrd (int i O) ->
o ⊆ int i O ->
n ∈ NATi (osucc o) ->
cc_app (NATREC (F i) (osucc o)) n ==
cc_app (int (V.cons (NATREC (F i) o) (V.cons o i)) M) n.
Lemma nat_fix_eqn : ∀ i j,
val_ok e i j ->
NATREC (F i) (int i O) ==
cc_lam (NATi (int i O))
(fun x => cc_app (F i (int i O) (NATREC (F i) (int i O))) x).
Lemma equiv_piSAT_piNAT o B B' f:
isOrd o ->
(∀ n, n ∈ NATi o -> eqSAT (Real (B n) (f n)) (B' n)) ->
eqSAT (piSAT (mkTY (NATi o) cNAT) B f)
(piNATi (fun n => prodSAT (cNAT n) (B' n)) o).
Lemma typ_nat_fix :
typ e (NatFix O M) (Prod (NatI O) (subst_rec O 1 U)).
Lemma nat_fix_eq : ∀ N,
typ e N (NatI O) ->
eq_typ e (App (NatFix O M) N)
(App (subst O (subst (lift 1 (NatFix O M)) M)) N).
Lemma nat_fix_extend :
fx_subval E O ->
fx_extends E (NatI O) (NatFix O M).
Lemma nat_fix_equals :
fx_equals E O ->
fx_equals E (NatFix O M).
End NatFixRules.
Print Assumptions typ_nat_fix.
Lemma typ_nat_fix' : ∀ infty e O U M T,
T <> kind ->
isOrd infty ->
typ e O (Ordt infty) ->
typ (Prod (NatI (Ref 0)) U :: OSucct O :: e) M
(Prod (NatI (OSucc (Ref 1)))
(lift_rec 1 1 (subst_rec (OSucc (Ref 0)) 1 (lift_rec 1 2 U)))) ->
fx_extends (push_fun (push_ord (tinj e) (OSucct O)) (NatI (Ref 0)) U)
(NatI (OSucc (Ref 1))) M ->
fx_sub (push_var (push_ord (tinj e) (OSucct O)) (NatI (OSucc (Ref 0)))) U ->
sub_typ e (Prod (NatI O) (subst_rec O 1 U)) T ->
typ e (NatFix O M) T.
Compound judgements : typing + variance
Definition typ_ext e M A B :=
fx_extends e A M /\ typ (tenv e) M (Prod A B).
Definition typ_mono e M :=
fx_sub e M /\ typs (tenv e) M.
Definition typ_monoval e M T :=
fx_subval e M /\ typ (tenv e) M T.
Definition typ_impl e M T :=
fx_equals e M /\ typ (tenv e) M T.
Instance typ_impl_morph e : Proper (eq_trm ==> eq_trm ==> iff) (typ_impl e).
Qed.
Lemma typ_var_impl : ∀ e n t T,
spec_var e n = false ->
nth_error (tenv e) n = value t ->
t <> kind ->
T <> kind ->
sub_typ (tenv e) (lift (S n) t) T ->
typ_impl e (Ref n) T.
Lemma impl_abs : ∀ e s1 U T T' M,
T <> kind ->
U <> kind ->
s1=prop \/ s1=kind ->
eq_typ (tenv e) T T' ->
typ_impl e T s1 ->
typ_impl (push_var e T) M U ->
typ_impl e (Abs T M) (Prod T' U).
Lemma impl_app : ∀ e u v V Ur T,
T <> kind ->
V <> kind ->
Ur <> kind ->
sub_typ (tenv e) (subst v Ur) T ->
typ_impl e u (Prod V Ur) ->
typ_impl e v V ->
typ_impl e (App u v) T.
Lemma NATi_fx_sub : ∀ e o O,
isOrd o ->
typ_monoval e O (Ordt o) ->
fx_sub e (NatI O).
Lemma OSucc_fx_sub : ∀ e O o,
isOrd o ->
typ_monoval e O (Ordt o)->
typ_monoval e (OSucc O) (Ordt (osucc o)).
Lemma typ_var_mono : ∀ e n t T,
ords e n = true ->
nth_error (tenv e) n = value t ->
T <> kind ->
t <> kind ->
sub_typ (tenv e) (lift (S n) t) T ->
typ_monoval e (Ref n) T.
Lemma ext_abs : ∀ e U T M,
T <> kind ->
U <> kind ->
typ_mono e T ->
typ_impl (push_var e T) M U ->
typ_ext e (Abs T M) T U.
Lemma impl_call : ∀ e n x t u T,
ords e n = false ->
fixs e n = Some t ->
T <> kind ->
t <> kind ->
u <> kind ->
nth_error (tenv e) n = value (Prod t u) ->
sub_typ (tenv e) (subst x (lift_rec (S n) 1 u)) T ->
typ_impl e x (lift (S n) t) ->
typ_impl e (App (Ref n) x) T.
Lemma typ_nat_fix'' : ∀ infty e O U M T,
isOrd infty ->
T <> kind ->
sub_typ (tenv e) (Prod (NatI O) (subst_rec O 1 U)) T ->
typ (tenv e) O (Ordt infty) ->
typ_mono (push_var (push_ord e (OSucct O)) (NatI (OSucc (Ref 0)))) U ->
typ_ext (push_fun (push_ord e (OSucct O)) (NatI (Ref 0)) U)
M (NatI (OSucc (Ref 1)))
(lift_rec 1 1 (subst_rec (OSucc (Ref 0)) 1 (lift_rec 1 2 U))) ->
typ (tenv e) (NatFix O M) T.
Lemma typ_ext_fix : ∀ eps e O U M,
isOrd eps ->
typ_monoval e O (Ordt eps) ->
typ_ext (push_fun (push_ord e (OSucct O)) (NatI (Ref 0)) U) M
(NatI (OSucc (Ref 1))) (lift_rec 1 1 (subst_rec (OSucc (Ref 0)) 1 (lift_rec 1 2 U))) ->
fx_sub (push_var (push_ord e (OSucct O)) (NatI (OSucc (Ref 0)))) U ->
typ_ext e (NatFix O M) (NatI O) (subst_rec O 1 U).
Lemma typ_impl_fix : ∀ eps e O U M,
isOrd eps ->
typ_impl e O (Ordt eps) ->
typ_ext (push_fun (push_ord e (OSucct O)) (NatI (Ref 0)) U) M
(NatI (OSucc (Ref 1))) (lift_rec 1 1 (subst_rec (OSucc (Ref 0)) 1 (lift_rec 1 2 U))) ->
fx_sub (push_var (push_ord e (OSucct O)) (NatI (OSucc (Ref 0)))) U ->
typ_impl e (NatFix O M) (Prod (NatI O) (subst_rec O 1 U)).