Reasoning Details

 < Module lambda_calculus:typing.
 < Prove_Constraint lambda_calculus:host:proj_is.

Variables: Body X Ty
Hyp : |{e}- tyabs X Ty Body ~~> abs X Body
Hyp1 : is_e (tyabs X Ty Body)
============================
 is_e (abs X Body)
 < case Hyp1.

Variables: Body X Ty
Hyp : |{e}- tyabs X Ty Body ~~> abs X Body
H1 : is_string X
H2 : is_ty Ty
H3 : is_e Body
============================
 is_e (abs X Body)
 < search.

Proof completed.
 < Add_Proj_Rel lambda_calculus:host:is_e.

Proof completed.
 < Prove_Ext_Ind lambda_calculus:host:is_e.

Warning:  No definition of Ext Size for all relations in Ext Ind; defaulting to proving Ext Ind without Ext Size
Subgoal 6:

Variables: E1 Ty S
IH : forall E, is_e E * -> <is_e {P}> E
R : is_e (tyabs S Ty E1) @
R1 : is_string S
R2 : is_ty Ty
R3 : is_e E1 *
============================
 <is_e {P}> (tyabs S Ty E1)
 < apply IH to R3.

Subgoal 6:

Variables: E1 Ty S
IH : forall E, is_e E * -> <is_e {P}> E
R : is_e (tyabs S Ty E1) @
R1 : is_string S
R2 : is_ty Ty
R3 : is_e E1 *
H1 : <is_e {P}> E1
============================
 <is_e {P}> (tyabs S Ty E1)
 < search.

Proof completed.
 < Prove_Constraint lambda_calculus:host:proj_same.

Variables: E2 Body X Ty
Hyp : |{e}- tyabs X Ty Body ~~> abs X Body
Hyp1 : |{e}- tyabs X Ty Body ~~> E2
============================
 abs X Body = E2
 < case Hyp1.

Variables: Body X Ty
Hyp : |{e}- tyabs X Ty Body ~~> abs X Body
============================
 abs X Body = abs X Body
 < search.

Proof completed.
 < Prove lambda_calculus:host:subst_exists.

Subgoal 6:

Variables: X R E1 Ty S
IH : forall X R E, is_e E * -> is_string X -> is_e R -> exists S, subst X R E S
IsE : is_e (tyabs S Ty E1) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
============================
 exists S1, subst X R (tyabs S Ty E1) S1
 < Or: apply is_string_eq_or_not to IsX IsE1.

Subgoal 6:

Variables: X R E1 Ty S
IH : forall X R E, is_e E * -> is_string X -> is_e R -> exists S, subst X R E S
IsE : is_e (tyabs S Ty E1) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
Or : X = S \/ (X = S -> false)
============================
 exists S1, subst X R (tyabs S Ty E1) S1
 < Eq: case Or.

Subgoal 6.1:

Variables: R E1 Ty S
IH : forall X R E, is_e E * -> is_string X -> is_e R -> exists S, subst X R E S
IsE : is_e (tyabs S Ty E1) @
IsX : is_string S
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
============================
 exists S1, subst S R (tyabs S Ty E1) S1
 < search.

Subgoal 6.2:

Variables: X R E1 Ty S
IH : forall X R E, is_e E * -> is_string X -> is_e R -> exists S, subst X R E S
IsE : is_e (tyabs S Ty E1) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
Eq : X = S -> false
============================
 exists S1, subst X R (tyabs S Ty E1) S1
 < apply IH to IsE3 IsX IsR.

Subgoal 6.2:

Variables: X R E1 Ty S S1
IH : forall X R E, is_e E * -> is_string X -> is_e R -> exists S, subst X R E S
IsE : is_e (tyabs S Ty E1) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
Eq : X = S -> false
H1 : subst X R E1 S1
============================
 exists S1, subst X R (tyabs S Ty E1) S1
 < search.

Proof completed.
 < Prove lambda_calculus:host:subst_is.

Subgoal 8:

Variables: X R Body Ty
IH : forall X R E S,
       is_e E -> is_string X -> is_e R -> subst X R E S * -> is_e S
IsE : is_e (tyabs X Ty Body)
IsX : is_string X
IsR : is_e R
S : subst X R (tyabs X Ty Body) (abs X Body) @
============================
 is_e (abs X Body)
 < case IsE.

Subgoal 8:

Variables: X R Body Ty
IH : forall X R E S,
       is_e E -> is_string X -> is_e R -> subst X R E S * -> is_e S
IsX : is_string X
IsR : is_e R
S : subst X R (tyabs X Ty Body) (abs X Body) @
H1 : is_string X
H2 : is_ty Ty
H3 : is_e Body
============================
 is_e (abs X Body)
 < search.

Subgoal 9:

Variables: X R B Y Body Ty
IH : forall X R E S,
       is_e E -> is_string X -> is_e R -> subst X R E S * -> is_e S
IsE : is_e (tyabs Y Ty Body)
IsX : is_string X
IsR : is_e R
S : subst X R (tyabs Y Ty Body) (abs Y B) @
S1 : X = Y -> false
S2 : subst X R Body B *
============================
 is_e (abs Y B)
 < Is: case IsE.

Subgoal 9:

Variables: X R B Y Body Ty
IH : forall X R E S,
       is_e E -> is_string X -> is_e R -> subst X R E S * -> is_e S
IsX : is_string X
IsR : is_e R
S : subst X R (tyabs Y Ty Body) (abs Y B) @
S1 : X = Y -> false
S2 : subst X R Body B *
Is : is_string Y
Is1 : is_ty Ty
Is2 : is_e Body
============================
 is_e (abs Y B)
 < apply IH to _ _ _ S2.

Subgoal 9:

Variables: X R B Y Body Ty
IH : forall X R E S,
       is_e E -> is_string X -> is_e R -> subst X R E S * -> is_e S
IsX : is_string X
IsR : is_e R
S : subst X R (tyabs Y Ty Body) (abs Y B) @
S1 : X = Y -> false
S2 : subst X R Body B *
Is : is_string Y
Is1 : is_ty Ty
Is2 : is_e Body
H1 : is_e B
============================
 is_e (abs Y B)
 < search.

Proof completed.
 < Prove lambda_calculus:host:eval_is.

Subgoal 5:

Variables: Body X Ty
IH : forall E V, is_e E -> eval E V * -> is_e V
IsE : is_e (tyabs X Ty Body)
Ev : eval (tyabs X Ty Body) (abs X Body) @
============================
 is_e (abs X Body)
 < Is: case IsE.

Subgoal 5:

Variables: Body X Ty
IH : forall E V, is_e E -> eval E V * -> is_e V
Ev : eval (tyabs X Ty Body) (abs X Body) @
Is : is_string X
Is1 : is_ty Ty
Is2 : is_e Body
============================
 is_e (abs X Body)
 < search.

Proof completed.
 < Prove lambda_calculus:host:subst_unique.

Subgoal 8:

Variables: X R SB Body Ty
IH : forall X R E SA SB,
       is_e E -> is_string X -> is_e R -> subst X R E SA * -> subst X R E SB -> SA = SB
IsE : is_e (tyabs X Ty Body)
IsX : is_string X
IsR : is_e R
SA : subst X R (tyabs X Ty Body) (abs X Body) @
SB : subst X R (tyabs X Ty Body) SB
============================
 abs X Body = SB
 < SB: case SB.

Subgoal 8.1:

Variables: X R Body Ty
IH : forall X R E SA SB,
       is_e E -> is_string X -> is_e R -> subst X R E SA * -> subst X R E SB -> SA = SB
