112 nominal_primrec |
110 nominal_primrec |
113 ftv_tyS :: "tyS \<Rightarrow> tvar list" |
111 ftv_tyS :: "tyS \<Rightarrow> tvar list" |
114 where |
112 where |
115 "ftv_tyS (Ty T) = ((ftv (T::ty))::tvar list)" |
113 "ftv_tyS (Ty T) = ((ftv (T::ty))::tvar list)" |
116 | "ftv_tyS (\<forall>[X].S) = (ftv_tyS S) - [X]" |
114 | "ftv_tyS (\<forall>[X].S) = (ftv_tyS S) - [X]" |
117 apply(finite_guess add: ftv_ty_eqvt fs_tvar1)+ |
115 apply(finite_guess add: ftv_ty_eqvt fs_tvar1 | rule TrueI)+ |
118 apply(rule TrueI)+ |
116 apply (metis difference_fresh list.set_intros(1)) |
119 apply(rule difference_fresh) |
|
120 apply(simp) |
|
121 apply(fresh_guess add: ftv_ty_eqvt fs_tvar1)+ |
117 apply(fresh_guess add: ftv_ty_eqvt fs_tvar1)+ |
122 done |
118 done |
123 |
119 |
124 end |
120 end |
125 |
121 |
126 lemma ftv_tyS_eqvt[eqvt]: |
122 lemma ftv_tyS_eqvt[eqvt]: |
127 fixes pi::"tvar prm" |
123 fixes pi::"tvar prm" |
128 and S::"tyS" |
124 and S::"tyS" |
129 shows "pi\<bullet>(ftv S) = ftv (pi\<bullet>S)" |
125 shows "pi\<bullet>(ftv S) = ftv (pi\<bullet>S)" |
130 apply(nominal_induct S rule: tyS.strong_induct) |
126 proof (nominal_induct S rule: tyS.strong_induct) |
131 apply(simp add: eqvts) |
127 case (Ty ty) |
132 apply(simp only: ftv_tyS.simps) |
128 then show ?case |
133 apply(simp only: eqvts) |
129 by (simp add: ftv_ty_eqvt) |
134 apply(simp add: eqvts) |
130 next |
135 done |
131 case (ALL tvar tyS) |
|
132 then show ?case |
|
133 by (metis difference_eqvt_tvar ftv_ty.simps(1) ftv_tyS.simps(2) ftv_ty_eqvt ty.perm(3) tyS.perm(4)) |
|
134 qed |
136 |
135 |
137 lemma ftv_Ctxt_eqvt[eqvt]: |
136 lemma ftv_Ctxt_eqvt[eqvt]: |
138 fixes pi::"tvar prm" |
137 fixes pi::"tvar prm" |
139 and \<Gamma>::"Ctxt" |
138 and \<Gamma>::"Ctxt" |
140 shows "pi\<bullet>(ftv \<Gamma>) = ftv (pi\<bullet>\<Gamma>)" |
139 shows "pi\<bullet>(ftv \<Gamma>) = ftv (pi\<bullet>\<Gamma>)" |
141 by (induct \<Gamma>) (auto simp add: eqvts) |
140 by (induct \<Gamma>) (auto simp add: eqvts) |
142 |
141 |
143 text \<open>Valid\<close> |
142 text \<open>Valid\<close> |
144 inductive |
143 inductive |
145 valid :: "Ctxt \<Rightarrow> bool" |
144 valid :: "Ctxt \<Rightarrow> bool" |
146 where |
145 where |
181 abbreviation |
180 abbreviation |
182 subst :: "'a \<Rightarrow> tvar \<Rightarrow> ty \<Rightarrow> 'a" ("_[_::=_]" [100,100,100] 100) |
181 subst :: "'a \<Rightarrow> tvar \<Rightarrow> ty \<Rightarrow> 'a" ("_[_::=_]" [100,100,100] 100) |
183 where |
182 where |
184 "smth[X::=T] \<equiv> ([(X,T)])<smth>" |
183 "smth[X::=T] \<equiv> ([(X,T)])<smth>" |
185 |
184 |
186 fun |
185 fun lookup :: "Subst \<Rightarrow> tvar \<Rightarrow> ty" |
187 lookup :: "Subst \<Rightarrow> tvar \<Rightarrow> ty" |
|
188 where |
186 where |
189 "lookup [] X = TVar X" |
187 "lookup [] X = TVar X" |
190 | "lookup ((Y,T)#\<theta>) X = (if X=Y then T else lookup \<theta> X)" |
188 | "lookup ((Y,T)#\<theta>) X = (if X=Y then T else lookup \<theta> X)" |
191 |
189 |
192 lemma lookup_eqvt[eqvt]: |
190 lemma lookup_eqvt[eqvt]: |
193 fixes pi::"tvar prm" |
191 fixes pi::"tvar prm" |
194 shows "pi\<bullet>(lookup \<theta> X) = lookup (pi\<bullet>\<theta>) (pi\<bullet>X)" |
192 shows "pi\<bullet>(lookup \<theta> X) = lookup (pi\<bullet>\<theta>) (pi\<bullet>X)" |
195 by (induct \<theta>) (auto simp add: eqvts) |
193 by (induct \<theta>) (auto simp add: eqvts) |
196 |
194 |
197 lemma lookup_fresh: |
195 lemma lookup_fresh: |
198 fixes X::"tvar" |
196 fixes X::"tvar" |
199 assumes a: "X\<sharp>\<theta>" |
197 assumes a: "X\<sharp>\<theta>" |
200 shows "lookup \<theta> X = TVar X" |
198 shows "lookup \<theta> X = TVar X" |
201 using a |
199 using a |
202 by (induct \<theta>) |
200 by (induct \<theta>) |
203 (auto simp add: fresh_list_cons fresh_prod fresh_atm) |
201 (auto simp add: fresh_list_cons fresh_prod fresh_atm) |
204 |
202 |
205 overloading |
203 overloading |
206 psubst_ty \<equiv> "psubst :: Subst \<Rightarrow> ty \<Rightarrow> ty" |
204 psubst_ty \<equiv> "psubst :: Subst \<Rightarrow> ty \<Rightarrow> ty" |
207 begin |
205 begin |
208 |
206 |
328 and T'::"ty" |
324 and T'::"ty" |
329 and T::"ty" |
325 and T::"ty" |
330 assumes a: "X\<sharp>\<theta>" |
326 assumes a: "X\<sharp>\<theta>" |
331 shows "\<theta><T[X::=T']> = (\<theta><T>)[X::=\<theta><T'>]" |
327 shows "\<theta><T[X::=T']> = (\<theta><T>)[X::=\<theta><T'>]" |
332 using a |
328 using a |
333 apply(nominal_induct T avoiding: \<theta> X T' rule: ty.strong_induct) |
329 proof (nominal_induct T avoiding: \<theta> X T' rule: ty.strong_induct) |
334 apply(auto simp add: ty.inject lookup_fresh) |
330 case (TVar tvar) |
335 apply(rule sym) |
331 then show ?case |
336 apply(rule subst_forget_ty) |
332 by (simp add: fresh_atm(1) fresh_lookup lookup_fresh subst_forget_ty) |
337 apply(rule fresh_lookup) |
333 qed auto |
338 apply(simp_all add: fresh_atm) |
|
339 done |
|
340 |
334 |
341 lemma general_preserved: |
335 lemma general_preserved: |
342 fixes \<theta>::"Subst" |
336 fixes \<theta>::"Subst" |
343 assumes a: "T \<prec> S" |
337 assumes a: "T \<prec> S" |
344 shows "\<theta><T> \<prec> \<theta><S>" |
338 shows "\<theta><T> \<prec> \<theta><S>" |
345 using a |
339 using a |
346 apply(nominal_induct T S avoiding: \<theta> rule: inst.strong_induct) |
340 proof (nominal_induct T S avoiding: \<theta> rule: inst.strong_induct) |
347 apply(auto)[1] |
341 case (I_Ty T) |
348 apply(simp add: psubst_ty_lemma) |
342 then show ?case |
349 apply(rule_tac I_All) |
343 by (simp add: inst.I_Ty) |
350 apply(simp add: fresh_psubst_ty) |
344 next |
351 apply(simp) |
345 case (I_All X T' T S) |
352 done |
346 then show ?case |
|
347 by (simp add: fresh_psubst_ty inst.I_All psubst_ty_lemma) |
|
348 qed |
353 |
349 |
354 |
350 |
355 text\<open>typing judgements\<close> |
351 text\<open>typing judgements\<close> |
356 inductive |
352 inductive |
357 typing :: "Ctxt \<Rightarrow> trm \<Rightarrow> ty \<Rightarrow> bool" (" _ \<turnstile> _ : _ " [60,60,60] 60) |
353 typing :: "Ctxt \<Rightarrow> trm \<Rightarrow> ty \<Rightarrow> bool" (" _ \<turnstile> _ : _ " [60,60,60] 60) |
384 (auto simp add: tyS.supp abs_supp ftv_ty) |
380 (auto simp add: tyS.supp abs_supp ftv_ty) |
385 |
381 |
386 lemma ftv_Ctxt: |
382 lemma ftv_Ctxt: |
387 fixes \<Gamma>::"Ctxt" |
383 fixes \<Gamma>::"Ctxt" |
388 shows "supp \<Gamma> = set (ftv \<Gamma>)" |
384 shows "supp \<Gamma> = set (ftv \<Gamma>)" |
389 apply (induct \<Gamma>) |
385 proof (induct \<Gamma>) |
390 apply (simp_all add: supp_list_nil supp_list_cons) |
386 case Nil |
391 apply (rename_tac a \<Gamma>') |
387 then show ?case |
392 apply (case_tac a) |
388 by (simp add: supp_list_nil) |
393 apply (simp add: supp_prod supp_atm ftv_tyS) |
389 next |
394 done |
390 case (Cons c \<Gamma>) |
395 |
391 show ?case |
396 lemma ftv_tvars: |
392 proof (cases c) |
|
393 case (Pair a b) |
|
394 with Cons show ?thesis |
|
395 by (simp add: ftv_tyS supp_atm(3) supp_list_cons supp_prod) |
|
396 qed |
|
397 qed |
|
398 |
|
399 lemma ftv_tvars: |
397 fixes Tvs::"tvar list" |
400 fixes Tvs::"tvar list" |
398 shows "supp Tvs = set Tvs" |
401 shows "supp Tvs = set Tvs" |
399 by (induct Tvs) |
402 by (induct Tvs) (simp_all add: supp_list_nil supp_list_cons supp_atm) |
400 (simp_all add: supp_list_nil supp_list_cons supp_atm) |
|
401 |
403 |
402 lemma difference_supp: |
404 lemma difference_supp: |
403 fixes xs ys::"tvar list" |
405 fixes xs ys::"tvar list" |
404 shows "((supp (xs - ys))::tvar set) = supp xs - supp ys" |
406 shows "((supp (xs - ys))::tvar set) = supp xs - supp ys" |
405 by (induct xs) |
407 by (induct xs) (auto simp add: supp_list_nil supp_list_cons ftv_tvars) |
406 (auto simp add: supp_list_nil supp_list_cons ftv_tvars) |
|
407 |
408 |
408 lemma set_supp_eq: |
409 lemma set_supp_eq: |
409 fixes xs::"tvar list" |
410 fixes xs::"tvar list" |
410 shows "set xs = supp xs" |
411 shows "set xs = supp xs" |
411 by (induct xs) |
412 by (induct xs) (simp_all add: supp_list_nil supp_list_cons supp_atm) |
412 (simp_all add: supp_list_nil supp_list_cons supp_atm) |
|
413 |
413 |
414 nominal_inductive2 typing |
414 nominal_inductive2 typing |
415 avoids T_LET: "set (ftv T\<^sub>1 - ftv \<Gamma>)" |
415 avoids T_LET: "set (ftv T\<^sub>1 - ftv \<Gamma>)" |
416 apply (simp add: fresh_star_def fresh_def ftv_Ctxt) |
416 apply (simp_all add: fresh_star_def fresh_def ftv_Ctxt fresh_tvar_trm) |
417 apply (simp add: fresh_star_def fresh_tvar_trm) |
417 by (meson fresh_def fresh_tvar_trm) |
418 apply assumption |
418 |
419 apply simp |
|
420 done |
|
421 |
419 |
422 lemma perm_fresh_fresh_aux: |
420 lemma perm_fresh_fresh_aux: |
423 "\<forall>(x,y)\<in>set (pi::tvar prm). x \<sharp> z \<and> y \<sharp> z \<Longrightarrow> pi \<bullet> (z::'a::pt_tvar) = z" |
421 "\<forall>(x,y)\<in>set (pi::tvar prm). x \<sharp> z \<and> y \<sharp> z \<Longrightarrow> pi \<bullet> (z::'a::pt_tvar) = z" |
424 apply (induct pi rule: rev_induct) |
422 proof (induct pi rule: rev_induct) |
425 apply simp |
423 case Nil |
|
424 then show ?case |
|
425 by simp |
|
426 next |
|
427 case (snoc x xs) |
|
428 then show ?case |
426 apply (simp add: split_paired_all pt_tvar2) |
429 apply (simp add: split_paired_all pt_tvar2) |
427 apply (frule_tac x="(a, b)" in bspec) |
430 using perm_fresh_fresh(1) by fastforce |
428 apply simp |
431 qed |
429 apply (simp add: perm_fresh_fresh) |
|
430 done |
|
431 |
432 |
432 lemma freshs_mem: |
433 lemma freshs_mem: |
433 fixes S::"tvar set" |
434 fixes S::"tvar set" |
434 assumes "x \<in> S" |
435 assumes "x \<in> S" |
435 and "S \<sharp>* z" |
436 and "S \<sharp>* z" |
436 shows "x \<sharp> z" |
437 shows "x \<sharp> z" |
437 using assms by (simp add: fresh_star_def) |
438 using assms by (simp add: fresh_star_def) |
438 |
439 |
439 lemma fresh_gen_set: |
440 lemma fresh_gen_set: |
440 fixes X::"tvar" |
441 fixes X::"tvar" |
441 and Xs::"tvar list" |
442 and Xs::"tvar list" |
442 assumes asm: "X\<in>set Xs" |
443 assumes "X\<in>set Xs" |
443 shows "X\<sharp>gen T Xs" |
444 shows "X\<sharp>gen T Xs" |
444 using asm |
445 using assms by (induct Xs) (auto simp: abs_fresh) |
445 apply(induct Xs) |
|
446 apply(simp) |
|
447 apply(rename_tac a Xs') |
|
448 apply(case_tac "X=a") |
|
449 apply(simp add: abs_fresh) |
|
450 apply(simp add: abs_fresh) |
|
451 done |
|
452 |
446 |
453 lemma close_fresh: |
447 lemma close_fresh: |
454 fixes \<Gamma>::"Ctxt" |
448 fixes \<Gamma>::"Ctxt" |
455 shows "\<forall>(X::tvar)\<in>set ((ftv T) - (ftv \<Gamma>)). X\<sharp>(close \<Gamma> T)" |
449 shows "\<forall>(X::tvar)\<in>set ((ftv T) - (ftv \<Gamma>)). X\<sharp>(close \<Gamma> T)" |
456 by (simp add: fresh_gen_set) |
450 by (meson fresh_gen_set) |
457 |
451 |
458 lemma gen_supp: |
452 lemma gen_supp: |
459 shows "(supp (gen T Xs)::tvar set) = supp T - supp Xs" |
453 shows "(supp (gen T Xs)::tvar set) = supp T - supp Xs" |
460 by (induct Xs) |
454 by (induct Xs) |
461 (auto simp add: supp_list_nil supp_list_cons tyS.supp abs_supp supp_atm) |
455 (auto simp add: supp_list_nil supp_list_cons tyS.supp abs_supp supp_atm) |
481 and pi2: "set pi \<subseteq> set (ftv T\<^sub>1 - ftv \<Gamma>) \<times> (pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>))" |
473 and pi2: "set pi \<subseteq> set (ftv T\<^sub>1 - ftv \<Gamma>) \<times> (pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>))" |
482 by (rule at_set_avoiding [OF at_tvar_inst fin fs_tvar1, of "(T\<^sub>2, \<Gamma>)"]) |
474 by (rule at_set_avoiding [OF at_tvar_inst fin fs_tvar1, of "(T\<^sub>2, \<Gamma>)"]) |
483 from pi1 have pi1': "(pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>)) \<sharp>* \<Gamma>" |
475 from pi1 have pi1': "(pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>)) \<sharp>* \<Gamma>" |
484 by (simp add: fresh_star_prod) |
476 by (simp add: fresh_star_prod) |
485 have Gamma_fresh: "\<forall>(x,y)\<in>set pi. x \<sharp> \<Gamma> \<and> y \<sharp> \<Gamma>" |
477 have Gamma_fresh: "\<forall>(x,y)\<in>set pi. x \<sharp> \<Gamma> \<and> y \<sharp> \<Gamma>" |
486 apply (rule ballI) |
478 using freshs_mem [OF _ pi1'] subsetD [OF pi2] ftv_Ctxt fresh_def by fastforce |
487 apply (simp add: split_paired_all) |
479 have "\<And>x y. \<lbrakk>x \<in> set (ftv T\<^sub>1 - ftv \<Gamma>); y \<in> pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>)\<rbrakk> |
488 apply (drule subsetD [OF pi2]) |
480 \<Longrightarrow> x \<sharp> close \<Gamma> T\<^sub>1 \<and> y \<sharp> close \<Gamma> T\<^sub>1" |
489 apply (erule SigmaE) |
481 by (metis DiffE filter_set fresh_def fresh_gen_set freshs_mem ftv_Ctxt ftv_ty gen_supp member_filter pi1') |
490 apply (drule freshs_mem [OF _ pi1']) |
482 then have close_fresh': "\<forall>(x, y)\<in>set pi. x \<sharp> close \<Gamma> T\<^sub>1 \<and> y \<sharp> close \<Gamma> T\<^sub>1" |
491 apply (simp add: ftv_Ctxt [symmetric] fresh_def) |
483 using pi2 by auto |
492 done |
|
493 have close_fresh': "\<forall>(x, y)\<in>set pi. x \<sharp> close \<Gamma> T\<^sub>1 \<and> y \<sharp> close \<Gamma> T\<^sub>1" |
|
494 apply (rule ballI) |
|
495 apply (simp add: split_paired_all) |
|
496 apply (drule subsetD [OF pi2]) |
|
497 apply (erule SigmaE) |
|
498 apply (drule bspec [OF close_fresh]) |
|
499 apply (drule freshs_mem [OF _ pi1']) |
|
500 apply (simp add: fresh_def close_supp ftv_Ctxt) |
|
501 done |
|
502 note x |
484 note x |
503 moreover from Gamma_fresh perm_boolI [OF t1, of pi] |
485 moreover from Gamma_fresh perm_boolI [OF t1, of pi] |
504 have "\<Gamma> \<turnstile> t\<^sub>1 : pi \<bullet> T\<^sub>1" |
486 have "\<Gamma> \<turnstile> t\<^sub>1 : pi \<bullet> T\<^sub>1" |
505 by (simp add: perm_fresh_fresh_aux eqvts fresh_tvar_trm) |
487 by (simp add: perm_fresh_fresh_aux eqvts fresh_tvar_trm) |
506 moreover from t2 close_fresh' |
488 moreover from t2 close_fresh' |
516 |
498 |
517 lemma ftv_ty_subst: |
499 lemma ftv_ty_subst: |
518 fixes T::"ty" |
500 fixes T::"ty" |
519 and \<theta>::"Subst" |
501 and \<theta>::"Subst" |
520 and X Y ::"tvar" |
502 and X Y ::"tvar" |
521 assumes a1: "X \<in> set (ftv T)" |
503 assumes "X \<in> set (ftv T)" |
522 and a2: "Y \<in> set (ftv (lookup \<theta> X))" |
504 and "Y \<in> set (ftv (lookup \<theta> X))" |
523 shows "Y \<in> set (ftv (\<theta><T>))" |
505 shows "Y \<in> set (ftv (\<theta><T>))" |
524 using a1 a2 |
506 using assms |
525 by (nominal_induct T rule: ty.strong_induct) (auto) |
507 by (nominal_induct T rule: ty.strong_induct) (auto) |
526 |
508 |
527 lemma ftv_tyS_subst: |
509 lemma ftv_tyS_subst: |
528 fixes S::"tyS" |
510 fixes S::"tyS" |
529 and \<theta>::"Subst" |
511 and \<theta>::"Subst" |
530 and X Y::"tvar" |
512 and X Y::"tvar" |
531 assumes a1: "X \<in> set (ftv S)" |
513 assumes "X \<in> set (ftv S)" |
532 and a2: "Y \<in> set (ftv (lookup \<theta> X))" |
514 and "Y \<in> set (ftv (lookup \<theta> X))" |
533 shows "Y \<in> set (ftv (\<theta><S>))" |
515 shows "Y \<in> set (ftv (\<theta><S>))" |
534 using a1 a2 |
516 using assms |
535 by (nominal_induct S avoiding: \<theta> Y rule: tyS.strong_induct) |
517 by (nominal_induct S avoiding: \<theta> Y rule: tyS.strong_induct) |
536 (auto simp add: ftv_ty_subst fresh_atm) |
518 (auto simp add: ftv_ty_subst fresh_atm) |
537 |
519 |
538 lemma ftv_Ctxt_subst: |
520 lemma ftv_Ctxt_subst: |
539 fixes \<Gamma>::"Ctxt" |
521 fixes \<Gamma>::"Ctxt" |
540 and \<theta>::"Subst" |
522 and \<theta>::"Subst" |
541 assumes a1: "X \<in> set (ftv \<Gamma>)" |
523 assumes "X \<in> set (ftv \<Gamma>)" |
542 and a2: "Y \<in> set (ftv (lookup \<theta> X))" |
524 and "Y \<in> set (ftv (lookup \<theta> X))" |
543 shows "Y \<in> set (ftv (\<theta><\<Gamma>>))" |
525 shows "Y \<in> set (ftv (\<theta><\<Gamma>>))" |
544 using a1 a2 |
526 using assms by (induct \<Gamma>) (auto simp add: ftv_tyS_subst) |
545 by (induct \<Gamma>) |
|
546 (auto simp add: ftv_tyS_subst) |
|
547 |
527 |
548 lemma gen_preserved1: |
528 lemma gen_preserved1: |
549 assumes asm: "Xs \<sharp>* \<theta>" |
529 assumes "Xs \<sharp>* \<theta>" |
550 shows "\<theta><gen T Xs> = gen (\<theta><T>) Xs" |
530 shows "\<theta><gen T Xs> = gen (\<theta><T>) Xs" |
551 using asm |
531 using assms by (induct Xs) (auto simp add: fresh_star_def) |
552 by (induct Xs) |
|
553 (auto simp add: fresh_star_def) |
|
554 |
532 |
555 lemma gen_preserved2: |
533 lemma gen_preserved2: |
556 fixes T::"ty" |
534 fixes T::"ty" |
557 and \<Gamma>::"Ctxt" |
535 and \<Gamma>::"Ctxt" |
558 assumes asm: "((ftv T) - (ftv \<Gamma>)) \<sharp>* \<theta>" |
536 assumes "((ftv T) - (ftv \<Gamma>)) \<sharp>* \<theta>" |
559 shows "((ftv (\<theta><T>)) - (ftv (\<theta><\<Gamma>>))) = ((ftv T) - (ftv \<Gamma>))" |
537 shows "((ftv (\<theta><T>)) - (ftv (\<theta><\<Gamma>>))) = ((ftv T) - (ftv \<Gamma>))" |
560 using asm |
538 using assms |
561 apply(nominal_induct T rule: ty.strong_induct) |
539 proof(nominal_induct T rule: ty.strong_induct) |
562 apply(auto simp add: fresh_star_def) |
540 case (TVar tvar) |
563 apply(simp add: lookup_fresh) |
541 then show ?case |
564 apply(simp add: ftv_Ctxt[symmetric]) |
542 apply(auto simp add: fresh_star_def ftv_Ctxt_subst) |
565 apply(fold fresh_def) |
543 by (metis filter.simps fresh_def fresh_psubst_Ctxt ftv_Ctxt ftv_ty.simps(1) lookup_fresh) |
566 apply(rule fresh_psubst_Ctxt) |
544 next |
567 apply(assumption) |
545 case (Fun ty1 ty2) |
568 apply(assumption) |
546 then show ?case |
569 apply(rule difference_supset) |
547 by (simp add: fresh_star_list) |
570 apply(auto) |
548 qed |
571 apply(simp add: ftv_Ctxt_subst) |
|
572 done |
|
573 |
549 |
574 lemma close_preserved: |
550 lemma close_preserved: |
575 fixes \<Gamma>::"Ctxt" |
551 fixes \<Gamma>::"Ctxt" |
576 assumes asm: "((ftv T) - (ftv \<Gamma>)) \<sharp>* \<theta>" |
552 assumes "((ftv T) - (ftv \<Gamma>)) \<sharp>* \<theta>" |
577 shows "\<theta><close \<Gamma> T> = close (\<theta><\<Gamma>>) (\<theta><T>)" |
553 shows "\<theta><close \<Gamma> T> = close (\<theta><\<Gamma>>) (\<theta><T>)" |
578 using asm |
554 using assms by (simp add: gen_preserved1 gen_preserved2) |
579 by (simp add: gen_preserved1 gen_preserved2) |
|
580 |
555 |
581 lemma var_fresh_for_ty: |
556 lemma var_fresh_for_ty: |
582 fixes x::"var" |
557 fixes x::"var" |
583 and T::"ty" |
558 and T::"ty" |
584 shows "x\<sharp>T" |
559 shows "x\<sharp>T" |
585 by (nominal_induct T rule: ty.strong_induct) |
560 by (nominal_induct T rule: ty.strong_induct) (simp_all add: fresh_atm) |
586 (simp_all add: fresh_atm) |
|
587 |
561 |
588 lemma var_fresh_for_tyS: |
562 lemma var_fresh_for_tyS: |
589 fixes x::"var" |
563 fixes x::"var" and S::"tyS" |
590 and S::"tyS" |
|
591 shows "x\<sharp>S" |
564 shows "x\<sharp>S" |
592 by (nominal_induct S rule: tyS.strong_induct) |
565 by (nominal_induct S rule: tyS.strong_induct) (simp_all add: abs_fresh var_fresh_for_ty) |
593 (simp_all add: abs_fresh var_fresh_for_ty) |
|
594 |
566 |
595 lemma psubst_fresh_Ctxt: |
567 lemma psubst_fresh_Ctxt: |
596 fixes x::"var" |
568 fixes x::"var" and \<Gamma>::"Ctxt" and \<theta>::"Subst" |
597 and \<Gamma>::"Ctxt" |
|
598 and \<theta>::"Subst" |
|
599 shows "x\<sharp>\<theta><\<Gamma>> = x\<sharp>\<Gamma>" |
569 shows "x\<sharp>\<theta><\<Gamma>> = x\<sharp>\<Gamma>" |
600 by (induct \<Gamma>) |
570 by (induct \<Gamma>) (auto simp add: fresh_list_cons fresh_list_nil fresh_prod var_fresh_for_tyS) |
601 (auto simp add: fresh_list_cons fresh_list_nil fresh_prod var_fresh_for_tyS) |
|
602 |
571 |
603 lemma psubst_valid: |
572 lemma psubst_valid: |
604 fixes \<theta>::Subst |
573 fixes \<theta>::Subst |
605 and \<Gamma>::Ctxt |
574 and \<Gamma>::Ctxt |
606 assumes a: "valid \<Gamma>" |
575 assumes "valid \<Gamma>" |
607 shows "valid (\<theta><\<Gamma>>)" |
576 shows "valid (\<theta><\<Gamma>>)" |
608 using a |
577 using assms by (induct) (auto simp add: psubst_fresh_Ctxt) |
609 by (induct) |
|
610 (auto simp add: psubst_fresh_Ctxt) |
|
611 |
578 |
612 lemma psubst_in: |
579 lemma psubst_in: |
613 fixes \<Gamma>::"Ctxt" |
580 fixes \<Gamma>::"Ctxt" |
614 and \<theta>::"Subst" |
581 and \<theta>::"Subst" |
615 and pi::"tvar prm" |
582 and pi::"tvar prm" |
616 and S::"tyS" |
583 and S::"tyS" |
617 assumes a: "(x,S)\<in>set \<Gamma>" |
584 assumes a: "(x,S)\<in>set \<Gamma>" |
618 shows "(x,\<theta><S>)\<in>set (\<theta><\<Gamma>>)" |
585 shows "(x,\<theta><S>)\<in>set (\<theta><\<Gamma>>)" |
619 using a |
586 using a by (induct \<Gamma>) (auto simp add: calc_atm) |
620 by (induct \<Gamma>) |
|
621 (auto simp add: calc_atm) |
|
622 |
|
623 |
587 |
624 lemma typing_preserved: |
588 lemma typing_preserved: |
625 fixes \<theta>::"Subst" |
589 fixes \<theta>::"Subst" |
626 and pi::"tvar prm" |
590 and pi::"tvar prm" |
627 assumes a: "\<Gamma> \<turnstile> t : T" |
591 assumes "\<Gamma> \<turnstile> t : T" |
628 shows "(\<theta><\<Gamma>>) \<turnstile> t : (\<theta><T>)" |
592 shows "(\<theta><\<Gamma>>) \<turnstile> t : (\<theta><T>)" |
629 using a |
593 using assms |
630 proof (nominal_induct \<Gamma> t T avoiding: \<theta> rule: typing.strong_induct) |
594 proof (nominal_induct \<Gamma> t T avoiding: \<theta> rule: typing.strong_induct) |
631 case (T_VAR \<Gamma> x S T) |
595 case (T_VAR \<Gamma> x S T) |
632 have a1: "valid \<Gamma>" by fact |
596 have a1: "valid \<Gamma>" by fact |
633 have a2: "(x, S) \<in> set \<Gamma>" by fact |
597 have a2: "(x, S) \<in> set \<Gamma>" by fact |
634 have a3: "T \<prec> S" by fact |
598 have a3: "T \<prec> S" by fact |