Reasoning Details

 < Module walkthrough:let.
 < Prove walkthrough:host:typeOf_unique.

Subgoal 4:

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

Subgoal 4:

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

Subgoal 4:

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

Subgoal 4:

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

Proof completed.
 < Prove walkthrough:host:ty_lookup.

Subgoal 4:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1 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 (let X T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx1) T2 Ty *
============================
 typeOf Ctx2 (let X T1 T2) Ty
 < apply IH to Ty1 L.

Subgoal 4:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1 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 (let X T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx1) T2 Ty *
H1 : typeOf Ctx2 T1 Ty1
============================
 typeOf Ctx2 (let X T1 T2) Ty
 < apply IH to Ty2 _ with
     Ctx2 = (X, Ty1)::Ctx2.

Subgoal 4.1:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1 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 (let X T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx1) T2 Ty *
H1 : typeOf Ctx2 T1 Ty1
============================
 forall X1 XTy, lookup ((X, Ty1)::Ctx1) X1 XTy -> lookup ((X, Ty1)::Ctx2) X1 XTy
 < intros Lkp.

Subgoal 4.1:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1 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 (let X T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx1) T2 Ty *
H1 : typeOf Ctx2 T1 Ty1
Lkp : lookup ((X, Ty1)::Ctx1) X1 XTy
============================
 lookup ((X, Ty1)::Ctx2) X1 XTy
 < Lkp: case Lkp.

Subgoal 4.1.1:

