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" |
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" |
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 = |
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 |
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 |
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) |