src/HOL/Lambda/WeakNorm.thy
changeset 24536 fe33524ee721
parent 24423 ae9cd0e92423
child 24630 351a308ab58d
equal deleted inserted replaced
24535:d458d44639fc 24536:fe33524ee721
     5 *)
     5 *)
     6 
     6 
     7 header {* Weak normalization for simply-typed lambda calculus *}
     7 header {* Weak normalization for simply-typed lambda calculus *}
     8 
     8 
     9 theory WeakNorm
     9 theory WeakNorm
    10 imports Type Pretty_Int
    10 imports Type NormalForm Pretty_Int
    11 begin
    11 begin
    12 
    12 
    13 text {*
    13 text {*
    14 Formalization by Stefan Berghofer. Partly based on a paper proof by
    14 Formalization by Stefan Berghofer. Partly based on a paper proof by
    15 Felix Joachimski and Ralph Matthes \cite{Matthes-Joachimski-AML}.
    15 Felix Joachimski and Ralph Matthes \cite{Matthes-Joachimski-AML}.
    16 *}
    16 *}
    17 
       
    18 
       
    19 subsection {* Terms in normal form *}
       
    20 
       
    21 definition
       
    22   listall :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> bool" where
       
    23   "listall P xs \<equiv> (\<forall>i. i < length xs \<longrightarrow> P (xs ! i))"
       
    24 
       
    25 declare listall_def [extraction_expand]
       
    26 
       
    27 theorem listall_nil: "listall P []"
       
    28   by (simp add: listall_def)
       
    29 
       
    30 theorem listall_nil_eq [simp]: "listall P [] = True"
       
    31   by (iprover intro: listall_nil)
       
    32 
       
    33 theorem listall_cons: "P x \<Longrightarrow> listall P xs \<Longrightarrow> listall P (x # xs)"
       
    34   apply (simp add: listall_def)
       
    35   apply (rule allI impI)+
       
    36   apply (case_tac i)
       
    37   apply simp+
       
    38   done
       
    39 
       
    40 theorem listall_cons_eq [simp]: "listall P (x # xs) = (P x \<and> listall P xs)"
       
    41   apply (rule iffI)
       
    42   prefer 2
       
    43   apply (erule conjE)
       
    44   apply (erule listall_cons)
       
    45   apply assumption
       
    46   apply (unfold listall_def)
       
    47   apply (rule conjI)
       
    48   apply (erule_tac x=0 in allE)
       
    49   apply simp
       
    50   apply simp
       
    51   apply (rule allI)
       
    52   apply (erule_tac x="Suc i" in allE)
       
    53   apply simp
       
    54   done
       
    55 
       
    56 lemma listall_conj1: "listall (\<lambda>x. P x \<and> Q x) xs \<Longrightarrow> listall P xs"
       
    57   by (induct xs) simp_all
       
    58 
       
    59 lemma listall_conj2: "listall (\<lambda>x. P x \<and> Q x) xs \<Longrightarrow> listall Q xs"
       
    60   by (induct xs) simp_all
       
    61 
       
    62 lemma listall_app: "listall P (xs @ ys) = (listall P xs \<and> listall P ys)"
       
    63   apply (induct xs)
       
    64    apply (rule iffI, simp, simp)
       
    65   apply (rule iffI, simp, simp)
       
    66   done
       
    67 
       
    68 lemma listall_snoc [simp]: "listall P (xs @ [x]) = (listall P xs \<and> P x)"
       
    69   apply (rule iffI)
       
    70   apply (simp add: listall_app)+
       
    71   done
       
    72 
       
    73 lemma listall_cong [cong, extraction_expand]:
       
    74   "xs = ys \<Longrightarrow> listall P xs = listall P ys"
       
    75   -- {* Currently needed for strange technical reasons *}
       
    76   by (unfold listall_def) simp
       
    77 
       
    78 inductive NF :: "dB \<Rightarrow> bool"
       
    79 where
       
    80   App: "listall NF ts \<Longrightarrow> NF (Var x \<degree>\<degree> ts)"
       
    81 | Abs: "NF t \<Longrightarrow> NF (Abs t)"
       
    82 monos listall_def
       
    83 
       
    84 lemma nat_eq_dec: "\<And>n::nat. m = n \<or> m \<noteq> n"
       
    85   apply (induct m)
       
    86   apply (case_tac n)
       
    87   apply (case_tac [3] n)
       
    88   apply (simp only: nat.simps, iprover?)+
       
    89   done
       
    90 
       
    91 lemma nat_le_dec: "\<And>n::nat. m < n \<or> \<not> (m < n)"
       
    92   apply (induct m)
       
    93   apply (case_tac n)
       
    94   apply (case_tac [3] n)
       
    95   apply (simp del: simp_thms, iprover?)+
       
    96   done
       
    97 
       
    98 lemma App_NF_D: assumes NF: "NF (Var n \<degree>\<degree> ts)"
       
    99   shows "listall NF ts" using NF
       
   100   by cases simp_all
       
   101 
       
   102 
       
   103 subsection {* Properties of @{text NF} *}
       
   104 
       
   105 lemma Var_NF: "NF (Var n)"
       
   106   apply (subgoal_tac "NF (Var n \<degree>\<degree> [])")
       
   107    apply simp
       
   108   apply (rule NF.App)
       
   109   apply simp
       
   110   done
       
   111 
       
   112 lemma subst_terms_NF: "listall NF ts \<Longrightarrow>
       
   113     listall (\<lambda>t. \<forall>i j. NF (t[Var i/j])) ts \<Longrightarrow>
       
   114     listall NF (map (\<lambda>t. t[Var i/j]) ts)"
       
   115   by (induct ts) simp_all
       
   116 
       
   117 lemma subst_Var_NF: "NF t \<Longrightarrow> NF (t[Var i/j])"
       
   118   apply (induct arbitrary: i j set: NF)
       
   119   apply simp
       
   120   apply (frule listall_conj1)
       
   121   apply (drule listall_conj2)
       
   122   apply (drule_tac i=i and j=j in subst_terms_NF)
       
   123   apply assumption
       
   124   apply (rule_tac m=x and n=j in nat_eq_dec [THEN disjE, standard])
       
   125   apply simp
       
   126   apply (erule NF.App)
       
   127   apply (rule_tac m=j and n=x in nat_le_dec [THEN disjE, standard])
       
   128   apply simp
       
   129   apply (iprover intro: NF.App)
       
   130   apply simp
       
   131   apply (iprover intro: NF.App)
       
   132   apply simp
       
   133   apply (iprover intro: NF.Abs)
       
   134   done
       
   135 
       
   136 lemma app_Var_NF: "NF t \<Longrightarrow> \<exists>t'. t \<degree> Var i \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'"
       
   137   apply (induct set: NF)
       
   138   apply (simplesubst app_last)  --{*Using @{text subst} makes extraction fail*}
       
   139   apply (rule exI)
       
   140   apply (rule conjI)
       
   141   apply (rule rtranclp.rtrancl_refl)
       
   142   apply (rule NF.App)
       
   143   apply (drule listall_conj1)
       
   144   apply (simp add: listall_app)
       
   145   apply (rule Var_NF)
       
   146   apply (rule exI)
       
   147   apply (rule conjI)
       
   148   apply (rule rtranclp.rtrancl_into_rtrancl)
       
   149   apply (rule rtranclp.rtrancl_refl)
       
   150   apply (rule beta)
       
   151   apply (erule subst_Var_NF)
       
   152   done
       
   153 
       
   154 lemma lift_terms_NF: "listall NF ts \<Longrightarrow>
       
   155     listall (\<lambda>t. \<forall>i. NF (lift t i)) ts \<Longrightarrow>
       
   156     listall NF (map (\<lambda>t. lift t i) ts)"
       
   157   by (induct ts) simp_all
       
   158 
       
   159 lemma lift_NF: "NF t \<Longrightarrow> NF (lift t i)"
       
   160   apply (induct arbitrary: i set: NF)
       
   161   apply (frule listall_conj1)
       
   162   apply (drule listall_conj2)
       
   163   apply (drule_tac i=i in lift_terms_NF)
       
   164   apply assumption
       
   165   apply (rule_tac m=x and n=i in nat_le_dec [THEN disjE, standard])
       
   166   apply simp
       
   167   apply (rule NF.App)
       
   168   apply assumption
       
   169   apply simp
       
   170   apply (rule NF.App)
       
   171   apply assumption
       
   172   apply simp
       
   173   apply (rule NF.Abs)
       
   174   apply simp
       
   175   done
       
   176 
    17 
   177 
    18 
   178 subsection {* Main theorems *}
    19 subsection {* Main theorems *}
   179 
    20 
   180 lemma norm_list:
    21 lemma norm_list: