author | urbanc |
Tue, 16 May 2006 14:11:39 +0200 | |
changeset 19651 | 247ca17caddd |
parent 19496 | 79dbe35c6cba |
child 19858 | d319e39a2e0e |
permissions | -rw-r--r-- |
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
1 |
(* $Id$ *) |
19496 | 2 |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
3 |
theory Iteration |
19496 | 4 |
imports "../Nominal" |
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
5 |
begin |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
6 |
|
19651 | 7 |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
8 |
atom_decl name |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
9 |
|
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
10 |
nominal_datatype lam = Var "name" |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
11 |
| App "lam" "lam" |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
12 |
| Lam "\<guillemotleft>name\<guillemotright>lam" ("Lam [_]._" [100,100] 100) |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
13 |
|
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
14 |
types 'a f1_ty = "name\<Rightarrow>('a::pt_name)" |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
15 |
'a f2_ty = "'a\<Rightarrow>'a\<Rightarrow>('a::pt_name)" |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
16 |
'a f3_ty = "name\<Rightarrow>'a\<Rightarrow>('a::pt_name)" |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
17 |
|
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
18 |
consts |
19651 | 19 |
it :: "'a f1_ty \<Rightarrow> 'a f2_ty \<Rightarrow> 'a f3_ty \<Rightarrow> (lam \<times> 'a::pt_name) set" |
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
20 |
|
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
21 |
inductive "it f1 f2 f3" |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
22 |
intros |
19651 | 23 |
it1: "(Var a, f1 a) \<in> it f1 f2 f3" |
24 |
it2: "\<lbrakk>(t1,r1) \<in> it f1 f2 f3; (t2,r2) \<in> it f1 f2 f3\<rbrakk> \<Longrightarrow> (App t1 t2, f2 r1 r2) \<in> it f1 f2 f3" |
|
25 |
it3: "\<lbrakk>a\<sharp>(f1,f2,f3); (t,r) \<in> it f1 f2 f3\<rbrakk> \<Longrightarrow> (Lam [a].t,f3 a r) \<in> it f1 f2 f3" |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
26 |
|
19651 | 27 |
lemma it_equiv: |
28 |
fixes pi::"name prm" |
|
29 |
assumes a: "(t,r) \<in> it f1 f2 f3" |
|
30 |
shows "(pi\<bullet>t,pi\<bullet>r) \<in> it (pi\<bullet>f1) (pi\<bullet>f2) (pi\<bullet>f3)" |
|
31 |
using a |
|
32 |
apply(induct) |
|
33 |
apply(perm_simp | auto intro!: it.intros simp add: fresh_right)+ |
|
34 |
done |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
35 |
|
19651 | 36 |
lemma it_fin_supp: |
37 |
assumes f: "finite ((supp (f1,f2,f3))::name set)" |
|
38 |
and a: "(t,r) \<in> it f1 f2 f3" |
|
39 |
shows "finite ((supp r)::name set)" |
|
40 |
using a f |
|
41 |
apply(induct) |
|
42 |
apply(finite_guess, simp add: supp_prod fs_name1)+ |
|
43 |
done |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
44 |
|
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
45 |
lemma it_total: |
19651 | 46 |
assumes a: "finite ((supp (f1,f2,f3))::name set)" |
47 |
and b: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)" |
|
48 |
shows "\<exists>r. (t,r)\<in>it f1 f2 f3" |
|
49 |
apply(rule_tac lam.induct'[of "\<lambda>_. (supp (f1,f2,f3))::name set" |
|
50 |
"\<lambda>z. \<lambda>t. \<exists>r. (t,r)\<in>it f1 f2 f3", simplified]) |
|
51 |
apply(fold fresh_def) |
|
52 |
apply(auto intro: it.intros a) |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
53 |
done |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
54 |
|
19651 | 55 |
lemma it_unique: |
56 |
assumes a: "finite ((supp (f1,f2,f3))::name set)" |
|
57 |
and b: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(y::'a::pt_name). a\<sharp>f3 a y)" |
|
58 |
and c1: "(t,r)\<in>it f1 f2 f3" |
|
59 |
and c2: "(t,r')\<in>it f1 f2 f3" |
|
60 |
shows "r=r'" |
|
61 |
using c1 c2 |
|
62 |
proof (induct fixing: r') |
|
63 |
case it1 |
|
64 |
then show ?case by cases (simp_all add: lam.inject) |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
65 |
next |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
66 |
case (it2 r1 r2 t1 t2) |
19651 | 67 |
have ih1: "\<And>r'. (t1,r') \<in> it f1 f2 f3 \<Longrightarrow> r1 = r'" by fact |
68 |
have ih2: "\<And>r'. (t2,r') \<in> it f1 f2 f3 \<Longrightarrow> r2 = r'" by fact |
|
69 |
have "(App t1 t2, r') \<in>it f1 f2 f3" by fact |
|
70 |
then show ?case |
|
71 |
proof cases |
|
72 |
case it2 |
|
73 |
then show ?thesis using ih1 ih2 by (simp add: lam.inject) |
|
74 |
qed (simp_all (no_asm_use)) |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
75 |
next |
19651 | 76 |
case (it3 a1 r1 t1) |
77 |
have f1: "a1\<sharp>(f1,f2,f3)" by fact |
|
78 |
have ih: "\<And>r'. (t1,r') \<in> it f1 f2 f3 \<Longrightarrow> r1 = r'" by fact |
|
79 |
have it1: "(t1,r1) \<in> it f1 f2 f3" by fact |
|
80 |
have "(Lam [a1].t1, r') \<in> it f1 f2 f3" by fact |
|
81 |
then show ?case |
|
82 |
proof cases |
|
83 |
case (it3 a2 r2 t2) |
|
84 |
then have f2: "a2\<sharp>(f1,f2,f3)" |
|
85 |
and it2: "(t2,r2) \<in> it f1 f2 f3" |
|
86 |
and eq1: "[a1].t1 = [a2].t2" and eq2: "r' = f3 a2 r2" by (simp_all add: lam.inject) |
|
87 |
have "\<exists>(c::name). c\<sharp>(f1,f2,f3,a1,a2,t1,t2,r1,r2)" using a it1 it2 |
|
88 |
by (auto intro!: at_exists_fresh[OF at_name_inst] simp add: supp_prod fs_name1 it_fin_supp[OF a]) |
|
89 |
then obtain c where fresh: "c\<sharp>f1" "c\<sharp>f2" "c\<sharp>f3" "c\<noteq>a1" "c\<noteq>a2" "c\<sharp>t1" "c\<sharp>t2" "c\<sharp>r1" "c\<sharp>r2" |
|
90 |
by (force simp add: fresh_prod fresh_atm) |
|
91 |
have eq3: "[(a1,c)]\<bullet>t1 = [(a2,c)]\<bullet>t2" using eq1 fresh |
|
92 |
apply(auto simp add: alpha) |
|
93 |
apply(rule trans) |
|
94 |
apply(rule perm_compose) |
|
95 |
apply(simp add: calc_atm perm_fresh_fresh) |
|
96 |
apply(rule pt_name3, rule at_ds5[OF at_name_inst]) |
|
97 |
done |
|
98 |
have eq4: "[(a1,c)]\<bullet>r1 = [(a2,c)]\<bullet>r2" using eq3 it2 f1 f2 fresh |
|
99 |
apply(drule_tac sym) |
|
100 |
apply(rule_tac pt_bij2[OF pt_name_inst, OF at_name_inst]) |
|
101 |
apply(rule ih) |
|
102 |
apply(drule_tac pi="[(a2,c)]" in it_equiv) |
|
103 |
apply(perm_simp only: fresh_prod) |
|
104 |
apply(drule_tac pi="[(a1,c)]" in it_equiv) |
|
105 |
apply(perm_simp) |
|
106 |
done |
|
107 |
have fs1: "a1\<sharp>f3 a1 r1" using b f1 |
|
108 |
apply(auto) |
|
109 |
apply(case_tac "a=a1") |
|
110 |
apply(simp) |
|
111 |
apply(rule_tac pi="[(a1,a)]" in pt_fresh_bij2[OF pt_name_inst, OF at_name_inst]) |
|
112 |
apply(perm_simp add: calc_atm fresh_prod) |
|
113 |
done |
|
114 |
have fs2: "a2\<sharp>f3 a2 r2" using b f2 |
|
115 |
apply(auto) |
|
116 |
apply(case_tac "a=a2") |
|
117 |
apply(simp) |
|
118 |
apply(rule_tac pi="[(a2,a)]" in pt_fresh_bij2[OF pt_name_inst, OF at_name_inst]) |
|
119 |
apply(perm_simp add: calc_atm fresh_prod) |
|
120 |
done |
|
121 |
have fs3: "c\<sharp>f3 a1 r1" using fresh it1 a |
|
122 |
apply(rule_tac S="supp (f3,a1,r1)" in supports_fresh) |
|
123 |
apply(supports_simp) |
|
124 |
apply(simp add: supp_prod fs_name1 it_fin_supp[OF a]) |
|
125 |
apply(simp add: fresh_def[symmetric] fresh_prod fresh_atm) |
|
126 |
done |
|
127 |
have fs4: "c\<sharp>f3 a2 r2" using fresh it2 a |
|
128 |
apply(rule_tac S="supp (f3,a2,r2)" in supports_fresh) |
|
129 |
apply(supports_simp) |
|
130 |
apply(simp add: supp_prod fs_name1 it_fin_supp[OF a]) |
|
131 |
apply(simp add: fresh_def[symmetric] fresh_prod fresh_atm) |
|
132 |
done |
|
133 |
have "f3 a1 r1 = [(a1,c)]\<bullet>(f3 a1 r1)" using fs1 fs3 by perm_simp |
|
134 |
also have "\<dots> = f3 c ([(a1,c)]\<bullet>r1)" using f1 fresh by (perm_simp add: calc_atm fresh_prod) |
|
135 |
also have "\<dots> = f3 c ([(a2,c)]\<bullet>r2)" using eq4 by simp |
|
136 |
also have "\<dots> = [(a2,c)]\<bullet>(f3 a2 r2)" using f2 fresh by (perm_simp add: calc_atm fresh_prod) |
|
137 |
also have "\<dots> = f3 a2 r2" using fs2 fs4 by perm_simp |
|
138 |
finally have eq4: "f3 a1 r1 = f3 a2 r2" by simp |
|
139 |
then show ?thesis using eq2 by simp |
|
140 |
qed (simp_all (no_asm_use)) |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
141 |
qed |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
142 |
|
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
143 |
lemma it_function: |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
144 |
assumes f: "finite ((supp (f1,f2,f3))::name set)" |
19158 | 145 |
and c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(r::'a::pt_name). a\<sharp>f3 a r)" |
146 |
shows "\<exists>!r. (t,r) \<in> it f1 f2 f3" |
|
19651 | 147 |
proof (rule ex_ex1I, rule it_total[OF f, OF c]) |
19225 | 148 |
case (goal1 r1 r2) |
19158 | 149 |
have a1: "(t,r1) \<in> it f1 f2 f3" and a2: "(t,r2) \<in> it f1 f2 f3" by fact |
19651 | 150 |
thus "r1 = r2" using it_unique[OF f, OF c] by simp |
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
151 |
qed |
19651 | 152 |
|
153 |
constdefs |
|
154 |
itfun :: "'a f1_ty \<Rightarrow> 'a f2_ty \<Rightarrow> 'a f3_ty \<Rightarrow> lam \<Rightarrow> ('a::pt_name)" |
|
155 |
"itfun f1 f2 f3 t \<equiv> (THE r. (t,r) \<in> it f1 f2 f3)" |
|
156 |
||
157 |
lemma itfun_eqvt: |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
158 |
fixes pi::"name prm" |
19158 | 159 |
assumes f: "finite ((supp (f1,f2,f3))::name set)" |
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
160 |
and c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(r::'a::pt_name). a\<sharp>f3 a r)" |
19651 | 161 |
shows "pi\<bullet>(itfun f1 f2 f3 t) = itfun (pi\<bullet>f1) (pi\<bullet>f2) (pi\<bullet>f3) (pi\<bullet>t)" |
162 |
proof - |
|
163 |
have f_pi: "finite ((supp (pi\<bullet>f1,pi\<bullet>f2,pi\<bullet>f3))::name set)" using f |
|
164 |
by (simp add: supp_prod pt_supp_finite_pi[OF pt_name_inst, OF at_name_inst]) |
|
165 |
have fs_pi: "\<exists>(a::name). a\<sharp>(pi\<bullet>f3) \<and> (\<forall>(r::'a::pt_name). a\<sharp>(pi\<bullet>f3) a r)" |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
166 |
proof - |
19651 | 167 |
from c obtain a where fs1: "a\<sharp>f3" and fs2: "\<forall>(r::'a::pt_name). a\<sharp>f3 a r" by force |
168 |
have "(pi\<bullet>a)\<sharp>(pi\<bullet>f3)" using fs1 by (simp add: fresh_eqvt) |
|
19168 | 169 |
moreover |
19651 | 170 |
have "\<forall>(r::'a::pt_name). (pi\<bullet>a)\<sharp>((pi\<bullet>f3) (pi\<bullet>a) r)" using fs2 by (perm_simp add: fresh_right) |
171 |
ultimately show "\<exists>(a::name). a\<sharp>(pi\<bullet>f3) \<and> (\<forall>(r::'a::pt_name). a\<sharp>(pi\<bullet>f3) a r)" by blast |
|
19168 | 172 |
qed |
173 |
show ?thesis |
|
174 |
apply(rule sym) |
|
19651 | 175 |
apply(auto simp add: itfun_def) |
176 |
apply(rule the1_equality[OF it_function, OF f_pi, OF fs_pi]) |
|
177 |
apply(rule it_equiv) |
|
19168 | 178 |
apply(rule theI'[OF it_function,OF f, OF c]) |
179 |
done |
|
180 |
qed |
|
181 |
||
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
182 |
lemma itfun_Var: |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
183 |
assumes f: "finite ((supp (f1,f2,f3))::name set)" |
19651 | 184 |
and c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(r::'a::pt_name). a\<sharp>f3 a r)" |
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
185 |
shows "itfun f1 f2 f3 (Var c) = (f1 c)" |
19651 | 186 |
using f c by (auto intro!: the1_equality it_function it.intros simp add: itfun_def) |
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
187 |
|
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
188 |
lemma itfun_App: |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
189 |
assumes f: "finite ((supp (f1,f2,f3))::name set)" |
19651 | 190 |
and c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(r::'a::pt_name). a\<sharp>f3 a r)" |
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
191 |
shows "itfun f1 f2 f3 (App t1 t2) = (f2 (itfun f1 f2 f3 t1) (itfun f1 f2 f3 t2))" |
19651 | 192 |
by (auto intro!: the1_equality it_function[OF f, OF c] it.intros |
193 |
intro: theI'[OF it_function, OF f, OF c] simp add: itfun_def) |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
194 |
|
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
195 |
lemma itfun_Lam: |
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
196 |
assumes f: "finite ((supp (f1,f2,f3))::name set)" |
19651 | 197 |
and c: "\<exists>(a::name). a\<sharp>f3 \<and> (\<forall>(r::'a::pt_name). a\<sharp>f3 a r)" |
198 |
and a: "a\<sharp>(f1,f2,f3)" |
|
199 |
shows "itfun f1 f2 f3 (Lam [a].t) = f3 a (itfun f1 f2 f3 t)" |
|
200 |
using a |
|
201 |
by (auto intro!: the1_equality it_function[OF f, OF c] it.intros |
|
202 |
intro: theI'[OF it_function, OF f, OF c] simp add: itfun_def) |
|
19496 | 203 |
|
19157
6e4ce7402dbe
initial commit (especially 2nd half needs to be cleaned up)
urbanc
parents:
diff
changeset
|
204 |
end |