Skip to content

Commit db059b3

Browse files
committed
Prove the progress lemma
1 parent 73f4ea8 commit db059b3

File tree

1 file changed

+66
-94
lines changed

1 file changed

+66
-94
lines changed

Soundness.thy

Lines changed: 66 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,80 +2,67 @@ theory Soundness
22
imports Defs
33
begin
44

5-
lemma context_invariance: "\<lbrakk> \<Gamma> \<turnstile> e : \<tau> ; \<forall>x \<tau>'. atom x \<in> fv_term e \<and> (x, \<tau>') \<in> \<Gamma> \<longrightarrow> (x, \<tau>') \<in> \<Gamma>' \<rbrakk> \<Longrightarrow> \<Gamma>' \<turnstile> e : \<tau>"
5+
no_notation Set.member ("(_/ \<in> _)" [51, 51] 50)
6+
7+
lemma context_invariance: "\<lbrakk> \<Gamma> \<turnstile> e : \<tau> ; \<forall>x \<tau>'. Set.member (atom x) (fv_term e) \<and> BVar x \<tau>' \<in> \<Gamma> \<longrightarrow> BVar x \<tau>' \<in> \<Gamma>' \<rbrakk> \<Longrightarrow> \<Gamma>' \<turnstile> e : \<tau>"
68
proof(nominal_induct \<Gamma> e \<tau> avoiding: \<Gamma>' rule: T.strong_induct)
7-
case (T_UnitI \<Gamma>)
8-
then show ?case using T.T_UnitI by simp
9-
next
10-
case (T_VarI x \<tau> \<Gamma>)
11-
then show ?case using T.T_VarI supp_at_base by fastforce
12-
next
13-
case (T_AbsI x \<Gamma> \<tau>1 e \<tau>2)
14-
then show ?case using T.T_AbsI by fastforce
15-
next
169
case (T_AppI \<Gamma> e1 \<tau>1 \<tau>2 e2)
17-
then show ?case by (metis T.T_AppI Un_iff term.fv_defs(3))
10+
then show ?case by (metis T.T_AppI Un_iff term.fv_defs(2))
1811
next
1912
case (T_LetI x \<Gamma> e1 \<tau>1 e2 \<tau>2)
20-
then have 1: "atom x \<sharp> (\<Gamma>', e1)" by simp
21-
from T_LetI have 2: "(x, \<tau>1) # \<Gamma>' \<turnstile> e2 : \<tau>2" by simp
22-
show ?case using T.T_LetI[OF 1 2] using T_LetI by simp
23-
qed
13+
then have 1: "\<Gamma>' \<turnstile> e1 : \<tau>1" by auto
14+
from T_LetI have 2: "BVar x \<tau>1#\<Gamma>' \<turnstile> e2 : \<tau>2" by auto
15+
from T_LetI have 3: "atom x \<sharp> (\<Gamma>', e1)" by force
16+
show ?case using T.T_LetI[OF 3 2 1] .
17+
next
18+
case (T_AbsTI a \<Gamma> e \<sigma>)
19+
then have 1: "BTyVar a # \<Gamma>' \<turnstile> e : \<sigma>" by simp
20+
from T_AbsTI have 2: "atom a \<sharp> (e, \<sigma>, \<Gamma>')" by simp
21+
show ?case using T.T_AbsTI[OF 1 2] .
22+
qed (auto simp: T.intros supp_at_base)
2423

25-
lemma free_in_context: "\<lbrakk> \<Gamma> \<turnstile> e : \<tau> ; atom x \<in> fv_term e \<rbrakk> \<Longrightarrow> \<exists>\<tau>'. (x, \<tau>') \<in> \<Gamma>"
24+
lemma free_in_context: "\<lbrakk> \<Gamma> \<turnstile> e : \<tau> ; Set.member (atom x) (fv_term e) \<rbrakk> \<Longrightarrow> \<exists>\<tau>'. BVar x \<tau>' \<in> \<Gamma>"
2625
proof(nominal_induct \<Gamma> e \<tau> avoiding: x rule: T.strong_induct)
27-
case (T_UnitI \<Gamma>)
28-
then show ?case by simp
29-
next
30-
case (T_VarI x' \<tau> \<Gamma>)
26+
case (T_VarI x \<tau> \<Gamma>)
3127
then show ?case by (metis atom_eq_iff singletonD supp_at_base term.fv_defs(1))
3228
next
33-
case (T_AbsI x' \<Gamma> \<tau>1 e \<tau>2)
34-
then show ?case by (metis Diff_iff Un_iff fresh_def insert_iff isin.simps(2) list.set(2) no_vars_in_ty term.fv_defs(2))
29+
case (T_AbsI x \<Gamma> \<tau>1 e \<tau>2)
30+
then show ?case by (metis Diff_iff Un_iff fresh_at_base(2) fresh_def isin.simps(2) no_vars_in_ty term.fv_defs(5))
3531
next
36-
case (T_AppI \<Gamma> e1 \<tau>1 \<tau>2 e2)
37-
then show ?case by auto
32+
case (T_LetI x \<Gamma> e1 \<tau>1 e2 \<tau>2)
33+
then show ?case by (metis Diff_iff Un_iff fresh_at_base(2) isin.simps(2) term.fv_defs(7))
3834
next
39-
case (T_LetI x' \<Gamma> e1 \<tau>1 e2 \<tau>2)
40-
then show ?case by (metis Diff_iff UnE fresh_at_base(2) isin.simps(2) term.fv_defs(5))
41-
qed
35+
case (T_AppTI \<Gamma> e a \<sigma> \<tau>)
36+
then show ?case using fresh_def by fastforce
37+
qed auto
4238

43-
lemma fresh_term[simp]: "\<lbrakk> \<Gamma> \<turnstile> e : \<tau> ; atom x \<sharp> \<Gamma> \<rbrakk> \<Longrightarrow> atom x \<sharp> e"
44-
apply (nominal_induct \<Gamma> e \<tau> avoiding: x rule: T.strong_induct)
45-
apply (auto simp: fresh_Cons)
46-
using fresh_ineq_at_base fresh_not_isin apply force
47-
done
39+
lemma fresh_term_var: "\<lbrakk> \<Gamma> \<turnstile> e : \<tau> ; atom (x::var) \<sharp> \<Gamma> \<rbrakk> \<Longrightarrow> atom x \<sharp> e"
40+
proof (nominal_induct \<Gamma> e \<tau> avoiding: x rule: T.strong_induct)
41+
case (T_VarI y \<tau> \<Gamma>)
42+
then show ?case using T.T_VarI free_in_context fresh_def fresh_not_isin_var term.fv_defs(1) term.supp(1) by blast
43+
qed (auto simp: fresh_Cons)
4844

49-
lemma fun_ty_lam: "\<lbrakk> \<Gamma> \<turnstile> e : \<tau>1 \<rightarrow> \<tau>2 ; is_v_of_e e \<rbrakk> \<Longrightarrow> \<exists>x e'. e = (\<lambda>x:\<tau>1. e')"
45+
lemma fun_ty_lam: "\<lbrakk> \<Gamma> \<turnstile> e : \<tau>1 \<rightarrow> \<tau>2 ; is_value e \<rbrakk> \<Longrightarrow> \<exists>x e'. e = (\<lambda>x:\<tau>1. e')"
5046
by (nominal_induct \<Gamma> e "\<tau>1 \<rightarrow> \<tau>2" rule: T.strong_induct) auto
5147

52-
theorem progress: "[] \<turnstile> e : \<tau> \<Longrightarrow> is_v_of_e e \<or> (\<exists>e'. Step e e')"
48+
theorem progress: "[] \<turnstile> e : \<tau> \<Longrightarrow> is_value e \<or> (\<exists>e'. Step e e')"
5349
proof (induction "[] :: \<Gamma>" e \<tau> rule: T.induct)
54-
case T_UnitI
55-
then show ?case by simp
56-
next
57-
case (T_VarI x \<tau>)
58-
then show ?case by simp
59-
next
60-
case (T_AbsI x \<tau>1 e \<tau>2)
61-
then show ?case by simp
62-
next
6350
case (T_AppI e1 \<tau>1 \<tau>2 e2)
6451
note IH1 = T_AppI(2)
6552
note IH2 = T_AppI(4)
6653

6754
from IH1 show ?case
6855
proof (elim disjE)
69-
assume "is_v_of_e e1"
56+
assume "is_value e1"
7057
from IH2 show ?thesis
7158
proof (elim disjE)
72-
assume "is_v_of_e e2"
73-
from \<open>is_v_of_e e1\<close> T_AppI(1) have "\<exists>x e. e1 = (\<lambda>x:\<tau>1. e)" by (simp add: fun_ty_lam)
74-
then have "\<exists>e'. Step (App e1 e2) e'" using \<open>is_v_of_e e2\<close> ST_BetaI by blast
59+
assume "is_value e2"
60+
from \<open>is_value e1\<close> T_AppI(1) have "\<exists>x e. e1 = (\<lambda>x:\<tau>1. e)" by (simp add: fun_ty_lam)
61+
then have "\<exists>e'. Step (App e1 e2) e'" using \<open>is_value e2\<close> ST_BetaI by blast
7562
then show ?thesis by simp
7663
next
7764
assume "\<exists>e2'. Step e2 e2'"
78-
then show ?thesis using ST_App2I \<open>is_v_of_e e1\<close> by blast
65+
then show ?thesis using ST_App2I \<open>is_value e1\<close> by blast
7966
qed
8067
next
8168
assume "\<exists>e1'. Step e1 e1'"
@@ -86,77 +73,62 @@ next
8673
next
8774
case (T_LetI e1 \<tau>1 x e2 \<tau>2)
8875
then show ?case using ST_SubstI ST_LetI by blast
89-
qed
90-
91-
lemma swap_term: "\<lbrakk> \<Gamma> \<turnstile> e : \<tau> ; atom y \<sharp> \<Gamma> \<rbrakk> \<Longrightarrow> ((x \<leftrightarrow> y) \<bullet> \<Gamma>) \<turnstile> (x \<leftrightarrow> y) \<bullet> e : \<tau>"
92-
proof (nominal_induct \<Gamma> e \<tau> avoiding: x y rule: T.strong_induct)
93-
case (T_UnitI \<Gamma>)
94-
then show ?case by (simp add: T.T_UnitI)
95-
next
96-
case (T_VarI z \<tau> \<Gamma>)
97-
then show ?case
98-
by (metis T.T_VarI T.eqvt flip_fresh_fresh no_vars_in_ty)
99-
next
100-
case (T_AbsI x \<Gamma> \<tau>1 e \<tau>2)
101-
then show ?case
102-
by (metis T.T_AbsI T.eqvt flip_fresh_fresh no_vars_in_ty)
103-
next
104-
case (T_AppI \<Gamma> e1 \<tau>1 \<tau>2 e2)
105-
then show ?case using T.T_AppI by fastforce
10676
next
107-
case (T_LetI z \<Gamma> e1 \<tau>1 e2 \<tau>2)
108-
then have 1: "atom y \<sharp> (z, \<tau>1) # \<Gamma>" by (simp add: fresh_Cons fresh_at_base(2))
109-
110-
from T_LetI have e1: "atom z \<sharp> (x \<leftrightarrow> y) \<bullet> e1" by (smt eq_eqvt flip_def fresh_at_base(2) fresh_eqvt swap_atom_simps(3))
111-
from T_LetI have "atom z \<sharp> (x \<leftrightarrow> y) \<bullet> \<Gamma>" by (metis flip_def fresh_at_base(2) fresh_permute_iff swap_atom_simps(3))
112-
then have 2: "atom z \<sharp> ((x \<leftrightarrow> y) \<bullet> \<Gamma>, (x \<leftrightarrow> y) \<bullet> e1)" using T_LetI e1 by simp
113-
114-
from T_LetI have "(x \<leftrightarrow> y) \<bullet> ((z, \<tau>1) # \<Gamma>) = (z, \<tau>1)#((x \<leftrightarrow> y) \<bullet> \<Gamma>)" by (simp add: flip_fresh_fresh fresh_at_base(2))
115-
then have 3: "(z, \<tau>1) # (x \<leftrightarrow> y) \<bullet> \<Gamma> \<turnstile> (x \<leftrightarrow> y) \<bullet> e2 : \<tau>2" using T_LetI(6)[OF 1, of x] by simp
116-
117-
show ?case using T.T_LetI[OF 2 3 T_LetI(8)[OF \<open>atom y \<sharp> \<Gamma>\<close>, of x]]
118-
by (smt "1" T_LetI.hyps(1) flip_fresh_fresh fresh_Cons fresh_PairD(1) fresh_at_base(2) term.perm_simps(5))
119-
qed
77+
case (T_AppTI e a \<sigma> \<tau>)
78+
from T_AppTI(2) show ?case
79+
proof (elim disjE)
80+
assume "is_value e"
81+
then obtain b e1 where "e = (\<Lambda> b . e1)" using T_AppTI
82+
by (smt T.cases \<tau>.distinct(11) \<tau>.distinct(5) is_value.simps(1) is_value.simps(4) is_value.simps(5) is_value.simps(7))
83+
then show ?thesis using Step.ST_BetaTI T_AppTI by blast
84+
next
85+
assume "\<exists>e'. Step e e'"
86+
then show ?thesis using ST_AppTI by fast
87+
qed
88+
qed auto
12089

12190
lemma T_Abs_Inv:
12291
assumes a: "\<Gamma> \<turnstile> (\<lambda>x : \<tau>1 . e) : \<tau>" and b: "atom x \<sharp> \<Gamma>"
123-
shows "\<exists>\<tau>2. (x, \<tau>1)#\<Gamma> \<turnstile> e : \<tau>2 \<and> \<tau> = (\<tau>1 \<rightarrow> \<tau>2)"
92+
shows "\<exists>\<tau>2. BVar x \<tau>1#\<Gamma> \<turnstile> e : \<tau>2 \<and> \<tau> = (\<tau>1 \<rightarrow> \<tau>2)"
12493
proof (cases rule: T.cases[OF a])
12594
case (3 x' \<Gamma>' \<tau>1' e' \<tau>2)
126-
then show ?thesis
95+
have swap: "(x' \<leftrightarrow> x) \<bullet> e' = e" by (metis "3"(2) Abs1_eq_iff(3) Nominal2_Base.swap_self add_flip_cancel flip_def permute_eq_iff permute_plus term.eq_iff(5))
96+
show ?thesis
12797
proof (cases "atom x' = atom x")
12898
case True
129-
then show ?thesis by (metis "3"(1) "3"(2) "3"(3) "3"(5) Abs1_eq_iff(3) atom_eq_iff term.eq_iff(2))
99+
then show ?thesis by (metis "3"(1) "3"(2) "3"(3) "3"(5) Abs1_eq_iff(3) atom_eq_iff term.eq_iff(5))
130100
next
131101
case False
132-
then have 1: "atom x \<sharp> (x', \<tau>1') # \<Gamma>'" using b by (simp add: 3 fresh_Cons)
133-
have 2: "((x' \<leftrightarrow> x) \<bullet> ((x', \<tau>1) # \<Gamma>)) \<turnstile> (x' \<leftrightarrow> x) \<bullet> e' : \<tau>2" using swap_term[OF "3"(5) 1, of x'] 3 by auto
102+
then have 1: "atom x \<sharp> BVar x' \<tau>1' # \<Gamma>'" using b by (simp add: 3 fresh_Cons)
103+
have 2: "((x' \<leftrightarrow> x) \<bullet> (BVar x' \<tau>1 # \<Gamma>)) \<turnstile> (x' \<leftrightarrow> x) \<bullet> e' : \<tau>2" using T.eqvt
104+
by (metis "3"(1) "3"(2) "3"(5) flip_def no_vars_in_ty swap_fresh_fresh term.eq_iff(5))
134105

135-
have 4: "(x' \<leftrightarrow> x) \<bullet> e' = e" by (metis "3"(2) Abs1_eq_iff(3) False flip_commute term.eq_iff(2))
136-
have 5: "((x' \<leftrightarrow> x) \<bullet> ((x', \<tau>1) # \<Gamma>)) = (x, \<tau>1)#\<Gamma>" by (smt "3"(1) "3"(4) Cons_eqvt Pair_eqvt b flip_at_simps(1) flip_fresh_fresh no_vars_in_ty)
106+
have 4: "((x' \<leftrightarrow> x) \<bullet> (BVar x' \<tau>1 # \<Gamma>)) = BVar x \<tau>1#\<Gamma>"
107+
by (metis "1" "3"(1) "3"(4) Cons_eqvt a binder.perm_simps(1) flip_at_simps(1) flip_fresh_fresh fresh_Cons fresh_term_var term.fresh(5))
137108

138-
from 2 3 4 5 show ?thesis by auto
109+
from 1 2 3 4 swap show ?thesis by auto
139110
qed
140111
qed simp_all
141112

142113
lemma T_Let_Inv:
143114
assumes a: "\<Gamma> \<turnstile> Let x e1 e2 : \<tau>" and b: "atom x \<sharp> \<Gamma>"
144-
shows "\<exists>\<tau>1. \<Gamma> \<turnstile> e1 : \<tau>1 \<and> (x, \<tau>1)#\<Gamma> \<turnstile> e2 : \<tau>"
115+
shows "\<exists>\<tau>1. \<Gamma> \<turnstile> e1 : \<tau>1 \<and> BVar x \<tau>1#\<Gamma> \<turnstile> e2 : \<tau>"
145116
proof (cases rule: T.cases[OF a])
146117
case (5 x' \<Gamma>' _ \<tau>1 e2' \<tau>2)
118+
have swap: "(x' \<leftrightarrow> x) \<bullet> e2' = e2"
119+
by (metis "5"(2) Abs1_eq_iff(3) Nominal2_Base.swap_self add_flip_cancel flip_def permute_flip_cancel permute_plus term.eq_iff(7))
147120
show ?thesis
148121
proof (cases "atom x' = atom x")
149122
case True
150-
then show ?thesis by (metis "5"(1) "5"(2) "5"(3) "5"(5) "5"(6) Abs1_eq_iff(3) atom_eq_iff term.eq_iff(5))
123+
then show ?thesis by (metis "5"(1) "5"(2) "5"(3) "5"(5) "5"(6) Abs1_eq_iff(3) atom_eq_iff term.eq_iff(7))
151124
next
152125
case False
153-
then have 1: "atom x \<sharp> (x', \<tau>1) # \<Gamma>'" using b by (simp add: 5 fresh_Cons)
154-
have 2: "((x' \<leftrightarrow> x) \<bullet> ((x', \<tau>1)#\<Gamma>)) \<turnstile> (x' \<leftrightarrow> x) \<bullet> e2' : \<tau>" using swap_term[OF "5"(5) 1, of x'] 5 by blast
155-
156-
have 3: "(x' \<leftrightarrow> x) \<bullet> e2' = e2" by (metis "5"(2) Abs1_eq_iff(3) False flip_commute term.eq_iff(5))
157-
have 4: "((x' \<leftrightarrow> x) \<bullet> ((x', \<tau>1) # \<Gamma>)) = (x, \<tau>1)#\<Gamma>" by (smt "5"(1) "5"(4) Cons_eqvt Pair_eqvt b flip_at_simps(1) flip_fresh_fresh fresh_PairD(1) no_vars_in_ty)
126+
then have 1: "atom x \<sharp> BVar x' \<tau>1 # \<Gamma>'" using b by (simp add: 5 fresh_Cons)
127+
have 2: "((x' \<leftrightarrow> x) \<bullet> (BVar x' \<tau>1#\<Gamma>)) \<turnstile> (x' \<leftrightarrow> x) \<bullet> e2' : \<tau>" using T.eqvt by (metis "5"(1) "5"(3) "5"(5) flip_fresh_fresh no_vars_in_ty)
128+
have 3: "((x' \<leftrightarrow> x) \<bullet> (BVar x' \<tau>1 # \<Gamma>)) = BVar x \<tau>1#\<Gamma>"
129+
by (metis "5"(1) "5"(4) Cons_eqvt b binder.perm_simps(1) flip_at_simps(1) flip_fresh_fresh fresh_PairD(1) no_vars_in_ty)
158130

159-
from 2 3 4 5 show ?thesis by auto
131+
from 2 3 5 swap show ?thesis by auto
160132
qed
161133
qed simp_all
162134

0 commit comments

Comments
 (0)