IsE : is_e (tyabs X Ty Body)
IsX : is_string X
IsR : is_e R
SA : subst X R (tyabs X Ty Body) (abs X Body) @
============================
 abs X Body = abs X Body
 < search.

Subgoal 8.2:

Variables: X R Body Ty B
IH : forall X R E SA SB,
       is_e E -> is_string X -> is_e R -> subst X R E SA * -> subst X R E SB -> SA = SB
IsE : is_e (tyabs X Ty Body)
IsX : is_string X
IsR : is_e R
SA : subst X R (tyabs X Ty Body) (abs X Body) @
SB : X = X -> false
SB1 : subst X R Body B
============================
 abs X Body = abs X B
 < apply SB to _.

Subgoal 9:

Variables: X R SB B Y Body Ty
IH : forall X R E SA SB,
       is_e E -> is_string X -> is_e R -> subst X R E SA * -> subst X R E SB -> SA = SB
IsE : is_e (tyabs Y Ty Body)
IsX : is_string X
IsR : is_e R
SA : subst X R (tyabs Y Ty Body) (abs Y B) @
SB : subst X R (tyabs Y Ty Body) SB
SA1 : X = Y -> false
SA2 : subst X R Body B *
============================
 abs Y B = SB
 < SB: case SB.

Subgoal 9.1:

Variables: R B Y Body Ty
IH : forall X R E SA SB,
       is_e E -> is_string X -> is_e R -> subst X R E SA * -> subst X R E SB -> SA = SB
IsE : is_e (tyabs Y Ty Body)
IsX : is_string Y
IsR : is_e R
SA : subst Y R (tyabs Y Ty Body) (abs Y B) @
SA1 : Y = Y -> false
SA2 : subst Y R Body B *
============================
 abs Y B = abs Y Body
 < apply SA1 to _.

Subgoal 9.2:

Variables: X R B Y Body Ty B1
IH : forall X R E SA SB,
       is_e E -> is_string X -> is_e R -> subst X R E SA * -> subst X R E SB -> SA = SB
IsE : is_e (tyabs Y Ty Body)
IsX : is_string X
IsR : is_e R
SA : subst X R (tyabs Y Ty Body) (abs Y B) @
SA1 : X = Y -> false
SA2 : subst X R Body B *
SB : X = Y -> false
SB1 : subst X R Body B1
============================
 abs Y B = abs Y B1
 < Is: case IsE.

Subgoal 9.2:

Variables: X R B Y Body Ty B1
IH : forall X R E SA SB,
       is_e E -> is_string X -> is_e R -> subst X R E SA * -> subst X R E SB -> SA = SB
IsX : is_string X
IsR : is_e R
SA : subst X R (tyabs Y Ty Body) (abs Y B) @
SA1 : X = Y -> false
SA2 : subst X R Body B *
SB : X = Y -> false
SB1 : subst X R Body B1
Is : is_string Y
Is1 : is_ty Ty
Is2 : is_e Body
============================
 abs Y B = abs Y B1
 < apply IH to _ _ _ SA2 SB1.

Subgoal 9.2:

Variables: X R Y Body Ty B1
IH : forall X R E SA SB,
       is_e E -> is_string X -> is_e R -> subst X R E SA * -> subst X R E SB -> SA = SB
IsX : is_string X
IsR : is_e R
SA : subst X R (tyabs Y Ty Body) (abs Y B1) @
SA1 : X = Y -> false
SA2 : subst X R Body B1 *
SB : X = Y -> false
SB1 : subst X R Body B1
Is : is_string Y
Is1 : is_ty Ty
Is2 : is_e Body
============================
 abs Y B1 = abs Y B1
 < search.

Proof completed.
 < Prove lambda_calculus:host:eval_unique.

Subgoal 5:

Variables: VB Body X Ty
IH : forall E VA VB, is_e E -> eval E VA * -> eval E VB -> VA = VB
IsE : is_e (tyabs X Ty Body)
EvA : eval (tyabs X Ty Body) (abs X Body) @
EvB : eval (tyabs X Ty Body) VB
============================
 abs X Body = VB
 < case EvB.

Subgoal 5:

Variables: Body X Ty
IH : forall E VA VB, is_e E -> eval E VA * -> eval E VB -> VA = VB
IsE : is_e (tyabs X Ty Body)
EvA : eval (tyabs X Ty Body) (abs X Body) @
============================
 abs X Body = abs X Body
 < search.

Proof completed.
 < Prove_Constraint lambda_calculus:host:proj_subst.

Variables: X R S Body X1 Ty
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X
IsR : is_e R
S : subst X R (tyabs X1 Ty Body) S
============================
 exists S', subst X R (abs X1 Body) S'
 < S: case S.

Subgoal 1:

Variables: R Body X1 Ty
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X1
IsR : is_e R
============================
 exists S', subst X1 R (abs X1 Body) S'
 < search.

Subgoal 2:

Variables: X R Body X1 Ty B
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X
IsR : is_e R
S : X = X1 -> false
S1 : subst X R Body B
============================
 exists S', subst X R (abs X1 Body) S'
 < search.

Proof completed.
 < Prove_Constraint lambda_calculus:host:proj_subst_same.

Variables: X R S S' Body X1 Ty
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X
IsR : is_e R
S : subst X R (tyabs X1 Ty Body) S
S' : subst X R (abs X1 Body) S'
============================
 S = S'
 < S: case S.

Subgoal 1:

Variables: R S' Body X1 Ty
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X1
IsR : is_e R
S' : subst X1 R (abs X1 Body) S'
============================
 abs X1 Body = S'
 < S': case S'.

Subgoal 1.1:

Variables: R Body X1 Ty
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X1
IsR : is_e R
============================
 abs X1 Body = abs X1 Body
 < search.

Subgoal 1.2:

Variables: R Body X1 Ty B
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X1
IsR : is_e R
S' : X1 = X1 -> false
S'1 : subst X1 R Body B
============================
 abs X1 Body = abs X1 B
 < apply S' to _.

Subgoal 2:

Variables: X R S' Body X1 Ty B
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X
IsR : is_e R
S' : subst X R (abs X1 Body) S'
S : X = X1 -> false
S1 : subst X R Body B
============================
 abs X1 B = S'
 < S': case S'.

Subgoal 2.1:

Variables: R Body X1 Ty B
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X1
IsR : is_e R
S : X1 = X1 -> false
S1 : subst X1 R Body B
============================
 abs X1 B = abs X1 Body
 < apply S to _.

Subgoal 2.2:

Variables: X R Body X1 Ty B B1
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsE : is_e (tyabs X1 Ty Body)
IsX : is_string X
IsR : is_e R
S : X = X1 -> false
S1 : subst X R Body B
S' : X = X1 -> false
S'1 : subst X R Body B1
============================
 abs X1 B = abs X1 B1
 < case IsE.

Subgoal 2.2:

Variables: X R Body X1 Ty B B1
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsX : is_string X
IsR : is_e R
S : X = X1 -> false
S1 : subst X R Body B
S' : X = X1 -> false
S'1 : subst X R Body B1
H1 : is_string X1
H2 : is_ty Ty
H3 : is_e Body
============================
 abs X1 B = abs X1 B1
 < apply subst_unique to _ _ _ S1 S'1.

Subgoal 2.2:

