Reasoning Details

 < Module walkthrough:host.
 < Extensible_Theorem
      typeOf_unique : forall Ctx T TyA TyB,
         TyA : typeOf Ctx T TyA ->
         TyB : typeOf Ctx T TyB ->
         TyA = TyB
      on TyA.

Subgoal 1:

Variables: Ctx TyA TyB X
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (var X) TyA @
TyB : typeOf Ctx (var X) TyB
TyA1 : lookup Ctx X TyA
============================
 TyA = TyB
 < TyB: case TyB.

Subgoal 1:

Variables: Ctx TyA TyB X
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (var X) TyA @
TyA1 : lookup Ctx X TyA
TyB : lookup Ctx X TyB
============================
 TyA = TyB
 < apply lookup_unique to TyA1 TyB.

Subgoal 1:

Variables: Ctx TyB X
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (var X) TyB @
TyA1 : lookup Ctx X TyB
TyB : lookup Ctx X TyB
============================
 TyB = TyB
 < search.

Subgoal 2:

Variables: Ctx TyB Ty2 Ty1 Body X
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
TyB : typeOf Ctx (abs X Ty1 Body) TyB
TyA1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
============================
 arrowTy Ty1 Ty2 = TyB
 < TyB: case TyB.

Subgoal 2:

Variables: Ctx Ty2 Ty1 Body X Ty4
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
TyA1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
TyB : typeOf ((X, Ty1)::Ctx) Body Ty4
============================
 arrowTy Ty1 Ty2 = arrowTy Ty1 Ty4
 < apply IH to TyA1 TyB.

Subgoal 2:

Variables: Ctx Ty1 Body X Ty4
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty4) @
TyA1 : typeOf ((X, Ty1)::Ctx) Body Ty4 *
TyB : typeOf ((X, Ty1)::Ctx) Body Ty4
============================
 arrowTy Ty1 Ty4 = arrowTy Ty1 Ty4
 < search.

Subgoal 3:

Variables: Ctx TyA TyB Ty1 T2 T1
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (app T1 T2) TyA @
TyB : typeOf Ctx (app T1 T2) TyB
TyA1 : typeOf Ctx T1 (arrowTy Ty1 TyA) *
TyA2 : typeOf Ctx T2 Ty1 *
============================
 TyA = TyB
 < TyB: case TyB.

Subgoal 3:

Variables: Ctx TyA TyB Ty1 T2 T1 Ty2
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (app T1 T2) TyA @
TyA1 : typeOf Ctx T1 (arrowTy Ty1 TyA) *
TyA2 : typeOf Ctx T2 Ty1 *
TyB : typeOf Ctx T1 (arrowTy Ty2 TyB)
TyB1 : typeOf Ctx T2 Ty2
============================
 TyA = TyB
 < apply IH to TyA1 TyB.

Subgoal 3:

Variables: Ctx TyB T2 T1 Ty2
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (app T1 T2) TyB @
TyA1 : typeOf Ctx T1 (arrowTy Ty2 TyB) *
TyA2 : typeOf Ctx T2 Ty2 *
TyB : typeOf Ctx T1 (arrowTy Ty2 TyB)
TyB1 : typeOf Ctx T2 Ty2
============================
 TyB = TyB
 < apply IH to TyA2 TyB1.

Subgoal 3:

Variables: Ctx TyB T2 T1 Ty2
IH : forall Ctx T TyA TyB, typeOf Ctx T TyA * -> typeOf Ctx T TyB -> TyA = TyB
TyA : typeOf Ctx (app T1 T2) TyB @
TyA1 : typeOf Ctx T1 (arrowTy Ty2 TyB) *
TyA2 : typeOf Ctx T2 Ty2 *
TyB : typeOf Ctx T1 (arrowTy Ty2 TyB)
TyB1 : typeOf Ctx T2 Ty2
============================
 TyB = TyB
 < search.

Proof completed.
 < Extensible_Theorem
      ty_lookup : forall Ctx1 Ctx2 T Ty,
         Ty : typeOf Ctx1 T Ty ->
         L : (forall X XTy,
           lookup Ctx1 X XTy -> lookup Ctx2 X XTy) ->
         typeOf Ctx2 T Ty
      on Ty.