Variables: Ctx1 Ctx2 Ty T2 T1 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 (let X1 T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 XTy *
Ty2 : typeOf ((X1, XTy)::Ctx1) T2 Ty *
H1 : typeOf Ctx2 T1 XTy
============================
 lookup ((X1, XTy)::Ctx2) X1 XTy
 < search.

Subgoal 4.1.2:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1 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 (let X T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx1) T2 Ty *
H1 : typeOf Ctx2 T1 Ty1
Lkp : X = X1 -> false
Lkp1 : lookup Ctx1 X1 XTy
============================
 lookup ((X, Ty1)::Ctx2) X1 XTy
 < apply L to Lkp1.

Subgoal 4.1.2:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1 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 (let X T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx1) T2 Ty *
H1 : typeOf Ctx2 T1 Ty1
Lkp : X = X1 -> false
Lkp1 : lookup Ctx1 X1 XTy
H2 : lookup Ctx2 X1 XTy
============================
 lookup ((X, Ty1)::Ctx2) X1 XTy
 < search.

Subgoal 4:

Variables: Ctx1 Ctx2 Ty Ty1 T2 T1 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 (let X T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx1) T2 Ty *
H1 : typeOf Ctx2 T1 Ty1
H2 : typeOf ((X, Ty1)::Ctx2) T2 Ty
============================
 typeOf Ctx2 (let X T1 T2) Ty
 < search.

Proof completed.
 < Prove walkthrough:host:subst_type_preservation.

Subgoal 6:

Variables: Ctx X XTy Ty R S2 S1 Y 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) (let Y T1 T2) Ty
S : subst X R (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
============================
 typeOf Ctx (let Y S1 S2) Ty
 < Ty: case TTy.

Subgoal 6:

Variables: Ctx X XTy Ty R S2 S1 Y 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 (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) T2 Ty
============================
 typeOf Ctx (let Y S1 S2) Ty
 < apply IH to Ty S2 RTy.

Subgoal 6:

Variables: Ctx X XTy Ty R S2 S1 Y 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 (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
============================
 typeOf Ctx (let Y S1 S2) Ty
 < Ty': apply ty_lookup to Ty1 _ with
          Ctx2 = (X, XTy)::((Y, Ty1)::Ctx).

Subgoal 6.1:

Variables: Ctx X XTy Ty R S2 S1 Y 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 (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
============================
 forall X1 XTy1,
   lookup ((Y, Ty1)::((X, XTy)::Ctx)) X1 XTy1 -> lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
 < intros L.

Subgoal 6.1:

Variables: Ctx X XTy Ty R S2 S1 Y T2 T1 Ty1 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 (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
L : lookup ((Y, Ty1)::((X, XTy)::Ctx)) X1 XTy1
============================
 lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
 < L: case L.

Subgoal 6.1.1:

Variables: Ctx X XTy Ty R S2 S1 T2 T1 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 (let X1 T1 T2) (let X1 S1 S2) @
RTy : typeOf [] R XTy
S1 : X = X1 -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 XTy1
Ty1 : typeOf ((X1, XTy1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 XTy1
============================
 lookup ((X, XTy)::((X1, XTy1)::Ctx)) X1 XTy1
 < search.

Subgoal 6.1.2:

Variables: Ctx X XTy Ty R S2 S1 Y T2 T1 Ty1 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 (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
L : Y = X1 -> false
L1 : lookup ((X, XTy)::Ctx) X1 XTy1
============================
 lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
 < L: case L1.

Subgoal 6.1.2.1:

Variables: Ctx Ty R S2 S1 Y T2 T1 Ty1 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 (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy1
S1 : X1 = Y -> false
S2 : subst X1 R T1 S1 *
S3 : subst X1 R T2 S2 *
Ty : typeOf ((X1, XTy1)::Ctx) T1 Ty1
Ty1 : typeOf ((Y, Ty1)::((X1, XTy1)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
L : Y = X1 -> false
============================
 lookup ((X1, XTy1)::((Y, Ty1)::Ctx)) X1 XTy1
 < search.

Subgoal 6.1.2.2:

Variables: Ctx X XTy Ty R S2 S1 Y T2 T1 Ty1 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 (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
L : Y = X1 -> false
L1 : X = X1 -> false
L2 : lookup Ctx X1 XTy1
============================
 lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
 < search.

Subgoal 6:

Variables: Ctx X XTy Ty R S2 S1 Y 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 (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
Ty' : typeOf ((X, XTy)::((Y, Ty1)::Ctx)) T2 Ty
============================
 typeOf Ctx (let Y S1 S2) Ty
 < apply IH to Ty' S3 RTy.

Subgoal 6:

Variables: Ctx X XTy Ty R S2 S1 Y 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 (let Y T1 T2) (let Y S1 S2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R T1 S1 *
S3 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
Ty' : typeOf ((X, XTy)::((Y, Ty1)::Ctx)) T2 Ty
H2 : typeOf ((Y, Ty1)::Ctx) S2 Ty
============================
 typeOf Ctx (let Y S1 S2) Ty
 < search.

Subgoal 7:

Variables: Ctx X XTy Ty R T2 S1 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) (let X T1 T2) Ty
S : subst X R (let X T1 T2) (let X S1 T2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
============================
 typeOf Ctx (let X S1 T2) Ty
 < Ty: case TTy.

Subgoal 7:

Variables: Ctx X XTy Ty R T2 S1 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 (let X T1 T2) (let X S1 T2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((X, Ty1)::((X, XTy)::Ctx)) T2 Ty
============================
 typeOf Ctx (let X S1 T2) Ty
 < apply IH to Ty S1 RTy.

Subgoal 7:

Variables: Ctx X XTy Ty R T2 S1 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 (let X T1 T2) (let X S1 T2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((X, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
============================
 typeOf Ctx (let X S1 T2) Ty
 < apply ty_lookup to Ty1 _ with
     Ctx2 = (X, Ty1)::Ctx.

Subgoal 7.1:

Variables: Ctx X XTy Ty R T2 S1 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 (let X T1 T2) (let X S1 T2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((X, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
============================
 forall X1 XTy1,
   lookup ((X, Ty1)::((X, XTy)::Ctx)) X1 XTy1 -> lookup ((X, Ty1)::Ctx) X1 XTy1
 < intros L.

Subgoal 7.1:

Variables: Ctx X XTy Ty R T2 S1 T1 Ty1 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 (let X T1 T2) (let X S1 T2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((X, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
L : lookup ((X, Ty1)::((X, XTy)::Ctx)) X1 XTy1
============================
 lookup ((X, Ty1)::Ctx) X1 XTy1
 < L: case L.

Subgoal 7.1.1:

Variables: Ctx XTy Ty R T2 S1 T1 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 (let X1 T1 T2) (let X1 S1 T2) @
RTy : typeOf [] R XTy
S1 : subst X1 R T1 S1 *
Ty : typeOf ((X1, XTy)::Ctx) T1 XTy1
Ty1 : typeOf ((X1, XTy1)::((X1, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 XTy1
============================
 lookup ((X1, XTy1)::Ctx) X1 XTy1
 < search.

Subgoal 7.1.2:

Variables: Ctx X XTy Ty R T2 S1 T1 Ty1 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 (let X T1 T2) (let X S1 T2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((X, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
L : X = X1 -> false
L1 : lookup ((X, XTy)::Ctx) X1 XTy1
============================
 lookup ((X, Ty1)::Ctx) X1 XTy1
 < L: case L1.

Subgoal 7.1.2.1:

Variables: Ctx Ty R T2 S1 T1 Ty1 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 (let X1 T1 T2) (let X1 S1 T2) @
RTy : typeOf [] R XTy1
S1 : subst X1 R T1 S1 *
Ty : typeOf ((X1, XTy1)::Ctx) T1 Ty1
Ty1 : typeOf ((X1, Ty1)::((X1, XTy1)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
L : X1 = X1 -> false
============================
 lookup ((X1, Ty1)::Ctx) X1 XTy1
 < apply L to _.

Subgoal 7.1.2.2:

Variables: Ctx X XTy Ty R T2 S1 T1 Ty1 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 (let X T1 T2) (let X S1 T2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((X, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
L : X = X1 -> false
L1 : X = X1 -> false
L2 : lookup Ctx X1 XTy1
============================
 lookup ((X, Ty1)::Ctx) X1 XTy1
 < search.

Subgoal 7:

Variables: Ctx X XTy Ty R T2 S1 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 (let X T1 T2) (let X S1 T2) @
RTy : typeOf [] R XTy
S1 : subst X R T1 S1 *
Ty : typeOf ((X, XTy)::Ctx) T1 Ty1
Ty1 : typeOf ((X, Ty1)::((X, XTy)::Ctx)) T2 Ty
H1 : typeOf Ctx S1 Ty1
H2 : typeOf ((X, Ty1)::Ctx) T2 Ty
============================
 typeOf Ctx (let X S1 T2) Ty
 < search.

Proof completed.
 < Prove walkthrough:host:type_preservation.

Subgoal 4:

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

Subgoal 4:

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

Subgoal 4:

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

Subgoal 5:

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

Subgoal 5:

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

Subgoal 5:

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

Proof completed.
 < Prove_Constraint walkthrough:host:proj_type_same.

Variables: G Ty T1 T2 Ty1 X
Hyp : G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
Hyp1 : typeOf G (let X T1 T2) Ty
Hyp2 : typeOf G T1 Ty1
============================
 typeOf G (app (abs X Ty1 T2) T1) Ty
 < case Hyp1.

Variables: G Ty T1 T2 Ty1 X Ty2
Hyp : G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
Hyp2 : typeOf G T1 Ty1
H1 : typeOf G T1 Ty2
H2 : typeOf ((X, Ty2)::G) T2 Ty
============================
 typeOf G (app (abs X Ty1 T2) T1) Ty
 < apply typeOf_unique to Hyp2 H1.

Variables: G Ty T1 T2 X Ty2
Hyp : G |{tm}- let X T1 T2 ~~> app (abs X Ty2 T2) T1
Hyp2 : typeOf G T1 Ty2
H1 : typeOf G T1 Ty2
H2 : typeOf ((X, Ty2)::G) T2 Ty
============================
 typeOf G (app (abs X Ty2 T2) T1) Ty
 < search.

Proof completed.
 < Add_Ext_Size walkthrough:host:eval.

Proof completed.
 < Add_Proj_Rel walkthrough:host:eval.

Proof completed.
 < Prove_Ext_Ind walkthrough:host:eval.

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
Acc : acc N @
Ty : typeOf G (let X T1 T2) Ty
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
============================
 <eval {P}> (let X T1 T2) (let X T11 T2)
 < Acc: case Acc.

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
Ty : typeOf G (let X T1 T2) Ty
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
Acc : forall M, 0 <= M -> M < N -> acc M *
============================
 <eval {P}> (let X T1 T2) (let X T11 T2)
 < unfold .

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
Ty : typeOf G (let X T1 T2) Ty
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
Acc : forall M, 0 <= M -> M < N -> acc M *
============================
 exists Ctx T_T T3,
   <eval {P}> T1 T11 /\ (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < Ty: case Ty.

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
Acc : forall M, 0 <= M -> M < N -> acc M *
Ty : typeOf G T1 Ty1
Ty1 : typeOf ((X, Ty1)::G) T2 Ty
============================
 exists Ctx T_T T3,
   <eval {P}> T1 T11 /\ (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < assert G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1.

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
Acc : forall M, 0 <= M -> M < N -> acc M *
Ty : typeOf G T1 Ty1
Ty1 : typeOf ((X, Ty1)::G) T2 Ty
H1 : G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
============================
 exists Ctx T_T T3,
   <eval {P}> T1 T11 /\ (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < IsN2: apply ext_size_is_int_eval to R2.

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
Acc : forall M, 0 <= M -> M < N -> acc M *
Ty : typeOf G T1 Ty1
Ty1 : typeOf ((X, Ty1)::G) T2 Ty
H1 : G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
IsN2 : is_integer N2
============================
 exists Ctx T_T T3,
   <eval {P}> T1 T11 /\ (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < L: apply lt_plus_one to R1 _.

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
Acc : forall M, 0 <= M -> M < N -> acc M *
Ty : typeOf G T1 Ty1
Ty1 : typeOf ((X, Ty1)::G) T2 Ty
H1 : G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
IsN2 : is_integer N2
L : N2 < N
============================
 exists Ctx T_T T3,
   <eval {P}> T1 T11 /\ (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < PosN2: apply ext_size_pos_eval to R2.

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
Acc : forall M, 0 <= M -> M < N -> acc M *
Ty : typeOf G T1 Ty1
Ty1 : typeOf ((X, Ty1)::G) T2 Ty
H1 : G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
IsN2 : is_integer N2
L : N2 < N
PosN2 : 0 <= N2
============================
 exists Ctx T_T T3,
   <eval {P}> T1 T11 /\ (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < A: apply Acc to PosN2 L.

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
Acc : forall M, 0 <= M -> M < N -> acc M *
Ty : typeOf G T1 Ty1
Ty1 : typeOf ((X, Ty1)::G) T2 Ty
H1 : G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
IsN2 : is_integer N2
L : N2 < N
PosN2 : 0 <= N2
A : acc N2 *
============================
 exists Ctx T_T T3,
   <eval {P}> T1 T11 /\ (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < apply IH to R2 A Ty.

Subgoal 4:

Variables: N G Ty N2 T2 T11 X 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}> (let X T1 T2) (let X T11 T2) N @@
R1 : 1 + N2 = N
R2 : <eval {ES}> T1 T11 N2 **
Acc : forall M, 0 <= M -> M < N -> acc M *
Ty : typeOf G T1 Ty1
Ty1 : typeOf ((X, Ty1)::G) T2 Ty
H1 : G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
IsN2 : is_integer N2
L : N2 < N
PosN2 : 0 <= N2
A : acc N2 *
H2 : <eval {P}> T1 T11
============================
 exists Ctx T_T T3,
   <eval {P}> T1 T11 /\ (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < search.

Subgoal 5:

Variables: G T' Ty T2 T1 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}> (let X T1 T2) T' 1 @@
Acc : acc 1 @
Ty : typeOf G (let X T1 T2) Ty
R1 : value T1
R2 : subst X T1 T2 T'
============================
 <eval {P}> (let X T1 T2) T'
 < unfold .

Subgoal 5:

Variables: G T' Ty T2 T1 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}> (let X T1 T2) T' 1 @@
Acc : acc 1 @
Ty : typeOf G (let X T1 T2) Ty
R1 : value T1
R2 : subst X T1 T2 T'
============================
 exists Ctx T_T T3,
   (value T1 /\ subst X T1 T2 T') /\
   (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < Ty: case Ty.

Subgoal 5:

Variables: G T' Ty T2 T1 X 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}> (let X T1 T2) T' 1 @@
Acc : acc 1 @
R1 : value T1
R2 : subst X T1 T2 T'
Ty : typeOf G T1 Ty1
Ty1 : typeOf ((X, Ty1)::G) T2 Ty
============================
 exists Ctx T_T T3,
   (value T1 /\ subst X T1 T2 T') /\
   (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < assert G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1.

Subgoal 5:

Variables: G T' Ty T2 T1 X 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}> (let X T1 T2) T' 1 @@
Acc : acc 1 @
R1 : value T1
R2 : subst X T1 T2 T'
Ty : typeOf G T1 Ty1
Ty1 : typeOf ((X, Ty1)::G) T2 Ty
H1 : G |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
============================
 exists Ctx T_T T3,
   (value T1 /\ subst X T1 T2 T') /\
   (Ctx |{tm}- let X T1 T2 ~~> T_T /\ <eval {P}> T_T T3)
 < search.

Proof completed.
Back to example home