15 | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [100,100] 100) |
15 | Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [100,100] 100) |
16 |
16 |
17 section {* Strong induction principles for lam *} |
17 section {* Strong induction principles for lam *} |
18 |
18 |
19 lemma lam_induct_aux: |
19 lemma lam_induct_aux: |
20 fixes P :: "lam \<Rightarrow> 'a \<Rightarrow> bool" |
20 fixes P :: "'a \<Rightarrow> lam \<Rightarrow> bool" |
21 and f :: "'a \<Rightarrow> 'a" |
21 and f :: "'a \<Rightarrow> 'a" |
22 assumes fs: "\<And>x. finite ((supp (f x))::name set)" |
22 assumes fs: "\<And>x. finite ((supp (f x))::name set)" |
23 and h1: "\<And>x a. P (Var a) x" |
23 and h1: "\<And>x a. P x (Var a)" |
24 and h2: "\<And>x t1 t2. (\<forall>z. P t1 z) \<Longrightarrow> (\<forall>z. P t2 z) \<Longrightarrow> P (App t1 t2) x" |
24 and h2: "\<And>x t1 t2. (\<And>z. P z t1) \<Longrightarrow> (\<And>z. P z t2) \<Longrightarrow> P x (App t1 t2)" |
25 and h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<forall>z. P t z) \<Longrightarrow> P (Lam [a].t) x" |
25 and h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<And>z. P z t) \<Longrightarrow> P x (Lam [a].t)" |
26 shows "\<forall>(pi::name prm) x. P (pi\<bullet>t) x" |
26 shows "\<And>(pi::name prm) x. P x (pi\<bullet>t)" |
27 proof (induct rule: lam.induct_weak) |
27 proof (induct rule: lam.induct_weak) |
28 case (Lam a t) |
28 case (Lam a t) |
29 have ih: "\<forall>(pi::name prm) x. P (pi\<bullet>t) x" by fact |
29 have ih: "\<And>(pi::name prm) x. P x (pi\<bullet>t)" by fact |
30 show "\<forall>(pi::name prm) x. P (pi\<bullet>(Lam [a].t)) x" |
30 show "\<And>(pi::name prm) x. P x (pi\<bullet>(Lam [a].t))" |
31 proof (intro strip, simp add: abs_perm) |
31 proof (simp add: abs_perm) |
32 fix x::"'a" and pi::"name prm" |
32 fix x::"'a" and pi::"name prm" |
33 have "\<exists>c::name. c\<sharp>(f x,pi\<bullet>a,pi\<bullet>t)" |
33 have "\<exists>c::name. c\<sharp>(f x,pi\<bullet>a,pi\<bullet>t)" |
34 by (rule at_exists_fresh[OF at_name_inst], simp add: supp_prod fs_name1 fs) |
34 by (rule at_exists_fresh[OF at_name_inst], simp add: supp_prod fs_name1 fs) |
35 then obtain c::"name" |
35 then obtain c::"name" |
36 where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>(f x)" and f3: "c\<sharp>(pi\<bullet>t)" |
36 where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>(f x)" and f3: "c\<sharp>(pi\<bullet>t)" |
37 by (force simp add: fresh_prod fresh_atm) |
37 by (force simp add: fresh_prod fresh_atm) |
38 have "Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)) = Lam [(pi\<bullet>a)].(pi\<bullet>t)" using f1 f3 |
38 have "Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)) = Lam [(pi\<bullet>a)].(pi\<bullet>t)" using f1 f3 |
39 by (simp add: lam.inject alpha) |
39 by (simp add: lam.inject alpha) |
40 moreover |
40 moreover |
41 from ih have "\<forall>x. P (([(c,pi\<bullet>a)]@pi)\<bullet>t) x" by force |
41 from ih have "\<And>x. P x (([(c,pi\<bullet>a)]@pi)\<bullet>t)" by force |
42 hence "\<forall>x. P ([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)) x" by (simp add: pt_name2[symmetric]) |
42 hence "\<And>x. P x ([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t))" by (simp add: pt_name2[symmetric]) |
43 hence "P (Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t))) x" using h3 f2 |
43 hence "P x (Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>t)))" using h3 f2 |
44 by (auto simp add: fresh_def at_fin_set_supp[OF at_name_inst, OF fs]) |
44 by (auto simp add: fresh_def at_fin_set_supp[OF at_name_inst, OF fs]) |
45 ultimately show "P (Lam [(pi\<bullet>a)].(pi\<bullet>t)) x" by simp |
45 ultimately show "P x (Lam [(pi\<bullet>a)].(pi\<bullet>t))" by simp |
46 qed |
46 qed |
47 qed (auto intro: h1 h2) |
47 qed (auto intro: h1 h2) |
48 |
48 |
49 lemma lam_induct'[case_names Fin Var App Lam]: |
49 lemma lam_induct'[case_names Fin Var App Lam]: |
50 fixes P :: "lam \<Rightarrow> 'a \<Rightarrow> bool" |
50 fixes P :: "'a \<Rightarrow> lam \<Rightarrow> bool" |
51 and x :: "'a" |
51 and x :: "'a" |
52 and t :: "lam" |
52 and t :: "lam" |
53 and f :: "'a \<Rightarrow> 'a" |
53 and f :: "'a \<Rightarrow> 'a" |
54 assumes fs: "\<And>x. finite ((supp (f x))::name set)" |
54 assumes fs: "\<And>x. finite ((supp (f x))::name set)" |
55 and h1: "\<And>x a. P (Var a) x" |
55 and h1: "\<And>x a. P x (Var a)" |
56 and h2: "\<And>x t1 t2. (\<forall>z. P t1 z)\<Longrightarrow>(\<forall>z. P t2 z)\<Longrightarrow>P (App t1 t2) x" |
56 and h2: "\<And>x t1 t2. (\<And>z. P z t1)\<Longrightarrow>(\<And>z. P z t2)\<Longrightarrow>P x (App t1 t2)" |
57 and h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<forall>z. P t z)\<Longrightarrow> P (Lam [a].t) x" |
57 and h3: "\<And>x a t. a\<sharp>f x \<Longrightarrow> (\<And>z. P z t)\<Longrightarrow> P x (Lam [a].t)" |
58 shows "P t x" |
58 shows "P x t" |
59 proof - |
59 proof - |
60 from fs h1 h2 h3 have "\<forall>(pi::name prm) x. P (pi\<bullet>t) x" by (rule lam_induct_aux, auto) |
60 from fs h1 h2 h3 have "\<And>(pi::name prm) x. P x (pi\<bullet>t)" by (rule lam_induct_aux, auto) |
61 hence "P (([]::name prm)\<bullet>t) x" by blast |
61 hence "P x (([]::name prm)\<bullet>t)" by blast |
62 thus "P t x" by simp |
62 thus "P x t" by simp |
63 qed |
63 qed |
64 |
64 |
65 lemma lam_induct[case_names Var App Lam]: |
65 lemma lam_induct[case_names Var App Lam]: |
66 fixes P :: "lam \<Rightarrow> ('a::fs_name) \<Rightarrow> bool" |
66 fixes P :: "('a::fs_name) \<Rightarrow> lam \<Rightarrow> bool" |
67 and x :: "'a::fs_name" |
67 and x :: "'a::fs_name" |
68 and t :: "lam" |
68 and t :: "lam" |
69 assumes h1: "\<And>x a. P (Var a) x" |
69 assumes h1: "\<And>x a. P x (Var a)" |
70 and h2: "\<And>x t1 t2. (\<forall>z. P t1 z)\<Longrightarrow>(\<forall>z. P t2 z)\<Longrightarrow>P (App t1 t2) x" |
70 and h2: "\<And>x t1 t2. (\<And>z. P z t1)\<Longrightarrow>(\<And>z. P z t2)\<Longrightarrow>P x (App t1 t2)" |
71 and h3: "\<And>x a t. a\<sharp>x \<Longrightarrow> (\<forall>z. P t z)\<Longrightarrow> P (Lam [a].t) x" |
71 and h3: "\<And>x a t. a\<sharp>x \<Longrightarrow> (\<And>z. P z t)\<Longrightarrow> P x (Lam [a].t)" |
72 shows "P t x" |
72 shows "P x t" |
73 by (rule lam_induct'[of "\<lambda>x. x" "P"], |
73 apply(rule lam_induct'[of "\<lambda>x. x" "P"]) |
74 simp_all add: fs_name1 fresh_def[symmetric], auto intro: h1 h2 h3) |
74 apply(simp add: fs_name1) |
|
75 apply(auto intro: h1 h2 h3) |
|
76 done |
75 |
77 |
76 types 'a f1_ty = "name\<Rightarrow>('a::pt_name)" |
78 types 'a f1_ty = "name\<Rightarrow>('a::pt_name)" |
77 'a f2_ty = "'a\<Rightarrow>'a\<Rightarrow>('a::pt_name)" |
79 'a f2_ty = "'a\<Rightarrow>'a\<Rightarrow>('a::pt_name)" |
78 'a f3_ty = "name\<Rightarrow>'a\<Rightarrow>('a::pt_name)" |
80 'a f3_ty = "name\<Rightarrow>'a\<Rightarrow>('a::pt_name)" |
79 |
81 |
1037 and f2::"('a::pt_name) f2_ty'" |
1039 and f2::"('a::pt_name) f2_ty'" |
1038 and f3::"('a::pt_name) f3_ty'" |
1040 and f3::"('a::pt_name) f3_ty'" |
1039 assumes f: "finite ((supp (f1,f2,f3))::name set)" |
1041 assumes f: "finite ((supp (f1,f2,f3))::name set)" |
1040 and c: "(\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y))" |
1042 and c: "(\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name) t. a\<sharp>f3 t a y))" |
1041 shows "fst (rfun_gen' f1 f2 f3 t) = t" |
1043 shows "fst (rfun_gen' f1 f2 f3 t) = t" |
1042 apply(rule lam_induct'[of "\<lambda>_. (f1,f2,f3)" "\<lambda>t _. fst (rfun_gen' f1 f2 f3 t) = t"]) |
1044 apply(rule lam_induct'[of "\<lambda>_. (f1,f2,f3)" "\<lambda>_ t. fst (rfun_gen' f1 f2 f3 t) = t"]) |
1043 apply(simp add: f) |
1045 apply(simp add: f) |
1044 apply(unfold rfun_gen'_def) |
1046 apply(unfold rfun_gen'_def) |
1045 apply(simp only: rfun_Var[OF fsupp'[OF f],OF fcb'[OF f, OF c]]) |
1047 apply(simp only: rfun_Var[OF fsupp'[OF f],OF fcb'[OF f, OF c]]) |
1046 apply(simp) |
1048 apply(simp) |
1047 apply(simp only: rfun_App[OF fsupp'[OF f],OF fcb'[OF f, OF c]]) |
1049 apply(simp only: rfun_App[OF fsupp'[OF f],OF fcb'[OF f, OF c]]) |