Reasoning Details

 < Module soundX:let.
 < Prove_Constraint soundX:host:proj_ty_is.

Proof completed.
 < Prove soundX:host:type_is.

Subgoal 6:

Variables: Ctx Ty Ty1 T2 T1 X
IH : forall Ctx T Ty,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (let X T1 T2)
Ty : typeOf Ctx (let X T1 T2) Ty @
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
============================
 is_ty Ty
 < Is: case IsT.

Subgoal 6:

Variables: Ctx Ty Ty1 T2 T1 X
IH : forall Ctx T Ty,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
Is : is_string X
Is1 : is_tm T1
Is2 : is_tm T2
============================
 is_ty Ty
 < apply IH to _ Is1 Ty1.

Subgoal 6:

Variables: Ctx Ty Ty1 T2 T1 X
IH : forall Ctx T Ty,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
Is : is_string X
Is1 : is_tm T1
Is2 : is_tm T2
H1 : is_ty Ty1
============================
 is_ty Ty
 < apply IH to _ Is2 Ty2.

Subgoal 6:

Variables: Ctx Ty Ty1 T2 T1 X
IH : forall Ctx T Ty,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
Is : is_string X
Is1 : is_tm T1
Is2 : is_tm T2
H1 : is_ty Ty1
H2 : is_ty Ty
============================
 is_ty Ty
 < search.

Proof completed.
 < Prove_Constraint soundX:host:proj_is.

Variables: Ctx T1 T2 Ty X
Proj : Ctx |{tm}- let X T1 T2 ~~> app (abs X Ty T2) T1
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (let X T1 T2)
Proj1 : typeOf Ctx T1 Ty
============================
 is_tm (app (abs X Ty T2) T1)
 < case IsT.

Variables: Ctx T1 T2 Ty X
Proj : Ctx |{tm}- let X T1 T2 ~~> app (abs X Ty T2) T1
IsCtx : is_list (is_pair is_string is_ty) Ctx
Proj1 : typeOf Ctx T1 Ty
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
============================
 is_tm (app (abs X Ty T2) T1)
 < apply type_is to _ _ Proj1.

Variables: Ctx T1 T2 Ty X
Proj : Ctx |{tm}- let X T1 T2 ~~> app (abs X Ty T2) T1
IsCtx : is_list (is_pair is_string is_ty) Ctx
Proj1 : typeOf Ctx T1 Ty
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
H4 : is_ty Ty
============================
 is_tm (app (abs X Ty T2) T1)
 < search.

Proof completed.
 < Prove soundX:host:type_unique.

Subgoal 6:

Variables: Ctx TyA TyB Ty1 T2 T1 X
IH : forall Ctx T TyA TyB,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
       typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (let X T1 T2)
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 6:

Variables: Ctx TyA TyB Ty1 T2 T1 X Ty2
IH : forall Ctx T TyA TyB,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
       typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (let X T1 T2)
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
 < case IsT.

Subgoal 6:

Variables: Ctx TyA TyB Ty1 T2 T1 X Ty2
IH : forall Ctx T TyA TyB,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
       typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
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
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
============================
 TyA = TyB
 < apply IH to _ _ TyA1 TyB.

Subgoal 6:

Variables: Ctx TyA TyB T2 T1 X Ty2
IH : forall Ctx T TyA TyB,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
       typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
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
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
============================
 TyA = TyB
 < apply type_is to _ _ TyA1.

Subgoal 6:

Variables: Ctx TyA TyB T2 T1 X Ty2
IH : forall Ctx T TyA TyB,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
       typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
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
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
H4 : is_ty Ty2
============================
 TyA = TyB
 < apply IH to _ _ TyA2 TyB1.

Subgoal 6:

Variables: Ctx TyB T2 T1 X Ty2
IH : forall Ctx T TyA TyB,
       is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
       typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
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
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
H4 : is_ty Ty2
============================
 TyB = TyB
 < search.

Proof completed.
 < Prove soundX:host:ty_lookup.

Subgoal 6:

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 6:

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 6.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 6.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 6.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 6.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 6.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 6:

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_Constraint soundX:host:proj_ty_unique.

Proof completed.
 < Prove_Constraint soundX:host:proj_tm_unique.

Variables: Ctx TB T1 T2 Ty X
Hyp : Ctx |{tm}- let X T1 T2 ~~> app (abs X Ty T2) T1
Hyp1 : Ctx |{tm}- let X T1 T2 ~~> TB
Hyp2 : is_tm (let X T1 T2)
Hyp3 : is_list (is_pair is_string is_ty) Ctx
Hyp4 : typeOf Ctx T1 Ty
============================
 app (abs X Ty T2) T1 = TB
 < case Hyp1.

Variables: Ctx T1 T2 Ty X Ty1
Hyp : Ctx |{tm}- let X T1 T2 ~~> app (abs X Ty T2) T1
Hyp2 : is_tm (let X T1 T2)
Hyp3 : is_list (is_pair is_string is_ty) Ctx
Hyp4 : typeOf Ctx T1 Ty
H1 : typeOf Ctx T1 Ty1
============================
 app (abs X Ty T2) T1 = app (abs X Ty1 T2) T1
 < case Hyp2.

Variables: Ctx T1 T2 Ty X Ty1
Hyp : Ctx |{tm}- let X T1 T2 ~~> app (abs X Ty T2) T1
Hyp3 : is_list (is_pair is_string is_ty) Ctx
Hyp4 : typeOf Ctx T1 Ty
H1 : typeOf Ctx T1 Ty1
H2 : is_string X
H3 : is_tm T1
H4 : is_tm T2
============================
 app (abs X Ty T2) T1 = app (abs X Ty1 T2) T1
 < apply type_unique to _ _ Hyp4 H1.

