Skip to content

Commit 52a47f2

Browse files
committed
Prove progress and type soundness
1 parent 4569079 commit 52a47f2

File tree

3 files changed

+94
-31
lines changed

3 files changed

+94
-31
lines changed

Lemmas.thy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ lemma subst_type_same: "[[atom a]]lst. e = [[atom a']]lst. e' \<Longrightarrow>
8282
by (metis Abs1_eq_iff(3) flip_commute subst_type_var_name)
8383
lemma subst_term_type_same: "[[atom a]]lst. e = [[atom a']]lst. e' \<Longrightarrow> subst_term_type e \<tau> a = subst_term_type e' \<tau> a'"
8484
by (metis Abs1_eq_iff(3) flip_commute subst_term_type_var_name)
85+
lemmas subst_same = subst_term_same subst_type_same subst_term_type_same
8586

8687
(* atom x \<sharp> \<Gamma> \<Longrightarrow> \<not>isin (B x _) \<Gamma> *)
8788
lemma fresh_not_isin_tyvar: "atom a \<sharp> \<Gamma> \<Longrightarrow> \<not>isin (BTyVar a k) \<Gamma>"

Soundness.thy

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -356,59 +356,86 @@ next
356356
qed
357357

358358
theorem preservation:
359-
fixes e e'::"term"
360-
assumes "[] \<turnstile> e : \<tau>" "e \<longrightarrow> e'"
361-
shows "[] \<turnstile> e' : \<tau>"
362-
using assms beta_nf_def value_beta_nf proof (nominal_induct "[]::\<Gamma>" e \<tau> arbitrary: e' rule: Tm.strong_induct)
363-
case (Tm_App e1 \<tau>1 \<tau>2 e2)
359+
fixes e e'::"term" and \<Gamma>::\<Gamma>
360+
assumes "\<Gamma> , \<Delta> \<turnstile> e : \<tau>" "e \<longrightarrow> e'" "\<nexists>x \<tau>. BVar x \<tau> \<in> \<Gamma>"
361+
shows "\<Gamma> , \<Delta> \<turnstile> e' : \<tau>"
362+
using assms beta_nf_def value_beta_nf proof (nominal_induct \<Gamma> \<Delta> e \<tau> arbitrary: e' rule: Tm.strong_induct)
363+
case (Tm_App \<Gamma> \<Delta> e1 \<tau>1 \<tau>2 e2)
364364
from Tm_App(5) show ?case
365365
proof cases
366-
case (ST_BetaI x \<tau> e)
367-
then show ?thesis by (metis Tm_App.hyps(1,3) T_Abs_Inv \<tau>.eq_iff(3) append_Nil fresh_Nil substitution)
366+
case (ST_Beta x \<tau> e)
367+
then have "\<tau>1 = \<tau>" using Tm_App(1) fun_ty_val by fastforce
368+
obtain x' e2' where P: "BVar x' \<tau>1 # \<Gamma> , \<Delta> \<turnstile> e2' : \<tau>2" "(\<lambda>x:\<tau>1. e) = (\<lambda>x':\<tau>1. e2')" "atom x' \<sharp> (x, e)" using T_Abs_Inv_2 Tm_App(1) ST_Beta(1) by (metis \<tau>.eq_iff(4))
369+
have 1: "\<Gamma> , \<Delta> \<turnstile> e2'[e2/x'] : \<tau>2" using substitution[of "[]"] Tm_App(3) P(1) by simp
370+
have "e2'[e2/x'] = e[e2/x]" using subst_same(1)[of x e x' e2'] P(2) by simp
371+
then show ?thesis using ST_Beta(2) 1 by argo
368372
next
369-
case (ST_AppI e2')
370-
then show ?thesis using Tm_App.hyps(2,3,6) Tm.Tm_App value_beta_nf by blast
373+
case (ST_App e2')
374+
then show ?thesis using Tm.Tm_App Tm_App(2,3,6) beta_nf_def value_beta_nf by blast
371375
qed
372376
next
373-
case (Tm_TApp e a k \<sigma> \<tau>)
377+
case (Tm_TAbs a k \<Gamma> \<Delta> e \<sigma>)
378+
from Tm_TAbs(3) show ?case
379+
proof cases
380+
case (ST_TAbs e2 e2' b)
381+
obtain c::tyvar where "atom c \<sharp> (a, e, b, e2, e', e2', \<sigma>, \<Gamma>)" by (rule obtain_fresh)
382+
then have c: "atom c \<sharp> a" "atom c \<sharp> e" "atom c \<sharp> b" "atom c \<sharp> e2" "atom c \<sharp> e'" "atom c \<sharp> e2'" "atom c \<sharp> \<sigma>" "atom c \<sharp> \<Gamma>" by auto
383+
then obtain e3 where 1: "[[atom b]]lst. e2 = [[atom c]]lst. e3" by (metis Abs_lst_rename)
384+
then have 2: "e3 = (b \<leftrightarrow> c) \<bullet> e2" using Abs_rename_body by blast
385+
from 1 have 3: "e = (c \<leftrightarrow> a) \<bullet> e3" using ST_TAbs(1) Abs_rename_body[of c e3 a e] by argo
386+
from ST_TAbs(3) have "e3 \<longrightarrow> (b \<leftrightarrow> c) \<bullet> e2'" using 2 Step.eqvt by blast
387+
then have 4: "e \<longrightarrow> (c \<leftrightarrow> a) \<bullet> (b \<leftrightarrow> c) \<bullet> e2'" using 3 Step.eqvt by blast
388+
then have 5: "BTyVar a k # \<Gamma> , \<Delta> \<turnstile> (c \<leftrightarrow> a) \<bullet> (b \<leftrightarrow> c) \<bullet> e2' : \<sigma>" using Tm_TAbs(2,4) beta_nf_def value_beta_nf by simp
389+
have "BTyVar c k # \<Gamma> , \<Delta> \<turnstile> (b \<leftrightarrow> c) \<bullet> e2' : (a \<leftrightarrow> c) \<bullet> \<sigma>" using Tm_eqvt_tyvar[OF 5 c(8)] flip_commute permute_flip_cancel by simp
390+
then have 6: "\<Gamma> , \<Delta> \<turnstile> \<Lambda> c : k . (b \<leftrightarrow> c) \<bullet> e2' : \<forall> c : k . (a \<leftrightarrow> c) \<bullet> \<sigma>" by (rule Tm.Tm_TAbs)
391+
have 7: "(\<Lambda> c : k . (b \<leftrightarrow> c) \<bullet> e2') = (\<Lambda> b : k . e2')" using Abs_lst_rename c(6) by fastforce
392+
have 8: "(\<forall> c : k . (a \<leftrightarrow> c) \<bullet> \<sigma>) = (\<forall> a : k . \<sigma>)" using Abs_lst_rename c(7) by fastforce
393+
show ?thesis using 6 7 8 ST_TAbs(2) by argo
394+
qed
395+
next
396+
case (Tm_TApp \<Gamma> \<Delta> e a k \<sigma> \<tau>)
374397
from Tm_TApp(4) show ?case
375398
proof cases
376-
case (ST_BetaTI b k2 e2)
377-
obtain c::tyvar where "atom c \<sharp> (a, b, e2, \<sigma>)" using obtain_fresh by blast
378-
then have c: "atom c \<sharp> a" "atom c \<sharp> b" "atom c \<sharp> e2" "atom c \<sharp> \<sigma>" by auto
399+
case (ST_TBeta e2 b k2)
400+
obtain c::tyvar where "atom c \<sharp> (a, b, e2, \<sigma>, \<Gamma>)" using obtain_fresh by blast
401+
then have c: "atom c \<sharp> a" "atom c \<sharp> b" "atom c \<sharp> e2" "atom c \<sharp> \<sigma>" "atom c \<sharp> \<Gamma>" by auto
379402
obtain \<sigma>2 where c1: "(\<forall> a:k. \<sigma>) = (\<forall> c:k. \<sigma>2)" using Abs_lst_rename[OF c(4)] by auto
380-
have same: "k = k2" using Tm_TApp(1) forall_ty_lam ST_BetaTI(1) by fastforce
403+
have same: "k = k2" using Tm_TApp.hyps(1) forall_ty_val local.ST_TBeta(1) local.ST_TBeta(3) by fastforce
381404
obtain e2' where c2: "(\<Lambda> b:k2. e2) = (\<Lambda> c:k. e2')" using Abs_lst_rename[OF c(3)] same by auto
382-
have 1: "[] \<turnstile> (\<Lambda> c:k. e2') : \<forall> c:k. \<sigma>2" using Tm_TApp(1) ST_BetaTI(1) c2 c1 by simp
383-
have 2: "[BTyVar c k] \<turnstile> e2' : \<sigma>2"
405+
have 1: "\<Gamma> , \<Delta> \<turnstile> (\<Lambda> c:k. e2') : \<forall> c:k. \<sigma>2" using Tm_TApp(1) ST_TBeta(1) c2 c1 by simp
406+
have 2: "BTyVar c k # \<Gamma> , \<Delta> \<turnstile> e2' : \<sigma>2"
384407
proof (cases rule: Tm.cases[OF 1])
385-
case (4 d _ _ e \<sigma>)
386-
have x1: "(d \<leftrightarrow> c) \<bullet> e = e2'" using Abs_rename_body[of d e c e2'] 4(2) by simp
387-
have x2: "(d \<leftrightarrow> c) \<bullet> \<sigma> = \<sigma>2" using Abs_rename_body[of d \<sigma> c \<sigma>2] 4(3) by simp
388-
show ?thesis
389-
by (metis "1" Abs1_eq_iff(3) T_AbsT_Inv \<tau>.eq_iff(5) fresh_Nil fresh_in_context_ty typing_regularity)
408+
case (4 d _ _ _ e \<sigma>)
409+
have x1: "(d \<leftrightarrow> c) \<bullet> e = e2'" using Abs_rename_body[of d e c e2'] 4(3) by simp
410+
have x2: "(d \<leftrightarrow> c) \<bullet> \<sigma> = \<sigma>2" using Abs_rename_body[of d \<sigma> c \<sigma>2] 4(4) by simp
411+
have "(d \<leftrightarrow> c) \<bullet> (BTyVar d k # \<Gamma> , \<Delta> \<turnstile> e : \<sigma>)" using 4 by auto
412+
then have x3: "((d \<leftrightarrow> c) \<bullet> BTyVar d k) # ((d \<leftrightarrow> c) \<bullet> \<Gamma>) , (d \<leftrightarrow> c) \<bullet> \<Delta> \<turnstile> e2' : \<sigma>2" using x1 x2 Tm.eqvt by auto
413+
have "atom d \<sharp> \<Gamma>" using 4(1,5) context_valid_tm by blast
414+
then have x4: "(d \<leftrightarrow> c) \<bullet> \<Gamma> = \<Gamma>" using c(5) flip_fresh_fresh by blast
415+
have x5: "(d \<leftrightarrow> c) \<bullet> \<Delta> = \<Delta>" using fresh_in_axioms flip_fresh_fresh axioms_valid(3)[OF 1] by blast
416+
from x3 x4 x5 have "((d \<leftrightarrow> c) \<bullet> BTyVar d k) # \<Gamma> , \<Delta> \<turnstile> e2' : \<sigma>2" by argo
417+
then show ?thesis by (simp add: flip_fresh_fresh)
390418
qed auto
391419
then show ?thesis
392-
by (metis Tm_TApp.hyps(3) \<tau>.eq_iff(5) append_Nil c1 c2 local.ST_BetaTI(2) subst_context.simps(1) subst_term_type_same subst_type_same term.eq_iff(6) type_substitution(3))
420+
by (metis Tm_TApp.hyps(3) \<tau>.eq_iff(5) append_Nil c1 c2 local.ST_TBeta(2) subst_context.simps(1) subst_term_type_same subst_type_same term.eq_iff(6) type_substitution(3))
393421
next
394-
case (ST_AppTI e2)
395-
then show ?thesis using Tm_TApp(2,3) Tm.Tm_TApp beta_nf_def value_beta_nf by blast
422+
case (ST_TApp e2)
423+
then show ?thesis using Tm.Tm_TApp Tm_TApp(2,3,5) beta_nf_def value_beta_nf by blast
396424
qed
397425
next
398426
case (Tm_Let e1 \<tau>1 x e2 \<tau>2)
399-
from Tm_Let(4) show ?case
427+
from Tm_Let(5) show ?case
400428
proof cases
401-
case (ST_SubstI x e2)
402-
then show ?thesis
403-
by (metis Tm_Let.hyps(1,3,4) Step.ST_SubstI Step_deterministic append.left_neutral substitution)
429+
case (ST_Let x e2)
430+
then show ?thesis by (metis Tm_Let(1,3) append_self_conv2 subst_term_same substitution)
404431
qed
405432
qed auto
406433

407-
lemma multi_preservation: "\<lbrakk> e \<longrightarrow>* e' ; [] \<turnstile> e : \<tau> \<rbrakk> \<Longrightarrow> [] \<turnstile> e' : \<tau>"
434+
lemma multi_preservation: "\<lbrakk> e \<longrightarrow>* e' ; [] , \<Delta> \<turnstile> e : \<tau> \<rbrakk> \<Longrightarrow> [] , \<Delta> \<turnstile> e' : \<tau>"
408435
by (induction e e' rule: Steps.induct) (auto simp: preservation)
409436

410-
corollary soundness: "\<lbrakk> [] \<turnstile> e : \<tau> ; e \<longrightarrow>* e' \<rbrakk> \<Longrightarrow> \<not>(stuck e')"
437+
corollary soundness: "\<lbrakk> [] , \<Delta> \<turnstile> e : \<tau> ; e \<longrightarrow>* e' \<rbrakk> \<Longrightarrow> \<not>(stuck e')"
411438
unfolding stuck_def beta_nf_def
412-
using progress multi_preservation by blast
439+
using progress multi_preservation isin.simps(1) by blast
413440

414441
end

Typing_Lemmas.thy

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,27 @@ proof (cases rule: Tm.cases[OF a])
3434
qed
3535
qed simp_all
3636

37+
lemma T_Abs_Inv_2:
38+
fixes \<tau>::\<tau>
39+
assumes a: "\<Gamma> , \<Delta> \<turnstile> (\<lambda>x:\<tau>1. e) : \<tau>"
40+
obtains x' e' \<tau>2 where "BVar x' \<tau>1 # \<Gamma> , \<Delta> \<turnstile> e' : \<tau>2" "(\<lambda>x:\<tau>1. e) = (\<lambda>x':\<tau>1. e')" "atom x' \<sharp> (x, e)" "\<tau> = (\<tau>1 \<rightarrow> \<tau>2)"
41+
proof (cases rule: Tm.cases[OF a])
42+
case (2 x' _ _ _ e' \<tau>2)
43+
then obtain c::var where "atom c \<sharp> (x, e, x', e', \<Gamma>)" using obtain_fresh by blast
44+
then have c: "atom c \<sharp> x" "atom c \<sharp> e" "atom c \<sharp> x'" "atom c \<sharp> e'" "atom c \<sharp> \<Gamma>" by auto
45+
obtain e2 where P: "(x' \<leftrightarrow> c) \<bullet> (\<lambda> x' : \<tau>1 . e') = (\<lambda> c : \<tau>1 . e2)" using flip_fresh_fresh by force
46+
then have 1: "(x' \<leftrightarrow> c) \<bullet> e' = e2" by (simp add: Abs1_eq_iff(3))
47+
have 3: "(x' \<leftrightarrow> c) \<bullet> \<Gamma> = \<Gamma>" by (metis 2(1,5) CtxE(2) c(5) context_valid_tm flip_def swap_fresh_fresh)
48+
have 4: "((x' \<leftrightarrow> c) \<bullet> BVar x' \<tau>1) = BVar c \<tau>1" using P by auto
49+
have valid: "\<turnstile> \<Delta>" using axioms_valid(3)[OF 2(5)] 2(2) by simp
50+
have "(x' \<leftrightarrow> c) \<bullet> (BVar x' \<tau>1 # \<Gamma> , \<Delta> \<turnstile> e' : \<tau>2)" using 2 by auto
51+
then have "((x' \<leftrightarrow> c) \<bullet> (BVar x' \<tau>1 # \<Gamma>)) , \<Delta> \<turnstile> (x' \<leftrightarrow> c) \<bullet> e' : \<tau>2" using valid by auto
52+
then have "(((x' \<leftrightarrow> c) \<bullet> BVar x' \<tau>1) # ((x' \<leftrightarrow> c) \<bullet> \<Gamma>)) , \<Delta> \<turnstile> e2 : \<tau>2" using 1 by auto
53+
then have x: "BVar c \<tau>1 # \<Gamma> , \<Delta> \<turnstile> e2 : \<tau>2" using 3 4 by argo
54+
have y: "(\<lambda> x : \<tau>1 . e) = (\<lambda> c : \<tau>1 . e2)" by (metis 1 2(3) Abs1_eq_iff(3) c(3,4) flip_commute fresh_at_base(2) term.eq_iff(5))
55+
show ?thesis using that[OF x y] 2(3,4) c(1,2) by simp
56+
qed auto
57+
3758
lemma T_Let_Inv:
3859
assumes a: "\<Gamma> , \<Delta> \<turnstile> Let x \<tau>1 e1 e2 : \<tau>" and b: "atom x \<sharp> \<Gamma>"
3960
shows "\<Gamma> , \<Delta> \<turnstile> e1 : \<tau>1 \<and> BVar x \<tau>1 # \<Gamma> , \<Delta> \<turnstile> e2 : \<tau>"
@@ -263,4 +284,18 @@ lemma axioms_regularity: "\<turnstile> \<Delta>' @ AxCtor D \<tau> # \<Delta> \<
263284
lemma context_regularity: "\<Delta> \<turnstile> \<Gamma>' @ BVar x \<tau> # \<Gamma> \<Longrightarrow> \<Gamma> , \<Delta> \<turnstile>\<^sub>t\<^sub>y \<tau> : \<star>"
264285
using Ctx_Var context_split_valid by (induction \<Gamma>) blast+
265286

287+
lemma Tm_eqvt_tyvar:
288+
assumes "BTyVar a k # \<Gamma> , \<Delta> \<turnstile> e : \<tau>" "atom c \<sharp> \<Gamma>"
289+
shows "BTyVar c k # \<Gamma> , \<Delta> \<turnstile> (a \<leftrightarrow> c) \<bullet> e : (a \<leftrightarrow> c) \<bullet> \<tau>"
290+
proof -
291+
have "\<turnstile> \<Delta>" by (rule axioms_valid(3)[OF assms(1)])
292+
then have 1: "(a \<leftrightarrow> c) \<bullet> \<Delta> = \<Delta>" by auto
293+
have "\<Delta> \<turnstile> BTyVar a k # \<Gamma>" by (rule context_valid(2)[OF assms(1)])
294+
then have 2: "(a \<leftrightarrow> c) \<bullet> \<Gamma> = \<Gamma>" using assms(2) flip_fresh_fresh by blast
295+
have 3: "(a \<leftrightarrow> c) \<bullet> BTyVar a k = BTyVar c k" using flip_fresh_fresh by force
296+
297+
have "(a \<leftrightarrow> c) \<bullet> (BTyVar a k # \<Gamma>) , (a \<leftrightarrow> c) \<bullet> \<Delta> \<turnstile> (a \<leftrightarrow> c) \<bullet> e : (a \<leftrightarrow> c) \<bullet> \<tau>" by (rule Tm.eqvt[OF assms(1), of "(a \<leftrightarrow> c)"])
298+
then show ?thesis using 1 2 3 by auto
299+
qed
300+
266301
end

0 commit comments

Comments
 (0)