Subgoal 1:

Variables: Ctx1 Ctx2 Ty X
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (var X) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : lookup Ctx1 X Ty
============================
 typeOf Ctx2 (var X) Ty
 < apply L to Ty1.

Subgoal 1:

Variables: Ctx1 Ctx2 Ty X
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (var X) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : lookup Ctx1 X Ty
H1 : lookup Ctx2 X Ty
============================
 typeOf Ctx2 (var X) Ty
 < search.

Subgoal 2:

Variables: Ctx1 Ctx2 Ty2 Ty1 Body X
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
============================
 typeOf Ctx2 (abs X Ty1 Body) (arrowTy Ty1 Ty2)
 < apply IH to Ty1 _ with
     Ctx2 = (X, Ty1)::Ctx2.

Subgoal 2.1:

Variables: Ctx1 Ctx2 Ty2 Ty1 Body X
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
============================
 forall X1 XTy, lookup ((X, Ty1)::Ctx1) X1 XTy -> lookup ((X, Ty1)::Ctx2) X1 XTy
 < intros LkpX.

Subgoal 2.1:

Variables: Ctx1 Ctx2 Ty2 Ty1 Body X X1 XTy
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
LkpX : lookup ((X, Ty1)::Ctx1) X1 XTy
============================
 lookup ((X, Ty1)::Ctx2) X1 XTy
 < LkpX: case LkpX.

Subgoal 2.1.1:

Variables: Ctx1 Ctx2 Ty2 Body X1 XTy
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X1 XTy Body) (arrowTy XTy Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X1, XTy)::Ctx1) Body Ty2 *
============================
 lookup ((X1, XTy)::Ctx2) X1 XTy
 < search.

Subgoal 2.1.2:

Variables: Ctx1 Ctx2 Ty2 Ty1 Body X X1 XTy
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
LkpX : X = X1 -> false
LkpX1 : lookup Ctx1 X1 XTy
============================
 lookup ((X, Ty1)::Ctx2) X1 XTy
 < apply L to LkpX1.

Subgoal 2.1.2:

Variables: Ctx1 Ctx2 Ty2 Ty1 Body X X1 XTy
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
LkpX : X = X1 -> false
LkpX1 : lookup Ctx1 X1 XTy
H1 : lookup Ctx2 X1 XTy
============================
 lookup ((X, Ty1)::Ctx2) X1 XTy
 < search.

Subgoal 2:

Variables: Ctx1 Ctx2 Ty2 Ty1 Body X
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
H1 : typeOf ((X, Ty1)::Ctx2) Body Ty2
============================
 typeOf Ctx2 (abs X Ty1 Body) (arrowTy Ty1 Ty2)
 < search.

