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