153 case (t_Lam x \<Gamma>1 T1 t T2) (* lambda case *) |
153 case (t_Lam x \<Gamma>1 T1 t T2) (* lambda case *) |
154 have fc0: "x\<sharp>\<Gamma>1" by fact |
154 have fc0: "x\<sharp>\<Gamma>1" by fact |
155 have ih: "\<And>\<Gamma>3. \<lbrakk>valid \<Gamma>3; (x,T1)#\<Gamma>1 \<subseteq> \<Gamma>3\<rbrakk> \<Longrightarrow> \<Gamma>3 \<turnstile> t : T2" by fact |
155 have ih: "\<And>\<Gamma>3. \<lbrakk>valid \<Gamma>3; (x,T1)#\<Gamma>1 \<subseteq> \<Gamma>3\<rbrakk> \<Longrightarrow> \<Gamma>3 \<turnstile> t : T2" by fact |
156 obtain c::"name" where fc1: "c\<sharp>(x,t,\<Gamma>1,\<Gamma>2)" (* we obtain a fresh name *) |
156 obtain c::"name" where fc1: "c\<sharp>(x,t,\<Gamma>1,\<Gamma>2)" (* we obtain a fresh name *) |
157 by (rule exists_fresh) (auto simp add: fs_name1) |
157 by (rule exists_fresh) (auto simp add: fs_name1) |
158 have "Lam [c].([(c,x)]\<bullet>t) = Lam [x].t" using fc1 (* we alpha-rename the lambda-abstraction *) |
158 have "Lam [c].([(c,x)]\<bullet>t) = Lam [x].t" using fc1 (* we then alpha-rename the lambda-abstraction *) |
159 by (auto simp add: lam.inject alpha fresh_prod fresh_atm) |
159 by (auto simp add: lam.inject alpha fresh_prod fresh_atm) |
160 moreover |
160 moreover |
161 have "\<Gamma>2 \<turnstile> Lam [c].([(c,x)]\<bullet>t) : T1 \<rightarrow> T2" (* we can then alpha-rename our original goal *) |
161 have "\<Gamma>2 \<turnstile> Lam [c].([(c,x)]\<bullet>t) : T1 \<rightarrow> T2" (* we can then alpha-rename our original goal *) |
162 proof - |
162 proof - |
163 (* we establish (x,T1)#\<Gamma>1 \<subseteq> (x,T1)#([(c,x)]\<bullet>\<Gamma>2) and valid ((x,T1)#([(c,x)]\<bullet>\<Gamma>2)) *) |
163 (* we establish (x,T1)#\<Gamma>1 \<subseteq> (x,T1)#([(c,x)]\<bullet>\<Gamma>2) and valid ((x,T1)#([(c,x)]\<bullet>\<Gamma>2)) *) |
175 then show "valid ((x,T1)#([(c,x)]\<bullet>\<Gamma>2))" using fc1 |
175 then show "valid ((x,T1)#([(c,x)]\<bullet>\<Gamma>2))" using fc1 |
176 by (auto intro!: v2 simp add: fresh_left calc_atm eqvts) |
176 by (auto intro!: v2 simp add: fresh_left calc_atm eqvts) |
177 qed |
177 qed |
178 (* these two facts give us by induction hypothesis the following *) |
178 (* these two facts give us by induction hypothesis the following *) |
179 ultimately have "(x,T1)#([(c,x)]\<bullet>\<Gamma>2) \<turnstile> t : T2" using ih by simp |
179 ultimately have "(x,T1)#([(c,x)]\<bullet>\<Gamma>2) \<turnstile> t : T2" using ih by simp |
180 (* we now apply renamings to get our goal *) |
180 (* we now apply renamings to get to our goal *) |
181 then have "[(c,x)]\<bullet>((x,T1)#([(c,x)]\<bullet>\<Gamma>2) \<turnstile> t : T2)" by (rule perm_boolI) |
181 then have "[(c,x)]\<bullet>((x,T1)#([(c,x)]\<bullet>\<Gamma>2) \<turnstile> t : T2)" by (rule perm_boolI) |
182 then have "(c,T1)#\<Gamma>2 \<turnstile> ([(c,x)]\<bullet>t) : T2" using fc1 |
182 then have "(c,T1)#\<Gamma>2 \<turnstile> ([(c,x)]\<bullet>t) : T2" using fc1 |
183 by (perm_simp add: eqvts calc_atm perm_fresh_fresh ty_fresh) |
183 by (perm_simp add: eqvts calc_atm perm_fresh_fresh ty_fresh) |
184 then show "\<Gamma>2 \<turnstile> Lam [c].([(c,x)]\<bullet>t) : T1 \<rightarrow> T2" using fc1 by auto |
184 then show "\<Gamma>2 \<turnstile> Lam [c].([(c,x)]\<bullet>t) : T1 \<rightarrow> T2" using fc1 by auto |
185 qed |
185 qed |
186 ultimately show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" by simp |
186 ultimately show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" by simp |
187 qed (auto) |
187 qed (auto) |
188 |
188 |
|
189 text {* |
|
190 Compare the proof with explicit renamings to version1 and version2, |
|
191 and imagine you are proving something more substantial than the |
|
192 weakening lemma. *} |
|
193 |
189 end |
194 end |