1 (* Title: HOL/Proofs/Lambda/WeakNorm.thy |
1 (* Title: HOL/Proofs/Lambda/WeakNorm.thy |
2 Author: Stefan Berghofer |
2 Author: Stefan Berghofer |
3 Copyright 2003 TU Muenchen |
3 Copyright 2003 TU Muenchen |
4 *) |
4 *) |
5 |
5 |
6 section {* Weak normalization for simply-typed lambda calculus *} |
6 section \<open>Weak normalization for simply-typed lambda calculus\<close> |
7 |
7 |
8 theory WeakNorm |
8 theory WeakNorm |
9 imports LambdaType NormalForm "~~/src/HOL/Library/Old_Datatype" |
9 imports LambdaType NormalForm "~~/src/HOL/Library/Old_Datatype" |
10 "~~/src/HOL/Library/Code_Target_Int" |
10 "~~/src/HOL/Library/Code_Target_Int" |
11 begin |
11 begin |
12 |
12 |
13 text {* |
13 text \<open> |
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 \<close> |
17 |
17 |
18 |
18 |
19 subsection {* Main theorems *} |
19 subsection \<open>Main theorems\<close> |
20 |
20 |
21 lemma norm_list: |
21 lemma norm_list: |
22 assumes f_compat: "\<And>t t'. t \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<Longrightarrow> f t \<rightarrow>\<^sub>\<beta>\<^sup>* f t'" |
22 assumes f_compat: "\<And>t t'. t \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<Longrightarrow> f t \<rightarrow>\<^sub>\<beta>\<^sup>* f t'" |
23 and f_NF: "\<And>t. NF t \<Longrightarrow> NF (f t)" |
23 and f_NF: "\<And>t. NF t \<Longrightarrow> NF (f t)" |
24 and uNF: "NF u" and uT: "e \<turnstile> u : T" |
24 and uNF: "NF u" and uT: "e \<turnstile> u : T" |
189 qed |
189 qed |
190 next |
190 next |
191 case (Abs r e1 T'1 u1 i1) |
191 case (Abs r e1 T'1 u1 i1) |
192 assume absT: "e\<langle>i:T\<rangle> \<turnstile> Abs r : T'" |
192 assume absT: "e\<langle>i:T\<rangle> \<turnstile> Abs r : T'" |
193 then obtain R S where "e\<langle>0:R\<rangle>\<langle>Suc i:T\<rangle> \<turnstile> r : S" by (rule abs_typeE) simp |
193 then obtain R S where "e\<langle>0:R\<rangle>\<langle>Suc i:T\<rangle> \<turnstile> r : S" by (rule abs_typeE) simp |
194 moreover have "NF (lift u 0)" using `NF u` by (rule lift_NF) |
194 moreover have "NF (lift u 0)" using \<open>NF u\<close> by (rule lift_NF) |
195 moreover have "e\<langle>0:R\<rangle> \<turnstile> lift u 0 : T" using uT by (rule lift_type) |
195 moreover have "e\<langle>0:R\<rangle> \<turnstile> lift u 0 : T" using uT by (rule lift_type) |
196 ultimately have "\<exists>t'. r[lift u 0/Suc i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'" by (rule Abs) |
196 ultimately have "\<exists>t'. r[lift u 0/Suc i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'" by (rule Abs) |
197 thus "\<exists>t'. Abs r[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'" |
197 thus "\<exists>t'. Abs r[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'" |
198 by simp (iprover intro: rtrancl_beta_Abs NF.Abs) |
198 by simp (iprover intro: rtrancl_beta_Abs NF.Abs) |
199 } |
199 } |
200 qed |
200 qed |
201 qed |
201 qed |
202 |
202 |
203 |
203 |
204 -- {* A computationally relevant copy of @{term "e \<turnstile> t : T"} *} |
204 \<comment> \<open>A computationally relevant copy of @{term "e \<turnstile> t : T"}\<close> |
205 inductive rtyping :: "(nat \<Rightarrow> type) \<Rightarrow> dB \<Rightarrow> type \<Rightarrow> bool" ("_ \<turnstile>\<^sub>R _ : _" [50, 50, 50] 50) |
205 inductive rtyping :: "(nat \<Rightarrow> type) \<Rightarrow> dB \<Rightarrow> type \<Rightarrow> bool" ("_ \<turnstile>\<^sub>R _ : _" [50, 50, 50] 50) |
206 where |
206 where |
207 Var: "e x = T \<Longrightarrow> e \<turnstile>\<^sub>R Var x : T" |
207 Var: "e x = T \<Longrightarrow> e \<turnstile>\<^sub>R Var x : T" |
208 | Abs: "e\<langle>0:T\<rangle> \<turnstile>\<^sub>R t : U \<Longrightarrow> e \<turnstile>\<^sub>R Abs t : (T \<Rightarrow> U)" |
208 | Abs: "e\<langle>0:T\<rangle> \<turnstile>\<^sub>R t : U \<Longrightarrow> e \<turnstile>\<^sub>R Abs t : (T \<Rightarrow> U)" |
209 | App: "e \<turnstile>\<^sub>R s : T \<Rightarrow> U \<Longrightarrow> e \<turnstile>\<^sub>R t : T \<Longrightarrow> e \<turnstile>\<^sub>R (s \<degree> t) : U" |
209 | App: "e \<turnstile>\<^sub>R s : T \<Rightarrow> U \<Longrightarrow> e \<turnstile>\<^sub>R t : T \<Longrightarrow> e \<turnstile>\<^sub>R (s \<degree> t) : U" |
255 hence "s \<degree> t \<rightarrow>\<^sub>\<beta>\<^sup>* u" using ured by (rule rtranclp_trans) |
255 hence "s \<degree> t \<rightarrow>\<^sub>\<beta>\<^sup>* u" using ured by (rule rtranclp_trans) |
256 with unf show ?case by iprover |
256 with unf show ?case by iprover |
257 qed |
257 qed |
258 |
258 |
259 |
259 |
260 subsection {* Extracting the program *} |
260 subsection \<open>Extracting the program\<close> |
261 |
261 |
262 declare NF.induct [ind_realizer] |
262 declare NF.induct [ind_realizer] |
263 declare rtranclp.induct [ind_realizer irrelevant] |
263 declare rtranclp.induct [ind_realizer irrelevant] |
264 declare rtyping.induct [ind_realizer] |
264 declare rtyping.induct [ind_realizer] |
265 lemmas [extraction_expand] = conj_assoc listall_cons_eq |
265 lemmas [extraction_expand] = conj_assoc listall_cons_eq |
283 apply (rule NF.intros) |
283 apply (rule NF.intros) |
284 apply (simp add: listall_def) |
284 apply (simp add: listall_def) |
285 apply (erule NF.intros) |
285 apply (erule NF.intros) |
286 done |
286 done |
287 |
287 |
288 text_raw {* |
288 text_raw \<open> |
289 \begin{figure} |
289 \begin{figure} |
290 \renewcommand{\isastyle}{\scriptsize\it}% |
290 \renewcommand{\isastyle}{\scriptsize\it}% |
291 @{thm [display,eta_contract=false,margin=100] subst_type_NF_def} |
291 @{thm [display,eta_contract=false,margin=100] subst_type_NF_def} |
292 \renewcommand{\isastyle}{\small\it}% |
292 \renewcommand{\isastyle}{\small\it}% |
293 \caption{Program extracted from @{text subst_type_NF}} |
293 \caption{Program extracted from \<open>subst_type_NF\<close>} |
294 \label{fig:extr-subst-type-nf} |
294 \label{fig:extr-subst-type-nf} |
295 \end{figure} |
295 \end{figure} |
296 |
296 |
297 \begin{figure} |
297 \begin{figure} |
298 \renewcommand{\isastyle}{\scriptsize\it}% |
298 \renewcommand{\isastyle}{\scriptsize\it}% |
302 @{thm [display,eta_contract=false,margin=100] type_NF_def} |
302 @{thm [display,eta_contract=false,margin=100] type_NF_def} |
303 \renewcommand{\isastyle}{\small\it}% |
303 \renewcommand{\isastyle}{\small\it}% |
304 \caption{Program extracted from lemmas and main theorem} |
304 \caption{Program extracted from lemmas and main theorem} |
305 \label{fig:extr-type-nf} |
305 \label{fig:extr-type-nf} |
306 \end{figure} |
306 \end{figure} |
307 *} |
307 \<close> |
308 |
308 |
309 text {* |
309 text \<open> |
310 The program corresponding to the proof of the central lemma, which |
310 The program corresponding to the proof of the central lemma, which |
311 performs substitution and normalization, is shown in Figure |
311 performs substitution and normalization, is shown in Figure |
312 \ref{fig:extr-subst-type-nf}. The correctness |
312 \ref{fig:extr-subst-type-nf}. The correctness |
313 theorem corresponding to the program @{text "subst_type_NF"} is |
313 theorem corresponding to the program \<open>subst_type_NF\<close> is |
314 @{thm [display,margin=100] subst_type_NF_correctness |
314 @{thm [display,margin=100] subst_type_NF_correctness |
315 [simplified rtranclR_rtrancl_eq Collect_mem_eq, no_vars]} |
315 [simplified rtranclR_rtrancl_eq Collect_mem_eq, no_vars]} |
316 where @{text NFR} is the realizability predicate corresponding to |
316 where \<open>NFR\<close> is the realizability predicate corresponding to |
317 the datatype @{text NFT}, which is inductively defined by the rules |
317 the datatype \<open>NFT\<close>, which is inductively defined by the rules |
318 \pagebreak |
318 \pagebreak |
319 @{thm [display,margin=90] NFR.App [of ts nfs x] NFR.Abs [of nf t]} |
319 @{thm [display,margin=90] NFR.App [of ts nfs x] NFR.Abs [of nf t]} |
320 |
320 |
321 The programs corresponding to the main theorem @{text "type_NF"}, as |
321 The programs corresponding to the main theorem \<open>type_NF\<close>, as |
322 well as to some lemmas, are shown in Figure \ref{fig:extr-type-nf}. |
322 well as to some lemmas, are shown in Figure \ref{fig:extr-type-nf}. |
323 The correctness statement for the main function @{text "type_NF"} is |
323 The correctness statement for the main function \<open>type_NF\<close> is |
324 @{thm [display,margin=100] type_NF_correctness |
324 @{thm [display,margin=100] type_NF_correctness |
325 [simplified rtranclR_rtrancl_eq Collect_mem_eq, no_vars]} |
325 [simplified rtranclR_rtrancl_eq Collect_mem_eq, no_vars]} |
326 where the realizability predicate @{text "rtypingR"} corresponding to the |
326 where the realizability predicate \<open>rtypingR\<close> corresponding to the |
327 computationally relevant version of the typing judgement is inductively |
327 computationally relevant version of the typing judgement is inductively |
328 defined by the rules |
328 defined by the rules |
329 @{thm [display,margin=100] rtypingR.Var [no_vars] |
329 @{thm [display,margin=100] rtypingR.Var [no_vars] |
330 rtypingR.Abs [of ty, no_vars] rtypingR.App [of ty e s T U ty' t]} |
330 rtypingR.Abs [of ty, no_vars] rtypingR.App [of ty e s T U ty' t]} |
331 *} |
331 \<close> |
332 |
332 |
333 subsection {* Generating executable code *} |
333 subsection \<open>Generating executable code\<close> |
334 |
334 |
335 instantiation NFT :: default |
335 instantiation NFT :: default |
336 begin |
336 begin |
337 |
337 |
338 definition "default = Dummy ()" |
338 definition "default = Dummy ()" |
378 end |
378 end |
379 |
379 |
380 definition int_of_nat :: "nat \<Rightarrow> int" where |
380 definition int_of_nat :: "nat \<Rightarrow> int" where |
381 "int_of_nat = of_nat" |
381 "int_of_nat = of_nat" |
382 |
382 |
383 text {* |
383 text \<open> |
384 The following functions convert between Isabelle's built-in {\tt term} |
384 The following functions convert between Isabelle's built-in {\tt term} |
385 datatype and the generated {\tt dB} datatype. This allows to |
385 datatype and the generated {\tt dB} datatype. This allows to |
386 generate example terms using Isabelle's parser and inspect |
386 generate example terms using Isabelle's parser and inspect |
387 normalized terms using Isabelle's pretty printer. |
387 normalized terms using Isabelle's pretty printer. |
388 *} |
388 \<close> |
389 |
389 |
390 ML {* |
390 ML \<open> |
391 val nat_of_integer = @{code nat} o @{code int_of_integer}; |
391 val nat_of_integer = @{code nat} o @{code int_of_integer}; |
392 |
392 |
393 fun dBtype_of_typ (Type ("fun", [T, U])) = |
393 fun dBtype_of_typ (Type ("fun", [T, U])) = |
394 @{code Fun} (dBtype_of_typ T, dBtype_of_typ U) |
394 @{code Fun} (dBtype_of_typ T, dBtype_of_typ U) |
395 | dBtype_of_typ (TFree (s, _)) = (case raw_explode s of |
395 | dBtype_of_typ (TFree (s, _)) = (case raw_explode s of |