Variables: Ctx T1 T2 X Ty1
Hyp : Ctx |{tm}- let X T1 T2 ~~> app (abs X Ty1 T2) T1
Hyp3 : is_list (is_pair is_string is_ty) Ctx
Hyp4 : typeOf Ctx T1 Ty1
H1 : typeOf Ctx T1 Ty1
H2 : is_string X
H3 : is_tm T1
H4 : is_tm T2
============================
 app (abs X Ty1 T2) T1 = app (abs X Ty1 T2) T1
 < search.

Proof completed.
 < Prove soundX:host:desugar_ty_exists.

Proof completed.
 < Prove soundX:host:desugar_ty_rel.

Subgoal 6:

Variables: Ctx Ty T' Ty' Ctx' Ty1 T2 T1 X
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (let X T1 T2)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DT : desugar_tm Ctx (let X T1 T2) T'
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
============================
 typeOf Ctx' T' Ty'
 < case IsT.

Subgoal 6:

Variables: Ctx Ty T' Ty' Ctx' Ty1 T2 T1 X
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DT : desugar_tm Ctx (let X T1 T2) T'
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
============================
 typeOf Ctx' T' Ty'
 < DT: case DT.

Subgoal 6:

Variables: Ctx Ty T' Ty' Ctx' Ty1 T2 T1 X T_P
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT : Ctx |{tm}- let X T1 T2 ~~> T_P
DT1 : desugar_tm Ctx T_P T'
============================
 typeOf Ctx' T' Ty'
 < DT: case DT.

Subgoal 6:

Variables: Ctx Ty T' Ty' Ctx' Ty1 T2 T1 X Ty2
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT1 : desugar_tm Ctx (app (abs X Ty2 T2) T1) T'
DT : typeOf Ctx T1 Ty2
============================
 typeOf Ctx' T' Ty'
 < DT: case DT1.

Subgoal 6.1:

Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 X Ty2 DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT : typeOf Ctx T1 Ty2
DT1 : desugar_tm Ctx (abs X Ty2 T2) DA
DT2 : desugar_tm Ctx T1 DB
============================
 typeOf Ctx' (app DA DB) Ty'
 < DT: case DT1.

Subgoal 6.1.1:

Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 X Ty2 DB DTm DTy
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT : typeOf Ctx T1 Ty2
DT2 : desugar_tm Ctx T1 DB
DT1 : desugar_ty Ty2 DTy
DT3 : desugar_tm ((X, Ty2)::Ctx) T2 DTm
============================
 typeOf Ctx' (app (abs X DTy DTm) DB) Ty'
 < apply type_unique to _ _ DT Ty1.

Subgoal 6.1.1:

Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 X DB DTm DTy
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT : typeOf Ctx T1 Ty1
DT2 : desugar_tm Ctx T1 DB
DT1 : desugar_ty Ty1 DTy
DT3 : desugar_tm ((X, Ty1)::Ctx) T2 DTm
============================
 typeOf Ctx' (app (abs X DTy DTm) DB) Ty'
 < apply IH to _ _ Ty1 _ _ _.

Subgoal 6.1.1:

Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 X DB DTm DTy
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT : typeOf Ctx T1 Ty1
DT2 : desugar_tm Ctx T1 DB
DT1 : desugar_ty Ty1 DTy
DT3 : desugar_tm ((X, Ty1)::Ctx) T2 DTm
H4 : typeOf Ctx' DB DTy
============================
 typeOf Ctx' (app (abs X DTy DTm) DB) Ty'
 < apply type_is to _ _ Ty1.

Subgoal 6.1.1:

Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 X DB DTm DTy
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT : typeOf Ctx T1 Ty1
DT2 : desugar_tm Ctx T1 DB
DT1 : desugar_ty Ty1 DTy
DT3 : desugar_tm ((X, Ty1)::Ctx) T2 DTm
H4 : typeOf Ctx' DB DTy
H5 : is_ty Ty1
============================
 typeOf Ctx' (app (abs X DTy DTm) DB) Ty'
 < apply IH to _ _ Ty2 _ _ _.

Subgoal 6.1.1:

Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 X DB DTm DTy
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT : typeOf Ctx T1 Ty1
DT2 : desugar_tm Ctx T1 DB
DT1 : desugar_ty Ty1 DTy
DT3 : desugar_tm ((X, Ty1)::Ctx) T2 DTm
H4 : typeOf Ctx' DB DTy
H5 : is_ty Ty1
H6 : typeOf ((X, DTy)::Ctx') DTm Ty'
============================
 typeOf Ctx' (app (abs X DTy DTm) DB) Ty'
 < search.

Subgoal 6.1.2:

Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 X Ty2 DB DA T_P1
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT : typeOf Ctx T1 Ty2
DT2 : desugar_tm Ctx T1 DB
DT1 : Ctx |{tm}- abs X Ty2 T2 ~~> T_P1
DT3 : desugar_tm Ctx T_P1 DA
============================
 typeOf Ctx' (app DA DB) Ty'
 < case DT1.

Subgoal 6.2:

Variables: Ctx Ty T' Ty' Ctx' Ty1 T2 T1 X Ty2 T_P1
IH : forall Ctx T Ty T' Ty' Ctx',
       is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
       desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (let X T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 Ty1 *
Ty2 : typeOf ((X, Ty1)::Ctx) T2 Ty *
H1 : is_string X
H2 : is_tm T1
H3 : is_tm T2
DT : typeOf Ctx T1 Ty2
DT1 : Ctx |{tm}- app (abs X Ty2 T2) T1 ~~> T_P1
DT2 : desugar_tm Ctx T_P1 T'
============================
 typeOf Ctx' T' Ty'
 < case DT1.

Proof completed.
Back to example home