Variables: X R Body X1 Ty B1
Proj : |{e}- tyabs X1 Ty Body ~~> abs X1 Body
IsX : is_string X
IsR : is_e R
S : X = X1 -> false
S1 : subst X R Body B1
S' : X = X1 -> false
S'1 : subst X R Body B1
H1 : is_string X1
H2 : is_ty Ty
H3 : is_e Body
============================
 abs X1 B1 = abs X1 B1
 < search.

Proof completed.
 < Prove_Constraint lambda_calculus:host:proj_eval.

Variables: V Body X Ty
Proj : |{e}- tyabs X Ty Body ~~> abs X Body
IsE : is_e (tyabs X Ty Body)
Ev : eval (tyabs X Ty Body) V
============================
 exists V', eval (abs X Body) V'
 < case Ev.

Variables: Body X Ty
Proj : |{e}- tyabs X Ty Body ~~> abs X Body
IsE : is_e (tyabs X Ty Body)
============================
 exists V', eval (abs X Body) V'
 < search.

Proof completed.
 < Prove_Constraint lambda_calculus:host:proj_eval_same.

Variables: V V' Body X Ty
Proj : |{e}- tyabs X Ty Body ~~> abs X Body
IsE : is_e (tyabs X Ty Body)
Ev : eval (tyabs X Ty Body) V
Ev' : eval (abs X Body) V'
============================
 V = V'
 < case Ev.

Variables: V' Body X Ty
Proj : |{e}- tyabs X Ty Body ~~> abs X Body
IsE : is_e (tyabs X Ty Body)
Ev' : eval (abs X Body) V'
============================
 abs X Body = V'
 < case Ev'.

Variables: Body X Ty
Proj : |{e}- tyabs X Ty Body ~~> abs X Body
IsE : is_e (tyabs X Ty Body)
============================
 abs X Body = abs X Body
 < search.

Proof completed.
 < Add_Ext_Size lambda_calculus:host:eval.

Proof completed.
 < Add_Proj_Rel lambda_calculus:host:eval.

Proof completed.
 < Prove_Ext_Ind lambda_calculus:host:eval.

Subgoal 5:

Variables: Body X Ty
IH : forall N E V, <eval {ES}> E V N -> acc N * -> <eval {P}> E V
IH1 : forall N E V, <eval {ES}> E V N ** -> acc N @ -> <eval {P}> E V
R : <eval {ES}> (tyabs X Ty Body) (abs X Body) 1 @@
Acc : acc 1 @
============================
 <eval {P}> (tyabs X Ty Body) (abs X Body)
 < search.

