< Module stlc:let.
< Prove_Constraint stlc:host:proj_ty_is. Proof completed.
< Prove stlc: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 stlc: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 stlc: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_Constraint stlc:host:proj_ty_unique. Proof completed.
< Prove_Constraint stlc: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 stlc:host:subst_is. Subgoal 8: Variables: X R S2 S1 Y T2 T1 IH : forall X R T S, is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S IsT : is_tm (let Y T1 T2) IsX : is_string X IsR : is_tm R S : subst X R (let Y T1 T2) (let Y S1 S2) @ S1 : X = Y -> false S2 : subst X R T1 S1 * S3 : subst X R T2 S2 * ============================ is_tm (let Y S1 S2)
< Is: case IsT. Subgoal 8: Variables: X R S2 S1 Y T2 T1 IH : forall X R T S, is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S IsX : is_string X IsR : is_tm R S : subst X R (let Y T1 T2) (let Y S1 S2) @ S1 : X = Y -> false S2 : subst X R T1 S1 * S3 : subst X R T2 S2 * Is : is_string Y Is1 : is_tm T1 Is2 : is_tm T2 ============================ is_tm (let Y S1 S2)
< apply IH to _ _ _ S2. Subgoal 8: Variables: X R S2 S1 Y T2 T1 IH : forall X R T S, is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S IsX : is_string X IsR : is_tm R S : subst X R (let Y T1 T2) (let Y S1 S2) @ S1 : X = Y -> false S2 : subst X R T1 S1 * S3 : subst X R T2 S2 * Is : is_string Y Is1 : is_tm T1 Is2 : is_tm T2 H1 : is_tm S1 ============================ is_tm (let Y S1 S2)
< apply IH to _ _ _ S3. Subgoal 8: Variables: X R S2 S1 Y T2 T1 IH : forall X R T S, is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S IsX : is_string X IsR : is_tm R S : subst X R (let Y T1 T2) (let Y S1 S2) @ S1 : X = Y -> false S2 : subst X R T1 S1 * S3 : subst X R T2 S2 * Is : is_string Y Is1 : is_tm T1 Is2 : is_tm T2 H1 : is_tm S1 H2 : is_tm S2 ============================ is_tm (let Y S1 S2)
< search. Subgoal 9: Variables: X R T2 S1 T1 IH : forall X R T S, is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S IsT : is_tm (let X T1 T2) IsX : is_string X IsR : is_tm R S : subst X R (let X T1 T2) (let X S1 T2) @ S1 : subst X R T1 S1 * ============================ is_tm (let X S1 T2)
< Is: case IsT. Subgoal 9: Variables: X R T2 S1 T1 IH : forall X R T S, is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S IsX : is_string X IsR : is_tm R S : subst X R (let X T1 T2) (let X S1 T2) @ S1 : subst X R T1 S1 * Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 ============================ is_tm (let X S1 T2)
< apply IH to _ _ _ S1. Subgoal 9: Variables: X R T2 S1 T1 IH : forall X R T S, is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S IsX : is_string X IsR : is_tm R S : subst X R (let X T1 T2) (let X S1 T2) @ S1 : subst X R T1 S1 * Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 H1 : is_tm S1 ============================ is_tm (let X S1 T2)
< search. Proof completed.
< Prove stlc:host:eval_is. Subgoal 7: Variables: T2 T11 X T1 IH : forall T T', is_tm T -> eval T T' * -> is_tm T' IsT : is_tm (let X T1 T2) Ev : eval (let X T1 T2) (let X T11 T2) @ Ev1 : eval T1 T11 * ============================ is_tm (let X T11 T2)
< Is: case IsT. Subgoal 7: Variables: T2 T11 X T1 IH : forall T T', is_tm T -> eval T T' * -> is_tm T' Ev : eval (let X T1 T2) (let X T11 T2) @ Ev1 : eval T1 T11 * Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 ============================ is_tm (let X T11 T2)
< apply IH to _ Ev1. Subgoal 7: Variables: T2 T11 X T1 IH : forall T T', is_tm T -> eval T T' * -> is_tm T' Ev : eval (let X T1 T2) (let X T11 T2) @ Ev1 : eval T1 T11 * Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 H1 : is_tm T11 ============================ is_tm (let X T11 T2)
< search. Subgoal 8: Variables: T' T2 T1 X IH : forall T T', is_tm T -> eval T T' * -> is_tm T' IsT : is_tm (let X T1 T2) Ev : eval (let X T1 T2) T' @ Ev1 : value T1 Ev2 : subst X T1 T2 T' ============================ is_tm T'
< Is: case IsT. Subgoal 8: Variables: T' T2 T1 X IH : forall T T', is_tm T -> eval T T' * -> is_tm T' Ev : eval (let X T1 T2) T' @ Ev1 : value T1 Ev2 : subst X T1 T2 T' Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 ============================ is_tm T'
< apply subst_is to _ _ _ Ev2. Subgoal 8: Variables: T' T2 T1 X IH : forall T T', is_tm T -> eval T T' * -> is_tm T' Ev : eval (let X T1 T2) T' @ Ev1 : value T1 Ev2 : subst X T1 T2 T' Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 H1 : is_tm T' ============================ is_tm T'
< search. Proof completed.
< Prove stlc:host:subst_unique. Subgoal 8: Variables: X R VB S2 S1 Y T2 T1 IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB SA : subst X R (let Y T1 T2) (let Y S1 S2) @ SB : subst X R (let Y T1 T2) VB SA1 : X = Y -> false SA2 : subst X R T1 S1 * SA3 : subst X R T2 S2 * ============================ let Y S1 S2 = VB
< SB: case SB. Subgoal 8.1: Variables: X R S2 S1 Y T2 T1 S4 S3 IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB SA : subst X R (let Y T1 T2) (let Y S1 S2) @ SA1 : X = Y -> false SA2 : subst X R T1 S1 * SA3 : subst X R T2 S2 * SB : X = Y -> false SB1 : subst X R T1 S3 SB2 : subst X R T2 S4 ============================ let Y S1 S2 = let Y S3 S4
< apply IH to SA2 SB1. Subgoal 8.1: Variables: X R S2 Y T2 T1 S4 S3 IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB SA : subst X R (let Y T1 T2) (let Y S3 S2) @ SA1 : X = Y -> false SA2 : subst X R T1 S3 * SA3 : subst X R T2 S2 * SB : X = Y -> false SB1 : subst X R T1 S3 SB2 : subst X R T2 S4 ============================ let Y S3 S2 = let Y S3 S4
< apply IH to SA3 SB2. Subgoal 8.1: Variables: X R Y T2 T1 S4 S3 IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB SA : subst X R (let Y T1 T2) (let Y S3 S4) @ SA1 : X = Y -> false SA2 : subst X R T1 S3 * SA3 : subst X R T2 S4 * SB : X = Y -> false SB1 : subst X R T1 S3 SB2 : subst X R T2 S4 ============================ let Y S3 S4 = let Y S3 S4
< search. Subgoal 8.2: Variables: R S2 S1 Y T2 T1 S3 IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB SA : subst Y R (let Y T1 T2) (let Y S1 S2) @ SA1 : Y = Y -> false SA2 : subst Y R T1 S1 * SA3 : subst Y R T2 S2 * SB : subst Y R T1 S3 ============================ let Y S1 S2 = let Y S3 T2
< apply SA1 to _. Subgoal 9: Variables: X R VB T2 S1 T1 IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB SA : subst X R (let X T1 T2) (let X S1 T2) @ SB : subst X R (let X T1 T2) VB SA1 : subst X R T1 S1 * ============================ let X S1 T2 = VB
< SB: case SB. Subgoal 9.1: Variables: X R T2 S1 T1 S3 S2 IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB SA : subst X R (let X T1 T2) (let X S1 T2) @ SA1 : subst X R T1 S1 * SB : X = X -> false SB1 : subst X R T1 S2 SB2 : subst X R T2 S3 ============================ let X S1 T2 = let X S2 S3
< apply SB to _. Subgoal 9.2: Variables: X R T2 S1 T1 S2 IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB SA : subst X R (let X T1 T2) (let X S1 T2) @ SA1 : subst X R T1 S1 * SB : subst X R T1 S2 ============================ let X S1 T2 = let X S2 T2
< apply IH to SA1 SB. Subgoal 9.2: Variables: X R T2 T1 S2 IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB SA : subst X R (let X T1 T2) (let X S2 T2) @ SA1 : subst X R T1 S2 * SB : subst X R T1 S2 ============================ let X S2 T2 = let X S2 T2
< search. Proof completed.
< Prove stlc:host:value_eval_false. Proof completed.
< Prove stlc:host:eval_unique. Subgoal 7: Variables: VB T2 T11 X T1 IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB EvA : eval (let X T1 T2) (let X T11 T2) @ EvB : eval (let X T1 T2) VB EvA1 : eval T1 T11 * ============================ let X T11 T2 = VB
< EvB: case EvB. Subgoal 7.1: Variables: T2 T11 X T1 T5 IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB EvA : eval (let X T1 T2) (let X T11 T2) @ EvA1 : eval T1 T11 * EvB : eval T1 T5 ============================ let X T11 T2 = let X T5 T2
< apply IH to EvA1 EvB. Subgoal 7.1: Variables: T2 X T1 T5 IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB EvA : eval (let X T1 T2) (let X T5 T2) @ EvA1 : eval T1 T5 * EvB : eval T1 T5 ============================ let X T5 T2 = let X T5 T2
< search. Subgoal 7.2: Variables: VB T2 T11 X T1 IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB EvA : eval (let X T1 T2) (let X T11 T2) @ EvA1 : eval T1 T11 * EvB : value T1 EvB1 : subst X T1 T2 VB ============================ let X T11 T2 = VB
< apply value_eval_false to EvB EvA1. Subgoal 8: Variables: VA VB T2 T1 X IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB EvA : eval (let X T1 T2) VA @ EvB : eval (let X T1 T2) VB EvA1 : value T1 EvA2 : subst X T1 T2 VA ============================ VA = VB
< EvB: case EvB. Subgoal 8.1: Variables: VA T2 T1 X T11 IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB EvA : eval (let X T1 T2) VA @ EvA1 : value T1 EvA2 : subst X T1 T2 VA EvB : eval T1 T11 ============================ VA = let X T11 T2
< apply value_eval_false to EvA1 EvB. Subgoal 8.2: Variables: VA VB T2 T1 X IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB EvA : eval (let X T1 T2) VA @ EvA1 : value T1 EvA2 : subst X T1 T2 VA EvB : value T1 EvB1 : subst X T1 T2 VB ============================ VA = VB
< apply subst_unique to EvA2 EvB1. Subgoal 8.2: Variables: VB T2 T1 X IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB EvA : eval (let X T1 T2) VB @ EvA1 : value T1 EvA2 : subst X T1 T2 VB EvB : value T1 EvB1 : subst X T1 T2 VB ============================ VB = VB
< search. Proof completed.
< Prove stlc: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 stlc:host:subst_type_preservation. Subgoal 8: 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 8: 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 8: 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 8.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 8.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 8.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 8.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 8.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 8.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 8: 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 8: 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 9: 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 9: 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 9: 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 9.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 9.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 9.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 9.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 9.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 9.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 9: 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 stlc:host:type_preservation. Subgoal 7: 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 7: 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 7: 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 8: 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 8: 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 8: 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 stlc:host:subst_total. Subgoal 6: Variables: X R Tm Tm1 S IH : forall X R T, is_tm T * -> is_string X -> exists S, subst X R T S IsT : is_tm (let S Tm1 Tm) @ IsX : is_string X IsT1 : is_string S IsT2 : is_tm Tm1 * IsT3 : is_tm Tm * ============================ exists S1, subst X R (let S Tm1 Tm) S1
< Or: apply is_string_eq_or_not to IsX IsT1. Subgoal 6: Variables: X R Tm Tm1 S IH : forall X R T, is_tm T * -> is_string X -> exists S, subst X R T S IsT : is_tm (let S Tm1 Tm) @ IsX : is_string X IsT1 : is_string S IsT2 : is_tm Tm1 * IsT3 : is_tm Tm * Or : X = S \/ (X = S -> false) ============================ exists S1, subst X R (let S Tm1 Tm) S1
< E: case Or. Subgoal 6.1: Variables: R Tm Tm1 S IH : forall X R T, is_tm T * -> is_string X -> exists S, subst X R T S IsT : is_tm (let S Tm1 Tm) @ IsX : is_string S IsT1 : is_string S IsT2 : is_tm Tm1 * IsT3 : is_tm Tm * ============================ exists S1, subst S R (let S Tm1 Tm) S1
< apply IH to IsT2 IsX with R = R. Subgoal 6.1: Variables: R Tm Tm1 S S1 IH : forall X R T, is_tm T * -> is_string X -> exists S, subst X R T S IsT : is_tm (let S Tm1 Tm) @ IsX : is_string S IsT1 : is_string S IsT2 : is_tm Tm1 * IsT3 : is_tm Tm * H1 : subst S R Tm1 S1 ============================ exists S1, subst S R (let S Tm1 Tm) S1
< search. Subgoal 6.2: Variables: X R Tm Tm1 S IH : forall X R T, is_tm T * -> is_string X -> exists S, subst X R T S IsT : is_tm (let S Tm1 Tm) @ IsX : is_string X IsT1 : is_string S IsT2 : is_tm Tm1 * IsT3 : is_tm Tm * E : X = S -> false ============================ exists S1, subst X R (let S Tm1 Tm) S1
< apply IH to IsT2 IsX with R = R. Subgoal 6.2: Variables: X R Tm Tm1 S S1 IH : forall X R T, is_tm T * -> is_string X -> exists S, subst X R T S IsT : is_tm (let S Tm1 Tm) @ IsX : is_string X IsT1 : is_string S IsT2 : is_tm Tm1 * IsT3 : is_tm Tm * E : X = S -> false H1 : subst X R Tm1 S1 ============================ exists S1, subst X R (let S Tm1 Tm) S1
< apply IH to IsT3 IsX with R = R. Subgoal 6.2: Variables: X R Tm Tm1 S S1 S2 IH : forall X R T, is_tm T * -> is_string X -> exists S, subst X R T S IsT : is_tm (let S Tm1 Tm) @ IsX : is_string X IsT1 : is_string S IsT2 : is_tm Tm1 * IsT3 : is_tm Tm * E : X = S -> false H1 : subst X R Tm1 S1 H2 : subst X R Tm S2 ============================ exists S1, subst X R (let S Tm1 Tm) S1
< search. Proof completed.
< Prove stlc:host:canonical_forms. Proof completed.
< Prove stlc:host:progress. Subgoal 6: Variables: Ty Ty1 T2 T1 X IH : forall T Ty, is_tm T -> typeOf [] T Ty * -> (exists T', eval T T') \/ value T IsT : is_tm (let X T1 T2) Ty : typeOf [] (let X T1 T2) Ty @ Ty1 : typeOf [] T1 Ty1 * Ty2 : typeOf [(X, Ty1)] T2 Ty * ============================ (exists T', eval (let X T1 T2) T') \/ value (let X T1 T2)
< Is: case IsT. Subgoal 6: Variables: Ty Ty1 T2 T1 X IH : forall T Ty, is_tm T -> typeOf [] T Ty * -> (exists T', eval T T') \/ value T Ty : typeOf [] (let X T1 T2) Ty @ Ty1 : typeOf [] T1 Ty1 * Ty2 : typeOf [(X, Ty1)] T2 Ty * Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 ============================ (exists T', eval (let X T1 T2) T') \/ value (let X T1 T2)
< Or: apply IH to _ Ty1. Subgoal 6: Variables: Ty Ty1 T2 T1 X IH : forall T Ty, is_tm T -> typeOf [] T Ty * -> (exists T', eval T T') \/ value T Ty : typeOf [] (let X T1 T2) Ty @ Ty1 : typeOf [] T1 Ty1 * Ty2 : typeOf [(X, Ty1)] T2 Ty * Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 Or : (exists T', eval T1 T') \/ value T1 ============================ (exists T', eval (let X T1 T2) T') \/ value (let X T1 T2)
< EV: case Or. Subgoal 6.1: Variables: Ty Ty1 T2 T1 X T' IH : forall T Ty, is_tm T -> typeOf [] T Ty * -> (exists T', eval T T') \/ value T Ty : typeOf [] (let X T1 T2) Ty @ Ty1 : typeOf [] T1 Ty1 * Ty2 : typeOf [(X, Ty1)] T2 Ty * Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 EV : eval T1 T' ============================ (exists T', eval (let X T1 T2) T') \/ value (let X T1 T2)
< search. Subgoal 6.2: Variables: Ty Ty1 T2 T1 X IH : forall T Ty, is_tm T -> typeOf [] T Ty * -> (exists T', eval T T') \/ value T Ty : typeOf [] (let X T1 T2) Ty @ Ty1 : typeOf [] T1 Ty1 * Ty2 : typeOf [(X, Ty1)] T2 Ty * Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 EV : value T1 ============================ (exists T', eval (let X T1 T2) T') \/ value (let X T1 T2)
< apply subst_total to Is2 Is with R = T1. Subgoal 6.2: Variables: Ty Ty1 T2 T1 X S IH : forall T Ty, is_tm T -> typeOf [] T Ty * -> (exists T', eval T T') \/ value T Ty : typeOf [] (let X T1 T2) Ty @ Ty1 : typeOf [] T1 Ty1 * Ty2 : typeOf [(X, Ty1)] T2 Ty * Is : is_string X Is1 : is_tm T1 Is2 : is_tm T2 EV : value T1 H1 : subst X T1 T2 S ============================ (exists T', eval (let X T1 T2) T') \/ value (let X T1 T2)
< search. Proof completed.