Subgoal 3:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (app T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx1 T2 Ty1 *
============================
 typeOf Ctx2 (app T1 T2) Ty
 < apply IH to Ty1 L.

Subgoal 3:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (app T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx1 T2 Ty1 *
H1 : typeOf Ctx2 T1 (arrowTy Ty1 Ty)
============================
 typeOf Ctx2 (app T1 T2) Ty
 < apply IH to Ty2 L.

Subgoal 3:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1
IH : forall Ctx1 Ctx2 T Ty,
       typeOf Ctx1 T Ty * -> (forall X XTy,
         lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (app T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx1 T2 Ty1 *
H1 : typeOf Ctx2 T1 (arrowTy Ty1 Ty)
H2 : typeOf Ctx2 T2 Ty1
============================
 typeOf Ctx2 (app T1 T2) Ty
 < search.

Proof completed.
 < Theorem empty_ty_any :
     forall T Ty Ctx, typeOf [] T Ty -> typeOf Ctx T Ty.

============================
 forall T Ty Ctx, typeOf [] T Ty -> typeOf Ctx T Ty
 < intros T.

Variables: T Ty Ctx
T : typeOf [] T Ty
============================
 typeOf Ctx T Ty
 < backchain ty_lookup.

Variables: T Ty Ctx
T : typeOf [] T Ty
============================
 forall X XTy, lookup [] X XTy -> lookup Ctx X XTy
 < intros L.

Variables: T Ty Ctx X XTy
T : typeOf [] T Ty
L : lookup [] X XTy
============================
 lookup Ctx X XTy
 < case L.

Proof completed.
 < Extensible_Theorem
      subst_type_preservation : forall T Ctx X XTy Ty R S,
         TTy : typeOf ((X, XTy)::Ctx) T Ty ->
         S : subst X R T S ->
         RTy : typeOf [] R XTy ->
         typeOf Ctx S Ty
      on S.

Subgoal 1:

Variables: Ctx X XTy Ty R Y
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (var Y) Ty
S : subst X R (var Y) (var Y) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
============================
 typeOf Ctx (var Y) Ty
 < Ty: case TTy.

Subgoal 1:

Variables: Ctx X XTy Ty R Y
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (var Y) (var Y) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
Ty : lookup ((X, XTy)::Ctx) Y Ty
============================
 typeOf Ctx (var Y) Ty
 < Lkp: case Ty.

Subgoal 1.1:

Variables: Ctx Ty R Y
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst Y R (var Y) (var Y) @
RTy : typeOf [] R Ty
S1 : Y = Y -> false
============================
 typeOf Ctx (var Y) Ty
 < apply S1 to _.

Subgoal 1.2:

Variables: Ctx X XTy Ty R Y
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (var Y) (var Y) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
Lkp : X = Y -> false
Lkp1 : lookup Ctx Y Ty
============================
 typeOf Ctx (var Y) Ty
 < search.

Subgoal 2:

Variables: Ctx X XTy Ty S
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (var X) Ty
S : subst X S (var X) S @
RTy : typeOf [] S XTy
============================
 typeOf Ctx S Ty
 < Ty: case TTy.

Subgoal 2:

Variables: Ctx X XTy Ty S
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X S (var X) S @
RTy : typeOf [] S XTy
Ty : lookup ((X, XTy)::Ctx) X Ty
============================
 typeOf Ctx S Ty
 < L: case Ty.

Subgoal 2.1:

Variables: Ctx X Ty S
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X S (var X) S @
RTy : typeOf [] S Ty
============================
 typeOf Ctx S Ty
 < backchain empty_ty_any.

Subgoal 2.2:

Variables: Ctx X XTy Ty S
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X S (var X) S @
RTy : typeOf [] S XTy
L : X = X -> false
L1 : lookup Ctx X Ty
============================
 typeOf Ctx S Ty
 < apply L to _.

Subgoal 3:

Variables: Ctx X XTy Ty R S1 Ty1 Y B
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (abs Y Ty1 B) Ty
S : subst X R (abs Y Ty1 B) (abs Y Ty1 S1) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R B S1 *
============================
 typeOf Ctx (abs Y Ty1 S1) Ty
 < Ty: case TTy.

Subgoal 3:

Variables: Ctx X XTy R S1 Ty1 Y B Ty3
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs Y Ty1 B) (abs Y Ty1 S1) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
============================
 typeOf Ctx (abs Y Ty1 S1) (arrowTy Ty1 Ty3)
 < Ty': apply ty_lookup to Ty _ with
          Ctx2 = (X, XTy)::((Y, Ty1)::Ctx).

Subgoal 3.1:

Variables: Ctx X XTy R S1 Ty1 Y B Ty3
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs Y Ty1 B) (abs Y Ty1 S1) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
============================
 forall X1 XTy1,
   lookup ((Y, Ty1)::((X, XTy)::Ctx)) X1 XTy1 -> lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
 < intros L.

Subgoal 3.1:

Variables: Ctx X XTy R S1 Ty1 Y B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs Y Ty1 B) (abs Y Ty1 S1) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
L : lookup ((Y, Ty1)::((X, XTy)::Ctx)) X1 XTy1
============================
 lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
 < L: case L.

Subgoal 3.1.1:

Variables: Ctx X XTy R S1 B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs X1 XTy1 B) (abs X1 XTy1 S1) @
RTy : typeOf [] R XTy
S1 : X = X1 -> false
S2 : subst X R B S1 *
Ty : typeOf ((X1, XTy1)::((X, XTy)::Ctx)) B Ty3
============================
 lookup ((X, XTy)::((X1, XTy1)::Ctx)) X1 XTy1
 < search.

