1theory Class1
2imports "HOL-Nominal.Nominal" 
3begin
4
5section \<open>Term-Calculus from Urban's PhD\<close>
6
7atom_decl name coname
8
9text \<open>types\<close>
10
11nominal_datatype ty =
12    PR "string"
13  | NOT  "ty"
14  | AND  "ty" "ty"   ("_ AND _" [100,100] 100)
15  | OR   "ty" "ty"   ("_ OR _" [100,100] 100)
16  | IMP  "ty" "ty"   ("_ IMP _" [100,100] 100)
17
18instantiation ty :: size
19begin
20
21nominal_primrec size_ty
22where
23  "size (PR s)     = (1::nat)"
24| "size (NOT T)     = 1 + size T"
25| "size (T1 AND T2) = 1 + size T1 + size T2"
26| "size (T1 OR T2)  = 1 + size T1 + size T2"
27| "size (T1 IMP T2) = 1 + size T1 + size T2"
28by (rule TrueI)+
29
30instance ..
31
32end
33
34lemma ty_cases:
35  fixes T::ty
36  shows "(\<exists>s. T=PR s) \<or> (\<exists>T'. T=NOT T') \<or> (\<exists>S U. T=S OR U) \<or> (\<exists>S U. T=S AND U) \<or> (\<exists>S U. T=S IMP U)"
37by (induct T rule:ty.induct) (auto)
38
39lemma fresh_ty:
40  fixes a::"coname"
41  and   x::"name"
42  and   T::"ty"
43  shows "a\<sharp>T" and "x\<sharp>T"
44by (nominal_induct T rule: ty.strong_induct)
45   (auto simp add: fresh_string)
46
47text \<open>terms\<close>
48
49nominal_datatype trm = 
50    Ax   "name" "coname"
51  | Cut  "\<guillemotleft>coname\<guillemotright>trm" "\<guillemotleft>name\<guillemotright>trm"            ("Cut <_>._ (_)._" [100,100,100,100] 100)
52  | NotR "\<guillemotleft>name\<guillemotright>trm" "coname"                 ("NotR (_)._ _" [100,100,100] 100)
53  | NotL "\<guillemotleft>coname\<guillemotright>trm" "name"                 ("NotL <_>._ _" [100,100,100] 100)
54  | AndR "\<guillemotleft>coname\<guillemotright>trm" "\<guillemotleft>coname\<guillemotright>trm" "coname" ("AndR <_>._ <_>._ _" [100,100,100,100,100] 100)
55  | AndL1 "\<guillemotleft>name\<guillemotright>trm" "name"                  ("AndL1 (_)._ _" [100,100,100] 100)
56  | AndL2 "\<guillemotleft>name\<guillemotright>trm" "name"                  ("AndL2 (_)._ _" [100,100,100] 100)
57  | OrR1 "\<guillemotleft>coname\<guillemotright>trm" "coname"               ("OrR1 <_>._ _" [100,100,100] 100)
58  | OrR2 "\<guillemotleft>coname\<guillemotright>trm" "coname"               ("OrR2 <_>._ _" [100,100,100] 100)
59  | OrL "\<guillemotleft>name\<guillemotright>trm" "\<guillemotleft>name\<guillemotright>trm" "name"        ("OrL (_)._ (_)._ _" [100,100,100,100,100] 100)
60  | ImpR "\<guillemotleft>name\<guillemotright>(\<guillemotleft>coname\<guillemotright>trm)" "coname"       ("ImpR (_).<_>._ _" [100,100,100,100] 100)
61  | ImpL "\<guillemotleft>coname\<guillemotright>trm" "\<guillemotleft>name\<guillemotright>trm" "name"     ("ImpL <_>._ (_)._ _" [100,100,100,100,100] 100)
62
63text \<open>named terms\<close>
64
65nominal_datatype ntrm = Na "\<guillemotleft>name\<guillemotright>trm" ("((_):_)" [100,100] 100)
66
67text \<open>conamed terms\<close>
68
69nominal_datatype ctrm = Co "\<guillemotleft>coname\<guillemotright>trm" ("(<_>:_)" [100,100] 100)
70
71text \<open>renaming functions\<close>
72
73nominal_primrec (freshness_context: "(d::coname,e::coname)") 
74  crename :: "trm \<Rightarrow> coname \<Rightarrow> coname \<Rightarrow> trm"  ("_[_\<turnstile>c>_]" [100,100,100] 100) 
75where
76  "(Ax x a)[d\<turnstile>c>e] = (if a=d then Ax x e else Ax x a)" 
77| "\<lbrakk>a\<sharp>(d,e,N);x\<sharp>M\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N)[d\<turnstile>c>e] = Cut <a>.(M[d\<turnstile>c>e]) (x).(N[d\<turnstile>c>e])" 
78| "(NotR (x).M a)[d\<turnstile>c>e] = (if a=d then NotR (x).(M[d\<turnstile>c>e]) e else NotR (x).(M[d\<turnstile>c>e]) a)" 
79| "a\<sharp>(d,e) \<Longrightarrow> (NotL <a>.M x)[d\<turnstile>c>e] = (NotL <a>.(M[d\<turnstile>c>e]) x)" 
80| "\<lbrakk>a\<sharp>(d,e,N,c);b\<sharp>(d,e,M,c);b\<noteq>a\<rbrakk> \<Longrightarrow> (AndR <a>.M <b>.N c)[d\<turnstile>c>e] = 
81          (if c=d then AndR <a>.(M[d\<turnstile>c>e]) <b>.(N[d \<turnstile>c>e]) e else AndR <a>.(M[d\<turnstile>c>e]) <b>.(N[d\<turnstile>c>e]) c)" 
82| "x\<sharp>y \<Longrightarrow> (AndL1 (x).M y)[d\<turnstile>c>e] = AndL1 (x).(M[d\<turnstile>c>e]) y"
83| "x\<sharp>y \<Longrightarrow> (AndL2 (x).M y)[d\<turnstile>c>e] = AndL2 (x).(M[d\<turnstile>c>e]) y"
84| "a\<sharp>(d,e,b) \<Longrightarrow> (OrR1 <a>.M b)[d\<turnstile>c>e] = (if b=d then OrR1 <a>.(M[d\<turnstile>c>e]) e else OrR1 <a>.(M[d\<turnstile>c>e]) b)"
85| "a\<sharp>(d,e,b) \<Longrightarrow> (OrR2 <a>.M b)[d\<turnstile>c>e] = (if b=d then OrR2 <a>.(M[d\<turnstile>c>e]) e else OrR2 <a>.(M[d\<turnstile>c>e]) b)"
86| "\<lbrakk>x\<sharp>(N,z);y\<sharp>(M,z);y\<noteq>x\<rbrakk> \<Longrightarrow> (OrL (x).M (y).N z)[d\<turnstile>c>e] = OrL (x).(M[d\<turnstile>c>e]) (y).(N[d\<turnstile>c>e]) z"
87| "a\<sharp>(d,e,b) \<Longrightarrow> (ImpR (x).<a>.M b)[d\<turnstile>c>e] = 
88       (if b=d then ImpR (x).<a>.(M[d\<turnstile>c>e]) e else ImpR (x).<a>.(M[d\<turnstile>c>e]) b)"
89| "\<lbrakk>a\<sharp>(d,e,N);x\<sharp>(M,y)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N y)[d\<turnstile>c>e] = ImpL <a>.(M[d\<turnstile>c>e]) (x).(N[d\<turnstile>c>e]) y"
90apply(finite_guess)+
91apply(rule TrueI)+
92apply(simp add: abs_fresh abs_supp fin_supp)+
93apply(fresh_guess)+
94done
95
96nominal_primrec (freshness_context: "(u::name,v::name)") 
97  nrename :: "trm \<Rightarrow> name \<Rightarrow> name \<Rightarrow> trm"      ("_[_\<turnstile>n>_]" [100,100,100] 100) 
98where
99  "(Ax x a)[u\<turnstile>n>v] = (if x=u then Ax v a else Ax x a)" 
100| "\<lbrakk>a\<sharp>N;x\<sharp>(u,v,M)\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N)[u\<turnstile>n>v] = Cut <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v])" 
101| "x\<sharp>(u,v) \<Longrightarrow> (NotR (x).M a)[u\<turnstile>n>v] = NotR (x).(M[u\<turnstile>n>v]) a" 
102| "(NotL <a>.M x)[u\<turnstile>n>v] = (if x=u then NotL <a>.(M[u\<turnstile>n>v]) v else NotL <a>.(M[u\<turnstile>n>v]) x)" 
103| "\<lbrakk>a\<sharp>(N,c);b\<sharp>(M,c);b\<noteq>a\<rbrakk> \<Longrightarrow> (AndR <a>.M <b>.N c)[u\<turnstile>n>v] = AndR <a>.(M[u\<turnstile>n>v]) <b>.(N[u\<turnstile>n>v]) c" 
104| "x\<sharp>(u,v,y) \<Longrightarrow> (AndL1 (x).M y)[u\<turnstile>n>v] = (if y=u then AndL1 (x).(M[u\<turnstile>n>v]) v else AndL1 (x).(M[u\<turnstile>n>v]) y)"
105| "x\<sharp>(u,v,y) \<Longrightarrow> (AndL2 (x).M y)[u\<turnstile>n>v] = (if y=u then AndL2 (x).(M[u\<turnstile>n>v]) v else AndL2 (x).(M[u\<turnstile>n>v]) y)"
106| "a\<sharp>b \<Longrightarrow> (OrR1 <a>.M b)[u\<turnstile>n>v] = OrR1 <a>.(M[u\<turnstile>n>v]) b"
107| "a\<sharp>b \<Longrightarrow> (OrR2 <a>.M b)[u\<turnstile>n>v] = OrR2 <a>.(M[u\<turnstile>n>v]) b"
108| "\<lbrakk>x\<sharp>(u,v,N,z);y\<sharp>(u,v,M,z);y\<noteq>x\<rbrakk> \<Longrightarrow> (OrL (x).M (y).N z)[u\<turnstile>n>v] = 
109        (if z=u then OrL (x).(M[u\<turnstile>n>v]) (y).(N[u\<turnstile>n>v]) v else OrL (x).(M[u\<turnstile>n>v]) (y).(N[u\<turnstile>n>v]) z)"
110| "\<lbrakk>a\<sharp>b; x\<sharp>(u,v)\<rbrakk> \<Longrightarrow> (ImpR (x).<a>.M b)[u\<turnstile>n>v] = ImpR (x).<a>.(M[u\<turnstile>n>v]) b"
111| "\<lbrakk>a\<sharp>N;x\<sharp>(u,v,M,y)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N y)[u\<turnstile>n>v] = 
112        (if y=u then ImpL <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v]) v else ImpL <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v]) y)"
113apply(finite_guess)+
114apply(rule TrueI)+
115apply(simp add: abs_fresh abs_supp fs_name1 fs_coname1)+
116apply(fresh_guess)+
117done
118
119lemmas eq_bij = pt_bij[OF pt_name_inst, OF at_name_inst] pt_bij[OF pt_coname_inst, OF at_coname_inst]
120
121lemma crename_name_eqvt[eqvt]:
122  fixes pi::"name prm"
123  shows "pi\<bullet>(M[d\<turnstile>c>e]) = (pi\<bullet>M)[(pi\<bullet>d)\<turnstile>c>(pi\<bullet>e)]"
124apply(nominal_induct M avoiding: d e rule: trm.strong_induct)
125apply(auto simp add: fresh_bij eq_bij)
126done
127
128lemma crename_coname_eqvt[eqvt]:
129  fixes pi::"coname prm"
130  shows "pi\<bullet>(M[d\<turnstile>c>e]) = (pi\<bullet>M)[(pi\<bullet>d)\<turnstile>c>(pi\<bullet>e)]"
131apply(nominal_induct M avoiding: d e rule: trm.strong_induct)
132apply(auto simp add: fresh_bij eq_bij)
133done
134
135lemma nrename_name_eqvt[eqvt]:
136  fixes pi::"name prm"
137  shows "pi\<bullet>(M[x\<turnstile>n>y]) = (pi\<bullet>M)[(pi\<bullet>x)\<turnstile>n>(pi\<bullet>y)]"
138apply(nominal_induct M avoiding: x y rule: trm.strong_induct)
139apply(auto simp add: fresh_bij eq_bij)
140done
141
142lemma nrename_coname_eqvt[eqvt]:
143  fixes pi::"coname prm"
144  shows "pi\<bullet>(M[x\<turnstile>n>y]) = (pi\<bullet>M)[(pi\<bullet>x)\<turnstile>n>(pi\<bullet>y)]"
145apply(nominal_induct M avoiding: x y rule: trm.strong_induct)
146apply(auto simp add: fresh_bij eq_bij)
147done
148
149lemmas rename_eqvts = crename_name_eqvt crename_coname_eqvt
150                      nrename_name_eqvt nrename_coname_eqvt
151lemma nrename_fresh:
152  assumes a: "x\<sharp>M"
153  shows "M[x\<turnstile>n>y] = M"
154using a
155by (nominal_induct M avoiding: x y rule: trm.strong_induct)
156   (auto simp add: trm.inject fresh_atm abs_fresh fin_supp abs_supp)
157
158lemma crename_fresh:
159  assumes a: "a\<sharp>M"
160  shows "M[a\<turnstile>c>b] = M"
161using a
162by (nominal_induct M avoiding: a b rule: trm.strong_induct)
163   (auto simp add: trm.inject fresh_atm abs_fresh)
164
165lemma nrename_nfresh:
166  fixes x::"name"
167  shows "x\<sharp>y\<Longrightarrow>x\<sharp>M[x\<turnstile>n>y]"
168by (nominal_induct M avoiding: x y rule: trm.strong_induct)
169   (auto simp add: fresh_atm abs_fresh abs_supp fin_supp)
170
171 lemma crename_nfresh:
172  fixes x::"name"
173  shows "x\<sharp>M\<Longrightarrow>x\<sharp>M[a\<turnstile>c>b]"
174by (nominal_induct M avoiding: a b rule: trm.strong_induct)
175   (auto simp add: fresh_atm abs_fresh abs_supp fin_supp)
176
177lemma crename_cfresh:
178  fixes a::"coname"
179  shows "a\<sharp>b\<Longrightarrow>a\<sharp>M[a\<turnstile>c>b]"
180by (nominal_induct M avoiding: a b rule: trm.strong_induct)
181   (auto simp add: fresh_atm abs_fresh abs_supp fin_supp)
182
183lemma nrename_cfresh:
184  fixes c::"coname"
185  shows "c\<sharp>M\<Longrightarrow>c\<sharp>M[x\<turnstile>n>y]"
186by (nominal_induct M avoiding: x y rule: trm.strong_induct)
187   (auto simp add: fresh_atm abs_fresh abs_supp fin_supp)
188
189lemma nrename_nfresh':
190  fixes x::"name"
191  shows "x\<sharp>(M,z,y)\<Longrightarrow>x\<sharp>M[z\<turnstile>n>y]"
192by (nominal_induct M avoiding: x z y rule: trm.strong_induct)
193   (auto simp add: fresh_prod fresh_atm abs_fresh abs_supp fin_supp)
194
195lemma crename_cfresh':
196  fixes a::"coname"
197  shows "a\<sharp>(M,b,c)\<Longrightarrow>a\<sharp>M[b\<turnstile>c>c]"
198by (nominal_induct M avoiding: a b c rule: trm.strong_induct)
199   (auto simp add: fresh_prod fresh_atm abs_fresh abs_supp fin_supp)
200
201lemma nrename_rename:
202  assumes a: "x'\<sharp>M"
203  shows "([(x',x)]\<bullet>M)[x'\<turnstile>n>y]= M[x\<turnstile>n>y]"
204using a
205apply(nominal_induct M avoiding: x x' y rule: trm.strong_induct)
206apply(auto simp add: abs_fresh fresh_bij fresh_atm fresh_prod fresh_right calc_atm abs_supp fin_supp)
207apply(auto simp add: fresh_left calc_atm fresh_prod fresh_atm)
208done
209
210lemma crename_rename:
211  assumes a: "a'\<sharp>M"
212  shows "([(a',a)]\<bullet>M)[a'\<turnstile>c>b]= M[a\<turnstile>c>b]"
213using a
214apply(nominal_induct M avoiding: a a' b rule: trm.strong_induct)
215apply(auto simp add: abs_fresh fresh_bij fresh_atm fresh_prod fresh_right calc_atm abs_supp fin_supp)
216apply(auto simp add: fresh_left calc_atm fresh_prod fresh_atm)
217done
218
219lemmas rename_fresh = nrename_fresh crename_fresh 
220                      nrename_nfresh crename_nfresh crename_cfresh nrename_cfresh
221                      nrename_nfresh' crename_cfresh'
222                      nrename_rename crename_rename
223
224lemma better_nrename_Cut:
225  assumes a: "x\<sharp>(u,v)"
226  shows "(Cut <a>.M (x).N)[u\<turnstile>n>v] = Cut <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v])"
227proof -
228  obtain x'::"name"   where fs1: "x'\<sharp>(M,N,a,x,u,v)" by (rule exists_fresh(1), rule fin_supp, blast)
229  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,a,x,u,v)" by (rule exists_fresh(2), rule fin_supp, blast)
230  have eq1: "(Cut <a>.M (x).N) = (Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N))"
231    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
232  have "(Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N))[u\<turnstile>n>v] = 
233                        Cut <a'>.(([(a',a)]\<bullet>M)[u\<turnstile>n>v]) (x').(([(x',x)]\<bullet>N)[u\<turnstile>n>v])"
234    using fs1 fs2
235    apply -
236    apply(rule nrename.simps)
237    apply(simp add: fresh_left calc_atm)
238    apply(simp add: fresh_left calc_atm)
239    done
240  also have "\<dots> = Cut <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v])" using fs1 fs2 a
241    apply -
242    apply(simp add: trm.inject alpha fresh_atm fresh_prod rename_eqvts)
243    apply(simp add: calc_atm)
244    apply(simp add: rename_fresh fresh_atm)
245    done
246  finally show "(Cut <a>.M (x).N)[u\<turnstile>n>v] = Cut <a>.(M[u\<turnstile>n>v]) (x).(N[u\<turnstile>n>v])" using eq1
247    by simp
248qed
249
250lemma better_crename_Cut:
251  assumes a: "a\<sharp>(b,c)"
252  shows "(Cut <a>.M (x).N)[b\<turnstile>c>c] = Cut <a>.(M[b\<turnstile>c>c]) (x).(N[b\<turnstile>c>c])"
253proof -
254  obtain x'::"name"   where fs1: "x'\<sharp>(M,N,a,x,b,c)" by (rule exists_fresh(1), rule fin_supp, blast)
255  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,a,x,b,c)" by (rule exists_fresh(2), rule fin_supp, blast)
256  have eq1: "(Cut <a>.M (x).N) = (Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N))"
257    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
258  have "(Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N))[b\<turnstile>c>c] = 
259                        Cut <a'>.(([(a',a)]\<bullet>M)[b\<turnstile>c>c]) (x').(([(x',x)]\<bullet>N)[b\<turnstile>c>c])"
260    using fs1 fs2
261    apply -
262    apply(rule crename.simps)
263    apply(simp add: fresh_left calc_atm)
264    apply(simp add: fresh_left calc_atm)
265    done
266  also have "\<dots> = Cut <a>.(M[b\<turnstile>c>c]) (x).(N[b\<turnstile>c>c])" using fs1 fs2 a
267    apply -
268    apply(simp add: trm.inject alpha fresh_atm fresh_prod rename_eqvts)
269    apply(simp add: calc_atm)
270    apply(simp add: rename_fresh fresh_atm)
271    done
272  finally show "(Cut <a>.M (x).N)[b\<turnstile>c>c] = Cut <a>.(M[b\<turnstile>c>c]) (x).(N[b\<turnstile>c>c])" using eq1
273    by simp
274qed
275
276lemma crename_id:
277  shows "M[a\<turnstile>c>a] = M"
278by (nominal_induct M avoiding: a rule: trm.strong_induct) (auto)
279
280lemma nrename_id:
281  shows "M[x\<turnstile>n>x] = M"
282by (nominal_induct M avoiding: x rule: trm.strong_induct) (auto)
283
284lemma nrename_swap:
285  shows "x\<sharp>M \<Longrightarrow> [(x,y)]\<bullet>M = M[y\<turnstile>n>x]"
286by (nominal_induct M avoiding: x y rule: trm.strong_induct) 
287   (simp_all add: calc_atm fresh_atm trm.inject alpha abs_fresh abs_supp fin_supp)
288
289lemma crename_swap:
290  shows "a\<sharp>M \<Longrightarrow> [(a,b)]\<bullet>M = M[b\<turnstile>c>a]"
291by (nominal_induct M avoiding: a b rule: trm.strong_induct) 
292   (simp_all add: calc_atm fresh_atm trm.inject alpha abs_fresh abs_supp fin_supp)
293
294lemma crename_ax:
295  assumes a: "M[a\<turnstile>c>b] = Ax x c" "c\<noteq>a" "c\<noteq>b"
296  shows "M = Ax x c"
297using a
298apply(nominal_induct M avoiding: a b x c rule: trm.strong_induct)
299apply(simp_all add: trm.inject split: if_splits)
300done
301
302lemma nrename_ax:
303  assumes a: "M[x\<turnstile>n>y] = Ax z a" "z\<noteq>x" "z\<noteq>y"
304  shows "M = Ax z a"
305using a
306apply(nominal_induct M avoiding: x y z a rule: trm.strong_induct)
307apply(simp_all add: trm.inject split: if_splits)
308done
309
310text \<open>substitution functions\<close>
311
312lemma fresh_perm_coname:
313  fixes c::"coname"
314  and   pi::"coname prm"
315  and   M::"trm"
316  assumes a: "c\<sharp>pi" "c\<sharp>M"
317  shows "c\<sharp>(pi\<bullet>M)"
318using a
319apply -
320apply(simp add: fresh_left)
321apply(simp add: at_prm_fresh[OF at_coname_inst] fresh_list_rev)
322done
323
324lemma fresh_perm_name:
325  fixes x::"name"
326  and   pi::"name prm"
327  and   M::"trm"
328  assumes a: "x\<sharp>pi" "x\<sharp>M"
329  shows "x\<sharp>(pi\<bullet>M)"
330using a
331apply -
332apply(simp add: fresh_left)
333apply(simp add: at_prm_fresh[OF at_name_inst] fresh_list_rev)
334done
335
336lemma fresh_fun_simp_NotL:
337  assumes a: "x'\<sharp>P" "x'\<sharp>M"
338  shows "fresh_fun (\<lambda>x'. Cut <c>.P (x').NotL <a>.M x') = Cut <c>.P (x').NotL <a>.M x'"
339using a
340apply -
341apply(rule fresh_fun_app)
342apply(rule pt_name_inst)
343apply(rule at_name_inst)
344apply(finite_guess)
345apply(subgoal_tac "\<exists>n::name. n\<sharp>(c,P,a,M)")
346apply(erule exE)
347apply(rule_tac x="n" in exI)
348apply(simp add: fresh_prod abs_fresh)
349apply(fresh_guess)
350apply(rule exists_fresh')
351apply(simp add: fin_supp)
352apply(fresh_guess)
353done
354
355lemma fresh_fun_NotL[eqvt_force]:
356  fixes pi1::"name prm"
357  and   pi2::"coname prm"
358  shows "pi1\<bullet>fresh_fun (\<lambda>x'. Cut <c>.P (x').NotL <a>.M x')=
359             fresh_fun (pi1\<bullet>(\<lambda>x'. Cut <c>.P (x').NotL <a>.M x'))"
360  and   "pi2\<bullet>fresh_fun (\<lambda>x'. Cut <c>.P (x').NotL <a>.M x')=
361             fresh_fun (pi2\<bullet>(\<lambda>x'. Cut <c>.P (x').NotL <a>.M x'))"
362apply -
363apply(perm_simp)
364apply(generate_fresh "name")
365apply(auto simp add: fresh_prod)
366apply(simp add: fresh_fun_simp_NotL)
367apply(rule sym)
368apply(rule trans)
369apply(rule fresh_fun_simp_NotL)
370apply(rule fresh_perm_name)
371apply(assumption)
372apply(assumption)
373apply(rule fresh_perm_name)
374apply(assumption)
375apply(assumption)
376apply(simp add: at_prm_fresh[OF at_name_inst] swap_simps)
377apply(perm_simp)
378apply(subgoal_tac "\<exists>n::name. n\<sharp>(P,M,pi2\<bullet>P,pi2\<bullet>M,pi2)")
379apply(simp add: fresh_prod)
380apply(auto)
381apply(simp add: fresh_fun_simp_NotL calc_atm)
382apply(rule exists_fresh')
383apply(simp add: fin_supp)
384done
385
386lemma fresh_fun_simp_AndL1:
387  assumes a: "z'\<sharp>P" "z'\<sharp>M" "z'\<sharp>x"
388  shows "fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL1 (x).M z') = Cut <c>.P (z').AndL1 (x).M z'"
389using a
390apply -
391apply(rule fresh_fun_app)
392apply(rule pt_name_inst)
393apply(rule at_name_inst)
394apply(finite_guess)
395apply(subgoal_tac "\<exists>n::name. n\<sharp>(c,P,x,M)")
396apply(erule exE)
397apply(rule_tac x="n" in exI)
398apply(simp add: fresh_prod abs_fresh)
399apply(fresh_guess)
400apply(rule exists_fresh')
401apply(simp add: fin_supp)
402apply(fresh_guess)
403done
404
405lemma fresh_fun_AndL1[eqvt_force]:
406  fixes pi1::"name prm"
407  and   pi2::"coname prm"
408  shows "pi1\<bullet>fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL1 (x).M z')=
409             fresh_fun (pi1\<bullet>(\<lambda>z'. Cut <c>.P (z').AndL1 (x).M z'))"
410  and   "pi2\<bullet>fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL1 (x).M z')=
411             fresh_fun (pi2\<bullet>(\<lambda>z'. Cut <c>.P (z').AndL1 (x).M z'))"
412apply -
413apply(perm_simp)
414apply(subgoal_tac "\<exists>n::name. n\<sharp>(P,M,x,pi1\<bullet>P,pi1\<bullet>M,pi1\<bullet>x,pi1)")
415apply(simp add: fresh_prod)
416apply(auto)
417apply(simp add: fresh_fun_simp_AndL1 at_prm_fresh[OF at_name_inst] swap_simps)
418apply(rule exists_fresh')
419apply(simp add: fin_supp)
420apply(perm_simp)
421apply(subgoal_tac "\<exists>n::name. n\<sharp>(P,M,x,pi2\<bullet>P,pi2\<bullet>M,pi2\<bullet>x,pi2)")
422apply(simp add: fresh_prod)
423apply(auto)
424apply(simp add: fresh_fun_simp_AndL1 calc_atm)
425apply(rule exists_fresh')
426apply(simp add: fin_supp)
427done
428
429lemma fresh_fun_simp_AndL2:
430  assumes a: "z'\<sharp>P" "z'\<sharp>M" "z'\<sharp>x"
431  shows "fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL2 (x).M z') = Cut <c>.P (z').AndL2 (x).M z'"
432using a
433apply -
434apply(rule fresh_fun_app)
435apply(rule pt_name_inst)
436apply(rule at_name_inst)
437apply(finite_guess)
438apply(subgoal_tac "\<exists>n::name. n\<sharp>(c,P,x,M)")
439apply(erule exE)
440apply(rule_tac x="n" in exI)
441apply(simp add: fresh_prod abs_fresh)
442apply(fresh_guess)
443apply(rule exists_fresh')
444apply(simp add: fin_supp)
445apply(fresh_guess)
446done
447
448lemma fresh_fun_AndL2[eqvt_force]:
449  fixes pi1::"name prm"
450  and   pi2::"coname prm"
451  shows "pi1\<bullet>fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL2 (x).M z')=
452             fresh_fun (pi1\<bullet>(\<lambda>z'. Cut <c>.P (z').AndL2 (x).M z'))"
453  and   "pi2\<bullet>fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL2 (x).M z')=
454             fresh_fun (pi2\<bullet>(\<lambda>z'. Cut <c>.P (z').AndL2 (x).M z'))"
455apply -
456apply(perm_simp)
457apply(subgoal_tac "\<exists>n::name. n\<sharp>(P,M,x,pi1\<bullet>P,pi1\<bullet>M,pi1\<bullet>x,pi1)")
458apply(simp add: fresh_prod)
459apply(auto)
460apply(simp add: fresh_fun_simp_AndL2 at_prm_fresh[OF at_name_inst] swap_simps)
461apply(rule exists_fresh')
462apply(simp add: fin_supp)
463apply(perm_simp)
464apply(subgoal_tac "\<exists>n::name. n\<sharp>(P,M,x,pi2\<bullet>P,pi2\<bullet>M,pi2\<bullet>x,pi2)")
465apply(simp add: fresh_prod)
466apply(auto)
467apply(simp add: fresh_fun_simp_AndL2 calc_atm)
468apply(rule exists_fresh')
469apply(simp add: fin_supp)
470done
471
472lemma fresh_fun_simp_OrL:
473  assumes a: "z'\<sharp>P" "z'\<sharp>M" "z'\<sharp>N" "z'\<sharp>u" "z'\<sharp>x"
474  shows "fresh_fun (\<lambda>z'. Cut <c>.P (z').OrL (x).M (u).N z') = Cut <c>.P (z').OrL (x).M (u).N z'"
475using a
476apply -
477apply(rule fresh_fun_app)
478apply(rule pt_name_inst)
479apply(rule at_name_inst)
480apply(finite_guess)
481apply(subgoal_tac "\<exists>n::name. n\<sharp>(c,P,x,M,u,N)")
482apply(erule exE)
483apply(rule_tac x="n" in exI)
484apply(simp add: fresh_prod abs_fresh)
485apply(fresh_guess)
486apply(rule exists_fresh')
487apply(simp add: fin_supp)
488apply(fresh_guess)
489done
490
491lemma fresh_fun_OrL[eqvt_force]:
492  fixes pi1::"name prm"
493  and   pi2::"coname prm"
494  shows "pi1\<bullet>fresh_fun (\<lambda>z'. Cut <c>.P (z').OrL (x).M (u).N z')=
495             fresh_fun (pi1\<bullet>(\<lambda>z'. Cut <c>.P (z').OrL (x).M (u).N z'))"
496  and   "pi2\<bullet>fresh_fun (\<lambda>z'. Cut <c>.P (z').OrL (x).M (u).N z')=
497             fresh_fun (pi2\<bullet>(\<lambda>z'. Cut <c>.P (z').OrL (x).M (u).N z'))"
498apply -
499apply(perm_simp)
500apply(subgoal_tac "\<exists>n::name. n\<sharp>(P,M,N,x,u,pi1\<bullet>P,pi1\<bullet>M,pi1\<bullet>N,pi1\<bullet>x,pi1\<bullet>u,pi1)")
501apply(simp add: fresh_prod)
502apply(auto)
503apply(simp add: fresh_fun_simp_OrL at_prm_fresh[OF at_name_inst] swap_simps)
504apply(rule exists_fresh')
505apply(simp add: fin_supp)
506apply(perm_simp)
507apply(subgoal_tac "\<exists>n::name. n\<sharp>(P,M,N,x,u,pi2\<bullet>P,pi2\<bullet>M,pi2\<bullet>N,pi2\<bullet>x,pi2\<bullet>u,pi2)")
508apply(simp add: fresh_prod)
509apply(auto)
510apply(simp add: fresh_fun_simp_OrL calc_atm)
511apply(rule exists_fresh')
512apply(simp add: fin_supp)
513done
514
515lemma fresh_fun_simp_ImpL:
516  assumes a: "z'\<sharp>P" "z'\<sharp>M" "z'\<sharp>N" "z'\<sharp>x"
517  shows "fresh_fun (\<lambda>z'. Cut <c>.P (z').ImpL <a>.M (x).N z') = Cut <c>.P (z').ImpL <a>.M (x).N z'"
518using a
519apply -
520apply(rule fresh_fun_app)
521apply(rule pt_name_inst)
522apply(rule at_name_inst)
523apply(finite_guess)
524apply(subgoal_tac "\<exists>n::name. n\<sharp>(c,P,x,M,N)")
525apply(erule exE)
526apply(rule_tac x="n" in exI)
527apply(simp add: fresh_prod abs_fresh)
528apply(fresh_guess)
529apply(rule exists_fresh')
530apply(simp add: fin_supp)
531apply(fresh_guess)
532done
533
534lemma fresh_fun_ImpL[eqvt_force]:
535  fixes pi1::"name prm"
536  and   pi2::"coname prm"
537  shows "pi1\<bullet>fresh_fun (\<lambda>z'. Cut <c>.P (z').ImpL <a>.M (x).N z')=
538             fresh_fun (pi1\<bullet>(\<lambda>z'. Cut <c>.P (z').ImpL <a>.M (x).N z'))"
539  and   "pi2\<bullet>fresh_fun (\<lambda>z'. Cut <c>.P (z').ImpL <a>.M (x).N z')=
540             fresh_fun (pi2\<bullet>(\<lambda>z'. Cut <c>.P (z').ImpL <a>.M (x).N z'))"
541apply -
542apply(perm_simp)
543apply(subgoal_tac "\<exists>n::name. n\<sharp>(P,M,N,x,pi1\<bullet>P,pi1\<bullet>M,pi1\<bullet>N,pi1\<bullet>x,pi1)")
544apply(simp add: fresh_prod)
545apply(auto)
546apply(simp add: fresh_fun_simp_ImpL at_prm_fresh[OF at_name_inst] swap_simps)
547apply(rule exists_fresh')
548apply(simp add: fin_supp)
549apply(perm_simp)
550apply(subgoal_tac "\<exists>n::name. n\<sharp>(P,M,N,x,pi2\<bullet>P,pi2\<bullet>M,pi2\<bullet>N,pi2\<bullet>x,pi2)")
551apply(simp add: fresh_prod)
552apply(auto)
553apply(simp add: fresh_fun_simp_ImpL calc_atm)
554apply(rule exists_fresh')
555apply(simp add: fin_supp)
556done
557
558lemma fresh_fun_simp_NotR:
559  assumes a: "a'\<sharp>P" "a'\<sharp>M"
560  shows "fresh_fun (\<lambda>a'. Cut <a'>.(NotR (y).M a') (x).P) = Cut <a'>.(NotR (y).M a') (x).P"
561using a
562apply -
563apply(rule fresh_fun_app)
564apply(rule pt_coname_inst)
565apply(rule at_coname_inst)
566apply(finite_guess)
567apply(subgoal_tac "\<exists>n::coname. n\<sharp>(x,P,y,M)")
568apply(erule exE)
569apply(rule_tac x="n" in exI)
570apply(simp add: fresh_prod abs_fresh)
571apply(fresh_guess)
572apply(rule exists_fresh')
573apply(simp add: fin_supp)
574apply(fresh_guess)
575done
576
577lemma fresh_fun_NotR[eqvt_force]:
578  fixes pi1::"name prm"
579  and   pi2::"coname prm"
580  shows "pi1\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(NotR (y).M a') (x).P)=
581             fresh_fun (pi1\<bullet>(\<lambda>a'. Cut <a'>.(NotR (y).M a') (x).P))"
582  and   "pi2\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(NotR (y).M a') (x).P)=
583             fresh_fun (pi2\<bullet>(\<lambda>a'. Cut <a'>.(NotR (y).M a') (x).P))"
584apply -
585apply(perm_simp)
586apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,pi1\<bullet>P,pi1\<bullet>M,pi1)")
587apply(simp add: fresh_prod)
588apply(auto)
589apply(simp add: fresh_fun_simp_NotR calc_atm)
590apply(rule exists_fresh')
591apply(simp add: fin_supp)
592apply(perm_simp)
593apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,pi2\<bullet>P,pi2\<bullet>M,pi2)")
594apply(simp add: fresh_prod)
595apply(auto)
596apply(simp add: fresh_fun_simp_NotR at_prm_fresh[OF at_coname_inst] swap_simps)
597apply(rule exists_fresh')
598apply(simp add: fin_supp)
599done
600
601lemma fresh_fun_simp_AndR:
602  assumes a: "a'\<sharp>P" "a'\<sharp>M" "a'\<sharp>N" "a'\<sharp>b" "a'\<sharp>c"
603  shows "fresh_fun (\<lambda>a'. Cut <a'>.(AndR <b>.M <c>.N a') (x).P) = Cut <a'>.(AndR <b>.M <c>.N a') (x).P"
604using a
605apply -
606apply(rule fresh_fun_app)
607apply(rule pt_coname_inst)
608apply(rule at_coname_inst)
609apply(finite_guess)
610apply(subgoal_tac "\<exists>n::coname. n\<sharp>(x,P,b,M,c,N)")
611apply(erule exE)
612apply(rule_tac x="n" in exI)
613apply(simp add: fresh_prod abs_fresh)
614apply(fresh_guess)
615apply(rule exists_fresh')
616apply(simp add: fin_supp)
617apply(fresh_guess)
618done
619
620lemma fresh_fun_AndR[eqvt_force]:
621  fixes pi1::"name prm"
622  and   pi2::"coname prm"
623  shows "pi1\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(AndR <b>.M <c>.N a') (x).P)=
624             fresh_fun (pi1\<bullet>(\<lambda>a'. Cut <a'>.(AndR <b>.M <c>.N a') (x).P))"
625  and   "pi2\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(AndR <b>.M <c>.N a') (x).P)=
626             fresh_fun (pi2\<bullet>(\<lambda>a'. Cut <a'>.(AndR <b>.M <c>.N a') (x).P))"
627apply -
628apply(perm_simp)
629apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,N,b,c,pi1\<bullet>P,pi1\<bullet>M,pi1\<bullet>N,pi1\<bullet>b,pi1\<bullet>c,pi1)")
630apply(simp add: fresh_prod)
631apply(auto)
632apply(simp add: fresh_fun_simp_AndR calc_atm)
633apply(rule exists_fresh')
634apply(simp add: fin_supp)
635apply(perm_simp)
636apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,N,b,c,pi2\<bullet>P,pi2\<bullet>M,pi2\<bullet>N,pi2\<bullet>b,pi2\<bullet>c,pi2)")
637apply(simp add: fresh_prod)
638apply(auto)
639apply(simp add: fresh_fun_simp_AndR at_prm_fresh[OF at_coname_inst] swap_simps)
640apply(rule exists_fresh')
641apply(simp add: fin_supp)
642done
643
644lemma fresh_fun_simp_OrR1:
645  assumes a: "a'\<sharp>P" "a'\<sharp>M" "a'\<sharp>b" 
646  shows "fresh_fun (\<lambda>a'. Cut <a'>.(OrR1 <b>.M a') (x).P) = Cut <a'>.(OrR1 <b>.M a') (x).P"
647using a
648apply -
649apply(rule fresh_fun_app)
650apply(rule pt_coname_inst)
651apply(rule at_coname_inst)
652apply(finite_guess)
653apply(subgoal_tac "\<exists>n::coname. n\<sharp>(x,P,b,M)")
654apply(erule exE)
655apply(rule_tac x="n" in exI)
656apply(simp add: fresh_prod abs_fresh)
657apply(fresh_guess)
658apply(rule exists_fresh')
659apply(simp add: fin_supp)
660apply(fresh_guess)
661done
662
663lemma fresh_fun_OrR1[eqvt_force]:
664  fixes pi1::"name prm"
665  and   pi2::"coname prm"
666  shows "pi1\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(OrR1 <b>.M a') (x).P)=
667             fresh_fun (pi1\<bullet>(\<lambda>a'. Cut <a'>.(OrR1 <b>.M  a') (x).P))"
668  and   "pi2\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(OrR1 <b>.M a') (x).P)=
669             fresh_fun (pi2\<bullet>(\<lambda>a'. Cut <a'>.(OrR1 <b>.M a') (x).P))"
670apply -
671apply(perm_simp)
672apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,b,pi1\<bullet>P,pi1\<bullet>M,pi1\<bullet>b,pi1)")
673apply(simp add: fresh_prod)
674apply(auto)
675apply(simp add: fresh_fun_simp_OrR1 calc_atm)
676apply(rule exists_fresh')
677apply(simp add: fin_supp)
678apply(perm_simp)
679apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,b,pi2\<bullet>P,pi2\<bullet>M,pi2\<bullet>b,pi2)")
680apply(simp add: fresh_prod)
681apply(auto)
682apply(simp add: fresh_fun_simp_OrR1 at_prm_fresh[OF at_coname_inst] swap_simps)
683apply(rule exists_fresh')
684apply(simp add: fin_supp)
685done
686
687lemma fresh_fun_simp_OrR2:
688  assumes a: "a'\<sharp>P" "a'\<sharp>M" "a'\<sharp>b" 
689  shows "fresh_fun (\<lambda>a'. Cut <a'>.(OrR2 <b>.M a') (x).P) = Cut <a'>.(OrR2 <b>.M a') (x).P"
690using a
691apply -
692apply(rule fresh_fun_app)
693apply(rule pt_coname_inst)
694apply(rule at_coname_inst)
695apply(finite_guess)
696apply(subgoal_tac "\<exists>n::coname. n\<sharp>(x,P,b,M)")
697apply(erule exE)
698apply(rule_tac x="n" in exI)
699apply(simp add: fresh_prod abs_fresh)
700apply(fresh_guess)
701apply(rule exists_fresh')
702apply(simp add: fin_supp)
703apply(fresh_guess)
704done
705
706lemma fresh_fun_OrR2[eqvt_force]:
707  fixes pi1::"name prm"
708  and   pi2::"coname prm"
709  shows "pi1\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(OrR2 <b>.M a') (x).P)=
710             fresh_fun (pi1\<bullet>(\<lambda>a'. Cut <a'>.(OrR2 <b>.M  a') (x).P))"
711  and   "pi2\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(OrR2 <b>.M a') (x).P)=
712             fresh_fun (pi2\<bullet>(\<lambda>a'. Cut <a'>.(OrR2 <b>.M a') (x).P))"
713apply -
714apply(perm_simp)
715apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,b,pi1\<bullet>P,pi1\<bullet>M,pi1\<bullet>b,pi1)")
716apply(simp add: fresh_prod)
717apply(auto)
718apply(simp add: fresh_fun_simp_OrR2 calc_atm)
719apply(rule exists_fresh')
720apply(simp add: fin_supp)
721apply(perm_simp)
722apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,b,pi2\<bullet>P,pi2\<bullet>M,pi2\<bullet>b,pi2)")
723apply(simp add: fresh_prod)
724apply(auto)
725apply(simp add: fresh_fun_simp_OrR2 at_prm_fresh[OF at_coname_inst] swap_simps)
726apply(rule exists_fresh')
727apply(simp add: fin_supp)
728done
729
730lemma fresh_fun_simp_ImpR:
731  assumes a: "a'\<sharp>P" "a'\<sharp>M" "a'\<sharp>b" 
732  shows "fresh_fun (\<lambda>a'. Cut <a'>.(ImpR (y).<b>.M a') (x).P) = Cut <a'>.(ImpR (y).<b>.M a') (x).P"
733using a
734apply -
735apply(rule fresh_fun_app)
736apply(rule pt_coname_inst)
737apply(rule at_coname_inst)
738apply(finite_guess)
739apply(subgoal_tac "\<exists>n::coname. n\<sharp>(x,P,y,b,M)")
740apply(erule exE)
741apply(rule_tac x="n" in exI)
742apply(simp add: fresh_prod abs_fresh)
743apply(fresh_guess)
744apply(rule exists_fresh')
745apply(simp add: fin_supp)
746apply(fresh_guess)
747done
748
749lemma fresh_fun_ImpR[eqvt_force]:
750  fixes pi1::"name prm"
751  and   pi2::"coname prm"
752  shows "pi1\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(ImpR (y).<b>.M a') (x).P)=
753             fresh_fun (pi1\<bullet>(\<lambda>a'. Cut <a'>.(ImpR (y).<b>.M  a') (x).P))"
754  and   "pi2\<bullet>fresh_fun (\<lambda>a'. Cut <a'>.(ImpR (y).<b>.M a') (x).P)=
755             fresh_fun (pi2\<bullet>(\<lambda>a'. Cut <a'>.(ImpR (y).<b>.M a') (x).P))"
756apply -
757apply(perm_simp)
758apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,b,pi1\<bullet>P,pi1\<bullet>M,pi1\<bullet>b,pi1)")
759apply(simp add: fresh_prod)
760apply(auto)
761apply(simp add: fresh_fun_simp_ImpR calc_atm)
762apply(rule exists_fresh')
763apply(simp add: fin_supp)
764apply(perm_simp)
765apply(subgoal_tac "\<exists>n::coname. n\<sharp>(P,M,b,pi2\<bullet>P,pi2\<bullet>M,pi2\<bullet>b,pi2)")
766apply(simp add: fresh_prod)
767apply(auto)
768apply(simp add: fresh_fun_simp_ImpR at_prm_fresh[OF at_coname_inst] swap_simps)
769apply(rule exists_fresh')
770apply(simp add: fin_supp)
771done
772
773nominal_primrec (freshness_context: "(y::name,c::coname,P::trm)")
774  substn :: "trm \<Rightarrow> name   \<Rightarrow> coname \<Rightarrow> trm \<Rightarrow> trm" ("_{_:=<_>._}" [100,100,100,100] 100) 
775where
776  "(Ax x a){y:=<c>.P} = (if x=y then Cut <c>.P (y).Ax y a else Ax x a)" 
777| "\<lbrakk>a\<sharp>(c,P,N);x\<sharp>(y,P,M)\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N){y:=<c>.P} = 
778  (if M=Ax y a then Cut <c>.P (x).(N{y:=<c>.P}) else Cut <a>.(M{y:=<c>.P}) (x).(N{y:=<c>.P}))" 
779| "x\<sharp>(y,P) \<Longrightarrow> (NotR (x).M a){y:=<c>.P} = NotR (x).(M{y:=<c>.P}) a" 
780| "a\<sharp>(c,P) \<Longrightarrow> (NotL <a>.M x){y:=<c>.P} = 
781  (if x=y then fresh_fun (\<lambda>x'. Cut <c>.P (x').NotL <a>.(M{y:=<c>.P}) x') else NotL <a>.(M{y:=<c>.P}) x)"
782| "\<lbrakk>a\<sharp>(c,P,N,d);b\<sharp>(c,P,M,d);b\<noteq>a\<rbrakk> \<Longrightarrow> 
783  (AndR <a>.M <b>.N d){y:=<c>.P} = AndR <a>.(M{y:=<c>.P}) <b>.(N{y:=<c>.P}) d" 
784| "x\<sharp>(y,P,z) \<Longrightarrow> (AndL1 (x).M z){y:=<c>.P} = 
785  (if z=y then fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL1 (x).(M{y:=<c>.P}) z') 
786   else AndL1 (x).(M{y:=<c>.P}) z)"
787| "x\<sharp>(y,P,z) \<Longrightarrow> (AndL2 (x).M z){y:=<c>.P} = 
788  (if z=y then fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL2 (x).(M{y:=<c>.P}) z') 
789   else AndL2 (x).(M{y:=<c>.P}) z)"
790| "a\<sharp>(c,P,b) \<Longrightarrow> (OrR1 <a>.M b){y:=<c>.P} = OrR1 <a>.(M{y:=<c>.P}) b"
791| "a\<sharp>(c,P,b) \<Longrightarrow> (OrR2 <a>.M b){y:=<c>.P} = OrR2 <a>.(M{y:=<c>.P}) b"
792| "\<lbrakk>x\<sharp>(y,N,P,z);u\<sharp>(y,M,P,z);x\<noteq>u\<rbrakk> \<Longrightarrow> (OrL (x).M (u).N z){y:=<c>.P} = 
793  (if z=y then fresh_fun (\<lambda>z'. Cut <c>.P (z').OrL (x).(M{y:=<c>.P}) (u).(N{y:=<c>.P}) z') 
794   else OrL (x).(M{y:=<c>.P}) (u).(N{y:=<c>.P}) z)"
795| "\<lbrakk>a\<sharp>(b,c,P); x\<sharp>(y,P)\<rbrakk> \<Longrightarrow> (ImpR (x).<a>.M b){y:=<c>.P} = ImpR (x).<a>.(M{y:=<c>.P}) b"
796| "\<lbrakk>a\<sharp>(N,c,P);x\<sharp>(y,P,M,z)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N z){y:=<c>.P} = 
797  (if y=z then fresh_fun (\<lambda>z'. Cut <c>.P (z').ImpL <a>.(M{y:=<c>.P}) (x).(N{y:=<c>.P}) z') 
798   else ImpL <a>.(M{y:=<c>.P}) (x).(N{y:=<c>.P}) z)"
799apply(finite_guess)+
800apply(rule TrueI)+
801apply(simp add: abs_fresh abs_supp)+
802apply(rule impI)
803apply(subgoal_tac "\<exists>x::name. x\<sharp>(x1,P,y1)", erule exE, simp add: fresh_prod)
804apply(erule conjE)+
805apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
806apply(rule exists_fresh', simp add: fin_supp)
807apply(simp add: abs_fresh abs_supp)+
808apply(rule impI)
809apply(subgoal_tac "\<exists>x::name. x\<sharp>(x1,P,y1)", erule exE, simp add: fresh_prod)
810apply(erule conjE)+
811apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
812apply(rule exists_fresh', simp add: fin_supp)
813apply(simp add: abs_fresh abs_supp)+
814apply(rule impI)
815apply(subgoal_tac "\<exists>x::name. x\<sharp>(x1,P,y1)", erule exE, simp add: fresh_prod)
816apply(erule conjE)+
817apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
818apply(rule exists_fresh', simp add: fin_supp)
819apply(simp add: abs_fresh abs_supp)+
820apply(rule impI)
821apply(subgoal_tac "\<exists>x::name. x\<sharp>(x1,P,y1,x3,y2)", erule exE, simp add: fresh_prod)
822apply(erule conjE)+
823apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
824apply(rule exists_fresh', simp add: fin_supp)
825apply(simp add: abs_fresh abs_supp)+
826apply(rule impI)
827apply(subgoal_tac "\<exists>x::name. x\<sharp>(x1,P,y1,x3,y2)", erule exE, simp add: fresh_prod)
828apply(erule conjE)+
829apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
830apply(rule exists_fresh', simp add: fin_supp)
831apply(simp add: abs_fresh abs_supp)+
832apply(rule impI)
833apply(subgoal_tac "\<exists>x::name. x\<sharp>(x3,P,y1,y2)", erule exE, simp add: fresh_prod)
834apply(erule conjE)+
835apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
836apply(rule exists_fresh', simp add: fin_supp)
837apply(simp add: abs_fresh abs_supp)+
838apply(rule impI)
839apply(subgoal_tac "\<exists>x::name. x\<sharp>(x3,P,y1,y2)", erule exE, simp add: fresh_prod)
840apply(erule conjE)+
841apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
842apply(rule exists_fresh', simp add: fin_supp)
843apply(fresh_guess)+
844done
845
846nominal_primrec (freshness_context: "(d::name,z::coname,P::trm)")
847  substc :: "trm \<Rightarrow> coname \<Rightarrow> name   \<Rightarrow> trm \<Rightarrow> trm" ("_{_:=(_)._}" [100,100,100,100] 100)
848where
849  "(Ax x a){d:=(z).P} = (if d=a then Cut <a>.(Ax x a) (z).P else Ax x a)" 
850| "\<lbrakk>a\<sharp>(d,P,N);x\<sharp>(z,P,M)\<rbrakk> \<Longrightarrow> (Cut <a>.M (x).N){d:=(z).P} = 
851  (if N=Ax x d then Cut <a>.(M{d:=(z).P}) (z).P else Cut <a>.(M{d:=(z).P}) (x).(N{d:=(z).P}))" 
852| "x\<sharp>(z,P) \<Longrightarrow> (NotR (x).M a){d:=(z).P} = 
853  (if d=a then fresh_fun (\<lambda>a'. Cut <a'>.NotR (x).(M{d:=(z).P}) a' (z).P) else NotR (x).(M{d:=(z).P}) a)" 
854| "a\<sharp>(d,P) \<Longrightarrow> (NotL <a>.M x){d:=(z).P} = NotL <a>.(M{d:=(z).P}) x" 
855| "\<lbrakk>a\<sharp>(P,c,N,d);b\<sharp>(P,c,M,d);b\<noteq>a\<rbrakk> \<Longrightarrow> (AndR <a>.M <b>.N c){d:=(z).P} = 
856  (if d=c then fresh_fun (\<lambda>a'. Cut <a'>.(AndR <a>.(M{d:=(z).P}) <b>.(N{d:=(z).P}) a') (z).P)
857   else AndR <a>.(M{d:=(z).P}) <b>.(N{d:=(z).P}) c)" 
858| "x\<sharp>(y,z,P) \<Longrightarrow> (AndL1 (x).M y){d:=(z).P} = AndL1 (x).(M{d:=(z).P}) y"
859| "x\<sharp>(y,P,z) \<Longrightarrow> (AndL2 (x).M y){d:=(z).P} = AndL2 (x).(M{d:=(z).P}) y"
860| "a\<sharp>(d,P,b) \<Longrightarrow> (OrR1 <a>.M b){d:=(z).P} = 
861  (if d=b then fresh_fun (\<lambda>a'. Cut <a'>.OrR1 <a>.(M{d:=(z).P}) a' (z).P) else OrR1 <a>.(M{d:=(z).P}) b)"
862| "a\<sharp>(d,P,b) \<Longrightarrow> (OrR2 <a>.M b){d:=(z).P} = 
863  (if d=b then fresh_fun (\<lambda>a'. Cut <a'>.OrR2 <a>.(M{d:=(z).P}) a' (z).P) else OrR2 <a>.(M{d:=(z).P}) b)"
864| "\<lbrakk>x\<sharp>(N,z,P,u);y\<sharp>(M,z,P,u);x\<noteq>y\<rbrakk> \<Longrightarrow> (OrL (x).M (y).N u){d:=(z).P} = 
865  OrL (x).(M{d:=(z).P}) (y).(N{d:=(z).P}) u" 
866| "\<lbrakk>a\<sharp>(b,d,P); x\<sharp>(z,P)\<rbrakk> \<Longrightarrow> (ImpR (x).<a>.M b){d:=(z).P} = 
867  (if d=b then fresh_fun (\<lambda>a'. Cut <a'>.ImpR (x).<a>.(M{d:=(z).P}) a' (z).P) 
868   else ImpR (x).<a>.(M{d:=(z).P}) b)"
869| "\<lbrakk>a\<sharp>(N,d,P);x\<sharp>(y,z,P,M)\<rbrakk> \<Longrightarrow> (ImpL <a>.M (x).N y){d:=(z).P} = 
870  ImpL <a>.(M{d:=(z).P}) (x).(N{d:=(z).P}) y"
871apply(finite_guess)+
872apply(rule TrueI)+
873apply(simp add: abs_fresh abs_supp fs_name1 fs_coname1)+
874apply(rule impI)
875apply(subgoal_tac "\<exists>x::coname. x\<sharp>(x1,P,y1)", erule exE, simp add: fresh_prod)
876apply(erule conjE)+
877apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
878apply(rule exists_fresh', simp add: fin_supp)
879apply(simp add: abs_fresh abs_supp)+
880apply(rule impI)
881apply(subgoal_tac "\<exists>x::coname. x\<sharp>(x1,P,y1,x3,y2)", erule exE, simp add: fresh_prod)
882apply(erule conjE)+
883apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
884apply(rule exists_fresh', simp add: fin_supp)
885apply(simp add: abs_fresh abs_supp)+
886apply(rule impI)
887apply(subgoal_tac "\<exists>x::coname. x\<sharp>(x1,P,y1,x3,y2)", erule exE, simp add: fresh_prod)
888apply(erule conjE)+
889apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
890apply(rule exists_fresh', simp add: fin_supp)
891apply(simp add: abs_fresh abs_supp)+
892apply(rule impI)
893apply(subgoal_tac "\<exists>x::coname. x\<sharp>(x1,P,y1)", erule exE, simp add: fresh_prod)
894apply(erule conjE)+
895apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
896apply(rule exists_fresh', simp add: fin_supp)
897apply(simp add: abs_fresh abs_supp)+
898apply(rule impI)
899apply(subgoal_tac "\<exists>x::coname. x\<sharp>(x1,P,y1)", erule exE, simp add: fresh_prod)
900apply(erule conjE)+
901apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
902apply(rule exists_fresh', simp add: fin_supp)
903apply(simp add: abs_fresh abs_supp)+
904apply(rule impI)
905apply(subgoal_tac "\<exists>x::coname. x\<sharp>(x1,P,x2,y1)", erule exE, simp add: fresh_prod)
906apply(erule conjE)+
907apply(simp add: fresh_fun_simp_ImpR abs_fresh fresh_atm abs_supp)
908apply(rule exists_fresh', simp add: fin_supp)
909apply(simp add: abs_fresh abs_supp)+
910apply(rule impI)
911apply(subgoal_tac "\<exists>x::coname. x\<sharp>(x1,P,x2,y1)", erule exE, simp add: fresh_prod)
912apply(erule conjE)+
913apply(simp add: fresh_fun_simp_ImpR abs_fresh fresh_atm)
914apply(rule exists_fresh', simp add: fin_supp)
915apply(simp add: abs_fresh abs_supp)+
916apply(fresh_guess add: abs_fresh fresh_prod)+
917done
918
919lemma csubst_eqvt[eqvt]:
920  fixes pi1::"name prm"
921  and   pi2::"coname prm"
922  shows "pi1\<bullet>(M{c:=(x).N}) = (pi1\<bullet>M){(pi1\<bullet>c):=(pi1\<bullet>x).(pi1\<bullet>N)}"
923  and   "pi2\<bullet>(M{c:=(x).N}) = (pi2\<bullet>M){(pi2\<bullet>c):=(pi2\<bullet>x).(pi2\<bullet>N)}"
924apply(nominal_induct M avoiding: c x N rule: trm.strong_induct)
925apply(auto simp add: eq_bij fresh_bij eqvts)
926apply(perm_simp)+
927done
928
929lemma nsubst_eqvt[eqvt]:
930  fixes pi1::"name prm"
931  and   pi2::"coname prm"
932  shows "pi1\<bullet>(M{x:=<c>.N}) = (pi1\<bullet>M){(pi1\<bullet>x):=<(pi1\<bullet>c)>.(pi1\<bullet>N)}"
933  and   "pi2\<bullet>(M{x:=<c>.N}) = (pi2\<bullet>M){(pi2\<bullet>x):=<(pi2\<bullet>c)>.(pi2\<bullet>N)}"
934apply(nominal_induct M avoiding: c x N rule: trm.strong_induct)
935apply(auto simp add: eq_bij fresh_bij eqvts)
936apply(perm_simp)+
937done
938
939lemma supp_subst1:
940  shows "supp (M{y:=<c>.P}) \<subseteq> ((supp M) - {y}) \<union> (supp P)"
941apply(nominal_induct M avoiding: y P c rule: trm.strong_induct)
942apply(auto)
943apply(auto simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
944apply(blast)+
945apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P)")
946apply(erule exE)
947apply(simp add: fresh_prod)
948apply(erule conjE)+
949apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
950apply(simp add: fresh_def abs_supp trm.supp supp_atm)
951apply(blast)
952apply(rule exists_fresh'(1)[OF fs_name1])
953apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P)")
954apply(erule exE)
955apply(simp add: fresh_prod)
956apply(erule conjE)+
957apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
958apply(simp add: fresh_def abs_supp trm.supp supp_atm)
959apply(blast)
960apply(rule exists_fresh'(1)[OF fs_name1])
961apply(blast)+
962apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
963apply(erule exE)
964apply(simp add: fresh_prod)
965apply(erule conjE)+
966apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
967apply(simp add: fresh_def abs_supp trm.supp supp_atm)
968apply(blast)
969apply(rule exists_fresh'(1)[OF fs_name1])
970apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
971apply(erule exE)
972apply(simp add: fresh_prod)
973apply(erule conjE)+
974apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
975apply(simp add: fresh_def abs_supp trm.supp supp_atm)
976apply(rule exists_fresh'(1)[OF fs_name1])
977apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
978apply(erule exE)
979apply(simp add: fresh_prod)
980apply(erule conjE)+
981apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
982apply(simp add: fresh_def abs_supp trm.supp supp_atm)
983apply(blast)
984apply(rule exists_fresh'(1)[OF fs_name1])
985apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
986apply(erule exE)
987apply(simp add: fresh_prod)
988apply(erule conjE)+
989apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
990apply(simp add: fresh_def abs_supp trm.supp supp_atm)
991apply(blast)
992apply(rule exists_fresh'(1)[OF fs_name1])
993apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
994apply(erule exE)
995apply(simp add: fresh_prod)
996apply(erule conjE)+
997apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
998apply(simp add: fresh_def abs_supp trm.supp supp_atm)
999apply(rule exists_fresh'(1)[OF fs_name1])
1000apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
1001apply(erule exE)
1002apply(simp add: fresh_prod)
1003apply(erule conjE)+
1004apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
1005apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1006apply(blast)
1007apply(rule exists_fresh'(1)[OF fs_name1])
1008apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1009apply(erule exE)
1010apply(simp add: fresh_prod)
1011apply(erule conjE)+
1012apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1013apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1014apply(blast)
1015apply(rule exists_fresh'(1)[OF fs_name1])
1016apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1017apply(erule exE)
1018apply(simp add: fresh_prod)
1019apply(erule conjE)+
1020apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1021apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1022apply(blast)
1023apply(rule exists_fresh'(1)[OF fs_name1])
1024apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1025apply(erule exE)
1026apply(simp add: fresh_prod)
1027apply(erule conjE)+
1028apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1029apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1030apply(blast)
1031apply(rule exists_fresh'(1)[OF fs_name1])
1032apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1033apply(erule exE)
1034apply(simp add: fresh_prod)
1035apply(erule conjE)+
1036apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1037apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1038apply(blast)
1039apply(rule exists_fresh'(1)[OF fs_name1])
1040apply(blast)+
1041apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1042apply(erule exE)
1043apply(simp add: fresh_prod)
1044apply(erule conjE)+
1045apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1046apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1047apply(blast)
1048apply(rule exists_fresh'(1)[OF fs_name1])
1049apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1050apply(erule exE)
1051apply(simp add: fresh_prod)
1052apply(erule conjE)+
1053apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1054apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1055apply(blast)
1056apply(rule exists_fresh'(1)[OF fs_name1])
1057apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1058apply(erule exE)
1059apply(simp add: fresh_prod)
1060apply(erule conjE)+
1061apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1062apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1063apply(blast)
1064apply(rule exists_fresh'(1)[OF fs_name1])
1065apply(blast)+
1066done
1067
1068lemma supp_subst2:
1069  shows "supp (M{y:=<c>.P}) \<subseteq> supp (M) \<union> ((supp P) - {c})"
1070apply(nominal_induct M avoiding: y P c rule: trm.strong_induct)
1071apply(auto)
1072apply(auto simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1073apply(blast)+
1074apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P)")
1075apply(erule exE)
1076apply(simp add: fresh_prod)
1077apply(erule conjE)+
1078apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
1079apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1080apply(blast)
1081apply(rule exists_fresh'(1)[OF fs_name1])
1082apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P)")
1083apply(erule exE)
1084apply(simp add: fresh_prod)
1085apply(erule conjE)+
1086apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
1087apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1088apply(rule exists_fresh'(1)[OF fs_name1])
1089apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P)")
1090apply(erule exE)
1091apply(simp add: fresh_prod)
1092apply(erule conjE)+
1093apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
1094apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1095apply(blast)
1096apply(rule exists_fresh'(1)[OF fs_name1])
1097apply(blast)+
1098apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
1099apply(erule exE)
1100apply(simp add: fresh_prod)
1101apply(erule conjE)+
1102apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
1103apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1104apply(blast)
1105apply(rule exists_fresh'(1)[OF fs_name1])
1106apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
1107apply(erule exE)
1108apply(simp add: fresh_prod)
1109apply(erule conjE)+
1110apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
1111apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1112apply(blast)
1113apply(rule exists_fresh'(1)[OF fs_name1])
1114apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
1115apply(erule exE)
1116apply(simp add: fresh_prod)
1117apply(erule conjE)+
1118apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
1119apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1120apply(blast)
1121apply(rule exists_fresh'(1)[OF fs_name1])
1122apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
1123apply(erule exE)
1124apply(simp add: fresh_prod)
1125apply(erule conjE)+
1126apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
1127apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1128apply(blast)
1129apply(rule exists_fresh'(1)[OF fs_name1])
1130apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1131apply(erule exE)
1132apply(simp add: fresh_prod)
1133apply(erule conjE)+
1134apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1135apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1136apply(blast)
1137apply(rule exists_fresh'(1)[OF fs_name1])
1138apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1139apply(erule exE)
1140apply(simp add: fresh_prod)
1141apply(erule conjE)+
1142apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1143apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1144apply(blast)
1145apply(rule exists_fresh'(1)[OF fs_name1])
1146apply(blast)+
1147apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1148apply(erule exE)
1149apply(simp add: fresh_prod)
1150apply(erule conjE)+
1151apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1152apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1153apply(blast)
1154apply(rule exists_fresh'(1)[OF fs_name1])
1155apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1156apply(erule exE)
1157apply(simp add: fresh_prod)
1158apply(erule conjE)+
1159apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1160apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1161apply(blast)
1162apply(rule exists_fresh'(1)[OF fs_name1])
1163apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1164apply(erule exE)
1165apply(simp add: fresh_prod)
1166apply(erule conjE)+
1167apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1168apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1169apply(blast)
1170apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1171apply(erule exE)
1172apply(simp add: fresh_prod)
1173apply(erule conjE)+
1174apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1175apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1176apply(blast)
1177apply(rule exists_fresh'(1)[OF fs_name1])
1178apply(blast)+
1179done
1180
1181lemma supp_subst3:
1182  shows "supp (M{c:=(x).P}) \<subseteq> ((supp M) - {c}) \<union> (supp P)"
1183apply(nominal_induct M avoiding: x P c rule: trm.strong_induct)
1184apply(auto)
1185apply(auto simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1186apply(blast)+
1187apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname:=(x).P},P)")
1188apply(erule exE)
1189apply(simp add: fresh_prod)
1190apply(erule conjE)+
1191apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
1192apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1193apply(blast)
1194apply(rule exists_fresh'(2)[OF fs_coname1])
1195apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname:=(x).P},P)")
1196apply(erule exE)
1197apply(simp add: fresh_prod)
1198apply(erule conjE)+
1199apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
1200apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1201apply(blast)
1202apply(rule exists_fresh'(2)[OF fs_coname1])
1203apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1204apply(erule exE)
1205apply(simp add: fresh_prod)
1206apply(erule conjE)+
1207apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1208apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1209apply(blast)
1210apply(rule exists_fresh'(2)[OF fs_coname1])
1211apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1212apply(erule exE)
1213apply(simp add: fresh_prod)
1214apply(erule conjE)+
1215apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1216apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1217apply(blast)
1218apply(rule exists_fresh'(2)[OF fs_coname1])
1219apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1220apply(erule exE)
1221apply(simp add: fresh_prod)
1222apply(erule conjE)+
1223apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1224apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1225apply(blast)
1226apply(rule exists_fresh'(2)[OF fs_coname1])
1227apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1228apply(erule exE)
1229apply(simp add: fresh_prod)
1230apply(erule conjE)+
1231apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1232apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1233apply(blast)
1234apply(rule exists_fresh'(2)[OF fs_coname1])
1235apply(blast)+
1236apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1237apply(erule exE)
1238apply(simp add: fresh_prod)
1239apply(erule conjE)+
1240apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
1241apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1242apply(blast)
1243apply(rule exists_fresh'(2)[OF fs_coname1])
1244apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1245apply(erule exE)
1246apply(simp add: fresh_prod)
1247apply(erule conjE)+
1248apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
1249apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1250apply(rule exists_fresh'(2)[OF fs_coname1])
1251apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1252apply(erule exE)
1253apply(simp add: fresh_prod)
1254apply(erule conjE)+
1255apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
1256apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1257apply(blast)
1258apply(rule exists_fresh'(2)[OF fs_coname1])
1259apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1260apply(erule exE)
1261apply(simp add: fresh_prod)
1262apply(erule conjE)+
1263apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
1264apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1265apply(blast)
1266apply(rule exists_fresh'(2)[OF fs_coname1])
1267apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1268apply(erule exE)
1269apply(simp add: fresh_prod)
1270apply(erule conjE)+
1271apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
1272apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1273apply(rule exists_fresh'(2)[OF fs_coname1])
1274apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1275apply(erule exE)
1276apply(simp add: fresh_prod)
1277apply(erule conjE)+
1278apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
1279apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1280apply(blast)
1281apply(rule exists_fresh'(2)[OF fs_coname1])
1282apply(blast)+
1283apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1284apply(erule exE)
1285apply(simp add: fresh_prod)
1286apply(erule conjE)+
1287apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
1288apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1289apply(blast)
1290apply(rule exists_fresh'(2)[OF fs_coname1])
1291apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1292apply(erule exE)
1293apply(simp add: fresh_prod)
1294apply(erule conjE)+
1295apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
1296apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1297apply(rule exists_fresh'(2)[OF fs_coname1])
1298apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1299apply(erule exE)
1300apply(simp add: fresh_prod)
1301apply(erule conjE)+
1302apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
1303apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1304apply(blast)
1305apply(rule exists_fresh'(2)[OF fs_coname1])
1306apply(blast)+
1307done
1308
1309lemma supp_subst4:
1310  shows "supp (M{c:=(x).P}) \<subseteq> (supp M) \<union> ((supp P) - {x})"
1311apply(nominal_induct M avoiding: x P c rule: trm.strong_induct)
1312apply(auto)
1313apply(auto simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1314apply(blast)+
1315apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname:=(x).P},P)")
1316apply(erule exE)
1317apply(simp add: fresh_prod)
1318apply(erule conjE)+
1319apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
1320apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1321apply(blast)
1322apply(rule exists_fresh'(2)[OF fs_coname1])
1323apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname:=(x).P},P)")
1324apply(erule exE)
1325apply(simp add: fresh_prod)
1326apply(erule conjE)+
1327apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
1328apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1329apply(rule exists_fresh'(2)[OF fs_coname1])
1330apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname:=(x).P},P)")
1331apply(erule exE)
1332apply(simp add: fresh_prod)
1333apply(erule conjE)+
1334apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
1335apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1336apply(blast)
1337apply(rule exists_fresh'(2)[OF fs_coname1])
1338apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1339apply(erule exE)
1340apply(simp add: fresh_prod)
1341apply(erule conjE)+
1342apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1343apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1344apply(blast)
1345apply(rule exists_fresh'(2)[OF fs_coname1])
1346apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1347apply(erule exE)
1348apply(simp add: fresh_prod)
1349apply(erule conjE)+
1350apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1351apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1352apply(blast)
1353apply(rule exists_fresh'(2)[OF fs_coname1])
1354apply(blast)+
1355apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1356apply(erule exE)
1357apply(simp add: fresh_prod)
1358apply(erule conjE)+
1359apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
1360apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1361apply(blast)
1362apply(rule exists_fresh'(2)[OF fs_coname1])
1363apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1364apply(erule exE)
1365apply(simp add: fresh_prod)
1366apply(erule conjE)+
1367apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
1368apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1369apply(blast)
1370apply(rule exists_fresh'(2)[OF fs_coname1])
1371apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1372apply(erule exE)
1373apply(simp add: fresh_prod)
1374apply(erule conjE)+
1375apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
1376apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1377apply(blast)
1378apply(rule exists_fresh'(2)[OF fs_coname1])
1379apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1380apply(erule exE)
1381apply(simp add: fresh_prod)
1382apply(erule conjE)+
1383apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
1384apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1385apply(blast)
1386apply(rule exists_fresh'(2)[OF fs_coname1])
1387apply(blast)+
1388apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1389apply(erule exE)
1390apply(simp add: fresh_prod)
1391apply(erule conjE)+
1392apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
1393apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1394apply(blast)
1395apply(rule exists_fresh'(2)[OF fs_coname1])
1396apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1397apply(erule exE)
1398apply(simp add: fresh_prod)
1399apply(erule conjE)+
1400apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
1401apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1402apply(rule exists_fresh'(2)[OF fs_coname1])
1403apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1404apply(erule exE)
1405apply(simp add: fresh_prod)
1406apply(erule conjE)+
1407apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
1408apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1409apply(blast)
1410apply(rule exists_fresh'(2)[OF fs_coname1])
1411apply(blast)+
1412done
1413
1414lemma supp_subst5:
1415  shows "(supp M - {y}) \<subseteq> supp (M{y:=<c>.P})"
1416apply(nominal_induct M avoiding: y P c rule: trm.strong_induct)
1417apply(auto)
1418apply(auto simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1419apply(blast)+
1420apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P)")
1421apply(erule exE)
1422apply(simp add: fresh_prod)
1423apply(erule conjE)+
1424apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
1425apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1426apply(blast)
1427apply(rule exists_fresh'(1)[OF fs_name1])
1428apply(blast)
1429apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
1430apply(erule exE)
1431apply(simp add: fresh_prod)
1432apply(erule conjE)+
1433apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
1434apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1435apply(blast)
1436apply(rule exists_fresh'(1)[OF fs_name1])
1437apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
1438apply(erule exE)
1439apply(simp add: fresh_prod)
1440apply(erule conjE)+
1441apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
1442apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1443apply(blast)
1444apply(rule exists_fresh'(1)[OF fs_name1])
1445apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1446apply(erule exE)
1447apply(simp add: fresh_prod)
1448apply(erule conjE)+
1449apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1450apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1451apply(blast)
1452apply(rule exists_fresh'(1)[OF fs_name1])
1453apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1454apply(erule exE)
1455apply(simp add: fresh_prod)
1456apply(erule conjE)+
1457apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1458apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1459apply(blast)
1460apply(rule exists_fresh'(1)[OF fs_name1])
1461apply(blast)
1462apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1463apply(erule exE)
1464apply(simp add: fresh_prod)
1465apply(erule conjE)+
1466apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1467apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1468apply(blast)
1469apply(rule exists_fresh'(1)[OF fs_name1])
1470apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1471apply(erule exE)
1472apply(simp add: fresh_prod)
1473apply(erule conjE)+
1474apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1475apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1476apply(blast)
1477apply(rule exists_fresh'(1)[OF fs_name1])
1478apply(blast)
1479done
1480
1481lemma supp_subst6:
1482  shows "(supp M) \<subseteq> ((supp (M{y:=<c>.P}))::coname set)"
1483apply(nominal_induct M avoiding: y P c rule: trm.strong_induct)
1484apply(auto)
1485apply(auto simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1486apply(blast)+
1487apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P)")
1488apply(erule exE)
1489apply(simp add: fresh_prod)
1490apply(erule conjE)+
1491apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
1492apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1493apply(blast)
1494apply(rule exists_fresh'(1)[OF fs_name1])
1495apply(blast)
1496apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
1497apply(erule exE)
1498apply(simp add: fresh_prod)
1499apply(erule conjE)+
1500apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
1501apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1502apply(blast)
1503apply(rule exists_fresh'(1)[OF fs_name1])
1504apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1)")
1505apply(erule exE)
1506apply(simp add: fresh_prod)
1507apply(erule conjE)+
1508apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
1509apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1510apply(blast)
1511apply(rule exists_fresh'(1)[OF fs_name1])
1512apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1513apply(erule exE)
1514apply(simp add: fresh_prod)
1515apply(erule conjE)+
1516apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1517apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1518apply(blast)
1519apply(rule exists_fresh'(1)[OF fs_name1])
1520apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},P,name1,trm2{y:=<c>.P},name2)")
1521apply(erule exE)
1522apply(simp add: fresh_prod)
1523apply(erule conjE)+
1524apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
1525apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1526apply(blast)
1527apply(rule exists_fresh'(1)[OF fs_name1])
1528apply(blast)
1529apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1530apply(erule exE)
1531apply(simp add: fresh_prod)
1532apply(erule conjE)+
1533apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1534apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1535apply(blast)
1536apply(rule exists_fresh'(1)[OF fs_name1])
1537apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
1538apply(erule exE)
1539apply(simp add: fresh_prod)
1540apply(erule conjE)+
1541apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
1542apply(simp add: fresh_def abs_supp trm.supp supp_atm)
1543apply(blast)
1544apply(rule exists_fresh'(1)[OF fs_name1])
1545apply(blast)
1546done
1547
1548lemma supp_subst7:
1549  shows "(supp M - {c}) \<subseteq>  supp (M{c:=(x).P})"
1550apply(nominal_induct M avoiding: x P c rule: trm.strong_induct)
1551apply(auto)
1552apply(auto simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1553apply(blast)+
1554apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname:=(x).P},P)")
1555apply(erule exE)
1556apply(simp add: fresh_prod)
1557apply(erule conjE)+
1558apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
1559apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1560apply(blast)
1561apply(rule exists_fresh'(2)[OF fs_coname1])
1562apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1563apply(erule exE)
1564apply(simp add: fresh_prod)
1565apply(erule conjE)+
1566apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1567apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1568apply(blast)
1569apply(rule exists_fresh'(2)[OF fs_coname1])
1570apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1571apply(erule exE)
1572apply(simp add: fresh_prod)
1573apply(erule conjE)+
1574apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1575apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1576apply(blast)
1577apply(rule exists_fresh'(2)[OF fs_coname1])
1578apply(blast)+
1579apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1580apply(erule exE)
1581apply(simp add: fresh_prod)
1582apply(erule conjE)+
1583apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
1584apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1585apply(blast)
1586apply(rule exists_fresh'(2)[OF fs_coname1])
1587apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1588apply(erule exE)
1589apply(simp add: fresh_prod)
1590apply(erule conjE)+
1591apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
1592apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1593apply(blast)
1594apply(rule exists_fresh'(2)[OF fs_coname1])
1595apply(blast)+
1596apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1597apply(erule exE)
1598apply(simp add: fresh_prod)
1599apply(erule conjE)+
1600apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
1601apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1602apply(blast)
1603apply(rule exists_fresh'(2)[OF fs_coname1])
1604apply(blast)
1605done
1606
1607lemma supp_subst8:
1608  shows "(supp M) \<subseteq> ((supp (M{c:=(x).P}))::name set)"
1609apply(nominal_induct M avoiding: x P c rule: trm.strong_induct)
1610apply(auto)
1611apply(auto simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1612apply(blast)+
1613apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname:=(x).P},P)")
1614apply(erule exE)
1615apply(simp add: fresh_prod)
1616apply(erule conjE)+
1617apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
1618apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1619apply(blast)
1620apply(rule exists_fresh'(2)[OF fs_coname1])
1621apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1622apply(erule exE)
1623apply(simp add: fresh_prod)
1624apply(erule conjE)+
1625apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1626apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1627apply(blast)
1628apply(rule exists_fresh'(2)[OF fs_coname1])
1629apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
1630apply(erule exE)
1631apply(simp add: fresh_prod)
1632apply(erule conjE)+
1633apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
1634apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1635apply(blast)
1636apply(rule exists_fresh'(2)[OF fs_coname1])
1637apply(blast)+
1638apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1639apply(erule exE)
1640apply(simp add: fresh_prod)
1641apply(erule conjE)+
1642apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
1643apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1644apply(blast)
1645apply(rule exists_fresh'(2)[OF fs_coname1])
1646apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1647apply(erule exE)
1648apply(simp add: fresh_prod)
1649apply(erule conjE)+
1650apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
1651apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1652apply(blast)
1653apply(rule exists_fresh'(2)[OF fs_coname1])
1654apply(blast)
1655apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(x).P},P,coname1)")
1656apply(erule exE)
1657apply(simp add: fresh_prod)
1658apply(erule conjE)+
1659apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
1660apply(simp add: fresh_def abs_supp trm.supp supp_atm fin_supp)
1661apply(blast)
1662apply(rule exists_fresh'(2)[OF fs_coname1])
1663apply(blast)+
1664done
1665
1666lemmas subst_supp = supp_subst1 supp_subst2 supp_subst3 supp_subst4
1667                    supp_subst5 supp_subst6 supp_subst7 supp_subst8
1668lemma subst_fresh:
1669  fixes x::"name"
1670  and   c::"coname"
1671  shows "x\<sharp>P \<Longrightarrow> x\<sharp>M{x:=<c>.P}"   
1672  and   "b\<sharp>P \<Longrightarrow> b\<sharp>M{b:=(y).P}"
1673  and   "x\<sharp>(M,P) \<Longrightarrow> x\<sharp>M{y:=<c>.P}"
1674  and   "x\<sharp>M \<Longrightarrow> x\<sharp>M{c:=(x).P}"
1675  and   "x\<sharp>(M,P) \<Longrightarrow> x\<sharp>M{c:=(y).P}"
1676  and   "b\<sharp>(M,P) \<Longrightarrow> b\<sharp>M{c:=(y).P}"
1677  and   "b\<sharp>M \<Longrightarrow> b\<sharp>M{y:=<b>.P}"
1678  and   "b\<sharp>(M,P) \<Longrightarrow> b\<sharp>M{y:=<c>.P}"
1679apply -
1680apply(insert subst_supp)
1681apply(simp_all add: fresh_def supp_prod)
1682apply(blast)+ 
1683done
1684
1685lemma forget:
1686  shows "x\<sharp>M \<Longrightarrow> M{x:=<c>.P} = M"
1687  and   "c\<sharp>M \<Longrightarrow> M{c:=(x).P} = M"
1688apply(nominal_induct M avoiding: x c P rule: trm.strong_induct)
1689apply(auto simp add: fresh_atm abs_fresh abs_supp fin_supp)
1690done
1691
1692lemma substc_rename1:
1693  assumes a: "c\<sharp>(M,a)"
1694  shows "M{a:=(x).N} = ([(c,a)]\<bullet>M){c:=(x).N}"
1695using a
1696proof(nominal_induct M avoiding: c a x N rule: trm.strong_induct)
1697  case (Ax z d)
1698  then show ?case by (auto simp add: fresh_prod fresh_atm calc_atm trm.inject alpha)
1699next
1700  case NotL
1701  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1702next
1703  case (NotR y M d)
1704  then show ?case 
1705    by(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1706next
1707  case (AndR c1 M c2 M' c3)
1708  then show ?case
1709    apply(auto simp add: fresh_prod calc_atm fresh_atm abs_fresh fresh_left)
1710    apply (metis (erased, hide_lams))
1711    by metis
1712next
1713  case AndL1
1714  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1715next
1716  case AndL2
1717  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1718next
1719  case (OrR1 d M e)
1720  then show ?case 
1721    by(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1722next
1723  case (OrR2 d M e)
1724  then show ?case 
1725    by(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1726next
1727  case (OrL x1 M x2 M' x3)
1728  then show ?case
1729    by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1730next 
1731  case ImpL
1732  then show ?case
1733    by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1734       metis
1735next
1736  case (ImpR y d M e)
1737  then show ?case
1738    by(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1739next
1740  case (Cut d M y M')
1741  then show ?case
1742    by(simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1743      (metis crename.simps(1) crename_id crename_rename)
1744qed
1745
1746lemma substc_rename2:
1747  assumes a: "y\<sharp>(N,x)"
1748  shows "M{a:=(x).N} = M{a:=(y).([(y,x)]\<bullet>N)}"
1749using a
1750proof(nominal_induct M avoiding: a x y N rule: trm.strong_induct)
1751  case (Ax z d)
1752  then show ?case 
1753    by (auto simp add: fresh_prod fresh_atm calc_atm trm.inject alpha perm_swap fresh_left)
1754next
1755  case NotL
1756  then show ?case 
1757    by (auto simp add: fresh_prod fresh_atm calc_atm trm.inject alpha perm_swap fresh_left)
1758next
1759  case (NotR y M d)
1760  then show ?case
1761    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1762    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(N,M{d:=(y).([(y,x)]\<bullet>N)},[(y,x)]\<bullet>N)")
1763    apply(erule exE, simp add: fresh_prod)
1764    apply(erule conjE)+
1765    apply(simp add: fresh_fun_simp_NotR)
1766    apply(simp add: trm.inject alpha perm_swap fresh_left calc_atm)
1767    apply(rule exists_fresh'(2)[OF fs_coname1])
1768    done
1769next
1770  case (AndR c1 M c2 M' c3)
1771  then show ?case
1772    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1773    apply(subgoal_tac 
1774       "\<exists>a'::coname. a'\<sharp>(N,M{c3:=(y).([(y,x)]\<bullet>N)},M'{c3:=(y).([(y,x)]\<bullet>N)},[(y,x)]\<bullet>N,c1,c2,c3)")
1775    apply(erule exE, simp add: fresh_prod)
1776    apply(erule conjE)+
1777    apply(simp add: fresh_fun_simp_AndR)
1778    apply (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh subst_fresh perm_swap fresh_left)
1779    apply(rule exists_fresh'(2)[OF fs_coname1])
1780    done
1781next
1782  case AndL1
1783  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1784next
1785  case AndL2
1786  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1787next
1788  case (OrR1 d M e)
1789  then show ?case 
1790    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1791    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(N,M{e:=(y).([(y,x)]\<bullet>N)},[(y,x)]\<bullet>N,d,e)")
1792    apply(erule exE, simp add: fresh_prod)
1793    apply(erule conjE)+
1794    apply(simp add: fresh_fun_simp_OrR1)
1795    apply(simp add: trm.inject alpha perm_swap fresh_left calc_atm)
1796    apply(rule exists_fresh'(2)[OF fs_coname1])
1797    done
1798next
1799  case (OrR2 d M e)
1800  then show ?case
1801    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1802    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(N,M{e:=(y).([(y,x)]\<bullet>N)},[(y,x)]\<bullet>N,d,e)")
1803    apply(erule exE, simp add: fresh_prod)
1804    apply(erule conjE)+
1805    apply(simp add: fresh_fun_simp_OrR2)
1806    apply(simp add: trm.inject alpha perm_swap fresh_left calc_atm)
1807    apply(rule exists_fresh'(2)[OF fs_coname1])
1808    done
1809next
1810  case (OrL x1 M x2 M' x3)
1811  then show ?case
1812    by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1813next 
1814  case ImpL
1815  then show ?case
1816    by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1817next
1818  case (ImpR y d M e)
1819  then show ?case
1820    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1821    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(N,M{e:=(y).([(y,x)]\<bullet>N)},[(y,x)]\<bullet>N,d,e)")
1822    apply(erule exE, simp add: fresh_prod)
1823    apply(erule conjE)+
1824    apply(simp add: fresh_fun_simp_ImpR)
1825    apply(simp add: trm.inject alpha perm_swap fresh_left calc_atm)
1826    apply(rule exists_fresh'(2)[OF fs_coname1])
1827    done
1828next
1829  case (Cut d M y M')
1830  then show ?case
1831    by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left perm_swap)
1832qed
1833
1834lemma substn_rename3:
1835  assumes a: "y\<sharp>(M,x)"
1836  shows "M{x:=<a>.N} = ([(y,x)]\<bullet>M){y:=<a>.N}"
1837using a
1838proof(nominal_induct M avoiding: a x y N rule: trm.strong_induct)
1839  case (Ax z d)
1840  then show ?case by (auto simp add: fresh_prod fresh_atm calc_atm trm.inject alpha)
1841next
1842  case NotR
1843  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1844next
1845  case (NotL d M z)
1846  then show ?case 
1847    by(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1848next
1849  case (AndR c1 M c2 M' c3)
1850  then show ?case
1851    by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1852next
1853  case OrR1
1854  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1855next
1856  case OrR2
1857  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1858next
1859  case (AndL1 u M v)
1860  then show ?case 
1861    by(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1862next
1863  case (AndL2 u M v)
1864  then show ?case 
1865    by(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod)
1866next
1867  case (OrL x1 M x2 M' x3)
1868  then show ?case
1869    by(simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1870      (metis (poly_guards_query))
1871next 
1872  case ImpR
1873  then show ?case
1874  by(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_left abs_supp fin_supp fresh_prod)
1875next
1876  case (ImpL d M v M' u)
1877  then show ?case
1878    by(simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1879       (metis (poly_guards_query))
1880next
1881  case (Cut d M y M')
1882  then show ?case
1883    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1884    apply(drule pt_bij1[OF pt_name_inst, OF at_name_inst])
1885    apply(simp add: calc_atm)
1886    apply metis
1887    done
1888qed
1889
1890lemma substn_rename4:
1891  assumes a: "c\<sharp>(N,a)"
1892  shows "M{x:=<a>.N} = M{x:=<c>.([(c,a)]\<bullet>N)}"
1893using a
1894proof(nominal_induct M avoiding: x c a N rule: trm.strong_induct)
1895  case (Ax z d)
1896  then show ?case 
1897    by (auto simp add: fresh_prod fresh_atm calc_atm trm.inject alpha perm_swap fresh_left)
1898next
1899  case NotR
1900  then show ?case 
1901    by (auto simp add: fresh_prod fresh_atm calc_atm trm.inject alpha perm_swap fresh_left)
1902next
1903  case (NotL d M y)
1904  then show ?case
1905    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1906    apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(N,M{x:=<c>.([(c,a)]\<bullet>N)},[(c,a)]\<bullet>N)")
1907    apply(erule exE, simp add: fresh_prod)
1908    apply(erule conjE)+
1909    apply(simp add: fresh_fun_simp_NotL)
1910    apply(simp add: trm.inject alpha perm_swap fresh_left calc_atm)
1911    apply(rule exists_fresh'(1)[OF fs_name1])
1912    done
1913next
1914  case (OrL x1 M x2 M' x3)
1915  then show ?case
1916    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1917    apply(subgoal_tac 
1918       "\<exists>a'::name. a'\<sharp>(N,M{x:=<c>.([(c,a)]\<bullet>N)},M'{x:=<c>.([(c,a)]\<bullet>N)},[(c,a)]\<bullet>N,x1,x2,x3)")
1919    apply(erule exE, simp add: fresh_prod)
1920    apply(erule conjE)+
1921    apply(simp add: fresh_fun_simp_OrL)
1922    apply (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh subst_fresh perm_swap fresh_left)
1923    apply(rule exists_fresh'(1)[OF fs_name1])
1924    done
1925next
1926  case OrR1
1927  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1928next
1929  case OrR2
1930  then show ?case by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1931next
1932  case (AndL1 u M v)
1933  then show ?case 
1934    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1935    apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(N,M{x:=<c>.([(c,a)]\<bullet>N)},[(c,a)]\<bullet>N,u,v)")
1936    apply(erule exE, simp add: fresh_prod)
1937    apply(erule conjE)+
1938    apply(simp add: fresh_fun_simp_AndL1)
1939    apply(simp add: trm.inject alpha perm_swap fresh_left calc_atm)
1940    apply(rule exists_fresh'(1)[OF fs_name1])
1941    done
1942next
1943  case (AndL2 u M v)
1944  then show ?case 
1945    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1946    apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(N,M{x:=<c>.([(c,a)]\<bullet>N)},[(c,a)]\<bullet>N,u,v)")
1947    apply(erule exE, simp add: fresh_prod)
1948    apply(erule conjE)+
1949    apply(simp add: fresh_fun_simp_AndL2)
1950    apply(simp add: trm.inject alpha perm_swap fresh_left calc_atm)
1951    apply(rule exists_fresh'(1)[OF fs_name1])
1952    done
1953next
1954  case (AndR c1 M c2 M' c3)
1955  then show ?case
1956    by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1957next 
1958  case ImpR
1959  then show ?case
1960    by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1961next
1962  case (ImpL d M y M' u)
1963  then show ?case
1964    apply(auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left)
1965    apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(N,M{u:=<c>.([(c,a)]\<bullet>N)},M'{u:=<c>.([(c,a)]\<bullet>N)},[(c,a)]\<bullet>N,y,u)")
1966    apply(erule exE, simp add: fresh_prod)
1967    apply(erule conjE)+
1968    apply(simp add: fresh_fun_simp_ImpL)
1969    apply(simp add: trm.inject alpha perm_swap fresh_left calc_atm)
1970    apply(rule exists_fresh'(1)[OF fs_name1])
1971    done
1972next
1973  case (Cut d M y M')
1974  then show ?case
1975    by (auto simp add: calc_atm trm.inject alpha fresh_atm abs_fresh fresh_prod fresh_left perm_swap)
1976qed
1977
1978lemma subst_rename5:
1979  assumes a: "c'\<sharp>(c,N)" "x'\<sharp>(x,M)"
1980  shows "M{x:=<c>.N} = ([(x',x)]\<bullet>M){x':=<c'>.([(c',c)]\<bullet>N)}"
1981proof -
1982  have "M{x:=<c>.N} = ([(x',x)]\<bullet>M){x':=<c>.N}" using a by (simp add: substn_rename3)
1983  also have "\<dots> = ([(x',x)]\<bullet>M){x':=<c'>.([(c',c)]\<bullet>N)}" using a by (simp add: substn_rename4)
1984  finally show ?thesis by simp
1985qed
1986
1987lemma subst_rename6:
1988  assumes a: "c'\<sharp>(c,M)" "x'\<sharp>(x,N)"
1989  shows "M{c:=(x).N} = ([(c',c)]\<bullet>M){c':=(x').([(x',x)]\<bullet>N)}"
1990proof -
1991  have "M{c:=(x).N} = ([(c',c)]\<bullet>M){c':=(x).N}" using a by (simp add: substc_rename1)
1992  also have "\<dots> = ([(c',c)]\<bullet>M){c':=(x').([(x',x)]\<bullet>N)}" using a by (simp add: substc_rename2)
1993  finally show ?thesis by simp
1994qed
1995
1996lemmas subst_rename = substc_rename1 substc_rename2 substn_rename3 substn_rename4 subst_rename5 subst_rename6
1997
1998lemma better_Cut_substn[simp]:
1999  assumes a: "a\<sharp>[c].P" "x\<sharp>(y,P)"
2000  shows "(Cut <a>.M (x).N){y:=<c>.P} = 
2001  (if M=Ax y a then Cut <c>.P (x).(N{y:=<c>.P}) else Cut <a>.(M{y:=<c>.P}) (x).(N{y:=<c>.P}))"
2002proof -   
2003  obtain x'::"name"   where fs1: "x'\<sharp>(M,N,c,P,x,y)" by (rule exists_fresh(1), rule fin_supp, blast)
2004  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,c,P,a)" by (rule exists_fresh(2), rule fin_supp, blast)
2005  have eq1: "(Cut <a>.M (x).N) = (Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N))"
2006    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
2007  have eq2: "(M=Ax y a) = (([(a',a)]\<bullet>M)=Ax y a')"
2008    apply(auto simp add: calc_atm)
2009    apply(drule pt_bij1[OF pt_coname_inst, OF at_coname_inst])
2010    apply(simp add: calc_atm)
2011    done
2012  have "(Cut <a>.M (x).N){y:=<c>.P} = (Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N)){y:=<c>.P}" 
2013    using eq1 by simp
2014  also have "\<dots> = (if ([(a',a)]\<bullet>M)=Ax y a' then Cut <c>.P (x').(([(x',x)]\<bullet>N){y:=<c>.P}) 
2015                              else Cut <a'>.(([(a',a)]\<bullet>M){y:=<c>.P}) (x').(([(x',x)]\<bullet>N){y:=<c>.P}))" 
2016    using fs1 fs2 by (auto simp add: fresh_prod fresh_left calc_atm fresh_atm)
2017  also have "\<dots> =(if M=Ax y a then Cut <c>.P (x).(N{y:=<c>.P}) else Cut <a>.(M{y:=<c>.P}) (x).(N{y:=<c>.P}))"
2018    using fs1 fs2 a
2019    apply -
2020    apply(simp only: eq2[symmetric])
2021    apply(auto simp add: trm.inject)
2022    apply(simp_all add: alpha fresh_atm fresh_prod subst_fresh)
2023    apply(simp_all add: eqvts perm_fresh_fresh calc_atm)
2024    apply(auto)
2025    apply(rule subst_rename)
2026    apply(simp add: fresh_prod fresh_atm)
2027    apply(simp add: abs_fresh)
2028    apply(simp add: perm_fresh_fresh)
2029    done
2030  finally show ?thesis by simp
2031qed
2032    
2033lemma better_Cut_substc[simp]:
2034  assumes a: "a\<sharp>(c,P)" "x\<sharp>[y].P"
2035  shows "(Cut <a>.M (x).N){c:=(y).P} = 
2036  (if N=Ax x c then Cut <a>.(M{c:=(y).P}) (y).P else Cut <a>.(M{c:=(y).P}) (x).(N{c:=(y).P}))" 
2037proof -   
2038  obtain x'::"name"   where fs1: "x'\<sharp>(M,N,c,P,x,y)" by (rule exists_fresh(1), rule fin_supp, blast)
2039  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,c,P,a)" by (rule exists_fresh(2), rule fin_supp, blast)
2040  have eq1: "(Cut <a>.M (x).N) = (Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N))"
2041    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
2042  have eq2: "(N=Ax x c) = (([(x',x)]\<bullet>N)=Ax x' c)"
2043    apply(auto simp add: calc_atm)
2044    apply(drule pt_bij1[OF pt_name_inst, OF at_name_inst])
2045    apply(simp add: calc_atm)
2046    done
2047  have "(Cut <a>.M (x).N){c:=(y).P} = (Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N)){c:=(y).P}" 
2048    using eq1 by simp
2049  also have "\<dots> = (if ([(x',x)]\<bullet>N)=Ax x' c then  Cut <a'>.(([(a',a)]\<bullet>M){c:=(y).P}) (y).P
2050                              else Cut <a'>.(([(a',a)]\<bullet>M){c:=(y).P}) (x').(([(x',x)]\<bullet>N){c:=(y).P}))" 
2051    using fs1 fs2  by (simp add: fresh_prod fresh_left calc_atm fresh_atm trm.inject)
2052  also have "\<dots> =(if N=Ax x c then Cut <a>.(M{c:=(y).P}) (y).P else Cut <a>.(M{c:=(y).P}) (x).(N{c:=(y).P}))"
2053    using fs1 fs2 a
2054    apply -
2055    apply(simp only: eq2[symmetric])
2056    apply(auto simp add: trm.inject)
2057    apply(simp_all add: alpha fresh_atm fresh_prod subst_fresh)
2058    apply(simp_all add: eqvts perm_fresh_fresh calc_atm)
2059    apply(auto)
2060    apply(rule subst_rename)
2061    apply(simp add: fresh_prod fresh_atm)
2062    apply(simp add: abs_fresh)
2063    apply(simp add: perm_fresh_fresh)
2064    done
2065  finally show ?thesis by simp
2066qed
2067
2068lemma better_Cut_substn':
2069  assumes a: "a\<sharp>[c].P" "y\<sharp>(N,x)" "M\<noteq>Ax y a"
2070  shows "(Cut <a>.M (x).N){y:=<c>.P} = Cut <a>.(M{y:=<c>.P}) (x).N"
2071using a
2072apply -
2073apply(generate_fresh "name")
2074apply(subgoal_tac "Cut <a>.M (x).N = Cut <a>.M (ca).([(ca,x)]\<bullet>N)")
2075apply(simp)
2076apply(subgoal_tac"y\<sharp>([(ca,x)]\<bullet>N)")
2077apply(simp add: forget)
2078apply(simp add: trm.inject)
2079apply(auto simp add: fresh_left calc_atm fresh_prod fresh_atm)[1]
2080apply(simp add: trm.inject)
2081apply(rule sym)
2082apply(simp add: alpha fresh_prod fresh_atm)
2083done
2084
2085lemma better_NotR_substc:
2086  assumes a: "d\<sharp>M"
2087  shows "(NotR (x).M d){d:=(z).P} = fresh_fun (\<lambda>a'. Cut <a'>.NotR (x).M a' (z).P)"
2088using a
2089apply -
2090apply(generate_fresh "name")
2091apply(subgoal_tac "NotR (x).M d = NotR (c).([(c,x)]\<bullet>M) d")
2092apply(auto simp add: fresh_left calc_atm forget)
2093apply(generate_fresh "coname")
2094apply(rule_tac f="fresh_fun" in arg_cong)
2095apply(simp add:  fun_eq_iff)
2096apply(rule allI)
2097apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2098apply(perm_simp add: trm.inject alpha fresh_prod fresh_atm fresh_left, auto)
2099done
2100
2101lemma better_NotL_substn:
2102  assumes a: "y\<sharp>M"
2103  shows "(NotL <a>.M y){y:=<c>.P} = fresh_fun (\<lambda>x'. Cut <c>.P (x').NotL <a>.M x')"
2104using a
2105apply -
2106apply(generate_fresh "coname")
2107apply(subgoal_tac "NotL <a>.M y = NotL <ca>.([(ca,a)]\<bullet>M) y")
2108apply(auto simp add: fresh_left calc_atm forget)
2109apply(generate_fresh "name")
2110apply(rule_tac f="fresh_fun" in arg_cong)
2111apply(simp add:  fun_eq_iff)
2112apply(rule allI)
2113apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2114apply(perm_simp add: trm.inject alpha fresh_prod fresh_atm fresh_left, auto)
2115done
2116
2117lemma better_AndL1_substn:
2118  assumes a: "y\<sharp>[x].M"
2119  shows "(AndL1 (x).M y){y:=<c>.P} = fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL1 (x).M z')"
2120using a
2121apply -
2122apply(generate_fresh "name")
2123apply(subgoal_tac "AndL1 (x).M y = AndL1 (ca).([(ca,x)]\<bullet>M) y")
2124apply(auto simp add: fresh_left calc_atm forget abs_fresh)[1]
2125apply(generate_fresh "name")
2126apply(rule_tac f="fresh_fun" in arg_cong)
2127apply(simp add:  fun_eq_iff)
2128apply(rule allI)
2129apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2130apply(rule forget)
2131apply(simp add: fresh_left calc_atm)
2132apply(rule_tac f="fresh_fun" in arg_cong)
2133apply(simp add:  fun_eq_iff)
2134apply(rule allI)
2135apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2136apply(rule forget)
2137apply(simp add: fresh_left calc_atm)
2138apply(perm_simp add: trm.inject alpha fresh_left calc_atm fresh_prod fresh_atm)
2139apply(auto)
2140done
2141
2142lemma better_AndL2_substn:
2143  assumes a: "y\<sharp>[x].M"
2144  shows "(AndL2 (x).M y){y:=<c>.P} = fresh_fun (\<lambda>z'. Cut <c>.P (z').AndL2 (x).M z')"
2145using a
2146apply -
2147apply(generate_fresh "name")
2148apply(subgoal_tac "AndL2 (x).M y = AndL2 (ca).([(ca,x)]\<bullet>M) y")
2149apply(auto simp add: fresh_left calc_atm forget abs_fresh)[1]
2150apply(generate_fresh "name")
2151apply(rule_tac f="fresh_fun" in arg_cong)
2152apply(simp add:  fun_eq_iff)
2153apply(rule allI)
2154apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2155apply(rule forget)
2156apply(simp add: fresh_left calc_atm)
2157apply(rule_tac f="fresh_fun" in arg_cong)
2158apply(simp add:  fun_eq_iff)
2159apply(rule allI)
2160apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2161apply(rule forget)
2162apply(simp add: fresh_left calc_atm)
2163apply(perm_simp add: trm.inject alpha fresh_left calc_atm fresh_prod fresh_atm)
2164apply(auto)
2165done
2166
2167lemma better_AndR_substc:
2168  assumes a: "c\<sharp>([a].M,[b].N)"
2169  shows "(AndR <a>.M <b>.N c){c:=(z).P} = fresh_fun (\<lambda>a'. Cut <a'>.(AndR <a>.M <b>.N a') (z).P)"
2170using a
2171apply -
2172apply(generate_fresh "coname")
2173apply(generate_fresh "coname")
2174apply(subgoal_tac "AndR <a>.M <b>.N c = AndR <ca>.([(ca,a)]\<bullet>M) <caa>.([(caa,b)]\<bullet>N) c")
2175apply(auto simp add: fresh_left calc_atm forget abs_fresh)[1]
2176apply(rule trans)
2177apply(rule substc.simps)
2178apply(auto simp add: fresh_left calc_atm fresh_prod fresh_atm)[1]
2179apply(auto simp add: fresh_left calc_atm fresh_prod fresh_atm)[1]
2180apply(auto simp add: fresh_prod fresh_atm)[1]
2181apply(simp)
2182apply(rule_tac f="fresh_fun" in arg_cong)
2183apply(simp add:  fun_eq_iff)
2184apply(rule allI)
2185apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2186apply(rule conjI)
2187apply(rule forget)
2188apply(auto simp add: fresh_left calc_atm abs_fresh)[1]
2189apply(rule forget)
2190apply(auto simp add: fresh_left calc_atm abs_fresh)[1]
2191apply(perm_simp add: trm.inject alpha fresh_left calc_atm fresh_prod fresh_atm)
2192apply(auto)
2193done
2194
2195lemma better_OrL_substn:
2196  assumes a: "x\<sharp>([y].M,[z].N)"
2197  shows "(OrL (y).M (z).N x){x:=<c>.P} = fresh_fun (\<lambda>z'. Cut <c>.P (z').OrL (y).M (z).N z')"
2198using a
2199apply -
2200apply(generate_fresh "name")
2201apply(generate_fresh "name")
2202apply(subgoal_tac "OrL (y).M (z).N x = OrL (ca).([(ca,y)]\<bullet>M) (caa).([(caa,z)]\<bullet>N) x")
2203apply(auto simp add: fresh_left calc_atm forget abs_fresh)[1]
2204apply(rule trans)
2205apply(rule substn.simps)
2206apply(auto simp add: fresh_left calc_atm fresh_prod fresh_atm)[1]
2207apply(auto simp add: fresh_left calc_atm fresh_prod fresh_atm)[1]
2208apply(auto simp add: fresh_prod fresh_atm)[1]
2209apply(simp)
2210apply(rule_tac f="fresh_fun" in arg_cong)
2211apply(simp add:  fun_eq_iff)
2212apply(rule allI)
2213apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2214apply(rule conjI)
2215apply(rule forget)
2216apply(auto simp add: fresh_left calc_atm abs_fresh)[1]
2217apply(rule forget)
2218apply(auto simp add: fresh_left calc_atm abs_fresh)[1]
2219apply(perm_simp add: trm.inject alpha fresh_left calc_atm fresh_prod fresh_atm)
2220apply(auto)
2221done
2222
2223lemma better_OrR1_substc:
2224  assumes a: "d\<sharp>[a].M"
2225  shows "(OrR1 <a>.M d){d:=(z).P} = fresh_fun (\<lambda>a'. Cut <a'>.OrR1 <a>.M a' (z).P)"
2226using a
2227apply -
2228apply(generate_fresh "coname")
2229apply(subgoal_tac "OrR1 <a>.M d = OrR1 <c>.([(c,a)]\<bullet>M) d")
2230apply(auto simp add: fresh_left calc_atm forget abs_fresh)[1]
2231apply(rule_tac f="fresh_fun" in arg_cong)
2232apply(simp add:  fun_eq_iff)
2233apply(rule allI)
2234apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2235apply(rule forget)
2236apply(simp add: fresh_left calc_atm)
2237apply(rule_tac f="fresh_fun" in arg_cong)
2238apply(simp add:  fun_eq_iff)
2239apply(rule allI)
2240apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2241apply(rule forget)
2242apply(simp add: fresh_left calc_atm)
2243apply(perm_simp add: trm.inject alpha fresh_left calc_atm fresh_prod fresh_atm)
2244apply(auto)
2245done
2246
2247lemma better_OrR2_substc:
2248  assumes a: "d\<sharp>[a].M"
2249  shows "(OrR2 <a>.M d){d:=(z).P} = fresh_fun (\<lambda>a'. Cut <a'>.OrR2 <a>.M a' (z).P)"
2250using a
2251apply -
2252apply(generate_fresh "coname")
2253apply(subgoal_tac "OrR2 <a>.M d = OrR2 <c>.([(c,a)]\<bullet>M) d")
2254apply(auto simp add: fresh_left calc_atm forget abs_fresh)[1]
2255apply(rule_tac f="fresh_fun" in arg_cong)
2256apply(simp add:  fun_eq_iff)
2257apply(rule allI)
2258apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2259apply(rule forget)
2260apply(simp add: fresh_left calc_atm)
2261apply(rule_tac f="fresh_fun" in arg_cong)
2262apply(simp add:  fun_eq_iff)
2263apply(rule allI)
2264apply(simp add: trm.inject alpha fresh_prod fresh_atm)
2265apply(rule forget)
2266apply(simp add: fresh_left calc_atm)
2267apply(perm_simp add: trm.inject alpha fresh_left calc_atm fresh_prod fresh_atm)
2268apply(auto)
2269done
2270
2271lemma better_ImpR_substc:
2272  assumes a: "d\<sharp>[a].M"
2273  shows "(ImpR (x).<a>.M d){d:=(z).P} = fresh_fun (\<lambda>a'. Cut <a'>.ImpR (x).<a>.M a' (z).P)"
2274using a
2275apply -
2276apply(generate_fresh "coname")
2277apply(generate_fresh "name")
2278apply(subgoal_tac "ImpR (x).<a>.M d = ImpR (ca).<c>.([(c,a)]\<bullet>[(ca,x)]\<bullet>M) d")
2279apply(auto simp add: fresh_left calc_atm forget abs_fresh)[1]
2280apply(rule_tac f="fresh_fun" in arg_cong)
2281apply(simp add:  fun_eq_iff)
2282apply(rule allI)
2283apply(simp add: trm.inject alpha fresh_prod fresh_atm abs_perm abs_fresh fresh_left calc_atm)
2284apply(rule forget)
2285apply(simp add: fresh_left calc_atm)
2286apply(rule_tac f="fresh_fun" in arg_cong)
2287apply(simp add:  fun_eq_iff)
2288apply(rule allI)
2289apply(simp add: trm.inject alpha fresh_prod fresh_atm abs_perm fresh_left calc_atm abs_fresh)
2290apply(rule forget)
2291apply(simp add: fresh_left calc_atm)
2292apply(rule sym)
2293apply(perm_simp add: trm.inject alpha fresh_left calc_atm fresh_prod fresh_atm abs_fresh abs_perm)
2294done
2295
2296lemma better_ImpL_substn:
2297  assumes a: "y\<sharp>(M,[x].N)"
2298  shows "(ImpL <a>.M (x).N y){y:=<c>.P} = fresh_fun (\<lambda>z'. Cut <c>.P (z').ImpL <a>.M (x).N z')"
2299using a
2300apply -
2301apply(generate_fresh "coname")
2302apply(generate_fresh "name")
2303apply(subgoal_tac "ImpL <a>.M (x).N y = ImpL <ca>.([(ca,a)]\<bullet>M) (caa).([(caa,x)]\<bullet>N) y")
2304apply(auto simp add: fresh_left calc_atm forget abs_fresh)[1]
2305apply(rule_tac f="fresh_fun" in arg_cong)
2306apply(simp add:  fun_eq_iff)
2307apply(rule allI)
2308apply(simp add: trm.inject alpha fresh_prod fresh_atm abs_perm abs_fresh fresh_left calc_atm)
2309apply(rule forget)
2310apply(simp add: fresh_left calc_atm)
2311apply(auto)[1]
2312apply(rule sym)
2313apply(perm_simp add: trm.inject alpha fresh_left calc_atm fresh_prod fresh_atm abs_fresh abs_perm)
2314done
2315
2316lemma freshn_after_substc:
2317  fixes x::"name"
2318  assumes a: "x\<sharp>M{c:=(y).P}"
2319  shows "x\<sharp>M"
2320using a supp_subst8
2321apply(simp add: fresh_def)
2322apply(blast)
2323done
2324
2325lemma freshn_after_substn:
2326  fixes x::"name"
2327  assumes a: "x\<sharp>M{y:=<c>.P}" "x\<noteq>y"
2328  shows "x\<sharp>M"
2329using a
2330using a supp_subst5
2331apply(simp add: fresh_def)
2332apply(blast)
2333done
2334
2335lemma freshc_after_substc:
2336  fixes a::"coname"
2337  assumes a: "a\<sharp>M{c:=(y).P}" "a\<noteq>c"
2338  shows "a\<sharp>M"
2339using a supp_subst7
2340apply(simp add: fresh_def)
2341apply(blast)
2342done
2343
2344lemma freshc_after_substn:
2345  fixes a::"coname"
2346  assumes a: "a\<sharp>M{y:=<c>.P}" 
2347  shows "a\<sharp>M"
2348using a supp_subst6
2349apply(simp add: fresh_def)
2350apply(blast)
2351done
2352
2353lemma substn_crename_comm:
2354  assumes a: "c\<noteq>a" "c\<noteq>b"
2355  shows "M{x:=<c>.P}[a\<turnstile>c>b] = M[a\<turnstile>c>b]{x:=<c>.(P[a\<turnstile>c>b])}"
2356using a
2357apply(nominal_induct M avoiding: x c P a b rule: trm.strong_induct)
2358apply(auto simp add: subst_fresh rename_fresh trm.inject)
2359apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,x,c)")
2360apply(erule exE)
2361apply(subgoal_tac "Cut <c>.P (x).Ax x a = Cut <c>.P (x').Ax x' a")
2362apply(simp)
2363apply(rule trans)
2364apply(rule crename.simps)
2365apply(simp add: fresh_prod fresh_atm)
2366apply(simp)
2367apply(simp add: trm.inject)
2368apply(simp add: alpha trm.inject calc_atm fresh_atm)
2369apply(simp add: trm.inject)
2370apply(simp add: alpha trm.inject calc_atm fresh_atm)
2371apply(rule exists_fresh')
2372apply(rule fin_supp)
2373apply(rule trans)
2374apply(rule better_crename_Cut)
2375apply(simp add: fresh_atm)
2376apply(simp)
2377apply(simp add: crename_id)
2378apply(rule trans)
2379apply(rule better_crename_Cut)
2380apply(simp add: fresh_atm fresh_prod)
2381apply(simp add: rename_fresh fresh_atm)
2382apply(auto simp add: fresh_atm)[1]
2383apply(rule trans)
2384apply(rule better_crename_Cut)
2385apply(simp add: fresh_atm)
2386apply(auto simp add: fresh_atm)[1]
2387apply(drule crename_ax)
2388apply(simp add: fresh_atm)
2389apply(simp add: fresh_atm)
2390apply(simp)
2391apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<c>.P},P,P[a\<turnstile>c>b],x,trm[a\<turnstile>c>b]{x:=<c>.P[a\<turnstile>c>b]})")
2392apply(erule exE, simp add: fresh_prod)
2393apply(erule conjE)+
2394apply(simp add: fresh_fun_simp_NotL)
2395apply(rule trans)
2396apply(rule better_crename_Cut)
2397apply(simp add: fresh_atm fresh_prod)
2398apply(simp add: rename_fresh fresh_atm)
2399apply(rule exists_fresh')
2400apply(rule fin_supp)
2401apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<c>.P},P,P[a\<turnstile>c>b],name1,trm[a\<turnstile>c>b]{x:=<c>.P[a\<turnstile>c>b]})")
2402apply(erule exE, simp add: fresh_prod)
2403apply(erule conjE)+
2404apply(simp add: fresh_fun_simp_AndL1)
2405apply(rule trans)
2406apply(rule better_crename_Cut)
2407apply(simp add: fresh_atm fresh_prod)
2408apply(simp add: rename_fresh fresh_atm)
2409apply(rule exists_fresh')
2410apply(rule fin_supp)
2411apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<c>.P},P,P[a\<turnstile>c>b],name1,trm[a\<turnstile>c>b]{x:=<c>.P[a\<turnstile>c>b]})")
2412apply(erule exE, simp add: fresh_prod)
2413apply(erule conjE)+
2414apply(simp add: fresh_fun_simp_AndL2)
2415apply(rule trans)
2416apply(rule better_crename_Cut)
2417apply(simp add: fresh_atm fresh_prod)
2418apply(simp add: rename_fresh fresh_atm)
2419apply(rule exists_fresh')
2420apply(rule fin_supp)
2421apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{x:=<c>.P},trm2{x:=<c>.P},P,P[a\<turnstile>c>b],name1,name2,
2422                                  trm1[a\<turnstile>c>b]{x:=<c>.P[a\<turnstile>c>b]},trm2[a\<turnstile>c>b]{x:=<c>.P[a\<turnstile>c>b]})")
2423apply(erule exE, simp add: fresh_prod)
2424apply(erule conjE)+
2425apply(simp add: fresh_fun_simp_OrL)
2426apply(rule trans)
2427apply(rule better_crename_Cut)
2428apply(simp add: fresh_atm fresh_prod)
2429apply(simp add: rename_fresh subst_fresh fresh_atm)
2430apply(rule exists_fresh')
2431apply(rule fin_supp)
2432apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},trm2{name2:=<c>.P},P,P[a\<turnstile>c>b],name1,
2433                                  trm1[a\<turnstile>c>b]{name2:=<c>.P[a\<turnstile>c>b]},trm2[a\<turnstile>c>b]{name2:=<c>.P[a\<turnstile>c>b]})")
2434apply(erule exE, simp add: fresh_prod)
2435apply(erule conjE)+
2436apply(simp add: fresh_fun_simp_ImpL)
2437apply(rule trans)
2438apply(rule better_crename_Cut)
2439apply(simp add: fresh_atm fresh_prod)
2440apply(simp add: rename_fresh subst_fresh fresh_atm)
2441apply(rule exists_fresh')
2442apply(rule fin_supp)
2443done
2444
2445lemma substc_crename_comm:
2446  assumes a: "c\<noteq>a" "c\<noteq>b"
2447  shows "M{c:=(x).P}[a\<turnstile>c>b] = M[a\<turnstile>c>b]{c:=(x).(P[a\<turnstile>c>b])}"
2448using a
2449apply(nominal_induct M avoiding: x c P a b rule: trm.strong_induct)
2450apply(auto simp add: subst_fresh rename_fresh trm.inject)
2451apply(rule trans)
2452apply(rule better_crename_Cut)
2453apply(simp add: fresh_atm fresh_prod)
2454apply(simp add: rename_fresh fresh_atm)
2455apply(rule trans)
2456apply(rule better_crename_Cut)
2457apply(simp add: fresh_atm fresh_prod)
2458apply(simp add: rename_fresh fresh_atm)
2459apply(drule crename_ax)
2460apply(simp add: fresh_atm)
2461apply(simp add: fresh_atm)
2462apply(simp)
2463apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(a,b,trm{coname:=(x).P},P,P[a\<turnstile>c>b],x,trm[a\<turnstile>c>b]{coname:=(x).P[a\<turnstile>c>b]})")
2464apply(erule exE, simp add: fresh_prod)
2465apply(erule conjE)+
2466apply(simp add: fresh_fun_simp_NotR)
2467apply(rule trans)
2468apply(rule better_crename_Cut)
2469apply(simp add: fresh_atm fresh_prod)
2470apply(simp add: rename_fresh fresh_atm)
2471apply(rule exists_fresh')
2472apply(rule fin_supp)
2473apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(coname1,coname2,a,b,trm1{coname3:=(x).P},trm2{coname3:=(x).P},
2474                   P,P[a\<turnstile>c>b],x,trm1[a\<turnstile>c>b]{coname3:=(x).P[a\<turnstile>c>b]},trm2[a\<turnstile>c>b]{coname3:=(x).P[a\<turnstile>c>b]})")
2475apply(erule exE, simp add: fresh_prod)
2476apply(erule conjE)+
2477apply(simp add: fresh_fun_simp_AndR)
2478apply(rule trans)
2479apply(rule better_crename_Cut)
2480apply(simp add: fresh_atm fresh_prod)
2481apply(simp add: rename_fresh subst_fresh fresh_atm)
2482apply(rule exists_fresh')
2483apply(rule fin_supp)
2484apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(coname1,trm{coname2:=(x).P},P,P[a\<turnstile>c>b],a,b,
2485                         trm[a\<turnstile>c>b]{coname2:=(x).P[a\<turnstile>c>b]})")
2486apply(erule exE, simp add: fresh_prod)
2487apply(erule conjE)+
2488apply(simp add: fresh_fun_simp_OrR1)
2489apply(rule trans)
2490apply(rule better_crename_Cut)
2491apply(simp add: fresh_atm fresh_prod)
2492apply(simp add: rename_fresh fresh_atm)
2493apply(rule exists_fresh')
2494apply(rule fin_supp)
2495apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(coname1,trm{coname2:=(x).P},P,P[a\<turnstile>c>b],a,b,
2496                         trm[a\<turnstile>c>b]{coname2:=(x).P[a\<turnstile>c>b]})")
2497apply(erule exE, simp add: fresh_prod)
2498apply(erule conjE)+
2499apply(simp add: fresh_fun_simp_OrR2)
2500apply(rule trans)
2501apply(rule better_crename_Cut)
2502apply(simp add: fresh_atm fresh_prod)
2503apply(simp add: rename_fresh fresh_atm)
2504apply(rule exists_fresh')
2505apply(rule fin_supp)
2506apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(coname1,trm{coname2:=(x).P},P,P[a\<turnstile>c>b],a,b,
2507                         trm[a\<turnstile>c>b]{coname2:=(x).P[a\<turnstile>c>b]})")
2508apply(erule exE, simp add: fresh_prod)
2509apply(erule conjE)+
2510apply(simp add: fresh_fun_simp_ImpR)
2511apply(rule trans)
2512apply(rule better_crename_Cut)
2513apply(simp add: fresh_atm fresh_prod)
2514apply(simp add: rename_fresh fresh_atm)
2515apply(rule exists_fresh')
2516apply(rule fin_supp)
2517done
2518
2519lemma substn_nrename_comm:
2520  assumes a: "x\<noteq>y" "x\<noteq>z"
2521  shows "M{x:=<c>.P}[y\<turnstile>n>z] = M[y\<turnstile>n>z]{x:=<c>.(P[y\<turnstile>n>z])}"
2522using a
2523apply(nominal_induct M avoiding: x c P y z rule: trm.strong_induct)
2524apply(auto simp add: subst_fresh rename_fresh trm.inject)
2525apply(rule trans)
2526apply(rule better_nrename_Cut)
2527apply(simp add: fresh_prod fresh_atm)
2528apply(simp add: trm.inject)
2529apply(rule trans)
2530apply(rule better_nrename_Cut)
2531apply(simp add: fresh_atm)
2532apply(simp)
2533apply(drule nrename_ax)
2534apply(simp add: fresh_atm)
2535apply(simp add: fresh_atm)
2536apply(simp)
2537apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(y,z,trm{x:=<c>.P},P,P[y\<turnstile>n>z],x,trm[y\<turnstile>n>z]{x:=<c>.P[y\<turnstile>n>z]})")
2538apply(erule exE, simp add: fresh_prod)
2539apply(erule conjE)+
2540apply(simp add: fresh_fun_simp_NotL)
2541apply(rule trans)
2542apply(rule better_nrename_Cut)
2543apply(simp add: fresh_atm fresh_prod)
2544apply(simp add: fresh_atm)
2545apply(rule exists_fresh')
2546apply(rule fin_supp)
2547apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<c>.P},P,P[y\<turnstile>n>z],name1,trm[y\<turnstile>n>z]{x:=<c>.P[y\<turnstile>n>z]},y,z)")
2548apply(erule exE, simp add: fresh_prod)
2549apply(erule conjE)+
2550apply(simp add: fresh_fun_simp_AndL1)
2551apply(rule trans)
2552apply(rule better_nrename_Cut)
2553apply(simp add: fresh_atm fresh_prod)
2554apply(simp add: rename_fresh fresh_atm)
2555apply(rule exists_fresh')
2556apply(rule fin_supp)
2557apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(y,z,trm{x:=<c>.P},P,P[y\<turnstile>n>z],name1,trm[y\<turnstile>n>z]{x:=<c>.P[y\<turnstile>n>z]})")
2558apply(erule exE, simp add: fresh_prod)
2559apply(erule conjE)+
2560apply(simp add: fresh_fun_simp_AndL2)
2561apply(rule trans)
2562apply(rule better_nrename_Cut)
2563apply(simp add: fresh_atm fresh_prod)
2564apply(simp add: rename_fresh fresh_atm)
2565apply(rule exists_fresh')
2566apply(rule fin_supp)
2567apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{x:=<c>.P},trm2{x:=<c>.P},P,P[y\<turnstile>n>z],name1,name2,y,z,
2568                                  trm1[y\<turnstile>n>z]{x:=<c>.P[y\<turnstile>n>z]},trm2[y\<turnstile>n>z]{x:=<c>.P[y\<turnstile>n>z]})")
2569apply(erule exE, simp add: fresh_prod)
2570apply(erule conjE)+
2571apply(simp add: fresh_fun_simp_OrL)
2572apply(rule trans)
2573apply(rule better_nrename_Cut)
2574apply(simp add: fresh_atm fresh_prod)
2575apply(simp add: rename_fresh subst_fresh fresh_atm)
2576apply(rule exists_fresh')
2577apply(rule fin_supp)
2578apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},trm2{name2:=<c>.P},P,P[y\<turnstile>n>z],y,z,name1,
2579                                  trm1[y\<turnstile>n>z]{name2:=<c>.P[y\<turnstile>n>z]},trm2[y\<turnstile>n>z]{name2:=<c>.P[y\<turnstile>n>z]})")
2580apply(erule exE, simp add: fresh_prod)
2581apply(erule conjE)+
2582apply(simp add: fresh_fun_simp_ImpL)
2583apply(rule trans)
2584apply(rule better_nrename_Cut)
2585apply(simp add: fresh_atm fresh_prod)
2586apply(simp add: rename_fresh subst_fresh fresh_atm)
2587apply(rule exists_fresh')
2588apply(rule fin_supp)
2589done
2590
2591lemma substc_nrename_comm:
2592  assumes a: "x\<noteq>y" "x\<noteq>z"
2593  shows "M{c:=(x).P}[y\<turnstile>n>z] = M[y\<turnstile>n>z]{c:=(x).(P[y\<turnstile>n>z])}"
2594using a
2595apply(nominal_induct M avoiding: x c P y z rule: trm.strong_induct)
2596apply(auto simp add: subst_fresh rename_fresh trm.inject)
2597apply(rule trans)
2598apply(rule better_nrename_Cut)
2599apply(simp add: fresh_atm fresh_prod)
2600apply(simp add: rename_fresh fresh_atm)
2601apply(rule trans)
2602apply(rule better_nrename_Cut)
2603apply(simp add: fresh_atm fresh_prod)
2604apply(simp add: rename_fresh fresh_atm)
2605apply(rule trans)
2606apply(rule better_nrename_Cut)
2607apply(simp add: fresh_atm fresh_prod)
2608apply(simp add: rename_fresh fresh_atm)
2609apply(rule trans)
2610apply(rule better_nrename_Cut)
2611apply(simp add: fresh_atm fresh_prod)
2612apply(simp add: rename_fresh fresh_atm)
2613apply(drule nrename_ax)
2614apply(simp add: fresh_atm)
2615apply(simp add: fresh_atm)
2616apply(simp)
2617apply(rule trans)
2618apply(rule better_nrename_Cut)
2619apply(simp add: fresh_atm fresh_prod)
2620apply(simp add: rename_fresh fresh_atm)
2621apply(drule nrename_ax)
2622apply(simp add: fresh_atm)
2623apply(simp add: fresh_atm)
2624apply(simp)
2625apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(y,z,trm{coname:=(x).P},P,P[y\<turnstile>n>z],x,trm[y\<turnstile>n>z]{coname:=(x).P[y\<turnstile>n>z]})")
2626apply(erule exE, simp add: fresh_prod)
2627apply(erule conjE)+
2628apply(simp add: fresh_fun_simp_NotR)
2629apply(rule trans)
2630apply(rule better_nrename_Cut)
2631apply(simp add: fresh_atm fresh_prod)
2632apply(simp add: rename_fresh fresh_atm)
2633apply(rule exists_fresh')
2634apply(rule fin_supp)
2635apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(coname1,coname2,y,z,trm1{coname3:=(x).P},trm2{coname3:=(x).P},
2636                   P,P[y\<turnstile>n>z],x,trm1[y\<turnstile>n>z]{coname3:=(x).P[y\<turnstile>n>z]},trm2[y\<turnstile>n>z]{coname3:=(x).P[y\<turnstile>n>z]})")
2637apply(erule exE, simp add: fresh_prod)
2638apply(erule conjE)+
2639apply(simp add: fresh_fun_simp_AndR)
2640apply(rule trans)
2641apply(rule better_nrename_Cut)
2642apply(simp add: fresh_atm fresh_prod)
2643apply(simp add: rename_fresh subst_fresh fresh_atm)
2644apply(rule exists_fresh')
2645apply(rule fin_supp)
2646apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(coname1,trm{coname2:=(x).P},P,P[y\<turnstile>n>z],y,z,
2647                         trm[y\<turnstile>n>z]{coname2:=(x).P[y\<turnstile>n>z]})")
2648apply(erule exE, simp add: fresh_prod)
2649apply(erule conjE)+
2650apply(simp add: fresh_fun_simp_OrR1)
2651apply(rule trans)
2652apply(rule better_nrename_Cut)
2653apply(simp add: fresh_atm fresh_prod)
2654apply(simp add: rename_fresh fresh_atm)
2655apply(rule exists_fresh')
2656apply(rule fin_supp)
2657apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(coname1,trm{coname2:=(x).P},P,P[y\<turnstile>n>z],y,z,
2658                         trm[y\<turnstile>n>z]{coname2:=(x).P[y\<turnstile>n>z]})")
2659apply(erule exE, simp add: fresh_prod)
2660apply(erule conjE)+
2661apply(simp add: fresh_fun_simp_OrR2)
2662apply(rule trans)
2663apply(rule better_nrename_Cut)
2664apply(simp add: fresh_atm fresh_prod)
2665apply(simp add: rename_fresh fresh_atm)
2666apply(rule exists_fresh')
2667apply(rule fin_supp)
2668apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(coname1,trm{coname2:=(x).P},P,P[y\<turnstile>n>z],y,z,
2669                         trm[y\<turnstile>n>z]{coname2:=(x).P[y\<turnstile>n>z]})")
2670apply(erule exE, simp add: fresh_prod)
2671apply(erule conjE)+
2672apply(simp add: fresh_fun_simp_ImpR)
2673apply(rule trans)
2674apply(rule better_nrename_Cut)
2675apply(simp add: fresh_atm fresh_prod)
2676apply(simp add: rename_fresh fresh_atm)
2677apply(rule exists_fresh')
2678apply(rule fin_supp)
2679done
2680
2681lemma substn_crename_comm':
2682  assumes a: "a\<noteq>c" "a\<sharp>P"
2683  shows "M{x:=<c>.P}[a\<turnstile>c>b] = M[a\<turnstile>c>b]{x:=<c>.P}"
2684using a
2685proof -
2686  assume a1: "a\<noteq>c"
2687  assume a2: "a\<sharp>P"
2688  obtain c'::"coname" where fs2: "c'\<sharp>(c,P,a,b)" by (rule exists_fresh(2), rule fin_supp, blast)
2689  have eq: "M{x:=<c>.P} = M{x:=<c'>.([(c',c)]\<bullet>P)}"
2690    using fs2
2691    apply -
2692    apply(rule subst_rename)
2693    apply(simp)
2694    done
2695   have eq': "M[a\<turnstile>c>b]{x:=<c>.P} = M[a\<turnstile>c>b]{x:=<c'>.([(c',c)]\<bullet>P)}"
2696    using fs2
2697    apply -
2698    apply(rule subst_rename)
2699    apply(simp)
2700    done
2701  have eq2: "([(c',c)]\<bullet>P)[a\<turnstile>c>b] = ([(c',c)]\<bullet>P)" using fs2 a2 a1
2702    apply -
2703    apply(rule rename_fresh)
2704    apply(simp add: fresh_left calc_atm fresh_prod fresh_atm)
2705    done
2706  have "M{x:=<c>.P}[a\<turnstile>c>b] = M{x:=<c'>.([(c',c)]\<bullet>P)}[a\<turnstile>c>b]" using eq by simp
2707  also have "\<dots> = M[a\<turnstile>c>b]{x:=<c'>.(([(c',c)]\<bullet>P)[a\<turnstile>c>b])}"
2708    using fs2
2709    apply -
2710    apply(rule substn_crename_comm)
2711    apply(simp_all add: fresh_prod fresh_atm)
2712    done
2713  also have "\<dots> = M[a\<turnstile>c>b]{x:=<c'>.(([(c',c)]\<bullet>P))}" using eq2 by simp
2714  also have "\<dots> = M[a\<turnstile>c>b]{x:=<c>.P}" using eq' by simp 
2715  finally show ?thesis by simp
2716qed
2717
2718lemma substc_crename_comm':
2719  assumes a: "c\<noteq>a" "c\<noteq>b" "a\<sharp>P"
2720  shows "M{c:=(x).P}[a\<turnstile>c>b] = M[a\<turnstile>c>b]{c:=(x).P}"
2721using a
2722proof -
2723  assume a1: "c\<noteq>a"
2724  assume a1': "c\<noteq>b"
2725  assume a2: "a\<sharp>P"
2726  obtain c'::"coname" where fs2: "c'\<sharp>(c,M,a,b)" by (rule exists_fresh(2), rule fin_supp, blast)
2727  have eq: "M{c:=(x).P} = ([(c',c)]\<bullet>M){c':=(x).P}"
2728    using fs2
2729    apply -
2730    apply(rule subst_rename)
2731    apply(simp)
2732    done
2733   have eq': "([(c',c)]\<bullet>(M[a\<turnstile>c>b])){c':=(x).P} = M[a\<turnstile>c>b]{c:=(x).P}"
2734    using fs2
2735    apply -
2736    apply(rule subst_rename[symmetric])
2737    apply(simp add: rename_fresh)
2738    done
2739  have eq2: "([(c',c)]\<bullet>M)[a\<turnstile>c>b] = ([(c',c)]\<bullet>(M[a\<turnstile>c>b]))" using fs2 a2 a1 a1'
2740    apply -
2741    apply(simp add: rename_eqvts)
2742    apply(simp add: fresh_left calc_atm fresh_prod fresh_atm)
2743    done
2744  have "M{c:=(x).P}[a\<turnstile>c>b] = ([(c',c)]\<bullet>M){c':=(x).P}[a\<turnstile>c>b]" using eq by simp
2745  also have "\<dots> = ([(c',c)]\<bullet>M)[a\<turnstile>c>b]{c':=(x).P[a\<turnstile>c>b]}"
2746    using fs2
2747    apply -
2748    apply(rule substc_crename_comm)
2749    apply(simp_all add: fresh_prod fresh_atm)
2750    done
2751  also have "\<dots> = ([(c',c)]\<bullet>(M[a\<turnstile>c>b])){c':=(x).P[a\<turnstile>c>b]}" using eq2 by simp
2752  also have "\<dots> = ([(c',c)]\<bullet>(M[a\<turnstile>c>b])){c':=(x).P}" using a2 by (simp add: rename_fresh)
2753  also have "\<dots> = M[a\<turnstile>c>b]{c:=(x).P}" using eq' by simp
2754  finally show ?thesis by simp
2755qed
2756
2757lemma substn_nrename_comm':
2758  assumes a: "x\<noteq>y" "x\<noteq>z" "y\<sharp>P"
2759  shows "M{x:=<c>.P}[y\<turnstile>n>z] = M[y\<turnstile>n>z]{x:=<c>.P}"
2760using a
2761proof -
2762  assume a1: "x\<noteq>y"
2763  assume a1': "x\<noteq>z"
2764  assume a2: "y\<sharp>P"
2765  obtain x'::"name" where fs2: "x'\<sharp>(x,M,y,z)" by (rule exists_fresh(1), rule fin_supp, blast)
2766  have eq: "M{x:=<c>.P} = ([(x',x)]\<bullet>M){x':=<c>.P}"
2767    using fs2
2768    apply -
2769    apply(rule subst_rename)
2770    apply(simp)
2771    done
2772   have eq': "([(x',x)]\<bullet>(M[y\<turnstile>n>z])){x':=<c>.P} = M[y\<turnstile>n>z]{x:=<c>.P}"
2773    using fs2
2774    apply -
2775    apply(rule subst_rename[symmetric])
2776    apply(simp add: rename_fresh)
2777    done
2778  have eq2: "([(x',x)]\<bullet>M)[y\<turnstile>n>z] = ([(x',x)]\<bullet>(M[y\<turnstile>n>z]))" using fs2 a2 a1 a1'
2779    apply -
2780    apply(simp add: rename_eqvts)
2781    apply(simp add: fresh_left calc_atm fresh_prod fresh_atm)
2782    done
2783  have "M{x:=<c>.P}[y\<turnstile>n>z] = ([(x',x)]\<bullet>M){x':=<c>.P}[y\<turnstile>n>z]" using eq by simp
2784  also have "\<dots> = ([(x',x)]\<bullet>M)[y\<turnstile>n>z]{x':=<c>.P[y\<turnstile>n>z]}"
2785    using fs2
2786    apply -
2787    apply(rule substn_nrename_comm)
2788    apply(simp_all add: fresh_prod fresh_atm)
2789    done
2790  also have "\<dots> = ([(x',x)]\<bullet>(M[y\<turnstile>n>z])){x':=<c>.P[y\<turnstile>n>z]}" using eq2 by simp
2791  also have "\<dots> = ([(x',x)]\<bullet>(M[y\<turnstile>n>z])){x':=<c>.P}" using a2 by (simp add: rename_fresh)
2792  also have "\<dots> = M[y\<turnstile>n>z]{x:=<c>.P}" using eq' by simp
2793  finally show ?thesis by simp
2794qed
2795
2796lemma substc_nrename_comm':
2797  assumes a: "x\<noteq>y" "y\<sharp>P"
2798  shows "M{c:=(x).P}[y\<turnstile>n>z] = M[y\<turnstile>n>z]{c:=(x).P}"
2799using a
2800proof -
2801  assume a1: "x\<noteq>y"
2802  assume a2: "y\<sharp>P"
2803  obtain x'::"name" where fs2: "x'\<sharp>(x,P,y,z)" by (rule exists_fresh(1), rule fin_supp, blast)
2804  have eq: "M{c:=(x).P} = M{c:=(x').([(x',x)]\<bullet>P)}"
2805    using fs2
2806    apply -
2807    apply(rule subst_rename)
2808    apply(simp)
2809    done
2810   have eq': "M[y\<turnstile>n>z]{c:=(x).P} = M[y\<turnstile>n>z]{c:=(x').([(x',x)]\<bullet>P)}"
2811    using fs2
2812    apply -
2813    apply(rule subst_rename)
2814    apply(simp)
2815    done
2816  have eq2: "([(x',x)]\<bullet>P)[y\<turnstile>n>z] = ([(x',x)]\<bullet>P)" using fs2 a2 a1
2817    apply -
2818    apply(rule rename_fresh)
2819    apply(simp add: fresh_left calc_atm fresh_prod fresh_atm)
2820    done
2821  have "M{c:=(x).P}[y\<turnstile>n>z] = M{c:=(x').([(x',x)]\<bullet>P)}[y\<turnstile>n>z]" using eq by simp
2822  also have "\<dots> = M[y\<turnstile>n>z]{c:=(x').(([(x',x)]\<bullet>P)[y\<turnstile>n>z])}"
2823    using fs2
2824    apply -
2825    apply(rule substc_nrename_comm)
2826    apply(simp_all add: fresh_prod fresh_atm)
2827    done
2828  also have "\<dots> = M[y\<turnstile>n>z]{c:=(x').(([(x',x)]\<bullet>P))}" using eq2 by simp
2829  also have "\<dots> = M[y\<turnstile>n>z]{c:=(x).P}" using eq' by simp 
2830  finally show ?thesis by simp
2831qed
2832
2833lemmas subst_comm = substn_crename_comm substc_crename_comm
2834                    substn_nrename_comm substc_nrename_comm
2835lemmas subst_comm' = substn_crename_comm' substc_crename_comm'
2836                     substn_nrename_comm' substc_nrename_comm'
2837
2838text \<open>typing contexts\<close>
2839
2840type_synonym ctxtn = "(name\<times>ty) list"
2841type_synonym ctxtc = "(coname\<times>ty) list"
2842
2843inductive
2844  validc :: "ctxtc \<Rightarrow> bool"
2845where
2846  vc1[intro]: "validc []"
2847| vc2[intro]: "\<lbrakk>a\<sharp>\<Delta>; validc \<Delta>\<rbrakk> \<Longrightarrow> validc ((a,T)#\<Delta>)"
2848
2849equivariance validc
2850
2851inductive
2852  validn :: "ctxtn \<Rightarrow> bool"
2853where
2854  vn1[intro]: "validn []"
2855| vn2[intro]: "\<lbrakk>x\<sharp>\<Gamma>; validn \<Gamma>\<rbrakk> \<Longrightarrow> validn ((x,T)#\<Gamma>)"
2856
2857equivariance validn
2858
2859lemma fresh_ctxt:
2860  fixes a::"coname"
2861  and   x::"name"
2862  and   \<Gamma>::"ctxtn"
2863  and   \<Delta>::"ctxtc"
2864  shows "a\<sharp>\<Gamma>" and "x\<sharp>\<Delta>"
2865proof -
2866  show "a\<sharp>\<Gamma>" by (induct \<Gamma>) (auto simp add: fresh_list_nil fresh_list_cons fresh_prod fresh_atm fresh_ty)
2867next
2868  show "x\<sharp>\<Delta>" by (induct \<Delta>) (auto simp add: fresh_list_nil fresh_list_cons fresh_prod fresh_atm fresh_ty)
2869qed
2870
2871text \<open>cut-reductions\<close>
2872
2873declare abs_perm[eqvt]
2874
2875inductive
2876  fin :: "trm \<Rightarrow> name \<Rightarrow> bool"
2877where
2878  [intro]: "fin (Ax x a) x"
2879| [intro]: "x\<sharp>M \<Longrightarrow> fin (NotL <a>.M x) x"
2880| [intro]: "y\<sharp>[x].M \<Longrightarrow> fin (AndL1 (x).M y) y"
2881| [intro]: "y\<sharp>[x].M \<Longrightarrow> fin (AndL2 (x).M y) y"
2882| [intro]: "\<lbrakk>z\<sharp>[x].M;z\<sharp>[y].N\<rbrakk> \<Longrightarrow> fin (OrL (x).M (y).N z) z"
2883| [intro]: "\<lbrakk>y\<sharp>M;y\<sharp>[x].N\<rbrakk> \<Longrightarrow> fin (ImpL <a>.M (x).N y) y"
2884
2885equivariance fin
2886
2887lemma fin_Ax_elim:
2888  assumes a: "fin (Ax x a) y"
2889  shows "x=y"
2890using a
2891apply(erule_tac fin.cases)
2892apply(auto simp add: trm.inject)
2893done
2894
2895lemma fin_NotL_elim:
2896  assumes a: "fin (NotL <a>.M x) y"
2897  shows "x=y \<and> x\<sharp>M"
2898using a
2899apply(erule_tac fin.cases)
2900apply(auto simp add: trm.inject)
2901apply(subgoal_tac "y\<sharp>[aa].Ma")
2902apply(drule sym)
2903apply(simp_all add: abs_fresh)
2904done
2905
2906lemma fin_AndL1_elim:
2907  assumes a: "fin (AndL1 (x).M y) z"
2908  shows "z=y \<and> z\<sharp>[x].M"
2909using a
2910apply(erule_tac fin.cases)
2911apply(auto simp add: trm.inject)
2912done
2913
2914lemma fin_AndL2_elim:
2915  assumes a: "fin (AndL2 (x).M y) z"
2916  shows "z=y \<and> z\<sharp>[x].M"
2917using a
2918apply(erule_tac fin.cases)
2919apply(auto simp add: trm.inject)
2920done
2921
2922lemma fin_OrL_elim:
2923  assumes a: "fin (OrL (x).M (y).N u) z"
2924  shows "z=u \<and> z\<sharp>[x].M \<and> z\<sharp>[y].N"
2925using a
2926apply(erule_tac fin.cases)
2927apply(auto simp add: trm.inject)
2928done
2929
2930lemma fin_ImpL_elim:
2931  assumes a: "fin (ImpL <a>.M (x).N z) y"
2932  shows "z=y \<and> z\<sharp>M \<and> z\<sharp>[x].N"
2933using a
2934apply(erule_tac fin.cases)
2935apply(auto simp add: trm.inject)
2936apply(subgoal_tac "y\<sharp>[aa].Ma")
2937apply(drule sym)
2938apply(simp_all add: abs_fresh)
2939done
2940
2941lemma fin_rest_elims:
2942  shows "fin (Cut <a>.M (x).N) y \<Longrightarrow> False"
2943  and   "fin (NotR (x).M c) y \<Longrightarrow> False"
2944  and   "fin (AndR <a>.M <b>.N c) y \<Longrightarrow> False"
2945  and   "fin (OrR1 <a>.M b) y \<Longrightarrow> False"
2946  and   "fin (OrR2 <a>.M b) y \<Longrightarrow> False"
2947  and   "fin (ImpR (x).<a>.M b) y \<Longrightarrow> False"
2948by (erule fin.cases, simp_all add: trm.inject)+
2949
2950lemmas fin_elims = fin_Ax_elim fin_NotL_elim fin_AndL1_elim fin_AndL2_elim fin_OrL_elim 
2951                   fin_ImpL_elim fin_rest_elims
2952
2953lemma fin_rename:
2954  shows "fin M x \<Longrightarrow> fin ([(x',x)]\<bullet>M) x'"
2955by (induct rule: fin.induct)
2956   (auto simp add: calc_atm simp add: fresh_left abs_fresh)
2957
2958lemma not_fin_subst1:
2959  assumes a: "\<not>(fin M x)" 
2960  shows "\<not>(fin (M{c:=(y).P}) x)"
2961using a
2962apply(nominal_induct M avoiding: x c y P rule: trm.strong_induct)
2963apply(auto)
2964apply(drule fin_elims, simp)
2965apply(drule fin_elims, simp)
2966apply(drule fin_elims, simp)
2967apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm{coname:=(y).P},P,x)")
2968apply(erule exE)
2969apply(simp add: fresh_prod)
2970apply(erule conjE)+
2971apply(simp add: fresh_fun_simp_NotR)
2972apply(erule fin.cases, simp_all add: trm.inject)
2973apply(rule exists_fresh'(2)[OF fs_coname1])
2974apply(drule fin_elims, simp)
2975apply(drule fin_elims)
2976apply(auto)[1]
2977apply(drule freshn_after_substc)
2978apply(simp add: fin.intros)
2979apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm1{coname3:=(y).P},trm2{coname3:=(y).P},P,coname1,coname2,coname3,x)")
2980apply(erule exE)
2981apply(simp add: fresh_prod)
2982apply(erule conjE)+
2983apply(simp add: fresh_fun_simp_AndR)
2984apply(erule fin.cases, simp_all add: trm.inject)
2985apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm1{coname3:=(y).P},trm2{coname3:=(y).P},P,coname1,coname2,coname3,x)")
2986apply(erule exE)
2987apply(simp add: fresh_prod)
2988apply(erule conjE)+
2989apply(simp add: fresh_fun_simp_AndR)
2990apply(erule fin.cases, simp_all add: trm.inject)
2991apply(rule exists_fresh'(2)[OF fs_coname1])
2992apply(erule fin.cases, simp_all add: trm.inject)
2993apply(drule fin_AndL1_elim)
2994apply(auto simp add: abs_fresh)[1]
2995apply(drule freshn_after_substc)
2996apply(subgoal_tac "name2\<sharp>[name1]. trm")
2997apply(simp add: fin.intros)
2998apply(simp add: abs_fresh)
2999apply(drule fin_AndL2_elim)
3000apply(auto simp add: abs_fresh)[1]
3001apply(drule freshn_after_substc)
3002apply(subgoal_tac "name2\<sharp>[name1].trm")
3003apply(simp add: fin.intros)
3004apply(simp add: abs_fresh)
3005apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm{coname2:=(y).P},coname1,P,x)")
3006apply(erule exE)
3007apply(simp add: fresh_prod)
3008apply(erule conjE)+
3009apply(simp add: fresh_fun_simp_OrR1)
3010apply(erule fin.cases, simp_all add: trm.inject)
3011apply(rule exists_fresh'(2)[OF fs_coname1])
3012apply(erule fin.cases, simp_all add: trm.inject)
3013apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm{coname2:=(y).P},coname1,P,x)")
3014apply(erule exE)
3015apply(simp add: fresh_prod)
3016apply(erule conjE)+
3017apply(simp add: fresh_fun_simp_OrR2)
3018apply(erule fin.cases, simp_all add: trm.inject)
3019apply(rule exists_fresh'(2)[OF fs_coname1])
3020apply(erule fin.cases, simp_all add: trm.inject)
3021apply(drule fin_OrL_elim)
3022apply(auto simp add: abs_fresh)[1]
3023apply(drule freshn_after_substc)+
3024apply(subgoal_tac "name3\<sharp>[name1].trm1 \<and> name3\<sharp>[name2].trm2")
3025apply(simp add: fin.intros)
3026apply(simp add: abs_fresh)
3027apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm{coname2:=(y).P},coname1,P,x)")
3028apply(erule exE)
3029apply(simp add: fresh_prod)
3030apply(erule conjE)+
3031apply(simp add: fresh_fun_simp_ImpR)
3032apply(erule fin.cases, simp_all add: trm.inject)
3033apply(rule exists_fresh'(2)[OF fs_coname1])
3034apply(erule fin.cases, simp_all add: trm.inject)
3035apply(drule fin_ImpL_elim)
3036apply(auto simp add: abs_fresh)[1]
3037apply(drule freshn_after_substc)+
3038apply(subgoal_tac "x\<sharp>[name1].trm2")
3039apply(simp add: fin.intros)
3040apply(simp add: abs_fresh)
3041done
3042
3043lemma not_fin_subst2:
3044  assumes a: "\<not>(fin M x)" 
3045  shows "\<not>(fin (M{y:=<c>.P}) x)"
3046using a
3047apply(nominal_induct M avoiding: x c y P rule: trm.strong_induct)
3048apply(auto)
3049apply(erule fin.cases, simp_all add: trm.inject)
3050apply(erule fin.cases, simp_all add: trm.inject)
3051apply(erule fin.cases, simp_all add: trm.inject)
3052apply(erule fin.cases, simp_all add: trm.inject)
3053apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(trm{y:=<c>.P},P,x)")
3054apply(erule exE)
3055apply(simp add: fresh_prod)
3056apply(erule conjE)+
3057apply(simp add: fresh_fun_simp_NotL)
3058apply(erule fin.cases, simp_all add: trm.inject)
3059apply(rule exists_fresh'(1)[OF fs_name1])
3060apply(drule fin_NotL_elim)
3061apply(auto)[1]
3062apply(drule freshn_after_substn)
3063apply(simp)
3064apply(simp add: fin.intros)
3065apply(erule fin.cases, simp_all add: trm.inject)
3066apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(trm{y:=<c>.P},P,name1,x)")
3067apply(erule exE)
3068apply(simp add: fresh_prod)
3069apply(erule conjE)+
3070apply(simp add: fresh_fun_simp_AndL1)
3071apply(erule fin.cases, simp_all add: trm.inject)
3072apply(rule exists_fresh'(1)[OF fs_name1])
3073apply(drule fin_AndL1_elim)
3074apply(auto simp add: abs_fresh)[1]
3075apply(drule freshn_after_substn)
3076apply(simp)
3077apply(subgoal_tac "name2\<sharp>[name1]. trm")
3078apply(simp add: fin.intros)
3079apply(simp add: abs_fresh)
3080apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(trm{y:=<c>.P},P,name1,x)")
3081apply(erule exE)
3082apply(simp add: fresh_prod)
3083apply(erule conjE)+
3084apply(simp add: fresh_fun_simp_AndL2)
3085apply(erule fin.cases, simp_all add: trm.inject)
3086apply(rule exists_fresh'(1)[OF fs_name1])
3087apply(drule fin_AndL2_elim)
3088apply(auto simp add: abs_fresh)[1]
3089apply(drule freshn_after_substn)
3090apply(simp)
3091apply(subgoal_tac "name2\<sharp>[name1].trm")
3092apply(simp add: fin.intros)
3093apply(simp add: abs_fresh)
3094apply(erule fin.cases, simp_all add: trm.inject)
3095apply(erule fin.cases, simp_all add: trm.inject)
3096apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(trm1{y:=<c>.P},trm2{y:=<c>.P},name1,name2,P,x)")
3097apply(erule exE)
3098apply(simp add: fresh_prod)
3099apply(erule conjE)+
3100apply(simp add: fresh_fun_simp_OrL)
3101apply(erule fin.cases, simp_all add: trm.inject)
3102apply(rule exists_fresh'(1)[OF fs_name1])
3103apply(drule fin_OrL_elim)
3104apply(auto simp add: abs_fresh)[1]
3105apply(drule freshn_after_substn)
3106apply(simp)
3107apply(drule freshn_after_substn)
3108apply(simp)
3109apply(subgoal_tac "name3\<sharp>[name1].trm1 \<and> name3\<sharp>[name2].trm2")
3110apply(simp add: fin.intros)
3111apply(simp add: abs_fresh)
3112apply(erule fin.cases, simp_all add: trm.inject)
3113apply(subgoal_tac "\<exists>a'::name. a'\<sharp>(trm1{name2:=<c>.P},trm2{name2:=<c>.P},name1,P,x)")
3114apply(erule exE)
3115apply(simp add: fresh_prod)
3116apply(erule conjE)+
3117apply(simp add: fresh_fun_simp_ImpL)
3118apply(erule fin.cases, simp_all add: trm.inject)
3119apply(rule exists_fresh'(1)[OF fs_name1])
3120apply(drule fin_ImpL_elim)
3121apply(auto simp add: abs_fresh)[1]
3122apply(drule freshn_after_substn)
3123apply(simp)
3124apply(drule freshn_after_substn)
3125apply(simp)
3126apply(subgoal_tac "x\<sharp>[name1].trm2")
3127apply(simp add: fin.intros)
3128apply(simp add: abs_fresh)
3129done
3130
3131lemma fin_subst1:
3132  assumes a: "fin M x" "x\<noteq>y" "x\<sharp>P"
3133  shows "fin (M{y:=<c>.P}) x"
3134using a
3135apply(nominal_induct M avoiding: x y c P rule: trm.strong_induct)
3136apply(auto dest!: fin_elims simp add: subst_fresh abs_fresh)
3137apply(rule fin.intros, simp add: subst_fresh abs_fresh)
3138apply(rule fin.intros, simp add: subst_fresh abs_fresh)
3139apply(rule fin.intros, simp add: subst_fresh abs_fresh)
3140apply(rule fin.intros, simp add: subst_fresh abs_fresh)
3141apply(rule fin.intros, simp add: subst_fresh abs_fresh, simp add: subst_fresh abs_fresh)
3142apply(rule fin.intros, simp add: subst_fresh abs_fresh, simp add: subst_fresh abs_fresh)
3143apply(rule fin.intros, simp add: subst_fresh abs_fresh, simp add: subst_fresh abs_fresh)
3144apply(rule fin.intros, simp add: subst_fresh abs_fresh, simp add: subst_fresh abs_fresh)
3145apply(rule fin.intros, simp add: subst_fresh abs_fresh, simp add: subst_fresh abs_fresh)
3146done
3147
3148lemma fin_subst2:
3149  assumes a: "fin M y" "x\<noteq>y" "y\<sharp>P" "M\<noteq>Ax y c" 
3150  shows "fin (M{c:=(x).P}) y"
3151using a
3152apply(nominal_induct M avoiding: x y c P rule: trm.strong_induct)
3153apply(drule fin_elims)
3154apply(simp add: trm.inject)
3155apply(rule fin.intros)
3156apply(drule fin_elims, simp)
3157apply(drule fin_elims, simp)
3158apply(drule fin_elims, simp)
3159apply(rule fin.intros)
3160apply(auto)[1]
3161apply(rule subst_fresh)
3162apply(simp)
3163apply(drule fin_elims, simp)
3164apply(drule fin_elims, simp)
3165apply(rule fin.intros)
3166apply(simp add: abs_fresh fresh_atm)
3167apply(rule subst_fresh)
3168apply(auto)[1]
3169apply(drule fin_elims, simp)
3170apply(rule fin.intros)
3171apply(simp add: abs_fresh fresh_atm)
3172apply(rule subst_fresh)
3173apply(auto)[1]
3174apply(drule fin_elims, simp)
3175apply(drule fin_elims, simp)
3176apply(drule fin_elims, simp)
3177apply(rule fin.intros)
3178apply(simp add: abs_fresh fresh_atm)
3179apply(rule subst_fresh)
3180apply(auto)[1]
3181apply(simp add: abs_fresh fresh_atm)
3182apply(rule subst_fresh)
3183apply(auto)[1]
3184apply(drule fin_elims, simp)
3185apply(drule fin_elims, simp)
3186apply(rule fin.intros)
3187apply(simp add: abs_fresh fresh_atm)
3188apply(rule subst_fresh)
3189apply(auto)[1]
3190apply(simp add: abs_fresh fresh_atm)
3191apply(rule subst_fresh)
3192apply(auto)[1]
3193done
3194
3195lemma fin_substn_nrename:
3196  assumes a: "fin M x" "x\<noteq>y" "x\<sharp>P"
3197  shows "M[x\<turnstile>n>y]{y:=<c>.P} = Cut <c>.P (x).(M{y:=<c>.P})"
3198using a
3199apply(nominal_induct M avoiding: x y c P rule: trm.strong_induct)
3200apply(drule fin_Ax_elim)
3201apply(simp)
3202apply(simp add: trm.inject)
3203apply(simp add: alpha calc_atm fresh_atm)
3204apply(simp)
3205apply(drule fin_rest_elims)
3206apply(simp)
3207apply(drule fin_rest_elims)
3208apply(simp)
3209apply(drule fin_NotL_elim)
3210apply(simp)
3211apply(subgoal_tac "\<exists>z::name. z\<sharp>(trm,y,x,P,trm[x\<turnstile>n>y]{y:=<c>.P})")
3212apply(erule exE, simp add: fresh_prod)
3213apply(erule conjE)+
3214apply(simp add: fresh_fun_simp_NotL)
3215apply(simp add: trm.inject alpha fresh_atm calc_atm abs_fresh)
3216apply(rule conjI)
3217apply(simp add: nsubst_eqvt calc_atm)
3218apply(simp add: perm_fresh_fresh)
3219apply(simp add: nrename_fresh)
3220apply(rule subst_fresh)
3221apply(simp)
3222apply(rule exists_fresh')
3223apply(rule fin_supp)
3224apply(drule fin_rest_elims)
3225apply(simp)
3226apply(drule fin_AndL1_elim)
3227apply(simp)
3228apply(subgoal_tac "\<exists>z::name. z\<sharp>(name2,name1,P,trm[name2\<turnstile>n>y]{y:=<c>.P},y,P,trm)")
3229apply(erule exE, simp add: fresh_prod)
3230apply(erule conjE)+
3231apply(simp add: fresh_fun_simp_AndL1)
3232apply(simp add: trm.inject alpha fresh_atm calc_atm abs_fresh)
3233apply(rule conjI)
3234apply(simp add: nsubst_eqvt calc_atm)
3235apply(simp add: perm_fresh_fresh)
3236apply(simp add: nrename_fresh)
3237apply(rule subst_fresh)
3238apply(simp)
3239apply(rule exists_fresh')
3240apply(rule fin_supp)
3241apply(drule fin_AndL2_elim)
3242apply(simp)
3243apply(subgoal_tac "\<exists>z::name. z\<sharp>(name2,name1,P,trm[name2\<turnstile>n>y]{y:=<c>.P},y,P,trm)")
3244apply(erule exE, simp add: fresh_prod)
3245apply(erule conjE)+
3246apply(simp add: fresh_fun_simp_AndL2)
3247apply(simp add: trm.inject alpha fresh_atm calc_atm abs_fresh)
3248apply(rule conjI)
3249apply(simp add: nsubst_eqvt calc_atm)
3250apply(simp add: perm_fresh_fresh)
3251apply(simp add: nrename_fresh)
3252apply(rule subst_fresh)
3253apply(simp)
3254apply(rule exists_fresh')
3255apply(rule fin_supp)
3256apply(drule fin_rest_elims)
3257apply(simp)
3258apply(drule fin_rest_elims)
3259apply(simp)
3260apply(drule fin_OrL_elim)
3261apply(simp add: abs_fresh)
3262apply(simp add: subst_fresh rename_fresh)
3263apply(subgoal_tac "\<exists>z::name. z\<sharp>(name3,name2,name1,P,trm1[name3\<turnstile>n>y]{y:=<c>.P},trm2[name3\<turnstile>n>y]{y:=<c>.P},y,P,trm1,trm2)")
3264apply(erule exE, simp add: fresh_prod)
3265apply(erule conjE)+
3266apply(simp add: fresh_fun_simp_OrL)
3267apply(simp add: trm.inject alpha fresh_atm calc_atm abs_fresh)
3268apply(rule conjI)
3269apply(simp add: nsubst_eqvt calc_atm)
3270apply(simp add: perm_fresh_fresh)
3271apply(simp add: nrename_fresh)
3272apply(simp add: nsubst_eqvt calc_atm)
3273apply(simp add: perm_fresh_fresh)
3274apply(simp add: nrename_fresh)
3275apply(rule exists_fresh')
3276apply(rule fin_supp)
3277apply(drule fin_rest_elims)
3278apply(simp)
3279apply(drule fin_ImpL_elim)
3280apply(simp add: abs_fresh)
3281apply(simp add: subst_fresh rename_fresh)
3282apply(subgoal_tac "\<exists>z::name. z\<sharp>(name1,x,P,trm1[x\<turnstile>n>y]{y:=<c>.P},trm2[x\<turnstile>n>y]{y:=<c>.P},y,P,trm1,trm2)")
3283apply(erule exE, simp add: fresh_prod)
3284apply(erule conjE)+
3285apply(simp add: fresh_fun_simp_ImpL)
3286apply(simp add: trm.inject alpha fresh_atm calc_atm abs_fresh)
3287apply(rule conjI)
3288apply(simp add: nsubst_eqvt calc_atm)
3289apply(simp add: perm_fresh_fresh)
3290apply(simp add: nrename_fresh)
3291apply(simp add: nsubst_eqvt calc_atm)
3292apply(simp add: perm_fresh_fresh)
3293apply(simp add: nrename_fresh)
3294apply(rule exists_fresh')
3295apply(rule fin_supp)
3296done
3297
3298inductive
3299  fic :: "trm \<Rightarrow> coname \<Rightarrow> bool"
3300where
3301  [intro]: "fic (Ax x a) a"
3302| [intro]: "a\<sharp>M \<Longrightarrow> fic (NotR (x).M a) a"
3303| [intro]: "\<lbrakk>c\<sharp>[a].M;c\<sharp>[b].N\<rbrakk> \<Longrightarrow> fic (AndR <a>.M <b>.N c) c"
3304| [intro]: "b\<sharp>[a].M \<Longrightarrow> fic (OrR1 <a>.M b) b"
3305| [intro]: "b\<sharp>[a].M \<Longrightarrow> fic (OrR2 <a>.M b) b"
3306| [intro]: "\<lbrakk>b\<sharp>[a].M\<rbrakk> \<Longrightarrow> fic (ImpR (x).<a>.M b) b"
3307
3308equivariance fic
3309
3310lemma fic_Ax_elim:
3311  assumes a: "fic (Ax x a) b"
3312  shows "a=b"
3313using a
3314apply(erule_tac fic.cases)
3315apply(auto simp add: trm.inject)
3316done
3317
3318lemma fic_NotR_elim:
3319  assumes a: "fic (NotR (x).M a) b"
3320  shows "a=b \<and> b\<sharp>M"
3321using a
3322apply(erule_tac fic.cases)
3323apply(auto simp add: trm.inject)
3324apply(subgoal_tac "b\<sharp>[xa].Ma")
3325apply(drule sym)
3326apply(simp_all add: abs_fresh)
3327done
3328
3329lemma fic_OrR1_elim:
3330  assumes a: "fic (OrR1 <a>.M b) c"
3331  shows "b=c \<and> c\<sharp>[a].M"
3332using a
3333apply(erule_tac fic.cases)
3334apply(auto simp add: trm.inject)
3335done
3336
3337lemma fic_OrR2_elim:
3338  assumes a: "fic (OrR2 <a>.M b) c"
3339  shows "b=c \<and> c\<sharp>[a].M"
3340using a
3341apply(erule_tac fic.cases)
3342apply(auto simp add: trm.inject)
3343done
3344
3345lemma fic_AndR_elim:
3346  assumes a: "fic (AndR <a>.M <b>.N c) d"
3347  shows "c=d \<and> d\<sharp>[a].M \<and> d\<sharp>[b].N"
3348using a
3349apply(erule_tac fic.cases)
3350apply(auto simp add: trm.inject)
3351done
3352
3353lemma fic_ImpR_elim:
3354  assumes a: "fic (ImpR (x).<a>.M b) c"
3355  shows "b=c \<and> b\<sharp>[a].M"
3356using a
3357apply(erule_tac fic.cases)
3358apply(auto simp add: trm.inject)
3359apply(subgoal_tac "c\<sharp>[xa].[aa].Ma")
3360apply(drule sym)
3361apply(simp_all add: abs_fresh)
3362done
3363
3364lemma fic_rest_elims:
3365  shows "fic (Cut <a>.M (x).N) d \<Longrightarrow> False"
3366  and   "fic (NotL <a>.M x) d \<Longrightarrow> False"
3367  and   "fic (OrL (x).M (y).N z) d \<Longrightarrow> False"
3368  and   "fic (AndL1 (x).M y) d \<Longrightarrow> False"
3369  and   "fic (AndL2 (x).M y) d \<Longrightarrow> False"
3370  and   "fic (ImpL <a>.M (x).N y) d \<Longrightarrow> False"
3371by (erule fic.cases, simp_all add: trm.inject)+
3372
3373lemmas fic_elims = fic_Ax_elim fic_NotR_elim fic_OrR1_elim fic_OrR2_elim fic_AndR_elim 
3374                   fic_ImpR_elim fic_rest_elims
3375
3376lemma fic_rename:
3377  shows "fic M a \<Longrightarrow> fic ([(a',a)]\<bullet>M) a'"
3378by (induct rule: fic.induct)
3379   (auto simp add: calc_atm simp add: fresh_left abs_fresh)
3380
3381lemma not_fic_subst1:
3382  assumes a: "\<not>(fic M a)" 
3383  shows "\<not>(fic (M{y:=<c>.P}) a)"
3384using a
3385apply(nominal_induct M avoiding: a c y P rule: trm.strong_induct)
3386apply(auto)
3387apply(drule fic_elims, simp)
3388apply(drule fic_elims, simp)
3389apply(drule fic_elims, simp)
3390apply(drule fic_elims)
3391apply(auto)[1]
3392apply(drule freshc_after_substn)
3393apply(simp add: fic.intros)
3394apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,a)")
3395apply(erule exE)
3396apply(simp add: fresh_prod)
3397apply(erule conjE)+
3398apply(simp add: fresh_fun_simp_NotL)
3399apply(drule fic_elims, simp)
3400apply(rule exists_fresh'(1)[OF fs_name1])
3401apply(drule fic_elims, simp)
3402apply(drule fic_elims)
3403apply(auto)[1]
3404apply(simp add: abs_fresh fresh_atm)
3405apply(drule freshc_after_substn)
3406apply(drule freshc_after_substn)
3407apply(simp add: fic.intros abs_fresh)
3408apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1,a)")
3409apply(erule exE)
3410apply(simp add: fresh_prod)
3411apply(erule conjE)+
3412apply(simp add: fresh_fun_simp_AndL1)
3413apply(drule fic_elims, simp)
3414apply(rule exists_fresh'(1)[OF fs_name1])
3415apply(drule fic_elims, simp)
3416apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{y:=<c>.P},P,name1,a)")
3417apply(erule exE)
3418apply(simp add: fresh_prod)
3419apply(erule conjE)+
3420apply(simp add: fresh_fun_simp_AndL2)
3421apply(drule fic_elims, simp)
3422apply(rule exists_fresh'(1)[OF fs_name1])
3423apply(drule fic_elims, simp)
3424apply(drule fic_elims)
3425apply(auto)[1]
3426apply(simp add: abs_fresh fresh_atm)
3427apply(drule freshc_after_substn)
3428apply(simp add: fic.intros abs_fresh)
3429apply(drule fic_elims)
3430apply(auto)[1]
3431apply(simp add: abs_fresh fresh_atm)
3432apply(drule freshc_after_substn)
3433apply(simp add: fic.intros abs_fresh)
3434apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{y:=<c>.P},trm2{y:=<c>.P},P,name1,name2,a)")
3435apply(erule exE)
3436apply(simp add: fresh_prod)
3437apply(erule conjE)+
3438apply(simp add: fresh_fun_simp_OrL)
3439apply(drule fic_elims, simp)
3440apply(rule exists_fresh'(1)[OF fs_name1])
3441apply(drule fic_elims, simp)
3442apply(drule fic_elims, simp)
3443apply(auto)[1]
3444apply(simp add: abs_fresh fresh_atm)
3445apply(drule freshc_after_substn)
3446apply(simp add: fic.intros abs_fresh)
3447apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},trm2{name2:=<c>.P},P,name1,name2,a)")
3448apply(erule exE)
3449apply(simp add: fresh_prod)
3450apply(erule conjE)+
3451apply(simp add: fresh_fun_simp_ImpL)
3452apply(drule fic_elims, simp)
3453apply(rule exists_fresh'(1)[OF fs_name1])
3454apply(drule fic_elims, simp)
3455done
3456
3457lemma not_fic_subst2:
3458  assumes a: "\<not>(fic M a)" 
3459  shows "\<not>(fic (M{c:=(y).P}) a)"
3460using a
3461apply(nominal_induct M avoiding: a c y P rule: trm.strong_induct)
3462apply(auto)
3463apply(drule fic_elims, simp)
3464apply(drule fic_elims, simp)
3465apply(drule fic_elims, simp)
3466apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm{coname:=(y).P},P,a)")
3467apply(erule exE)
3468apply(simp add: fresh_prod)
3469apply(erule conjE)+
3470apply(simp add: fresh_fun_simp_NotR)
3471apply(drule fic_elims, simp)
3472apply(rule exists_fresh'(2)[OF fs_coname1])
3473apply(drule fic_elims, simp)
3474apply(erule conjE)+
3475apply(drule freshc_after_substc)
3476apply(simp)
3477apply(simp add: fic.intros abs_fresh)
3478apply(drule fic_elims, simp)
3479apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm1{coname3:=(y).P},trm2{coname3:=(y).P},P,coname1,coname2,a)")
3480apply(erule exE)
3481apply(simp add: fresh_prod)
3482apply(erule conjE)+
3483apply(simp add: fresh_fun_simp_AndR)
3484apply(drule fic_elims, simp)
3485apply(rule exists_fresh'(2)[OF fs_coname1])
3486apply(drule fic_elims, simp)
3487apply(auto)[1]
3488apply(simp add: abs_fresh fresh_atm)
3489apply(drule freshc_after_substc)
3490apply(simp)
3491apply(drule freshc_after_substc)
3492apply(simp)
3493apply(simp add: fic.intros abs_fresh)
3494apply(drule fic_elims, simp)
3495apply(drule fic_elims, simp)
3496apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm{coname2:=(y).P},P,coname1,a)")
3497apply(erule exE)
3498apply(simp add: fresh_prod)
3499apply(erule conjE)+
3500apply(simp add: fresh_fun_simp_OrR1)
3501apply(drule fic_elims, simp)
3502apply(rule exists_fresh'(2)[OF fs_coname1])
3503apply(drule fic_elims, simp)
3504apply(auto)[1]
3505apply(simp add: abs_fresh fresh_atm)
3506apply(drule freshc_after_substc)
3507apply(simp)
3508apply(simp add: fic.intros abs_fresh)
3509apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm{coname2:=(y).P},P,coname1,a)")
3510apply(erule exE)
3511apply(simp add: fresh_prod)
3512apply(erule conjE)+
3513apply(simp add: fresh_fun_simp_OrR2)
3514apply(drule fic_elims, simp)
3515apply(rule exists_fresh'(2)[OF fs_coname1])
3516apply(drule fic_elims, simp)
3517apply(auto)[1]
3518apply(simp add: abs_fresh fresh_atm)
3519apply(drule freshc_after_substc)
3520apply(simp)
3521apply(simp add: fic.intros abs_fresh)
3522apply(drule fic_elims, simp)
3523apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm{coname2:=(y).P},P,coname1,a)")
3524apply(erule exE)
3525apply(simp add: fresh_prod)
3526apply(erule conjE)+
3527apply(simp add: fresh_fun_simp_ImpR)
3528apply(drule fic_elims, simp)
3529apply(rule exists_fresh'(2)[OF fs_coname1])
3530apply(drule fic_elims, simp)
3531apply(auto)[1]
3532apply(simp add: abs_fresh fresh_atm)
3533apply(drule freshc_after_substc)
3534apply(simp)
3535apply(simp add: fic.intros abs_fresh)
3536apply(drule fic_elims, simp)
3537done
3538
3539lemma fic_subst1:
3540  assumes a: "fic M a" "a\<noteq>b" "a\<sharp>P"
3541  shows "fic (M{b:=(x).P}) a"
3542using a
3543apply(nominal_induct M avoiding: x b a P rule: trm.strong_induct)
3544apply(drule fic_elims)
3545apply(simp add: fic.intros)
3546apply(drule fic_elims, simp)
3547apply(drule fic_elims, simp)
3548apply(rule fic.intros)
3549apply(auto)[1]
3550apply(rule subst_fresh)
3551apply(simp)
3552apply(drule fic_elims, simp)
3553apply(drule fic_elims, simp)
3554apply(rule fic.intros)
3555apply(simp add: abs_fresh fresh_atm)
3556apply(rule subst_fresh)
3557apply(auto)[1]
3558apply(simp add: abs_fresh fresh_atm)
3559apply(rule subst_fresh)
3560apply(auto)[1]
3561apply(drule fic_elims, simp)
3562apply(drule fic_elims, simp)
3563apply(drule fic_elims, simp)
3564apply(rule fic.intros)
3565apply(simp add: abs_fresh fresh_atm)
3566apply(rule subst_fresh)
3567apply(auto)[1]
3568apply(drule fic_elims, simp)
3569apply(rule fic.intros)
3570apply(simp add: abs_fresh fresh_atm)
3571apply(rule subst_fresh)
3572apply(auto)[1]
3573apply(drule fic_elims, simp)
3574apply(drule fic_elims, simp)
3575apply(rule fic.intros)
3576apply(simp add: abs_fresh fresh_atm)
3577apply(rule subst_fresh)
3578apply(auto)[1]
3579apply(drule fic_elims, simp)
3580done
3581
3582lemma fic_subst2:
3583  assumes a: "fic M a" "c\<noteq>a" "a\<sharp>P" "M\<noteq>Ax x a" 
3584  shows "fic (M{x:=<c>.P}) a"
3585using a
3586apply(nominal_induct M avoiding: x a c P rule: trm.strong_induct)
3587apply(drule fic_elims)
3588apply(simp add: trm.inject)
3589apply(rule fic.intros)
3590apply(drule fic_elims, simp)
3591apply(drule fic_elims, simp)
3592apply(rule fic.intros)
3593apply(auto)[1]
3594apply(rule subst_fresh)
3595apply(simp)
3596apply(drule fic_elims, simp)
3597apply(drule fic_elims, simp)
3598apply(rule fic.intros)
3599apply(simp add: abs_fresh fresh_atm)
3600apply(rule subst_fresh)
3601apply(auto)[1]
3602apply(simp add: abs_fresh fresh_atm)
3603apply(rule subst_fresh)
3604apply(auto)[1]
3605apply(drule fic_elims, simp)
3606apply(drule fic_elims, simp)
3607apply(drule fic_elims, simp)
3608apply(rule fic.intros)
3609apply(simp add: abs_fresh fresh_atm)
3610apply(rule subst_fresh)
3611apply(auto)[1]
3612apply(drule fic_elims, simp)
3613apply(rule fic.intros)
3614apply(simp add: abs_fresh fresh_atm)
3615apply(rule subst_fresh)
3616apply(auto)[1]
3617apply(drule fic_elims, simp)
3618apply(drule fic_elims, simp)
3619apply(rule fic.intros)
3620apply(simp add: abs_fresh fresh_atm)
3621apply(rule subst_fresh)
3622apply(auto)[1]
3623apply(drule fic_elims, simp)
3624done
3625
3626lemma fic_substc_crename:
3627  assumes a: "fic M a" "a\<noteq>b" "a\<sharp>P"
3628  shows "M[a\<turnstile>c>b]{b:=(y).P} = Cut <a>.(M{b:=(y).P}) (y).P"
3629using a
3630apply(nominal_induct M avoiding: a b  y P rule: trm.strong_induct)
3631apply(drule fic_Ax_elim)
3632apply(simp)
3633apply(simp add: trm.inject)
3634apply(simp add: alpha calc_atm fresh_atm trm.inject)
3635apply(simp)
3636apply(drule fic_rest_elims)
3637apply(simp)
3638apply(drule fic_NotR_elim)
3639apply(simp)
3640apply(generate_fresh "coname")
3641apply(fresh_fun_simp)
3642apply(simp add: trm.inject alpha fresh_atm fresh_prod fresh_atm calc_atm abs_fresh)
3643apply(rule conjI)
3644apply(simp add: csubst_eqvt calc_atm)
3645apply(simp add: perm_fresh_fresh)
3646apply(simp add: crename_fresh)
3647apply(rule subst_fresh)
3648apply(simp)
3649apply(drule fic_rest_elims)
3650apply(simp)
3651apply(drule fic_AndR_elim)
3652apply(simp add: abs_fresh fresh_atm subst_fresh rename_fresh)
3653apply(generate_fresh "coname")
3654apply(fresh_fun_simp)
3655apply(simp add: trm.inject alpha fresh_atm calc_atm abs_fresh fresh_prod)
3656apply(rule conjI)
3657apply(simp add: csubst_eqvt calc_atm)
3658apply(simp add: perm_fresh_fresh)
3659apply(simp add: csubst_eqvt calc_atm)
3660apply(simp add: perm_fresh_fresh)
3661apply(simp add: subst_fresh)
3662apply(drule fic_rest_elims)
3663apply(simp)
3664apply(drule fic_rest_elims)
3665apply(simp)
3666apply(drule fic_OrR1_elim)
3667apply(simp)
3668apply(generate_fresh "coname")
3669apply(fresh_fun_simp)
3670apply(simp add: trm.inject alpha fresh_atm calc_atm abs_fresh fresh_prod)
3671apply(simp add: csubst_eqvt calc_atm)
3672apply(simp add: perm_fresh_fresh)
3673apply(simp add: subst_fresh rename_fresh)
3674apply(drule fic_OrR2_elim)
3675apply(simp add: abs_fresh fresh_atm)
3676apply(generate_fresh "coname")
3677apply(fresh_fun_simp)
3678apply(simp add: trm.inject alpha fresh_atm calc_atm abs_fresh fresh_prod)
3679apply(simp add: csubst_eqvt calc_atm)
3680apply(simp add: perm_fresh_fresh)
3681apply(simp add: subst_fresh rename_fresh)
3682apply(drule fic_rest_elims)
3683apply(simp)
3684apply(drule fic_ImpR_elim)
3685apply(simp add: abs_fresh fresh_atm)
3686apply(auto)[1]
3687apply(generate_fresh "coname")
3688apply(fresh_fun_simp)
3689apply(simp add: trm.inject alpha fresh_atm calc_atm abs_fresh fresh_prod)
3690apply(simp add: csubst_eqvt calc_atm)
3691apply(simp add: perm_fresh_fresh)
3692apply(simp add: subst_fresh rename_fresh)
3693apply(drule fic_rest_elims)
3694apply(simp)
3695done
3696
3697inductive
3698  l_redu :: "trm \<Rightarrow> trm \<Rightarrow> bool" ("_ \<longrightarrow>\<^sub>l _" [100,100] 100)
3699where
3700  LAxR:  "\<lbrakk>x\<sharp>M; a\<sharp>b; fic M a\<rbrakk> \<Longrightarrow> Cut <a>.M (x).(Ax x b) \<longrightarrow>\<^sub>l M[a\<turnstile>c>b]"
3701| LAxL:  "\<lbrakk>a\<sharp>M; x\<sharp>y; fin M x\<rbrakk> \<Longrightarrow> Cut <a>.(Ax y a) (x).M \<longrightarrow>\<^sub>l M[x\<turnstile>n>y]"
3702| LNot:  "\<lbrakk>y\<sharp>(M,N); x\<sharp>(N,y); a\<sharp>(M,N,b); b\<sharp>M; y\<noteq>x; b\<noteq>a\<rbrakk> \<Longrightarrow>
3703          Cut <a>.(NotR (x).M a) (y).(NotL <b>.N y) \<longrightarrow>\<^sub>l Cut <b>.N (x).M" 
3704| LAnd1: "\<lbrakk>b\<sharp>([a1].M1,[a2].M2,N,a1,a2); y\<sharp>([x].N,M1,M2,x); x\<sharp>(M1,M2); a1\<sharp>(M2,N); a2\<sharp>(M1,N); a1\<noteq>a2\<rbrakk> \<Longrightarrow>
3705          Cut <b>.(AndR <a1>.M1 <a2>.M2 b) (y).(AndL1 (x).N y) \<longrightarrow>\<^sub>l Cut <a1>.M1 (x).N"
3706| LAnd2: "\<lbrakk>b\<sharp>([a1].M1,[a2].M2,N,a1,a2); y\<sharp>([x].N,M1,M2,x); x\<sharp>(M1,M2); a1\<sharp>(M2,N); a2\<sharp>(M1,N); a1\<noteq>a2\<rbrakk> \<Longrightarrow>
3707          Cut <b>.(AndR <a1>.M1 <a2>.M2 b) (y).(AndL2 (x).N y) \<longrightarrow>\<^sub>l Cut <a2>.M2 (x).N"
3708| LOr1:  "\<lbrakk>b\<sharp>([a].M,N1,N2,a); y\<sharp>([x1].N1,[x2].N2,M,x1,x2); x1\<sharp>(M,N2); x2\<sharp>(M,N1); a\<sharp>(N1,N2); x1\<noteq>x2\<rbrakk> \<Longrightarrow>
3709          Cut <b>.(OrR1 <a>.M b) (y).(OrL (x1).N1 (x2).N2 y) \<longrightarrow>\<^sub>l Cut <a>.M (x1).N1"
3710| LOr2:  "\<lbrakk>b\<sharp>([a].M,N1,N2,a); y\<sharp>([x1].N1,[x2].N2,M,x1,x2); x1\<sharp>(M,N2); x2\<sharp>(M,N1); a\<sharp>(N1,N2); x1\<noteq>x2\<rbrakk> \<Longrightarrow>
3711          Cut <b>.(OrR2 <a>.M b) (y).(OrL (x1).N1 (x2).N2 y) \<longrightarrow>\<^sub>l Cut <a>.M (x2).N2"
3712| LImp:  "\<lbrakk>z\<sharp>(N,[y].P,[x].M,y,x); b\<sharp>([a].M,[c].N,P,c,a); x\<sharp>(N,[y].P,y); 
3713          c\<sharp>(P,[a].M,b,a); a\<sharp>([c].N,P); y\<sharp>(N,[x].M)\<rbrakk> \<Longrightarrow>
3714          Cut <b>.(ImpR (x).<a>.M b) (z).(ImpL <c>.N (y).P z) \<longrightarrow>\<^sub>l Cut <a>.(Cut <c>.N (x).M) (y).P"
3715
3716equivariance l_redu
3717
3718lemma l_redu_eqvt':
3719  fixes pi1::"name prm"
3720  and   pi2::"coname prm"
3721  shows "(pi1\<bullet>M) \<longrightarrow>\<^sub>l (pi1\<bullet>M') \<Longrightarrow> M \<longrightarrow>\<^sub>l M'"
3722  and   "(pi2\<bullet>M) \<longrightarrow>\<^sub>l (pi2\<bullet>M') \<Longrightarrow> M \<longrightarrow>\<^sub>l M'"
3723apply -
3724apply(drule_tac pi="rev pi1" in l_redu.eqvt(1))
3725apply(perm_simp)
3726apply(drule_tac pi="rev pi2" in l_redu.eqvt(2))
3727apply(perm_simp)
3728done
3729
3730nominal_inductive l_redu
3731  apply(simp_all add: abs_fresh fresh_atm rename_fresh fresh_prod abs_supp fin_supp)
3732  apply(force)+
3733  done
3734
3735lemma fresh_l_redu:
3736  fixes x::"name"
3737  and   a::"coname"
3738  shows "M \<longrightarrow>\<^sub>l M' \<Longrightarrow> x\<sharp>M \<Longrightarrow> x\<sharp>M'"
3739  and   "M \<longrightarrow>\<^sub>l M' \<Longrightarrow> a\<sharp>M \<Longrightarrow> a\<sharp>M'"
3740apply -
3741apply(induct rule: l_redu.induct)
3742apply(auto simp add: abs_fresh rename_fresh)
3743apply(case_tac "xa=x")
3744apply(simp add: rename_fresh)
3745apply(simp add: rename_fresh fresh_atm)
3746apply(simp add: fresh_prod abs_fresh abs_supp fin_supp)+
3747apply(induct rule: l_redu.induct)
3748apply(auto simp add: abs_fresh rename_fresh)
3749apply(case_tac "aa=a")
3750apply(simp add: rename_fresh)
3751apply(simp add: rename_fresh fresh_atm)
3752apply(simp add: fresh_prod abs_fresh abs_supp fin_supp)+
3753done
3754
3755lemma better_LAxR_intro[intro]:
3756  shows "fic M a \<Longrightarrow> Cut <a>.M (x).(Ax x b) \<longrightarrow>\<^sub>l M[a\<turnstile>c>b]"
3757proof -
3758  assume fin: "fic M a"
3759  obtain x'::"name" where fs1: "x'\<sharp>(M,x)" by (rule exists_fresh(1), rule fin_supp, blast)
3760  obtain a'::"coname" where fs2: "a'\<sharp>(a,M,b)" by (rule exists_fresh(2), rule fin_supp, blast)
3761  have "Cut <a>.M (x).(Ax x b) =  Cut <a'>.([(a',a)]\<bullet>M) (x').(Ax x' b)"
3762    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
3763  also have "\<dots> \<longrightarrow>\<^sub>l ([(a',a)]\<bullet>M)[a'\<turnstile>c>b]" using fs1 fs2 fin
3764    by (auto intro: l_redu.intros simp add: fresh_left calc_atm fic_rename)
3765  also have "\<dots> = M[a\<turnstile>c>b]" using fs1 fs2 by (simp add: crename_rename)
3766  finally show ?thesis by simp
3767qed
3768    
3769lemma better_LAxL_intro[intro]:
3770  shows "fin M x \<Longrightarrow> Cut <a>.(Ax y a) (x).M \<longrightarrow>\<^sub>l M[x\<turnstile>n>y]"
3771proof -
3772  assume fin: "fin M x"
3773  obtain x'::"name" where fs1: "x'\<sharp>(y,M,x)" by (rule exists_fresh(1), rule fin_supp, blast)
3774  obtain a'::"coname" where fs2: "a'\<sharp>(a,M)" by (rule exists_fresh(2), rule fin_supp, blast)
3775  have "Cut <a>.(Ax y a) (x).M = Cut <a'>.(Ax y a') (x').([(x',x)]\<bullet>M)"
3776    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
3777  also have "\<dots> \<longrightarrow>\<^sub>l ([(x',x)]\<bullet>M)[x'\<turnstile>n>y]" using fs1 fs2 fin
3778    by (auto intro: l_redu.intros simp add: fresh_left calc_atm fin_rename)
3779  also have "\<dots> = M[x\<turnstile>n>y]" using fs1 fs2 by (simp add: nrename_rename)
3780  finally show ?thesis by simp
3781qed
3782
3783lemma better_LNot_intro[intro]:
3784  shows "\<lbrakk>y\<sharp>N; a\<sharp>M\<rbrakk> \<Longrightarrow> Cut <a>.(NotR (x).M a) (y).(NotL <b>.N y) \<longrightarrow>\<^sub>l Cut <b>.N (x).M"
3785proof -
3786  assume fs: "y\<sharp>N" "a\<sharp>M"
3787  obtain x'::"name" where f1: "x'\<sharp>(y,N,M,x)" by (rule exists_fresh(1), rule fin_supp, blast)
3788  obtain y'::"name" where f2: "y'\<sharp>(y,N,M,x,x')" by (rule exists_fresh(1), rule fin_supp, blast)
3789  obtain a'::"coname" where f3: "a'\<sharp>(a,M,N,b)" by (rule exists_fresh(2), rule fin_supp, blast)
3790  obtain b'::"coname" where f4: "b'\<sharp>(a,M,N,b,a')" by (rule exists_fresh(2), rule fin_supp, blast)
3791  have "Cut <a>.(NotR (x).M a) (y).(NotL <b>.N y) 
3792                      = Cut <a'>.(NotR (x).([(a',a)]\<bullet>M) a') (y').(NotL <b>.([(y',y)]\<bullet>N) y')"
3793    using f1 f2 f3 f4 
3794    by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm abs_fresh)
3795  also have "\<dots> = Cut <a'>.(NotR (x).M a') (y').(NotL <b>.N y')"
3796    using f1 f2 f3 f4 fs by (perm_simp)
3797  also have "\<dots> = Cut <a'>.(NotR (x').([(x',x)]\<bullet>M) a') (y').(NotL <b'>.([(b',b)]\<bullet>N) y')"
3798    using f1 f2 f3 f4 
3799    by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
3800  also have "\<dots> \<longrightarrow>\<^sub>l Cut <b'>.([(b',b)]\<bullet>N) (x').([(x',x)]\<bullet>M)"
3801    using f1 f2 f3 f4 fs
3802    by (auto intro:  l_redu.intros simp add: fresh_prod fresh_left calc_atm fresh_atm)
3803  also have "\<dots> = Cut <b>.N (x).M"
3804    using f1 f2 f3 f4 by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
3805  finally show ?thesis by simp
3806qed 
3807
3808lemma better_LAnd1_intro[intro]:
3809  shows "\<lbrakk>a\<sharp>([b1].M1,[b2].M2); y\<sharp>[x].N\<rbrakk> 
3810         \<Longrightarrow> Cut <a>.(AndR <b1>.M1 <b2>.M2 a) (y).(AndL1 (x).N y) \<longrightarrow>\<^sub>l Cut <b1>.M1 (x).N"
3811proof -
3812  assume fs: "a\<sharp>([b1].M1,[b2].M2)" "y\<sharp>[x].N"
3813  obtain x'::"name" where f1: "x'\<sharp>(y,N,M1,M2,x)" by (rule exists_fresh(1), rule fin_supp, blast)
3814  obtain y'::"name" where f2: "y'\<sharp>(y,N,M1,M2,x,x')" by (rule exists_fresh(1), rule fin_supp, blast)
3815  obtain a'::"coname" where f3: "a'\<sharp>(a,M1,M2,N,b1,b2)" by (rule exists_fresh(2), rule fin_supp, blast)
3816  obtain b1'::"coname" where f4:"b1'\<sharp>(a,M1,M2,N,b1,b2,a')" by (rule exists_fresh(2), rule fin_supp, blast)
3817  obtain b2'::"coname" where f5:"b2'\<sharp>(a,M1,M2,N,b1,b2,a',b1')" by (rule exists_fresh(2),rule fin_supp, blast)
3818  have "Cut <a>.(AndR <b1>.M1 <b2>.M2 a) (y).(AndL1 (x).N y)
3819                      = Cut <a'>.(AndR <b1>.M1 <b2>.M2 a') (y').(AndL1 (x).N y')"
3820    using f1 f2 f3 f4 fs
3821    apply(rule_tac sym)
3822    apply(perm_simp add: trm.inject alpha calc_atm fresh_prod fresh_left fresh_atm abs_fresh)
3823    apply(auto simp add: perm_fresh_fresh)
3824    done
3825  also have "\<dots> = Cut <a'>.(AndR <b1'>.([(b1',b1)]\<bullet>M1) <b2'>.([(b2',b2)]\<bullet>M2) a') 
3826                                                               (y').(AndL1 (x').([(x',x)]\<bullet>N) y')"
3827    using f1 f2 f3 f4 f5 fs 
3828    apply(rule_tac sym)
3829    apply(perm_simp add: trm.inject alpha calc_atm fresh_prod fresh_left fresh_atm abs_fresh)
3830    done
3831  also have "\<dots> \<longrightarrow>\<^sub>l Cut <b1'>.([(b1',b1)]\<bullet>M1) (x').([(x',x)]\<bullet>N)"
3832    using f1 f2 f3 f4 f5 fs
3833    apply -
3834    apply(rule l_redu.intros)
3835    apply(auto simp add: abs_fresh fresh_prod fresh_left calc_atm fresh_atm)
3836    done
3837  also have "\<dots> = Cut <b1>.M1 (x).N"
3838    using f1 f2 f3 f4 f5 fs by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
3839  finally show ?thesis by simp
3840qed 
3841
3842lemma better_LAnd2_intro[intro]:
3843  shows "\<lbrakk>a\<sharp>([b1].M1,[b2].M2); y\<sharp>[x].N\<rbrakk> 
3844         \<Longrightarrow> Cut <a>.(AndR <b1>.M1 <b2>.M2 a) (y).(AndL2 (x).N y) \<longrightarrow>\<^sub>l Cut <b2>.M2 (x).N"
3845proof -
3846  assume fs: "a\<sharp>([b1].M1,[b2].M2)" "y\<sharp>[x].N"
3847  obtain x'::"name" where f1: "x'\<sharp>(y,N,M1,M2,x)" by (rule exists_fresh(1), rule fin_supp, blast)
3848  obtain y'::"name" where f2: "y'\<sharp>(y,N,M1,M2,x,x')" by (rule exists_fresh(1), rule fin_supp, blast)
3849  obtain a'::"coname" where f3: "a'\<sharp>(a,M1,M2,N,b1,b2)" by (rule exists_fresh(2), rule fin_supp, blast)
3850  obtain b1'::"coname" where f4:"b1'\<sharp>(a,M1,M2,N,b1,b2,a')" by (rule exists_fresh(2), rule fin_supp, blast)
3851  obtain b2'::"coname" where f5:"b2'\<sharp>(a,M1,M2,N,b1,b2,a',b1')" by (rule exists_fresh(2),rule fin_supp, blast)
3852  have "Cut <a>.(AndR <b1>.M1 <b2>.M2 a) (y).(AndL2 (x).N y)
3853                      = Cut <a'>.(AndR <b1>.M1 <b2>.M2 a') (y').(AndL2 (x).N y')"
3854    using f1 f2 f3 f4 fs
3855    apply(rule_tac sym)
3856    apply(perm_simp add: trm.inject alpha calc_atm fresh_prod fresh_left fresh_atm abs_fresh)
3857    apply(auto simp add: perm_fresh_fresh)
3858    done
3859  also have "\<dots> = Cut <a'>.(AndR <b1'>.([(b1',b1)]\<bullet>M1) <b2'>.([(b2',b2)]\<bullet>M2) a') 
3860                                                               (y').(AndL2 (x').([(x',x)]\<bullet>N) y')"
3861    using f1 f2 f3 f4 f5 fs 
3862    apply(rule_tac sym)
3863    apply(perm_simp add: trm.inject alpha calc_atm fresh_prod fresh_left fresh_atm abs_fresh)
3864    done
3865  also have "\<dots> \<longrightarrow>\<^sub>l Cut <b2'>.([(b2',b2)]\<bullet>M2) (x').([(x',x)]\<bullet>N)"
3866    using f1 f2 f3 f4 f5 fs
3867    apply -
3868    apply(rule l_redu.intros)
3869    apply(auto simp add: abs_fresh fresh_prod fresh_left calc_atm fresh_atm)
3870    done
3871  also have "\<dots> = Cut <b2>.M2 (x).N"
3872    using f1 f2 f3 f4 f5 fs by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
3873  finally show ?thesis by simp
3874qed
3875
3876lemma better_LOr1_intro[intro]:
3877  shows "\<lbrakk>y\<sharp>([x1].N1,[x2].N2); b\<sharp>[a].M\<rbrakk> 
3878         \<Longrightarrow> Cut <b>.(OrR1 <a>.M b) (y).(OrL (x1).N1 (x2).N2 y) \<longrightarrow>\<^sub>l Cut <a>.M (x1).N1"
3879proof -
3880  assume fs: "y\<sharp>([x1].N1,[x2].N2)" "b\<sharp>[a].M"
3881  obtain y'::"name" where f1: "y'\<sharp>(y,M,N1,N2,x1,x2)" by (rule exists_fresh(1), rule fin_supp, blast)
3882  obtain x1'::"name" where f2: "x1'\<sharp>(y,M,N1,N2,x1,x2,y')" by (rule exists_fresh(1), rule fin_supp, blast)
3883  obtain x2'::"name" where f3: "x2'\<sharp>(y,M,N1,N2,x1,x2,y',x1')" by (rule exists_fresh(1), rule fin_supp, blast)
3884  obtain a'::"coname" where f4: "a'\<sharp>(a,N1,N2,M,b)" by (rule exists_fresh(2), rule fin_supp, blast)
3885  obtain b'::"coname" where f5: "b'\<sharp>(a,N1,N2,M,b,a')" by (rule exists_fresh(2),rule fin_supp, blast)
3886  have "Cut <b>.(OrR1 <a>.M b) (y).(OrL (x1).N1 (x2).N2 y)
3887                      = Cut <b'>.(OrR1 <a>.M b') (y').(OrL (x1).N1 (x2).N2 y')"
3888    using f1 f2 f3 f4 f5 fs
3889    apply(rule_tac sym)
3890    apply(perm_simp add: trm.inject alpha calc_atm fresh_prod fresh_left fresh_atm abs_fresh)
3891    apply(auto simp add: perm_fresh_fresh)
3892    done
3893  also have "\<dots> = Cut <b'>.(OrR1 <a'>.([(a',a)]\<bullet>M) b') 
3894              (y').(OrL (x1').([(x1',x1)]\<bullet>N1) (x2').([(x2',x2)]\<bullet>N2) y')"   
3895    using f1 f2 f3 f4 f5 fs 
3896    apply(rule_tac sym)
3897    apply(perm_simp add: trm.inject alpha calc_atm fresh_prod fresh_left fresh_atm abs_fresh)
3898    done
3899  also have "\<dots> \<longrightarrow>\<^sub>l Cut <a'>.([(a',a)]\<bullet>M) (x1').([(x1',x1)]\<bullet>N1)"
3900    using f1 f2 f3 f4 f5 fs
3901    apply -
3902    apply(rule l_redu.intros)
3903    apply(auto simp add: abs_fresh fresh_prod fresh_left calc_atm fresh_atm)
3904    done
3905  also have "\<dots> = Cut <a>.M (x1).N1"
3906    using f1 f2 f3 f4 f5 fs by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
3907  finally show ?thesis by simp
3908qed
3909
3910lemma better_LOr2_intro[intro]:
3911  shows "\<lbrakk>y\<sharp>([x1].N1,[x2].N2); b\<sharp>[a].M\<rbrakk> 
3912         \<Longrightarrow> Cut <b>.(OrR2 <a>.M b) (y).(OrL (x1).N1 (x2).N2 y) \<longrightarrow>\<^sub>l Cut <a>.M (x2).N2"
3913proof -
3914  assume fs: "y\<sharp>([x1].N1,[x2].N2)" "b\<sharp>[a].M"
3915  obtain y'::"name" where f1: "y'\<sharp>(y,M,N1,N2,x1,x2)" by (rule exists_fresh(1), rule fin_supp, blast)
3916  obtain x1'::"name" where f2: "x1'\<sharp>(y,M,N1,N2,x1,x2,y')" by (rule exists_fresh(1), rule fin_supp, blast)
3917  obtain x2'::"name" where f3: "x2'\<sharp>(y,M,N1,N2,x1,x2,y',x1')" by (rule exists_fresh(1), rule fin_supp, blast)
3918  obtain a'::"coname" where f4: "a'\<sharp>(a,N1,N2,M,b)" by (rule exists_fresh(2), rule fin_supp, blast)
3919  obtain b'::"coname" where f5: "b'\<sharp>(a,N1,N2,M,b,a')" by (rule exists_fresh(2),rule fin_supp, blast)
3920  have "Cut <b>.(OrR2 <a>.M b) (y).(OrL (x1).N1 (x2).N2 y)
3921                      = Cut <b'>.(OrR2 <a>.M b') (y').(OrL (x1).N1 (x2).N2 y')"
3922    using f1 f2 f3 f4 f5 fs
3923    apply(rule_tac sym)
3924    apply(perm_simp add: trm.inject alpha calc_atm fresh_prod fresh_left fresh_atm abs_fresh)
3925    apply(auto simp add: perm_fresh_fresh)
3926    done
3927  also have "\<dots> = Cut <b'>.(OrR2 <a'>.([(a',a)]\<bullet>M) b') 
3928              (y').(OrL (x1').([(x1',x1)]\<bullet>N1) (x2').([(x2',x2)]\<bullet>N2) y')"   
3929    using f1 f2 f3 f4 f5 fs 
3930    apply(rule_tac sym)
3931    apply(perm_simp add: trm.inject alpha calc_atm fresh_prod fresh_left fresh_atm abs_fresh)
3932    done
3933  also have "\<dots> \<longrightarrow>\<^sub>l Cut <a'>.([(a',a)]\<bullet>M) (x2').([(x2',x2)]\<bullet>N2)"
3934    using f1 f2 f3 f4 f5 fs
3935    apply -
3936    apply(rule l_redu.intros)
3937    apply(auto simp add: abs_fresh fresh_prod fresh_left calc_atm fresh_atm)
3938    done
3939  also have "\<dots> = Cut <a>.M (x2).N2"
3940    using f1 f2 f3 f4 f5 fs by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
3941  finally show ?thesis by simp
3942qed 
3943
3944lemma better_LImp_intro[intro]:
3945  shows "\<lbrakk>z\<sharp>(N,[y].P); b\<sharp>[a].M; a\<sharp>N\<rbrakk> 
3946         \<Longrightarrow> Cut <b>.(ImpR (x).<a>.M b) (z).(ImpL <c>.N (y).P z) \<longrightarrow>\<^sub>l Cut <a>.(Cut <c>.N (x).M) (y).P"
3947proof -
3948  assume fs: "z\<sharp>(N,[y].P)" "b\<sharp>[a].M" "a\<sharp>N"
3949  obtain y'::"name" where f1: "y'\<sharp>(y,M,N,P,z,x)" by (rule exists_fresh(1), rule fin_supp, blast)
3950  obtain x'::"name" where f2: "x'\<sharp>(y,M,N,P,z,x,y')" by (rule exists_fresh(1), rule fin_supp, blast)
3951  obtain z'::"name" where f3: "z'\<sharp>(y,M,N,P,z,x,y',x')" by (rule exists_fresh(1), rule fin_supp, blast)
3952  obtain a'::"coname" where f4: "a'\<sharp>(a,N,P,M,b)" by (rule exists_fresh(2), rule fin_supp, blast)
3953  obtain b'::"coname" where f5: "b'\<sharp>(a,N,P,M,b,c,a')" by (rule exists_fresh(2),rule fin_supp, blast)
3954  obtain c'::"coname" where f6: "c'\<sharp>(a,N,P,M,b,c,a',b')" by (rule exists_fresh(2),rule fin_supp, blast)
3955  have " Cut <b>.(ImpR (x).<a>.M b) (z).(ImpL <c>.N (y).P z)
3956                      =  Cut <b'>.(ImpR (x).<a>.M b') (z').(ImpL <c>.N (y).P z')"
3957    using f1 f2 f3 f4 f5 fs
3958    apply(rule_tac sym)
3959    apply(perm_simp add: trm.inject alpha calc_atm fresh_prod fresh_left fresh_atm abs_fresh)
3960    apply(auto simp add: perm_fresh_fresh)
3961    done
3962  also have "\<dots> = Cut <b'>.(ImpR (x').<a'>.([(a',a)]\<bullet>([(x',x)]\<bullet>M)) b') 
3963                           (z').(ImpL <c'>.([(c',c)]\<bullet>N) (y').([(y',y)]\<bullet>P) z')"
3964    using f1 f2 f3 f4 f5 f6 fs 
3965    apply(rule_tac sym)
3966    apply(simp add: trm.inject)
3967    apply(simp add: alpha)
3968    apply(rule conjI)
3969    apply(simp add: trm.inject)
3970    apply(simp add: alpha fresh_prod fresh_atm abs_perm calc_atm fresh_left abs_fresh)
3971    apply(simp add: trm.inject)
3972    apply(simp add: alpha)
3973    apply(rule conjI)
3974    apply(simp add: alpha fresh_prod fresh_atm abs_perm calc_atm fresh_left abs_fresh)
3975    apply(simp add: alpha fresh_prod fresh_atm abs_perm calc_atm fresh_left abs_fresh)
3976    done
3977  also have "\<dots> \<longrightarrow>\<^sub>l Cut <a'>.(Cut <c'>.([(c',c)]\<bullet>N) (x').([(a',a)]\<bullet>[(x',x)]\<bullet>M)) (y').([(y',y)]\<bullet>P)"
3978    using f1 f2 f3 f4 f5 f6 fs
3979    apply -
3980    apply(rule l_redu.intros)
3981    apply(auto simp add: abs_fresh fresh_prod fresh_left calc_atm fresh_atm)
3982    done
3983  also have "\<dots> = Cut <a>.(Cut <c>.N (x).M) (y).P"
3984    using f1 f2 f3 f4 f5 f6 fs 
3985    apply(simp add: trm.inject)
3986    apply(rule conjI)
3987    apply(simp add: alpha)
3988    apply(rule disjI2)
3989    apply(simp add: trm.inject)
3990    apply(rule conjI)
3991    apply(simp add: fresh_prod fresh_atm)
3992    apply(rule conjI)
3993    apply(perm_simp add: calc_atm)
3994    apply(auto simp add: fresh_prod fresh_atm)[1]
3995    apply(perm_simp add: alpha)
3996    apply(perm_simp add: alpha)
3997    apply(perm_simp add: alpha)
3998    apply(rule conjI)
3999    apply(perm_simp add: calc_atm)
4000    apply(rule_tac pi="[(a',a)]" in pt_bij4[OF pt_coname_inst, OF at_coname_inst])
4001    apply(perm_simp add: abs_perm calc_atm)
4002    apply(perm_simp add: alpha fresh_prod fresh_atm)
4003    apply(simp add: abs_fresh)
4004    apply(perm_simp add: alpha fresh_prod fresh_atm)
4005    done
4006  finally show ?thesis by simp
4007qed 
4008
4009lemma alpha_coname:
4010  fixes M::"trm"
4011  and   a::"coname"
4012  assumes a: "[a].M = [b].N" "c\<sharp>(a,b,M,N)"
4013  shows "M = [(a,c)]\<bullet>[(b,c)]\<bullet>N"
4014using a
4015apply(auto simp add: alpha_fresh fresh_prod fresh_atm)
4016apply(drule sym)
4017apply(perm_simp)
4018done 
4019
4020lemma alpha_name:
4021  fixes M::"trm"
4022  and   x::"name"
4023  assumes a: "[x].M = [y].N" "z\<sharp>(x,y,M,N)"
4024  shows "M = [(x,z)]\<bullet>[(y,z)]\<bullet>N"
4025using a
4026apply(auto simp add: alpha_fresh fresh_prod fresh_atm)
4027apply(drule sym)
4028apply(perm_simp)
4029done 
4030
4031lemma alpha_name_coname:
4032  fixes M::"trm"
4033  and   x::"name"
4034  and   a::"coname"
4035  assumes a: "[x].[b].M = [y].[c].N" "z\<sharp>(x,y,M,N)" "a\<sharp>(b,c,M,N)"
4036  shows "M = [(x,z)]\<bullet>[(b,a)]\<bullet>[(c,a)]\<bullet>[(y,z)]\<bullet>N"
4037using a
4038apply(auto simp add: alpha_fresh fresh_prod fresh_atm 
4039                     abs_supp fin_supp abs_fresh abs_perm fresh_left calc_atm)
4040apply(drule sym)
4041apply(simp)
4042apply(perm_simp)
4043done 
4044
4045lemma Cut_l_redu_elim:
4046  assumes a: "Cut <a>.M (x).N \<longrightarrow>\<^sub>l R"
4047  shows "(\<exists>b. R = M[a\<turnstile>c>b]) \<or> (\<exists>y. R = N[x\<turnstile>n>y]) \<or>
4048  (\<exists>y M' b N'. M = NotR (y).M' a \<and> N = NotL <b>.N' x \<and> R = Cut <b>.N' (y).M' \<and> fic M a \<and> fin N x) \<or>
4049  (\<exists>b M1 c M2 y N'. M = AndR <b>.M1 <c>.M2 a \<and> N = AndL1 (y).N' x \<and> R = Cut <b>.M1 (y).N' 
4050                                                                            \<and> fic M a \<and> fin N x) \<or>
4051  (\<exists>b M1 c M2 y N'. M = AndR <b>.M1 <c>.M2 a \<and> N = AndL2 (y).N' x \<and> R = Cut <c>.M2 (y).N' 
4052                                                                            \<and> fic M a \<and> fin N x) \<or>
4053  (\<exists>b N' z M1 y M2. M = OrR1 <b>.N' a \<and> N = OrL (z).M1 (y).M2 x \<and> R = Cut <b>.N' (z).M1 
4054                                                                            \<and> fic M a \<and> fin N x) \<or>
4055  (\<exists>b N' z M1 y M2. M = OrR2 <b>.N' a \<and> N = OrL (z).M1 (y).M2 x \<and> R = Cut <b>.N' (y).M2 
4056                                                                            \<and> fic M a \<and> fin N x) \<or>
4057  (\<exists>z b M' c N1 y N2. M = ImpR (z).<b>.M' a \<and> N = ImpL <c>.N1 (y).N2 x \<and> 
4058            R = Cut <b>.(Cut <c>.N1 (z).M') (y).N2 \<and> b\<sharp>(c,N1) \<and> fic M a \<and> fin N x)"
4059using a
4060apply(erule_tac l_redu.cases)
4061apply(rule disjI1)
4062(* ax case *)
4063apply(simp add: trm.inject)
4064apply(rule_tac x="b" in exI)
4065apply(erule conjE)
4066apply(simp add: alpha)
4067apply(erule disjE)
4068apply(simp)
4069apply(simp)
4070apply(simp add: rename_fresh)
4071apply(rule disjI2)
4072apply(rule disjI1)
4073(* ax case *)
4074apply(simp add: trm.inject)
4075apply(rule_tac x="y" in exI)
4076apply(erule conjE)
4077apply(thin_tac "[a].M = [aa].Ax y aa")
4078apply(simp add: alpha)
4079apply(erule disjE)
4080apply(simp)
4081apply(simp)
4082apply(simp add: rename_fresh)
4083apply(rule disjI2)
4084apply(rule disjI2)
4085apply(rule disjI1)
4086(* not case *)
4087apply(simp add: trm.inject)
4088apply(erule conjE)+
4089apply(generate_fresh "coname")
4090apply(simp add: abs_fresh fresh_prod fresh_atm)
4091apply(auto)[1]
4092apply(drule_tac c="c" in  alpha_coname)
4093apply(simp add: fresh_prod fresh_atm abs_fresh)
4094apply(simp add: calc_atm)
4095apply(rule exI)+
4096apply(rule conjI)
4097apply(rule refl)
4098apply(generate_fresh "name")
4099apply(simp add: calc_atm abs_fresh fresh_prod fresh_atm fresh_left)
4100apply(auto)[1]
4101apply(drule_tac z="ca" in  alpha_name)
4102apply(simp add: fresh_prod fresh_atm abs_fresh)
4103apply(simp add: calc_atm)
4104apply(rule exI)+
4105apply(rule conjI)
4106apply(rule refl)
4107apply(auto simp add: calc_atm abs_fresh fresh_left)[1]
4108apply(case_tac "y=x")
4109apply(perm_simp)
4110apply(perm_simp)
4111apply(case_tac "aa=a")
4112apply(perm_simp)
4113apply(perm_simp)
4114(* and1 case *)
4115apply(rule disjI2)
4116apply(rule disjI2)
4117apply(rule disjI2)
4118apply(rule disjI1)
4119apply(simp add: trm.inject)
4120apply(erule conjE)+
4121apply(generate_fresh "coname")
4122apply(simp add: abs_fresh fresh_prod fresh_atm)
4123apply(auto)[1]
4124apply(drule_tac c="c" in  alpha_coname)
4125apply(simp add: fresh_prod fresh_atm abs_fresh)
4126apply(simp)
4127apply(rule exI)+
4128apply(rule conjI)
4129apply(rule exI)+
4130apply(rule_tac s="a" and t="[(a,c)]\<bullet>[(b,c)]\<bullet>b" in subst)
4131apply(simp add: calc_atm)
4132apply(rule refl)
4133apply(generate_fresh "name")
4134apply(simp add: abs_fresh fresh_prod fresh_atm)
4135apply(auto)[1]
4136apply(drule_tac z="ca" in  alpha_name)
4137apply(simp add: fresh_prod fresh_atm abs_fresh)
4138apply(simp)
4139apply(rule exI)+
4140apply(rule conjI)
4141apply(rule_tac s="x" and t="[(x,ca)]\<bullet>[(y,ca)]\<bullet>y" in subst)
4142apply(simp add: calc_atm)
4143apply(rule refl)
4144apply(auto simp add: fresh_left calc_atm abs_fresh split: if_splits)[1]
4145apply(generate_fresh "name")
4146apply(simp add: abs_fresh fresh_prod fresh_atm)
4147apply(auto)[1]
4148apply(drule_tac z="cb" in  alpha_name)
4149apply(simp add: fresh_prod fresh_atm abs_fresh)
4150apply(simp)
4151apply(rule exI)+
4152apply(rule conjI)
4153apply(rule_tac s="x" and t="[(x,cb)]\<bullet>[(y,cb)]\<bullet>y" in subst)
4154apply(simp add: calc_atm)
4155apply(rule refl)
4156apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4157apply(perm_simp)+
4158apply(generate_fresh "name")
4159apply(simp add: abs_fresh fresh_prod fresh_atm)
4160apply(auto)[1]
4161apply(drule_tac z="cb" in  alpha_name)
4162apply(simp add: fresh_prod fresh_atm abs_fresh)
4163apply(simp)
4164apply(rule exI)+
4165apply(rule conjI)
4166apply(rule_tac s="x" and t="[(x,cb)]\<bullet>[(y,cb)]\<bullet>y" in subst)
4167apply(simp add: calc_atm)
4168apply(rule refl)
4169apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4170apply(perm_simp)+
4171apply(generate_fresh "name")
4172apply(simp add: abs_fresh fresh_prod fresh_atm)
4173apply(auto)[1]
4174apply(drule_tac z="cb" in  alpha_name)
4175apply(simp add: fresh_prod fresh_atm abs_fresh)
4176apply(simp)
4177apply(rule exI)+
4178apply(rule conjI)
4179apply(rule_tac s="x" and t="[(x,cb)]\<bullet>[(y,cb)]\<bullet>y" in subst)
4180apply(simp add: calc_atm)
4181apply(rule refl)
4182apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4183apply(perm_simp)+
4184(* and2 case *)
4185apply(rule disjI2)
4186apply(rule disjI2)
4187apply(rule disjI2)
4188apply(rule disjI2)
4189apply(rule disjI1)
4190apply(simp add: trm.inject)
4191apply(erule conjE)+
4192apply(generate_fresh "coname")
4193apply(simp add: abs_fresh fresh_prod fresh_atm)
4194apply(auto)[1]
4195apply(drule_tac c="c" in  alpha_coname)
4196apply(simp add: fresh_prod fresh_atm abs_fresh)
4197apply(simp)
4198apply(rule exI)+
4199apply(rule conjI)
4200apply(rule_tac s="a" and t="[(a,c)]\<bullet>[(b,c)]\<bullet>b" in subst)
4201apply(simp add: calc_atm)
4202apply(rule refl)
4203apply(generate_fresh "name")
4204apply(simp add: abs_fresh fresh_prod fresh_atm)
4205apply(auto)[1]
4206apply(drule_tac z="ca" in  alpha_name)
4207apply(simp add: fresh_prod fresh_atm abs_fresh)
4208apply(simp)
4209apply(rule exI)+
4210apply(rule conjI)
4211apply(rule_tac s="x" and t="[(x,ca)]\<bullet>[(y,ca)]\<bullet>y" in subst)
4212apply(simp add: calc_atm)
4213apply(rule refl)
4214apply(auto simp add: fresh_left calc_atm abs_fresh split: if_splits)[1]
4215apply(generate_fresh "name")
4216apply(simp add: abs_fresh fresh_prod fresh_atm)
4217apply(auto)[1]
4218apply(drule_tac z="cb" in  alpha_name)
4219apply(simp add: fresh_prod fresh_atm abs_fresh)
4220apply(simp)
4221apply(rule exI)+
4222apply(rule conjI)
4223apply(rule_tac s="x" and t="[(x,cb)]\<bullet>[(y,cb)]\<bullet>y" in subst)
4224apply(simp add: calc_atm)
4225apply(rule refl)
4226apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4227apply(perm_simp)+
4228apply(generate_fresh "name")
4229apply(simp add: abs_fresh fresh_prod fresh_atm)
4230apply(auto)[1]
4231apply(drule_tac z="cb" in  alpha_name)
4232apply(simp add: fresh_prod fresh_atm abs_fresh)
4233apply(simp)
4234apply(rule exI)+
4235apply(rule conjI)
4236apply(rule_tac s="x" and t="[(x,cb)]\<bullet>[(y,cb)]\<bullet>y" in subst)
4237apply(simp add: calc_atm)
4238apply(rule refl)
4239apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4240apply(perm_simp)+
4241apply(generate_fresh "name")
4242apply(simp add: abs_fresh fresh_prod fresh_atm)
4243apply(auto)[1]
4244apply(drule_tac z="cb" in  alpha_name)
4245apply(simp add: fresh_prod fresh_atm abs_fresh)
4246apply(simp)
4247apply(rule exI)+
4248apply(rule conjI)
4249apply(rule_tac s="x" and t="[(x,cb)]\<bullet>[(y,cb)]\<bullet>y" in subst)
4250apply(simp add: calc_atm)
4251apply(rule refl)
4252apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4253apply(perm_simp)+
4254(* or1 case *)
4255apply(rule disjI2)
4256apply(rule disjI2)
4257apply(rule disjI2)
4258apply(rule disjI2)
4259apply(rule disjI2)
4260apply(rule disjI1)
4261apply(simp add: trm.inject)
4262apply(erule conjE)+
4263apply(generate_fresh "coname")
4264apply(simp add: abs_fresh fresh_prod fresh_atm)
4265apply(auto)[1]
4266apply(drule_tac c="c" in  alpha_coname)
4267apply(simp add: fresh_prod fresh_atm abs_fresh)
4268apply(simp)
4269apply(rule exI)+
4270apply(rule conjI)
4271apply(rule_tac s="a" and t="[(a,c)]\<bullet>[(b,c)]\<bullet>b" in subst)
4272apply(simp add: calc_atm)
4273apply(rule refl)
4274apply(generate_fresh "name")
4275apply(simp add: abs_fresh fresh_prod fresh_atm)
4276apply(auto)[1]
4277apply(drule_tac z="ca" in  alpha_name)
4278apply(simp add: fresh_prod fresh_atm abs_fresh)
4279apply(simp)
4280apply(rule exI)+
4281apply(rule conjI)
4282apply(rule exI)+
4283apply(rule_tac s="x" and t="[(x,ca)]\<bullet>[(y,ca)]\<bullet>y" in subst)
4284apply(simp add: calc_atm)
4285apply(rule refl)
4286apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4287apply(perm_simp)+
4288apply(generate_fresh "name")
4289apply(simp add: abs_fresh fresh_prod fresh_atm)
4290apply(auto)[1]
4291apply(drule_tac z="cb" in  alpha_name)
4292apply(simp add: fresh_prod fresh_atm abs_fresh)
4293apply(simp)
4294apply(rule exI)+
4295apply(rule conjI)
4296apply(rule exI)+
4297apply(rule_tac s="x" and t="[(x,cb)]\<bullet>[(y,cb)]\<bullet>y" in subst)
4298apply(simp add: calc_atm)
4299apply(rule refl)
4300apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4301apply(perm_simp)+
4302(* or2 case *)
4303apply(rule disjI2)
4304apply(rule disjI2)
4305apply(rule disjI2)
4306apply(rule disjI2)
4307apply(rule disjI2)
4308apply(rule disjI2)
4309apply(rule disjI1)
4310apply(simp add: trm.inject)
4311apply(erule conjE)+
4312apply(generate_fresh "coname")
4313apply(simp add: abs_fresh fresh_prod fresh_atm)
4314apply(auto)[1]
4315apply(drule_tac c="c" in  alpha_coname)
4316apply(simp add: fresh_prod fresh_atm abs_fresh)
4317apply(simp)
4318apply(rule exI)+
4319apply(rule conjI)
4320apply(rule_tac s="a" and t="[(a,c)]\<bullet>[(b,c)]\<bullet>b" in subst)
4321apply(simp add: calc_atm)
4322apply(rule refl)
4323apply(generate_fresh "name")
4324apply(simp add: abs_fresh fresh_prod fresh_atm)
4325apply(auto)[1]
4326apply(drule_tac z="ca" in  alpha_name)
4327apply(simp add: fresh_prod fresh_atm abs_fresh)
4328apply(simp)
4329apply(rule exI)+
4330apply(rule conjI)
4331apply(rule_tac s="x" and t="[(x,ca)]\<bullet>[(y,ca)]\<bullet>y" in subst)
4332apply(simp add: calc_atm)
4333apply(rule refl)
4334apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4335apply(perm_simp)+
4336apply(generate_fresh "name")
4337apply(simp add: abs_fresh fresh_prod fresh_atm)
4338apply(auto)[1]
4339apply(drule_tac z="cb" in  alpha_name)
4340apply(simp add: fresh_prod fresh_atm abs_fresh)
4341apply(simp)
4342apply(rule exI)+
4343apply(rule conjI)
4344apply(rule_tac s="x" and t="[(x,cb)]\<bullet>[(y,cb)]\<bullet>y" in subst)
4345apply(simp add: calc_atm)
4346apply(rule refl)
4347apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4348apply(perm_simp)+
4349(* imp-case *)
4350apply(rule disjI2)
4351apply(rule disjI2)
4352apply(rule disjI2)
4353apply(rule disjI2)
4354apply(rule disjI2)
4355apply(rule disjI2)
4356apply(rule disjI2)
4357apply(simp add: trm.inject)
4358apply(erule conjE)+
4359apply(generate_fresh "coname")
4360apply(simp add: abs_fresh fresh_prod fresh_atm)
4361apply(auto)[1]
4362apply(drule_tac c="ca" in  alpha_coname)
4363apply(simp add: fresh_prod fresh_atm abs_fresh)
4364apply(simp)
4365apply(rule exI)+
4366apply(rule conjI)
4367apply(rule_tac s="a" and t="[(a,ca)]\<bullet>[(b,ca)]\<bullet>b" in subst)
4368apply(simp add: calc_atm)
4369apply(rule refl)
4370apply(generate_fresh "name")
4371apply(simp add: abs_fresh fresh_prod fresh_atm)
4372apply(auto)[1]
4373apply(drule_tac z="cb" in  alpha_name)
4374apply(simp add: fresh_prod fresh_atm abs_fresh)
4375apply(simp)
4376apply(rule exI)+
4377apply(rule conjI)
4378apply(rule_tac s="x" and t="[(x,cb)]\<bullet>[(z,cb)]\<bullet>z" in subst)
4379apply(simp add: calc_atm)
4380apply(rule refl)
4381apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4382apply(perm_simp)+
4383apply(generate_fresh "name")
4384apply(simp add: abs_fresh fresh_prod fresh_atm)
4385apply(auto)[1]
4386apply(drule_tac z="cc" in  alpha_name)
4387apply(simp add: fresh_prod fresh_atm abs_fresh)
4388apply(simp)
4389apply(rule exI)+
4390apply(rule conjI)
4391apply(rule_tac s="x" and t="[(x,cc)]\<bullet>[(z,cc)]\<bullet>z" in subst)
4392apply(simp add: calc_atm)
4393apply(rule refl)
4394apply(auto simp add: fresh_left calc_atm abs_fresh alpha perm_fresh_fresh split: if_splits)[1]
4395apply(perm_simp)+
4396done
4397
4398inductive
4399  c_redu :: "trm \<Rightarrow> trm \<Rightarrow> bool" ("_ \<longrightarrow>\<^sub>c _" [100,100] 100)
4400where
4401  left[intro]:  "\<lbrakk>\<not>fic M a; a\<sharp>N; x\<sharp>M\<rbrakk> \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>c M{a:=(x).N}"
4402| right[intro]: "\<lbrakk>\<not>fin N x; a\<sharp>N; x\<sharp>M\<rbrakk> \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>c N{x:=<a>.M}"
4403
4404equivariance c_redu
4405
4406nominal_inductive c_redu
4407 by (simp_all add: abs_fresh subst_fresh)
4408
4409lemma better_left[intro]:
4410  shows "\<not>fic M a \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>c M{a:=(x).N}"
4411proof -
4412  assume not_fic: "\<not>fic M a"
4413  obtain x'::"name" where fs1: "x'\<sharp>(N,M,x)" by (rule exists_fresh(1), rule fin_supp, blast)
4414  obtain a'::"coname" where fs2: "a'\<sharp>(a,M,N)" by (rule exists_fresh(2), rule fin_supp, blast)
4415  have "Cut <a>.M (x).N =  Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N)"
4416    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4417  also have "\<dots> \<longrightarrow>\<^sub>c ([(a',a)]\<bullet>M){a':=(x').([(x',x)]\<bullet>N)}" using fs1 fs2 not_fic
4418    apply -
4419    apply(rule left)
4420    apply(clarify)
4421    apply(drule_tac a'="a" in fic_rename)
4422    apply(simp add: perm_swap)
4423    apply(simp add: fresh_left calc_atm)+
4424    done
4425  also have "\<dots> = M{a:=(x).N}" using fs1 fs2
4426    by (simp add: subst_rename[symmetric] fresh_atm fresh_prod fresh_left calc_atm)
4427  finally show ?thesis by simp
4428qed
4429
4430lemma better_right[intro]:
4431  shows "\<not>fin N x \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>c N{x:=<a>.M}"
4432proof -
4433  assume not_fin: "\<not>fin N x"
4434  obtain x'::"name" where fs1: "x'\<sharp>(N,M,x)" by (rule exists_fresh(1), rule fin_supp, blast)
4435  obtain a'::"coname" where fs2: "a'\<sharp>(a,M,N)" by (rule exists_fresh(2), rule fin_supp, blast)
4436  have "Cut <a>.M (x).N =  Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N)"
4437    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4438  also have "\<dots> \<longrightarrow>\<^sub>c ([(x',x)]\<bullet>N){x':=<a'>.([(a',a)]\<bullet>M)}" using fs1 fs2 not_fin
4439    apply -
4440    apply(rule right)
4441    apply(clarify)
4442    apply(drule_tac x'="x" in fin_rename)
4443    apply(simp add: perm_swap)
4444    apply(simp add: fresh_left calc_atm)+
4445    done
4446  also have "\<dots> = N{x:=<a>.M}" using fs1 fs2
4447    by (simp add: subst_rename[symmetric] fresh_atm fresh_prod fresh_left calc_atm)
4448  finally show ?thesis by simp
4449qed
4450
4451lemma fresh_c_redu:
4452  fixes x::"name"
4453  and   c::"coname"
4454  shows "M \<longrightarrow>\<^sub>c M' \<Longrightarrow> x\<sharp>M \<Longrightarrow> x\<sharp>M'"
4455  and   "M \<longrightarrow>\<^sub>c M' \<Longrightarrow> c\<sharp>M \<Longrightarrow> c\<sharp>M'"
4456apply -
4457apply(induct rule: c_redu.induct)
4458apply(auto simp add: abs_fresh rename_fresh subst_fresh)
4459apply(induct rule: c_redu.induct)
4460apply(auto simp add: abs_fresh rename_fresh subst_fresh)
4461done
4462
4463inductive
4464  a_redu :: "trm \<Rightarrow> trm \<Rightarrow> bool" ("_ \<longrightarrow>\<^sub>a _" [100,100] 100)
4465where
4466  al_redu[intro]: "M\<longrightarrow>\<^sub>l M' \<Longrightarrow> M \<longrightarrow>\<^sub>a M'"
4467| ac_redu[intro]: "M\<longrightarrow>\<^sub>c M' \<Longrightarrow> M \<longrightarrow>\<^sub>a M'"
4468| a_Cut_l: "\<lbrakk>a\<sharp>N; x\<sharp>M; M\<longrightarrow>\<^sub>a M'\<rbrakk> \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>a Cut <a>.M' (x).N"
4469| a_Cut_r: "\<lbrakk>a\<sharp>N; x\<sharp>M; N\<longrightarrow>\<^sub>a N'\<rbrakk> \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>a Cut <a>.M (x).N'"
4470| a_NotL[intro]: "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> NotL <a>.M x \<longrightarrow>\<^sub>a NotL <a>.M' x"
4471| a_NotR[intro]: "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> NotR (x).M a \<longrightarrow>\<^sub>a NotR (x).M' a"
4472| a_AndR_l: "\<lbrakk>a\<sharp>(N,c); b\<sharp>(M,c); b\<noteq>a; M\<longrightarrow>\<^sub>a M'\<rbrakk> \<Longrightarrow> AndR <a>.M <b>.N c \<longrightarrow>\<^sub>a AndR <a>.M' <b>.N c"
4473| a_AndR_r: "\<lbrakk>a\<sharp>(N,c); b\<sharp>(M,c); b\<noteq>a; N\<longrightarrow>\<^sub>a N'\<rbrakk> \<Longrightarrow> AndR <a>.M <b>.N c \<longrightarrow>\<^sub>a AndR <a>.M <b>.N' c"
4474| a_AndL1: "\<lbrakk>x\<sharp>y; M\<longrightarrow>\<^sub>a M'\<rbrakk> \<Longrightarrow> AndL1 (x).M y \<longrightarrow>\<^sub>a AndL1 (x).M' y"
4475| a_AndL2: "\<lbrakk>x\<sharp>y; M\<longrightarrow>\<^sub>a M'\<rbrakk> \<Longrightarrow> AndL2 (x).M y \<longrightarrow>\<^sub>a AndL2 (x).M' y"
4476| a_OrL_l: "\<lbrakk>x\<sharp>(N,z); y\<sharp>(M,z); y\<noteq>x; M\<longrightarrow>\<^sub>a M'\<rbrakk> \<Longrightarrow> OrL (x).M (y).N z \<longrightarrow>\<^sub>a OrL (x).M' (y).N z"
4477| a_OrL_r: "\<lbrakk>x\<sharp>(N,z); y\<sharp>(M,z); y\<noteq>x; N\<longrightarrow>\<^sub>a N'\<rbrakk> \<Longrightarrow> OrL (x).M (y).N z \<longrightarrow>\<^sub>a OrL (x).M (y).N' z"
4478| a_OrR1: "\<lbrakk>a\<sharp>b; M\<longrightarrow>\<^sub>a M'\<rbrakk> \<Longrightarrow> OrR1 <a>.M b \<longrightarrow>\<^sub>a OrR1 <a>.M' b"
4479| a_OrR2: "\<lbrakk>a\<sharp>b; M\<longrightarrow>\<^sub>a M'\<rbrakk> \<Longrightarrow> OrR2 <a>.M b \<longrightarrow>\<^sub>a OrR2 <a>.M' b"
4480| a_ImpL_l: "\<lbrakk>a\<sharp>N; x\<sharp>(M,y); M\<longrightarrow>\<^sub>a M'\<rbrakk> \<Longrightarrow> ImpL <a>.M (x).N y \<longrightarrow>\<^sub>a ImpL <a>.M' (x).N y"
4481| a_ImpL_r: "\<lbrakk>a\<sharp>N; x\<sharp>(M,y); N\<longrightarrow>\<^sub>a N'\<rbrakk> \<Longrightarrow> ImpL <a>.M (x).N y \<longrightarrow>\<^sub>a ImpL <a>.M (x).N' y"
4482| a_ImpR: "\<lbrakk>a\<sharp>b; M\<longrightarrow>\<^sub>a M'\<rbrakk> \<Longrightarrow> ImpR (x).<a>.M b \<longrightarrow>\<^sub>a ImpR (x).<a>.M' b"
4483
4484lemma fresh_a_redu:
4485  fixes x::"name"
4486  and   c::"coname"
4487  shows "M \<longrightarrow>\<^sub>a M' \<Longrightarrow> x\<sharp>M \<Longrightarrow> x\<sharp>M'"
4488  and   "M \<longrightarrow>\<^sub>a M' \<Longrightarrow> c\<sharp>M \<Longrightarrow> c\<sharp>M'"
4489apply -
4490apply(induct rule: a_redu.induct)
4491apply(simp add: fresh_l_redu)
4492apply(simp add: fresh_c_redu)
4493apply(auto simp add: abs_fresh abs_supp fin_supp)
4494apply(induct rule: a_redu.induct)
4495apply(simp add: fresh_l_redu)
4496apply(simp add: fresh_c_redu)
4497apply(auto simp add: abs_fresh abs_supp fin_supp)
4498done
4499
4500equivariance a_redu
4501
4502nominal_inductive a_redu
4503  by (simp_all add: abs_fresh fresh_atm fresh_prod abs_supp fin_supp fresh_a_redu)
4504
4505lemma better_CutL_intro[intro]:
4506  shows "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>a Cut <a>.M' (x).N"
4507proof -
4508  assume red: "M\<longrightarrow>\<^sub>a M'"
4509  obtain x'::"name"   where fs1: "x'\<sharp>(M,N,x)" by (rule exists_fresh(1), rule fin_supp, blast)
4510  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,a)" by (rule exists_fresh(2), rule fin_supp, blast)
4511  have "Cut <a>.M (x).N =  Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N)"
4512    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4513  also have "\<dots> \<longrightarrow>\<^sub>a  Cut <a'>.([(a',a)]\<bullet>M') (x').([(x',x)]\<bullet>N)" using fs1 fs2 red
4514    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt)
4515  also have "\<dots> = Cut <a>.M' (x).N" 
4516    using fs1 fs2 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4517  finally show ?thesis by simp
4518qed
4519
4520lemma better_CutR_intro[intro]:
4521  shows "N\<longrightarrow>\<^sub>a N' \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>a Cut <a>.M (x).N'"
4522proof -
4523  assume red: "N\<longrightarrow>\<^sub>a N'"
4524  obtain x'::"name"   where fs1: "x'\<sharp>(M,N,x)" by (rule exists_fresh(1), rule fin_supp, blast)
4525  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,a)" by (rule exists_fresh(2), rule fin_supp, blast)
4526  have "Cut <a>.M (x).N =  Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N)"
4527    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4528  also have "\<dots> \<longrightarrow>\<^sub>a  Cut <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N')" using fs1 fs2 red
4529    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt)
4530  also have "\<dots> = Cut <a>.M (x).N'" 
4531    using fs1 fs2 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4532  finally show ?thesis by simp
4533qed
4534    
4535lemma better_AndRL_intro[intro]:
4536  shows "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> AndR <a>.M <b>.N c \<longrightarrow>\<^sub>a AndR <a>.M' <b>.N c"
4537proof -
4538  assume red: "M\<longrightarrow>\<^sub>a M'"
4539  obtain b'::"coname" where fs1: "b'\<sharp>(M,N,a,b,c)" by (rule exists_fresh(2), rule fin_supp, blast)
4540  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,a,b,c,b')" by (rule exists_fresh(2), rule fin_supp, blast)
4541  have "AndR <a>.M <b>.N c =  AndR <a'>.([(a',a)]\<bullet>M) <b'>.([(b',b)]\<bullet>N) c"
4542    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4543  also have "\<dots> \<longrightarrow>\<^sub>a  AndR <a'>.([(a',a)]\<bullet>M') <b'>.([(b',b)]\<bullet>N) c" using fs1 fs2 red
4544    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4545  also have "\<dots> = AndR <a>.M' <b>.N c" 
4546    using fs1 fs2 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4547  finally show ?thesis by simp
4548qed
4549
4550lemma better_AndRR_intro[intro]:
4551  shows "N\<longrightarrow>\<^sub>a N' \<Longrightarrow> AndR <a>.M <b>.N c \<longrightarrow>\<^sub>a AndR <a>.M <b>.N' c"
4552proof -
4553  assume red: "N\<longrightarrow>\<^sub>a N'"
4554  obtain b'::"coname" where fs1: "b'\<sharp>(M,N,a,b,c)" by (rule exists_fresh(2), rule fin_supp, blast)
4555  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,a,b,c,b')" by (rule exists_fresh(2), rule fin_supp, blast)
4556  have "AndR <a>.M <b>.N c =  AndR <a'>.([(a',a)]\<bullet>M) <b'>.([(b',b)]\<bullet>N) c"
4557    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4558  also have "\<dots> \<longrightarrow>\<^sub>a  AndR <a'>.([(a',a)]\<bullet>M) <b'>.([(b',b)]\<bullet>N') c" using fs1 fs2 red
4559    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4560  also have "\<dots> = AndR <a>.M <b>.N' c" 
4561    using fs1 fs2 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4562  finally show ?thesis by simp
4563qed
4564
4565lemma better_AndL1_intro[intro]:
4566  shows "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> AndL1 (x).M y \<longrightarrow>\<^sub>a AndL1 (x).M' y"
4567proof -
4568  assume red: "M\<longrightarrow>\<^sub>a M'"
4569  obtain x'::"name" where fs1: "x'\<sharp>(M,y,x)" by (rule exists_fresh(1), rule fin_supp, blast)
4570  have "AndL1 (x).M y = AndL1 (x').([(x',x)]\<bullet>M) y"
4571    using fs1 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4572  also have "\<dots> \<longrightarrow>\<^sub>a AndL1 (x').([(x',x)]\<bullet>M') y" using fs1 red
4573    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4574  also have "\<dots> = AndL1 (x).M' y" 
4575    using fs1 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4576  finally show ?thesis by simp
4577qed
4578
4579lemma better_AndL2_intro[intro]:
4580  shows "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> AndL2 (x).M y \<longrightarrow>\<^sub>a AndL2 (x).M' y"
4581proof -
4582  assume red: "M\<longrightarrow>\<^sub>a M'"
4583  obtain x'::"name" where fs1: "x'\<sharp>(M,y,x)" by (rule exists_fresh(1), rule fin_supp, blast)
4584  have "AndL2 (x).M y = AndL2 (x').([(x',x)]\<bullet>M) y"
4585    using fs1 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4586  also have "\<dots> \<longrightarrow>\<^sub>a AndL2 (x').([(x',x)]\<bullet>M') y" using fs1 red
4587    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4588  also have "\<dots> = AndL2 (x).M' y" 
4589    using fs1 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4590  finally show ?thesis by simp
4591qed
4592
4593lemma better_OrLL_intro[intro]:
4594  shows "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> OrL (x).M (y).N z \<longrightarrow>\<^sub>a OrL (x).M' (y).N z"
4595proof -
4596  assume red: "M\<longrightarrow>\<^sub>a M'"
4597  obtain x'::"name" where fs1: "x'\<sharp>(M,N,x,y,z)" by (rule exists_fresh(1), rule fin_supp, blast)
4598  obtain y'::"name" where fs2: "y'\<sharp>(M,N,x,y,z,x')" by (rule exists_fresh(1), rule fin_supp, blast)
4599  have "OrL (x).M (y).N z =  OrL (x').([(x',x)]\<bullet>M) (y').([(y',y)]\<bullet>N) z"
4600    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4601  also have "\<dots> \<longrightarrow>\<^sub>a OrL (x').([(x',x)]\<bullet>M') (y').([(y',y)]\<bullet>N) z" using fs1 fs2 red
4602    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4603  also have "\<dots> = OrL (x).M' (y).N z" 
4604    using fs1 fs2 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4605  finally show ?thesis by simp
4606qed
4607
4608lemma better_OrLR_intro[intro]:
4609  shows "N\<longrightarrow>\<^sub>a N' \<Longrightarrow> OrL (x).M (y).N z \<longrightarrow>\<^sub>a OrL (x).M (y).N' z"
4610proof -
4611  assume red: "N\<longrightarrow>\<^sub>a N'"
4612  obtain x'::"name" where fs1: "x'\<sharp>(M,N,x,y,z)" by (rule exists_fresh(1), rule fin_supp, blast)
4613  obtain y'::"name" where fs2: "y'\<sharp>(M,N,x,y,z,x')" by (rule exists_fresh(1), rule fin_supp, blast)
4614  have "OrL (x).M (y).N z =  OrL (x').([(x',x)]\<bullet>M) (y').([(y',y)]\<bullet>N) z"
4615    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4616  also have "\<dots> \<longrightarrow>\<^sub>a OrL (x').([(x',x)]\<bullet>M) (y').([(y',y)]\<bullet>N') z" using fs1 fs2 red
4617    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4618  also have "\<dots> = OrL (x).M (y).N' z" 
4619    using fs1 fs2 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4620  finally show ?thesis by simp
4621qed
4622
4623lemma better_OrR1_intro[intro]:
4624  shows "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> OrR1 <a>.M b \<longrightarrow>\<^sub>a OrR1 <a>.M' b"
4625proof -
4626  assume red: "M\<longrightarrow>\<^sub>a M'"
4627  obtain a'::"coname" where fs1: "a'\<sharp>(M,b,a)" by (rule exists_fresh(2), rule fin_supp, blast)
4628  have "OrR1 <a>.M b = OrR1 <a'>.([(a',a)]\<bullet>M) b"
4629    using fs1 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4630  also have "\<dots> \<longrightarrow>\<^sub>a OrR1 <a'>.([(a',a)]\<bullet>M') b" using fs1 red
4631    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4632  also have "\<dots> = OrR1 <a>.M' b" 
4633    using fs1 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4634  finally show ?thesis by simp
4635qed
4636
4637lemma better_OrR2_intro[intro]:
4638  shows "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> OrR2 <a>.M b \<longrightarrow>\<^sub>a OrR2 <a>.M' b"
4639proof -
4640  assume red: "M\<longrightarrow>\<^sub>a M'"
4641  obtain a'::"coname" where fs1: "a'\<sharp>(M,b,a)" by (rule exists_fresh(2), rule fin_supp, blast)
4642  have "OrR2 <a>.M b = OrR2 <a'>.([(a',a)]\<bullet>M) b"
4643    using fs1 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4644  also have "\<dots> \<longrightarrow>\<^sub>a OrR2 <a'>.([(a',a)]\<bullet>M') b" using fs1 red
4645    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4646  also have "\<dots> = OrR2 <a>.M' b" 
4647    using fs1 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4648  finally show ?thesis by simp
4649qed
4650
4651lemma better_ImpLL_intro[intro]:
4652  shows "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> ImpL <a>.M (x).N y \<longrightarrow>\<^sub>a ImpL <a>.M' (x).N y"
4653proof -
4654  assume red: "M\<longrightarrow>\<^sub>a M'"
4655  obtain x'::"name"   where fs1: "x'\<sharp>(M,N,x,y)" by (rule exists_fresh(1), rule fin_supp, blast)
4656  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,a)" by (rule exists_fresh(2), rule fin_supp, blast)
4657  have "ImpL <a>.M (x).N y =  ImpL <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N) y"
4658    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4659  also have "\<dots> \<longrightarrow>\<^sub>a  ImpL <a'>.([(a',a)]\<bullet>M') (x').([(x',x)]\<bullet>N) y" using fs1 fs2 red
4660    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4661  also have "\<dots> = ImpL <a>.M' (x).N y" 
4662    using fs1 fs2 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4663  finally show ?thesis by simp
4664qed
4665
4666lemma better_ImpLR_intro[intro]:
4667  shows "N\<longrightarrow>\<^sub>a N' \<Longrightarrow> ImpL <a>.M (x).N y \<longrightarrow>\<^sub>a ImpL <a>.M (x).N' y"
4668proof -
4669  assume red: "N\<longrightarrow>\<^sub>a N'"
4670  obtain x'::"name"   where fs1: "x'\<sharp>(M,N,x,y)" by (rule exists_fresh(1), rule fin_supp, blast)
4671  obtain a'::"coname" where fs2: "a'\<sharp>(M,N,a)" by (rule exists_fresh(2), rule fin_supp, blast)
4672  have "ImpL <a>.M (x).N y =  ImpL <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N) y"
4673    using fs1 fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4674  also have "\<dots> \<longrightarrow>\<^sub>a  ImpL <a'>.([(a',a)]\<bullet>M) (x').([(x',x)]\<bullet>N') y" using fs1 fs2 red
4675    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4676  also have "\<dots> = ImpL <a>.M (x).N' y" 
4677    using fs1 fs2 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4678  finally show ?thesis by simp
4679qed
4680
4681lemma better_ImpR_intro[intro]:
4682  shows "M\<longrightarrow>\<^sub>a M' \<Longrightarrow> ImpR (x).<a>.M b \<longrightarrow>\<^sub>a ImpR (x).<a>.M' b"
4683proof -
4684  assume red: "M\<longrightarrow>\<^sub>a M'"
4685  obtain a'::"coname" where fs2: "a'\<sharp>(M,a,b)" by (rule exists_fresh(2), rule fin_supp, blast)
4686  have "ImpR (x).<a>.M b = ImpR (x).<a'>.([(a',a)]\<bullet>M) b"
4687    using fs2 by (rule_tac sym, auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm)
4688  also have "\<dots> \<longrightarrow>\<^sub>a ImpR (x).<a'>.([(a',a)]\<bullet>M') b" using fs2 red
4689    by (auto intro: a_redu.intros simp add: fresh_left calc_atm a_redu.eqvt fresh_atm fresh_prod)
4690  also have "\<dots> = ImpR (x).<a>.M' b" 
4691    using fs2 red by (auto simp add: trm.inject alpha fresh_atm fresh_prod calc_atm fresh_a_redu)
4692  finally show ?thesis by simp
4693qed
4694
4695text \<open>axioms do not reduce\<close>
4696
4697lemma ax_do_not_l_reduce:
4698  shows "Ax x a \<longrightarrow>\<^sub>l M \<Longrightarrow> False"
4699by (erule_tac l_redu.cases) (simp_all add: trm.inject)
4700 
4701lemma ax_do_not_c_reduce:
4702  shows "Ax x a \<longrightarrow>\<^sub>c M \<Longrightarrow> False"
4703by (erule_tac c_redu.cases) (simp_all add: trm.inject)
4704
4705lemma ax_do_not_a_reduce:
4706  shows "Ax x a \<longrightarrow>\<^sub>a M \<Longrightarrow> False"
4707apply(erule_tac a_redu.cases) 
4708apply(auto simp add: trm.inject)
4709apply(drule ax_do_not_l_reduce)
4710apply(simp)
4711apply(drule ax_do_not_c_reduce)
4712apply(simp)
4713done
4714
4715lemma a_redu_NotL_elim:
4716  assumes a: "NotL <a>.M x \<longrightarrow>\<^sub>a R"
4717  shows "\<exists>M'. R = NotL <a>.M' x \<and> M\<longrightarrow>\<^sub>aM'"
4718using a
4719apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4720apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4721apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4722apply(auto)
4723apply(rotate_tac 2)
4724apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4725apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4726apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4727apply(auto simp add: alpha a_redu.eqvt)
4728apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
4729apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4730apply(simp add: perm_swap)
4731apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
4732apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4733apply(simp add: perm_swap)
4734done
4735
4736lemma a_redu_NotR_elim:
4737  assumes a: "NotR (x).M a \<longrightarrow>\<^sub>a R"
4738  shows "\<exists>M'. R = NotR (x).M' a \<and> M\<longrightarrow>\<^sub>aM'"
4739using a
4740apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4741apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4742apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4743apply(auto)
4744apply(rotate_tac 2)
4745apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4746apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4747apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4748apply(auto simp add: alpha a_redu.eqvt)
4749apply(rule_tac x="([(x,xa)]\<bullet>M'a)" in exI)
4750apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4751apply(simp add: perm_swap)
4752apply(rule_tac x="([(x,xaa)]\<bullet>M'a)" in exI)
4753apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4754apply(simp add: perm_swap)
4755done
4756
4757lemma a_redu_AndR_elim:
4758  assumes a: "AndR <a>.M <b>.N c\<longrightarrow>\<^sub>a R"
4759  shows "(\<exists>M'. R = AndR <a>.M' <b>.N c \<and> M\<longrightarrow>\<^sub>aM') \<or> (\<exists>N'. R = AndR <a>.M <b>.N' c \<and> N\<longrightarrow>\<^sub>aN')"
4760using a
4761apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4762apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4763apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4764apply(rotate_tac 6)
4765apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4766apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4767apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4768apply(rule disjI1)
4769apply(auto simp add: alpha a_redu.eqvt)[1]
4770apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI) 
4771apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4772apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
4773apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4774apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
4775apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4776apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
4777apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4778apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
4779apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4780apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
4781apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4782apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
4783apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4784apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
4785apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4786apply(rule disjI2)
4787apply(auto simp add: alpha a_redu.eqvt)[1]
4788apply(rule_tac x="([(b,ba)]\<bullet>N')" in exI) 
4789apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4790apply(rule_tac x="([(b,baa)]\<bullet>N')" in exI)
4791apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4792apply(rule_tac x="([(b,ba)]\<bullet>N')" in exI)
4793apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4794apply(rule_tac x="([(b,baa)]\<bullet>N')" in exI)
4795apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4796apply(rule_tac x="([(b,ba)]\<bullet>N')" in exI)
4797apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4798apply(rule_tac x="([(b,baa)]\<bullet>N')" in exI)
4799apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4800apply(rule_tac x="([(b,ba)]\<bullet>N')" in exI)
4801apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4802apply(rule_tac x="([(b,baa)]\<bullet>N')" in exI)
4803apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4804apply(rotate_tac 6)
4805apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4806apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4807apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4808apply(rule disjI1)
4809apply(auto simp add: alpha a_redu.eqvt)[1]
4810apply(rule_tac x="([(a,aa)]\<bullet>M')" in exI) 
4811apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4812apply(rule_tac x="([(a,aa)]\<bullet>M')" in exI)
4813apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4814apply(rule_tac x="([(a,aa)]\<bullet>M')" in exI)
4815apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4816apply(rule_tac x="([(a,aa)]\<bullet>M')" in exI)
4817apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4818apply(rule_tac x="([(a,aaa)]\<bullet>M')" in exI)
4819apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4820apply(rule_tac x="([(a,aaa)]\<bullet>M')" in exI)
4821apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4822apply(rule_tac x="([(a,aaa)]\<bullet>M')" in exI)
4823apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4824apply(rule_tac x="([(a,aaa)]\<bullet>M')" in exI)
4825apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4826apply(rule disjI2)
4827apply(auto simp add: alpha a_redu.eqvt)[1]
4828apply(rule_tac x="([(b,ba)]\<bullet>N'a)" in exI) 
4829apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4830apply(rule_tac x="([(b,ba)]\<bullet>N'a)" in exI)
4831apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4832apply(rule_tac x="([(b,ba)]\<bullet>N'a)" in exI)
4833apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4834apply(rule_tac x="([(b,ba)]\<bullet>N'a)" in exI)
4835apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4836apply(rule_tac x="([(b,baa)]\<bullet>N'a)" in exI)
4837apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4838apply(rule_tac x="([(b,baa)]\<bullet>N'a)" in exI)
4839apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4840apply(rule_tac x="([(b,baa)]\<bullet>N'a)" in exI)
4841apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4842apply(rule_tac x="([(b,baa)]\<bullet>N'a)" in exI)
4843apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4844done
4845
4846lemma a_redu_AndL1_elim:
4847  assumes a: "AndL1 (x).M y \<longrightarrow>\<^sub>a R"
4848  shows "\<exists>M'. R = AndL1 (x).M' y \<and> M\<longrightarrow>\<^sub>aM'"
4849using a
4850apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4851apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4852apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4853apply(auto)
4854apply(rotate_tac 3)
4855apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4856apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4857apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4858apply(auto simp add: alpha a_redu.eqvt)
4859apply(rule_tac x="([(x,xa)]\<bullet>M'a)" in exI)
4860apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4861apply(simp add: perm_swap)
4862apply(rule_tac x="([(x,xaa)]\<bullet>M'a)" in exI)
4863apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4864apply(simp add: perm_swap)
4865done
4866
4867lemma a_redu_AndL2_elim:
4868  assumes a: "AndL2 (x).M y \<longrightarrow>\<^sub>a R"
4869  shows "\<exists>M'. R = AndL2 (x).M' y \<and> M\<longrightarrow>\<^sub>aM'"
4870using a
4871apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4872apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4873apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4874apply(auto)
4875apply(rotate_tac 3)
4876apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4877apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4878apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4879apply(auto simp add: alpha a_redu.eqvt)
4880apply(rule_tac x="([(x,xa)]\<bullet>M'a)" in exI)
4881apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4882apply(simp add: perm_swap)
4883apply(rule_tac x="([(x,xaa)]\<bullet>M'a)" in exI)
4884apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4885apply(simp add: perm_swap)
4886done
4887
4888lemma a_redu_OrL_elim:
4889  assumes a: "OrL (x).M (y).N z\<longrightarrow>\<^sub>a R"
4890  shows "(\<exists>M'. R = OrL (x).M' (y).N z \<and> M\<longrightarrow>\<^sub>aM') \<or> (\<exists>N'. R = OrL (x).M (y).N' z \<and> N\<longrightarrow>\<^sub>aN')"
4891using a
4892apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4893apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4894apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4895apply(rotate_tac 6)
4896apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4897apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4898apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4899apply(rule disjI1)
4900apply(auto simp add: alpha a_redu.eqvt)[1]
4901apply(rule_tac x="([(x,xa)]\<bullet>M'a)" in exI) 
4902apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4903apply(rule_tac x="([(x,xa)]\<bullet>M'a)" in exI)
4904apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4905apply(rule_tac x="([(x,xa)]\<bullet>M'a)" in exI)
4906apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4907apply(rule_tac x="([(x,xa)]\<bullet>M'a)" in exI)
4908apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4909apply(rule_tac x="([(x,xaa)]\<bullet>M'a)" in exI)
4910apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4911apply(rule_tac x="([(x,xaa)]\<bullet>M'a)" in exI)
4912apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4913apply(rule_tac x="([(x,xaa)]\<bullet>M'a)" in exI)
4914apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4915apply(rule_tac x="([(x,xaa)]\<bullet>M'a)" in exI)
4916apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4917apply(rule disjI2)
4918apply(auto simp add: alpha a_redu.eqvt)[1]
4919apply(rule_tac x="([(y,ya)]\<bullet>N')" in exI) 
4920apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4921apply(rule_tac x="([(y,yaa)]\<bullet>N')" in exI)
4922apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4923apply(rule_tac x="([(y,ya)]\<bullet>N')" in exI)
4924apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4925apply(rule_tac x="([(y,yaa)]\<bullet>N')" in exI)
4926apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4927apply(rule_tac x="([(y,ya)]\<bullet>N')" in exI)
4928apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4929apply(rule_tac x="([(y,yaa)]\<bullet>N')" in exI)
4930apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4931apply(rule_tac x="([(y,ya)]\<bullet>N')" in exI)
4932apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4933apply(rule_tac x="([(y,yaa)]\<bullet>N')" in exI)
4934apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4935apply(rotate_tac 6)
4936apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4937apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4938apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4939apply(rule disjI1)
4940apply(auto simp add: alpha a_redu.eqvt)[1]
4941apply(rule_tac x="([(x,xa)]\<bullet>M')" in exI) 
4942apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4943apply(rule_tac x="([(x,xa)]\<bullet>M')" in exI)
4944apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4945apply(rule_tac x="([(x,xa)]\<bullet>M')" in exI)
4946apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4947apply(rule_tac x="([(x,xa)]\<bullet>M')" in exI)
4948apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4949apply(rule_tac x="([(x,xaa)]\<bullet>M')" in exI)
4950apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4951apply(rule_tac x="([(x,xaa)]\<bullet>M')" in exI)
4952apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4953apply(rule_tac x="([(x,xaa)]\<bullet>M')" in exI)
4954apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4955apply(rule_tac x="([(x,xaa)]\<bullet>M')" in exI)
4956apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4957apply(rule disjI2)
4958apply(auto simp add: alpha a_redu.eqvt)[1]
4959apply(rule_tac x="([(y,ya)]\<bullet>N'a)" in exI) 
4960apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4961apply(rule_tac x="([(y,ya)]\<bullet>N'a)" in exI)
4962apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4963apply(rule_tac x="([(y,ya)]\<bullet>N'a)" in exI)
4964apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4965apply(rule_tac x="([(y,ya)]\<bullet>N'a)" in exI)
4966apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4967apply(rule_tac x="([(y,yaa)]\<bullet>N'a)" in exI)
4968apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4969apply(rule_tac x="([(y,yaa)]\<bullet>N'a)" in exI)
4970apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4971apply(rule_tac x="([(y,yaa)]\<bullet>N'a)" in exI)
4972apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4973apply(rule_tac x="([(y,yaa)]\<bullet>N'a)" in exI)
4974apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
4975done
4976
4977lemma a_redu_OrR1_elim:
4978  assumes a: "OrR1 <a>.M b \<longrightarrow>\<^sub>a R"
4979  shows "\<exists>M'. R = OrR1 <a>.M' b \<and> M\<longrightarrow>\<^sub>aM'"
4980using a
4981apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4982apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4983apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4984apply(auto)
4985apply(rotate_tac 3)
4986apply(erule_tac a_redu.cases, simp_all add: trm.inject)
4987apply(erule_tac l_redu.cases, simp_all add: trm.inject)
4988apply(erule_tac c_redu.cases, simp_all add: trm.inject)
4989apply(auto simp add: alpha a_redu.eqvt)
4990apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
4991apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4992apply(simp add: perm_swap)
4993apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
4994apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
4995apply(simp add: perm_swap)
4996done
4997
4998lemma a_redu_OrR2_elim:
4999  assumes a: "OrR2 <a>.M b \<longrightarrow>\<^sub>a R"
5000  shows "\<exists>M'. R = OrR2 <a>.M' b \<and> M\<longrightarrow>\<^sub>aM'"
5001using a
5002apply(erule_tac a_redu.cases, simp_all add: trm.inject)
5003apply(erule_tac l_redu.cases, simp_all add: trm.inject)
5004apply(erule_tac c_redu.cases, simp_all add: trm.inject)
5005apply(auto)
5006apply(rotate_tac 3)
5007apply(erule_tac a_redu.cases, simp_all add: trm.inject)
5008apply(erule_tac l_redu.cases, simp_all add: trm.inject)
5009apply(erule_tac c_redu.cases, simp_all add: trm.inject)
5010apply(auto simp add: alpha a_redu.eqvt)
5011apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
5012apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
5013apply(simp add: perm_swap)
5014apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
5015apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)
5016apply(simp add: perm_swap)
5017done
5018
5019lemma a_redu_ImpL_elim:
5020  assumes a: "ImpL <a>.M (y).N z\<longrightarrow>\<^sub>a R"
5021  shows "(\<exists>M'. R = ImpL <a>.M' (y).N z \<and> M\<longrightarrow>\<^sub>aM') \<or> (\<exists>N'. R = ImpL <a>.M (y).N' z \<and> N\<longrightarrow>\<^sub>aN')"
5022using a
5023apply(erule_tac a_redu.cases, simp_all add: trm.inject)
5024apply(erule_tac l_redu.cases, simp_all add: trm.inject)
5025apply(erule_tac c_redu.cases, simp_all add: trm.inject)
5026apply(rotate_tac 5)
5027apply(erule_tac a_redu.cases, simp_all add: trm.inject)
5028apply(erule_tac l_redu.cases, simp_all add: trm.inject)
5029apply(erule_tac c_redu.cases, simp_all add: trm.inject)
5030apply(rule disjI1)
5031apply(auto simp add: alpha a_redu.eqvt)[1]
5032apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI) 
5033apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5034apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
5035apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5036apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
5037apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5038apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
5039apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5040apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
5041apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5042apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
5043apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5044apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
5045apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5046apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
5047apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5048apply(rule disjI2)
5049apply(auto simp add: alpha a_redu.eqvt)[1]
5050apply(rule_tac x="([(y,xa)]\<bullet>N')" in exI) 
5051apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5052apply(rule_tac x="([(y,xa)]\<bullet>N')" in exI)
5053apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5054apply(rule_tac x="([(y,xa)]\<bullet>N')" in exI)
5055apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5056apply(rule_tac x="([(y,xa)]\<bullet>N')" in exI)
5057apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5058apply(rule_tac x="([(y,xa)]\<bullet>N')" in exI)
5059apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5060apply(rule_tac x="([(y,xa)]\<bullet>N')" in exI)
5061apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5062apply(rule_tac x="([(y,xa)]\<bullet>N')" in exI)
5063apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5064apply(rule_tac x="([(y,xa)]\<bullet>N')" in exI)
5065apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5066apply(rotate_tac 5)
5067apply(erule_tac a_redu.cases, simp_all add: trm.inject)
5068apply(erule_tac l_redu.cases, simp_all add: trm.inject)
5069apply(erule_tac c_redu.cases, simp_all add: trm.inject)
5070apply(rule disjI1)
5071apply(auto simp add: alpha a_redu.eqvt)[1]
5072apply(rule_tac x="([(a,aa)]\<bullet>M')" in exI) 
5073apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5074apply(rule_tac x="([(a,aa)]\<bullet>M')" in exI)
5075apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5076apply(rule_tac x="([(a,aa)]\<bullet>M')" in exI)
5077apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5078apply(rule_tac x="([(a,aa)]\<bullet>M')" in exI)
5079apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5080apply(rule_tac x="([(a,aaa)]\<bullet>M')" in exI)
5081apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5082apply(rule_tac x="([(a,aaa)]\<bullet>M')" in exI)
5083apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5084apply(rule_tac x="([(a,aaa)]\<bullet>M')" in exI)
5085apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5086apply(rule_tac x="([(a,aaa)]\<bullet>M')" in exI)
5087apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5088apply(rule disjI2)
5089apply(auto simp add: alpha a_redu.eqvt)[1]
5090apply(rule_tac x="([(y,xa)]\<bullet>N'a)" in exI) 
5091apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5092apply(rule_tac x="([(y,xa)]\<bullet>N'a)" in exI)
5093apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5094apply(rule_tac x="([(y,xa)]\<bullet>N'a)" in exI)
5095apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5096apply(rule_tac x="([(y,xa)]\<bullet>N'a)" in exI)
5097apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5098apply(rule_tac x="([(y,xa)]\<bullet>N'a)" in exI)
5099apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5100apply(rule_tac x="([(y,xa)]\<bullet>N'a)" in exI)
5101apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5102apply(rule_tac x="([(y,xa)]\<bullet>N'a)" in exI)
5103apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5104apply(rule_tac x="([(y,xa)]\<bullet>N'a)" in exI)
5105apply(auto simp add: perm_swap fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu)[1]
5106done
5107
5108lemma a_redu_ImpR_elim:
5109  assumes a: "ImpR (x).<a>.M b \<longrightarrow>\<^sub>a R"
5110  shows "\<exists>M'. R = ImpR (x).<a>.M' b \<and> M\<longrightarrow>\<^sub>aM'"
5111using a
5112apply(erule_tac a_redu.cases, simp_all add: trm.inject)
5113apply(erule_tac l_redu.cases, simp_all add: trm.inject)
5114apply(erule_tac c_redu.cases, simp_all add: trm.inject)
5115apply(auto)
5116apply(rotate_tac 3)
5117apply(erule_tac a_redu.cases, simp_all add: trm.inject)
5118apply(erule_tac l_redu.cases, simp_all add: trm.inject)
5119apply(erule_tac c_redu.cases, simp_all add: trm.inject)
5120apply(auto simp add: alpha a_redu.eqvt abs_perm abs_fresh)
5121apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
5122apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5123apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
5124apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5125apply(rule_tac x="([(a,aa)]\<bullet>M'a)" in exI)
5126apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5127apply(rule_tac x="([(a,aaa)]\<bullet>M'a)" in exI)
5128apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5129apply(rule_tac x="([(x,xa)]\<bullet>M'a)" in exI)
5130apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5131apply(rule_tac x="([(x,xa)]\<bullet>M'a)" in exI)
5132apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5133apply(rule_tac x="([(a,aa)]\<bullet>[(x,xa)]\<bullet>M'a)" in exI)
5134apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5135apply(rule sym)
5136apply(rule trans)
5137apply(rule perm_compose)
5138apply(simp add: calc_atm perm_swap)
5139apply(rule_tac x="([(a,aaa)]\<bullet>[(x,xa)]\<bullet>M'a)" in exI)
5140apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5141apply(rule sym)
5142apply(rule trans)
5143apply(rule perm_compose)
5144apply(simp add: calc_atm perm_swap)
5145apply(rule_tac x="([(x,xaa)]\<bullet>M'a)" in exI)
5146apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5147apply(rule_tac x="([(x,xaa)]\<bullet>M'a)" in exI)
5148apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5149apply(rule_tac x="([(a,aa)]\<bullet>[(x,xaa)]\<bullet>M'a)" in exI)
5150apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5151apply(rule sym)
5152apply(rule trans)
5153apply(rule perm_compose)
5154apply(simp add: calc_atm perm_swap)
5155apply(rule_tac x="([(a,aaa)]\<bullet>[(x,xaa)]\<bullet>M'a)" in exI)
5156apply(auto simp add: fresh_left alpha a_redu.eqvt calc_atm fresh_a_redu perm_swap)
5157apply(rule sym)
5158apply(rule trans)
5159apply(rule perm_compose)
5160apply(simp add: calc_atm perm_swap)
5161done
5162
5163text \<open>Transitive Closure\<close>
5164
5165abbreviation
5166 a_star_redu :: "trm \<Rightarrow> trm \<Rightarrow> bool" ("_ \<longrightarrow>\<^sub>a* _" [100,100] 100)
5167where
5168  "M \<longrightarrow>\<^sub>a* M' \<equiv> (a_redu)\<^sup>*\<^sup>* M M'"
5169
5170lemma a_starI:
5171  assumes a: "M \<longrightarrow>\<^sub>a M'"
5172  shows "M \<longrightarrow>\<^sub>a* M'"
5173using a by blast
5174
5175lemma a_starE:
5176  assumes a: "M \<longrightarrow>\<^sub>a* M'"
5177  shows "M = M' \<or> (\<exists>N. M \<longrightarrow>\<^sub>a N \<and> N \<longrightarrow>\<^sub>a* M')"
5178using a 
5179by (induct) (auto)
5180
5181lemma a_star_refl:
5182  shows "M \<longrightarrow>\<^sub>a* M"
5183  by blast
5184
5185lemma a_star_trans[trans]:
5186  assumes a1: "M1\<longrightarrow>\<^sub>a* M2"
5187  and     a2: "M2\<longrightarrow>\<^sub>a* M3"
5188  shows "M1 \<longrightarrow>\<^sub>a* M3"
5189using a2 a1
5190by (induct) (auto)
5191
5192text \<open>congruence rules for \<open>\<longrightarrow>\<^sub>a*\<close>\<close>
5193
5194lemma ax_do_not_a_star_reduce:
5195  shows "Ax x a \<longrightarrow>\<^sub>a* M \<Longrightarrow> M = Ax x a"
5196apply(induct set: rtranclp)
5197apply(auto)
5198apply(drule  ax_do_not_a_reduce)
5199apply(simp)
5200done
5201
5202
5203lemma a_star_CutL:
5204    "M \<longrightarrow>\<^sub>a* M' \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>a* Cut <a>.M' (x).N"
5205by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5206
5207lemma a_star_CutR:
5208    "N \<longrightarrow>\<^sub>a* N'\<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>a* Cut <a>.M (x).N'"
5209by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5210
5211lemma a_star_Cut:
5212    "\<lbrakk>M \<longrightarrow>\<^sub>a* M'; N \<longrightarrow>\<^sub>a* N'\<rbrakk> \<Longrightarrow> Cut <a>.M (x).N \<longrightarrow>\<^sub>a* Cut <a>.M' (x).N'"
5213by (blast intro!: a_star_CutL a_star_CutR intro: rtranclp_trans)
5214
5215lemma a_star_NotR:
5216    "M \<longrightarrow>\<^sub>a* M' \<Longrightarrow> NotR (x).M a \<longrightarrow>\<^sub>a* NotR (x).M' a"
5217by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5218
5219lemma a_star_NotL:
5220    "M \<longrightarrow>\<^sub>a* M' \<Longrightarrow> NotL <a>.M x \<longrightarrow>\<^sub>a* NotL <a>.M' x"
5221by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5222
5223lemma a_star_AndRL:
5224    "M \<longrightarrow>\<^sub>a* M'\<Longrightarrow> AndR <a>.M <b>.N c \<longrightarrow>\<^sub>a* AndR <a>.M' <b>.N c"
5225by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5226
5227lemma a_star_AndRR:
5228    "N \<longrightarrow>\<^sub>a* N'\<Longrightarrow> AndR <a>.M <b>.N c \<longrightarrow>\<^sub>a* AndR <a>.M <b>.N' c"
5229by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5230
5231lemma a_star_AndR:
5232    "\<lbrakk>M \<longrightarrow>\<^sub>a* M'; N \<longrightarrow>\<^sub>a* N'\<rbrakk> \<Longrightarrow> AndR <a>.M <b>.N c \<longrightarrow>\<^sub>a* AndR <a>.M' <b>.N' c"
5233by (blast intro!: a_star_AndRL a_star_AndRR intro: rtranclp_trans)
5234
5235lemma a_star_AndL1:
5236    "M \<longrightarrow>\<^sub>a* M' \<Longrightarrow> AndL1 (x).M y \<longrightarrow>\<^sub>a* AndL1 (x).M' y"
5237by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5238
5239lemma a_star_AndL2:
5240    "M \<longrightarrow>\<^sub>a* M' \<Longrightarrow> AndL2 (x).M y \<longrightarrow>\<^sub>a* AndL2 (x).M' y"
5241by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5242
5243lemma a_star_OrLL:
5244    "M \<longrightarrow>\<^sub>a* M'\<Longrightarrow> OrL (x).M (y).N z \<longrightarrow>\<^sub>a* OrL (x).M' (y).N z"
5245by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5246
5247lemma a_star_OrLR:
5248    "N \<longrightarrow>\<^sub>a* N'\<Longrightarrow> OrL (x).M (y).N z \<longrightarrow>\<^sub>a* OrL (x).M (y).N' z"
5249by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5250
5251lemma a_star_OrL:
5252    "\<lbrakk>M \<longrightarrow>\<^sub>a* M'; N \<longrightarrow>\<^sub>a* N'\<rbrakk> \<Longrightarrow> OrL (x).M (y).N z \<longrightarrow>\<^sub>a* OrL (x).M' (y).N' z"
5253by (blast intro!: a_star_OrLL a_star_OrLR intro: rtranclp_trans)
5254
5255lemma a_star_OrR1:
5256    "M \<longrightarrow>\<^sub>a* M' \<Longrightarrow> OrR1 <a>.M b \<longrightarrow>\<^sub>a* OrR1 <a>.M' b"
5257by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5258
5259lemma a_star_OrR2:
5260    "M \<longrightarrow>\<^sub>a* M' \<Longrightarrow> OrR2 <a>.M b \<longrightarrow>\<^sub>a* OrR2 <a>.M' b"
5261by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5262
5263lemma a_star_ImpLL:
5264    "M \<longrightarrow>\<^sub>a* M'\<Longrightarrow> ImpL <a>.M (y).N z \<longrightarrow>\<^sub>a* ImpL <a>.M' (y).N z"
5265by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5266
5267lemma a_star_ImpLR:
5268    "N \<longrightarrow>\<^sub>a* N'\<Longrightarrow> ImpL <a>.M (y).N z \<longrightarrow>\<^sub>a* ImpL <a>.M (y).N' z"
5269by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5270
5271lemma a_star_ImpL:
5272    "\<lbrakk>M \<longrightarrow>\<^sub>a* M'; N \<longrightarrow>\<^sub>a* N'\<rbrakk> \<Longrightarrow> ImpL <a>.M (y).N z \<longrightarrow>\<^sub>a* ImpL <a>.M' (y).N' z"
5273by (blast intro!: a_star_ImpLL a_star_ImpLR intro: rtranclp_trans)
5274
5275lemma a_star_ImpR:
5276    "M \<longrightarrow>\<^sub>a* M' \<Longrightarrow> ImpR (x).<a>.M b \<longrightarrow>\<^sub>a* ImpR (x).<a>.M' b"
5277by (induct set: rtranclp) (blast intro: rtranclp.rtrancl_into_rtrancl)+
5278
5279lemmas a_star_congs = a_star_Cut a_star_NotR a_star_NotL a_star_AndR a_star_AndL1 a_star_AndL2
5280                      a_star_OrL a_star_OrR1 a_star_OrR2 a_star_ImpL a_star_ImpR
5281
5282lemma a_star_redu_NotL_elim:
5283  assumes a: "NotL <a>.M x \<longrightarrow>\<^sub>a* R"
5284  shows "\<exists>M'. R = NotL <a>.M' x \<and> M \<longrightarrow>\<^sub>a* M'"
5285using a
5286apply(induct set: rtranclp)
5287apply(auto)
5288apply(drule a_redu_NotL_elim)
5289apply(auto)
5290done
5291
5292lemma a_star_redu_NotR_elim:
5293  assumes a: "NotR (x).M a \<longrightarrow>\<^sub>a* R"
5294  shows "\<exists>M'. R = NotR (x).M' a \<and> M \<longrightarrow>\<^sub>a* M'"
5295using a
5296apply(induct set: rtranclp)
5297apply(auto)
5298apply(drule a_redu_NotR_elim)
5299apply(auto)
5300done
5301
5302lemma a_star_redu_AndR_elim:
5303  assumes a: "AndR <a>.M <b>.N c\<longrightarrow>\<^sub>a* R"
5304  shows "(\<exists>M' N'. R = AndR <a>.M' <b>.N' c \<and> M \<longrightarrow>\<^sub>a* M' \<and> N \<longrightarrow>\<^sub>a* N')"
5305using a
5306apply(induct set: rtranclp)
5307apply(auto)
5308apply(drule a_redu_AndR_elim)
5309apply(auto simp add: alpha trm.inject)
5310done
5311
5312lemma a_star_redu_AndL1_elim:
5313  assumes a: "AndL1 (x).M y \<longrightarrow>\<^sub>a* R"
5314  shows "\<exists>M'. R = AndL1 (x).M' y \<and> M \<longrightarrow>\<^sub>a* M'"
5315using a
5316apply(induct set: rtranclp)
5317apply(auto)
5318apply(drule a_redu_AndL1_elim)
5319apply(auto simp add: alpha trm.inject)
5320done
5321
5322lemma a_star_redu_AndL2_elim:
5323  assumes a: "AndL2 (x).M y \<longrightarrow>\<^sub>a* R"
5324  shows "\<exists>M'. R = AndL2 (x).M' y \<and> M \<longrightarrow>\<^sub>a* M'"
5325using a
5326apply(induct set: rtranclp)
5327apply(auto)
5328apply(drule a_redu_AndL2_elim)
5329apply(auto simp add: alpha trm.inject)
5330done
5331
5332lemma a_star_redu_OrL_elim:
5333  assumes a: "OrL (x).M (y).N z \<longrightarrow>\<^sub>a* R"
5334  shows "(\<exists>M' N'. R = OrL (x).M' (y).N' z \<and> M \<longrightarrow>\<^sub>a* M' \<and> N \<longrightarrow>\<^sub>a* N')"
5335using a
5336apply(induct set: rtranclp)
5337apply(auto)
5338apply(drule a_redu_OrL_elim)
5339apply(auto simp add: alpha trm.inject)
5340done
5341
5342lemma a_star_redu_OrR1_elim:
5343  assumes a: "OrR1 <a>.M y \<longrightarrow>\<^sub>a* R"
5344  shows "\<exists>M'. R = OrR1 <a>.M' y \<and> M \<longrightarrow>\<^sub>a* M'"
5345using a
5346apply(induct set: rtranclp)
5347apply(auto)
5348apply(drule a_redu_OrR1_elim)
5349apply(auto simp add: alpha trm.inject)
5350done
5351
5352lemma a_star_redu_OrR2_elim:
5353  assumes a: "OrR2 <a>.M y \<longrightarrow>\<^sub>a* R"
5354  shows "\<exists>M'. R = OrR2 <a>.M' y \<and> M \<longrightarrow>\<^sub>a* M'"
5355using a
5356apply(induct set: rtranclp)
5357apply(auto)
5358apply(drule a_redu_OrR2_elim)
5359apply(auto simp add: alpha trm.inject)
5360done
5361
5362lemma a_star_redu_ImpR_elim:
5363  assumes a: "ImpR (x).<a>.M y \<longrightarrow>\<^sub>a* R"
5364  shows "\<exists>M'. R = ImpR (x).<a>.M' y \<and> M \<longrightarrow>\<^sub>a* M'"
5365using a
5366apply(induct set: rtranclp)
5367apply(auto)
5368apply(drule a_redu_ImpR_elim)
5369apply(auto simp add: alpha trm.inject)
5370done
5371
5372lemma a_star_redu_ImpL_elim:
5373  assumes a: "ImpL <a>.M (y).N z \<longrightarrow>\<^sub>a* R"
5374  shows "(\<exists>M' N'. R = ImpL <a>.M' (y).N' z \<and> M \<longrightarrow>\<^sub>a* M' \<and> N \<longrightarrow>\<^sub>a* N')"
5375using a
5376apply(induct set: rtranclp)
5377apply(auto)
5378apply(drule a_redu_ImpL_elim)
5379apply(auto simp add: alpha trm.inject)
5380done
5381
5382text \<open>Substitution\<close>
5383
5384lemma subst_not_fin1:
5385  shows "\<not>fin(M{x:=<c>.P}) x"
5386apply(nominal_induct M avoiding: x c P rule: trm.strong_induct)
5387apply(auto)
5388apply(drule fin_elims, simp)
5389apply(drule fin_elims, simp)
5390apply(erule fin.cases, simp_all add: trm.inject)
5391apply(erule fin.cases, simp_all add: trm.inject)
5392apply(erule fin.cases, simp_all add: trm.inject)
5393apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<c>.P},P)")
5394apply(erule exE)
5395apply(simp add: fresh_prod)
5396apply(erule conjE)+
5397apply(simp add: fresh_fun_simp_NotL)
5398apply(erule fin.cases, simp_all add: trm.inject)
5399apply(rule exists_fresh'(1)[OF fs_name1])
5400apply(erule fin.cases, simp_all add: trm.inject)
5401apply(erule fin.cases, simp_all add: trm.inject)
5402apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<c>.P},P,name1)")
5403apply(erule exE)
5404apply(simp add: fresh_prod)
5405apply(erule conjE)+
5406apply(simp add: fresh_fun_simp_AndL1)
5407apply(erule fin.cases, simp_all add: trm.inject)
5408apply(rule exists_fresh'(1)[OF fs_name1])
5409apply(erule fin.cases, simp_all add: trm.inject)
5410apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<c>.P},P,name1)")
5411apply(erule exE)
5412apply(simp add: fresh_prod)
5413apply(erule conjE)+
5414apply(simp add: fresh_fun_simp_AndL2)
5415apply(erule fin.cases, simp_all add: trm.inject)
5416apply(rule exists_fresh'(1)[OF fs_name1])
5417apply(erule fin.cases, simp_all add: trm.inject)
5418apply(erule fin.cases, simp_all add: trm.inject)
5419apply(erule fin.cases, simp_all add: trm.inject)
5420apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{x:=<c>.P},P,name1,trm2{x:=<c>.P},name2)")
5421apply(erule exE)
5422apply(simp add: fresh_prod)
5423apply(erule conjE)+
5424apply(simp add: fresh_fun_simp_OrL)
5425apply(erule fin.cases, simp_all add: trm.inject)
5426apply(rule exists_fresh'(1)[OF fs_name1])
5427apply(erule fin.cases, simp_all add: trm.inject)
5428apply(erule fin.cases, simp_all add: trm.inject)
5429apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<c>.P},P,name1,trm2{name2:=<c>.P})")
5430apply(erule exE)
5431apply(simp add: fresh_prod)
5432apply(erule conjE)+
5433apply(simp add: fresh_fun_simp_ImpL)
5434apply(erule fin.cases, simp_all add: trm.inject)
5435apply(rule exists_fresh'(1)[OF fs_name1])
5436apply(erule fin.cases, simp_all add: trm.inject)
5437done
5438
5439lemma subst_not_fin2:
5440  assumes a: "\<not>fin M y"
5441  shows "\<not>fin(M{c:=(x).P}) y" 
5442using a
5443apply(nominal_induct M avoiding: x c P y rule: trm.strong_induct)
5444apply(auto)
5445apply(drule fin_elims, simp)
5446apply(drule fin_elims, simp)
5447apply(drule fin_elims, simp)
5448apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm{coname:=(x).P},P)")
5449apply(erule exE)
5450apply(simp add: fresh_prod)
5451apply(erule conjE)+
5452apply(simp add: fresh_fun_simp_NotR)
5453apply(drule fin_elims, simp)
5454apply(rule exists_fresh'(2)[OF fs_coname1])
5455apply(drule fin_elims, simp)
5456apply(drule fin_elims, simp)
5457apply(auto)[1]
5458apply(drule freshn_after_substc)
5459apply(simp add: fin.intros)
5460apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm1{coname3:=(x).P},P,coname1,trm2{coname3:=(x).P},coname2)")
5461apply(erule exE)
5462apply(simp add: fresh_prod)
5463apply(erule conjE)+
5464apply(simp add: fresh_fun_simp_AndR)
5465apply(drule fin_elims, simp)
5466apply(rule exists_fresh'(2)[OF fs_coname1])
5467apply(drule fin_elims, simp)
5468apply(drule fin_elims, simp)
5469apply(auto)[1]
5470apply(simp add: abs_fresh fresh_atm)
5471apply(drule freshn_after_substc)
5472apply(simp add: fin.intros abs_fresh)
5473apply(drule fin_elims, simp)
5474apply(auto)[1]
5475apply(simp add: abs_fresh fresh_atm)
5476apply(drule freshn_after_substc)
5477apply(simp add: fin.intros abs_fresh)
5478apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm{coname2:=(x).P},P,coname1)")
5479apply(erule exE)
5480apply(simp add: fresh_prod)
5481apply(erule conjE)+
5482apply(simp add: fresh_fun_simp_OrR1)
5483apply(drule fin_elims, simp)
5484apply(rule exists_fresh'(2)[OF fs_coname1])
5485apply(drule fin_elims, simp)
5486apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm{coname2:=(x).P},P,coname1)")
5487apply(erule exE)
5488apply(simp add: fresh_prod)
5489apply(erule conjE)+
5490apply(simp add: fresh_fun_simp_OrR2)
5491apply(drule fin_elims, simp)
5492apply(rule exists_fresh'(2)[OF fs_coname1])
5493apply(drule fin_elims, simp)
5494apply(drule fin_elims, simp)
5495apply(auto)[1]
5496apply(simp add: abs_fresh fresh_atm)
5497apply(drule freshn_after_substc)
5498apply(drule freshn_after_substc)
5499apply(simp add: fin.intros abs_fresh)
5500apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(trm{coname2:=(x).P},P,coname1,coname2)")
5501apply(erule exE)
5502apply(simp add: fresh_prod)
5503apply(erule conjE)+
5504apply(simp add: fresh_fun_simp_ImpR)
5505apply(drule fin_elims, simp)
5506apply(rule exists_fresh'(2)[OF fs_coname1])
5507apply(drule fin_elims, simp)
5508apply(drule fin_elims, simp)
5509apply(auto)[1]
5510apply(simp add: abs_fresh fresh_atm)
5511apply(drule freshn_after_substc)
5512apply(drule freshn_after_substc)
5513apply(simp add: fin.intros abs_fresh)
5514done
5515
5516lemma subst_not_fic1:
5517  shows "\<not>fic (M{a:=(x).P}) a"
5518apply(nominal_induct M avoiding: a x P rule: trm.strong_induct)
5519apply(auto)
5520apply(erule fic.cases, simp_all add: trm.inject)
5521apply(erule fic.cases, simp_all add: trm.inject)
5522apply(erule fic.cases, simp_all add: trm.inject)
5523apply(erule fic.cases, simp_all add: trm.inject)
5524apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm{coname:=(x).P},P)")
5525apply(erule exE)
5526apply(simp add: fresh_prod)
5527apply(erule conjE)+
5528apply(simp add: fresh_fun_simp_NotR)
5529apply(erule fic.cases, simp_all add: trm.inject)
5530apply(rule exists_fresh'(2)[OF fs_coname1])
5531apply(erule fic.cases, simp_all add: trm.inject)
5532apply(erule fic.cases, simp_all add: trm.inject)
5533apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm1{coname3:=(x).P},P,trm2{coname3:=(x).P},coname1,coname2)")
5534apply(erule exE)
5535apply(simp add: fresh_prod)
5536apply(erule conjE)+
5537apply(simp add: fresh_fun_simp_AndR)
5538apply(erule fic.cases, simp_all add: trm.inject)
5539apply(rule exists_fresh'(2)[OF fs_coname1])
5540apply(erule fic.cases, simp_all add: trm.inject)
5541apply(erule fic.cases, simp_all add: trm.inject)
5542apply(erule fic.cases, simp_all add: trm.inject)
5543apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm{coname2:=(x).P},P,coname1)")
5544apply(erule exE)
5545apply(simp add: fresh_prod)
5546apply(erule conjE)+
5547apply(simp add: fresh_fun_simp_OrR1)
5548apply(erule fic.cases, simp_all add: trm.inject)
5549apply(rule exists_fresh'(2)[OF fs_coname1])
5550apply(erule fic.cases, simp_all add: trm.inject)
5551apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm{coname2:=(x).P},P,coname1)")
5552apply(erule exE)
5553apply(simp add: fresh_prod)
5554apply(erule conjE)+
5555apply(simp add: fresh_fun_simp_OrR2)
5556apply(erule fic.cases, simp_all add: trm.inject)
5557apply(rule exists_fresh'(2)[OF fs_coname1])
5558apply(erule fic.cases, simp_all add: trm.inject)
5559apply(erule fic.cases, simp_all add: trm.inject)
5560apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(trm{coname2:=(x).P},P,coname1)")
5561apply(erule exE)
5562apply(simp add: fresh_prod)
5563apply(erule conjE)+
5564apply(simp add: fresh_fun_simp_ImpR)
5565apply(erule fic.cases, simp_all add: trm.inject)
5566apply(rule exists_fresh'(2)[OF fs_coname1])
5567apply(erule fic.cases, simp_all add: trm.inject)
5568apply(erule fic.cases, simp_all add: trm.inject)
5569done
5570
5571lemma subst_not_fic2:
5572  assumes a: "\<not>fic M a"
5573  shows "\<not>fic(M{x:=<b>.P}) a" 
5574using a
5575apply(nominal_induct M avoiding: x a P b rule: trm.strong_induct)
5576apply(auto)
5577apply(drule fic_elims, simp)
5578apply(drule fic_elims, simp)
5579apply(drule fic_elims, simp)
5580apply(drule fic_elims, simp)
5581apply(auto)[1]
5582apply(drule freshc_after_substn)
5583apply(simp add: fic.intros)
5584apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<b>.P},P)")
5585apply(erule exE)
5586apply(simp add: fresh_prod)
5587apply(erule conjE)+
5588apply(simp add: fresh_fun_simp_NotL)
5589apply(drule fic_elims, simp)
5590apply(rule exists_fresh'(1)[OF fs_name1])
5591apply(drule fic_elims, simp)
5592apply(drule fic_elims, simp)
5593apply(auto)[1]
5594apply(simp add: abs_fresh fresh_atm)
5595apply(drule freshc_after_substn)
5596apply(drule freshc_after_substn)
5597apply(simp add: fic.intros abs_fresh)
5598apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<b>.P},P,name1)")
5599apply(erule exE)
5600apply(simp add: fresh_prod)
5601apply(erule conjE)+
5602apply(simp add: fresh_fun_simp_AndL1)
5603apply(drule fic_elims, simp)
5604apply(rule exists_fresh'(1)[OF fs_name1])
5605apply(drule fic_elims, simp)
5606apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<b>.P},P,name1)")
5607apply(erule exE)
5608apply(simp add: fresh_prod)
5609apply(erule conjE)+
5610apply(simp add: fresh_fun_simp_AndL2)
5611apply(drule fic_elims, simp)
5612apply(rule exists_fresh'(1)[OF fs_name1])
5613apply(drule fic_elims, simp)
5614apply(drule fic_elims, simp)
5615apply(auto)[1]
5616apply(simp add: abs_fresh fresh_atm)
5617apply(drule freshc_after_substn)
5618apply(simp add: fic.intros abs_fresh)
5619apply(drule fic_elims, simp)
5620apply(auto)[1]
5621apply(simp add: abs_fresh fresh_atm)
5622apply(drule freshc_after_substn)
5623apply(simp add: fic.intros abs_fresh)
5624apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{x:=<b>.P},P,name1,trm2{x:=<b>.P},name2)")
5625apply(erule exE)
5626apply(simp add: fresh_prod)
5627apply(erule conjE)+
5628apply(simp add: fresh_fun_simp_OrL)
5629apply(drule fic_elims, simp)
5630apply(rule exists_fresh'(1)[OF fs_name1])
5631apply(drule fic_elims, simp)
5632apply(drule fic_elims, simp)
5633apply(auto)[1]
5634apply(simp add: abs_fresh fresh_atm)
5635apply(drule freshc_after_substn)
5636apply(simp add: fic.intros abs_fresh)
5637apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<b>.P},trm2{name2:=<b>.P},P,name1)")
5638apply(erule exE)
5639apply(simp add: fresh_prod)
5640apply(erule conjE)+
5641apply(simp add: fresh_fun_simp_ImpL)
5642apply(drule fic_elims, simp)
5643apply(rule exists_fresh'(1)[OF fs_name1])
5644apply(drule fic_elims, simp)
5645done
5646
5647text \<open>Reductions\<close>
5648
5649lemma fin_l_reduce:
5650  assumes  a: "fin M x"
5651  and      b: "M \<longrightarrow>\<^sub>l M'"
5652  shows "fin M' x"
5653using b a
5654apply(induct)
5655apply(erule fin.cases)
5656apply(simp_all add: trm.inject)
5657apply(rotate_tac 3)
5658apply(erule fin.cases)
5659apply(simp_all add: trm.inject)
5660apply(erule fin.cases, simp_all add: trm.inject)+
5661done
5662
5663lemma fin_c_reduce:
5664  assumes  a: "fin M x"
5665  and      b: "M \<longrightarrow>\<^sub>c M'"
5666  shows "fin M' x"
5667using b a
5668apply(induct)
5669apply(erule fin.cases, simp_all add: trm.inject)+
5670done
5671
5672lemma fin_a_reduce:
5673  assumes  a: "fin M x"
5674  and      b: "M \<longrightarrow>\<^sub>a M'"
5675  shows "fin M' x"
5676using a b
5677apply(induct)
5678apply(drule ax_do_not_a_reduce)
5679apply(simp)
5680apply(drule a_redu_NotL_elim)
5681apply(auto)
5682apply(rule fin.intros)
5683apply(simp add: fresh_a_redu)
5684apply(drule a_redu_AndL1_elim)
5685apply(auto)
5686apply(rule fin.intros)
5687apply(force simp add: abs_fresh fresh_a_redu)
5688apply(drule a_redu_AndL2_elim)
5689apply(auto)
5690apply(rule fin.intros)
5691apply(force simp add: abs_fresh fresh_a_redu)
5692apply(drule a_redu_OrL_elim)
5693apply(auto)
5694apply(rule fin.intros)
5695apply(force simp add: abs_fresh fresh_a_redu)
5696apply(force simp add: abs_fresh fresh_a_redu)
5697apply(rule fin.intros)
5698apply(force simp add: abs_fresh fresh_a_redu)
5699apply(force simp add: abs_fresh fresh_a_redu)
5700apply(drule a_redu_ImpL_elim)
5701apply(auto)
5702apply(rule fin.intros)
5703apply(force simp add: abs_fresh fresh_a_redu)
5704apply(force simp add: abs_fresh fresh_a_redu)
5705apply(rule fin.intros)
5706apply(force simp add: abs_fresh fresh_a_redu)
5707apply(force simp add: abs_fresh fresh_a_redu)
5708done
5709
5710lemma fin_a_star_reduce:
5711  assumes  a: "fin M x"
5712  and      b: "M \<longrightarrow>\<^sub>a* M'"
5713  shows "fin M' x"
5714using b a
5715apply(induct set: rtranclp)
5716apply(auto simp add: fin_a_reduce)
5717done
5718
5719lemma fic_l_reduce:
5720  assumes  a: "fic M x"
5721  and      b: "M \<longrightarrow>\<^sub>l M'"
5722  shows "fic M' x"
5723using b a
5724apply(induct)
5725apply(erule fic.cases)
5726apply(simp_all add: trm.inject)
5727apply(rotate_tac 3)
5728apply(erule fic.cases)
5729apply(simp_all add: trm.inject)
5730apply(erule fic.cases, simp_all add: trm.inject)+
5731done
5732
5733lemma fic_c_reduce:
5734  assumes a: "fic M x"
5735  and     b: "M \<longrightarrow>\<^sub>c M'"
5736  shows "fic M' x"
5737using b a
5738apply(induct)
5739apply(erule fic.cases, simp_all add: trm.inject)+
5740done
5741
5742lemma fic_a_reduce:
5743  assumes a: "fic M x"
5744  and     b: "M \<longrightarrow>\<^sub>a M'"
5745  shows "fic M' x"
5746using a b
5747apply(induct)
5748apply(drule ax_do_not_a_reduce)
5749apply(simp)
5750apply(drule a_redu_NotR_elim)
5751apply(auto)
5752apply(rule fic.intros)
5753apply(simp add: fresh_a_redu)
5754apply(drule a_redu_AndR_elim)
5755apply(auto)
5756apply(rule fic.intros)
5757apply(force simp add: abs_fresh fresh_a_redu)
5758apply(force simp add: abs_fresh fresh_a_redu)
5759apply(rule fic.intros)
5760apply(force simp add: abs_fresh fresh_a_redu)
5761apply(force simp add: abs_fresh fresh_a_redu)
5762apply(drule a_redu_OrR1_elim)
5763apply(auto)
5764apply(rule fic.intros)
5765apply(force simp add: abs_fresh fresh_a_redu)
5766apply(drule a_redu_OrR2_elim)
5767apply(auto)
5768apply(rule fic.intros)
5769apply(force simp add: abs_fresh fresh_a_redu)
5770apply(drule a_redu_ImpR_elim)
5771apply(auto)
5772apply(rule fic.intros)
5773apply(force simp add: abs_fresh fresh_a_redu)
5774done
5775
5776lemma fic_a_star_reduce:
5777  assumes  a: "fic M x"
5778  and      b: "M \<longrightarrow>\<^sub>a* M'"
5779  shows "fic M' x"
5780using b a
5781apply(induct set: rtranclp)
5782apply(auto simp add: fic_a_reduce)
5783done
5784
5785text \<open>substitution properties\<close>
5786
5787lemma subst_with_ax1:
5788  shows "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]"
5789proof(nominal_induct M avoiding: x a y rule: trm.strong_induct)
5790  case (Ax z b x a y)
5791  show "(Ax z b){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (Ax z b)[x\<turnstile>n>y]"
5792  proof (cases "z=x")
5793    case True
5794    assume eq: "z=x"
5795    have "(Ax z b){x:=<a>.Ax y a} = Cut <a>.Ax y a (x).Ax x b" using eq by simp
5796    also have "\<dots> \<longrightarrow>\<^sub>a* (Ax x b)[x\<turnstile>n>y]" by blast
5797    finally show "Ax z b{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (Ax z b)[x\<turnstile>n>y]" using eq by simp
5798  next
5799    case False
5800    assume neq: "z\<noteq>x"
5801    then show "(Ax z b){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (Ax z b)[x\<turnstile>n>y]" using neq by simp
5802  qed
5803next
5804  case (Cut b M z N x a y)
5805  have fs: "b\<sharp>x" "b\<sharp>a" "b\<sharp>y" "b\<sharp>N" "z\<sharp>x" "z\<sharp>a" "z\<sharp>y" "z\<sharp>M" by fact+
5806  have ih1: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5807  have ih2: "N{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* N[x\<turnstile>n>y]" by fact
5808  show "(Cut <b>.M (z).N){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (Cut <b>.M (z).N)[x\<turnstile>n>y]"
5809  proof (cases "M = Ax x b")
5810    case True
5811    assume eq: "M = Ax x b"
5812    have "(Cut <b>.M (z).N){x:=<a>.Ax y a} = Cut <a>.Ax y a (z).(N{x:=<a>.Ax y a})" using fs eq by simp
5813    also have "\<dots> \<longrightarrow>\<^sub>a* Cut <a>.Ax y a (z).(N[x\<turnstile>n>y])" using ih2 a_star_congs by blast
5814    also have "\<dots> = Cut <b>.(M[x\<turnstile>n>y]) (z).(N[x\<turnstile>n>y])" using eq
5815      by (simp add: trm.inject alpha calc_atm fresh_atm)
5816    finally show "(Cut <b>.M (z).N){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (Cut <b>.M (z).N)[x\<turnstile>n>y]" using fs by simp
5817  next
5818    case False
5819    assume neq: "M \<noteq> Ax x b"
5820    have "(Cut <b>.M (z).N){x:=<a>.Ax y a} = Cut <b>.(M{x:=<a>.Ax y a}) (z).(N{x:=<a>.Ax y a})" 
5821      using fs neq by simp
5822    also have "\<dots> \<longrightarrow>\<^sub>a* Cut <b>.(M[x\<turnstile>n>y]) (z).(N[x\<turnstile>n>y])" using ih1 ih2 a_star_congs by blast
5823    finally show "(Cut <b>.M (z).N){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (Cut <b>.M (z).N)[x\<turnstile>n>y]" using fs by simp
5824  qed
5825next
5826  case (NotR z M b x a y)
5827  have fs: "z\<sharp>x" "z\<sharp>a" "z\<sharp>y" "z\<sharp>b" by fact+
5828  have ih: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5829  have "(NotR (z).M b){x:=<a>.Ax y a} = NotR (z).(M{x:=<a>.Ax y a}) b" using fs by simp
5830  also have "\<dots> \<longrightarrow>\<^sub>a* NotR (z).(M[x\<turnstile>n>y]) b" using ih by (auto intro: a_star_congs)
5831  finally show "(NotR (z).M b){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (NotR (z).M b)[x\<turnstile>n>y]" using fs by simp
5832next
5833  case (NotL b M z x a y)  
5834  have fs: "b\<sharp>x" "b\<sharp>a" "b\<sharp>y" "b\<sharp>z" by fact+
5835  have ih: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5836  show "(NotL <b>.M z){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (NotL <b>.M z)[x\<turnstile>n>y]"
5837  proof(cases "z=x")
5838    case True
5839    assume eq: "z=x"
5840    obtain x'::"name" where new: "x'\<sharp>(Ax y a,M{x:=<a>.Ax y a})" by (rule exists_fresh(1)[OF fs_name1])
5841    have "(NotL <b>.M z){x:=<a>.Ax y a} = 
5842                        fresh_fun (\<lambda>x'. Cut <a>.Ax y a (x').NotL <b>.(M{x:=<a>.Ax y a}) x')"
5843      using eq fs by simp
5844    also have "\<dots> = Cut <a>.Ax y a (x').NotL <b>.(M{x:=<a>.Ax y a}) x'" 
5845      using new by (simp add: fresh_fun_simp_NotL fresh_prod)
5846    also have "\<dots> \<longrightarrow>\<^sub>a* (NotL <b>.(M{x:=<a>.Ax y a}) x')[x'\<turnstile>n>y]"
5847      using new 
5848      apply(rule_tac a_starI)
5849      apply(rule al_redu)
5850      apply(rule better_LAxL_intro)
5851      apply(auto)
5852      done
5853    also have "\<dots> = NotL <b>.(M{x:=<a>.Ax y a}) y" using new by (simp add: nrename_fresh)
5854    also have "\<dots> \<longrightarrow>\<^sub>a* NotL <b>.(M[x\<turnstile>n>y]) y" using ih by (auto intro: a_star_congs)
5855    also have "\<dots> = (NotL <b>.M z)[x\<turnstile>n>y]" using eq by simp
5856    finally show "(NotL <b>.M z){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (NotL <b>.M z)[x\<turnstile>n>y]" by simp
5857  next
5858    case False
5859    assume neq: "z\<noteq>x"
5860    have "(NotL <b>.M z){x:=<a>.Ax y a} = NotL <b>.(M{x:=<a>.Ax y a}) z" using fs neq by simp
5861    also have "\<dots> \<longrightarrow>\<^sub>a* NotL <b>.(M[x\<turnstile>n>y]) z" using ih by (auto intro: a_star_congs)
5862    finally show "(NotL <b>.M z){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (NotL <b>.M z)[x\<turnstile>n>y]" using neq by simp
5863  qed
5864next
5865  case (AndR c M d N e x a y)
5866  have fs: "c\<sharp>x" "c\<sharp>a" "c\<sharp>y" "d\<sharp>x" "d\<sharp>a" "d\<sharp>y" "d\<noteq>c" "c\<sharp>N" "c\<sharp>e" "d\<sharp>M" "d\<sharp>e" by fact+
5867  have ih1: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5868  have ih2: "N{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* N[x\<turnstile>n>y]" by fact
5869  have "(AndR <c>.M <d>.N e){x:=<a>.Ax y a} = AndR <c>.(M{x:=<a>.Ax y a}) <d>.(N{x:=<a>.Ax y a}) e"
5870    using fs by simp
5871  also have "\<dots> \<longrightarrow>\<^sub>a* AndR <c>.(M[x\<turnstile>n>y]) <d>.(N[x\<turnstile>n>y]) e" using ih1 ih2 by (auto intro: a_star_congs)
5872  finally show "(AndR <c>.M <d>.N e){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (AndR <c>.M <d>.N e)[x\<turnstile>n>y]"
5873    using fs by simp
5874next
5875  case (AndL1 u M v x a y)
5876  have fs: "u\<sharp>x" "u\<sharp>a" "u\<sharp>y" "u\<sharp>v" by fact+
5877  have ih: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5878  show "(AndL1 (u).M v){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (AndL1 (u).M v)[x\<turnstile>n>y]"
5879  proof(cases "v=x")
5880    case True
5881    assume eq: "v=x"
5882    obtain v'::"name" where new: "v'\<sharp>(Ax y a,M{x:=<a>.Ax y a},u)" by (rule exists_fresh(1)[OF fs_name1])
5883    have "(AndL1 (u).M v){x:=<a>.Ax y a} = 
5884                        fresh_fun (\<lambda>v'. Cut <a>.Ax y a (v').AndL1 (u).(M{x:=<a>.Ax y a}) v')"
5885      using eq fs by simp
5886    also have "\<dots> = Cut <a>.Ax y a (v').AndL1 (u).(M{x:=<a>.Ax y a}) v'" 
5887      using new by (simp add: fresh_fun_simp_AndL1 fresh_prod)
5888    also have "\<dots> \<longrightarrow>\<^sub>a* (AndL1 (u).(M{x:=<a>.Ax y a}) v')[v'\<turnstile>n>y]"
5889      using new 
5890      apply(rule_tac a_starI)
5891      apply(rule a_redu.intros)
5892      apply(rule better_LAxL_intro)
5893      apply(rule fin.intros)
5894      apply(simp add: abs_fresh)
5895      done
5896    also have "\<dots> = AndL1 (u).(M{x:=<a>.Ax y a}) y" using fs new
5897      by (auto simp add: fresh_prod fresh_atm nrename_fresh)
5898    also have "\<dots> \<longrightarrow>\<^sub>a* AndL1 (u).(M[x\<turnstile>n>y]) y" using ih by (auto intro: a_star_congs)
5899    also have "\<dots> = (AndL1 (u).M v)[x\<turnstile>n>y]" using eq fs by simp
5900    finally show "(AndL1 (u).M v){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (AndL1 (u).M v)[x\<turnstile>n>y]" by simp
5901  next
5902    case False
5903    assume neq: "v\<noteq>x"
5904    have "(AndL1 (u).M v){x:=<a>.Ax y a} = AndL1 (u).(M{x:=<a>.Ax y a}) v" using fs neq by simp
5905    also have "\<dots> \<longrightarrow>\<^sub>a* AndL1 (u).(M[x\<turnstile>n>y]) v" using ih by (auto intro: a_star_congs)
5906    finally show "(AndL1 (u).M v){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (AndL1 (u).M v)[x\<turnstile>n>y]" using fs neq by simp
5907  qed
5908next
5909  case (AndL2 u M v x a y)
5910  have fs: "u\<sharp>x" "u\<sharp>a" "u\<sharp>y" "u\<sharp>v" by fact+
5911  have ih: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5912  show "(AndL2 (u).M v){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (AndL2 (u).M v)[x\<turnstile>n>y]"
5913  proof(cases "v=x")
5914    case True
5915    assume eq: "v=x"
5916    obtain v'::"name" where new: "v'\<sharp>(Ax y a,M{x:=<a>.Ax y a},u)" by (rule exists_fresh(1)[OF fs_name1])
5917    have "(AndL2 (u).M v){x:=<a>.Ax y a} = 
5918                        fresh_fun (\<lambda>v'. Cut <a>.Ax y a (v').AndL2 (u).(M{x:=<a>.Ax y a}) v')"
5919      using eq fs by simp
5920    also have "\<dots> = Cut <a>.Ax y a (v').AndL2 (u).(M{x:=<a>.Ax y a}) v'" 
5921      using new by (simp add: fresh_fun_simp_AndL2 fresh_prod)
5922    also have "\<dots> \<longrightarrow>\<^sub>a* (AndL2 (u).(M{x:=<a>.Ax y a}) v')[v'\<turnstile>n>y]"
5923      using new 
5924      apply(rule_tac a_starI)
5925      apply(rule a_redu.intros)
5926      apply(rule better_LAxL_intro)
5927      apply(rule fin.intros)
5928      apply(simp add: abs_fresh)
5929      done
5930    also have "\<dots> = AndL2 (u).(M{x:=<a>.Ax y a}) y" using fs new
5931      by (auto simp add: fresh_prod fresh_atm nrename_fresh)
5932    also have "\<dots> \<longrightarrow>\<^sub>a* AndL2 (u).(M[x\<turnstile>n>y]) y" using ih by (auto intro: a_star_congs)
5933    also have "\<dots> = (AndL2 (u).M v)[x\<turnstile>n>y]" using eq fs by simp
5934    finally show "(AndL2 (u).M v){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (AndL2 (u).M v)[x\<turnstile>n>y]" by simp
5935  next
5936    case False
5937    assume neq: "v\<noteq>x"
5938    have "(AndL2 (u).M v){x:=<a>.Ax y a} = AndL2 (u).(M{x:=<a>.Ax y a}) v" using fs neq by simp
5939    also have "\<dots> \<longrightarrow>\<^sub>a* AndL2 (u).(M[x\<turnstile>n>y]) v" using ih by (auto intro: a_star_congs)
5940    finally show "(AndL2 (u).M v){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (AndL2 (u).M v)[x\<turnstile>n>y]" using fs neq by simp
5941  qed
5942next
5943  case (OrR1 c M d  x a y)
5944  have fs: "c\<sharp>x" "c\<sharp>a" "c\<sharp>y" "c\<sharp>d" by fact+
5945  have ih: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5946  have "(OrR1 <c>.M d){x:=<a>.Ax y a} = OrR1 <c>.(M{x:=<a>.Ax y a}) d" using fs by (simp add: fresh_atm)
5947  also have "\<dots> \<longrightarrow>\<^sub>a* OrR1 <c>.(M[x\<turnstile>n>y]) d" using ih by (auto intro: a_star_congs)
5948  finally show "(OrR1 <c>.M d){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (OrR1 <c>.M d)[x\<turnstile>n>y]" using fs by simp
5949next
5950  case (OrR2 c M d  x a y)
5951  have fs: "c\<sharp>x" "c\<sharp>a" "c\<sharp>y" "c\<sharp>d" by fact+
5952  have ih: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5953  have "(OrR2 <c>.M d){x:=<a>.Ax y a} = OrR2 <c>.(M{x:=<a>.Ax y a}) d" using fs by (simp add: fresh_atm)
5954  also have "\<dots> \<longrightarrow>\<^sub>a* OrR2 <c>.(M[x\<turnstile>n>y]) d" using ih by (auto intro: a_star_congs)
5955  finally show "(OrR2 <c>.M d){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (OrR2 <c>.M d)[x\<turnstile>n>y]" using fs by simp
5956next
5957  case (OrL u M v N z x a y)
5958  have fs: "u\<sharp>x" "u\<sharp>a" "u\<sharp>y" "v\<sharp>x" "v\<sharp>a" "v\<sharp>y" "v\<noteq>u" "u\<sharp>N" "u\<sharp>z" "v\<sharp>M" "v\<sharp>z" by fact+
5959  have ih1: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5960  have ih2: "N{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* N[x\<turnstile>n>y]" by fact
5961  show "(OrL (u).M (v).N z){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (OrL (u).M (v).N z)[x\<turnstile>n>y]"
5962  proof(cases "z=x")
5963    case True
5964    assume eq: "z=x"
5965    obtain z'::"name" where new: "z'\<sharp>(Ax y a,M{x:=<a>.Ax y a},N{x:=<a>.Ax y a},u,v,y,a)" 
5966      by (rule exists_fresh(1)[OF fs_name1])
5967    have "(OrL (u).M (v).N z){x:=<a>.Ax y a} = 
5968                 fresh_fun (\<lambda>z'. Cut <a>.Ax y a (z').OrL (u).(M{x:=<a>.Ax y a}) (v).(N{x:=<a>.Ax y a}) z')"
5969      using eq fs by simp
5970    also have "\<dots> = Cut <a>.Ax y a (z').OrL (u).(M{x:=<a>.Ax y a}) (v).(N{x:=<a>.Ax y a}) z'" 
5971      using new by (simp add: fresh_fun_simp_OrL)
5972    also have "\<dots> \<longrightarrow>\<^sub>a* (OrL (u).(M{x:=<a>.Ax y a}) (v).(N{x:=<a>.Ax y a}) z')[z'\<turnstile>n>y]"
5973      using new 
5974      apply(rule_tac a_starI)
5975      apply(rule a_redu.intros)
5976      apply(rule better_LAxL_intro)
5977      apply(rule fin.intros)
5978      apply(simp_all add: abs_fresh)
5979      done
5980    also have "\<dots> = OrL (u).(M{x:=<a>.Ax y a}) (v).(N{x:=<a>.Ax y a}) y" using fs new
5981      by (auto simp add: fresh_prod fresh_atm nrename_fresh subst_fresh)
5982    also have "\<dots> \<longrightarrow>\<^sub>a* OrL (u).(M[x\<turnstile>n>y]) (v).(N[x\<turnstile>n>y]) y" 
5983      using ih1 ih2 by (auto intro: a_star_congs)
5984    also have "\<dots> = (OrL (u).M (v).N z)[x\<turnstile>n>y]" using eq fs by simp
5985    finally show "(OrL (u).M (v).N z){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (OrL (u).M (v).N z)[x\<turnstile>n>y]" by simp
5986  next
5987    case False
5988    assume neq: "z\<noteq>x"
5989    have "(OrL (u).M (v).N z){x:=<a>.Ax y a} = OrL (u).(M{x:=<a>.Ax y a}) (v).(N{x:=<a>.Ax y a}) z" 
5990      using fs neq by simp
5991    also have "\<dots> \<longrightarrow>\<^sub>a* OrL (u).(M[x\<turnstile>n>y]) (v).(N[x\<turnstile>n>y]) z" 
5992      using ih1 ih2 by (auto intro: a_star_congs)
5993    finally show "(OrL (u).M (v).N z){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (OrL (u).M (v).N z)[x\<turnstile>n>y]" using fs neq by simp
5994  qed
5995next
5996  case (ImpR z c M d x a y)
5997  have fs: "z\<sharp>x" "z\<sharp>a" "z\<sharp>y" "c\<sharp>x" "c\<sharp>a" "c\<sharp>y" "z\<sharp>d" "c\<sharp>d" by fact+
5998  have ih: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
5999  have "(ImpR (z).<c>.M d){x:=<a>.Ax y a} = ImpR (z).<c>.(M{x:=<a>.Ax y a}) d" using fs by simp
6000  also have "\<dots> \<longrightarrow>\<^sub>a* ImpR (z).<c>.(M[x\<turnstile>n>y]) d" using ih by (auto intro: a_star_congs)
6001  finally show "(ImpR (z).<c>.M d){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (ImpR (z).<c>.M d)[x\<turnstile>n>y]" using fs by simp
6002next
6003  case (ImpL c M u N v x a y)
6004  have fs: "c\<sharp>x" "c\<sharp>a" "c\<sharp>y" "u\<sharp>x" "u\<sharp>a" "u\<sharp>y" "c\<sharp>N" "c\<sharp>v" "u\<sharp>M" "u\<sharp>v" by fact+
6005  have ih1: "M{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* M[x\<turnstile>n>y]" by fact
6006  have ih2: "N{x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* N[x\<turnstile>n>y]" by fact
6007  show "(ImpL <c>.M (u).N v){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (ImpL <c>.M (u).N v)[x\<turnstile>n>y]"
6008  proof(cases "v=x")
6009    case True
6010    assume eq: "v=x"
6011    obtain v'::"name" where new: "v'\<sharp>(Ax y a,M{x:=<a>.Ax y a},N{x:=<a>.Ax y a},y,a,u)" 
6012      by (rule exists_fresh(1)[OF fs_name1])
6013    have "(ImpL <c>.M (u).N v){x:=<a>.Ax y a} = 
6014                 fresh_fun (\<lambda>v'. Cut <a>.Ax y a (v').ImpL <c>.(M{x:=<a>.Ax y a}) (u).(N{x:=<a>.Ax y a}) v')"
6015      using eq fs by simp 
6016    also have "\<dots> = Cut <a>.Ax y a (v').ImpL <c>.(M{x:=<a>.Ax y a}) (u).(N{x:=<a>.Ax y a}) v'" 
6017      using new by (simp add: fresh_fun_simp_ImpL)
6018    also have "\<dots> \<longrightarrow>\<^sub>a* (ImpL <c>.(M{x:=<a>.Ax y a}) (u).(N{x:=<a>.Ax y a}) v')[v'\<turnstile>n>y]"
6019      using new 
6020      apply(rule_tac a_starI)
6021      apply(rule a_redu.intros)
6022      apply(rule better_LAxL_intro)
6023      apply(rule fin.intros)
6024      apply(simp_all add: abs_fresh)
6025      done
6026    also have "\<dots> = ImpL <c>.(M{x:=<a>.Ax y a}) (u).(N{x:=<a>.Ax y a}) y" using fs new
6027      by (auto simp add: fresh_prod subst_fresh fresh_atm trm.inject alpha rename_fresh)
6028    also have "\<dots> \<longrightarrow>\<^sub>a* ImpL <c>.(M[x\<turnstile>n>y]) (u).(N[x\<turnstile>n>y]) y" 
6029      using ih1 ih2 by (auto intro: a_star_congs)
6030    also have "\<dots> = (ImpL <c>.M (u).N v)[x\<turnstile>n>y]" using eq fs by simp
6031    finally show "(ImpL <c>.M (u).N v){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (ImpL <c>.M (u).N v)[x\<turnstile>n>y]" using fs by simp
6032  next
6033    case False
6034    assume neq: "v\<noteq>x"
6035    have "(ImpL <c>.M (u).N v){x:=<a>.Ax y a} = ImpL <c>.(M{x:=<a>.Ax y a}) (u).(N{x:=<a>.Ax y a}) v" 
6036      using fs neq by simp
6037    also have "\<dots> \<longrightarrow>\<^sub>a* ImpL <c>.(M[x\<turnstile>n>y]) (u).(N[x\<turnstile>n>y]) v" 
6038      using ih1 ih2 by (auto intro: a_star_congs)
6039    finally show "(ImpL <c>.M (u).N v){x:=<a>.Ax y a} \<longrightarrow>\<^sub>a* (ImpL <c>.M (u).N v)[x\<turnstile>n>y]" 
6040      using fs neq by simp
6041  qed
6042qed
6043
6044lemma subst_with_ax2:
6045  shows "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]"
6046proof(nominal_induct M avoiding: b a x rule: trm.strong_induct)
6047  case (Ax z c b a x)
6048  show "(Ax z c){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (Ax z c)[b\<turnstile>c>a]"
6049  proof (cases "c=b")
6050    case True
6051    assume eq: "c=b"
6052    have "(Ax z c){b:=(x).Ax x a} = Cut <b>.Ax z c (x).Ax x a" using eq by simp
6053    also have "\<dots> \<longrightarrow>\<^sub>a* (Ax z c)[b\<turnstile>c>a]" using eq by blast
6054    finally show "(Ax z c){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (Ax z c)[b\<turnstile>c>a]" by simp
6055  next
6056    case False
6057    assume neq: "c\<noteq>b"
6058    then show "(Ax z c){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (Ax z c)[b\<turnstile>c>a]" by simp
6059  qed
6060next
6061  case (Cut c M z N b a x)
6062  have fs: "c\<sharp>b" "c\<sharp>a" "c\<sharp>x" "c\<sharp>N" "z\<sharp>b" "z\<sharp>a" "z\<sharp>x" "z\<sharp>M" by fact+
6063  have ih1: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6064  have ih2: "N{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* N[b\<turnstile>c>a]" by fact
6065  show "(Cut <c>.M (z).N){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (Cut <c>.M (z).N)[b\<turnstile>c>a]"
6066  proof (cases "N = Ax z b")
6067    case True
6068    assume eq: "N = Ax z b"
6069    have "(Cut <c>.M (z).N){b:=(x).Ax x a} = Cut <c>.(M{b:=(x).Ax x a}) (x).Ax x a" using eq fs by simp 
6070    also have "\<dots> \<longrightarrow>\<^sub>a* Cut <c>.(M[b\<turnstile>c>a]) (x).Ax x a" using ih1 a_star_congs by blast
6071    also have "\<dots> = Cut <c>.(M[b\<turnstile>c>a]) (z).(N[b\<turnstile>c>a])" using eq fs
6072      by (simp add: trm.inject alpha calc_atm fresh_atm)
6073    finally show "(Cut <c>.M (z).N){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (Cut <c>.M (z).N)[b\<turnstile>c>a]" using fs by simp
6074  next
6075    case False
6076    assume neq: "N \<noteq> Ax z b"
6077    have "(Cut <c>.M (z).N){b:=(x).Ax x a} = Cut <c>.(M{b:=(x).Ax x a}) (z).(N{b:=(x).Ax x a})" 
6078      using fs neq by simp
6079    also have "\<dots> \<longrightarrow>\<^sub>a* Cut <c>.(M[b\<turnstile>c>a]) (z).(N[b\<turnstile>c>a])" using ih1 ih2 a_star_congs by blast
6080    finally show "(Cut <c>.M (z).N){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (Cut <c>.M (z).N)[b\<turnstile>c>a]" using fs by simp
6081  qed
6082next
6083  case (NotR z M c b a x)
6084  have fs: "z\<sharp>b" "z\<sharp>a" "z\<sharp>x" "z\<sharp>c" by fact+
6085  have ih: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6086  show "(NotR (z).M c){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (NotR (z).M c)[b\<turnstile>c>a]"
6087  proof (cases "c=b")
6088    case True
6089    assume eq: "c=b"
6090    obtain a'::"coname" where new: "a'\<sharp>(Ax x a,M{b:=(x).Ax x a})" by (rule exists_fresh(2)[OF fs_coname1])
6091    have "(NotR (z).M c){b:=(x).Ax x a} = 
6092                        fresh_fun (\<lambda>a'. Cut <a'>.NotR (z).M{b:=(x).Ax x a} a' (x).Ax x a)" 
6093      using eq fs by simp
6094    also have "\<dots> = Cut <a'>.NotR (z).M{b:=(x).Ax x a} a' (x).Ax x a"
6095      using new by (simp add: fresh_fun_simp_NotR fresh_prod)
6096    also have "\<dots> \<longrightarrow>\<^sub>a* (NotR (z).(M{b:=(x).Ax x a}) a')[a'\<turnstile>c>a]"
6097      using new 
6098      apply(rule_tac a_starI)
6099      apply(rule a_redu.intros)
6100      apply(rule better_LAxR_intro)
6101      apply(rule fic.intros)
6102      apply(simp)
6103      done
6104    also have "\<dots> = NotR (z).(M{b:=(x).Ax x a}) a" using new by (simp add: crename_fresh)
6105    also have "\<dots> \<longrightarrow>\<^sub>a* NotR (z).(M[b\<turnstile>c>a]) a" using ih by (auto intro: a_star_congs)
6106    also have "\<dots> = (NotR (z).M c)[b\<turnstile>c>a]" using eq by simp
6107    finally show "(NotR (z).M c){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (NotR (z).M c)[b\<turnstile>c>a]" by simp
6108  next
6109    case False
6110    assume neq: "c\<noteq>b"
6111    have "(NotR (z).M c){b:=(x).Ax x a} = NotR (z).(M{b:=(x).Ax x a}) c" using fs neq by simp
6112    also have "\<dots> \<longrightarrow>\<^sub>a* NotR (z).(M[b\<turnstile>c>a]) c" using ih by (auto intro: a_star_congs)
6113    finally show "(NotR (z).M c){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (NotR (z).M c)[b\<turnstile>c>a]" using neq by simp
6114  qed
6115next
6116  case (NotL c M z b a x)  
6117  have fs: "c\<sharp>b" "c\<sharp>a" "c\<sharp>x" "c\<sharp>z" by fact+
6118  have ih: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6119  have "(NotL <c>.M z){b:=(x).Ax x a} = NotL <c>.(M{b:=(x).Ax x a}) z" using fs by simp
6120  also have "\<dots> \<longrightarrow>\<^sub>a* NotL <c>.(M[b\<turnstile>c>a]) z" using ih by (auto intro: a_star_congs)
6121  finally show "(NotL <c>.M z){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (NotL <c>.M z)[b\<turnstile>c>a]" using fs by simp
6122next
6123  case (AndR c M d N e b a x)
6124  have fs: "c\<sharp>b" "c\<sharp>a" "c\<sharp>x" "d\<sharp>b" "d\<sharp>a" "d\<sharp>x" "d\<noteq>c" "c\<sharp>N" "c\<sharp>e" "d\<sharp>M" "d\<sharp>e" by fact+
6125  have ih1: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6126  have ih2: "N{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* N[b\<turnstile>c>a]" by fact
6127  show "(AndR <c>.M <d>.N e){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (AndR <c>.M <d>.N e)[b\<turnstile>c>a]"
6128  proof(cases "e=b")
6129    case True
6130    assume eq: "e=b"
6131    obtain e'::"coname" where new: "e'\<sharp>(Ax x a,M{b:=(x).Ax x a},N{b:=(x).Ax x a},c,d)" 
6132      by (rule exists_fresh(2)[OF fs_coname1])
6133    have "(AndR <c>.M <d>.N e){b:=(x).Ax x a} = 
6134               fresh_fun (\<lambda>e'. Cut <e'>.AndR <c>.(M{b:=(x).Ax x a}) <d>.(N{b:=(x).Ax x a}) e' (x).Ax x a)"
6135      using eq fs by simp
6136    also have "\<dots> = Cut <e'>.AndR <c>.(M{b:=(x).Ax x a}) <d>.(N{b:=(x).Ax x a}) e' (x).Ax x a"
6137      using new by (simp add: fresh_fun_simp_AndR fresh_prod)
6138    also have "\<dots> \<longrightarrow>\<^sub>a* (AndR <c>.(M{b:=(x).Ax x a}) <d>.(N{b:=(x).Ax x a}) e')[e'\<turnstile>c>a]"
6139      using new 
6140      apply(rule_tac a_starI)
6141      apply(rule a_redu.intros)
6142      apply(rule better_LAxR_intro)
6143      apply(rule fic.intros)
6144      apply(simp_all add: abs_fresh)
6145      done
6146    also have "\<dots> = AndR <c>.(M{b:=(x).Ax x a}) <d>.(N{b:=(x).Ax x a}) a" using fs new
6147      by (auto simp add: fresh_prod fresh_atm subst_fresh crename_fresh)
6148    also have "\<dots> \<longrightarrow>\<^sub>a* AndR <c>.(M[b\<turnstile>c>a]) <d>.(N[b\<turnstile>c>a]) a" using ih1 ih2 by (auto intro: a_star_congs)
6149    also have "\<dots> = (AndR <c>.M <d>.N e)[b\<turnstile>c>a]" using eq fs by simp
6150    finally show "(AndR <c>.M <d>.N e){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (AndR <c>.M <d>.N e)[b\<turnstile>c>a]" by simp
6151  next
6152    case False
6153    assume neq: "e\<noteq>b"
6154    have "(AndR <c>.M <d>.N e){b:=(x).Ax x a} = AndR <c>.(M{b:=(x).Ax x a}) <d>.(N{b:=(x).Ax x a}) e"
6155      using fs neq by simp
6156    also have "\<dots> \<longrightarrow>\<^sub>a* AndR <c>.(M[b\<turnstile>c>a]) <d>.(N[b\<turnstile>c>a]) e" using ih1 ih2 by (auto intro: a_star_congs)
6157    finally show "(AndR <c>.M <d>.N e){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (AndR <c>.M <d>.N e)[b\<turnstile>c>a]"
6158      using fs neq by simp
6159  qed
6160next
6161  case (AndL1 u M v b a x)
6162  have fs: "u\<sharp>b" "u\<sharp>a" "u\<sharp>x" "u\<sharp>v" by fact+
6163  have ih: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6164  have "(AndL1 (u).M v){b:=(x).Ax x a} = AndL1 (u).(M{b:=(x).Ax x a}) v" using fs by simp
6165  also have "\<dots> \<longrightarrow>\<^sub>a* AndL1 (u).(M[b\<turnstile>c>a]) v" using ih by (auto intro: a_star_congs)
6166  finally show "(AndL1 (u).M v){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (AndL1 (u).M v)[b\<turnstile>c>a]" using fs by simp
6167next
6168  case (AndL2 u M v b a x)
6169  have fs: "u\<sharp>b" "u\<sharp>a" "u\<sharp>x" "u\<sharp>v" by fact+
6170  have ih: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6171  have "(AndL2 (u).M v){b:=(x).Ax x a} = AndL2 (u).(M{b:=(x).Ax x a}) v" using fs by simp
6172  also have "\<dots> \<longrightarrow>\<^sub>a* AndL2 (u).(M[b\<turnstile>c>a]) v" using ih by (auto intro: a_star_congs)
6173  finally show "(AndL2 (u).M v){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (AndL2 (u).M v)[b\<turnstile>c>a]" using fs by simp
6174next
6175  case (OrR1 c M d  b a x)
6176  have fs: "c\<sharp>b" "c\<sharp>a" "c\<sharp>x" "c\<sharp>d" by fact+
6177  have ih: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6178  show "(OrR1 <c>.M d){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (OrR1 <c>.M d)[b\<turnstile>c>a]"
6179  proof(cases "d=b")
6180    case True
6181    assume eq: "d=b"
6182    obtain a'::"coname" where new: "a'\<sharp>(Ax x a,M{b:=(x).Ax x a},c,x,a)" 
6183      by (rule exists_fresh(2)[OF fs_coname1])
6184    have "(OrR1 <c>.M d){b:=(x).Ax x a} = 
6185             fresh_fun (\<lambda>a'. Cut <a'>.OrR1 <c>.M{b:=(x).Ax x a} a' (x).Ax x a)" using fs eq by (simp)
6186    also have "\<dots> = Cut <a'>.OrR1 <c>.M{b:=(x).Ax x a} a' (x).Ax x a"
6187      using new by (simp add: fresh_fun_simp_OrR1)
6188    also have "\<dots> \<longrightarrow>\<^sub>a* (OrR1 <c>.M{b:=(x).Ax x a} a')[a'\<turnstile>c>a]"
6189      using new 
6190      apply(rule_tac a_starI)
6191      apply(rule a_redu.intros)
6192      apply(rule better_LAxR_intro)
6193      apply(rule fic.intros)
6194      apply(simp_all add: abs_fresh)
6195      done
6196    also have "\<dots> = OrR1 <c>.M{b:=(x).Ax x a} a" using fs new
6197      by (auto simp add: fresh_prod fresh_atm crename_fresh subst_fresh)
6198    also have "\<dots> \<longrightarrow>\<^sub>a* OrR1 <c>.(M[b\<turnstile>c>a]) a" using ih by (auto intro: a_star_congs)
6199    also have "\<dots> = (OrR1 <c>.M d)[b\<turnstile>c>a]" using eq fs by simp
6200    finally show "(OrR1 <c>.M d){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (OrR1 <c>.M d)[b\<turnstile>c>a]" by simp
6201  next
6202    case False
6203    assume neq: "d\<noteq>b"
6204    have "(OrR1 <c>.M d){b:=(x).Ax x a} = OrR1 <c>.(M{b:=(x).Ax x a}) d" using fs neq by (simp)
6205    also have "\<dots> \<longrightarrow>\<^sub>a* OrR1 <c>.(M[b\<turnstile>c>a]) d" using ih by (auto intro: a_star_congs)
6206    finally show "(OrR1 <c>.M d){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (OrR1 <c>.M d)[b\<turnstile>c>a]" using fs neq by simp
6207  qed
6208next
6209  case (OrR2 c M d  b a x)
6210  have fs: "c\<sharp>b" "c\<sharp>a" "c\<sharp>x" "c\<sharp>d" by fact+
6211  have ih: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6212  show "(OrR2 <c>.M d){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (OrR2 <c>.M d)[b\<turnstile>c>a]"
6213  proof(cases "d=b")
6214    case True
6215    assume eq: "d=b"
6216    obtain a'::"coname" where new: "a'\<sharp>(Ax x a,M{b:=(x).Ax x a},c,x,a)" 
6217      by (rule exists_fresh(2)[OF fs_coname1])
6218    have "(OrR2 <c>.M d){b:=(x).Ax x a} = 
6219             fresh_fun (\<lambda>a'. Cut <a'>.OrR2 <c>.M{b:=(x).Ax x a} a' (x).Ax x a)" using fs eq by (simp)
6220    also have "\<dots> = Cut <a'>.OrR2 <c>.M{b:=(x).Ax x a} a' (x).Ax x a"
6221      using new by (simp add: fresh_fun_simp_OrR2)
6222    also have "\<dots> \<longrightarrow>\<^sub>a* (OrR2 <c>.M{b:=(x).Ax x a} a')[a'\<turnstile>c>a]"
6223      using new 
6224      apply(rule_tac a_starI)
6225      apply(rule a_redu.intros)
6226      apply(rule better_LAxR_intro)
6227      apply(rule fic.intros)
6228      apply(simp_all add: abs_fresh)
6229      done
6230    also have "\<dots> = OrR2 <c>.M{b:=(x).Ax x a} a" using fs new
6231      by (auto simp add: fresh_prod fresh_atm crename_fresh subst_fresh)
6232    also have "\<dots> \<longrightarrow>\<^sub>a* OrR2 <c>.(M[b\<turnstile>c>a]) a" using ih by (auto intro: a_star_congs)
6233    also have "\<dots> = (OrR2 <c>.M d)[b\<turnstile>c>a]" using eq fs by simp
6234    finally show "(OrR2 <c>.M d){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (OrR2 <c>.M d)[b\<turnstile>c>a]" by simp
6235  next
6236    case False
6237    assume neq: "d\<noteq>b"
6238    have "(OrR2 <c>.M d){b:=(x).Ax x a} = OrR2 <c>.(M{b:=(x).Ax x a}) d" using fs neq by (simp)
6239    also have "\<dots> \<longrightarrow>\<^sub>a* OrR2 <c>.(M[b\<turnstile>c>a]) d" using ih by (auto intro: a_star_congs)
6240    finally show "(OrR2 <c>.M d){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (OrR2 <c>.M d)[b\<turnstile>c>a]" using fs neq by simp
6241  qed
6242next
6243  case (OrL u M v N z b a x)
6244  have fs: "u\<sharp>b" "u\<sharp>a" "u\<sharp>x" "v\<sharp>b" "v\<sharp>a" "v\<sharp>x" "v\<noteq>u" "u\<sharp>N" "u\<sharp>z" "v\<sharp>M" "v\<sharp>z" by fact+
6245  have ih1: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6246  have ih2: "N{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* N[b\<turnstile>c>a]" by fact
6247  have "(OrL (u).M (v).N z){b:=(x).Ax x a} = OrL (u).(M{b:=(x).Ax x a}) (v).(N{b:=(x).Ax x a}) z" 
6248    using fs by simp
6249  also have "\<dots> \<longrightarrow>\<^sub>a* OrL (u).(M[b\<turnstile>c>a]) (v).(N[b\<turnstile>c>a]) z" using ih1 ih2 by (auto intro: a_star_congs)
6250  finally show "(OrL (u).M (v).N z){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (OrL (u).M (v).N z)[b\<turnstile>c>a]" using fs by simp
6251next
6252  case (ImpR z c M d b a x)
6253  have fs: "z\<sharp>b" "z\<sharp>a" "z\<sharp>x" "c\<sharp>b" "c\<sharp>a" "c\<sharp>x" "z\<sharp>d" "c\<sharp>d" by fact+
6254  have ih: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6255  show "(ImpR (z).<c>.M d){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (ImpR (z).<c>.M d)[b\<turnstile>c>a]"
6256  proof(cases "b=d")
6257    case True
6258    assume eq: "b=d"
6259    obtain a'::"coname" where new: "a'\<sharp>(Ax x a,M{b:=(x).Ax x a},x,a,c)" 
6260      by (rule exists_fresh(2)[OF fs_coname1])
6261    have "(ImpR (z).<c>.M d){b:=(x).Ax x a} =
6262                fresh_fun (\<lambda>a'. Cut <a'>.ImpR z.<c>.M{b:=(x).Ax x a} a' (x).Ax x a)" using fs eq by simp
6263    also have "\<dots> = Cut <a'>.ImpR z.<c>.M{b:=(x).Ax x a} a' (x).Ax x a" 
6264      using new by (simp add: fresh_fun_simp_ImpR)
6265    also have "\<dots> \<longrightarrow>\<^sub>a* (ImpR z.<c>.M{b:=(x).Ax x a} a')[a'\<turnstile>c>a]"
6266      using new 
6267      apply(rule_tac a_starI)
6268      apply(rule a_redu.intros)
6269      apply(rule better_LAxR_intro)
6270      apply(rule fic.intros)
6271      apply(simp_all add: abs_fresh)
6272      done
6273    also have "\<dots> = ImpR z.<c>.M{b:=(x).Ax x a} a" using fs new
6274      by (auto simp add: fresh_prod crename_fresh subst_fresh fresh_atm)
6275    also have "\<dots> \<longrightarrow>\<^sub>a* ImpR z.<c>.(M[b\<turnstile>c>a]) a" using ih by (auto intro: a_star_congs)
6276    also have "\<dots> = (ImpR z.<c>.M b)[b\<turnstile>c>a]" using eq fs by simp
6277    finally show "(ImpR (z).<c>.M d){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (ImpR (z).<c>.M d)[b\<turnstile>c>a]" using eq by simp
6278  next
6279    case False
6280    assume neq: "b\<noteq>d"
6281    have "(ImpR (z).<c>.M d){b:=(x).Ax x a} = ImpR (z).<c>.(M{b:=(x).Ax x a}) d" using fs neq by simp
6282    also have "\<dots> \<longrightarrow>\<^sub>a* ImpR (z).<c>.(M[b\<turnstile>c>a]) d" using ih by (auto intro: a_star_congs)
6283    finally show "(ImpR (z).<c>.M d){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (ImpR (z).<c>.M d)[b\<turnstile>c>a]" using neq fs by simp
6284  qed
6285next
6286  case (ImpL c M u N v b a x)
6287  have fs: "c\<sharp>b" "c\<sharp>a" "c\<sharp>x" "u\<sharp>b" "u\<sharp>a" "u\<sharp>x" "c\<sharp>N" "c\<sharp>v" "u\<sharp>M" "u\<sharp>v" by fact+
6288  have ih1: "M{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* M[b\<turnstile>c>a]" by fact
6289  have ih2: "N{b:=(x).Ax x a} \<longrightarrow>\<^sub>a* N[b\<turnstile>c>a]" by fact
6290  have "(ImpL <c>.M (u).N v){b:=(x).Ax x a} = ImpL <c>.(M{b:=(x).Ax x a}) (u).(N{b:=(x).Ax x a}) v" 
6291    using fs by simp
6292  also have "\<dots> \<longrightarrow>\<^sub>a* ImpL <c>.(M[b\<turnstile>c>a]) (u).(N[b\<turnstile>c>a]) v" 
6293    using ih1 ih2 by (auto intro: a_star_congs)
6294  finally show "(ImpL <c>.M (u).N v){b:=(x).Ax x a} \<longrightarrow>\<^sub>a* (ImpL <c>.M (u).N v)[b\<turnstile>c>a]" 
6295    using fs by simp
6296qed
6297
6298text \<open>substitution lemmas\<close>
6299
6300lemma not_Ax1:
6301  shows "\<not>(b\<sharp>M) \<Longrightarrow> M{b:=(y).Q} \<noteq> Ax x a"
6302apply(nominal_induct M avoiding: b y Q x a rule: trm.strong_induct)
6303apply(auto simp add: fresh_atm abs_fresh abs_supp fin_supp)
6304apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname:=(y).Q},Q)")
6305apply(erule exE)
6306apply(simp add: fresh_prod)
6307apply(erule conjE)+
6308apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
6309apply(rule exists_fresh'(2)[OF fs_coname1])
6310apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname:=(y).Q},Q)")
6311apply(erule exE)
6312apply(simp add: fresh_prod)
6313apply(erule conjE)+
6314apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
6315apply(rule exists_fresh'(2)[OF fs_coname1])
6316apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(y).Q},Q,trm2{coname3:=(y).Q},coname1,coname2)")
6317apply(erule exE)
6318apply(simp add: fresh_prod)
6319apply(erule conjE)+
6320apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
6321apply(rule exists_fresh'(2)[OF fs_coname1])
6322apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(y).Q},Q,trm2{coname3:=(y).Q},coname1,coname2)")
6323apply(erule exE)
6324apply(simp add: fresh_prod)
6325apply(erule conjE)+
6326apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
6327apply(rule exists_fresh'(2)[OF fs_coname1])
6328apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm1{coname3:=(y).Q},Q,trm2{coname3:=(y).Q},coname1,coname2)")
6329apply(erule exE)
6330apply(simp add: fresh_prod)
6331apply(erule conjE)+
6332apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
6333apply(rule exists_fresh'(2)[OF fs_coname1])
6334apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(y).Q},Q,coname1)")
6335apply(erule exE)
6336apply(simp add: fresh_prod)
6337apply(erule conjE)+
6338apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
6339apply(rule exists_fresh'(2)[OF fs_coname1])
6340apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(y).Q},Q,coname1)")
6341apply(erule exE)
6342apply(simp add: fresh_prod)
6343apply(erule conjE)+
6344apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
6345apply(rule exists_fresh'(2)[OF fs_coname1])
6346apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(y).Q},Q,coname1)")
6347apply(erule exE)
6348apply(simp add: fresh_prod)
6349apply(erule conjE)+
6350apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
6351apply(rule exists_fresh'(2)[OF fs_coname1])
6352apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(y).Q},Q,coname1)")
6353apply(erule exE)
6354apply(simp add: fresh_prod)
6355apply(erule conjE)+
6356apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
6357apply(rule exists_fresh'(2)[OF fs_coname1])
6358apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(y).Q},Q,coname1)")
6359apply(erule exE)
6360apply(simp add: fresh_prod)
6361apply(erule conjE)+
6362apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
6363apply(rule exists_fresh'(2)[OF fs_coname1])
6364apply(subgoal_tac "\<exists>x'::coname. x'\<sharp>(trm{coname2:=(y).Q},Q,coname1)")
6365apply(erule exE)
6366apply(simp add: fresh_prod)
6367apply(erule conjE)+
6368apply(simp add: fresh_fun_simp_ImpR abs_fresh abs_supp fin_supp fresh_atm)
6369apply(rule exists_fresh'(2)[OF fs_coname1])
6370done
6371
6372lemma not_Ax2:
6373  shows "\<not>(x\<sharp>M) \<Longrightarrow> M{x:=<b>.Q} \<noteq> Ax y a"
6374apply(nominal_induct M avoiding: b y Q x a rule: trm.strong_induct)
6375apply(auto simp add: fresh_atm abs_fresh abs_supp fin_supp)
6376apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<b>.Q},Q)")
6377apply(erule exE)
6378apply(simp add: fresh_prod)
6379apply(erule conjE)+
6380apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
6381apply(rule exists_fresh'(1)[OF fs_name1])
6382apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<b>.Q},Q)")
6383apply(erule exE)
6384apply(simp add: fresh_prod)
6385apply(erule conjE)+
6386apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
6387apply(rule exists_fresh'(1)[OF fs_name1])
6388apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<b>.Q},Q,name1)")
6389apply(erule exE)
6390apply(simp add: fresh_prod)
6391apply(erule conjE)+
6392apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
6393apply(rule exists_fresh'(1)[OF fs_name1])
6394apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<b>.Q},Q,name1)")
6395apply(erule exE)
6396apply(simp add: fresh_prod)
6397apply(erule conjE)+
6398apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
6399apply(rule exists_fresh'(1)[OF fs_name1])
6400apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<b>.Q},Q,name1)")
6401apply(erule exE)
6402apply(simp add: fresh_prod)
6403apply(erule conjE)+
6404apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
6405apply(rule exists_fresh'(1)[OF fs_name1])
6406apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm{x:=<b>.Q},Q,name1)")
6407apply(erule exE)
6408apply(simp add: fresh_prod)
6409apply(erule conjE)+
6410apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
6411apply(rule exists_fresh'(1)[OF fs_name1])
6412apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{x:=<b>.Q},Q,trm2{x:=<b>.Q},name1,name2)")
6413apply(erule exE)
6414apply(simp add: fresh_prod)
6415apply(erule conjE)+
6416apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
6417apply(rule exists_fresh'(1)[OF fs_name1])
6418apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{x:=<b>.Q},Q,trm2{x:=<b>.Q},name1,name2)")
6419apply(erule exE)
6420apply(simp add: fresh_prod)
6421apply(erule conjE)+
6422apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
6423apply(rule exists_fresh'(1)[OF fs_name1])
6424apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{x:=<b>.Q},Q,trm2{x:=<b>.Q},name1,name2)")
6425apply(erule exE)
6426apply(simp add: fresh_prod)
6427apply(erule conjE)+
6428apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
6429apply(rule exists_fresh'(1)[OF fs_name1])
6430apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<b>.Q},Q,trm2{name2:=<b>.Q},name1)")
6431apply(erule exE)
6432apply(simp add: fresh_prod)
6433apply(erule conjE)+
6434apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
6435apply(rule exists_fresh'(1)[OF fs_name1])
6436apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<b>.Q},Q,trm2{name2:=<b>.Q},name1)")
6437apply(erule exE)
6438apply(simp add: fresh_prod)
6439apply(erule conjE)+
6440apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
6441apply(rule exists_fresh'(1)[OF fs_name1])
6442apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(trm1{name2:=<b>.Q},Q,trm2{name2:=<b>.Q},name1)")
6443apply(erule exE)
6444apply(simp add: fresh_prod)
6445apply(erule conjE)+
6446apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
6447apply(rule exists_fresh'(1)[OF fs_name1])
6448done
6449
6450lemma interesting_subst1:
6451  assumes a: "x\<noteq>y" "x\<sharp>P" "y\<sharp>P" 
6452  shows "N{y:=<c>.P}{x:=<c>.P} = N{x:=<c>.Ax y c}{y:=<c>.P}"
6453using a
6454proof(nominal_induct N avoiding: x y c P rule: trm.strong_induct)
6455  case Ax
6456  then show ?case
6457    by (auto simp add: abs_fresh fresh_atm forget trm.inject)
6458next 
6459  case (Cut d M u M' x' y' c P)
6460  with assms show ?case
6461    apply(simp)
6462    apply(auto)
6463    apply(rule trans)
6464    apply(rule better_Cut_substn)
6465    apply(simp add: abs_fresh)
6466    apply(simp)
6467    apply(simp)
6468    apply(auto)
6469    apply(rule sym)
6470    apply(rule trans)
6471    apply(rule better_Cut_substn)
6472    apply(simp add: abs_fresh)
6473    apply(simp)
6474    apply(simp)
6475    apply(simp add: trm.inject alpha forget)
6476    apply(rule trans)
6477    apply(rule better_Cut_substn)
6478    apply(simp add: abs_fresh)
6479    apply(simp)
6480    apply(simp)
6481    apply(auto)
6482    apply(rule sym)
6483    apply(rule trans)
6484    apply(rule better_Cut_substn)
6485    apply(simp add: abs_fresh)
6486    apply(simp)
6487    apply(simp)
6488    apply(rule impI)
6489    apply(simp add: trm.inject alpha forget)
6490    apply(simp add: trm.inject alpha forget)
6491    apply(rule trans)
6492    apply(rule better_Cut_substn)
6493    apply(simp add: abs_fresh)
6494    apply(simp)
6495    apply(simp)
6496    apply(auto)
6497    apply(rule sym)
6498    apply(rule trans)
6499    apply(rule better_Cut_substn)
6500    apply(simp add: abs_fresh)
6501    apply(simp)
6502    apply(simp)
6503    apply(rule sym)
6504    apply(rule trans)
6505    apply(rule better_Cut_substn)
6506    apply(simp add: abs_fresh)
6507    apply(simp)
6508    apply(simp)
6509    apply(simp add: trm.inject alpha forget)
6510    apply(rule trans)
6511    apply(rule better_Cut_substn)
6512    apply(simp add: abs_fresh)
6513    apply(simp)
6514    apply(simp)
6515    apply(rule sym)
6516    apply(rule trans)
6517    apply(rule better_Cut_substn)
6518    apply(simp add: abs_fresh)
6519    apply(simp)
6520    apply(simp)
6521    apply(rule trans)
6522    apply(rule better_Cut_substn)
6523    apply(simp add: abs_fresh)
6524    apply(simp)
6525    apply(simp)
6526    apply(auto)
6527    apply(case_tac "y'\<sharp>M")
6528    apply(simp add: forget)
6529    apply(simp add: not_Ax2)
6530    apply(rule sym)
6531    apply(rule trans)
6532    apply(rule better_Cut_substn)
6533    apply(simp add: abs_fresh)
6534    apply(simp)
6535    apply(simp)
6536    apply(auto)
6537    apply(case_tac "x'\<sharp>M")
6538    apply(simp add: forget)
6539    apply(simp add: not_Ax2)
6540    done
6541next
6542  case NotR
6543  then show ?case
6544    by (auto simp add: abs_fresh fresh_atm forget)
6545next
6546  case (NotL d M u)
6547  then show ?case
6548    apply (auto simp add: abs_fresh fresh_atm forget)
6549    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{y:=<c>.P},M{x:=<c>.Ax y c}{y:=<c>.P},y,x)")
6550    apply(erule exE, simp add: fresh_prod)
6551    apply(erule conjE)+
6552    apply(simp add: fresh_fun_simp_NotL)
6553    apply(rule trans)
6554    apply(rule better_Cut_substn)
6555    apply(simp add: abs_fresh)
6556    apply(simp)
6557    apply(simp)
6558    apply(auto simp add: fresh_atm)
6559    apply(simp add: trm.inject alpha forget)
6560    apply(rule exists_fresh'(1)[OF fs_name1])
6561    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{x:=<c>.Ax y c},M{x:=<c>.Ax y c}{y:=<c>.P},Ax y c,y,x)")
6562    apply(erule exE, simp only: fresh_prod)
6563    apply(erule conjE)+
6564    apply(simp only: fresh_fun_simp_NotL)
6565    apply(rule sym)
6566    apply(rule trans)
6567    apply(rule better_Cut_substn)
6568    apply(simp add: abs_fresh)
6569    apply(simp)
6570    apply(simp)
6571    apply(simp add: trm.inject alpha forget subst_fresh)
6572    apply(rule trans)
6573    apply(rule substn.simps)
6574    apply(simp add: abs_fresh fresh_prod fresh_atm)
6575    apply(simp add: fresh_atm)
6576    apply(rule exists_fresh'(1)[OF fs_name1])
6577    done
6578next
6579  case (AndR d1 M d2 M' d3)
6580  then show ?case
6581    by (auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6582next
6583  case (AndL1 u M d)
6584  then show ?case
6585    apply(auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6586    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{y:=<c>.P},M{x:=<c>.Ax y c}{y:=<c>.P},u,y,x)")
6587    apply(erule exE, simp add: fresh_prod)
6588    apply(erule conjE)+
6589    apply(simp add: fresh_fun_simp_AndL1)
6590    apply(rule trans)
6591    apply(rule better_Cut_substn)
6592    apply(simp add: abs_fresh)
6593    apply(simp)
6594    apply(simp)
6595    apply(auto simp add: fresh_atm)
6596    apply(simp add: trm.inject alpha forget)
6597    apply(rule exists_fresh'(1)[OF fs_name1])
6598    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,Ax y c,M{x:=<c>.Ax y c},M{x:=<c>.Ax y c}{y:=<c>.P},u,y,x)")
6599    apply(erule exE, simp only: fresh_prod)
6600    apply(erule conjE)+
6601    apply(simp only: fresh_fun_simp_AndL1)
6602    apply(rule sym)
6603    apply(rule trans)
6604    apply(rule better_Cut_substn)
6605    apply(simp add: abs_fresh)
6606    apply(simp)
6607    apply(simp)
6608    apply(auto simp add: fresh_atm)
6609    apply(rule exists_fresh'(1)[OF fs_name1])
6610    done
6611next
6612  case (AndL2 u M d)
6613  then show ?case
6614    apply(auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6615    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{y:=<c>.P},M{x:=<c>.Ax y c}{y:=<c>.P},u,y,x)")
6616    apply(erule exE, simp add: fresh_prod)
6617    apply(erule conjE)+
6618    apply(simp add: fresh_fun_simp_AndL2)
6619    apply(rule trans)
6620    apply(rule better_Cut_substn)
6621    apply(simp add: abs_fresh)
6622    apply(simp)
6623    apply(simp)
6624    apply(auto simp add: fresh_atm)
6625    apply(simp add: trm.inject alpha forget)
6626    apply(rule exists_fresh'(1)[OF fs_name1])
6627    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,Ax y c,M{x:=<c>.Ax y c},M{x:=<c>.Ax y c}{y:=<c>.P},u,y,x)")
6628    apply(erule exE, simp only: fresh_prod)
6629    apply(erule conjE)+
6630    apply(simp only: fresh_fun_simp_AndL2)
6631    apply(rule sym)
6632    apply(rule trans)
6633    apply(rule better_Cut_substn)
6634    apply(simp add: abs_fresh)
6635    apply(simp)
6636    apply(simp)
6637    apply(auto simp add: fresh_atm)
6638    apply(rule exists_fresh'(1)[OF fs_name1])
6639    done
6640next
6641  case OrR1
6642  then show ?case
6643    by (auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6644next
6645  case OrR2
6646  then show ?case
6647    by (auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6648next
6649  case (OrL x1 M x2 M' x3)
6650  then show ?case
6651    apply(auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6652    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{y:=<c>.P},M{x:=<c>.Ax y c}{y:=<c>.P},
6653                                        M'{y:=<c>.P},M'{x:=<c>.Ax y c}{y:=<c>.P},x1,x2,x3,y,x)")
6654    apply(erule exE, simp add: fresh_prod)
6655    apply(erule conjE)+
6656    apply(simp add: fresh_fun_simp_OrL)
6657    apply(rule trans)
6658    apply(rule better_Cut_substn)
6659    apply(simp add: abs_fresh)
6660    apply(simp)
6661    apply(simp)
6662    apply(auto simp add: fresh_atm)
6663    apply(simp add: trm.inject alpha forget)
6664    apply(rule trans)
6665    apply(rule substn.simps)
6666    apply(simp add: abs_fresh subst_fresh fresh_atm)
6667    apply(simp add: abs_fresh subst_fresh fresh_atm)
6668    apply(force)
6669    apply(simp)
6670    apply(rule exists_fresh'(1)[OF fs_name1])
6671    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,Ax y c,M{x:=<c>.Ax y c},M{x:=<c>.Ax y c}{y:=<c>.P},
6672                                        M'{x:=<c>.Ax y c},M'{x:=<c>.Ax y c}{y:=<c>.P},x1,x2,x3,y,x)")
6673    apply(erule exE, simp only: fresh_prod)
6674    apply(erule conjE)+
6675    apply(simp only: fresh_fun_simp_OrL)
6676    apply(rule sym)
6677    apply(rule trans)
6678    apply(rule better_Cut_substn)
6679    apply(simp add: abs_fresh)
6680    apply(simp)
6681    apply(simp)
6682    apply(simp add: trm.inject alpha)
6683    apply(rule trans)
6684    apply(rule substn.simps)
6685    apply(simp add: abs_fresh subst_fresh fresh_atm)
6686    apply(simp add: abs_fresh subst_fresh fresh_atm)
6687    apply(force)
6688    apply(simp)
6689    apply(auto simp add: fresh_atm)
6690    apply(rule exists_fresh'(1)[OF fs_name1])
6691    done
6692next
6693  case ImpR
6694  then show ?case
6695    by (auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6696next
6697  case (ImpL a M x1 M' x2)
6698  then show ?case
6699    apply(auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6700    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{x2:=<c>.P},M{x:=<c>.Ax x2 c}{x2:=<c>.P},
6701                                        M'{x2:=<c>.P},M'{x:=<c>.Ax x2 c}{x2:=<c>.P},x1,y,x)")
6702    apply(erule exE, simp add: fresh_prod)
6703    apply(erule conjE)+
6704    apply(simp add: fresh_fun_simp_ImpL)
6705    apply(rule trans)
6706    apply(rule better_Cut_substn)
6707    apply(simp add: abs_fresh)
6708    apply(simp)
6709    apply(simp)
6710    apply(auto simp add: fresh_atm)
6711    apply(simp add: trm.inject alpha forget)
6712    apply(rule trans)
6713    apply(rule substn.simps)
6714    apply(simp add: abs_fresh subst_fresh fresh_atm)
6715    apply(simp add: abs_fresh subst_fresh fresh_atm)
6716    apply(force)
6717    apply(rule exists_fresh'(1)[OF fs_name1])
6718    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,Ax y c,M{x2:=<c>.Ax y c},M{x2:=<c>.Ax y c}{y:=<c>.P},
6719                                        M'{x2:=<c>.Ax y c},M'{x2:=<c>.Ax y c}{y:=<c>.P},x1,x2,y,x)")
6720    apply(erule exE, simp only: fresh_prod)
6721    apply(erule conjE)+
6722    apply(simp only: fresh_fun_simp_ImpL)
6723    apply(rule sym)
6724    apply(rule trans)
6725    apply(rule better_Cut_substn)
6726    apply(simp add: abs_fresh)
6727    apply(simp)
6728    apply(simp)
6729    apply(simp add: trm.inject alpha)
6730    apply(rule trans)
6731    apply(rule substn.simps)
6732    apply(simp add: abs_fresh subst_fresh fresh_atm)
6733    apply(simp add: abs_fresh subst_fresh fresh_atm)
6734    apply(simp)
6735    apply(auto simp add: fresh_atm)
6736    apply(rule exists_fresh'(1)[OF fs_name1])
6737    done
6738qed 
6739
6740lemma interesting_subst1':
6741  assumes a: "x\<noteq>y" "x\<sharp>P" "y\<sharp>P" 
6742  shows "N{y:=<c>.P}{x:=<c>.P} = N{x:=<a>.Ax y a}{y:=<c>.P}"
6743proof -
6744  show ?thesis
6745  proof (cases "c=a")
6746    case True then show ?thesis using a by (simp add: interesting_subst1)
6747  next
6748    case False then show ?thesis using a
6749      apply - 
6750      apply(subgoal_tac "N{x:=<a>.Ax y a} = N{x:=<c>.([(c,a)]\<bullet>Ax y a)}") 
6751      apply(simp add: interesting_subst1 calc_atm)
6752      apply(rule subst_rename)
6753      apply(simp add: fresh_prod fresh_atm)
6754      done
6755  qed
6756qed
6757
6758lemma interesting_subst2:
6759  assumes a: "a\<noteq>b" "a\<sharp>P" "b\<sharp>P" 
6760  shows "N{a:=(y).P}{b:=(y).P} = N{b:=(y).Ax y a}{a:=(y).P}"
6761using a
6762proof(nominal_induct N avoiding: a b y P rule: trm.strong_induct)
6763  case Ax
6764  then show ?case
6765    by (auto simp add: abs_fresh fresh_atm forget trm.inject)
6766next 
6767  case (Cut d M u M' x' y' c P)
6768  with assms show ?case
6769    apply(simp)
6770    apply(auto simp add: trm.inject)
6771    apply(rule trans)
6772    apply(rule better_Cut_substc)
6773    apply(simp)
6774    apply(simp add: abs_fresh)
6775    apply(simp add: forget)
6776    apply(auto)
6777    apply(rule sym)
6778    apply(rule trans)
6779    apply(rule better_Cut_substc)
6780    apply(simp add: abs_fresh)
6781    apply(simp add: abs_fresh)
6782    apply(simp)
6783    apply(rule sym)
6784    apply(rule trans)
6785    apply(rule better_Cut_substc)
6786    apply(simp add: abs_fresh)
6787    apply(simp add: abs_fresh) 
6788    apply(simp)
6789    apply(rule sym)
6790    apply(rule trans)
6791    apply(rule better_Cut_substc)
6792    apply(simp add: abs_fresh)
6793    apply(simp add: abs_fresh)
6794    apply(simp)
6795    apply(rule sym)
6796    apply(rule trans)
6797    apply(rule better_Cut_substc)
6798    apply(simp add: abs_fresh)
6799    apply(simp add: abs_fresh)
6800    apply(simp)
6801    apply(rule trans)
6802    apply(rule better_Cut_substc)
6803    apply(simp add: abs_fresh)
6804    apply(simp add: abs_fresh)
6805    apply(auto)[1]
6806    apply(rule sym)
6807    apply(rule trans)
6808    apply(rule better_Cut_substc)
6809    apply(simp add: abs_fresh)
6810    apply(simp add: abs_fresh)
6811    apply(simp)
6812    apply(rule impI)
6813    apply(simp add: fresh_atm trm.inject alpha forget)
6814    apply(case_tac "x'\<sharp>M'")
6815    apply(simp add: forget)
6816    apply(simp add: not_Ax1)
6817    apply(rule sym)
6818    apply(rule trans)
6819    apply(rule better_Cut_substc)
6820    apply(simp add: abs_fresh)
6821    apply(simp add: abs_fresh)
6822    apply(auto)
6823    apply(case_tac "y'\<sharp>M'")
6824    apply(simp add: forget)
6825    apply(simp add: not_Ax1)
6826    done
6827next
6828  case NotL
6829  then show ?case
6830    by (auto simp add: abs_fresh fresh_atm forget)
6831next
6832  case (NotR u M d)
6833  then show ?case
6834    apply (auto simp add: abs_fresh fresh_atm forget)
6835    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(b,P,M{d:=(y).P},M{b:=(y).Ax y d}{d:=(y).P},u,y)")
6836    apply(erule exE, simp add: fresh_prod)
6837    apply(erule conjE)+
6838    apply(simp add: fresh_fun_simp_NotR)
6839    apply(rule trans)
6840    apply(rule better_Cut_substc)
6841    apply(simp add: abs_fresh)
6842    apply(simp add: abs_fresh)
6843    apply(simp)
6844    apply(auto simp add: fresh_atm)
6845    apply(simp add: trm.inject alpha forget)
6846    apply(rule exists_fresh'(2)[OF fs_coname1])
6847    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(P,M{d:=(y).Ax y a},M{d:=(y).Ax y a}{a:=(y).P},Ax y a,y,d)")
6848    apply(erule exE, simp only: fresh_prod)
6849    apply(erule conjE)+
6850    apply(simp only: fresh_fun_simp_NotR)
6851    apply(rule sym)
6852    apply(rule trans)
6853    apply(rule better_Cut_substc)
6854    apply(simp add: abs_fresh)
6855    apply(simp add: abs_fresh)
6856    apply(simp)
6857    apply(simp add: trm.inject alpha forget subst_fresh)
6858    apply(rule trans)
6859    apply(rule substc.simps)
6860    apply(simp add: abs_fresh fresh_prod fresh_atm)
6861    apply(simp add: fresh_atm)
6862    apply(rule exists_fresh'(2)[OF fs_coname1])
6863    done
6864next
6865  case (AndR d1 M d2 M' d3)
6866  then show ?case
6867    apply(auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6868    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(P,M{d3:=(y).P},M{b:=(y).Ax y d3}{d3:=(y).P},
6869                                        M'{d3:=(y).P},M'{b:=(y).Ax y d3}{d3:=(y).P},d1,d2,d3,b,y)")
6870    apply(erule exE, simp add: fresh_prod)
6871    apply(erule conjE)+
6872    apply(simp add: fresh_fun_simp_AndR)
6873    apply(rule trans)
6874    apply(rule better_Cut_substc)
6875    apply(simp add: abs_fresh fresh_atm)
6876    apply(simp add: abs_fresh fresh_atm)
6877    apply(simp)
6878    apply(auto simp add: fresh_atm)
6879    apply(simp add: trm.inject alpha forget)
6880    apply(rule trans)
6881    apply(rule substc.simps)
6882    apply(simp add: abs_fresh subst_fresh fresh_atm)
6883    apply(simp add: abs_fresh subst_fresh fresh_atm)
6884    apply(force)
6885    apply(simp)
6886    apply(rule exists_fresh'(2)[OF fs_coname1])
6887    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(P,Ax y a,M{d3:=(y).Ax y a},M{d3:=(y).Ax y a}{a:=(y).P},
6888                                        M'{d3:=(y).Ax y a},M'{d3:=(y).Ax y a}{a:=(y).P},d1,d2,d3,y,b)")
6889    apply(erule exE, simp only: fresh_prod)
6890    apply(erule conjE)+
6891    apply(simp only: fresh_fun_simp_AndR)
6892    apply(rule sym)
6893    apply(rule trans)
6894    apply(rule better_Cut_substc)
6895    apply(simp add: abs_fresh)
6896    apply(simp add: abs_fresh)
6897    apply(simp)
6898    apply(simp add: trm.inject alpha)
6899    apply(rule trans)
6900    apply(rule substc.simps)
6901    apply(simp add: abs_fresh subst_fresh fresh_atm)
6902    apply(simp add: abs_fresh subst_fresh fresh_atm)
6903    apply(force)
6904    apply(simp)
6905    apply(auto simp add: fresh_atm)
6906    apply(rule exists_fresh'(2)[OF fs_coname1])
6907    done
6908next
6909  case (AndL1 u M d)
6910  then show ?case
6911    by (auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6912next
6913  case (AndL2 u M d)
6914  then show ?case
6915    by (auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6916next
6917  case (OrR1 d M e)
6918  then show ?case
6919    apply (auto simp add: abs_fresh fresh_atm forget)
6920    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(b,P,M{e:=(y).P},M{b:=(y).Ax y e}{e:=(y).P},d,e)")
6921    apply(erule exE, simp add: fresh_prod)
6922    apply(erule conjE)+
6923    apply(simp add: fresh_fun_simp_OrR1)
6924    apply(rule trans)
6925    apply(rule better_Cut_substc)
6926    apply(simp add: abs_fresh)
6927    apply(simp add: abs_fresh)
6928    apply(simp)
6929    apply(auto simp add: fresh_atm)
6930    apply(simp add: trm.inject alpha forget)
6931    apply(rule exists_fresh'(2)[OF fs_coname1])
6932    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(b,P,Ax y a,M{e:=(y).Ax y a},M{e:=(y).Ax y a}{a:=(y).P},d,e)")
6933    apply(erule exE, simp only: fresh_prod)
6934    apply(erule conjE)+
6935    apply(simp only: fresh_fun_simp_OrR1)
6936    apply(rule sym)
6937    apply(rule trans)
6938    apply(rule better_Cut_substc)
6939    apply(simp add: abs_fresh)
6940    apply(simp add: abs_fresh)
6941    apply(simp)
6942    apply(simp add: trm.inject alpha forget subst_fresh)
6943    apply(rule trans)
6944    apply(rule substc.simps)
6945    apply(simp add: abs_fresh fresh_prod fresh_atm)
6946    apply(simp add: fresh_atm)
6947    apply(rule exists_fresh'(2)[OF fs_coname1])
6948    done
6949next
6950  case (OrR2 d M e)
6951  then show ?case
6952    apply (auto simp add: abs_fresh fresh_atm forget)
6953    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(b,P,M{e:=(y).P},M{b:=(y).Ax y e}{e:=(y).P},d,e)")
6954    apply(erule exE, simp add: fresh_prod)
6955    apply(erule conjE)+
6956    apply(simp add: fresh_fun_simp_OrR2)
6957    apply(rule trans)
6958    apply(rule better_Cut_substc)
6959    apply(simp add: abs_fresh)
6960    apply(simp add: abs_fresh)
6961    apply(simp)
6962    apply(auto simp add: fresh_atm)
6963    apply(simp add: trm.inject alpha forget)
6964    apply(rule exists_fresh'(2)[OF fs_coname1])
6965    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(b,P,Ax y a,M{e:=(y).Ax y a},M{e:=(y).Ax y a}{a:=(y).P},d,e)")
6966    apply(erule exE, simp only: fresh_prod)
6967    apply(erule conjE)+
6968    apply(simp only: fresh_fun_simp_OrR2)
6969    apply(rule sym)
6970    apply(rule trans)
6971    apply(rule better_Cut_substc)
6972    apply(simp add: abs_fresh)
6973    apply(simp add: abs_fresh)
6974    apply(simp)
6975    apply(simp add: trm.inject alpha forget subst_fresh)
6976    apply(rule trans)
6977    apply(rule substc.simps)
6978    apply(simp add: abs_fresh fresh_prod fresh_atm)
6979    apply(simp add: fresh_atm)
6980    apply(rule exists_fresh'(2)[OF fs_coname1])
6981    done
6982next
6983  case (OrL x1 M x2 M' x3)
6984  then show ?case
6985    by(auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6986next
6987  case ImpL
6988  then show ?case
6989    by (auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6990next
6991  case (ImpR u e M d)
6992  then show ?case
6993    apply(auto simp add: abs_fresh fresh_atm forget trm.inject subst_fresh)
6994    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(b,e,d,P,M{d:=(y).P},M{b:=(y).Ax y d}{d:=(y).P})")
6995    apply(erule exE, simp add: fresh_prod)
6996    apply(erule conjE)+
6997    apply(simp add: fresh_fun_simp_ImpR)
6998    apply(rule trans)
6999    apply(rule better_Cut_substc)
7000    apply(simp add: abs_fresh)
7001    apply(simp add: abs_fresh)
7002    apply(simp)
7003    apply(auto simp add: fresh_atm)
7004    apply(simp add: trm.inject alpha forget)
7005    apply(rule exists_fresh'(2)[OF fs_coname1])
7006    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(e,d,P,Ax y a,M{d:=(y).Ax y a},M{d:=(y).Ax y a}{a:=(y).P})")
7007    apply(erule exE, simp only: fresh_prod)
7008    apply(erule conjE)+
7009    apply(simp only: fresh_fun_simp_ImpR)
7010    apply(rule sym)
7011    apply(rule trans)
7012    apply(rule better_Cut_substc)
7013    apply(simp add: abs_fresh)
7014    apply(simp add: abs_fresh)
7015    apply(simp)
7016    apply(simp add: trm.inject alpha)
7017    apply(rule trans)
7018    apply(rule substc.simps)
7019    apply(simp add: abs_fresh subst_fresh fresh_atm)
7020    apply(simp add: abs_fresh subst_fresh fresh_atm)
7021    apply(simp)
7022    apply(auto simp add: fresh_atm)
7023    apply(rule exists_fresh'(2)[OF fs_coname1])
7024    done
7025qed 
7026
7027lemma interesting_subst2':
7028  assumes a: "a\<noteq>b" "a\<sharp>P" "b\<sharp>P" 
7029  shows "N{a:=(y).P}{b:=(y).P} = N{b:=(z).Ax z a}{a:=(y).P}"
7030proof -
7031  show ?thesis
7032  proof (cases "z=y")
7033    case True then show ?thesis using a by (simp add: interesting_subst2)
7034  next
7035    case False then show ?thesis using a
7036      apply - 
7037      apply(subgoal_tac "N{b:=(z).Ax z a} = N{b:=(y).([(y,z)]\<bullet>Ax z a)}") 
7038      apply(simp add: interesting_subst2 calc_atm)
7039      apply(rule subst_rename)
7040      apply(simp add: fresh_prod fresh_atm)
7041      done
7042  qed
7043qed
7044
7045lemma subst_subst1:
7046  assumes a: "a\<sharp>(Q,b)" "x\<sharp>(y,P,Q)" "b\<sharp>Q" "y\<sharp>P" 
7047  shows "M{x:=<a>.P}{b:=(y).Q} = M{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}"
7048using a
7049proof(nominal_induct M avoiding: x a P b y Q rule: trm.strong_induct)
7050  case (Ax z c)
7051  have fs: "a\<sharp>(Q,b)" "x\<sharp>(y,P,Q)" "b\<sharp>Q" "y\<sharp>P" by fact+
7052  { assume asm: "z=x \<and> c=b"
7053    have "(Ax x b){x:=<a>.P}{b:=(y).Q} = (Cut <a>.P (x).Ax x b){b:=(y).Q}" using fs by simp
7054    also have "\<dots> = Cut <a>.(P{b:=(y).Q}) (y).Q"
7055      using fs by (simp_all add: fresh_prod fresh_atm)
7056    also have "\<dots> = Cut <a>.(P{b:=(y).Q}) (y).(Q{x:=<a>.(P{b:=(y).Q})})" using fs by (simp add: forget)
7057    also have "\<dots> = (Cut <b>.Ax x b (y).Q){x:=<a>.(P{b:=(y).Q})}"
7058      using fs asm by (auto simp add: fresh_prod fresh_atm subst_fresh)
7059    also have "\<dots> = (Ax x b){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}" using fs by simp
7060    finally have "(Ax z c){x:=<a>.P}{b:=(y).Q} = (Ax z c){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}" 
7061      using asm by simp
7062  }
7063  moreover
7064  { assume asm: "z\<noteq>x \<and> c=b"
7065    have "(Ax z c){x:=<a>.P}{b:=(y).Q} = (Ax z c){b:=(y).Q}" using asm by simp
7066    also have "\<dots> = Cut <b>.Ax z c (y).Q" using fs asm by simp
7067    also have "\<dots> = Cut <b>.(Ax z c{x:=<a>.(P{b:=(y).Q})}) (y).(Q{x:=<a>.(P{b:=(y).Q})})" 
7068      using fs asm by (simp add: forget)
7069    also have "\<dots> = (Cut <b>.Ax z c (y).Q){x:=<a>.(P{b:=(y).Q})}" using asm fs
7070      by (auto simp add: trm.inject subst_fresh fresh_prod fresh_atm abs_fresh)
7071    also have "\<dots> = (Ax z c){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}" using asm fs by simp
7072    finally have "(Ax z c){x:=<a>.P}{b:=(y).Q} = (Ax z c){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}" by simp
7073  }
7074  moreover
7075  { assume asm: "z=x \<and> c\<noteq>b"
7076    have "(Ax z c){x:=<a>.P}{b:=(y).Q} = (Cut <a>.P (x).Ax z c){b:=(y).Q}" using fs asm by simp
7077    also have "\<dots> = Cut <a>.(P{b:=(y).Q}) (x).Ax z c" using fs asm by (auto simp add: trm.inject abs_fresh)
7078    also have "\<dots> = (Ax z c){x:=<a>.(P{b:=(y).Q})}" using fs asm by simp
7079    also have "\<dots> = (Ax z c){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}" using asm by auto
7080    finally have "(Ax z c){x:=<a>.P}{b:=(y).Q} = (Ax z c){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}" by simp
7081  }
7082  moreover
7083  { assume asm: "z\<noteq>x \<and> c\<noteq>b"
7084    have "(Ax z c){x:=<a>.P}{b:=(y).Q} = (Ax z c){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}" using asm by auto
7085  }
7086  ultimately show ?case by blast
7087next
7088  case (Cut c M z N)
7089  { assume asm: "M = Ax x c \<and> N = Ax z b"
7090    have "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = (Cut <a>.P (z).(N{x:=<a>.P})){b:=(y).Q}" 
7091      using Cut asm by simp
7092    also have "\<dots> = (Cut <a>.P (z).N){b:=(y).Q}" using Cut asm by (simp add: fresh_atm)
7093    also have "\<dots> = (Cut <a>.(P{b:=(y).Q}) (y).Q)" using Cut asm by (auto simp add: fresh_prod fresh_atm)
7094    finally have eq1: "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = (Cut <a>.(P{b:=(y).Q}) (y).Q)" by simp
7095    have "(Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})} = (Cut <c>.M (y).Q){x:=<a>.(P{b:=(y).Q})}"
7096      using Cut asm by (simp add: fresh_atm)
7097    also have "\<dots> = Cut <a>.(P{b:=(y).Q}) (y).(Q{x:=<a>.(P{b:=(y).Q})})" using Cut asm
7098      by (auto simp add: fresh_prod fresh_atm subst_fresh)
7099    also have "\<dots> = Cut <a>.(P{b:=(y).Q}) (y).Q" using Cut asm by (simp add: forget)
7100    finally have eq2: "(Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})} = Cut <a>.(P{b:=(y).Q}) (y).Q"
7101      by simp
7102    have "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = (Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}" 
7103      using eq1 eq2 by simp
7104  }
7105  moreover
7106  { assume asm: "M \<noteq> Ax x c \<and> N = Ax z b"
7107    have neq: "M{b:=(y).Q} \<noteq> Ax x c"
7108    proof (cases "b\<sharp>M")
7109      case True then show ?thesis using asm by (simp add: forget)
7110    next
7111      case False then show ?thesis by (simp add: not_Ax1)
7112    qed
7113    have "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = (Cut <c>.(M{x:=<a>.P}) (z).(N{x:=<a>.P})){b:=(y).Q}"
7114      using Cut asm by simp
7115    also have "\<dots> = (Cut <c>.(M{x:=<a>.P}) (z).N){b:=(y).Q}" using Cut asm by (simp add: fresh_atm)
7116    also have "\<dots> = Cut <c>.(M{x:=<a>.P}{b:=(y).Q}) (y).Q" using Cut asm by (simp add: abs_fresh)
7117    also have "\<dots> = Cut <c>.(M{b:=(y).Q}{x:=<a>.P{b:=(y).Q}}) (y).Q" using Cut asm by simp
7118    finally 
7119    have eq1: "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = Cut <c>.(M{b:=(y).Q}{x:=<a>.P{b:=(y).Q}}) (y).Q" 
7120      by simp
7121    have "(Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})} = 
7122               (Cut <c>.(M{b:=(y).Q}) (y).Q){x:=<a>.(P{b:=(y).Q})}" using Cut asm by simp
7123    also have "\<dots> = Cut <c>.(M{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}) (y).(Q{x:=<a>.(P{b:=(y).Q})})"
7124      using Cut asm neq by (auto simp add: fresh_prod fresh_atm subst_fresh abs_fresh)
7125    also have "\<dots> = Cut <c>.(M{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}) (y).Q" using Cut asm by (simp add: forget)
7126    finally have eq2: "(Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})} 
7127                                       = Cut <c>.(M{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}) (y).Q" by simp
7128    have "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = (Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}" 
7129      using eq1 eq2 by simp
7130  }
7131  moreover 
7132  { assume asm: "M = Ax x c \<and> N \<noteq> Ax z b"
7133    have neq: "N{x:=<a>.P} \<noteq> Ax z b"
7134    proof (cases "x\<sharp>N")
7135      case True then show ?thesis using asm by (simp add: forget)
7136    next
7137      case False then show ?thesis by (simp add: not_Ax2)
7138    qed
7139    have "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = (Cut <a>.P (z).(N{x:=<a>.P})){b:=(y).Q}"
7140      using Cut asm by simp
7141    also have "\<dots> = Cut <a>.(P{b:=(y).Q}) (z).(N{x:=<a>.P}{b:=(y).Q})" using Cut asm neq 
7142      by (simp add: abs_fresh)
7143    also have "\<dots> = Cut <a>.(P{b:=(y).Q}) (z).(N{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})})" using Cut asm by simp
7144    finally have eq1: "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} 
7145                    = Cut <a>.(P{b:=(y).Q}) (z).(N{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})})" by simp
7146    have "(Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})} 
7147                    = (Cut <c>.(M{b:=(y).Q}) (z).(N{b:=(y).Q})){x:=<a>.(P{b:=(y).Q})}"
7148      using Cut asm by auto
7149    also have "\<dots> = (Cut <c>.M (z).(N{b:=(y).Q})){x:=<a>.(P{b:=(y).Q})}"
7150      using Cut asm by (auto simp add: fresh_atm)
7151    also have "\<dots> = Cut <a>.(P{b:=(y).Q}) (z).(N{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})})" 
7152      using Cut asm by (simp add: fresh_prod fresh_atm subst_fresh)
7153    finally 
7154    have eq2: "(Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})} 
7155         = Cut <a>.(P{b:=(y).Q}) (z).(N{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})})" by simp
7156    have "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = (Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}"
7157      using eq1 eq2 by simp
7158  }
7159  moreover
7160  { assume asm: "M \<noteq> Ax x c \<and> N \<noteq> Ax z b"
7161    have neq1: "N{x:=<a>.P} \<noteq> Ax z b"
7162    proof (cases "x\<sharp>N")
7163      case True then show ?thesis using asm by (simp add: forget)
7164    next
7165      case False then show ?thesis by (simp add: not_Ax2)
7166    qed
7167    have neq2: "M{b:=(y).Q} \<noteq> Ax x c"
7168    proof (cases "b\<sharp>M")
7169      case True then show ?thesis using asm by (simp add: forget)
7170    next
7171      case False then show ?thesis by (simp add: not_Ax1)
7172    qed
7173    have "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = (Cut <c>.(M{x:=<a>.P}) (z).(N{x:=<a>.P})){b:=(y).Q}"
7174      using Cut asm by simp
7175    also have "\<dots> = Cut <c>.(M{x:=<a>.P}{b:=(y).Q}) (z).(N{x:=<a>.P}{b:=(y).Q})" using Cut asm neq1
7176      by (simp add: abs_fresh)
7177    also have "\<dots> = Cut <c>.(M{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}) (z).(N{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})})"
7178      using Cut asm by simp
7179    finally have eq1: "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q}
7180             = Cut <c>.(M{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}) (z).(N{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})})" by simp
7181    have "(Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})} = 
7182                (Cut <c>.(M{b:=(y).Q}) (z).(N{b:=(y).Q})){x:=<a>.(P{b:=(y).Q})}" using Cut asm neq1 by simp
7183    also have "\<dots> = Cut <c>.(M{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}) (z).(N{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})})"
7184      using Cut asm neq2 by (simp add: fresh_prod fresh_atm subst_fresh)
7185    finally have eq2: "(Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})} = 
7186           Cut <c>.(M{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}) (z).(N{b:=(y).Q}{x:=<a>.(P{b:=(y).Q})})" by simp
7187    have "(Cut <c>.M (z).N){x:=<a>.P}{b:=(y).Q} = (Cut <c>.M (z).N){b:=(y).Q}{x:=<a>.(P{b:=(y).Q})}"
7188      using eq1 eq2 by simp
7189  }
7190  ultimately show ?case by blast
7191next
7192  case (NotR z M c)
7193  then show ?case
7194    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7195    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(M{c:=(y).Q},M{c:=(y).Q}{x:=<a>.P{c:=(y).Q}},Q,a,P,c,y)")
7196    apply(erule exE)
7197    apply(simp add: fresh_prod)
7198    apply(erule conjE)+
7199    apply(simp add: fresh_fun_simp_NotR abs_fresh fresh_atm)
7200    apply(rule sym)
7201    apply(rule trans)
7202    apply(rule better_Cut_substn)
7203    apply(simp add: fresh_prod fresh_atm subst_fresh abs_fresh)
7204    apply(simp add: fresh_prod fresh_atm subst_fresh abs_fresh)
7205    apply(simp add: forget)
7206    apply(simp add: fresh_prod fresh_atm subst_fresh)
7207    apply(rule exists_fresh'(2)[OF fs_coname1])
7208    done
7209next
7210  case (NotL c M z)
7211  then show ?case  
7212    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7213    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{x:=<a>.P},P{b:=(y).Q},M{b:=(y).Q}{x:=<a>.P{b:=(y).Q}},y,Q)")
7214    apply(erule exE)
7215    apply(simp add: fresh_prod)
7216    apply(erule conjE)+
7217    apply(simp add: fresh_fun_simp_NotL abs_fresh fresh_atm)
7218    apply(rule exists_fresh'(1)[OF fs_name1])
7219    done
7220next
7221  case (AndR c1 M c2 N c3)
7222  then show ?case  
7223    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7224    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(Q,M{c3:=(y).Q},M{c3:=(y).Q}{x:=<a>.P{c3:=(y).Q}},c2,c3,a,
7225                                     P{c3:=(y).Q},N{c3:=(y).Q},N{c3:=(y).Q}{x:=<a>.P{c3:=(y).Q}},c1)")
7226    apply(erule exE)
7227    apply(simp add: fresh_prod)
7228    apply(erule conjE)+
7229    apply(simp add: fresh_fun_simp_AndR abs_fresh fresh_atm)
7230    apply(rule sym)
7231    apply(rule trans)
7232    apply(rule better_Cut_substn)
7233    apply(simp_all add: fresh_atm abs_fresh subst_fresh)
7234    apply(simp add: forget)
7235    apply(rule exists_fresh'(2)[OF fs_coname1])
7236    done
7237next
7238  case (AndL1 z1 M z2)
7239  then show ?case  
7240    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7241    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{x:=<a>.P},P{b:=(y).Q},z1,y,Q,M{b:=(y).Q}{x:=<a>.P{b:=(y).Q}})")
7242    apply(erule exE)
7243    apply(simp add: fresh_prod)
7244    apply(erule conjE)+
7245    apply(simp add: fresh_fun_simp_AndL1 abs_fresh fresh_atm)
7246    apply(rule exists_fresh'(1)[OF fs_name1])
7247    done
7248next
7249  case (AndL2 z1 M z2)
7250  then show ?case  
7251    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7252    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{x:=<a>.P},P{b:=(y).Q},z1,y,Q,M{b:=(y).Q}{x:=<a>.P{b:=(y).Q}})")
7253    apply(erule exE)
7254    apply(simp add: fresh_prod)
7255    apply(erule conjE)+
7256    apply(simp add: fresh_fun_simp_AndL2 abs_fresh fresh_atm)
7257    apply(rule exists_fresh'(1)[OF fs_name1])
7258    done
7259next
7260  case (OrL z1 M z2 N z3)
7261  then show ?case  
7262    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7263    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,M{x:=<a>.P},M{b:=(y).Q}{x:=<a>.P{b:=(y).Q}},z2,z3,a,y,Q,
7264                                     P{b:=(y).Q},N{x:=<a>.P},N{b:=(y).Q}{x:=<a>.P{b:=(y).Q}},z1)")
7265    apply(erule exE)
7266    apply(simp add: fresh_prod)
7267    apply(erule conjE)+
7268    apply(simp add: fresh_fun_simp_OrL abs_fresh fresh_atm)
7269    apply(simp add: trm.inject alpha)
7270    apply(rule trans)
7271    apply(rule substc.simps)
7272    apply(simp_all add: fresh_atm subst_fresh)
7273    apply(rule exists_fresh'(1)[OF fs_name1])
7274    done
7275next
7276  case (OrR1 c1 M c2)
7277  then show ?case  
7278    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7279    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(Q,M{c2:=(y).Q},a,P{c2:=(y).Q},c1,
7280                                                     M{c2:=(y).Q}{x:=<a>.P{c2:=(y).Q}})")
7281    apply(erule exE)
7282    apply(simp add: fresh_prod)
7283    apply(erule conjE)+
7284    apply(simp add: fresh_fun_simp_OrR1 abs_fresh fresh_atm)
7285    apply(simp_all add: fresh_atm subst_fresh abs_fresh)
7286    apply(simp add: forget)
7287    apply(rule exists_fresh'(2)[OF fs_coname1])
7288    done
7289next
7290  case (OrR2 c1 M c2)
7291  then show ?case  
7292    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7293    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(Q,M{c2:=(y).Q},a,P{c2:=(y).Q},c1,
7294                                                     M{c2:=(y).Q}{x:=<a>.P{c2:=(y).Q}})")
7295    apply(erule exE)
7296    apply(simp add: fresh_prod)
7297    apply(erule conjE)+
7298    apply(simp add: fresh_fun_simp_OrR2 abs_fresh fresh_atm)
7299    apply(simp_all add: fresh_atm subst_fresh abs_fresh)
7300    apply(simp add: forget)
7301    apply(rule exists_fresh'(2)[OF fs_coname1])
7302    done
7303next
7304  case (ImpR z c M d)
7305  then show ?case  
7306    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7307    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(Q,M{d:=(y).Q},a,P{d:=(y).Q},c,
7308                                                     M{d:=(y).Q}{x:=<a>.P{d:=(y).Q}})")
7309    apply(erule exE)
7310    apply(simp add: fresh_prod)
7311    apply(erule conjE)+
7312    apply(simp add: fresh_fun_simp_ImpR abs_fresh fresh_atm)
7313    apply(simp_all add: fresh_atm subst_fresh forget abs_fresh)
7314    apply(rule exists_fresh'(2)[OF fs_coname1])
7315    done
7316next
7317  case (ImpL c M z N u)
7318  then show ?case  
7319    apply(auto simp add: fresh_prod fresh_atm subst_fresh)
7320    apply(subgoal_tac "\<exists>z'::name. z'\<sharp>(P,P{b:=(y).Q},M{u:=<a>.P},N{u:=<a>.P},y,Q,
7321                        M{b:=(y).Q}{u:=<a>.P{b:=(y).Q}},N{b:=(y).Q}{u:=<a>.P{b:=(y).Q}},z)")
7322    apply(erule exE)
7323    apply(simp add: fresh_prod)
7324    apply(erule conjE)+
7325    apply(simp add: fresh_fun_simp_ImpL abs_fresh fresh_atm)
7326    apply(simp add: trm.inject alpha)
7327    apply(rule trans)
7328    apply(rule substc.simps)
7329    apply(simp_all add: fresh_atm subst_fresh forget)
7330    apply(rule exists_fresh'(1)[OF fs_name1])
7331    done
7332qed
7333
7334lemma subst_subst2:
7335  assumes a: "a\<sharp>(b,P,N)" "x\<sharp>(y,P,M)" "b\<sharp>(M,N)" "y\<sharp>P"
7336  shows "M{a:=(x).N}{y:=<b>.P} = M{y:=<b>.P}{a:=(x).N{y:=<b>.P}}"
7337using a
7338proof(nominal_induct M avoiding: a x N y b P rule: trm.strong_induct)
7339  case (Ax z c)
7340  then show ?case
7341    by (auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7342next
7343  case (Cut d M' u M'')
7344  then show ?case
7345    apply(simp add: fresh_atm fresh_prod trm.inject abs_fresh)
7346    apply(auto)
7347    apply(simp add: fresh_atm)
7348    apply(rule sym)
7349    apply(rule trans)
7350    apply(rule better_Cut_substc)
7351    apply(simp add: abs_fresh subst_fresh fresh_prod fresh_atm)
7352    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7353    apply(simp)
7354    apply(simp add: forget)
7355    apply(simp add: fresh_atm)
7356    apply(case_tac "a\<sharp>M'")
7357    apply(simp add: forget)
7358    apply(simp add: not_Ax1)
7359    apply(rule sym)
7360    apply(rule trans)
7361    apply(rule better_Cut_substc)
7362    apply(simp add: abs_fresh subst_fresh fresh_prod fresh_atm)
7363    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7364    apply(auto)[1]
7365    apply(case_tac "y\<sharp>M''")
7366    apply(simp add: forget)
7367    apply(simp add: not_Ax2)
7368    apply(simp add: forget)
7369    apply(rule sym)
7370    apply(rule trans)
7371    apply(rule better_Cut_substc)
7372    apply(simp add: subst_fresh fresh_atm)
7373    apply(simp add: abs_fresh subst_fresh)
7374    apply(auto)[1]
7375    apply(case_tac "y\<sharp>M''")
7376    apply(simp add: forget)
7377    apply(simp add: not_Ax2)
7378    apply(case_tac "a\<sharp>M'")
7379    apply(simp add: forget)
7380    apply(simp add: not_Ax1)
7381    apply(rule sym)
7382    apply(rule trans)
7383    apply(rule better_Cut_substc)
7384    apply(simp add: subst_fresh)
7385    apply(simp add: subst_fresh abs_fresh)
7386    apply(simp)
7387    apply(rule sym)
7388    apply(rule trans)
7389    apply(rule better_Cut_substc)
7390    apply(simp add: subst_fresh fresh_atm)
7391    apply(simp add: subst_fresh abs_fresh)
7392    apply(auto)[1]
7393    apply(case_tac "y\<sharp>M''")
7394    apply(simp add: forget)
7395    apply(simp add: not_Ax2)
7396    done
7397next
7398  case (NotR z M' d) 
7399  then show ?case
7400    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7401    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(y,P,N,N{y:=<b>.P},M'{d:=(x).N},M'{y:=<b>.P}{d:=(x).N{y:=<b>.P}})")
7402    apply(erule exE, simp add: fresh_prod)
7403    apply(erule conjE)+
7404    apply(simp add: fresh_fun_simp_NotR)
7405    apply(rule trans)
7406    apply(rule better_Cut_substn)
7407    apply(simp add: abs_fresh subst_fresh)
7408    apply(simp add: fresh_prod subst_fresh fresh_atm)
7409    apply(simp)
7410    apply(simp add: trm.inject alpha)
7411    apply(rule trans)
7412    apply(rule substn.simps)
7413    apply(simp add: fresh_prod fresh_atm)
7414    apply(simp add: fresh_atm)
7415    apply(rule exists_fresh'(2)[OF fs_coname1])
7416    done
7417next
7418  case (NotL d M' z) 
7419  then show ?case
7420    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7421    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(z,y,P,N,N{y:=<b>.P},M'{y:=<b>.P},M'{y:=<b>.P}{a:=(x).N{y:=<b>.P}})")
7422    apply(erule exE, simp add: fresh_prod)
7423    apply(erule conjE)+
7424    apply(simp add: fresh_fun_simp_NotL)
7425    apply(rule sym)
7426    apply(rule trans)
7427    apply(rule better_Cut_substc)
7428    apply(simp add: abs_fresh subst_fresh fresh_atm)
7429    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7430    apply(simp)
7431    apply(simp add: trm.inject alpha forget)
7432    apply(rule trans)
7433    apply(rule substc.simps)
7434    apply(simp add: fresh_prod fresh_atm)
7435    apply(simp add: fresh_atm subst_fresh)
7436    apply(simp)
7437    apply(rule exists_fresh'(1)[OF fs_name1])
7438    done
7439next
7440  case (AndR d M' e M'' f) 
7441  then show ?case
7442    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7443    apply(subgoal_tac "\<exists>a'::coname. a'\<sharp>(P,b,d,e,N,N{y:=<b>.P},M'{f:=(x).N},M''{f:=(x).N},
7444                  M'{y:=<b>.P}{f:=(x).N{y:=<b>.P}},M''{y:=<b>.P}{f:=(x).N{y:=<b>.P}})")
7445    apply(erule exE, simp add: fresh_prod)
7446    apply(erule conjE)+
7447    apply(simp add: fresh_fun_simp_AndR)
7448    apply(rule trans)
7449    apply(rule better_Cut_substn)
7450    apply(simp add: abs_fresh subst_fresh fresh_atm)
7451    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7452    apply(simp)
7453    apply(simp add: trm.inject alpha forget)
7454    apply(rule trans)
7455    apply(rule substn.simps)
7456    apply(simp add: fresh_prod fresh_atm subst_fresh)
7457    apply(simp add: fresh_atm subst_fresh)
7458    apply(simp add: fresh_atm)
7459    apply(simp)
7460    apply(rule exists_fresh'(2)[OF fs_coname1])
7461    done
7462next
7463  case (AndL1 z M' u) 
7464  then show ?case
7465    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7466    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,b,z,u,x,N,M'{y:=<b>.P},M'{y:=<b>.P}{a:=(x).N{y:=<b>.P}})")
7467    apply(erule exE, simp add: fresh_prod)
7468    apply(erule conjE)+
7469    apply(simp add: fresh_fun_simp_AndL1)
7470    apply(rule sym)
7471    apply(rule trans)
7472    apply(rule better_Cut_substc)
7473    apply(simp add: abs_fresh subst_fresh fresh_atm)
7474    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7475    apply(simp)
7476    apply(simp add: trm.inject alpha forget)
7477    apply(rule trans)
7478    apply(rule substc.simps)
7479    apply(simp add: fresh_prod fresh_atm subst_fresh)
7480    apply(simp)
7481    apply(rule exists_fresh'(1)[OF fs_name1])
7482    done
7483next
7484  case (AndL2 z M' u) 
7485  then show ?case
7486    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7487    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(P,b,z,u,x,N,M'{y:=<b>.P},M'{y:=<b>.P}{a:=(x).N{y:=<b>.P}})")
7488    apply(erule exE, simp add: fresh_prod)
7489    apply(erule conjE)+
7490    apply(simp add: fresh_fun_simp_AndL2)
7491    apply(rule sym)
7492    apply(rule trans)
7493    apply(rule better_Cut_substc)
7494    apply(simp add: abs_fresh subst_fresh fresh_atm)
7495    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7496    apply(simp)
7497    apply(simp add: trm.inject alpha forget)
7498    apply(rule trans)
7499    apply(rule substc.simps)
7500    apply(simp add: fresh_prod fresh_atm subst_fresh)
7501    apply(simp)
7502    apply(rule exists_fresh'(1)[OF fs_name1])
7503    done
7504next
7505  case (OrL u M' v M'' w) 
7506  then show ?case
7507    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7508    apply(subgoal_tac "\<exists>z'::name. z'\<sharp>(P,b,u,w,v,N,N{y:=<b>.P},M'{y:=<b>.P},M''{y:=<b>.P},
7509                  M'{y:=<b>.P}{a:=(x).N{y:=<b>.P}},M''{y:=<b>.P}{a:=(x).N{y:=<b>.P}})")
7510    apply(erule exE, simp add: fresh_prod)
7511    apply(erule conjE)+
7512    apply(simp add: fresh_fun_simp_OrL)
7513    apply(rule sym)
7514    apply(rule trans)
7515    apply(rule better_Cut_substc)
7516    apply(simp add: abs_fresh subst_fresh fresh_atm)
7517    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7518    apply(simp)
7519    apply(simp add: trm.inject alpha forget)
7520    apply(rule trans)
7521    apply(rule substc.simps)
7522    apply(simp add: fresh_prod fresh_atm subst_fresh)
7523    apply(simp add: fresh_atm subst_fresh)
7524    apply(simp add: fresh_atm)
7525    apply(simp)
7526    apply(rule exists_fresh'(1)[OF fs_name1])
7527    done
7528next
7529  case (OrR1 e M' f) 
7530  then show ?case
7531    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7532    apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(P,b,e,f,x,N,N{y:=<b>.P},
7533                                        M'{f:=(x).N},M'{y:=<b>.P}{f:=(x).N{y:=<b>.P}})")
7534    apply(erule exE, simp add: fresh_prod)
7535    apply(erule conjE)+
7536    apply(simp add: fresh_fun_simp_OrR1)
7537    apply(rule trans)
7538    apply(rule better_Cut_substn)
7539    apply(simp add: abs_fresh subst_fresh fresh_atm)
7540    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7541    apply(simp)
7542    apply(simp add: trm.inject alpha forget)
7543    apply(rule trans)
7544    apply(rule substn.simps)
7545    apply(simp add: fresh_prod fresh_atm subst_fresh)
7546    apply(simp)
7547    apply(rule exists_fresh'(2)[OF fs_coname1])
7548    done
7549next
7550  case (OrR2 e M' f) 
7551  then show ?case
7552    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7553    apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(P,b,e,f,x,N,N{y:=<b>.P},
7554                                        M'{f:=(x).N},M'{y:=<b>.P}{f:=(x).N{y:=<b>.P}})")
7555    apply(erule exE, simp add: fresh_prod)
7556    apply(erule conjE)+
7557    apply(simp add: fresh_fun_simp_OrR2)
7558    apply(rule trans)
7559    apply(rule better_Cut_substn)
7560    apply(simp add: abs_fresh subst_fresh fresh_atm)
7561    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7562    apply(simp)
7563    apply(simp add: trm.inject alpha forget)
7564    apply(rule trans)
7565    apply(rule substn.simps)
7566    apply(simp add: fresh_prod fresh_atm subst_fresh)
7567    apply(simp)
7568    apply(rule exists_fresh'(2)[OF fs_coname1])
7569    done
7570next
7571  case (ImpR x e M' f) 
7572  then show ?case
7573    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7574    apply(subgoal_tac "\<exists>c'::coname. c'\<sharp>(P,b,e,f,x,N,N{y:=<b>.P},
7575                                        M'{f:=(x).N},M'{y:=<b>.P}{f:=(x).N{y:=<b>.P}})")
7576    apply(erule exE, simp add: fresh_prod)
7577    apply(erule conjE)+
7578    apply(simp add: fresh_fun_simp_ImpR)
7579    apply(rule trans)
7580    apply(rule better_Cut_substn)
7581    apply(simp add: abs_fresh subst_fresh fresh_atm)
7582    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7583    apply(simp)
7584    apply(simp add: trm.inject alpha forget)
7585    apply(rule trans)
7586    apply(rule substn.simps)
7587    apply(simp add: fresh_prod fresh_atm subst_fresh)
7588    apply(simp add: fresh_atm)
7589    apply(simp add: fresh_atm trm.inject alpha abs_fresh fin_supp abs_supp)
7590    apply(rule exists_fresh'(2)[OF fs_coname1])
7591    apply(simp add: fresh_atm trm.inject alpha abs_fresh fin_supp abs_supp)
7592    done
7593next
7594  case (ImpL e M' v M'' w) 
7595  then show ?case
7596    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget trm.inject)
7597    apply(subgoal_tac "\<exists>z'::name. z'\<sharp>(P,b,e,w,v,N,N{y:=<b>.P},M'{w:=<b>.P},M''{w:=<b>.P},
7598                  M'{w:=<b>.P}{a:=(x).N{w:=<b>.P}},M''{w:=<b>.P}{a:=(x).N{w:=<b>.P}})")
7599    apply(erule exE, simp add: fresh_prod)
7600    apply(erule conjE)+
7601    apply(simp add: fresh_fun_simp_ImpL)
7602    apply(rule sym)
7603    apply(rule trans)
7604    apply(rule better_Cut_substc)
7605    apply(simp add: abs_fresh subst_fresh fresh_atm)
7606    apply(simp add: fresh_prod subst_fresh fresh_atm abs_fresh)
7607    apply(simp)
7608    apply(simp add: trm.inject alpha forget)
7609    apply(rule trans)
7610    apply(rule substc.simps)
7611    apply(simp add: fresh_prod fresh_atm subst_fresh)
7612    apply(simp add: fresh_atm subst_fresh)
7613    apply(simp add: fresh_atm)
7614    apply(rule exists_fresh'(1)[OF fs_name1])
7615    done
7616qed
7617
7618lemma subst_subst3:
7619  assumes a: "a\<sharp>(P,N,c)" "c\<sharp>(M,N)" "x\<sharp>(y,P,M)" "y\<sharp>(P,x)" "M\<noteq>Ax y a"
7620  shows "N{x:=<a>.M}{y:=<c>.P} = N{y:=<c>.P}{x:=<a>.(M{y:=<c>.P})}"
7621using a
7622proof(nominal_induct N avoiding: x y a c M P rule: trm.strong_induct)
7623  case (Ax z c)
7624  then show ?case
7625    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7626next
7627  case (Cut d M' u M'')
7628  then show ?case
7629    apply(simp add: fresh_atm fresh_prod trm.inject abs_fresh)
7630    apply(auto)
7631    apply(simp add: fresh_atm)
7632    apply(simp add: trm.inject)
7633    apply(rule sym)
7634    apply(rule trans)
7635    apply(rule better_Cut_substn)
7636    apply(simp add: abs_fresh subst_fresh)
7637    apply(simp add: fresh_prod subst_fresh fresh_atm)
7638    apply(subgoal_tac "P \<noteq> Ax x c")
7639    apply(simp)
7640    apply(simp add: forget)
7641    apply(clarify)
7642    apply(simp add: fresh_atm)
7643    apply(case_tac "x\<sharp>M'")
7644    apply(simp add: forget)
7645    apply(simp add: not_Ax2)
7646    apply(rule sym)
7647    apply(rule trans)
7648    apply(rule better_Cut_substn)
7649    apply(simp add: abs_fresh subst_fresh)
7650    apply(simp add: fresh_prod subst_fresh fresh_atm)
7651    apply(simp)
7652    apply(rule sym)
7653    apply(rule trans)
7654    apply(rule better_Cut_substn)
7655    apply(simp add: abs_fresh subst_fresh)
7656    apply(simp add: fresh_prod subst_fresh fresh_atm)
7657    apply(auto)
7658    apply(case_tac "y\<sharp>M'")
7659    apply(simp add: forget)
7660    apply(simp add: not_Ax2)
7661    done
7662next
7663  case NotR
7664  then show ?case
7665    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7666next
7667  case (NotL d M' u)
7668  then show ?case
7669    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7670    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(y,P,M,M{y:=<c>.P},M'{x:=<a>.M},M'{y:=<c>.P}{x:=<a>.M{y:=<c>.P}})")
7671    apply(erule exE, simp add: fresh_prod)
7672    apply(erule conjE)+
7673    apply(simp add: fresh_fun_simp_NotL)
7674    apply(rule trans)
7675    apply(rule better_Cut_substn)
7676    apply(simp add: abs_fresh subst_fresh)
7677    apply(simp add: fresh_prod subst_fresh fresh_atm)
7678    apply(simp)
7679    apply(simp add: trm.inject alpha)
7680    apply(rule trans)
7681    apply(rule substn.simps)
7682    apply(simp add: fresh_prod fresh_atm)
7683    apply(simp add: fresh_atm)
7684    apply(rule exists_fresh'(1)[OF fs_name1])
7685    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(x,y,P,M,M'{y:=<c>.P},M'{y:=<c>.P}{x:=<a>.M{y:=<c>.P}})")
7686    apply(erule exE, simp add: fresh_prod)
7687    apply(erule conjE)+
7688    apply(simp add: fresh_fun_simp_NotL)
7689    apply(rule sym)
7690    apply(rule trans)
7691    apply(rule better_Cut_substn)
7692    apply(simp add: abs_fresh subst_fresh)
7693    apply(simp add: fresh_atm subst_fresh fresh_prod)
7694    apply(subgoal_tac "P \<noteq> Ax x c")
7695    apply(simp)
7696    apply(simp add: forget trm.inject alpha)
7697    apply(rule trans)
7698    apply(rule substn.simps)
7699    apply(simp add: fresh_atm subst_fresh)
7700    apply(simp add: fresh_atm)
7701    apply(clarify)
7702    apply(simp add: fresh_atm)
7703    apply(rule exists_fresh'(1)[OF fs_name1])
7704    done
7705next
7706  case AndR
7707  then show ?case
7708    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7709next
7710  case (AndL1 u M' v)
7711  then show ?case
7712    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7713    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(u,y,v,P,M,M{y:=<c>.P},M'{x:=<a>.M},M'{y:=<c>.P}{x:=<a>.M{y:=<c>.P}})")
7714    apply(erule exE, simp add: fresh_prod)
7715    apply(erule conjE)+
7716    apply(simp add: fresh_fun_simp_AndL1)
7717    apply(rule trans)
7718    apply(rule better_Cut_substn)
7719    apply(simp add: abs_fresh subst_fresh)
7720    apply(simp add: fresh_prod subst_fresh fresh_atm)
7721    apply(simp)
7722    apply(simp add: trm.inject alpha)
7723    apply(rule trans)
7724    apply(rule substn.simps)
7725    apply(simp add: fresh_prod fresh_atm)
7726    apply(simp add: fresh_atm)
7727    apply(rule exists_fresh'(1)[OF fs_name1])
7728    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(x,y,u,v,P,M,M'{y:=<c>.P},M'{y:=<c>.P}{x:=<a>.M{y:=<c>.P}})")
7729    apply(erule exE, simp add: fresh_prod)
7730    apply(erule conjE)+
7731    apply(simp add: fresh_fun_simp_AndL1)
7732    apply(rule sym)
7733    apply(rule trans)
7734    apply(rule better_Cut_substn)
7735    apply(simp add: abs_fresh subst_fresh)
7736    apply(simp add: fresh_atm subst_fresh fresh_prod)
7737    apply(subgoal_tac "P \<noteq> Ax x c")
7738    apply(simp)
7739    apply(simp add: forget trm.inject alpha)
7740    apply(rule trans)
7741    apply(rule substn.simps)
7742    apply(simp add: fresh_atm subst_fresh)
7743    apply(simp add: fresh_atm)
7744    apply(clarify)
7745    apply(simp add: fresh_atm)
7746    apply(rule exists_fresh'(1)[OF fs_name1])
7747    done
7748next
7749  case (AndL2 u M' v)
7750  then show ?case
7751    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7752    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(u,y,v,P,M,M{y:=<c>.P},M'{x:=<a>.M},M'{y:=<c>.P}{x:=<a>.M{y:=<c>.P}})")
7753    apply(erule exE, simp add: fresh_prod)
7754    apply(erule conjE)+
7755    apply(simp add: fresh_fun_simp_AndL2)
7756    apply(rule trans)
7757    apply(rule better_Cut_substn)
7758    apply(simp add: abs_fresh subst_fresh)
7759    apply(simp add: fresh_prod subst_fresh fresh_atm)
7760    apply(simp)
7761    apply(simp add: trm.inject alpha)
7762    apply(rule trans)
7763    apply(rule substn.simps)
7764    apply(simp add: fresh_prod fresh_atm)
7765    apply(simp add: fresh_atm)
7766    apply(rule exists_fresh'(1)[OF fs_name1])
7767    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(x,y,u,v,P,M,M'{y:=<c>.P},M'{y:=<c>.P}{x:=<a>.M{y:=<c>.P}})")
7768    apply(erule exE, simp add: fresh_prod)
7769    apply(erule conjE)+
7770    apply(simp add: fresh_fun_simp_AndL2)
7771    apply(rule sym)
7772    apply(rule trans)
7773    apply(rule better_Cut_substn)
7774    apply(simp add: abs_fresh subst_fresh)
7775    apply(simp add: fresh_atm subst_fresh fresh_prod)
7776    apply(subgoal_tac "P \<noteq> Ax x c")
7777    apply(simp)
7778    apply(simp add: forget trm.inject alpha)
7779    apply(rule trans)
7780    apply(rule substn.simps)
7781    apply(simp add: fresh_atm subst_fresh)
7782    apply(simp add: fresh_atm)
7783    apply(clarify)
7784    apply(simp add: fresh_atm)
7785    apply(rule exists_fresh'(1)[OF fs_name1])
7786    done
7787next
7788  case OrR1
7789  then show ?case
7790    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7791next
7792  case OrR2
7793  then show ?case
7794    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7795next
7796  case (OrL x1 M' x2 M'' x3)
7797  then show ?case
7798    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7799    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(y,P,M,M{y:=<c>.P},M'{x:=<a>.M},M'{y:=<c>.P}{x:=<a>.M{y:=<c>.P}},
7800                                      x1,x2,x3,M''{x:=<a>.M},M''{y:=<c>.P}{x:=<a>.M{y:=<c>.P}})")
7801    apply(erule exE, simp add: fresh_prod)
7802    apply(erule conjE)+
7803    apply(simp add: fresh_fun_simp_OrL)
7804    apply(rule trans)
7805    apply(rule better_Cut_substn)
7806    apply(simp add: abs_fresh subst_fresh)
7807    apply(simp add: fresh_prod subst_fresh fresh_atm)
7808    apply(simp)
7809    apply(simp add: trm.inject alpha)
7810    apply(rule trans)
7811    apply(rule substn.simps)
7812    apply(simp add: fresh_prod fresh_atm subst_fresh)
7813    apply(simp add: fresh_prod fresh_atm subst_fresh)
7814    apply(simp add: fresh_atm)
7815    apply(simp add: fresh_atm)
7816    apply(rule exists_fresh'(1)[OF fs_name1])
7817    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(x,y,P,M,M'{y:=<c>.P},M'{y:=<c>.P}{x:=<a>.M{y:=<c>.P}},
7818                                      x1,x2,x3,M''{y:=<c>.P},M''{y:=<c>.P}{x:=<a>.M{y:=<c>.P}})")
7819    apply(erule exE, simp add: fresh_prod)
7820    apply(erule conjE)+
7821    apply(simp add: fresh_fun_simp_OrL)
7822    apply(rule sym)
7823    apply(rule trans)
7824    apply(rule better_Cut_substn)
7825    apply(simp add: abs_fresh subst_fresh)
7826    apply(simp add: fresh_atm subst_fresh fresh_prod)
7827    apply(simp add: fresh_prod fresh_atm)
7828    apply(auto)
7829    apply(simp add: fresh_atm)
7830    apply(simp add: forget trm.inject alpha)
7831    apply(rule trans)
7832    apply(rule substn.simps)
7833    apply(simp add: fresh_atm subst_fresh)
7834    apply(simp add: fresh_atm subst_fresh)
7835    apply(simp add: fresh_atm)
7836    apply(simp add: fresh_atm)
7837    apply(rule exists_fresh'(1)[OF fs_name1])
7838    done
7839next
7840  case ImpR
7841  then show ?case
7842    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7843next
7844  case (ImpL d M' x1 M'' x2)
7845  then show ?case
7846    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7847    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(y,P,M,M{y:=<c>.P},M'{x2:=<a>.M},M'{y:=<c>.P}{x2:=<a>.M{y:=<c>.P}},
7848                                      x1,x2,M''{x2:=<a>.M},M''{y:=<c>.P}{x2:=<a>.M{y:=<c>.P}})")
7849    apply(erule exE, simp add: fresh_prod)
7850    apply(erule conjE)+
7851    apply(simp add: fresh_fun_simp_ImpL)
7852    apply(rule trans)
7853    apply(rule better_Cut_substn)
7854    apply(simp add: abs_fresh subst_fresh)
7855    apply(simp add: fresh_prod subst_fresh fresh_atm)
7856    apply(simp)
7857    apply(simp add: trm.inject alpha)
7858    apply(rule trans)
7859    apply(rule substn.simps)
7860    apply(simp add: fresh_prod fresh_atm subst_fresh)
7861    apply(simp add: fresh_prod fresh_atm subst_fresh)
7862    apply(simp add: fresh_atm)
7863    apply(rule exists_fresh'(1)[OF fs_name1])
7864    apply(subgoal_tac "\<exists>x'::name. x'\<sharp>(x,y,P,M,M'{x2:=<c>.P},M'{x2:=<c>.P}{x:=<a>.M{x2:=<c>.P}},
7865                                      x1,x2,M''{x2:=<c>.P},M''{x2:=<c>.P}{x:=<a>.M{x2:=<c>.P}})")
7866    apply(erule exE, simp add: fresh_prod)
7867    apply(erule conjE)+
7868    apply(simp add: fresh_fun_simp_ImpL)
7869    apply(rule sym)
7870    apply(rule trans)
7871    apply(rule better_Cut_substn)
7872    apply(simp add: abs_fresh subst_fresh)
7873    apply(simp add: fresh_atm subst_fresh fresh_prod)
7874    apply(simp add: fresh_prod fresh_atm)
7875    apply(auto)
7876    apply(simp add: fresh_atm)
7877    apply(simp add: forget trm.inject alpha)
7878    apply(rule trans)
7879    apply(rule substn.simps)
7880    apply(simp add: fresh_atm subst_fresh)
7881    apply(simp add: fresh_atm subst_fresh)
7882    apply(simp add: fresh_atm)
7883    apply(rule exists_fresh'(1)[OF fs_name1])
7884    done
7885qed
7886
7887lemma subst_subst4:
7888  assumes a: "x\<sharp>(P,N,y)" "y\<sharp>(M,N)" "a\<sharp>(c,P,M)" "c\<sharp>(P,a)" "M\<noteq>Ax x c"
7889  shows "N{a:=(x).M}{c:=(y).P} = N{c:=(y).P}{a:=(x).(M{c:=(y).P})}"
7890using a
7891proof(nominal_induct N avoiding: x y a c M P rule: trm.strong_induct)
7892  case (Ax z c)
7893  then show ?case
7894    by (auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7895next
7896  case (Cut d M' u M'')
7897  then show ?case
7898    apply(simp add: fresh_atm fresh_prod trm.inject abs_fresh)
7899    apply(auto)
7900    apply(simp add: fresh_atm)
7901    apply(simp add: trm.inject)
7902    apply(rule sym)
7903    apply(rule trans)
7904    apply(rule better_Cut_substc)
7905    apply(simp add: abs_fresh subst_fresh fresh_atm)
7906    apply(simp add: fresh_prod subst_fresh abs_fresh fresh_atm)
7907    apply(subgoal_tac "P \<noteq> Ax y a")
7908    apply(simp)
7909    apply(simp add: forget)
7910    apply(clarify)
7911    apply(simp add: fresh_atm)
7912    apply(case_tac "a\<sharp>M''")
7913    apply(simp add: forget)
7914    apply(simp add: not_Ax1)
7915    apply(rule sym)
7916    apply(rule trans)
7917    apply(rule better_Cut_substc)
7918    apply(simp add: fresh_prod subst_fresh fresh_atm)
7919    apply(simp add: abs_fresh subst_fresh)
7920    apply(simp)
7921    apply(rule sym)
7922    apply(rule trans)
7923    apply(rule better_Cut_substc)
7924    apply(simp add: fresh_prod subst_fresh fresh_atm)
7925    apply(simp add: abs_fresh subst_fresh)
7926    apply(auto)
7927    apply(case_tac "c\<sharp>M''")
7928    apply(simp add: forget)
7929    apply(simp add: not_Ax1)
7930    done
7931next
7932  case NotL
7933  then show ?case
7934    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7935next
7936  case (NotR u M' d)
7937  then show ?case
7938    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7939    apply(generate_fresh "coname")
7940    apply(fresh_fun_simp)
7941    apply(fresh_fun_simp)
7942    apply(simp add: abs_fresh subst_fresh)
7943    apply(rule trans)
7944    apply(rule better_Cut_substc)
7945    apply(simp)
7946    apply(simp add: abs_fresh)
7947    apply(simp)
7948    apply(simp add: trm.inject alpha)
7949    apply(rule trans)
7950    apply(rule substc.simps)
7951    apply(simp add: fresh_prod fresh_atm)
7952    apply(auto simp add: fresh_atm fresh_prod)[1]
7953    apply(generate_fresh "coname")
7954    apply(fresh_fun_simp)
7955    apply(fresh_fun_simp)
7956    apply(rule sym)
7957    apply(rule trans)
7958    apply(rule better_Cut_substc)
7959    apply(simp add: fresh_prod fresh_atm subst_fresh)
7960    apply(simp add: abs_fresh subst_fresh)
7961    apply(auto simp add: fresh_atm)
7962    apply(simp add: trm.inject alpha forget)
7963    apply(rule trans)
7964    apply(rule substc.simps)
7965    apply(simp add: fresh_atm subst_fresh)
7966    apply(auto simp add: fresh_prod fresh_atm) 
7967    done
7968next
7969  case AndL1
7970  then show ?case
7971    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7972next
7973  case AndL2
7974  then show ?case
7975    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7976next
7977  case (AndR d M e M' f)
7978  then show ?case
7979    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
7980    apply(generate_fresh "coname")
7981    apply(fresh_fun_simp)
7982    apply(fresh_fun_simp)
7983    apply(simp add: abs_fresh subst_fresh)
7984    apply(rule trans)
7985    apply(rule better_Cut_substc)
7986    apply(simp)
7987    apply(simp add: abs_fresh)
7988    apply(simp)
7989    apply(simp add: trm.inject alpha)
7990    apply(rule trans)
7991    apply(rule substc.simps)
7992    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
7993    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
7994    apply(simp)
7995    apply(auto simp add: fresh_atm fresh_prod)[1]
7996    apply(generate_fresh "coname")
7997    apply(fresh_fun_simp)
7998    apply(fresh_fun_simp)
7999    apply(rule sym)
8000    apply(rule trans)
8001    apply(rule better_Cut_substc)
8002    apply(simp add: subst_fresh fresh_atm fresh_prod)
8003    apply(simp add: abs_fresh subst_fresh)
8004    apply(auto simp add: fresh_atm)[1]
8005    apply(simp add: trm.inject alpha forget)
8006    apply(rule trans)
8007    apply(rule substc.simps)
8008    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8009    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8010    apply(simp)
8011    apply(auto simp add: fresh_atm fresh_prod)[1]
8012    done
8013next
8014  case OrL
8015  then show ?case
8016    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
8017next
8018  case (OrR1 d M' e)
8019  then show ?case
8020    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
8021    apply(generate_fresh "coname")
8022    apply(fresh_fun_simp)
8023    apply(fresh_fun_simp)
8024    apply(simp add: abs_fresh subst_fresh)
8025    apply(rule trans)
8026    apply(rule better_Cut_substc)
8027    apply(simp)
8028    apply(simp add: abs_fresh)
8029    apply(simp)
8030    apply(simp add: trm.inject alpha)
8031    apply(rule trans)
8032    apply(rule substc.simps)
8033    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8034    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8035    apply(generate_fresh "coname")
8036    apply(fresh_fun_simp)
8037    apply(fresh_fun_simp)
8038    apply(rule sym)
8039    apply(rule trans)
8040    apply(rule better_Cut_substc)
8041    apply(simp add: subst_fresh fresh_atm fresh_prod)
8042    apply(simp add: abs_fresh subst_fresh)
8043    apply(auto simp add: fresh_atm)[1]
8044    apply(simp add: trm.inject alpha forget)
8045    apply(rule trans)
8046    apply(rule substc.simps)
8047    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8048    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8049    done
8050next
8051  case (OrR2 d M' e)
8052  then show ?case
8053    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
8054    apply(generate_fresh "coname")
8055    apply(fresh_fun_simp)
8056    apply(fresh_fun_simp)
8057    apply(simp add: abs_fresh subst_fresh)
8058    apply(rule trans)
8059    apply(rule better_Cut_substc)
8060    apply(simp)
8061    apply(simp add: abs_fresh)
8062    apply(simp)
8063    apply(simp add: trm.inject alpha)
8064    apply(rule trans)
8065    apply(rule substc.simps)
8066    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8067    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8068    apply(generate_fresh "coname")
8069    apply(fresh_fun_simp)
8070    apply(fresh_fun_simp)
8071    apply(rule sym)
8072    apply(rule trans)
8073    apply(rule better_Cut_substc)
8074    apply(simp add: subst_fresh fresh_atm fresh_prod)
8075    apply(simp add: abs_fresh subst_fresh)
8076    apply(auto simp add: fresh_atm)[1]
8077    apply(simp add: trm.inject alpha forget)
8078    apply(rule trans)
8079    apply(rule substc.simps)
8080    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8081    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8082    done
8083next
8084  case ImpL
8085  then show ?case
8086    by(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
8087next
8088  case (ImpR u d M' e)
8089  then show ?case
8090    apply(auto simp add: subst_fresh abs_fresh fresh_atm fresh_prod forget)
8091    apply(generate_fresh "coname")
8092    apply(fresh_fun_simp)
8093    apply(fresh_fun_simp)
8094    apply(simp add: abs_fresh subst_fresh)
8095    apply(rule trans)
8096    apply(rule better_Cut_substc)
8097    apply(simp)
8098    apply(simp add: abs_fresh)
8099    apply(simp)
8100    apply(simp add: trm.inject alpha)
8101    apply(rule trans)
8102    apply(rule substc.simps)
8103    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8104    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8105    apply(auto simp add: fresh_prod fresh_atm subst_fresh abs_fresh abs_supp fin_supp)[1]
8106    apply(generate_fresh "coname")
8107    apply(fresh_fun_simp)
8108    apply(fresh_fun_simp)
8109    apply(rule sym)
8110    apply(rule trans)
8111    apply(rule better_Cut_substc)
8112    apply(simp add: subst_fresh fresh_atm fresh_prod)
8113    apply(simp add: abs_fresh subst_fresh)
8114    apply(auto simp add: fresh_atm)[1]
8115    apply(simp add: trm.inject alpha forget)
8116    apply(rule trans)
8117    apply(rule substc.simps)
8118    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8119    apply(auto simp add: fresh_prod fresh_atm subst_fresh)[1]
8120    apply(auto simp add: fresh_prod fresh_atm subst_fresh abs_fresh abs_supp fin_supp)[1]
8121    apply(auto simp add: fresh_prod fresh_atm subst_fresh abs_fresh abs_supp fin_supp)[1]
8122    done
8123qed
8124
8125end
8126