tm = n) /\
(!s s'.
(s,s') env
==> ?x ty. (s = Var x ty) /\
(s' = Var x (
tyin ty)))
==> (?x ty. (
tyin ty))
env (Var x ty) = Var x ty)) \/
(!x ty.
tyin ty))
env (Var x ty) = Var x ty)) /\
(?tm'. (
tyin (typeof tm)) /\
(!u uty.
(Var u uty) tm' <=>
?oty.
(\(x,ty).
tyin ty))
(\s.
MATCH_MP_TAC
num_WF THEN GEN_TAC THEN DISCH_TAC THEN
MATCH_MP_TAC term_INDUCT THEN
ONCE_REWRITE_TAC[
INST_CORE] THEN REWRITE_TAC[
semantics] THEN
REPEAT CONJ_TAC THENL
[POP_ASSUM(K ALL_TAC) THEN
REWRITE_TAC[
REV_ASSOCD;
LET_DEF;
LET_END_DEF] THEN
REPEAT GEN_TAC THEN COND_CASES_TAC THEN
ASM_REWRITE_TAC[result_DISTINCT; result_INJ;
UNWIND_THM1] THEN
REWRITE_TAC[typeof;
has_type_RULES] THEN
CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
REWRITE_TAC[
RESULT;
semantics;
VFREE_IN; term_INJ] THEN ASM_MESON_TAC[];
POP_ASSUM(K ALL_TAC) THEN
REWRITE_TAC[
TYPE_SUBST;
RESULT;
VFREE_IN; term_DISTINCT] THEN
ASM_REWRITE_TAC[result_DISTINCT; result_INJ;
UNWIND_THM1] THEN
REWRITE_TAC[typeof;
has_type_RULES;
TYPE_SUBST;
VFREE_IN] THEN
REWRITE_TAC[
semantics;
typeset;
TYPESET_LEMMA;
TYPE_SUBST; term_DISTINCT];
POP_ASSUM(K ALL_TAC) THEN
REWRITE_TAC[
TYPE_SUBST;
RESULT;
VFREE_IN; term_DISTINCT] THEN
ASM_REWRITE_TAC[result_DISTINCT; result_INJ;
UNWIND_THM1] THEN
REWRITE_TAC[typeof;
has_type_RULES;
TYPE_SUBST;
VFREE_IN] THEN
REWRITE_TAC[
semantics;
typeset;
TYPESET_LEMMA;
TYPE_SUBST; term_DISTINCT];
MAP_EVERY X_GEN_TAC [`s:term`; `t:term`] THEN DISCH_THEN(K ALL_TAC) THEN
POP_ASSUM MP_TAC THEN ASM_CASES_TAC `n =
sizeof(Comb s t)` THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN(fun
th -> MP_TAC(SPEC `
sizeof t`
th) THEN
MP_TAC(SPEC `
sizeof s`
th)) THEN
REWRITE_TAC[
sizeof; ARITH_RULE `s < 1 + s + t /\ t < 1 + s + t`] THEN
DISCH_THEN(fun
th -> DISCH_THEN(MP_TAC o SPEC `t:term`) THEN
MP_TAC(SPEC `s:term`
th)) THEN
REWRITE_TAC[IMP_IMP;
AND_FORALL_THM;
WELLTYPED_CLAUSES] THEN
REPEAT(MATCH_MP_TAC
MONO_FORALL THEN GEN_TAC) THEN
DISCH_THEN(fun
th -> STRIP_TAC THEN MP_TAC
th) THEN ASM_REWRITE_TAC[] THEN
GEN_REWRITE_TAC I [
IMP_CONJ] THEN
DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL
[DISCH_THEN(fun
th -> DISCH_THEN(K ALL_TAC) THEN MP_TAC
th) THEN
DISCH_THEN(fun
th -> DISJ1_TAC THEN MP_TAC
th) THEN
REPEAT(MATCH_MP_TAC
MONO_EXISTS THEN GEN_TAC) THEN
STRIP_TAC THEN ASM_REWRITE_TAC[
LET_DEF;
LET_END_DEF;
IS_CLASH;
VFREE_IN];
ALL_TAC] THEN
REWRITE_TAC[
TYPE_SUBST] THEN
DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
DISCH_THEN(X_CHOOSE_THEN `s':term` STRIP_ASSUME_TAC) THEN
DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL
[DISCH_THEN(fun
th -> DISJ1_TAC THEN MP_TAC
th) THEN
REPEAT(MATCH_MP_TAC
MONO_EXISTS THEN GEN_TAC) THEN
STRIP_TAC THEN ASM_REWRITE_TAC[
LET_DEF;
LET_END_DEF;
IS_CLASH;
VFREE_IN];
ALL_TAC] THEN
DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
DISCH_THEN(X_CHOOSE_THEN `t':term` STRIP_ASSUME_TAC) THEN
DISJ2_TAC THEN CONJ_TAC THENL
[REWRITE_TAC[
VFREE_IN] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
EXISTS_TAC `Comb s' t'` THEN
ASM_SIMP_TAC[
LET_DEF;
LET_END_DEF;
IS_CLASH;
semantics;
RESULT] THEN
ASM_REWRITE_TAC[
VFREE_IN] THEN
ASM_REWRITE_TAC[typeof] THEN ONCE_REWRITE_TAC[
has_type_CASES] THEN
REWRITE_TAC[term_DISTINCT; term_INJ;
codomain] THEN ASM_MESON_TAC[];
ALL_TAC] THEN
MAP_EVERY X_GEN_TAC [`x:string`; `ty:type`; `t:term`] THEN
DISCH_THEN(K ALL_TAC) THEN POP_ASSUM MP_TAC THEN
ASM_CASES_TAC `n =
sizeof (Abs x ty t)` THEN ASM_REWRITE_TAC[] THEN
POP_ASSUM(K ALL_TAC) THEN DISCH_TAC THEN REPEAT GEN_TAC THEN
REWRITE_TAC[
WELLTYPED_CLAUSES] THEN STRIP_TAC THEN REPEAT LET_TAC THEN
FIRST_ASSUM(MP_TAC o SPEC `
sizeof t`) THEN
REWRITE_TAC[
sizeof; ARITH_RULE `t < 2 + t`] THEN
DISCH_THEN(MP_TAC o SPECL
[`t:term`; `env':(term#term)list`; `tyin:(type#type)list`]) THEN
ASM_REWRITE_TAC[] THEN
ANTS_TAC THENL
[EXPAND_TAC "env'" THEN REWRITE_TAC[
MEM;
PAIR_EQ] THEN ASM_MESON_TAC[];
ALL_TAC] THEN
DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL
[ALL_TAC;
FIRST_X_ASSUM(K ALL_TAC o SPEC `0`) THEN
DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
DISCH_THEN(X_CHOOSE_THEN `t':term` STRIP_ASSUME_TAC) THEN
DISJ2_TAC THEN ASM_REWRITE_TAC[
IS_RESULT] THEN CONJ_TAC THENL
[FIRST_X_ASSUM(fun
th ->
MP_TAC
th THEN MATCH_MP_TAC
MONO_FORALL THEN
GEN_TAC THEN MATCH_MP_TAC
MONO_FORALL THEN GEN_TAC THEN
DISCH_THEN(MP_TAC o check (is_imp o concl))) THEN
EXPAND_TAC "env'" THEN
REWRITE_TAC[
VFREE_IN;
REV_ASSOCD; term_INJ] THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[term_INJ] THEN MESON_TAC[];
ALL_TAC] THEN
REWRITE_TAC[result_INJ;
UNWIND_THM1;
RESULT] THEN
MATCH_MP_TAC(TAUT `a /\ b /\ (b ==> c) ==> b /\ a /\ c`) THEN
CONJ_TAC THENL
[ASM_REWRITE_TAC[
VFREE_IN; term_INJ] THEN
MAP_EVERY X_GEN_TAC [`u:string`; `uty:type`] THEN
ASM_CASES_TAC `u:string = x` THEN ASM_REWRITE_TAC[] THEN
UNDISCH_THEN `u:string = x` SUBST_ALL_TAC THEN
REWRITE_TAC[
RIGHT_AND_EXISTS_THM] THEN
AP_TERM_TAC THEN GEN_REWRITE_TAC I [
FUN_EQ_THM] THEN
X_GEN_TAC `oty:type` THEN REWRITE_TAC[] THEN
ASM_CASES_TAC `uty =
TYPE_SUBST tyin oty` THEN ASM_REWRITE_TAC[] THEN
ASM_CASES_TAC `
VFREE_IN (Var x oty) t` THEN ASM_REWRITE_TAC[] THEN
EQ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
REWRITE_TAC[CONTRAPOS_THM] THEN DISCH_THEN(ASSUME_TAC o SYM) THEN
FIRST_X_ASSUM(fun
th ->
MP_TAC(SPECL [`x:string`; `oty:type`]
th) THEN
ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN NO_TAC; ALL_TAC]) THEN
EXPAND_TAC "env'" THEN REWRITE_TAC[
REV_ASSOCD] THEN
ASM_MESON_TAC[term_INJ];
ALL_TAC] THEN
CONJ_TAC THENL
[REWRITE_TAC[typeof;
TYPE_SUBST] THEN ASM_REWRITE_TAC[] THEN
ASM_MESON_TAC[
has_type_RULES];
ALL_TAC] THEN
DISCH_TAC THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
REWRITE_TAC[
semantics] THEN
ASM_REWRITE_TAC[
TYPE_SUBST;
TYPESET_LEMMA] THEN
MATCH_MP_TAC
ABSTRACT_EQ THEN
CONJ_TAC THENL [ASM_SIMP_TAC[
TYPESET_INHABITED]; ALL_TAC] THEN
X_GEN_TAC `a:V` THEN REWRITE_TAC[] THEN DISCH_TAC THEN CONJ_TAC THENL
[MATCH_MP_TAC
SEMANTICS_TYPESET THEN
ASM_SIMP_TAC[
TERM_VALUATION_VALMOD] THEN
ASM_MESON_TAC[
welltyped;
WELLTYPED];
ALL_TAC] THEN
MATCH_MP_TAC(TAUT `(b ==> a) /\ b ==> a /\ b`) THEN CONJ_TAC THENL
[DISCH_THEN(SUBST1_TAC o SYM) THEN
MATCH_MP_TAC
SEMANTICS_TYPESET THEN
ASM_SIMP_TAC[
TERM_VALUATION_VALMOD];
ALL_TAC] THEN
FIRST_X_ASSUM(MP_TAC o SPECL
[`(x,ty' |-> a) (sigma:(string#type)->V)`; `tau:string->V`]) THEN
ASM_SIMP_TAC[
TERM_VALUATION_VALMOD] THEN DISCH_TAC THEN
REWRITE_TAC[GSYM(CONJUNCT1
TYPE_SUBST)] THEN
MATCH_MP_TAC
TERM_VALUATION_VFREE_IN THEN CONJ_TAC THENL
[REWRITE_TAC[
type_valuation] THEN ASM_SIMP_TAC[
TYPESET_INHABITED];
ALL_TAC] THEN
CONJ_TAC THENL
[REWRITE_TAC[
term_valuation] THEN
MAP_EVERY X_GEN_TAC [`y:string`; `yty:type`] THEN
CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
REWRITE_TAC[
VALMOD;
PAIR_EQ] THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[
TYPE_SUBST;
TYPESET_LEMMA] THEN
ASM_MESON_TAC[
term_valuation];
ALL_TAC] THEN
CONJ_TAC THENL
[REWRITE_TAC[
term_valuation] THEN
MAP_EVERY X_GEN_TAC [`y:string`; `yty:type`] THEN
REWRITE_TAC[
VALMOD] THEN
CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
REWRITE_TAC[
VALMOD;
PAIR_EQ] THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[
TYPE_SUBST;
TYPESET_LEMMA] THEN
ASM_MESON_TAC[
term_valuation];
ALL_TAC] THEN
UNDISCH_THEN
`!u uty.
VFREE_IN (Var u uty) t' <=>
(?oty.
VFREE_IN (Var u oty) t /\ (uty =
TYPE_SUBST tyin oty))`
(K ALL_TAC) THEN
ASM_REWRITE_TAC[] THEN MAP_EVERY X_GEN_TAC [`y:string`; `yty:type`] THEN
CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
REWRITE_TAC[
VALMOD] THEN
CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
ASM_CASES_TAC `y:string = x` THEN ASM_REWRITE_TAC[
PAIR_EQ] THEN
ASM_CASES_TAC `yty:type = ty` THEN ASM_REWRITE_TAC[] THEN
UNDISCH_THEN `y:string = x` SUBST_ALL_TAC THEN COND_CASES_TAC THEN
ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
FIRST_X_ASSUM(MP_TAC o SPECL [`x:string`; `yty:type`]) THEN
ASM_REWRITE_TAC[] THEN EXPAND_TAC "env'" THEN
ASM_REWRITE_TAC[
REV_ASSOCD; term_INJ]] THEN
DISCH_THEN(X_CHOOSE_THEN `z:string` (X_CHOOSE_THEN `zty:type`
(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC))) THEN
EXPAND_TAC "w" THEN REWRITE_TAC[
CLASH;
IS_RESULT; term_INJ] THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
[FIRST_X_ASSUM(K ALL_TAC o SPEC `0`) THEN
DISCH_THEN(fun
th ->
DISJ1_TAC THEN REWRITE_TAC[result_INJ] THEN
MAP_EVERY EXISTS_TAC [`z:string`; `zty:type`] THEN
MP_TAC
th) THEN
ASM_REWRITE_TAC[
VFREE_IN; term_INJ] THEN
EXPAND_TAC "env'" THEN ASM_REWRITE_TAC[
REV_ASSOCD; term_INJ] THEN
ASM_MESON_TAC[];
ALL_TAC] THEN
FIRST_X_ASSUM(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN STRIP_TAC THEN
ONCE_REWRITE_TAC[
INST_CORE] THEN ASM_REWRITE_TAC[] THEN
ONCE_REWRITE_TAC[
letlemma] THEN
ABBREV_TAC `env'' = CONS (Var x' ty,Var x' ty') env` THEN
ONCE_REWRITE_TAC[
letlemma] THEN
ABBREV_TAC
`ures =
INST_CORE env'' tyin (
VSUBST[Var x' ty,Var x ty] t)` THEN
ONCE_REWRITE_TAC[
letlemma] THEN
FIRST_X_ASSUM(MP_TAC o SPEC `
sizeof t`) THEN
REWRITE_TAC[
sizeof; ARITH_RULE `t < 2 + t`] THEN
DISCH_THEN(fun
th ->
MP_TAC(SPECL [`
VSUBST [Var x' ty,Var x ty] t`;
`env'':(term#term)list`; `tyin:(type#type)list`]
th) THEN
MP_TAC(SPECL [`t:term`; `[]:(term#term)list`; `tyin:(type#type)list`]
th)) THEN
REWRITE_TAC[
MEM;
REV_ASSOCD] THEN ASM_REWRITE_TAC[] THEN
DISCH_THEN(X_CHOOSE_THEN `t':term` MP_TAC) THEN STRIP_TAC THEN
UNDISCH_TAC `
VARIANT (
RESULT (
INST_CORE [] tyin t)) x ty' = x'` THEN
ASM_REWRITE_TAC[
RESULT] THEN DISCH_TAC THEN
MP_TAC(SPECL [`t':term`; `x:string`; `ty':type`]
VARIANT) THEN
ASM_REWRITE_TAC[] THEN
GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV)
[
NOT_EXISTS_THM; TAUT `~(a /\ b) <=> a ==> ~b`] THEN DISCH_TAC THEN
ANTS_TAC THENL
[ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
[MATCH_MP_TAC
VSUBST_WELLTYPED THEN ASM_REWRITE_TAC[
MEM;
PAIR_EQ] THEN
ASM_MESON_TAC[
has_type_RULES];
ALL_TAC] THEN
CONJ_TAC THENL
[MATCH_MP_TAC
SIZEOF_VSUBST THEN
ASM_REWRITE_TAC[
MEM;
PAIR_EQ] THEN ASM_MESON_TAC[
has_type_RULES];
ALL_TAC] THEN
EXPAND_TAC "env''" THEN REWRITE_TAC[
MEM;
PAIR_EQ] THEN
ASM_MESON_TAC[];
ALL_TAC] THEN
DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL
[DISCH_THEN(fun
th -> DISJ1_TAC THEN MP_TAC
th) THEN
MATCH_MP_TAC
MONO_EXISTS THEN X_GEN_TAC `v:string` THEN
MATCH_MP_TAC
MONO_EXISTS THEN X_GEN_TAC `vty:type` THEN
ASM_REWRITE_TAC[] THEN
DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
ASM_REWRITE_TAC[
IS_RESULT;
CLASH] THEN
ONCE_REWRITE_TAC[
letlemma] THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
[REWRITE_TAC[
VFREE_IN_VSUBST] THEN EXPAND_TAC "env''" THEN
REWRITE_TAC[
REV_ASSOCD] THEN ASM_REWRITE_TAC[] THEN
DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
ASM_REWRITE_TAC[] THEN REWRITE_TAC[term_INJ] THEN
DISCH_THEN(REPEAT_TCL CHOOSE_THEN MP_TAC) THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[
VFREE_IN; term_INJ] THEN
ASM_MESON_TAC[];
ALL_TAC] THEN
FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [term_INJ]) THEN
DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN
EXPAND_TAC "env''" THEN REWRITE_TAC[
REV_ASSOCD] THEN
ASM_CASES_TAC `vty:type = ty` THEN ASM_REWRITE_TAC[] THEN
DISCH_THEN(MP_TAC o CONJUNCT1) THEN
REWRITE_TAC[
VFREE_IN_VSUBST;
NOT_EXISTS_THM;
REV_ASSOCD] THEN
ONCE_REWRITE_TAC[
COND_RAND] THEN REWRITE_TAC[
VFREE_IN; term_INJ] THEN
MAP_EVERY X_GEN_TAC [`k:string`; `kty:type`] THEN
MP_TAC(SPECL [`t':term`; `x:string`; `ty':type`]
VARIANT) THEN
ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[];
ALL_TAC] THEN
ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
DISCH_THEN(X_CHOOSE_THEN `t'':term` STRIP_ASSUME_TAC) THEN
ASM_REWRITE_TAC[
IS_RESULT; result_INJ;
UNWIND_THM1; result_DISTINCT] THEN
REWRITE_TAC[
RESULT] THEN
MATCH_MP_TAC(TAUT `b /\ (b ==> c /\ a /\ d) ==> a /\ b /\ c /\ d`) THEN
CONJ_TAC THENL
[ASM_REWRITE_TAC[typeof;
TYPE_SUBST] THEN
MATCH_MP_TAC(last(CONJUNCTS
has_type_RULES)) THEN
SUBGOAL_THEN `(
VSUBST [Var x' ty,Var x ty] t)
has_type (typeof t)`
(fun
th -> ASM_MESON_TAC[
th;
WELLTYPED_LEMMA]) THEN
MATCH_MP_TAC
VSUBST_HAS_TYPE THEN ASM_REWRITE_TAC[GSYM
WELLTYPED] THEN
REWRITE_TAC[
MEM;
PAIR_EQ] THEN MESON_TAC[
has_type_RULES];
ALL_TAC] THEN
DISCH_TAC THEN MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN
CONJ_TAC THENL
[ASM_REWRITE_TAC[
VFREE_IN] THEN
MAP_EVERY X_GEN_TAC [`k:string`; `kty:type`] THEN
ASM_REWRITE_TAC[
VFREE_IN_VSUBST;
REV_ASSOCD] THEN
ONCE_REWRITE_TAC[
COND_RAND] THEN REWRITE_TAC[
VFREE_IN; term_INJ] THEN
SIMP_TAC[] THEN
REWRITE_TAC[TAUT `x /\ (if p then a /\ b else c /\ b) <=>
b /\ x /\ (if p then a else c)`] THEN
REWRITE_TAC[
UNWIND_THM2] THEN
REWRITE_TAC[TAUT `x /\ (if p /\ q then a else b) <=>
p /\ q /\ a /\ x \/ b /\ ~(p /\ q) /\ x`] THEN
REWRITE_TAC[
EXISTS_OR_THM;
UNWIND_THM1;
UNWIND_THM2] THEN
ASM_MESON_TAC[];
ALL_TAC] THEN
DISCH_TAC THEN CONJ_TAC THENL
[MAP_EVERY X_GEN_TAC [`k:string`; `kty:type`] THEN
REWRITE_TAC[
VFREE_IN] THEN STRIP_TAC THEN
UNDISCH_TAC `!x'' ty'.
VFREE_IN (Var x'' ty') (
VSUBST [Var x' ty,Var x ty] t)
==> (
REV_ASSOCD (Var x'' (
TYPE_SUBST tyin ty')) env''
(Var x'' ty') = Var x'' ty')` THEN
DISCH_THEN(MP_TAC o SPECL [`k:string`; `kty:type`]) THEN
REWRITE_TAC[
VFREE_IN_VSUBST;
REV_ASSOCD] THEN
ONCE_REWRITE_TAC[
COND_RAND] THEN REWRITE_TAC[
VFREE_IN] THEN
REWRITE_TAC[
VFREE_IN; term_INJ] THEN
SIMP_TAC[] THEN
REWRITE_TAC[TAUT `x /\ (if p then a /\ b else c /\ b) <=>
b /\ x /\ (if p then a else c)`] THEN
REWRITE_TAC[
UNWIND_THM2] THEN
REWRITE_TAC[TAUT `x /\ (if p /\ q then a else b) <=>
p /\ q /\ a /\ x \/ b /\ ~(p /\ q) /\ x`] THEN
REWRITE_TAC[
EXISTS_OR_THM;
UNWIND_THM1;
UNWIND_THM2] THEN
UNDISCH_TAC `~(Var x ty = Var k kty)` THEN
REWRITE_TAC[term_INJ] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
EXPAND_TAC "env''" THEN REWRITE_TAC[
REV_ASSOCD] THEN ASM_MESON_TAC[];
ALL_TAC] THEN
REPEAT STRIP_TAC THEN REWRITE_TAC[
semantics] THEN
REWRITE_TAC[
TYPE_SUBST;
TYPESET_LEMMA] THEN ASM_REWRITE_TAC[] THEN
MATCH_MP_TAC
ABSTRACT_EQ THEN
CONJ_TAC THENL [ASM_SIMP_TAC[
TYPESET_INHABITED]; ALL_TAC] THEN
X_GEN_TAC `a:V` THEN REWRITE_TAC[] THEN DISCH_TAC THEN CONJ_TAC THENL
[MATCH_MP_TAC
SEMANTICS_TYPESET THEN
ASM_SIMP_TAC[
TERM_VALUATION_VALMOD] THEN
ASM_MESON_TAC[
welltyped;
WELLTYPED];
ALL_TAC] THEN
MATCH_MP_TAC(TAUT `(b ==> a) /\ b ==> a /\ b`) THEN CONJ_TAC THENL
[DISCH_THEN(SUBST1_TAC o SYM) THEN
MATCH_MP_TAC
SEMANTICS_TYPESET THEN
ASM_SIMP_TAC[
TERM_VALUATION_VALMOD] THEN
SUBGOAL_THEN `(
VSUBST [Var x' ty,Var x ty] t)
has_type (typeof t)`
(fun
th -> ASM_MESON_TAC[
th;
WELLTYPED_LEMMA]) THEN
MATCH_MP_TAC
VSUBST_HAS_TYPE THEN ASM_REWRITE_TAC[GSYM
WELLTYPED] THEN
REWRITE_TAC[
MEM;
PAIR_EQ] THEN MESON_TAC[
has_type_RULES];
ALL_TAC] THEN
W(fun (asl,w) -> FIRST_X_ASSUM(fun
th ->
MP_TAC(PART_MATCH (lhand o rand)
th (lhand w)))) THEN
ASM_SIMP_TAC[
TERM_VALUATION_VALMOD] THEN DISCH_TAC THEN
REWRITE_TAC[GSYM(CONJUNCT1
TYPE_SUBST)] THEN
MP_TAC
SEMANTICS_VSUBST THEN
REWRITE_TAC[
RIGHT_IMP_FORALL_THM; IMP_IMP] THEN
DISCH_THEN(fun
th ->
W(fun (asl,w) -> MP_TAC(PART_MATCH (lhand o rand)
th (lhand w)))) THEN
ANTS_TAC THENL
[ASM_REWRITE_TAC[
MEM;
PAIR_EQ] THEN CONJ_TAC THENL
[MESON_TAC[
has_type_RULES]; ALL_TAC] THEN
CONJ_TAC THENL
[REWRITE_TAC[
type_valuation] THEN ASM_SIMP_TAC[
TYPESET_INHABITED];
ALL_TAC] THEN
REWRITE_TAC[
term_valuation] THEN
MAP_EVERY X_GEN_TAC [`y:string`; `yty:type`] THEN
REWRITE_TAC[
VALMOD] THEN
CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
REWRITE_TAC[
VALMOD;
PAIR_EQ] THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[
TYPE_SUBST;
TYPESET_LEMMA] THEN
ASM_MESON_TAC[
term_valuation];
ALL_TAC] THEN
DISCH_THEN SUBST1_TAC THEN
REWRITE_TAC[GSYM(CONJUNCT1
TYPE_SUBST)] THEN
MATCH_MP_TAC
TERM_VALUATION_VFREE_IN THEN CONJ_TAC THENL
[REWRITE_TAC[
type_valuation] THEN ASM_SIMP_TAC[
TYPESET_INHABITED];
ALL_TAC] THEN
REWRITE_TAC[
ITLIST] THEN
CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
REWRITE_TAC[
DEST_VAR] THEN REWRITE_TAC[
CONJ_ASSOC] THEN CONJ_TAC THENL
[ASM_REWRITE_TAC[] THEN CONJ_TAC THEN
REWRITE_TAC[
term_valuation;
semantics] THEN
MAP_EVERY X_GEN_TAC [`k:string`; `kty:type`] THEN
REWRITE_TAC[
VALMOD] THEN CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
REWRITE_TAC[
TYPESET_LEMMA;
TYPE_SUBST] THEN
SIMP_TAC[
PAIR_EQ] THEN ASM_REWRITE_TAC[] THEN
COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
ASM_MESON_TAC[
term_valuation];
ALL_TAC] THEN
MAP_EVERY X_GEN_TAC [`k:string`; `kty:type`] THEN DISCH_TAC THEN
REWRITE_TAC[
VALMOD;
semantics] THEN
CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
SIMP_TAC[
PAIR_EQ] THEN ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;