Subgoal 3.1.2:

Variables: Ctx X XTy R S1 Ty1 Y B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs Y Ty1 B) (abs Y Ty1 S1) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
L : Y = X1 -> false
L1 : lookup ((X, XTy)::Ctx) X1 XTy1
============================
 lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
 < L: case L1.

Subgoal 3.1.2.1:

Variables: Ctx R S1 Ty1 Y B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X1 R (abs Y Ty1 B) (abs Y Ty1 S1) @
RTy : typeOf [] R XTy1
S1 : X1 = Y -> false
S2 : subst X1 R B S1 *
Ty : typeOf ((Y, Ty1)::((X1, XTy1)::Ctx)) B Ty3
L : Y = X1 -> false
============================
 lookup ((X1, XTy1)::((Y, Ty1)::Ctx)) X1 XTy1
 < search.

Subgoal 3.1.2.2:

Variables: Ctx X XTy R S1 Ty1 Y B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs Y Ty1 B) (abs Y Ty1 S1) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
L : Y = X1 -> false
L1 : X = X1 -> false
L2 : lookup Ctx X1 XTy1
============================
 lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
 < search.

Subgoal 3:

Variables: Ctx X XTy R S1 Ty1 Y B Ty3
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs Y Ty1 B) (abs Y Ty1 S1) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
Ty' : typeOf ((X, XTy)::((Y, Ty1)::Ctx)) B Ty3
============================
 typeOf Ctx (abs Y Ty1 S1) (arrowTy Ty1 Ty3)
 < apply IH to Ty' S2 _.

Subgoal 3:

Variables: Ctx X XTy R S1 Ty1 Y B Ty3
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs Y Ty1 B) (abs Y Ty1 S1) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
Ty' : typeOf ((X, XTy)::((Y, Ty1)::Ctx)) B Ty3
H1 : typeOf ((Y, Ty1)::Ctx) S1 Ty3
============================
 typeOf Ctx (abs Y Ty1 S1) (arrowTy Ty1 Ty3)
 < search.

Subgoal 4:

Variables: Ctx X XTy Ty R B Ty1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (abs X Ty1 B) Ty
S : subst X R (abs X Ty1 B) (abs X Ty1 B) @
RTy : typeOf [] R XTy
============================
 typeOf Ctx (abs X Ty1 B) Ty
 < Ty: case TTy.

Subgoal 4:

Variables: Ctx X XTy R B Ty1 Ty3
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs X Ty1 B) (abs X Ty1 B) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
============================
 typeOf Ctx (abs X Ty1 B) (arrowTy Ty1 Ty3)
 < apply ty_lookup to Ty _ with
     Ctx2 = (X, Ty1)::Ctx.

Subgoal 4.1:

Variables: Ctx X XTy R B Ty1 Ty3
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs X Ty1 B) (abs X Ty1 B) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
============================
 forall X1 XTy1,
   lookup ((X, Ty1)::((X, XTy)::Ctx)) X1 XTy1 -> lookup ((X, Ty1)::Ctx) X1 XTy1
 < intros L.

Subgoal 4.1:

Variables: Ctx X XTy R B Ty1 Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs X Ty1 B) (abs X Ty1 B) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
L : lookup ((X, Ty1)::((X, XTy)::Ctx)) X1 XTy1
============================
 lookup ((X, Ty1)::Ctx) X1 XTy1
 < L: case L.

Subgoal 4.1.1:

Variables: Ctx XTy R B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X1 R (abs X1 XTy1 B) (abs X1 XTy1 B) @
RTy : typeOf [] R XTy
Ty : typeOf ((X1, XTy1)::((X1, XTy)::Ctx)) B Ty3
============================
 lookup ((X1, XTy1)::Ctx) X1 XTy1
 < search.

Subgoal 4.1.2:

Variables: Ctx X XTy R B Ty1 Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs X Ty1 B) (abs X Ty1 B) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
L : X = X1 -> false
L1 : lookup ((X, XTy)::Ctx) X1 XTy1
============================
 lookup ((X, Ty1)::Ctx) X1 XTy1
 < L: case L1.

