src/HOL/Nominal/Examples/Standardization.thy
changeset 63167 0909deb8059b
parent 62390 842917225d56
child 63882 018998c00003
equal deleted inserted replaced
63166:143f58bb34f9 63167:0909deb8059b
     1 (*  Title:      HOL/Nominal/Examples/Standardization.thy
     1 (*  Title:      HOL/Nominal/Examples/Standardization.thy
     2     Author:     Stefan Berghofer and Tobias Nipkow
     2     Author:     Stefan Berghofer and Tobias Nipkow
     3     Copyright   2005, 2008 TU Muenchen
     3     Copyright   2005, 2008 TU Muenchen
     4 *)
     4 *)
     5 
     5 
     6 section {* Standardization *}
     6 section \<open>Standardization\<close>
     7 
     7 
     8 theory Standardization
     8 theory Standardization
     9 imports "../Nominal"
     9 imports "../Nominal"
    10 begin
    10 begin
    11 
    11 
    12 text {*
    12 text \<open>
    13 The proof of the standardization theorem, as well as most of the theorems about
    13 The proof of the standardization theorem, as well as most of the theorems about
    14 lambda calculus in the following sections, are taken from @{text "HOL/Lambda"}.
    14 lambda calculus in the following sections, are taken from \<open>HOL/Lambda\<close>.
    15 *}
    15 \<close>
    16 
    16 
    17 subsection {* Lambda terms *}
    17 subsection \<open>Lambda terms\<close>
    18 
    18 
    19 atom_decl name
    19 atom_decl name
    20 
    20 
    21 nominal_datatype lam =
    21 nominal_datatype lam =
    22   Var "name"
    22   Var "name"
   116 abbreviation
   116 abbreviation
   117   beta_reds :: "lam \<Rightarrow> lam \<Rightarrow> bool"  (infixl "\<rightarrow>\<^sub>\<beta>\<^sup>*" 50) where
   117   beta_reds :: "lam \<Rightarrow> lam \<Rightarrow> bool"  (infixl "\<rightarrow>\<^sub>\<beta>\<^sup>*" 50) where
   118   "s \<rightarrow>\<^sub>\<beta>\<^sup>* t \<equiv> beta\<^sup>*\<^sup>* s t"
   118   "s \<rightarrow>\<^sub>\<beta>\<^sup>* t \<equiv> beta\<^sup>*\<^sup>* s t"
   119 
   119 
   120 
   120 
   121 subsection {* Application of a term to a list of terms *}
   121 subsection \<open>Application of a term to a list of terms\<close>
   122 
   122 
   123 abbreviation
   123 abbreviation
   124   list_application :: "lam \<Rightarrow> lam list \<Rightarrow> lam"  (infixl "\<degree>\<degree>" 150) where
   124   list_application :: "lam \<Rightarrow> lam list \<Rightarrow> lam"  (infixl "\<degree>\<degree>" 150) where
   125   "t \<degree>\<degree> ts \<equiv> foldl (op \<degree>) t ts"
   125   "t \<degree>\<degree> ts \<equiv> foldl (op \<degree>) t ts"
   126 
   126 
   194 
   194 
   195 lemma fresh_apps [simp]: "(x::name) \<sharp> (t \<degree>\<degree> ts) = (x \<sharp> t \<and> x \<sharp> ts)"
   195 lemma fresh_apps [simp]: "(x::name) \<sharp> (t \<degree>\<degree> ts) = (x \<sharp> t \<and> x \<sharp> ts)"
   196   by (induct ts rule: rev_induct)
   196   by (induct ts rule: rev_induct)
   197     (auto simp add: fresh_list_append fresh_list_nil fresh_list_cons)
   197     (auto simp add: fresh_list_append fresh_list_nil fresh_list_cons)
   198 
   198 
   199 text {* A customized induction schema for @{text "\<degree>\<degree>"}. *}
   199 text \<open>A customized induction schema for \<open>\<degree>\<degree>\<close>.\<close>
   200 
   200 
   201 lemma lem:
   201 lemma lem:
   202   assumes "\<And>n ts (z::'a::fs_name). (\<And>z. \<forall>t \<in> set ts. P z t) \<Longrightarrow> P z (Var n \<degree>\<degree> ts)"
   202   assumes "\<And>n ts (z::'a::fs_name). (\<And>z. \<forall>t \<in> set ts. P z t) \<Longrightarrow> P z (Var n \<degree>\<degree> ts)"
   203     and "\<And>x u ts z. x \<sharp> z \<Longrightarrow> (\<And>z. P z u) \<Longrightarrow> (\<And>z. \<forall>t \<in> set ts. P z t) \<Longrightarrow> P z ((Lam [x].u) \<degree>\<degree> ts)"
   203     and "\<And>x u ts z. x \<sharp> z \<Longrightarrow> (\<And>z. P z u) \<Longrightarrow> (\<And>z. \<forall>t \<in> set ts. P z t) \<Longrightarrow> P z ((Lam [x].u) \<degree>\<degree> ts)"
   204   shows "size t = n \<Longrightarrow> P z t"
   204   shows "size t = n \<Longrightarrow> P z t"
   248     apply (rule refl)
   248     apply (rule refl)
   249     using assms apply blast+
   249     using assms apply blast+
   250   done
   250   done
   251 
   251 
   252 
   252 
   253 subsection {* Congruence rules *}
   253 subsection \<open>Congruence rules\<close>
   254 
   254 
   255 lemma apps_preserves_beta [simp]:
   255 lemma apps_preserves_beta [simp]:
   256     "r \<rightarrow>\<^sub>\<beta> s \<Longrightarrow> r \<degree>\<degree> ss \<rightarrow>\<^sub>\<beta> s \<degree>\<degree> ss"
   256     "r \<rightarrow>\<^sub>\<beta> s \<Longrightarrow> r \<degree>\<degree> ss \<rightarrow>\<^sub>\<beta> s \<degree>\<degree> ss"
   257   by (induct ss rule: rev_induct) auto
   257   by (induct ss rule: rev_induct) auto
   258 
   258 
   271 lemma rtrancl_beta_App [intro]:
   271 lemma rtrancl_beta_App [intro]:
   272     "s \<rightarrow>\<^sub>\<beta>\<^sup>* s' \<Longrightarrow> t \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<Longrightarrow> s \<degree> t \<rightarrow>\<^sub>\<beta>\<^sup>* s' \<degree> t'"
   272     "s \<rightarrow>\<^sub>\<beta>\<^sup>* s' \<Longrightarrow> t \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<Longrightarrow> s \<degree> t \<rightarrow>\<^sub>\<beta>\<^sup>* s' \<degree> t'"
   273   by (blast intro!: rtrancl_beta_AppL rtrancl_beta_AppR intro: rtranclp_trans)
   273   by (blast intro!: rtrancl_beta_AppL rtrancl_beta_AppR intro: rtranclp_trans)
   274 
   274 
   275 
   275 
   276 subsection {* Lifting an order to lists of elements *}
   276 subsection \<open>Lifting an order to lists of elements\<close>
   277 
   277 
   278 definition
   278 definition
   279   step1 :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool" where
   279   step1 :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool" where
   280   "step1 r =
   280   "step1 r =
   281     (\<lambda>ys xs. \<exists>us z z' vs. xs = us @ z # vs \<and> r z' z \<and> ys =
   281     (\<lambda>ys xs. \<exists>us z z' vs. xs = us @ z # vs \<and> r z' z \<and> ys =
   337   apply simp
   337   apply simp
   338   apply blast
   338   apply blast
   339   done
   339   done
   340 
   340 
   341 
   341 
   342 subsection {* Lifting beta-reduction to lists *}
   342 subsection \<open>Lifting beta-reduction to lists\<close>
   343 
   343 
   344 abbreviation
   344 abbreviation
   345   list_beta :: "lam list \<Rightarrow> lam list \<Rightarrow> bool"  (infixl "[\<rightarrow>\<^sub>\<beta>]\<^sub>1" 50) where
   345   list_beta :: "lam list \<Rightarrow> lam list \<Rightarrow> bool"  (infixl "[\<rightarrow>\<^sub>\<beta>]\<^sub>1" 50) where
   346   "rs [\<rightarrow>\<^sub>\<beta>]\<^sub>1 ss \<equiv> step1 beta rs ss"
   346   "rs [\<rightarrow>\<^sub>\<beta>]\<^sub>1 ss \<equiv> step1 beta rs ss"
   347 
   347 
   415   apply (drule Snoc_step1_SnocD)
   415   apply (drule Snoc_step1_SnocD)
   416   apply blast
   416   apply blast
   417   done
   417   done
   418 
   418 
   419 
   419 
   420 subsection {* Standard reduction relation *}
   420 subsection \<open>Standard reduction relation\<close>
   421 
   421 
   422 text {*
   422 text \<open>
   423 Based on lecture notes by Ralph Matthes,
   423 Based on lecture notes by Ralph Matthes,
   424 original proof idea due to Ralph Loader.
   424 original proof idea due to Ralph Loader.
   425 *}
   425 \<close>
   426 
   426 
   427 declare listrel_mono [mono_set]
   427 declare listrel_mono [mono_set]
   428 
   428 
   429 lemma listrelp_eqvt [eqvt]:
   429 lemma listrelp_eqvt [eqvt]:
   430   fixes f :: "'a::pt_name \<Rightarrow> 'b::pt_name \<Rightarrow> bool"
   430   fixes f :: "'a::pt_name \<Rightarrow> 'b::pt_name \<Rightarrow> bool"
   512 next
   512 next
   513   case (Abs x ss ss' r r')
   513   case (Abs x ss ss' r r')
   514   from Abs(4) have "ss [\<rightarrow>\<^sub>s] ss'" by (rule listrelp_conj1)
   514   from Abs(4) have "ss [\<rightarrow>\<^sub>s] ss'" by (rule listrelp_conj1)
   515   moreover have "[s] [\<rightarrow>\<^sub>s] [s']" by (iprover intro: s listrelp.intros)
   515   moreover have "[s] [\<rightarrow>\<^sub>s] [s']" by (iprover intro: s listrelp.intros)
   516   ultimately have "ss @ [s] [\<rightarrow>\<^sub>s] ss' @ [s']" by (rule listrelp_app)
   516   ultimately have "ss @ [s] [\<rightarrow>\<^sub>s] ss' @ [s']" by (rule listrelp_app)
   517   with `r \<rightarrow>\<^sub>s r'` have "(Lam [x].r) \<degree>\<degree> (ss @ [s]) \<rightarrow>\<^sub>s (Lam [x].r') \<degree>\<degree> (ss' @ [s'])"
   517   with \<open>r \<rightarrow>\<^sub>s r'\<close> have "(Lam [x].r) \<degree>\<degree> (ss @ [s]) \<rightarrow>\<^sub>s (Lam [x].r') \<degree>\<degree> (ss' @ [s'])"
   518     by (rule better_sred_Abs)
   518     by (rule better_sred_Abs)
   519   thus ?case by (simp only: app_last)
   519   thus ?case by (simp only: app_last)
   520 next
   520 next
   521   case (Beta x u ss t r)
   521   case (Beta x u ss t r)
   522   hence "r[x::=u] \<degree>\<degree> (ss @ [s]) \<rightarrow>\<^sub>s t \<degree> s'" by (simp only: app_last)
   522   hence "r[x::=u] \<degree>\<degree> (ss @ [s]) \<rightarrow>\<^sub>s t \<degree> s'" by (simp only: app_last)
   551     by (cases "y = x") (auto simp add: Var intro: refl_sred)
   551     by (cases "y = x") (auto simp add: Var intro: refl_sred)
   552   ultimately show ?case by simp (rule lemma1')
   552   ultimately show ?case by simp (rule lemma1')
   553 next
   553 next
   554   case (Abs y ss ss' r r')
   554   case (Abs y ss ss' r r')
   555   then have "r[x::=s] \<rightarrow>\<^sub>s r'[x::=s']" by fast
   555   then have "r[x::=s] \<rightarrow>\<^sub>s r'[x::=s']" by fast
   556   moreover from Abs(8) `s \<rightarrow>\<^sub>s s'` have "map (\<lambda>t. t[x::=s]) ss [\<rightarrow>\<^sub>s] map (\<lambda>t. t[x::=s']) ss'"
   556   moreover from Abs(8) \<open>s \<rightarrow>\<^sub>s s'\<close> have "map (\<lambda>t. t[x::=s]) ss [\<rightarrow>\<^sub>s] map (\<lambda>t. t[x::=s']) ss'"
   557     by induct (auto intro: listrelp.intros Abs)
   557     by induct (auto intro: listrelp.intros Abs)
   558   ultimately show ?case using Abs(6) `y \<sharp> x` `y \<sharp> s` `y \<sharp> s'`
   558   ultimately show ?case using Abs(6) \<open>y \<sharp> x\<close> \<open>y \<sharp> s\<close> \<open>y \<sharp> s'\<close>
   559     by simp (rule better_sred_Abs)
   559     by simp (rule better_sred_Abs)
   560 next
   560 next
   561   case (Beta y u ss t r)
   561   case (Beta y u ss t r)
   562   thus ?case by (auto simp add: subst_subst fresh_atm intro: better_sred_Beta)
   562   thus ?case by (auto simp add: subst_subst fresh_atm intro: better_sred_Beta)
   563 qed
   563 qed
   605   from Var(1) [simplified] rs have "rs [\<rightarrow>\<^sub>s] ss" by (rule lemma4_aux)
   605   from Var(1) [simplified] rs have "rs [\<rightarrow>\<^sub>s] ss" by (rule lemma4_aux)
   606   hence "Var x \<degree>\<degree> rs \<rightarrow>\<^sub>s Var x \<degree>\<degree> ss" by (rule sred.Var)
   606   hence "Var x \<degree>\<degree> rs \<rightarrow>\<^sub>s Var x \<degree>\<degree> ss" by (rule sred.Var)
   607   with r'' show ?case by simp
   607   with r'' show ?case by simp
   608 next
   608 next
   609   case (Abs x ss ss' r r')
   609   case (Abs x ss ss' r r')
   610   from `(Lam [x].r') \<degree>\<degree> ss' \<rightarrow>\<^sub>\<beta> r''` show ?case
   610   from \<open>(Lam [x].r') \<degree>\<degree> ss' \<rightarrow>\<^sub>\<beta> r''\<close> show ?case
   611   proof (cases rule: apps_betasE [where x=x])
   611   proof (cases rule: apps_betasE [where x=x])
   612     case (appL s)
   612     case (appL s)
   613     then obtain r''' where s: "s = (Lam [x].r''')" and r''': "r' \<rightarrow>\<^sub>\<beta> r'''" using `x \<sharp> r''`
   613     then obtain r''' where s: "s = (Lam [x].r''')" and r''': "r' \<rightarrow>\<^sub>\<beta> r'''" using \<open>x \<sharp> r''\<close>
   614       by (cases rule: beta.strong_cases) (auto simp add: abs_fresh lam.inject alpha)
   614       by (cases rule: beta.strong_cases) (auto simp add: abs_fresh lam.inject alpha)
   615     from r''' have "r \<rightarrow>\<^sub>s r'''" by (blast intro: Abs)
   615     from r''' have "r \<rightarrow>\<^sub>s r'''" by (blast intro: Abs)
   616     moreover from Abs have "ss [\<rightarrow>\<^sub>s] ss'" by (iprover dest: listrelp_conj1)
   616     moreover from Abs have "ss [\<rightarrow>\<^sub>s] ss'" by (iprover dest: listrelp_conj1)
   617     ultimately have "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s (Lam [x].r''') \<degree>\<degree> ss'" by (rule better_sred_Abs)
   617     ultimately have "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s (Lam [x].r''') \<degree>\<degree> ss'" by (rule better_sred_Abs)
   618     with appL s show "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s r''" by simp
   618     with appL s show "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s r''" by simp
   619   next
   619   next
   620     case (appR rs')
   620     case (appR rs')
   621     from Abs(6) [simplified] `ss' [\<rightarrow>\<^sub>\<beta>]\<^sub>1 rs'`
   621     from Abs(6) [simplified] \<open>ss' [\<rightarrow>\<^sub>\<beta>]\<^sub>1 rs'\<close>
   622     have "ss [\<rightarrow>\<^sub>s] rs'" by (rule lemma4_aux)
   622     have "ss [\<rightarrow>\<^sub>s] rs'" by (rule lemma4_aux)
   623     with `r \<rightarrow>\<^sub>s r'` have "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s (Lam [x].r') \<degree>\<degree> rs'" by (rule better_sred_Abs)
   623     with \<open>r \<rightarrow>\<^sub>s r'\<close> have "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s (Lam [x].r') \<degree>\<degree> rs'" by (rule better_sred_Abs)
   624     with appR show "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s r''" by simp
   624     with appR show "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s r''" by simp
   625   next
   625   next
   626     case (beta t u' us')
   626     case (beta t u' us')
   627     then have Lam_eq: "(Lam [x].r') = (Lam [x].t)" and ss': "ss' = u' # us'"
   627     then have Lam_eq: "(Lam [x].r') = (Lam [x].t)" and ss': "ss' = u' # us'"
   628       and r'': "r'' = t[x::=u'] \<degree>\<degree> us'"
   628       and r'': "r'' = t[x::=u'] \<degree>\<degree> us'"
   629       by (simp_all add: abs_fresh)
   629       by (simp_all add: abs_fresh)
   630     from Abs(6) ss' obtain u us where
   630     from Abs(6) ss' obtain u us where
   631       ss: "ss = u # us" and u: "u \<rightarrow>\<^sub>s u'" and us: "us [\<rightarrow>\<^sub>s] us'"
   631       ss: "ss = u # us" and u: "u \<rightarrow>\<^sub>s u'" and us: "us [\<rightarrow>\<^sub>s] us'"
   632       by cases (auto dest!: listrelp_conj1)
   632       by cases (auto dest!: listrelp_conj1)
   633     have "r[x::=u] \<rightarrow>\<^sub>s r'[x::=u']" using `r \<rightarrow>\<^sub>s r'` and u by (rule lemma3)
   633     have "r[x::=u] \<rightarrow>\<^sub>s r'[x::=u']" using \<open>r \<rightarrow>\<^sub>s r'\<close> and u by (rule lemma3)
   634     with us have "r[x::=u] \<degree>\<degree> us \<rightarrow>\<^sub>s r'[x::=u'] \<degree>\<degree> us'" by (rule lemma1')
   634     with us have "r[x::=u] \<degree>\<degree> us \<rightarrow>\<^sub>s r'[x::=u'] \<degree>\<degree> us'" by (rule lemma1')
   635     hence "(Lam [x].r) \<degree> u \<degree>\<degree> us \<rightarrow>\<^sub>s r'[x::=u'] \<degree>\<degree> us'" by (rule better_sred_Beta)
   635     hence "(Lam [x].r) \<degree> u \<degree>\<degree> us \<rightarrow>\<^sub>s r'[x::=u'] \<degree>\<degree> us'" by (rule better_sred_Beta)
   636     with ss r'' Lam_eq show "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s r''" by (simp add: lam.inject alpha)
   636     with ss r'' Lam_eq show "(Lam [x].r) \<degree>\<degree> ss \<rightarrow>\<^sub>s r''" by (simp add: lam.inject alpha)
   637   qed
   637   qed
   638 next
   638 next
   645   assumes r: "r \<rightarrow>\<^sub>\<beta>\<^sup>* r'"
   645   assumes r: "r \<rightarrow>\<^sub>\<beta>\<^sup>* r'"
   646   shows "r \<rightarrow>\<^sub>s r'" using r
   646   shows "r \<rightarrow>\<^sub>s r'" using r
   647   by induct (iprover intro: refl_sred lemma4)+
   647   by induct (iprover intro: refl_sred lemma4)+
   648 
   648 
   649 
   649 
   650 subsection {* Terms in normal form *}
   650 subsection \<open>Terms in normal form\<close>
   651 
   651 
   652 lemma listsp_eqvt [eqvt]:
   652 lemma listsp_eqvt [eqvt]:
   653   assumes xs: "listsp p (xs::'a::pt_name list)"
   653   assumes xs: "listsp p (xs::'a::pt_name list)"
   654   shows "listsp ((pi::name prm) \<bullet> p) (pi \<bullet> xs)" using xs
   654   shows "listsp ((pi::name prm) \<bullet> p) (pi \<bullet> xs)" using xs
   655   apply induct
   655   apply induct
   679 next
   679 next
   680   case (Abs u)
   680   case (Abs u)
   681   thus ?thesis by simp
   681   thus ?thesis by simp
   682 qed
   682 qed
   683 
   683 
   684 text {*
   684 text \<open>
   685 @{term NF} characterizes exactly the terms that are in normal form.
   685 @{term NF} characterizes exactly the terms that are in normal form.
   686 *}
   686 \<close>
   687   
   687   
   688 lemma NF_eq: "NF t = (\<forall>t'. \<not> t \<rightarrow>\<^sub>\<beta> t')"
   688 lemma NF_eq: "NF t = (\<forall>t'. \<not> t \<rightarrow>\<^sub>\<beta> t')"
   689 proof
   689 proof
   690   assume H: "NF t"
   690   assume H: "NF t"
   691   show "\<forall>t'. \<not> t \<rightarrow>\<^sub>\<beta> t'"
   691   show "\<forall>t'. \<not> t \<rightarrow>\<^sub>\<beta> t'"
   738     qed
   738     qed
   739   qed
   739   qed
   740 qed
   740 qed
   741 
   741 
   742 
   742 
   743 subsection {* Leftmost reduction and weakly normalizing terms *}
   743 subsection \<open>Leftmost reduction and weakly normalizing terms\<close>
   744 
   744 
   745 inductive
   745 inductive
   746   lred :: "lam \<Rightarrow> lam \<Rightarrow> bool"  (infixl "\<rightarrow>\<^sub>l" 50)
   746   lred :: "lam \<Rightarrow> lam \<Rightarrow> bool"  (infixl "\<rightarrow>\<^sub>l" 50)
   747   and lredlist :: "lam list \<Rightarrow> lam list \<Rightarrow> bool"  (infixl "[\<rightarrow>\<^sub>l]" 50)
   747   and lredlist :: "lam list \<Rightarrow> lam list \<Rightarrow> bool"  (infixl "[\<rightarrow>\<^sub>l]" 50)
   748 where
   748 where
   759   then have "rs [\<rightarrow>\<^sub>s] rs'"
   759   then have "rs [\<rightarrow>\<^sub>s] rs'"
   760     by induct (iprover intro: listrelp.intros)+
   760     by induct (iprover intro: listrelp.intros)+
   761   then show ?case by (rule sred.Var)
   761   then show ?case by (rule sred.Var)
   762 next
   762 next
   763   case (Abs r r' x)
   763   case (Abs r r' x)
   764   from `r \<rightarrow>\<^sub>s r'`
   764   from \<open>r \<rightarrow>\<^sub>s r'\<close>
   765   have "(Lam [x].r) \<degree>\<degree> [] \<rightarrow>\<^sub>s (Lam [x].r') \<degree>\<degree> []" using listrelp.Nil
   765   have "(Lam [x].r) \<degree>\<degree> [] \<rightarrow>\<^sub>s (Lam [x].r') \<degree>\<degree> []" using listrelp.Nil
   766     by (rule better_sred_Abs)
   766     by (rule better_sred_Abs)
   767   then show ?case by simp
   767   then show ?case by simp
   768 next
   768 next
   769   case (Beta r x s ss t)
   769   case (Beta r x s ss t)
   770   from `r[x::=s] \<degree>\<degree> ss \<rightarrow>\<^sub>s t`
   770   from \<open>r[x::=s] \<degree>\<degree> ss \<rightarrow>\<^sub>s t\<close>
   771   show ?case by (rule better_sred_Beta)
   771   show ?case by (rule better_sred_Beta)
   772 qed
   772 qed
   773 
   773 
   774 inductive WN :: "lam \<Rightarrow> bool"
   774 inductive WN :: "lam \<Rightarrow> bool"
   775   where
   775   where
   808 lemma lemma7:
   808 lemma lemma7:
   809   assumes r: "r \<rightarrow>\<^sub>s r'"
   809   assumes r: "r \<rightarrow>\<^sub>s r'"
   810   shows "NF r' \<Longrightarrow> r \<rightarrow>\<^sub>l r'" using r
   810   shows "NF r' \<Longrightarrow> r \<rightarrow>\<^sub>l r'" using r
   811 proof induct
   811 proof induct
   812   case (Var rs rs' x)
   812   case (Var rs rs' x)
   813   from `NF (Var x \<degree>\<degree> rs')` have "listsp NF rs'"
   813   from \<open>NF (Var x \<degree>\<degree> rs')\<close> have "listsp NF rs'"
   814     by cases simp_all
   814     by cases simp_all
   815   with Var(1) have "rs [\<rightarrow>\<^sub>l] rs'"
   815   with Var(1) have "rs [\<rightarrow>\<^sub>l] rs'"
   816   proof induct
   816   proof induct
   817     case Nil
   817     case Nil
   818     show ?case by (rule listrelp.Nil)
   818     show ?case by (rule listrelp.Nil)
   822     thus ?case by (rule listrelp.Cons)
   822     thus ?case by (rule listrelp.Cons)
   823   qed
   823   qed
   824   thus ?case by (rule lred.Var)
   824   thus ?case by (rule lred.Var)
   825 next
   825 next
   826   case (Abs x ss ss' r r')
   826   case (Abs x ss ss' r r')
   827   from `NF ((Lam [x].r') \<degree>\<degree> ss')`
   827   from \<open>NF ((Lam [x].r') \<degree>\<degree> ss')\<close>
   828   have ss': "ss' = []" by (rule Abs_NF)
   828   have ss': "ss' = []" by (rule Abs_NF)
   829   from Abs(4) have ss: "ss = []" using ss'
   829   from Abs(4) have ss: "ss = []" using ss'
   830     by cases simp_all
   830     by cases simp_all
   831   from ss' Abs have "NF (Lam [x].r')" by simp
   831   from ss' Abs have "NF (Lam [x].r')" by simp
   832   hence "NF r'" by (cases rule: NF.strong_cases) (auto simp add: abs_fresh lam.inject alpha)
   832   hence "NF r'" by (cases rule: NF.strong_cases) (auto simp add: abs_fresh lam.inject alpha)