# HG changeset patch # User berghofe # Date 1056443877 -7200 # Node ID 35d36f43ba06f09f7c5336b865cd32a9b1d384c2 # Parent e61a310cde02614e783a0b474493b840e1886e58 Moved strong normalization proof to StrongNorm.thy diff -r e61a310cde02 -r 35d36f43ba06 src/HOL/Lambda/StrongNorm.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Lambda/StrongNorm.thy Tue Jun 24 10:37:57 2003 +0200 @@ -0,0 +1,289 @@ +(* Title: HOL/Lambda/StrongNorm.thy + ID: $Id$ + Author: Stefan Berghofer + Copyright 2000 TU Muenchen +*) + +header {* Strong normalization for simply-typed lambda calculus *} + +theory StrongNorm = Type + InductTermi: + +text {* +Formalization by Stefan Berghofer. Partly based on a paper proof by +Felix Joachimski and Ralph Matthes \cite{Matthes-Joachimski-AML}. +*} + + +subsection {* Properties of @{text IT} *} + +lemma lift_IT [intro!]: "t \ IT \ (\i. lift t i \ IT)" + apply (induct set: IT) + apply (simp (no_asm)) + apply (rule conjI) + apply + (rule impI, + rule IT.Var, + erule lists.induct, + simp (no_asm), + rule lists.Nil, + simp (no_asm), + erule IntE, + rule lists.Cons, + blast, + assumption)+ + apply auto + done + +lemma lifts_IT: "ts \ lists IT \ map (\t. lift t 0) ts \ lists IT" + by (induct ts) auto + +lemma subst_Var_IT: "r \ IT \ (\i j. r[Var i/j] \ IT)" + apply (induct set: IT) + txt {* Case @{term Var}: *} + apply (simp (no_asm) add: subst_Var) + apply + ((rule conjI impI)+, + rule IT.Var, + erule lists.induct, + simp (no_asm), + rule lists.Nil, + simp (no_asm), + erule IntE, + erule CollectE, + rule lists.Cons, + fast, + assumption)+ + txt {* Case @{term Lambda}: *} + apply atomize + apply simp + apply (rule IT.Lambda) + apply fast + txt {* Case @{term Beta}: *} + apply atomize + apply (simp (no_asm_use) add: subst_subst [symmetric]) + apply (rule IT.Beta) + apply auto + done + +lemma Var_IT: "Var n \ IT" + apply (subgoal_tac "Var n \\ [] \ IT") + apply simp + apply (rule IT.Var) + apply (rule lists.Nil) + done + +lemma app_Var_IT: "t \ IT \ t \ Var i \ IT" + apply (induct set: IT) + apply (subst app_last) + apply (rule IT.Var) + apply simp + apply (rule lists.Cons) + apply (rule Var_IT) + apply (rule lists.Nil) + apply (rule IT.Beta [where ?ss = "[]", unfolded foldl_Nil [THEN eq_reflection]]) + apply (erule subst_Var_IT) + apply (rule Var_IT) + apply (subst app_last) + apply (rule IT.Beta) + apply (subst app_last [symmetric]) + apply assumption + apply assumption + done + + +subsection {* Well-typed substitution preserves termination *} + +lemma subst_type_IT: + "\t e T u i. t \ IT \ e\i:U\ \ t : T \ + u \ IT \ e \ u : U \ t[u/i] \ IT" + (is "PROP ?P U" is "\t e T u i. _ \ PROP ?Q t e T u i U") +proof (induct U) + fix T t + assume MI1: "\T1 T2. T = T1 \ T2 \ PROP ?P T1" + assume MI2: "\T1 T2. T = T1 \ T2 \ PROP ?P T2" + assume "t \ IT" + thus "\e T' u i. PROP ?Q t e T' u i T" + proof induct + fix e T' u i + assume uIT: "u \ IT" + assume uT: "e \ u : T" + { + case (Var n rs e_ T'_ u_ i_) + assume nT: "e\i:T\ \ Var n \\ rs : T'" + let ?ty = "{t. \T'. e\i:T\ \ t : T'}" + let ?R = "\t. \e T' u i. + e\i:T\ \ t : T' \ u \ IT \ e \ u : T \ t[u/i] \ IT" + show "(Var n \\ rs)[u/i] \ IT" + proof (cases "n = i") + case True + show ?thesis + proof (cases rs) + case Nil + with uIT True show ?thesis by simp + next + case (Cons a as) + with nT have "e\i:T\ \ Var n \ a \\ as : T'" by simp + then obtain Ts + where headT: "e\i:T\ \ Var n \ a : Ts \ T'" + and argsT: "e\i:T\ \ as : Ts" + by (rule list_app_typeE) + from headT obtain T'' + where varT: "e\i:T\ \ Var n : T'' \ Ts \ T'" + and argT: "e\i:T\ \ a : T''" + by cases simp_all + from varT True have T: "T = T'' \ Ts \ T'" + by cases auto + with uT have uT': "e \ u : T'' \ Ts \ T'" by simp + from T have "(Var 0 \\ map (\t. lift t 0) + (map (\t. t[u/i]) as))[(u \ a[u/i])/0] \ IT" + proof (rule MI2) + from T have "(lift u 0 \ Var 0)[a[u/i]/0] \ IT" + proof (rule MI1) + have "lift u 0 \ IT" by (rule lift_IT) + thus "lift u 0 \ Var 0 \ IT" by (rule app_Var_IT) + show "e\0:T''\ \ lift u 0 \ Var 0 : Ts \ T'" + proof (rule typing.App) + show "e\0:T''\ \ lift u 0 : T'' \ Ts \ T'" + by (rule lift_type) (rule uT') + show "e\0:T''\ \ Var 0 : T''" + by (rule typing.Var) simp + qed + from Var have "?R a" by cases (simp_all add: Cons) + with argT uIT uT show "a[u/i] \ IT" by simp + from argT uT show "e \ a[u/i] : T''" + by (rule subst_lemma) simp + qed + thus "u \ a[u/i] \ IT" by simp + from Var have "as \ lists {t. ?R t}" + by cases (simp_all add: Cons) + moreover from argsT have "as \ lists ?ty" + by (rule lists_typings) + ultimately have "as \ lists ({t. ?R t} \ ?ty)" + by (rule lists_IntI) + hence "map (\t. lift t 0) (map (\t. t[u/i]) as) \ lists IT" + (is "(?ls as) \ _") + proof induct + case Nil + show ?case by fastsimp + next + case (Cons b bs) + hence I: "?R b" by simp + from Cons obtain U where "e\i:T\ \ b : U" by fast + with uT uIT I have "b[u/i] \ IT" by simp + hence "lift (b[u/i]) 0 \ IT" by (rule lift_IT) + hence "lift (b[u/i]) 0 # ?ls bs \ lists IT" + by (rule lists.Cons) (rule Cons) + thus ?case by simp + qed + thus "Var 0 \\ ?ls as \ IT" by (rule IT.Var) + have "e\0:Ts \ T'\ \ Var 0 : Ts \ T'" + by (rule typing.Var) simp + moreover from uT argsT have "e \ map (\t. t[u/i]) as : Ts" + by (rule substs_lemma) + hence "e\0:Ts \ T'\ \ ?ls as : Ts" + by (rule lift_types) + ultimately show "e\0:Ts \ T'\ \ Var 0 \\ ?ls as : T'" + by (rule list_app_typeI) + from argT uT have "e \ a[u/i] : T''" + by (rule subst_lemma) (rule refl) + with uT' show "e \ u \ a[u/i] : Ts \ T'" + by (rule typing.App) + qed + with Cons True show ?thesis + by (simp add: map_compose [symmetric] o_def) + qed + next + case False + from Var have "rs \ lists {t. ?R t}" by simp + moreover from nT obtain Ts where "e\i:T\ \ rs : Ts" + by (rule list_app_typeE) + hence "rs \ lists ?ty" by (rule lists_typings) + ultimately have "rs \ lists ({t. ?R t} \ ?ty)" + by (rule lists_IntI) + hence "map (\x. x[u/i]) rs \ lists IT" + proof induct + case Nil + show ?case by fastsimp + next + case (Cons a as) + hence I: "?R a" by simp + from Cons obtain U where "e\i:T\ \ a : U" by fast + with uT uIT I have "a[u/i] \ IT" by simp + hence "(a[u/i] # map (\t. t[u/i]) as) \ lists IT" + by (rule lists.Cons) (rule Cons) + thus ?case by simp + qed + with False show ?thesis by (auto simp add: subst_Var) + qed + next + case (Lambda r e_ T'_ u_ i_) + assume "e\i:T\ \ Abs r : T'" + and "\e T' u i. PROP ?Q r e T' u i T" + with uIT uT show "Abs r[u/i] \ IT" + by fastsimp + next + case (Beta r a as e_ T'_ u_ i_) + assume T: "e\i:T\ \ Abs r \ a \\ as : T'" + assume SI1: "\e T' u i. PROP ?Q (r[a/0] \\ as) e T' u i T" + assume SI2: "\e T' u i. PROP ?Q a e T' u i T" + have "Abs (r[lift u 0/Suc i]) \ a[u/i] \\ map (\t. t[u/i]) as \ IT" + proof (rule IT.Beta) + have "Abs r \ a \\ as \\<^sub>\ r[a/0] \\ as" + by (rule apps_preserves_beta) (rule beta.beta) + with T have "e\i:T\ \ r[a/0] \\ as : T'" + by (rule subject_reduction) + hence "(r[a/0] \\ as)[u/i] \ IT" + by (rule SI1) + thus "r[lift u 0/Suc i][a[u/i]/0] \\ map (\t. t[u/i]) as \ IT" + by (simp del: subst_map add: subst_subst subst_map [symmetric]) + from T obtain U where "e\i:T\ \ Abs r \ a : U" + by (rule list_app_typeE) fast + then obtain T'' where "e\i:T\ \ a : T''" by cases simp_all + thus "a[u/i] \ IT" by (rule SI2) + qed + thus "(Abs r \ a \\ as)[u/i] \ IT" by simp + } + qed +qed + + +subsection {* Well-typed terms are strongly normalizing *} + +lemma type_implies_IT: "e \ t : T \ t \ IT" +proof - + assume "e \ t : T" + thus ?thesis + proof induct + case Var + show ?case by (rule Var_IT) + next + case Abs + show ?case by (rule IT.Lambda) + next + case (App T U e s t) + have "(Var 0 \ lift t 0)[s/0] \ IT" + proof (rule subst_type_IT) + have "lift t 0 \ IT" by (rule lift_IT) + hence "[lift t 0] \ lists IT" by (rule lists.Cons) (rule lists.Nil) + hence "Var 0 \\ [lift t 0] \ IT" by (rule IT.Var) + also have "Var 0 \\ [lift t 0] = Var 0 \ lift t 0" by simp + finally show "\ \ IT" . + have "e\0:T \ U\ \ Var 0 : T \ U" + by (rule typing.Var) simp + moreover have "e\0:T \ U\ \ lift t 0 : T" + by (rule lift_type) + ultimately show "e\0:T \ U\ \ Var 0 \ lift t 0 : U" + by (rule typing.App) + qed + thus ?case by simp + qed +qed + +theorem type_implies_termi: "e \ t : T \ t \ termi beta" +proof - + assume "e \ t : T" + hence "t \ IT" by (rule type_implies_IT) + thus ?thesis by (rule IT_implies_termi) +qed + +end diff -r e61a310cde02 -r 35d36f43ba06 src/HOL/Lambda/Type.thy --- a/src/HOL/Lambda/Type.thy Tue Jun 24 10:37:12 2003 +0200 +++ b/src/HOL/Lambda/Type.thy Tue Jun 24 10:37:57 2003 +0200 @@ -4,15 +4,9 @@ Copyright 2000 TU Muenchen *) -header {* Simply-typed lambda terms: subject reduction and strong - normalization *} - -theory Type = InductTermi: +header {* Simply-typed lambda terms *} -text_raw {* - \footnote{Formalization by Stefan Berghofer. Partly based on a - paper proof by Ralph Matthes.} -*} +theory Type = ListApplication: subsection {* Environments *} @@ -95,6 +89,68 @@ by force +subsection {* Lists of types *} + +lemma lists_typings: + "\Ts. e \ ts : Ts \ ts \ lists {t. \T. e \ t : T}" + apply (induct ts) + apply (case_tac Ts) + apply simp + apply (rule lists.Nil) + apply simp + apply (case_tac Ts) + apply simp + apply simp + apply (rule lists.Cons) + apply blast + apply blast + done + +lemma types_snoc: "\Ts. e \ ts : Ts \ e \ t : T \ e \ ts @ [t] : Ts @ [T]" + apply (induct ts) + apply simp + apply (case_tac Ts) + apply simp+ + done + +lemma types_snoc_eq: "\Ts. e \ ts @ [t] : Ts @ [T] = + (e \ ts : Ts \ e \ t : T)" + apply (induct ts) + apply (case_tac Ts) + apply simp+ + apply (case_tac Ts) + apply (case_tac "list @ [t]") + apply simp+ + done + +lemma rev_exhaust2 [case_names Nil snoc, extraction_expand]: + "(xs = [] \ P) \ (\ys y. xs = ys @ [y] \ P) \ P" + -- {* Cannot use @{text rev_exhaust} from the @{text List} + theory, since it is not constructive *} + apply (subgoal_tac "\ys. xs = rev ys \ P") + apply (erule_tac x="rev xs" in allE) + apply simp + apply (rule allI) + apply (rule impI) + apply (case_tac ys) + apply simp + apply simp + apply atomize + apply (erule allE)+ + apply (erule mp, rule conjI) + apply (rule refl)+ + done + +lemma types_snocE: "e \ ts @ [t] : Ts \ + (\Us U. Ts = Us @ [U] \ e \ ts : Us \ e \ t : U \ P) \ P" + apply (cases Ts rule: rev_exhaust2) + apply simp + apply (case_tac "ts @ [t]") + apply (simp add: types_snoc_eq)+ + apply rules + done + + subsection {* n-ary function types *} lemma list_app_typeD: @@ -135,58 +191,105 @@ apply blast done -lemma lists_typings: - "\Ts. e \ ts : Ts \ ts \ lists {t. \T. e \ t : T}" - apply (induct ts) - apply (case_tac Ts) - apply simp - apply (rule lists.Nil) - apply simp - apply (case_tac Ts) - apply simp +text {* +For the specific case where the head of the term is a variable, +the following theorems allow to infer the types of the arguments +without analyzing the typing derivation. This is crucial +for program extraction. +*} + +theorem var_app_type_eq: + "\T U. e \ Var i \\ ts : T \ e \ Var i \\ ts : U \ T = U" + apply (induct ts rule: rev_induct) + apply simp + apply (ind_cases "e \ Var i : T") + apply (ind_cases "e \ Var i : T") + apply simp + apply simp + apply (ind_cases "e \ t \ u : T") + apply (ind_cases "e \ t \ u : T") + apply atomize + apply (erule_tac x="Ta \ T" in allE) + apply (erule_tac x="Tb \ U" in allE) + apply (erule impE) + apply assumption + apply (erule impE) + apply assumption + apply simp + done + +lemma var_app_types: "\ts Ts U. e \ Var i \\ ts \\ us : T \ e \ ts : Ts \ + e \ Var i \\ ts : U \ \Us. U = Us \ T \ e \ us : Us" + apply (induct us) + apply simp + apply (erule var_app_type_eq) + apply assumption + apply simp + apply atomize + apply (case_tac U) + apply (rule FalseE) + apply simp + apply (erule list_app_typeE) + apply (ind_cases "e \ t \ u : T") + apply (drule_tac T="Atom nat" and U="Ta \ Tsa \ T" in var_app_type_eq) + apply assumption apply simp - apply (rule lists.Cons) - apply blast - apply blast + apply (erule_tac x="ts @ [a]" in allE) + apply (erule_tac x="Ts @ [type1]" in allE) + apply (erule_tac x="type2" in allE) + apply simp + apply (erule impE) + apply (rule types_snoc) + apply assumption + apply (erule list_app_typeE) + apply (ind_cases "e \ t \ u : T") + apply (drule_tac T="type1 \ type2" and U="Ta \ Tsa \ T" in var_app_type_eq) + apply assumption + apply simp + apply (erule impE) + apply (rule typing.App) + apply assumption + apply (erule list_app_typeE) + apply (ind_cases "e \ t \ u : T") + apply (frule_tac T="type1 \ type2" and U="Ta \ Tsa \ T" in var_app_type_eq) + apply assumption + apply simp + apply (erule exE) + apply (rule_tac x="type1 # Us" in exI) + apply simp + apply (erule list_app_typeE) + apply (ind_cases "e \ t \ u : T") + apply (frule_tac T="type1 \ Us \ T" and U="Ta \ Tsa \ T" in var_app_type_eq) + apply assumption + apply simp + done + +lemma var_app_typesE: "e \ Var i \\ ts : T \ + (\Ts. e \ Var i : Ts \ T \ e \ ts : Ts \ P) \ P" + apply (drule var_app_types [of _ _ "[]", simplified]) + apply (rules intro: typing.Var)+ + done + +lemma abs_typeE: "e \ Abs t : T \ (\U V. e\0:U\ \ t : V \ P) \ P" + apply (cases T) + apply (rule FalseE) + apply (erule typing.elims) + apply simp_all + apply atomize + apply (erule_tac x="type1" in allE) + apply (erule_tac x="type2" in allE) + apply (erule mp) + apply (erule typing.elims) + apply simp_all done -subsection {* Lifting preserves termination and well-typedness *} - -lemma lift_map [simp]: - "\t. lift (t \\ ts) i = lift t i \\ map (\t. lift t i) ts" - by (induct ts) simp_all - -lemma subst_map [simp]: - "\t. subst (t \\ ts) u i = subst t u i \\ map (\t. subst t u i) ts" - by (induct ts) simp_all - -lemma lift_IT [intro!]: "t \ IT \ (\i. lift t i \ IT)" - apply (induct set: IT) - apply (simp (no_asm)) - apply (rule conjI) - apply - (rule impI, - rule IT.Var, - erule lists.induct, - simp (no_asm), - rule lists.Nil, - simp (no_asm), - erule IntE, - rule lists.Cons, - blast, - assumption)+ - apply auto - done - -lemma lifts_IT: "ts \ lists IT \ map (\t. lift t 0) ts \ lists IT" - by (induct ts) auto +subsection {* Lifting preserves well-typedness *} lemma lift_type [intro!]: "e \ t : T \ (\i U. e\i:U\ \ lift t i : T)" by (induct set: typing) auto - -lemma lift_typings: +lemma lift_types: "\Ts. e \ ts : Ts \ e\i:U\ \ (map (\t. lift t i) ts) : Ts" apply (induct ts) apply simp @@ -240,64 +343,11 @@ apply auto done - -subsection {* Additional lemmas *} - -lemma app_last: "(t \\ ts) \ u = t \\ (ts @ [u])" - by simp +theorem subject_reduction': "t \\<^sub>\\<^sup>* t' \ e \ t : T \ e \ t' : T" + by (induct set: rtrancl) (rules intro: subject_reduction)+ -lemma subst_Var_IT: "r \ IT \ (\i j. r[Var i/j] \ IT)" - apply (induct set: IT) - txt {* Case @{term Var}: *} - apply (simp (no_asm) add: subst_Var) - apply - ((rule conjI impI)+, - rule IT.Var, - erule lists.induct, - simp (no_asm), - rule lists.Nil, - simp (no_asm), - erule IntE, - erule CollectE, - rule lists.Cons, - fast, - assumption)+ - txt {* Case @{term Lambda}: *} - apply atomize - apply simp - apply (rule IT.Lambda) - apply fast - txt {* Case @{term Beta}: *} - apply atomize - apply (simp (no_asm_use) add: subst_subst [symmetric]) - apply (rule IT.Beta) - apply auto - done -lemma Var_IT: "Var n \ IT" - apply (subgoal_tac "Var n \\ [] \ IT") - apply simp - apply (rule IT.Var) - apply (rule lists.Nil) - done - -lemma app_Var_IT: "t \ IT \ t \ Var i \ IT" - apply (induct set: IT) - apply (subst app_last) - apply (rule IT.Var) - apply simp - apply (rule lists.Cons) - apply (rule Var_IT) - apply (rule lists.Nil) - apply (rule IT.Beta [where ?ss = "[]", unfolded foldl_Nil [THEN eq_reflection]]) - apply (erule subst_Var_IT) - apply (rule Var_IT) - apply (subst app_last) - apply (rule IT.Beta) - apply (subst app_last [symmetric]) - apply assumption - apply assumption - done +subsection {* Alternative induction rule for types *} lemma type_induct [induct type]: "(\T. (\T1 T2. T = T1 \ T2 \ P T1) \ @@ -314,200 +364,4 @@ qed qed - -subsection {* Well-typed substitution preserves termination *} - -lemma subst_type_IT: - "\t e T u i. t \ IT \ e\i:U\ \ t : T \ - u \ IT \ e \ u : U \ t[u/i] \ IT" - (is "PROP ?P U" is "\t e T u i. _ \ PROP ?Q t e T u i U") -proof (induct U) - fix T t - assume MI1: "\T1 T2. T = T1 \ T2 \ PROP ?P T1" - assume MI2: "\T1 T2. T = T1 \ T2 \ PROP ?P T2" - assume "t \ IT" - thus "\e T' u i. PROP ?Q t e T' u i T" - proof induct - fix e T' u i - assume uIT: "u \ IT" - assume uT: "e \ u : T" - { - case (Var n rs e_ T'_ u_ i_) - assume nT: "e\i:T\ \ Var n \\ rs : T'" - let ?ty = "{t. \T'. e\i:T\ \ t : T'}" - let ?R = "\t. \e T' u i. - e\i:T\ \ t : T' \ u \ IT \ e \ u : T \ t[u/i] \ IT" - show "(Var n \\ rs)[u/i] \ IT" - proof (cases "n = i") - case True - show ?thesis - proof (cases rs) - case Nil - with uIT True show ?thesis by simp - next - case (Cons a as) - with nT have "e\i:T\ \ Var n \ a \\ as : T'" by simp - then obtain Ts - where headT: "e\i:T\ \ Var n \ a : Ts \ T'" - and argsT: "e\i:T\ \ as : Ts" - by (rule list_app_typeE) - from headT obtain T'' - where varT: "e\i:T\ \ Var n : T'' \ Ts \ T'" - and argT: "e\i:T\ \ a : T''" - by cases simp_all - from varT True have T: "T = T'' \ Ts \ T'" - by cases auto - with uT have uT': "e \ u : T'' \ Ts \ T'" by simp - from T have "(Var 0 \\ map (\t. lift t 0) - (map (\t. t[u/i]) as))[(u \ a[u/i])/0] \ IT" - proof (rule MI2) - from T have "(lift u 0 \ Var 0)[a[u/i]/0] \ IT" - proof (rule MI1) - have "lift u 0 \ IT" by (rule lift_IT) - thus "lift u 0 \ Var 0 \ IT" by (rule app_Var_IT) - show "e\0:T''\ \ lift u 0 \ Var 0 : Ts \ T'" - proof (rule typing.App) - show "e\0:T''\ \ lift u 0 : T'' \ Ts \ T'" - by (rule lift_type) (rule uT') - show "e\0:T''\ \ Var 0 : T''" - by (rule typing.Var) simp - qed - from Var have "?R a" by cases (simp_all add: Cons) - with argT uIT uT show "a[u/i] \ IT" by simp - from argT uT show "e \ a[u/i] : T''" - by (rule subst_lemma) simp - qed - thus "u \ a[u/i] \ IT" by simp - from Var have "as \ lists {t. ?R t}" - by cases (simp_all add: Cons) - moreover from argsT have "as \ lists ?ty" - by (rule lists_typings) - ultimately have "as \ lists ({t. ?R t} \ ?ty)" - by (rule lists_IntI) - hence "map (\t. lift t 0) (map (\t. t[u/i]) as) \ lists IT" - (is "(?ls as) \ _") - proof induct - case Nil - show ?case by fastsimp - next - case (Cons b bs) - hence I: "?R b" by simp - from Cons obtain U where "e\i:T\ \ b : U" by fast - with uT uIT I have "b[u/i] \ IT" by simp - hence "lift (b[u/i]) 0 \ IT" by (rule lift_IT) - hence "lift (b[u/i]) 0 # ?ls bs \ lists IT" - by (rule lists.Cons) (rule Cons) - thus ?case by simp - qed - thus "Var 0 \\ ?ls as \ IT" by (rule IT.Var) - have "e\0:Ts \ T'\ \ Var 0 : Ts \ T'" - by (rule typing.Var) simp - moreover from uT argsT have "e \ map (\t. t[u/i]) as : Ts" - by (rule substs_lemma) - hence "e\0:Ts \ T'\ \ ?ls as : Ts" - by (rule lift_typings) - ultimately show "e\0:Ts \ T'\ \ Var 0 \\ ?ls as : T'" - by (rule list_app_typeI) - from argT uT have "e \ a[u/i] : T''" - by (rule subst_lemma) (rule refl) - with uT' show "e \ u \ a[u/i] : Ts \ T'" - by (rule typing.App) - qed - with Cons True show ?thesis - by (simp add: map_compose [symmetric] o_def) - qed - next - case False - from Var have "rs \ lists {t. ?R t}" by simp - moreover from nT obtain Ts where "e\i:T\ \ rs : Ts" - by (rule list_app_typeE) - hence "rs \ lists ?ty" by (rule lists_typings) - ultimately have "rs \ lists ({t. ?R t} \ ?ty)" - by (rule lists_IntI) - hence "map (\x. x[u/i]) rs \ lists IT" - proof induct - case Nil - show ?case by fastsimp - next - case (Cons a as) - hence I: "?R a" by simp - from Cons obtain U where "e\i:T\ \ a : U" by fast - with uT uIT I have "a[u/i] \ IT" by simp - hence "(a[u/i] # map (\t. t[u/i]) as) \ lists IT" - by (rule lists.Cons) (rule Cons) - thus ?case by simp - qed - with False show ?thesis by (auto simp add: subst_Var) - qed - next - case (Lambda r e_ T'_ u_ i_) - assume "e\i:T\ \ Abs r : T'" - and "\e T' u i. PROP ?Q r e T' u i T" - with uIT uT show "Abs r[u/i] \ IT" - by fastsimp - next - case (Beta r a as e_ T'_ u_ i_) - assume T: "e\i:T\ \ Abs r \ a \\ as : T'" - assume SI1: "\e T' u i. PROP ?Q (r[a/0] \\ as) e T' u i T" - assume SI2: "\e T' u i. PROP ?Q a e T' u i T" - have "Abs (r[lift u 0/Suc i]) \ a[u/i] \\ map (\t. t[u/i]) as \ IT" - proof (rule IT.Beta) - have "Abs r \ a \\ as -> r[a/0] \\ as" - by (rule apps_preserves_beta) (rule beta.beta) - with T have "e\i:T\ \ r[a/0] \\ as : T'" - by (rule subject_reduction) - hence "(r[a/0] \\ as)[u/i] \ IT" - by (rule SI1) - thus "r[lift u 0/Suc i][a[u/i]/0] \\ map (\t. t[u/i]) as \ IT" - by (simp del: subst_map add: subst_subst subst_map [symmetric]) - from T obtain U where "e\i:T\ \ Abs r \ a : U" - by (rule list_app_typeE) fast - then obtain T'' where "e\i:T\ \ a : T''" by cases simp_all - thus "a[u/i] \ IT" by (rule SI2) - qed - thus "(Abs r \ a \\ as)[u/i] \ IT" by simp - } - qed -qed - - -subsection {* Well-typed terms are strongly normalizing *} - -lemma type_implies_IT: "e \ t : T \ t \ IT" -proof - - assume "e \ t : T" - thus ?thesis - proof induct - case Var - show ?case by (rule Var_IT) - next - case Abs - show ?case by (rule IT.Lambda) - next - case (App T U e s t) - have "(Var 0 \ lift t 0)[s/0] \ IT" - proof (rule subst_type_IT) - have "lift t 0 \ IT" by (rule lift_IT) - hence "[lift t 0] \ lists IT" by (rule lists.Cons) (rule lists.Nil) - hence "Var 0 \\ [lift t 0] \ IT" by (rule IT.Var) - also have "Var 0 \\ [lift t 0] = Var 0 \ lift t 0" by simp - finally show "\ \ IT" . - have "e\0:T \ U\ \ Var 0 : T \ U" - by (rule typing.Var) simp - moreover have "e\0:T \ U\ \ lift t 0 : T" - by (rule lift_type) - ultimately show "e\0:T \ U\ \ Var 0 \ lift t 0 : U" - by (rule typing.App) - qed - thus ?case by simp - qed -qed - -theorem type_implies_termi: "e \ t : T \ t \ termi beta" -proof - - assume "e \ t : T" - hence "t \ IT" by (rule type_implies_IT) - thus ?thesis by (rule IT_implies_termi) -qed - end