Subgoal 4.1.2.1:

Variables: Ctx R B Ty1 Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X1 R (abs X1 Ty1 B) (abs X1 Ty1 B) @
RTy : typeOf [] R XTy1
Ty : typeOf ((X1, Ty1)::((X1, XTy1)::Ctx)) B Ty3
L : X1 = X1 -> false
============================
 lookup ((X1, Ty1)::Ctx) X1 XTy1
 < apply L to _.

Subgoal 4.1.2.2:

Variables: Ctx X XTy R B Ty1 Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs X Ty1 B) (abs X Ty1 B) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
L : X = X1 -> false
L1 : X = X1 -> false
L2 : lookup Ctx X1 XTy1
============================
 lookup ((X, Ty1)::Ctx) X1 XTy1
 < search.

Subgoal 4:

Variables: Ctx X XTy R B Ty1 Ty3
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (abs X Ty1 B) (abs X Ty1 B) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
H1 : typeOf ((X, Ty1)::Ctx) B Ty3
============================
 typeOf Ctx (abs X Ty1 B) (arrowTy Ty1 Ty3)
 < search.

Subgoal 5:

Variables: Ctx X XTy Ty R S2 S1 T2 T1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (app T1 T2) Ty
S : subst X R (app T1 T2) (app S1 S2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
S2 : subst X R T2 S2 *
============================
 typeOf Ctx (app S1 S2) Ty
 < Ty: case TTy.

Subgoal 5:

Variables: Ctx X XTy Ty R S2 S1 T2 T1 Ty1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (app T1 T2) (app S1 S2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
S2 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 (arrowTy Ty1 Ty)
Ty1 : typeOf ((X, XTy)::Ctx) T2 Ty1
============================
 typeOf Ctx (app S1 S2) Ty
 < apply IH to Ty S1 _.

Subgoal 5:

Variables: Ctx X XTy Ty R S2 S1 T2 T1 Ty1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (app T1 T2) (app S1 S2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
S2 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 (arrowTy Ty1 Ty)
Ty1 : typeOf ((X, XTy)::Ctx) T2 Ty1
H1 : typeOf Ctx S1 (arrowTy Ty1 Ty)
============================
 typeOf Ctx (app S1 S2) Ty
 < apply IH to Ty1 S2 _.

Subgoal 5:

Variables: Ctx X XTy Ty R S2 S1 T2 T1 Ty1
IH : forall T Ctx X XTy Ty R S,
       typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
S : subst X R (app T1 T2) (app S1 S2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
S2 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 (arrowTy Ty1 Ty)
Ty1 : typeOf ((X, XTy)::Ctx) T2 Ty1
H1 : typeOf Ctx S1 (arrowTy Ty1 Ty)
H2 : typeOf Ctx S2 Ty1
============================
 typeOf Ctx (app S1 S2) Ty
 < search.

Proof completed.
 < Extensible_Theorem
      type_preservation : forall T Ty T',
         Ty : typeOf [] T Ty ->
         Ev : eval T T' ->
         typeOf [] T' Ty
      on Ev.

Subgoal 1:

Variables: Ty T2 T11 T1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] (app T1 T2) Ty
Ev : eval (app T1 T2) (app T11 T2) @
Ev1 : eval T1 T11 *
============================
 typeOf [] (app T11 T2) Ty
 < Ty: case Ty.

Subgoal 1:

Variables: Ty T2 T11 T1 Ty1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval (app T1 T2) (app T11 T2) @
Ev1 : eval T1 T11 *
Ty : typeOf [] T1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] T2 Ty1
============================
 typeOf [] (app T11 T2) Ty
 < apply IH to Ty Ev1.

Subgoal 1:

Variables: Ty T2 T11 T1 Ty1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval (app T1 T2) (app T11 T2) @
Ev1 : eval T1 T11 *
Ty : typeOf [] T1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] T2 Ty1
H1 : typeOf [] T11 (arrowTy Ty1 Ty)
============================
 typeOf [] (app T11 T2) Ty
 < search.

Subgoal 2:

Variables: Ty T21 T1 T2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] (app T1 T2) Ty
Ev : eval (app T1 T2) (app T1 T21) @
Ev1 : value T1
Ev2 : eval T2 T21 *
============================
 typeOf [] (app T1 T21) Ty
 < Ty: case Ty.

