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: |