388 lemma typing_valid: |
399 lemma typing_valid: |
389 assumes a: "\<Gamma> \<turnstile> t : \<tau>" |
400 assumes a: "\<Gamma> \<turnstile> t : \<tau>" |
390 shows "valid \<Gamma>" |
401 shows "valid \<Gamma>" |
391 using a by (induct, auto dest!: valid_elim) |
402 using a by (induct, auto dest!: valid_elim) |
392 |
403 |
393 lemma ty_subs[rule_format]: |
404 lemma ty_subs: |
394 fixes \<Gamma> ::"(name\<times>ty) list" |
405 assumes a: "((c,\<sigma>)#\<Gamma>) \<turnstile> t1:\<tau>" |
395 and t1 ::"lam" |
406 and b: "\<Gamma>\<turnstile> t2:\<sigma>" |
396 and t2 ::"lam" |
407 shows "\<Gamma> \<turnstile> t1[c::=t2]:\<tau>" |
397 and \<tau> ::"ty" |
408 using a b |
398 and \<sigma> ::"ty" |
|
399 and c ::"name" |
|
400 shows "((c,\<sigma>)#\<Gamma>) \<turnstile> t1:\<tau>\<longrightarrow> \<Gamma>\<turnstile> t2:\<sigma>\<longrightarrow> \<Gamma> \<turnstile> t1[c::=t2]:\<tau>" |
|
401 proof(nominal_induct t1 avoiding: \<Gamma> \<sigma> \<tau> c t2 rule: lam_induct) |
409 proof(nominal_induct t1 avoiding: \<Gamma> \<sigma> \<tau> c t2 rule: lam_induct) |
402 case (Var a) |
410 case (Var a) |
403 show ?case |
411 have a1: "\<Gamma> \<turnstile>t2:\<sigma>" by fact |
404 proof(intro strip) |
412 have a2: "((c,\<sigma>)#\<Gamma>) \<turnstile> Var a:\<tau>" by fact |
405 assume a1: "\<Gamma> \<turnstile>t2:\<sigma>" |
413 hence a21: "(a,\<tau>)\<in>set((c,\<sigma>)#\<Gamma>)" and a22: "valid((c,\<sigma>)#\<Gamma>)" by (auto dest: t1_elim) |
406 assume a2: "((c,\<sigma>)#\<Gamma>) \<turnstile> Var a:\<tau>" |
414 from a22 have a23: "valid \<Gamma>" and a24: "c\<sharp>\<Gamma>" by (auto dest: valid_elim) |
407 hence a21: "(a,\<tau>)\<in>set((c,\<sigma>)#\<Gamma>)" and a22: "valid((c,\<sigma>)#\<Gamma>)" by (auto dest: t1_elim) |
415 from a24 have a25: "\<not>(\<exists>\<tau>. (c,\<tau>)\<in>set \<Gamma>)" by (rule fresh_context) |
408 from a22 have a23: "valid \<Gamma>" and a24: "c\<sharp>\<Gamma>" by (auto dest: valid_elim) |
416 show "\<Gamma>\<turnstile>(Var a)[c::=t2] : \<tau>" |
409 from a24 have a25: "\<not>(\<exists>\<tau>. (c,\<tau>)\<in>set \<Gamma>)" by (rule fresh_context) |
417 proof (cases "a=c", simp_all) |
410 show "\<Gamma>\<turnstile>(Var a)[c::=t2] : \<tau>" |
418 assume case1: "a=c" |
411 proof (cases "a=c", simp_all) |
419 show "\<Gamma> \<turnstile> t2:\<tau>" using a1 |
412 assume case1: "a=c" |
420 proof (cases "\<sigma>=\<tau>") |
413 show "\<Gamma> \<turnstile> t2:\<tau>" using a1 |
421 assume "\<sigma>=\<tau>" thus ?thesis using a1 by simp |
414 proof (cases "\<sigma>=\<tau>") |
422 next |
415 assume "\<sigma>=\<tau>" thus ?thesis using a1 by simp |
423 assume a3: "\<sigma>\<noteq>\<tau>" |
416 next |
424 show ?thesis |
417 assume a3: "\<sigma>\<noteq>\<tau>" |
425 proof (rule ccontr) |
418 show ?thesis |
426 from a3 a21 have "(a,\<tau>)\<in>set \<Gamma>" by force |
419 proof (rule ccontr) |
427 with case1 a25 show False by force |
420 from a3 a21 have "(a,\<tau>)\<in>set \<Gamma>" by force |
|
421 with case1 a25 show False by force |
|
422 qed |
|
423 qed |
428 qed |
424 next |
|
425 assume case2: "a\<noteq>c" |
|
426 with a21 have a26: "(a,\<tau>)\<in>set \<Gamma>" by force |
|
427 from a23 a26 show "\<Gamma> \<turnstile> Var a:\<tau>" by force |
|
428 qed |
429 qed |
|
430 next |
|
431 assume case2: "a\<noteq>c" |
|
432 with a21 have a26: "(a,\<tau>)\<in>set \<Gamma>" by force |
|
433 from a23 a26 show "\<Gamma> \<turnstile> Var a:\<tau>" by force |
429 qed |
434 qed |
430 next |
435 next |
431 case (App s1 s2) |
436 case (App s1 s2) |
432 show ?case |
437 have b1: "\<Gamma> \<turnstile>t2:\<sigma>" by fact |
433 proof (intro strip, simp) |
438 have b2: "((c,\<sigma>)#\<Gamma>)\<turnstile>App s1 s2 : \<tau>" by fact |
434 assume b1: "\<Gamma> \<turnstile>t2:\<sigma>" |
439 hence "\<exists>\<tau>'. (((c,\<sigma>)#\<Gamma>)\<turnstile>s1:\<tau>'\<rightarrow>\<tau> \<and> ((c,\<sigma>)#\<Gamma>)\<turnstile>s2:\<tau>')" by (rule t2_elim) |
435 assume b2: " ((c,\<sigma>)#\<Gamma>)\<turnstile>App s1 s2 : \<tau>" |
440 then obtain \<tau>' where b3a: "((c,\<sigma>)#\<Gamma>)\<turnstile>s1:\<tau>'\<rightarrow>\<tau>" and b3b: "((c,\<sigma>)#\<Gamma>)\<turnstile>s2:\<tau>'" by force |
436 hence "\<exists>\<tau>'. (((c,\<sigma>)#\<Gamma>)\<turnstile>s1:\<tau>'\<rightarrow>\<tau> \<and> ((c,\<sigma>)#\<Gamma>)\<turnstile>s2:\<tau>')" by (rule t2_elim) |
441 show "\<Gamma> \<turnstile> (App s1 s2)[c::=t2] : \<tau>" |
437 then obtain \<tau>' where b3a: "((c,\<sigma>)#\<Gamma>)\<turnstile>s1:\<tau>'\<rightarrow>\<tau>" and b3b: "((c,\<sigma>)#\<Gamma>)\<turnstile>s2:\<tau>'" by force |
442 using b1 b3a b3b prems by (simp, rule_tac \<tau>="\<tau>'" in t2, auto) |
438 show "\<Gamma> \<turnstile> App (s1[c::=t2]) (s2[c::=t2]) : \<tau>" |
|
439 using b1 b3a b3b App by (rule_tac \<tau>="\<tau>'" in t2, auto) |
|
440 qed |
|
441 next |
443 next |
442 case (Lam a s) |
444 case (Lam a s) |
443 have "a\<sharp>\<Gamma>" "a\<sharp>\<sigma>" "a\<sharp>\<tau>" "a\<sharp>c" "a\<sharp>t2" by fact |
445 have "a\<sharp>\<Gamma>" "a\<sharp>\<sigma>" "a\<sharp>\<tau>" "a\<sharp>c" "a\<sharp>t2" by fact |
444 hence f1: "a\<sharp>\<Gamma>" and f2: "a\<noteq>c" and f2': "c\<sharp>a" and f3: "a\<sharp>t2" and f4: "a\<sharp>((c,\<sigma>)#\<Gamma>)" |
446 hence f1: "a\<sharp>\<Gamma>" and f2: "a\<noteq>c" and f2': "c\<sharp>a" and f3: "a\<sharp>t2" and f4: "a\<sharp>((c,\<sigma>)#\<Gamma>)" |
445 by (auto simp add: fresh_atm fresh_prod fresh_list_cons) |
447 by (auto simp add: fresh_atm fresh_prod fresh_list_cons) |
446 show ?case using f2 f3 |
448 have c1: "((c,\<sigma>)#\<Gamma>)\<turnstile>Lam [a].s : \<tau>" by fact |
447 proof(intro strip, simp) |
449 hence "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" using f4 by (auto dest: t3_elim) |
448 assume c1: "((c,\<sigma>)#\<Gamma>)\<turnstile>Lam [a].s : \<tau>" |
450 then obtain \<tau>1 \<tau>2 where c11: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and c12: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" by force |
449 hence "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" using f4 by (auto dest: t3_elim) |
451 from c12 have "valid ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>)" by (rule typing_valid) |
450 then obtain \<tau>1 \<tau>2 where c11: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and c12: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" by force |
452 hence ca: "valid \<Gamma>" and cb: "a\<sharp>\<Gamma>" and cc: "c\<sharp>\<Gamma>" |
451 from c12 have "valid ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>)" by (rule typing_valid) |
453 by (auto dest: valid_elim simp add: fresh_list_cons) |
452 hence ca: "valid \<Gamma>" and cb: "a\<sharp>\<Gamma>" and cc: "c\<sharp>\<Gamma>" |
454 from c12 have c14: "((c,\<sigma>)#(a,\<tau>1)#\<Gamma>) \<turnstile> s : \<tau>2" |
453 by (auto dest: valid_elim simp add: fresh_list_cons) |
455 proof - |
454 from c12 have c14: "((c,\<sigma>)#(a,\<tau>1)#\<Gamma>) \<turnstile> s : \<tau>2" |
456 have c2: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<lless> ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" by (force simp add: sub_def) |
455 proof - |
457 have c3: "valid ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" |
456 have c2: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<lless> ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" by (force simp add: sub_def) |
458 by (rule v2, rule v2, auto simp add: fresh_list_cons fresh_prod ca cb cc f2' fresh_ty) |
457 have c3: "valid ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" |
459 from c12 c2 c3 show ?thesis by (force intro: weakening) |
458 by (rule v2, rule v2, auto simp add: fresh_list_cons fresh_prod ca cb cc f2' fresh_ty) |
|
459 from c12 c2 c3 show ?thesis by (force intro: weakening) |
|
460 qed |
|
461 assume c8: "\<Gamma> \<turnstile> t2 : \<sigma>" |
|
462 have c81: "((a,\<tau>1)#\<Gamma>)\<turnstile>t2 :\<sigma>" |
|
463 proof - |
|
464 have c82: "\<Gamma> \<lless> ((a,\<tau>1)#\<Gamma>)" by (force simp add: sub_def) |
|
465 have c83: "valid ((a,\<tau>1)#\<Gamma>)" using f1 ca by force |
|
466 with c8 c82 c83 show ?thesis by (force intro: weakening) |
|
467 qed |
|
468 show "\<Gamma> \<turnstile> Lam [a].(s[c::=t2]) : \<tau>" |
|
469 using c11 Lam c14 c81 f1 by force |
|
470 qed |
460 qed |
|
461 assume c8: "\<Gamma> \<turnstile> t2 : \<sigma>" |
|
462 have c81: "((a,\<tau>1)#\<Gamma>)\<turnstile>t2 :\<sigma>" |
|
463 proof - |
|
464 have c82: "\<Gamma> \<lless> ((a,\<tau>1)#\<Gamma>)" by (force simp add: sub_def) |
|
465 have c83: "valid ((a,\<tau>1)#\<Gamma>)" using f1 ca by force |
|
466 with c8 c82 c83 show ?thesis by (force intro: weakening) |
|
467 qed |
|
468 show "\<Gamma> \<turnstile> (Lam [a].s)[c::=t2] : \<tau>" |
|
469 using c11 prems c14 c81 f1 by force |
471 qed |
470 qed |
472 |
471 |
473 lemma subject[rule_format]: |
472 lemma subject: |
474 fixes \<Gamma> ::"(name\<times>ty) list" |
473 fixes \<Gamma> ::"(name\<times>ty) list" |
475 and t1 ::"lam" |
474 and t1 ::"lam" |
476 and t2 ::"lam" |
475 and t2 ::"lam" |
477 and \<tau> ::"ty" |
476 and \<tau> ::"ty" |
478 assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2" |
477 assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2" |
479 shows "(\<Gamma> \<turnstile> t1:\<tau>) \<longrightarrow> (\<Gamma> \<turnstile> t2:\<tau>)" |
478 and b: "\<Gamma> \<turnstile> t1:\<tau>" |
480 using a |
479 shows "\<Gamma> \<turnstile> t2:\<tau>" |
481 proof (nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct, auto) |
480 using a b |
|
481 proof (nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct) |
482 case (b1 t s1 s2) |
482 case (b1 t s1 s2) |
483 have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1:\<tau> \<longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact |
483 have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1:\<tau> \<Longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact |
484 assume "\<Gamma> \<turnstile> App s1 t : \<tau>" |
484 have "\<Gamma> \<turnstile> App s1 t : \<tau>" by fact |
485 hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> s1 : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> t : \<sigma>)" by (rule t2_elim) |
485 hence "\<exists>\<sigma>. \<Gamma> \<turnstile> s1 : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> t : \<sigma>" by (rule t2_elim) |
486 then obtain \<sigma> where a1: "\<Gamma> \<turnstile> s1 : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> t : \<sigma>" by force |
486 then obtain \<sigma> where a1: "\<Gamma> \<turnstile> s1 : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> t : \<sigma>" by blast |
487 thus "\<Gamma> \<turnstile> App s2 t : \<tau>" using i by force |
487 thus "\<Gamma> \<turnstile> App s2 t : \<tau>" using i by blast |
488 next |
488 next |
489 case (b2 t s1 s2) |
489 case (b2 t s1 s2) |
490 have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1 : \<tau> \<longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact |
490 have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1 : \<tau> \<Longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact |
491 assume "\<Gamma> \<turnstile> App t s1 : \<tau>" |
491 have "\<Gamma> \<turnstile> App t s1 : \<tau>" by fact |
492 hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> t : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s1 : \<sigma>)" by (rule t2_elim) |
492 hence "\<exists>\<sigma>. \<Gamma> \<turnstile> t : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s1 : \<sigma>" by (rule t2_elim) |
493 then obtain \<sigma> where a1: "\<Gamma> \<turnstile> t : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s1 : \<sigma>" by force |
493 then obtain \<sigma> where a1: "\<Gamma> \<turnstile> t : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s1 : \<sigma>" by blast |
494 thus "\<Gamma> \<turnstile> App t s2 : \<tau>" using i by force |
494 thus "\<Gamma> \<turnstile> App t s2 : \<tau>" using i by blast |
495 next |
495 next |
496 case (b3 a s1 s2) |
496 case (b3 a s1 s2) |
497 have f: "a\<sharp>\<Gamma>" and "a\<sharp>\<tau>" by fact+ |
497 have f: "a\<sharp>\<Gamma>" and "a\<sharp>\<tau>" by fact |
498 have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1 : \<tau> \<longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact |
498 have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1 : \<tau> \<Longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact |
499 assume "\<Gamma> \<turnstile> Lam [a].s1 : \<tau>" |
499 have "\<Gamma> \<turnstile> Lam [a].s1 : \<tau>" by fact |
500 with f have "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#\<Gamma>) \<turnstile> s1 : \<tau>2" by (force dest: t3_elim) |
500 with f have "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#\<Gamma>) \<turnstile> s1 : \<tau>2" by (blast dest: t3_elim) |
501 then obtain \<tau>1 \<tau>2 where a1: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and a2: "((a,\<tau>1)#\<Gamma>) \<turnstile> s1 : \<tau>2" by force |
501 then obtain \<tau>1 \<tau>2 where a1: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and a2: "((a,\<tau>1)#\<Gamma>) \<turnstile> s1 : \<tau>2" by blast |
502 thus "\<Gamma> \<turnstile> Lam [a].s2 : \<tau>" using f i by force |
502 thus "\<Gamma> \<turnstile> Lam [a].s2 : \<tau>" using f i by blast |
503 next |
503 next |
504 case (b4 a s1 s2) |
504 case (b4 a s1 s2) |
505 have f: "a\<sharp>\<Gamma>" by fact |
505 have f: "a\<sharp>\<Gamma>" by fact |
506 assume "\<Gamma> \<turnstile> App (Lam [a].s1) s2 : \<tau>" |
506 have "\<Gamma> \<turnstile> App (Lam [a].s1) s2 : \<tau>" by fact |
507 hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s2 : \<sigma>)" by (rule t2_elim) |
507 hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s2 : \<sigma>)" by (rule t2_elim) |
508 then obtain \<sigma> where a1: "\<Gamma> \<turnstile> (Lam [(a::name)].s1) : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s2 : \<sigma>" by force |
508 then obtain \<sigma> where a1: "\<Gamma> \<turnstile> (Lam [(a::name)].s1) : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s2 : \<sigma>" by blast |
509 have "((a,\<sigma>)#\<Gamma>) \<turnstile> s1 : \<tau>" using a1 f by (auto dest!: t3_elim) |
509 have "((a,\<sigma>)#\<Gamma>) \<turnstile> s1 : \<tau>" using a1 f by (blast dest!: t3_elim) |
510 with a2 show "\<Gamma> \<turnstile> s1[a::=s2] : \<tau>" by (force intro: ty_subs) |
510 with a2 show "\<Gamma> \<turnstile> s1[a::=s2] : \<tau>" by (blast intro: ty_subs) |
511 qed |
511 qed |
512 |
512 |
513 lemma subject[rule_format]: |
513 lemma subject_automatic: |
514 fixes \<Gamma> ::"(name\<times>ty) list" |
514 fixes \<Gamma> ::"(name\<times>ty) list" |
515 and t1 ::"lam" |
515 and t1 ::"lam" |
516 and t2 ::"lam" |
516 and t2 ::"lam" |
517 and \<tau> ::"ty" |
517 and \<tau> ::"ty" |
518 assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2" |
518 assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2" |
519 shows "\<Gamma> \<turnstile> t1:\<tau> \<longrightarrow> \<Gamma> \<turnstile> t2:\<tau>" |
519 and b: "\<Gamma> \<turnstile> t1:\<tau>" |
520 using a |
520 shows "\<Gamma> \<turnstile> t2:\<tau>" |
|
521 using a b |
521 apply(nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct) |
522 apply(nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct) |
522 apply(auto dest!: t2_elim t3_elim intro: ty_subs) |
523 apply(auto dest!: t2_elim t3_elim intro: ty_subs) |
523 done |
524 done |
524 |
525 |
525 subsection {* some facts about beta *} |
526 subsection {* some facts about beta *} |