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