Subgoal 2:

Variables: Ty T21 T1 T2 Ty1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval (app T1 T2) (app T1 T21) @
Ev1 : value T1
Ev2 : eval T2 T21 *
Ty : typeOf [] T1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] T2 Ty1
============================
 typeOf [] (app T1 T21) Ty
 < apply IH to Ty1 Ev2.

Subgoal 2:

Variables: Ty T21 T1 T2 Ty1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval (app T1 T2) (app T1 T21) @
Ev1 : value T1
Ev2 : eval T2 T21 *
Ty : typeOf [] T1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] T2 Ty1
H1 : typeOf [] T21 Ty1
============================
 typeOf [] (app T1 T21) Ty
 < search.

Subgoal 3:

Variables: Ty T' T2 Body Ty1 X
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] (app (abs X Ty1 Body) T2) Ty
Ev : eval (app (abs X Ty1 Body) T2) T' @
Ev1 : value T2
Ev2 : subst X T2 Body T'
============================
 typeOf [] T' Ty
 < Ty: case Ty.

Subgoal 3:

Variables: Ty T' T2 Body Ty1 X Ty2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval (app (abs X Ty1 Body) T2) T' @
Ev1 : value T2
Ev2 : subst X T2 Body T'
Ty : typeOf [] (abs X Ty1 Body) (arrowTy Ty2 Ty)
Ty1 : typeOf [] T2 Ty2
============================
 typeOf [] T' Ty
 < Ty: case Ty.

Subgoal 3:

Variables: Ty T' T2 Body X Ty2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval (app (abs X Ty2 Body) T2) T' @
Ev1 : value T2
Ev2 : subst X T2 Body T'
Ty1 : typeOf [] T2 Ty2
Ty : typeOf [(X, Ty2)] Body Ty
============================
 typeOf [] T' Ty
 < apply subst_type_preservation to Ty Ev2 Ty1.

Subgoal 3:

Variables: Ty T' T2 Body X Ty2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval (app (abs X Ty2 Body) T2) T' @
Ev1 : value T2
Ev2 : subst X T2 Body T'
Ty1 : typeOf [] T2 Ty2
Ty : typeOf [(X, Ty2)] Body Ty
H1 : typeOf [] T' Ty
============================
 typeOf [] T' Ty
 < search.

Proof completed.
 < Projection_Constraint proj_type_same :
   forall G T Ty T_T,
   G |{tm}- T ~~> T_T -> typeOf G T Ty -> typeOf G T_T Ty.

Proof completed.
 < Ext_Size eval T T'.

Proof completed.
 < Proj_Rel eval T T'.

Proof completed.
 < Ext_Ind forall G T T' Ty, eval T T' with Ty : typeOf G T Ty.

Subgoal 1:

Variables: N G Ty T2 T11 T1
IH : forall N G T T' Ty,
       <eval {ES}> T T' N -> acc N * -> typeOf G T Ty -> <eval {P}> T T'
IH1 : forall N G T T' Ty,
        <eval {ES}> T T' N ** -> acc N @ -> typeOf G T Ty -> <eval {P}> T T'
R : <eval {ES}> (app T1 T2) (app T11 T2) N @@
Acc : acc N @
Ty : typeOf G (app T1 T2) Ty
R1 : <eval {ES}> T1 T11 N **
============================
 <eval {P}> (app T1 T2) (app T11 T2)
 < Ty: case Ty.

Subgoal 1:

Variables: N G Ty T2 T11 T1 Ty1
IH : forall N G T T' Ty,
       <eval {ES}> T T' N -> acc N * -> typeOf G T Ty -> <eval {P}> T T'
IH1 : forall N G T T' Ty,
        <eval {ES}> T T' N ** -> acc N @ -> typeOf G T Ty -> <eval {P}> T T'