Proof completed.
 < Extensible_Theorem
      type_weakening : forall G E Ty G',
         IsE : is_e E ->
         Ty : typeOf G E Ty ->
         Lkp : (forall X XTy,
           lookup G X XTy -> lookup G' X XTy) ->
         typeOf G' E Ty
      on Ty.

Subgoal 1:

Variables: G Ty G' X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e (var X)
Ty : typeOf G (var X) Ty @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : lookup G X Ty
============================
 typeOf G' (var X) Ty
 < apply Lkp to Ty1.

Subgoal 1:

Variables: G Ty G' X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e (var X)
Ty : typeOf G (var X) Ty @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : lookup G X Ty
H1 : lookup G' X Ty
============================
 typeOf G' (var X) Ty
 < search.

Subgoal 2:

Variables: G G' Ty2 Ty1 Body X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e (abs X Body)
Ty : typeOf G (abs X Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
============================
 typeOf G' (abs X Body) (arrowTy Ty1 Ty2)
 < Is: case IsE.

Subgoal 2:

Variables: G G' Ty2 Ty1 Body X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (abs X Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_e Body
============================
 typeOf G' (abs X Body) (arrowTy Ty1 Ty2)
 < apply IH to _ Ty1 _ with
     G' = (X, Ty1)::G'.

Subgoal 2.1:

Variables: G G' Ty2 Ty1 Body X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (abs X Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_e Body
============================
 forall X1 XTy, lookup ((X, Ty1)::G) X1 XTy -> lookup ((X, Ty1)::G') X1 XTy
 < intros L.

Subgoal 2.1:

Variables: G G' Ty2 Ty1 Body X X1 XTy
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (abs X Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_e Body
L : lookup ((X, Ty1)::G) X1 XTy
============================
 lookup ((X, Ty1)::G') X1 XTy
 < L: case L.

Subgoal 2.1.1:

Variables: G G' Ty2 Body X1 XTy
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (abs X1 Body) (arrowTy XTy Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X1, XTy)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
============================
 lookup ((X1, XTy)::G') X1 XTy
 < search.

Subgoal 2.1.2:

Variables: G G' Ty2 Ty1 Body X X1 XTy
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (abs X Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_e Body
L : X = X1 -> false
L1 : lookup G X1 XTy
============================
 lookup ((X, Ty1)::G') X1 XTy
 < apply Lkp to L1.

Subgoal 2.1.2:

Variables: G G' Ty2 Ty1 Body X X1 XTy
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (abs X Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_e Body
L : X = X1 -> false
L1 : lookup G X1 XTy
H1 : lookup G' X1 XTy
============================
 lookup ((X, Ty1)::G') X1 XTy
 < search.

Subgoal 2:

Variables: G G' Ty2 Ty1 Body X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (abs X Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_e Body
H1 : typeOf ((X, Ty1)::G') Body Ty2
============================
 typeOf G' (abs X Body) (arrowTy Ty1 Ty2)
 < search.

Subgoal 3:

Variables: G G' Ty2 Ty1 Body X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e (tyabs X Ty1 Body)
Ty : typeOf G (tyabs X Ty1 Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
============================
 typeOf G' (tyabs X Ty1 Body) (arrowTy Ty1 Ty2)
 < Is: case IsE.

Subgoal 3:

Variables: G G' Ty2 Ty1 Body X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (tyabs X Ty1 Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_ty Ty1
Is2 : is_e Body
============================
 typeOf G' (tyabs X Ty1 Body) (arrowTy Ty1 Ty2)
 < apply IH to _ Ty1 _ with
     G' = (X, Ty1)::G'.

Subgoal 3.1:

Variables: G G' Ty2 Ty1 Body X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (tyabs X Ty1 Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_ty Ty1
Is2 : is_e Body
============================
 forall X1 XTy, lookup ((X, Ty1)::G) X1 XTy -> lookup ((X, Ty1)::G') X1 XTy
 < intros L.

Subgoal 3.1:

Variables: G G' Ty2 Ty1 Body X X1 XTy
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (tyabs X Ty1 Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_ty Ty1
Is2 : is_e Body
L : lookup ((X, Ty1)::G) X1 XTy
============================
 lookup ((X, Ty1)::G') X1 XTy
 < L: case L.

Subgoal 3.1.1:

Variables: G G' Ty2 Body X1 XTy
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (tyabs X1 XTy Body) (arrowTy XTy Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X1, XTy)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty XTy
Is2 : is_e Body
============================
 lookup ((X1, XTy)::G') X1 XTy
 < search.

Subgoal 3.1.2:

Variables: G G' Ty2 Ty1 Body X X1 XTy
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (tyabs X Ty1 Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_ty Ty1
Is2 : is_e Body
L : X = X1 -> false
L1 : lookup G X1 XTy
============================
 lookup ((X, Ty1)::G') X1 XTy
 < apply Lkp to L1.

Subgoal 3.1.2:

Variables: G G' Ty2 Ty1 Body X X1 XTy
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (tyabs X Ty1 Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_ty Ty1
Is2 : is_e Body
L : X = X1 -> false
L1 : lookup G X1 XTy
H1 : lookup G' X1 XTy
============================
 lookup ((X, Ty1)::G') X1 XTy
 < search.

Subgoal 3:

Variables: G G' Ty2 Ty1 Body X
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (tyabs X Ty1 Body) (arrowTy Ty1 Ty2) @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_ty Ty1
Is2 : is_e Body
H1 : typeOf ((X, Ty1)::G') Body Ty2
============================
 typeOf G' (tyabs X Ty1 Body) (arrowTy Ty1 Ty2)
 < search.

Subgoal 4:

Variables: G Ty G' Ty1 E2 E1
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e (app E1 E2)
Ty : typeOf G (app E1 E2) Ty @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf G E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf G E2 Ty1 *
============================
 typeOf G' (app E1 E2) Ty
 < Is: case IsE.

Subgoal 4:

Variables: G Ty G' Ty1 E2 E1
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (app E1 E2) Ty @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf G E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf G E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
============================
 typeOf G' (app E1 E2) Ty
 < apply IH to _ Ty1 _.

Subgoal 4:

Variables: G Ty G' Ty1 E2 E1
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (app E1 E2) Ty @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf G E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf G E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
H1 : typeOf G' E1 (arrowTy Ty1 Ty)
============================
 typeOf G' (app E1 E2) Ty
 < apply IH to _ Ty2 _.

Subgoal 4:

Variables: G Ty G' Ty1 E2 E1
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (app E1 E2) Ty @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf G E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf G E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
H1 : typeOf G' E1 (arrowTy Ty1 Ty)
H2 : typeOf G' E2 Ty1
============================
 typeOf G' (app E1 E2) Ty
 < search.

Subgoal 5:

Variables: G G' I
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e (intE I)
Ty : typeOf G (intE I) intTy @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
============================
 typeOf G' (intE I) intTy
 < search.

Subgoal 6:

Variables: G G' E2 E1
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e (plus E1 E2)
Ty : typeOf G (plus E1 E2) intTy @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf G E1 intTy *
Ty2 : typeOf G E2 intTy *
============================
 typeOf G' (plus E1 E2) intTy
 < case IsE.

Subgoal 6:

Variables: G G' E2 E1
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (plus E1 E2) intTy @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf G E1 intTy *
Ty2 : typeOf G E2 intTy *
H1 : is_e E1
H2 : is_e E2
============================
 typeOf G' (plus E1 E2) intTy
 < apply IH to _ Ty1 Lkp.

Subgoal 6:

Variables: G G' E2 E1
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (plus E1 E2) intTy @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf G E1 intTy *
Ty2 : typeOf G E2 intTy *
H1 : is_e E1
H2 : is_e E2
H3 : typeOf G' E1 intTy
============================
 typeOf G' (plus E1 E2) intTy
 < apply IH to _ Ty2 Lkp.

Subgoal 6:

Variables: G G' E2 E1
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
Ty : typeOf G (plus E1 E2) intTy @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : typeOf G E1 intTy *
Ty2 : typeOf G E2 intTy *
H1 : is_e E1
H2 : is_e E2
H3 : typeOf G' E1 intTy
H4 : typeOf G' E2 intTy
============================
 typeOf G' (plus E1 E2) intTy
 < search.

Subgoal 7:

Variables: G Ty G' E_T
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e <unknown I e>
Ty : typeOf G <unknown I e> Ty @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : |{e}- <unknown I e> ~~> E_T
Ty2 : typeOf G E_T Ty *
============================
 typeOf G' <unknown I e> Ty
 < apply proj_is to Ty1 IsE.

Subgoal 7:

Variables: G Ty G' E_T
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e <unknown I e>
Ty : typeOf G <unknown I e> Ty @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : |{e}- <unknown I e> ~~> E_T
Ty2 : typeOf G E_T Ty *
H1 : is_e E_T
============================
 typeOf G' <unknown I e> Ty
 < apply IH to _ Ty2 _.

Subgoal 7:

Variables: G Ty G' E_T
IH : forall G E Ty G',
       is_e E -> typeOf G E Ty * -> (forall X XTy,
         lookup G X XTy -> lookup G' X XTy) -> typeOf G' E Ty
IsE : is_e <unknown I e>
Ty : typeOf G <unknown I e> Ty @
Lkp : forall X XTy, lookup G X XTy -> lookup G' X XTy
Ty1 : |{e}- <unknown I e> ~~> E_T
Ty2 : typeOf G E_T Ty *
H1 : is_e E_T
H2 : typeOf G' E_T Ty
============================
 typeOf G' <unknown I e> Ty
 < search.

Proof completed.
 < Theorem any_ctx :
     forall E Ty G, is_e E -> typeOf [] E Ty -> typeOf G E Ty.

============================
 forall E Ty G, is_e E -> typeOf [] E Ty -> typeOf G E Ty
 < intros Is Ty.

Variables: E Ty G
Is : is_e E
Ty : typeOf [] E Ty
============================
 typeOf G E Ty
 < backchain type_weakening to
   G = [].

Variables: E Ty G
Is : is_e E
Ty : typeOf [] E Ty
============================
 forall X XTy, lookup [] X XTy -> lookup G X XTy
 < intros L.

Variables: E Ty G X XTy
Is : is_e E
Ty : typeOf [] E Ty
L : lookup [] X XTy
============================
 lookup G X XTy
 < case L.

Proof completed.
 < Extensible_Theorem
      tyabs_or_not : forall E,
         IsE : is_e E ->
         (exists X Ty B, E = tyabs X Ty B) \/
         ((exists X Ty B, E = tyabs X Ty B) -> false)
      on IsE.

Subgoal 1:

Variables: S
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (var S) @
IsE1 : is_string S
============================
 (exists X Ty B, var S = tyabs X Ty B) \/
 ((exists X Ty B, var S = tyabs X Ty B) -> false)
 < right.

Subgoal 1:

Variables: S
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (var S) @
IsE1 : is_string S
============================
 (exists X Ty B, var S = tyabs X Ty B) -> false
 < intros E.

Subgoal 1:

Variables: S
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (var S) @
IsE1 : is_string S
E : exists X Ty B, var S = tyabs X Ty B
============================
 false
 < case E.

Subgoal 2:

Variables: E1 S
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (abs S E1) @
IsE1 : is_string S
IsE2 : is_e E1 *
============================
 (exists X Ty B, abs S E1 = tyabs X Ty B) \/
 ((exists X Ty B, abs S E1 = tyabs X Ty B) -> false)
 < right.

Subgoal 2:

Variables: E1 S
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (abs S E1) @
IsE1 : is_string S
IsE2 : is_e E1 *
============================
 (exists X Ty B, abs S E1 = tyabs X Ty B) -> false
 < intros E.

Subgoal 2:

Variables: E1 S
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (abs S E1) @
IsE1 : is_string S
IsE2 : is_e E1 *
E : exists X Ty B, abs S E1 = tyabs X Ty B
============================
 false
 < case E.

Subgoal 3:

Variables: E2 E1
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (app E1 E2) @
IsE1 : is_e E1 *
IsE2 : is_e E2 *
============================
 (exists X Ty B, app E1 E2 = tyabs X Ty B) \/
 ((exists X Ty B, app E1 E2 = tyabs X Ty B) -> false)
 < right.

Subgoal 3:

Variables: E2 E1
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (app E1 E2) @
IsE1 : is_e E1 *
IsE2 : is_e E2 *
============================
 (exists X Ty B, app E1 E2 = tyabs X Ty B) -> false
 < intros E.

Subgoal 3:

Variables: E2 E1
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (app E1 E2) @
IsE1 : is_e E1 *
IsE2 : is_e E2 *
E : exists X Ty B, app E1 E2 = tyabs X Ty B
============================
 false
 < case E.

Subgoal 4:

Variables: I
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (intE I) @
IsE1 : is_integer I
============================
 (exists X Ty B, intE I = tyabs X Ty B) \/
 ((exists X Ty B, intE I = tyabs X Ty B) -> false)
 < search.

Subgoal 5:

Variables: E2 E1
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (plus E1 E2) @
IsE1 : is_e E1 *
IsE2 : is_e E2 *
============================
 (exists X Ty B, plus E1 E2 = tyabs X Ty B) \/
 ((exists X Ty B, plus E1 E2 = tyabs X Ty B) -> false)
 < search.

Subgoal 6:

Variables: E1 Ty S
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e (tyabs S Ty E1) @
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
============================
 (exists X Ty1 B, tyabs S Ty E1 = tyabs X Ty1 B) \/
 ((exists X Ty1 B, tyabs S Ty E1 = tyabs X Ty1 B) -> false)
 < search.

Subgoal 7:

Variables: X_T
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e <unknown K is_e> @
IsE1 : |{e}- <unknown K is_e> ~~> X_T
IsE2 : is_e X_T *
============================
 (exists X Ty B, <unknown K is_e> = tyabs X Ty B) \/
 ((exists X Ty B, <unknown K is_e> = tyabs X Ty B) -> false)
 < right.

Subgoal 7:

Variables: X_T
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e <unknown K is_e> @
IsE1 : |{e}- <unknown K is_e> ~~> X_T
IsE2 : is_e X_T *
============================
 (exists X Ty B, <unknown K is_e> = tyabs X Ty B) -> false
 < intros E.

Subgoal 7:

Variables: X_T
IH : forall E,
       is_e E * -> (exists X Ty B, E = tyabs X Ty B) \/
       ((exists X Ty B, E = tyabs X Ty B) -> false)
IsE : is_e <unknown K is_e> @
IsE1 : |{e}- <unknown K is_e> ~~> X_T
IsE2 : is_e X_T *
E : exists X Ty B, <unknown K is_e> = tyabs X Ty B
============================
 false
 < case E.

Proof completed.
 < Extensible_Theorem
      subst_type_preservation : forall X R E S G TyE TyX G',
         IsE : is_e E ->
         IsX : is_string X ->
         IsR : is_e R ->
         S : subst X R E S ->
         TyE : typeOf G E TyE ->
         TyR : typeOf [] R TyX ->
         Lkp : lookup G X TyX ->
         Slct : select (X, TyX) G' G ->
         typeOf G' S TyE
      on TyE.

Subgoal 1:

Variables: X R S G TyE TyX G' X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X1)
IsX : is_string X
IsR : is_e R
S : subst X R (var X1) S
TyE : typeOf G (var X1) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : lookup G X1 TyE
============================
 typeOf G' S TyE
 < S: case S.

Subgoal 1.1:

Variables: S G TyE TyX G' X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X1)
IsX : is_string X1
IsR : is_e S
TyE : typeOf G (var X1) TyE @
TyR : typeOf [] S TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : lookup G X1 TyE
============================
 typeOf G' S TyE
 < apply any_ctx to _ TyR with
     G = G'.

Subgoal 1.1:

Variables: S G TyE TyX G' X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X1)
IsX : is_string X1
IsR : is_e S
TyE : typeOf G (var X1) TyE @
TyR : typeOf [] S TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : lookup G X1 TyE
H1 : typeOf G' S TyX
============================
 typeOf G' S TyE
 < apply lookup_unique to Lkp TyE1.

Subgoal 1.1:

Variables: S G TyE G' X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X1)
IsX : is_string X1
IsR : is_e S
TyE : typeOf G (var X1) TyE @
TyR : typeOf [] S TyE
Lkp : lookup G X1 TyE
Slct : select (X1, TyE) G' G
TyE1 : lookup G X1 TyE
H1 : typeOf G' S TyE
============================
 typeOf G' S TyE
 < search.

Subgoal 1.2:

Variables: X R G TyE TyX G' X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X1)
IsX : is_string X
IsR : is_e R
TyE : typeOf G (var X1) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : lookup G X1 TyE
S : X = X1 -> false
============================
 typeOf G' (var X1) TyE
 < NEq: assert X1 = X -> false.

Subgoal 1.2.1:

Variables: X R G TyE TyX G' X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X1)
IsX : is_string X
IsR : is_e R
TyE : typeOf G (var X1) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : lookup G X1 TyE
S : X = X1 -> false
============================
 X1 = X -> false
 < intros E.

Subgoal 1.2.1:

Variables: X R G TyE TyX G' X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X1)
IsX : is_string X
IsR : is_e R
TyE : typeOf G (var X1) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : lookup G X1 TyE
S : X = X1 -> false
E : X1 = X
============================
 false
 < case E.

Subgoal 1.2.1:

Variables: X R G TyE TyX G'
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X)
IsX : is_string X
IsR : is_e R
TyE : typeOf G (var X) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : lookup G X TyE
S : X = X -> false
============================
 false
 < backchain S.

Subgoal 1.2:

Variables: X R G TyE TyX G' X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X1)
IsX : is_string X
IsR : is_e R
TyE : typeOf G (var X1) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : lookup G X1 TyE
S : X = X1 -> false
NEq : X1 = X -> false
============================
 typeOf G' (var X1) TyE
 < apply select_lookup to TyE1 Slct NEq.

Subgoal 1.2:

Variables: X R G TyE TyX G' X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (var X1)
IsX : is_string X
IsR : is_e R
TyE : typeOf G (var X1) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : lookup G X1 TyE
S : X = X1 -> false
NEq : X1 = X -> false
H1 : lookup G' X1 TyE
============================
 typeOf G' (var X1) TyE
 < search.

Subgoal 2:

Variables: X R S G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (abs X1 Body)
IsX : is_string X
IsR : is_e R
S : subst X R (abs X1 Body) S
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
============================
 typeOf G' S (arrowTy Ty1 Ty2)
 < Is: case IsE.

Subgoal 2:

Variables: X R S G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
S : subst X R (abs X1 Body) S
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
============================
 typeOf G' S (arrowTy Ty1 Ty2)
 < S: case S.

Subgoal 2.1:

Variables: R G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
============================
 typeOf G' (abs X1 Body) (arrowTy Ty1 Ty2)
 < L: assert forall Z ZTy,
     lookup ((X1, Ty1)::G) Z ZTy -> lookup ((X1, Ty1)::G') Z ZTy.

Subgoal 2.1.1:

Variables: R G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
============================
 forall Z ZTy, lookup ((X1, Ty1)::G) Z ZTy -> lookup ((X1, Ty1)::G') Z ZTy
 < intros L.

Subgoal 2.1.1:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
L : lookup ((X1, Ty1)::G) Z ZTy
============================
 lookup ((X1, Ty1)::G') Z ZTy
 < L: case L.

Subgoal 2.1.1.1:

Variables: R G TyX G' Ty2 Body Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string Z
IsR : is_e R
TyE : typeOf G (abs Z Body) (arrowTy ZTy Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G Z TyX
Slct : select (Z, TyX) G' G
TyE1 : typeOf ((Z, ZTy)::G) Body Ty2 *
Is : is_string Z
Is1 : is_e Body
============================
 lookup ((Z, ZTy)::G') Z ZTy
 < search.

Subgoal 2.1.1.2:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
============================
 lookup ((X1, Ty1)::G') Z ZTy
 < NEq: assert Z = X1 -> false.

Subgoal 2.1.1.2.1:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
============================
 Z = X1 -> false
 < intros E.

Subgoal 2.1.1.2.1:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
E : Z = X1
============================
 false
 < case E.

Subgoal 2.1.1.2.1:

Variables: R G TyX G' Ty2 Ty1 Body X1 ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
L : X1 = X1 -> false
L1 : lookup G X1 ZTy
============================
 false
 < backchain L.

Subgoal 2.1.1.2:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
NEq : Z = X1 -> false
============================
 lookup ((X1, Ty1)::G') Z ZTy
 < apply select_lookup to L1 Slct NEq.

Subgoal 2.1.1.2:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
NEq : Z = X1 -> false
H1 : lookup G' Z ZTy
============================
 lookup ((X1, Ty1)::G') Z ZTy
 < search.

Subgoal 2.1:

Variables: R G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
L : forall Z ZTy, lookup ((X1, Ty1)::G) Z ZTy -> lookup ((X1, Ty1)::G') Z ZTy
============================
 typeOf G' (abs X1 Body) (arrowTy Ty1 Ty2)
 < apply type_weakening to _ TyE1 L.

Subgoal 2.1:

Variables: R G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
L : forall Z ZTy, lookup ((X1, Ty1)::G) Z ZTy -> lookup ((X1, Ty1)::G') Z ZTy
H1 : typeOf ((X1, Ty1)::G') Body Ty2
============================
 typeOf G' (abs X1 Body) (arrowTy Ty1 Ty2)
 < search.

Subgoal 2.2:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
============================
 typeOf G' (abs X1 B) (arrowTy Ty1 Ty2)
 < assert X1 = X -> false.

Subgoal 2.2.1:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
============================
 X1 = X -> false
 < intros E.

Subgoal 2.2.1:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
E : X1 = X
============================
 false
 < case E.

Subgoal 2.2.1:

Variables: X R G TyX G' Ty2 Ty1 Body B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (abs X Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_e Body
S : X = X -> false
S1 : subst X R Body B
============================
 false
 < backchain S.

Subgoal 2.2:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
H1 : X1 = X -> false
============================
 typeOf G' (abs X1 B) (arrowTy Ty1 Ty2)
 < apply IH to _ _ _ S1 TyE1 _ _ _ with
     G' = (X1, Ty1)::G'.

Subgoal 2.2:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (abs X1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
H1 : X1 = X -> false
H2 : typeOf ((X1, Ty1)::G') B Ty2
============================
 typeOf G' (abs X1 B) (arrowTy Ty1 Ty2)
 < search.

Subgoal 3:

Variables: X R S G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (tyabs X1 Ty1 Body)
IsX : is_string X
IsR : is_e R
S : subst X R (tyabs X1 Ty1 Body) S
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
============================
 typeOf G' S (arrowTy Ty1 Ty2)
 < Is: case IsE.

Subgoal 3:

Variables: X R S G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
S : subst X R (tyabs X1 Ty1 Body) S
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
============================
 typeOf G' S (arrowTy Ty1 Ty2)
 < S: case S.

Subgoal 3.1:

Variables: R G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
============================
 typeOf G' (abs X1 Body) (arrowTy Ty1 Ty2)
 < L: assert forall Z ZTy,
     lookup ((X1, Ty1)::G) Z ZTy -> lookup ((X1, Ty1)::G') Z ZTy.

Subgoal 3.1.1:

Variables: R G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
============================
 forall Z ZTy, lookup ((X1, Ty1)::G) Z ZTy -> lookup ((X1, Ty1)::G') Z ZTy
 < intros L.

Subgoal 3.1.1:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
L : lookup ((X1, Ty1)::G) Z ZTy
============================
 lookup ((X1, Ty1)::G') Z ZTy
 < L: case L.

Subgoal 3.1.1.1:

Variables: R G TyX G' Ty2 Body Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string Z
IsR : is_e R
TyE : typeOf G (tyabs Z ZTy Body) (arrowTy ZTy Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G Z TyX
Slct : select (Z, TyX) G' G
TyE1 : typeOf ((Z, ZTy)::G) Body Ty2 *
Is : is_string Z
Is1 : is_ty ZTy
Is2 : is_e Body
============================
 lookup ((Z, ZTy)::G') Z ZTy
 < search.

Subgoal 3.1.1.2:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
============================
 lookup ((X1, Ty1)::G') Z ZTy
 < NEq: assert Z = X1 -> false.

Subgoal 3.1.1.2.1:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
============================
 Z = X1 -> false
 < intros E.

Subgoal 3.1.1.2.1:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
E : Z = X1
============================
 false
 < case E.

Subgoal 3.1.1.2.1:

Variables: R G TyX G' Ty2 Ty1 Body X1 ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
L : X1 = X1 -> false
L1 : lookup G X1 ZTy
============================
 false
 < backchain L.

Subgoal 3.1.1.2:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
NEq : Z = X1 -> false
============================
 lookup ((X1, Ty1)::G') Z ZTy
 < apply select_lookup to L1 Slct NEq.

Subgoal 3.1.1.2:

Variables: R G TyX G' Ty2 Ty1 Body X1 Z ZTy
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
L : X1 = Z -> false
L1 : lookup G Z ZTy
NEq : Z = X1 -> false
H1 : lookup G' Z ZTy
============================
 lookup ((X1, Ty1)::G') Z ZTy
 < search.

Subgoal 3.1:

Variables: R G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
L : forall Z ZTy, lookup ((X1, Ty1)::G) Z ZTy -> lookup ((X1, Ty1)::G') Z ZTy
============================
 typeOf G' (abs X1 Body) (arrowTy Ty1 Ty2)
 < apply type_weakening to _ TyE1 L.

Subgoal 3.1:

Variables: R G TyX G' Ty2 Ty1 Body X1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X1
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X1 TyX
Slct : select (X1, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
L : forall Z ZTy, lookup ((X1, Ty1)::G) Z ZTy -> lookup ((X1, Ty1)::G') Z ZTy
H1 : typeOf ((X1, Ty1)::G') Body Ty2
============================
 typeOf G' (abs X1 Body) (arrowTy Ty1 Ty2)
 < search.

Subgoal 3.2:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
============================
 typeOf G' (abs X1 B) (arrowTy Ty1 Ty2)
 < assert X1 = X -> false.

Subgoal 3.2.1:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
============================
 X1 = X -> false
 < intros E.

Subgoal 3.2.1:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
E : X1 = X
============================
 false
 < case E.

Subgoal 3.2.1:

Variables: X R G TyX G' Ty2 Ty1 Body B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (tyabs X Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X, Ty1)::G) Body Ty2 *
Is : is_string X
Is1 : is_ty Ty1
Is2 : is_e Body
S : X = X -> false
S1 : subst X R Body B
============================
 false
 < backchain S.

Subgoal 3.2:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
H1 : X1 = X -> false
============================
 typeOf G' (abs X1 B) (arrowTy Ty1 Ty2)
 < apply IH to _ _ _ S1 TyE1 _ _ _ with
     G' = (X1, Ty1)::G'.

Subgoal 3.2:

Variables: X R G TyX G' Ty2 Ty1 Body X1 B
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (tyabs X1 Ty1 Body) (arrowTy Ty1 Ty2) @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf ((X1, Ty1)::G) Body Ty2 *
Is : is_string X1
Is1 : is_ty Ty1
Is2 : is_e Body
S : X = X1 -> false
S1 : subst X R Body B
H1 : X1 = X -> false
H2 : typeOf ((X1, Ty1)::G') B Ty2
============================
 typeOf G' (abs X1 B) (arrowTy Ty1 Ty2)
 < search.

Subgoal 4:

Variables: X R S G TyE TyX G' Ty1 E2 E1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (app E1 E2)
IsX : is_string X
IsR : is_e R
S : subst X R (app E1 E2) S
TyE : typeOf G (app E1 E2) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 (arrowTy Ty1 TyE) *
TyE2 : typeOf G E2 Ty1 *
============================
 typeOf G' S TyE
 < Is: case IsE.

Subgoal 4:

Variables: X R S G TyE TyX G' Ty1 E2 E1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
S : subst X R (app E1 E2) S
TyE : typeOf G (app E1 E2) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 (arrowTy Ty1 TyE) *
TyE2 : typeOf G E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
============================
 typeOf G' S TyE
 < S: case S.

Subgoal 4:

Variables: X R G TyE TyX G' Ty1 E2 E1 S2 S1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (app E1 E2) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 (arrowTy Ty1 TyE) *
TyE2 : typeOf G E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
S : subst X R E1 S1
S1 : subst X R E2 S2
============================
 typeOf G' (app S1 S2) TyE
 < apply IH to _ _ _ S TyE1 _ _ _.

Subgoal 4:

Variables: X R G TyE TyX G' Ty1 E2 E1 S2 S1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (app E1 E2) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 (arrowTy Ty1 TyE) *
TyE2 : typeOf G E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
S : subst X R E1 S1
S1 : subst X R E2 S2
H1 : typeOf G' S1 (arrowTy Ty1 TyE)
============================
 typeOf G' (app S1 S2) TyE
 < apply IH to _ _ _ S1 TyE2 _ _ _.

Subgoal 4:

Variables: X R G TyE TyX G' Ty1 E2 E1 S2 S1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (app E1 E2) TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 (arrowTy Ty1 TyE) *
TyE2 : typeOf G E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
S : subst X R E1 S1
S1 : subst X R E2 S2
H1 : typeOf G' S1 (arrowTy Ty1 TyE)
H2 : typeOf G' S2 Ty1
============================
 typeOf G' (app S1 S2) TyE
 < search.

Subgoal 5:

Variables: X R S G TyX G' I
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (intE I)
IsX : is_string X
IsR : is_e R
S : subst X R (intE I) S
TyE : typeOf G (intE I) intTy @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
============================
 typeOf G' S intTy
 < case S.

Subgoal 5:

Variables: X R G TyX G' I
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (intE I)
IsX : is_string X
IsR : is_e R
TyE : typeOf G (intE I) intTy @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
============================
 typeOf G' (intE I) intTy
 < search.

Subgoal 6:

Variables: X R S G TyX G' E2 E1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e (plus E1 E2)
IsX : is_string X
IsR : is_e R
S : subst X R (plus E1 E2) S
TyE : typeOf G (plus E1 E2) intTy @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 intTy *
TyE2 : typeOf G E2 intTy *
============================
 typeOf G' S intTy
 < case IsE.

Subgoal 6:

Variables: X R S G TyX G' E2 E1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
S : subst X R (plus E1 E2) S
TyE : typeOf G (plus E1 E2) intTy @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 intTy *
TyE2 : typeOf G E2 intTy *
H1 : is_e E1
H2 : is_e E2
============================
 typeOf G' S intTy
 < S: case S.

Subgoal 6:

Variables: X R G TyX G' E2 E1 S2 S1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (plus E1 E2) intTy @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 intTy *
TyE2 : typeOf G E2 intTy *
H1 : is_e E1
H2 : is_e E2
S : subst X R E1 S1
S1 : subst X R E2 S2
============================
 typeOf G' (plus S1 S2) intTy
 < apply IH to _ _ _ S TyE1 _ _ _.

Subgoal 6:

Variables: X R G TyX G' E2 E1 S2 S1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (plus E1 E2) intTy @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 intTy *
TyE2 : typeOf G E2 intTy *
H1 : is_e E1
H2 : is_e E2
S : subst X R E1 S1
S1 : subst X R E2 S2
H3 : typeOf G' S1 intTy
============================
 typeOf G' (plus S1 S2) intTy
 < apply IH to _ _ _ S1 TyE2 _ _ _.

Subgoal 6:

Variables: X R G TyX G' E2 E1 S2 S1
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsX : is_string X
IsR : is_e R
TyE : typeOf G (plus E1 E2) intTy @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : typeOf G E1 intTy *
TyE2 : typeOf G E2 intTy *
H1 : is_e E1
H2 : is_e E2
S : subst X R E1 S1
S1 : subst X R E2 S2
H3 : typeOf G' S1 intTy
H4 : typeOf G' S2 intTy
============================
 typeOf G' (plus S1 S2) intTy
 < search.

Subgoal 7:

Variables: X R S G TyE TyX G' E_T
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e <unknown I e>
IsX : is_string X
IsR : is_e R
S : subst X R <unknown I e> S
TyE : typeOf G <unknown I e> TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : |{e}- <unknown I e> ~~> E_T
TyE2 : typeOf G E_T TyE *
============================
 typeOf G' S TyE
 < ST: apply proj_subst to TyE1 _ _ _ S.

Subgoal 7:

Variables: X R S G TyE TyX G' E_T S'
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e <unknown I e>
IsX : is_string X
IsR : is_e R
S : subst X R <unknown I e> S
TyE : typeOf G <unknown I e> TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : |{e}- <unknown I e> ~~> E_T
TyE2 : typeOf G E_T TyE *
ST : subst X R E_T S'
============================
 typeOf G' S TyE
 < apply proj_is to TyE1 _.

Subgoal 7:

Variables: X R S G TyE TyX G' E_T S'
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e <unknown I e>
IsX : is_string X
IsR : is_e R
S : subst X R <unknown I e> S
TyE : typeOf G <unknown I e> TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : |{e}- <unknown I e> ~~> E_T
TyE2 : typeOf G E_T TyE *
ST : subst X R E_T S'
H1 : is_e E_T
============================
 typeOf G' S TyE
 < apply proj_subst_same to TyE1 _ _ _ S ST.

Subgoal 7:

Variables: X R G TyE TyX G' E_T S'
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e <unknown I e>
IsX : is_string X
IsR : is_e R
S : subst X R <unknown I e> S'
TyE : typeOf G <unknown I e> TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : |{e}- <unknown I e> ~~> E_T
TyE2 : typeOf G E_T TyE *
ST : subst X R E_T S'
H1 : is_e E_T
============================
 typeOf G' S' TyE
 < apply IH to _ _ _ ST TyE2 _ _ _.

Subgoal 7:

Variables: X R G TyE TyX G' E_T S'
IH : forall X R E S G TyE TyX G',
       is_e E -> is_string X -> is_e R -> subst X R E S -> typeOf G E TyE * -> typeOf [] R TyX ->
       lookup G X TyX -> select (X, TyX) G' G -> typeOf G' S TyE
IsE : is_e <unknown I e>
IsX : is_string X
IsR : is_e R
S : subst X R <unknown I e> S'
TyE : typeOf G <unknown I e> TyE @
TyR : typeOf [] R TyX
Lkp : lookup G X TyX
Slct : select (X, TyX) G' G
TyE1 : |{e}- <unknown I e> ~~> E_T
TyE2 : typeOf G E_T TyE *
ST : subst X R E_T S'
H1 : is_e E_T
H2 : typeOf G' S' TyE
============================
 typeOf G' S' TyE
 < search.

Proof completed.
 < Extensible_Theorem
      type_preservation : forall E Ty V,
         IsE : is_e E ->
         Ty : typeOf [] E Ty ->
         Ev : eval E V ->
         typeOf [] V Ty
      on Ev.

Subgoal 1:

Variables: Ty Body X
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e (abs X Body)
Ty : typeOf [] (abs X Body) Ty
Ev : eval (abs X Body) (abs X Body) @
============================
 typeOf [] (abs X Body) Ty
 < search.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e (app E1 E2)
Ty : typeOf [] (app E1 E2) Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
============================
 typeOf [] V Ty
 < Is: case IsE.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ty : typeOf [] (app E1 E2) Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
============================
 typeOf [] V Ty
 < Ty: case Ty.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
============================
 typeOf [] V Ty
 < AbsTy: apply IH to _ Ty Ev1.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
AbsTy : typeOf [] (abs X Body) (arrowTy Ty1 Ty)
============================
 typeOf [] V Ty
 < Ty': case AbsTy.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
Ty' : typeOf [(X, Ty1)] Body Ty
============================
 typeOf [] V Ty
 < apply IH to _ Ty1 Ev2.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
Ty' : typeOf [(X, Ty1)] Body Ty
H1 : typeOf [] V2 Ty1
============================
 typeOf [] V Ty
 < apply eval_is to _ Ev2.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
Ty' : typeOf [(X, Ty1)] Body Ty
H1 : typeOf [] V2 Ty1
H2 : is_e V2
============================
 typeOf [] V Ty
 < IsAbs: apply eval_is to _ Ev1.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
Ty' : typeOf [(X, Ty1)] Body Ty
H1 : typeOf [] V2 Ty1
H2 : is_e V2
IsAbs : is_e (abs X Body)
============================
 typeOf [] V Ty
 < case IsAbs.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
Ty' : typeOf [(X, Ty1)] Body Ty
H1 : typeOf [] V2 Ty1
H2 : is_e V2
H3 : is_string X
H4 : is_e Body
============================
 typeOf [] V Ty
 < TyB: apply subst_type_preservation to _ _ _ Ev3 Ty' _ _ _.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
Ty' : typeOf [(X, Ty1)] Body Ty
H1 : typeOf [] V2 Ty1
H2 : is_e V2
H3 : is_string X
H4 : is_e Body
TyB : typeOf [] B Ty
============================
 typeOf [] V Ty
 < apply subst_is to _ _ _ Ev3.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
Ty' : typeOf [(X, Ty1)] Body Ty
H1 : typeOf [] V2 Ty1
H2 : is_e V2
H3 : is_string X
H4 : is_e Body
TyB : typeOf [] B Ty
H5 : is_e B
============================
 typeOf [] V Ty
 < apply IH to _ TyB Ev4.

Subgoal 2:

Variables: Ty V X Body V2 B E2 E1 Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
Ev : eval (app E1 E2) V @
Ev1 : eval E1 (abs X Body) *
Ev2 : eval E2 V2 *
Ev3 : subst X V2 Body B
Ev4 : eval B V *
Is : is_e E1
Is1 : is_e E2
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
Ty' : typeOf [(X, Ty1)] Body Ty
H1 : typeOf [] V2 Ty1
H2 : is_e V2
H3 : is_string X
H4 : is_e Body
TyB : typeOf [] B Ty
H5 : is_e B
H6 : typeOf [] V Ty
============================
 typeOf [] V Ty
 < search.

Subgoal 3:

Variables: Ty I
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e (intE I)
Ty : typeOf [] (intE I) Ty
Ev : eval (intE I) (intE I) @
============================
 typeOf [] (intE I) Ty
 < case Ty.

Subgoal 3:

Variables: I
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e (intE I)
Ev : eval (intE I) (intE I) @
============================
 typeOf [] (intE I) intTy
 < search.

Subgoal 4:

Variables: Ty I1 I2 I E2 E1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e (plus E1 E2)
Ty : typeOf [] (plus E1 E2) Ty
Ev : eval (plus E1 E2) (intE I) @
Ev1 : eval E1 (intE I1) *
Ev2 : eval E2 (intE I2) *
Ev3 : I1 + I2 = I
============================
 typeOf [] (intE I) Ty
 < case Ty.

Subgoal 4:

Variables: I1 I2 I E2 E1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e (plus E1 E2)
Ev : eval (plus E1 E2) (intE I) @
Ev1 : eval E1 (intE I1) *
Ev2 : eval E2 (intE I2) *
Ev3 : I1 + I2 = I
H1 : typeOf [] E1 intTy
H2 : typeOf [] E2 intTy
============================
 typeOf [] (intE I) intTy
 < search.

Subgoal 5:

Variables: Ty Body X Ty1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e (tyabs X Ty1 Body)
Ty : typeOf [] (tyabs X Ty1 Body) Ty
Ev : eval (tyabs X Ty1 Body) (abs X Body) @
============================
 typeOf [] (abs X Body) Ty
 < case Ty.

Subgoal 5:

Variables: Body X Ty1 Ty3
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e (tyabs X Ty1 Body)
Ev : eval (tyabs X Ty1 Body) (abs X Body) @
H1 : typeOf [(X, Ty1)] Body Ty3
============================
 typeOf [] (abs X Body) (arrowTy Ty1 Ty3)
 < search.

Subgoal 6:

Variables: Ty V E_T
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e <unknown K eval>
Ty : typeOf [] <unknown K eval> Ty
Ev : eval <unknown K eval> V @
Ev1 : |{e}- <unknown K eval> ~~> E_T
Ev2 : eval E_T V *
============================
 typeOf [] V Ty
 < Ty: case Ty.

Subgoal 6:

Variables: Ty V E_T E_T1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e <unknown K eval>
Ev : eval <unknown K eval> V @
Ev1 : |{e}- <unknown K eval> ~~> E_T
Ev2 : eval E_T V *
Ty : |{e}- <unknown K eval> ~~> E_T1
Ty1 : typeOf [] E_T1 Ty
============================
 typeOf [] V Ty
 < apply proj_same to Ev1 Ty.

Subgoal 6:

Variables: Ty V E_T1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e <unknown K eval>
Ev : eval <unknown K eval> V @
Ev1 : |{e}- <unknown K eval> ~~> E_T1
Ev2 : eval E_T1 V *
Ty : |{e}- <unknown K eval> ~~> E_T1
Ty1 : typeOf [] E_T1 Ty
============================
 typeOf [] V Ty
 < apply proj_is to Ty _.

Subgoal 6:

Variables: Ty V E_T1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e <unknown K eval>
Ev : eval <unknown K eval> V @
Ev1 : |{e}- <unknown K eval> ~~> E_T1
Ev2 : eval E_T1 V *
Ty : |{e}- <unknown K eval> ~~> E_T1
Ty1 : typeOf [] E_T1 Ty
H1 : is_e E_T1
============================
 typeOf [] V Ty
 < apply IH to _ Ty1 Ev2.

Subgoal 6:

Variables: Ty V E_T1
IH : forall E Ty V, is_e E -> typeOf [] E Ty -> eval E V * -> typeOf [] V Ty
IsE : is_e <unknown K eval>
Ev : eval <unknown K eval> V @
Ev1 : |{e}- <unknown K eval> ~~> E_T1
Ev2 : eval E_T1 V *
Ty : |{e}- <unknown K eval> ~~> E_T1
Ty1 : typeOf [] E_T1 Ty
H1 : is_e E_T1
H2 : typeOf [] V Ty
============================
 typeOf [] V Ty
 < search.

Proof completed.
Back to example home