src/HOL/Lambda/Type.thy
changeset 11935 cbcba2092d6b
parent 11704 3c50a2cd6f00
child 11943 a9672446b45f
equal deleted inserted replaced
11934:6c1bf72430b6 11935:cbcba2092d6b
    25   typing :: "((nat => type) \<times> dB \<times> type) set"
    25   typing :: "((nat => type) \<times> dB \<times> type) set"
    26 
    26 
    27 syntax
    27 syntax
    28   "_typing" :: "[nat => type, dB, type] => bool"  ("_ |- _ : _" [50,50,50] 50)
    28   "_typing" :: "[nat => type, dB, type] => bool"  ("_ |- _ : _" [50,50,50] 50)
    29   "_funs" :: "[type list, type] => type"  (infixl "=>>" 150)
    29   "_funs" :: "[type list, type] => type"  (infixl "=>>" 150)
       
    30 
    30 translations
    31 translations
    31   "env |- t : T" == "(env, t, T) \<in> typing"
    32   "env |- t : T" == "(env, t, T) \<in> typing"
    32   "Ts =>> T" == "foldr Fun Ts T"
    33   "Ts =>> T" == "foldr Fun Ts T"
    33 
    34 
    34 inductive typing
    35 inductive typing
    35   intros
    36   intros
    36     Var [intro!]: "env x = T ==> env |- Var x : T"
    37     Var [intro!]: "env x = T ==> env |- Var x : T"
    37     Abs [intro!]: "(nat_case T env) |- t : U ==> env |- Abs t : (T => U)"
    38     Abs [intro!]: "(nat_case T env) |- t : U ==> env |- Abs t : (T => U)"
    38     App [intro!]: "env |- s : T => U ==> env |- t : T ==> env |- (s $ t) : U"
    39     App [intro!]: "env |- s : T => U ==> env |- t : T ==> env |- (s $ t) : U"
       
    40 
       
    41 constdefs
       
    42   shift :: "(nat \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a \<Rightarrow> nat \<Rightarrow> 'a" ("_<_:_>" [50,0,0] 51)
       
    43   "e<i:a> == \<lambda>j. if j < i then e j else if j = i then a else e (j - 1)"
    39 
    44 
    40 inductive_cases [elim!]:
    45 inductive_cases [elim!]:
    41   "e |- Var i : T"
    46   "e |- Var i : T"
    42   "e |- t $ u : T"
    47   "e |- t $ u : T"
    43   "e |- Abs t : T"
    48   "e |- Abs t : T"
    58 
    63 
    59 
    64 
    60 subsection {* Some examples *}
    65 subsection {* Some examples *}
    61 
    66 
    62 lemma "e |- Abs (Abs (Abs (Var 1 $ (Var 2 $ Var 1 $ Var 0)))) : ?T"
    67 lemma "e |- Abs (Abs (Abs (Var 1 $ (Var 2 $ Var 1 $ Var 0)))) : ?T"
    63   apply force
    68   by force
    64   done
       
    65 
    69 
    66 lemma "e |- Abs (Abs (Abs (Var 2 $ Var 0 $ (Var 1 $ Var 0)))) : ?T"
    70 lemma "e |- Abs (Abs (Abs (Var 2 $ Var 0 $ (Var 1 $ Var 0)))) : ?T"
    67   apply force
    71   by force
    68   done
    72 
    69 
    73 
    70 
    74 subsection {* @{text n}-ary function types *}
    71 text {* Iterated function types *}
       
    72 
    75 
    73 lemma list_app_typeD [rule_format]:
    76 lemma list_app_typeD [rule_format]:
    74     "\<forall>t T. e |- t $$ ts : T --> (\<exists>Ts. e |- t : Ts =>> T \<and> types e ts Ts)"
    77     "\<forall>t T. e |- t $$ ts : T --> (\<exists>Ts. e |- t : Ts =>> T \<and> types e ts Ts)"
    75   apply (induct_tac ts)
    78   apply (induct_tac ts)
    76    apply simp
    79    apply simp
    84   apply (ind_cases "e |- t $ u : T")
    87   apply (ind_cases "e |- t $ u : T")
    85   apply (rule_tac x = "Ta # Ts" in exI)
    88   apply (rule_tac x = "Ta # Ts" in exI)
    86   apply simp
    89   apply simp
    87   done
    90   done
    88 
    91 
       
    92 lemma list_app_typeE:
       
    93   "e |- t $$ ts : T \<Longrightarrow> (\<And>Ts. e |- t : Ts =>> T \<Longrightarrow> types e ts Ts \<Longrightarrow> C) \<Longrightarrow> C"
       
    94   by (insert list_app_typeD) fast
       
    95 
    89 lemma list_app_typeI [rule_format]:
    96 lemma list_app_typeI [rule_format]:
    90     "\<forall>t T Ts. e |- t : Ts =>> T --> types e ts Ts --> e |- t $$ ts : T"
    97     "\<forall>t T Ts. e |- t : Ts =>> T --> types e ts Ts --> e |- t $$ ts : T"
    91   apply (induct_tac ts)
    98   apply (induct_tac ts)
    92    apply (intro strip)
    99    apply (intro strip)
    93    apply simp
   100    apply simp
   123   done
   130   done
   124 
   131 
   125 
   132 
   126 subsection {* Lifting preserves termination and well-typedness *}
   133 subsection {* Lifting preserves termination and well-typedness *}
   127 
   134 
   128 lemma lift_map [rule_format, simp]:
   135 lemma lift_map [simp]:
   129     "\<forall>t. lift (t $$ ts) i = lift t i $$ map (\<lambda>t. lift t i) ts"
   136     "\<And>t. lift (t $$ ts) i = lift t i $$ map (\<lambda>t. lift t i) ts"
   130   apply (induct_tac ts)
   137   by (induct ts) simp_all
   131    apply simp_all
   138 
   132   done
   139 lemma subst_map [simp]:
   133 
   140     "\<And>t. subst (t $$ ts) u i = subst t u i $$ map (\<lambda>t. subst t u i) ts"
   134 lemma subst_map [rule_format, simp]:
   141   by (induct ts) simp_all
   135   "\<forall>t. subst (t $$ ts) u i = subst t u i $$ map (\<lambda>t. subst t u i) ts"
       
   136   apply (induct_tac ts)
       
   137    apply simp_all
       
   138   done
       
   139 
   142 
   140 lemma lift_IT [rule_format, intro!]:
   143 lemma lift_IT [rule_format, intro!]:
   141     "t \<in> IT ==> \<forall>i. lift t i \<in> IT"
   144     "t \<in> IT ==> \<forall>i. lift t i \<in> IT"
   142   apply (erule IT.induct)
   145   apply (erule IT.induct)
   143     apply (rule allI)
   146     apply (rule allI)
   155        blast,
   158        blast,
   156        assumption)+
   159        assumption)+
   157      apply auto
   160      apply auto
   158    done
   161    done
   159 
   162 
   160 lemma lifts_IT [rule_format]:
   163 lemma lifts_IT:
   161     "ts \<in> lists IT --> map (\<lambda>t. lift t 0) ts \<in> lists IT"
   164     "ts \<in> lists IT \<Longrightarrow> map (\<lambda>t. lift t 0) ts \<in> lists IT"
   162   apply (induct_tac ts)
   165   by (induct ts) auto
   163    apply auto
       
   164   done
       
   165 
       
   166 
   166 
   167 lemma shift_env [simp]:
   167 lemma shift_env [simp]:
   168   "nat_case T
   168   "nat_case T
   169     (\<lambda>j. if j < i then e j else if j = i then Ua else e (j - 1)) =
   169     (\<lambda>j. if j < i then e j else if j = i then Ua else e (j - 1)) =
   170     (\<lambda>j. if j < Suc i then nat_case T e j else if j = Suc i then Ua
   170     (\<lambda>j. if j < Suc i then nat_case T e j else if j = Suc i then Ua
   174    apply simp
   174    apply simp
   175   apply (case_tac nat)
   175   apply (case_tac nat)
   176    apply simp_all
   176    apply simp_all
   177   done
   177   done
   178 
   178 
   179 lemma lift_type' [rule_format]:
   179 lemma lift_type':
   180   "e |- t : T ==> \<forall>i U.
   180   "e |- t : T ==> e<i:U> |- lift t i : T"
   181     (\<lambda>j. if j < i then e j
   181 proof -
   182           else if j = i then U
   182   assume "e |- t : T"
   183           else e (j - 1)) |- lift t i : T"
   183   thus "\<And>i U. e<i:U> |- lift t i : T"
   184   apply (erule typing.induct)
   184     by induct (auto simp add: shift_def)
   185     apply auto
   185 qed
   186   done
       
   187 
   186 
   188 lemma lift_type [intro!]:
   187 lemma lift_type [intro!]:
   189     "e |- t : T ==> nat_case U e |- lift t 0 : T"
   188     "e |- t : T ==> nat_case U e |- lift t 0 : T"
   190   apply (subgoal_tac
   189   apply (subgoal_tac "nat_case U e = e<0:U>")
   191     "nat_case U e =
       
   192       (\<lambda>j. if j < 0 then e j
       
   193             else if j = 0 then U else e (j - 1))")
       
   194    apply (erule ssubst)
   190    apply (erule ssubst)
   195    apply (erule lift_type')
   191    apply (erule lift_type')
   196   apply (rule ext)
   192   apply (rule ext)
   197   apply (case_tac j)
   193   apply (case_tac x)
   198    apply simp_all
   194    apply (simp_all add: shift_def)
   199   done
   195   done
   200 
   196 
   201 lemma lift_types [rule_format]:
   197 lemma lift_types [rule_format]:
   202   "\<forall>Ts. types e ts Ts -->
   198   "\<forall>Ts. types e ts Ts --> types (e<i:U>) (map (\<lambda>t. lift t i) ts) Ts"
   203     types (\<lambda>j. if j < i then e j
       
   204                 else if j = i then U
       
   205                 else e (j - 1)) (map (\<lambda>t. lift t i) ts) Ts"
       
   206   apply (induct_tac ts)
   199   apply (induct_tac ts)
   207    apply simp
   200    apply simp
   208   apply (intro strip)
   201   apply (intro strip)
   209   apply (case_tac Ts)
   202   apply (case_tac Ts)
   210    apply simp_all
   203    apply simp_all
   214 
   207 
   215 
   208 
   216 subsection {* Substitution lemmas *}
   209 subsection {* Substitution lemmas *}
   217 
   210 
   218 lemma subst_lemma [rule_format]:
   211 lemma subst_lemma [rule_format]:
   219   "e |- t : T ==> \<forall>e' i U u.
   212   "e |- t : T ==> \<forall>e' i U u. e' |- u : U -->
   220     e = (\<lambda>j. if j < i then e' j
   213     e = e'<i:U> --> e' |- t[u/i] : T"
   221               else if j = i then U
   214   apply (unfold shift_def)
   222               else e' (j - 1)) -->
       
   223     e' |- u : U --> e' |- t[u/i] : T"
       
   224   apply (erule typing.induct)
   215   apply (erule typing.induct)
   225     apply (intro strip)
   216     apply (intro strip)
   226     apply (case_tac "x = i")
   217     apply (case_tac "x = i")
   227      apply simp
   218      apply simp
   228     apply (frule linorder_neq_iff [THEN iffD1])
   219     apply (frule linorder_neq_iff [THEN iffD1])
   233     apply (frule order_less_not_sym)
   224     apply (frule order_less_not_sym)
   234     apply (simp only: subst_gt split: split_if add: if_False)
   225     apply (simp only: subst_gt split: split_if add: if_False)
   235     apply (rule typing.Var)
   226     apply (rule typing.Var)
   236     apply assumption
   227     apply assumption
   237    apply fastsimp
   228    apply fastsimp
   238   apply fastsimp
   229   apply auto
   239   done
   230   done
   240 
   231 
   241 lemma substs_lemma [rule_format]:
   232 lemma substs_lemma [rule_format]:
   242   "e |- u : T ==>
   233   "e |- u : T ==> \<forall>Ts. types (e<i:T>) ts Ts -->
   243     \<forall>Ts. types (\<lambda>j. if j < i then e j
   234      types e (map (\<lambda>t. t[u/i]) ts) Ts"
   244                      else if j = i then T else e (j - 1)) ts Ts -->
       
   245       types e (map (\<lambda>t. t[u/i]) ts) Ts"
       
   246   apply (induct_tac ts)
   235   apply (induct_tac ts)
   247    apply (intro strip)
   236    apply (intro strip)
   248    apply (case_tac Ts)
   237    apply (case_tac Ts)
   249     apply simp
   238     apply simp
   250    apply simp
   239    apply simp
   252   apply (case_tac Ts)
   241   apply (case_tac Ts)
   253    apply simp
   242    apply simp
   254   apply simp
   243   apply simp
   255   apply (erule conjE)
   244   apply (erule conjE)
   256   apply (erule subst_lemma)
   245   apply (erule subst_lemma)
   257    apply (rule refl)
   246    apply assumption
   258   apply assumption
   247   apply (rule refl)
   259   done
   248   done
   260 
   249 
   261 
   250 
   262 subsection {* Subject reduction *}
   251 subsection {* Subject reduction *}
   263 
   252 
   270   apply (ind_cases "s $ t -> t'")
   259   apply (ind_cases "s $ t -> t'")
   271     apply hypsubst
   260     apply hypsubst
   272     apply (ind_cases "env |- Abs t : T => U")
   261     apply (ind_cases "env |- Abs t : T => U")
   273     apply (rule subst_lemma)
   262     apply (rule subst_lemma)
   274       apply assumption
   263       apply assumption
   275      prefer 2
       
   276      apply assumption
   264      apply assumption
   277     apply (rule ext)
   265     apply (rule ext)
   278     apply (case_tac j)
   266     apply (case_tac x)
   279      apply auto
   267      apply (auto simp add: shift_def)
   280   done
   268   done
   281 
   269 
   282 
   270 
   283 subsection {* Additional lemmas *}
   271 subsection {* Additional lemmas *}
   284 
   272 
   285 lemma app_last: "(t $$ ts) $ u = t $$ (ts @ [u])"
   273 lemma app_last: "(t $$ ts) $ u = t $$ (ts @ [u])"
   286   apply simp
   274   by simp
   287   done
       
   288 
   275 
   289 lemma subst_Var_IT [rule_format]: "r \<in> IT ==> \<forall>i j. r[Var i/j] \<in> IT"
   276 lemma subst_Var_IT [rule_format]: "r \<in> IT ==> \<forall>i j. r[Var i/j] \<in> IT"
   290   apply (erule IT.induct)
   277   apply (erule IT.induct)
   291     txt {* Case @{term Var}: *}
   278     txt {* Case @{term Var}: *}
   292     apply (intro strip)
   279     apply (intro strip)
   338    apply (subst app_last [symmetric])
   325    apply (subst app_last [symmetric])
   339    apply assumption
   326    apply assumption
   340   apply assumption
   327   apply assumption
   341   done
   328   done
   342 
   329 
       
   330 lemma type_induct [induct type]:
       
   331   "(\<And>T. (\<And>T1 T2. T = T1 => T2 \<Longrightarrow> P T1) \<Longrightarrow>
       
   332    (\<And>T1 T2. T = T1 => T2 \<Longrightarrow> P T2) \<Longrightarrow> P T) \<Longrightarrow> P T"
       
   333 proof -
       
   334   case rule_context
       
   335   show ?thesis
       
   336   proof (induct T)
       
   337     case Atom
       
   338     show ?case by (rule rule_context) simp_all
       
   339   next
       
   340     case Fun
       
   341     show ?case  by (rule rule_context) (insert Fun, simp_all)
       
   342   qed
       
   343 qed
       
   344 
   343 
   345 
   344 subsection {* Well-typed substitution preserves termination *}
   346 subsection {* Well-typed substitution preserves termination *}
   345 
   347 
   346 lemma subst_type_IT [rule_format]:
   348 lemma subst_type_IT:
   347   "\<forall>t. t \<in> IT --> (\<forall>e T u i.
   349   "\<And>t e T u i. t \<in> IT \<Longrightarrow> e<i:U> |- t : T \<Longrightarrow>
   348     (\<lambda>j. if j < i then e j
   350     u \<in> IT \<Longrightarrow> e |- u : U \<Longrightarrow> t[u/i] \<in> IT"
   349           else if j = i then U
   351   (is "PROP ?P U" is "\<And>t e T u i. _ \<Longrightarrow> PROP ?Q t e T u i U")
   350           else e (j - 1)) |- t : T -->
   352 proof (induct U)
   351     u \<in> IT --> e |- u : U --> t[u/i] \<in> IT)"
   353   fix T t
   352   apply (rule_tac f = size and a = U in measure_induct)
   354   assume MI1: "\<And>T1 T2. T = T1 => T2 \<Longrightarrow> PROP ?P T1"
   353   apply (rule allI)
   355   assume MI2: "\<And>T1 T2. T = T1 => T2 \<Longrightarrow> PROP ?P T2"
   354   apply (rule impI)
   356   assume "t \<in> IT"
   355   apply (erule IT.induct)
   357   thus "\<And>e T' u i. PROP ?Q t e T' u i T"
   356     txt {* Case @{term Var}: *}
   358   proof induct
   357     apply (intro strip)
   359     fix e T' u i
   358     apply (case_tac "n = i")
   360     assume uIT: "u : IT"
   359      txt {* Case @{term "n = i"}: *}
   361     assume uT: "e |- u : T"
   360      apply (case_tac rs)
   362     {
   361       apply simp
   363       case (Var n rs)
   362      apply simp
   364       assume nT: "e<i:T> |- Var n $$ rs : T'"
   363      apply (drule list_app_typeD)
   365       let ?ty = "{t. \<exists>T'. e<i:T> |- t : T'}"
   364      apply (elim exE conjE)
   366       let ?R = "\<lambda>t. \<forall>e T' u i.
   365      apply (ind_cases "e |- t $ u : T")
   367 	e<i:T> |- t : T' \<longrightarrow> u \<in> IT \<longrightarrow> e |- u : T \<longrightarrow> t[u/i] \<in> IT"
   366      apply (ind_cases "e |- Var i : T")
   368       show "(Var n $$ rs)[u/i] \<in> IT"
   367      apply (drule_tac s = "(?T::type) => ?U" in sym)
   369       proof (cases "n = i")
   368      apply simp
   370 	case True
   369      apply (subgoal_tac "lift u 0 $ Var 0 \<in> IT")
   371 	show ?thesis
   370       prefer 2
   372 	proof (cases rs)
   371       apply (rule app_Var_IT)
   373 	  case Nil
   372       apply (erule lift_IT)
   374 	  with uIT True show ?thesis by simp
   373      apply (subgoal_tac "(lift u 0 $ Var 0)[a[u/i]/0] \<in> IT")
   375 	next
   374       apply (simp (no_asm_use))
   376 	  case (Cons a as)
   375       apply (subgoal_tac "(Var 0 $$ map (\<lambda>t. lift t 0)
   377 	  with nT have "e<i:T> |- Var n $ a $$ as : T'" by simp
   376         (map (\<lambda>t. t[u/i]) list))[(u $ a[u/i])/0] \<in> IT")
   378 	  then obtain Ts
   377        apply (simp (no_asm_use) del: map_compose
   379 	    where headT: "e<i:T> |- Var n $ a : Ts =>> T'"
   378 	 add: map_compose [symmetric] o_def)
   380 	    and argsT: "types (e<i:T>) as Ts"
   379       apply (erule_tac x = "Ts =>> T" in allE)
   381 	    by (rule list_app_typeE)
   380       apply (erule impE)
   382 	  from headT obtain T''
   381        apply simp
   383 	    where varT: "e<i:T> |- Var n : T'' => (Ts =>> T')"
   382       apply (erule_tac x = "Var 0 $$
   384 	    and argT: "e<i:T> |- a : T''"
   383         map (\<lambda>t. lift t 0) (map (\<lambda>t. t[u/i]) list)" in allE)
   385 	    by cases simp_all
   384       apply (erule impE)
   386 	  from varT True have T: "T = T'' => (Ts =>> T')"
   385        apply (rule IT.Var)
   387 	    by cases (auto simp add: shift_def)
   386        apply (rule lifts_IT)
   388 	  with uT have uT': "e |- u : T'' => (Ts =>> T')" by simp
   387        apply (drule lists_types)
   389 	  from Var have SI: "?R a" by cases (simp_all add: Cons)
   388        apply
   390 	  from T have "(Var 0 $$ map (\<lambda>t. lift t 0)
   389         (ind_cases "x # xs \<in> lists (Collect P)",
   391             (map (\<lambda>t. t[u/i]) as))[(u $ a[u/i])/0] \<in> IT"
   390          erule lists_IntI [THEN lists.induct],
   392 	  proof (rule MI2)
   391          assumption)
   393 	    from T have "(lift u 0 $ Var 0)[a[u/i]/0] \<in> IT"
   392         apply fastsimp
   394 	    proof (rule MI1)
   393        apply fastsimp
   395 	      have "lift u 0 : IT" by (rule lift_IT)
   394       apply (erule_tac x = e in allE)
   396 	      thus "lift u 0 $ Var 0 \<in> IT" by (rule app_Var_IT)
   395       apply (erule_tac x = T in allE)
   397 	      show "e<0:T''> |- lift u 0 $ Var 0 : Ts =>> T'"
   396       apply (erule_tac x = "u $ a[u/i]" in allE)
   398 	      proof (rule typing.App)
   397       apply (erule_tac x = 0 in allE)
   399 		show "e<0:T''> |- lift u 0 : T'' => (Ts =>> T')"
   398       apply (fastsimp intro!: list_app_typeI lift_types subst_lemma substs_lemma)
   400 		  by (rule lift_type') (rule uT')
   399      apply (erule_tac x = Ta in allE)
   401 		show "e<0:T''> |- Var 0 : T''"
   400      apply (erule impE)
   402 		  by (rule typing.Var) (simp add: shift_def)
   401       apply simp
   403 	      qed
   402      apply (erule_tac x = "lift u 0 $ Var 0" in allE)
   404 	      from argT uIT uT show "a[u/i] : IT"
   403      apply (erule impE)
   405 		by (rule SI[rule_format])
   404       apply assumption
   406 	      from argT uT show "e |- a[u/i] : T''"
   405      apply (erule_tac x = e in allE)
   407 		by (rule subst_lemma) (simp add: shift_def)
   406      apply (erule_tac x = "Ts =>> T" in allE)
   408 	    qed
   407      apply (erule_tac x = "a[u/i]" in allE)
   409 	    thus "u $ a[u/i] \<in> IT" by simp
   408      apply (erule_tac x = 0 in allE)
   410 	    from Var have "as : lists {t. ?R t}"
   409      apply (erule impE)
   411 	      by cases (simp_all add: Cons)
   410       apply (rule typing.App)
   412 	    moreover from argsT have "as : lists ?ty"
   411        apply (erule lift_type')
   413 	      by (rule lists_types)
   412       apply (rule typing.Var)
   414 	    ultimately have "as : lists ({t. ?R t} \<inter> ?ty)"
   413       apply simp
   415 	      by (rule lists_IntI)
   414      apply (fast intro!: subst_lemma)
   416 	    hence "map (\<lambda>t. lift t 0) (map (\<lambda>t. t[u/i]) as) \<in> lists IT"
   415     txt {* Case @{term "n ~= i"}: *}
   417 	      (is "(?ls as) \<in> _")
   416     apply (drule list_app_typeD)
   418 	    proof induct
   417     apply (erule exE)
   419 	      case Nil
   418     apply (erule conjE)
   420 	      show ?case by fastsimp
   419     apply (drule lists_types)
   421 	    next
   420     apply (subgoal_tac "map (\<lambda>x. x[u/i]) rs \<in> lists IT")
   422 	      case (Cons b bs)
   421      apply (simp add: subst_Var)
   423 	      hence I: "?R b" by simp
   422      apply fast
   424 	      from Cons obtain U where "e<i:T> |- b : U" by fast
   423     apply (erule lists_IntI [THEN lists.induct])
   425 	      with uT uIT I have "b[u/i] : IT" by simp
   424       apply assumption
   426 	      hence "lift (b[u/i]) 0 : IT" by (rule lift_IT)
   425      apply fastsimp
   427 	      hence "lift (b[u/i]) 0 # ?ls bs \<in> lists IT"
   426     apply fastsimp
   428 		by (rule lists.Cons) (rule Cons)
   427    txt {* Case @{term Lambda}: *}
   429 	      thus ?case by simp
   428    apply fastsimp
   430 	    qed
   429   txt {* Case @{term Beta}: *}
   431 	    thus "Var 0 $$ ?ls as \<in> IT" by (rule IT.Var)
   430   apply (intro strip)
   432 	    have "e<0:Ts =>> T'> |- Var 0 : Ts =>> T'"
   431   apply (simp (no_asm))
   433 	      by (rule typing.Var) (simp add: shift_def)
   432   apply (rule IT.Beta)
   434 	    moreover from uT argsT have "types e (map (\<lambda>t. t[u/i]) as) Ts"
   433    apply (simp (no_asm) del: subst_map add: subst_subst subst_map [symmetric])
   435 	      by (rule substs_lemma)
   434    apply (drule subject_reduction)
   436 	    hence "types (e<0:Ts =>> T'>) (?ls as) Ts"
   435     apply (rule apps_preserves_beta)
   437 	      by (rule lift_types)
   436     apply (rule beta.beta)
   438 	    ultimately show "e<0:Ts =>> T'> |- Var 0 $$ ?ls as : T'"
   437    apply fast
   439 	      by (rule list_app_typeI)
   438   apply (drule list_app_typeD)
   440 	    from argT uT have "e |- a[u/i] : T''"
   439   apply fast
   441 	      by (rule subst_lemma) (rule refl)
   440   done
   442 	    with uT' show "e |- u $ a[u/i] : Ts =>> T'"
   441 
   443 	      by (rule typing.App)
   442 
   444 	  qed
   443 subsection {* Main theorem: well-typed terms are strongly normalizing *}
   445 	  with Cons True show ?thesis
       
   446 	    by (simp add: map_compose [symmetric] o_def)
       
   447 	qed
       
   448       next
       
   449 	case False
       
   450 	from Var have "rs : lists {t. ?R t}" by simp
       
   451 	moreover from nT obtain Ts where "types (e<i:T>) rs Ts"
       
   452 	  by (rule list_app_typeE)
       
   453 	hence "rs : lists ?ty" by (rule lists_types)
       
   454 	ultimately have "rs : lists ({t. ?R t} \<inter> ?ty)"
       
   455 	  by (rule lists_IntI)
       
   456 	hence "map (\<lambda>x. x[u/i]) rs \<in> lists IT"
       
   457 	proof induct
       
   458 	  case Nil
       
   459 	  show ?case by fastsimp
       
   460 	next
       
   461 	  case (Cons a as)
       
   462 	  hence I: "?R a" by simp
       
   463 	  from Cons obtain U where "e<i:T> |- a : U" by fast
       
   464 	  with uT uIT I have "a[u/i] : IT" by simp
       
   465 	  hence "a[u/i] # map (\<lambda>t. t[u/i]) as \<in> lists IT"
       
   466 	    by (rule lists.Cons) (rule Cons)
       
   467 	  thus ?case by simp
       
   468 	qed
       
   469 	with False show ?thesis by (auto simp add: subst_Var)
       
   470       qed
       
   471     next
       
   472       case (Lambda r)
       
   473       assume "e<i:T> |- Abs r : T'"
       
   474 	and "\<And>e T' u i. PROP ?Q r e T' u i T"
       
   475       with uIT uT show "Abs r[u/i] \<in> IT"
       
   476 	by (fastsimp simp add: shift_def)
       
   477     next
       
   478       case (Beta r a as)
       
   479       assume T: "e<i:T> |- Abs r $ a $$ as : T'"
       
   480       assume SI1: "\<And>e T' u i. PROP ?Q (r[a/0] $$ as) e T' u i T"
       
   481       assume SI2: "\<And>e T' u i. PROP ?Q a e T' u i T"
       
   482       have "Abs (r[lift u 0/Suc i]) $ a[u/i] $$ map (\<lambda>t. t[u/i]) as \<in> IT"
       
   483       proof (rule IT.Beta)
       
   484 	have "Abs r $ a $$ as -> r[a/0] $$ as"
       
   485 	  by (rule apps_preserves_beta) (rule beta.beta)
       
   486 	with T have "e<i:T> |- r[a/0] $$ as : T'"
       
   487 	  by (rule subject_reduction)
       
   488 	hence "(r[a/0] $$ as)[u/i] \<in> IT"
       
   489 	  by (rule SI1)
       
   490 	thus "r[lift u 0/Suc i][a[u/i]/0] $$ map (\<lambda>t. t[u/i]) as \<in> IT"
       
   491 	  by (simp del: subst_map add: subst_subst subst_map [symmetric])
       
   492 	from T obtain U where "e<i:T> |- Abs r $ a : U"
       
   493 	  by (rule list_app_typeE) fast
       
   494 	then obtain T'' where "e<i:T> |- a : T''" by cases simp_all
       
   495 	thus "a[u/i] \<in> IT" by (rule SI2)
       
   496       qed
       
   497       thus "(Abs r $ a $$ as)[u/i] \<in> IT" by simp
       
   498     }
       
   499   qed
       
   500 qed
       
   501 
       
   502 subsection {* Well-typed terms are strongly normalizing *}
   444 
   503 
   445 lemma type_implies_IT: "e |- t : T ==> t \<in> IT"
   504 lemma type_implies_IT: "e |- t : T ==> t \<in> IT"
   446   apply (erule typing.induct)
   505 proof -
   447     apply (rule Var_IT)
   506   assume "e |- t : T"
   448    apply (erule IT.Lambda)
   507   thus ?thesis
   449   apply (subgoal_tac "(Var 0 $ lift t 0)[s/0] \<in> IT")
   508   proof induct
   450    apply simp
   509     case Var
   451   apply (rule subst_type_IT)
   510     show ?case by (rule Var_IT)
   452   apply (rule lists.Nil
   511   next
   453     [THEN [2] lists.Cons [THEN IT.Var], unfolded foldl_Nil [THEN eq_reflection]
   512     case Abs
   454       foldl_Cons [THEN eq_reflection]])
   513     show ?case by (rule IT.Lambda)
   455       apply (erule lift_IT)
   514   next
   456      apply (rule typing.App)
   515     case (App T U e s t)
   457      apply (rule typing.Var)
   516     have "(Var 0 $ lift t 0)[s/0] \<in> IT"
   458      apply simp
   517     proof (rule subst_type_IT)
   459     apply (erule lift_type')
   518       have "lift t 0 : IT" by (rule lift_IT)
   460    apply assumption
   519       hence "[lift t 0] : lists IT" by (rule lists.Cons) (rule lists.Nil)
   461   apply assumption
   520       hence "Var 0 $$ [lift t 0] : IT" by (rule IT.Var)
   462   done
   521       also have "(Var 0 $$ [lift t 0]) = (Var 0 $ lift t 0)" by simp
       
   522       finally show "\<dots> : IT" .
       
   523       have "e<0:T => U> |- Var 0 : T => U"
       
   524 	by (rule typing.Var) (simp add: shift_def)
       
   525       moreover have "e<0:T => U> |- lift t 0 : T"
       
   526 	by (rule lift_type')
       
   527       ultimately show "e<0:T => U> |- Var 0 $ lift t 0 : U"
       
   528 	by (rule typing.App)
       
   529     qed
       
   530     thus ?case by simp
       
   531   qed
       
   532 qed
   463 
   533 
   464 theorem type_implies_termi: "e |- t : T ==> t \<in> termi beta"
   534 theorem type_implies_termi: "e |- t : T ==> t \<in> termi beta"
   465   apply (rule IT_implies_termi)
   535 proof -
   466   apply (erule type_implies_IT)
   536   assume "e |- t : T"
   467   done
   537   hence "t \<in> IT" by (rule type_implies_IT)
       
   538   thus ?thesis by (rule IT_implies_termi)
       
   539 qed
   468 
   540 
   469 end
   541 end