R : <eval {ES}> (app T1 T2) (app T11 T2) N @@
Acc : acc N @
R1 : <eval {ES}> T1 T11 N **
Ty : typeOf G T1 (arrowTy Ty1 Ty)
Ty1 : typeOf G T2 Ty1
============================
 <eval {P}> (app T1 T2) (app T11 T2)
 < apply IH1 to R1 Acc Ty.

Subgoal 1:

Variables: N G Ty T2 T11 T1 Ty1
IH : forall N G T T' Ty,
       <eval {ES}> T T' N -> acc N * -> typeOf G T Ty -> <eval {P}> T T'
IH1 : forall N G T T' Ty,
        <eval {ES}> T T' N ** -> acc N @ -> typeOf G T Ty -> <eval {P}> T T'
R : <eval {ES}> (app T1 T2) (app T11 T2) N @@
Acc : acc N @
R1 : <eval {ES}> T1 T11 N **
Ty : typeOf G T1 (arrowTy Ty1 Ty)
Ty1 : typeOf G T2 Ty1
H1 : <eval {P}> T1 T11
============================
 <eval {P}> (app T1 T2) (app T11 T2)
 < search.

Subgoal 2:

Variables: N G Ty T21 T1 T2
IH : forall N G T T' Ty,
       <eval {ES}> T T' N -> acc N * -> typeOf G T Ty -> <eval {P}> T T'
IH1 : forall N G T T' Ty,
        <eval {ES}> T T' N ** -> acc N @ -> typeOf G T Ty -> <eval {P}> T T'
R : <eval {ES}> (app T1 T2) (app T1 T21) N @@
Acc : acc N @
Ty : typeOf G (app T1 T2) Ty
R1 : value T1
R2 : <eval {ES}> T2 T21 N **
============================
 <eval {P}> (app T1 T2) (app T1 T21)
 < Ty: case Ty.

Subgoal 2:

Variables: N G Ty T21 T1 T2 Ty1
IH : forall N G T T' Ty,
       <eval {ES}> T T' N -> acc N * -> typeOf G T Ty -> <eval {P}> T T'
IH1 : forall N G T T' Ty,
        <eval {ES}> T T' N ** -> acc N @ -> typeOf G T Ty -> <eval {P}> T T'
R : <eval {ES}> (app T1 T2) (app T1 T21) N @@
Acc : acc N @
R1 : value T1
R2 : <eval {ES}> T2 T21 N **
Ty : typeOf G T1 (arrowTy Ty1 Ty)
Ty1 : typeOf G T2 Ty1
============================
 <eval {P}> (app T1 T2) (app T1 T21)
 < apply IH1 to R2 Acc Ty1.

Subgoal 2:

Variables: N G Ty T21 T1 T2 Ty1
IH : forall N G T T' Ty,
       <eval {ES}> T T' N -> acc N * -> typeOf G T Ty -> <eval {P}> T T'
IH1 : forall N G T T' Ty,
        <eval {ES}> T T' N ** -> acc N @ -> typeOf G T Ty -> <eval {P}> T T'
R : <eval {ES}> (app T1 T2) (app T1 T21) N @@
Acc : acc N @
R1 : value T1
R2 : <eval {ES}> T2 T21 N **
Ty : typeOf G T1 (arrowTy Ty1 Ty)
Ty1 : typeOf G T2 Ty1
H1 : <eval {P}> T2 T21
============================
 <eval {P}> (app T1 T2) (app T1 T21)
 < search.

Subgoal 3:

Variables: G T' Ty T2 Body Ty1 X
IH : forall N G T T' Ty,
       <eval {ES}> T T' N -> acc N * -> typeOf G T Ty -> <eval {P}> T T'
IH1 : forall N G T T' Ty,
        <eval {ES}> T T' N ** -> acc N @ -> typeOf G T Ty -> <eval {P}> T T'
R : <eval {ES}> (app (abs X Ty1 Body) T2) T' 0 @@
Acc : acc 0 @
Ty : typeOf G (app (abs X Ty1 Body) T2) Ty
R1 : value T2
R2 : subst X T2 Body T'
============================
 <eval {P}> (app (abs X Ty1 Body) T2) T'
 < search.

Proof completed.
Back to example home