32 |
32 |
33 lemma perm_ty[simp]: |
33 lemma perm_ty[simp]: |
34 fixes T::"ty" |
34 fixes T::"ty" |
35 and pi::"name prm" |
35 and pi::"name prm" |
36 shows "pi\<bullet>T = T" |
36 shows "pi\<bullet>T = T" |
37 by (induct T rule: ty.weak_induct) (simp_all) |
37 by (induct T rule: ty.induct) (simp_all) |
38 |
38 |
39 lemma fresh_ty[simp]: |
39 lemma fresh_ty[simp]: |
40 fixes x::"name" |
40 fixes x::"name" |
41 and T::"ty" |
41 and T::"ty" |
42 shows "x\<sharp>T" |
42 shows "x\<sharp>T" |
43 by (simp add: fresh_def supp_def) |
43 by (simp add: fresh_def supp_def) |
44 |
44 |
45 lemma ty_cases: |
45 lemma ty_cases: |
46 fixes T::ty |
46 fixes T::ty |
47 shows "(\<exists> T\<^isub>1 T\<^isub>2. T=T\<^isub>1\<rightarrow>T\<^isub>2) \<or> T=TUnit \<or> T=TBase" |
47 shows "(\<exists> T\<^isub>1 T\<^isub>2. T=T\<^isub>1\<rightarrow>T\<^isub>2) \<or> T=TUnit \<or> T=TBase" |
48 by (induct T rule:ty.weak_induct) (auto) |
48 by (induct T rule:ty.induct) (auto) |
49 |
49 |
50 instance ty :: size .. |
50 instance ty :: size .. |
51 |
51 |
52 nominal_primrec |
52 nominal_primrec |
53 "size (TBase) = 1" |
53 "size (TBase) = 1" |
117 by (simp_all add: fresh_list_cons fresh_list_nil) |
117 by (simp_all add: fresh_list_cons fresh_list_nil) |
118 |
118 |
119 lemma subst_eqvt[eqvt]: |
119 lemma subst_eqvt[eqvt]: |
120 fixes pi::"name prm" |
120 fixes pi::"name prm" |
121 shows "pi\<bullet>(t[x::=t']) = (pi\<bullet>t)[(pi\<bullet>x)::=(pi\<bullet>t')]" |
121 shows "pi\<bullet>(t[x::=t']) = (pi\<bullet>t)[(pi\<bullet>x)::=(pi\<bullet>t')]" |
122 by (nominal_induct t avoiding: x t' rule: trm.induct) |
122 by (nominal_induct t avoiding: x t' rule: trm.strong_induct) |
123 (perm_simp add: fresh_bij)+ |
123 (perm_simp add: fresh_bij)+ |
124 |
124 |
125 lemma subst_rename: |
125 lemma subst_rename: |
126 fixes c::"name" |
126 fixes c::"name" |
127 assumes a: "c\<sharp>t\<^isub>1" |
127 assumes a: "c\<sharp>t\<^isub>1" |
128 shows "t\<^isub>1[a::=t\<^isub>2] = ([(c,a)]\<bullet>t\<^isub>1)[c::=t\<^isub>2]" |
128 shows "t\<^isub>1[a::=t\<^isub>2] = ([(c,a)]\<bullet>t\<^isub>1)[c::=t\<^isub>2]" |
129 using a |
129 using a |
130 apply(nominal_induct t\<^isub>1 avoiding: a c t\<^isub>2 rule: trm.induct) |
130 apply(nominal_induct t\<^isub>1 avoiding: a c t\<^isub>2 rule: trm.strong_induct) |
131 apply(simp add: trm.inject calc_atm fresh_atm abs_fresh perm_nat_def)+ |
131 apply(simp add: trm.inject calc_atm fresh_atm abs_fresh perm_nat_def)+ |
132 done |
132 done |
133 |
133 |
134 lemma fresh_psubst: |
134 lemma fresh_psubst: |
135 fixes z::"name" |
135 fixes z::"name" |
136 assumes a: "z\<sharp>t" "z\<sharp>\<theta>" |
136 assumes a: "z\<sharp>t" "z\<sharp>\<theta>" |
137 shows "z\<sharp>(\<theta><t>)" |
137 shows "z\<sharp>(\<theta><t>)" |
138 using a |
138 using a |
139 by (nominal_induct t avoiding: z \<theta> t rule: trm.induct) |
139 by (nominal_induct t avoiding: z \<theta> t rule: trm.strong_induct) |
140 (auto simp add: abs_fresh lookup_fresh) |
140 (auto simp add: abs_fresh lookup_fresh) |
141 |
141 |
142 lemma fresh_subst'': |
142 lemma fresh_subst'': |
143 fixes z::"name" |
143 fixes z::"name" |
144 assumes "z\<sharp>t\<^isub>2" |
144 assumes "z\<sharp>t\<^isub>2" |
145 shows "z\<sharp>t\<^isub>1[z::=t\<^isub>2]" |
145 shows "z\<sharp>t\<^isub>1[z::=t\<^isub>2]" |
146 using assms |
146 using assms |
147 by (nominal_induct t\<^isub>1 avoiding: t\<^isub>2 z rule: trm.induct) |
147 by (nominal_induct t\<^isub>1 avoiding: t\<^isub>2 z rule: trm.strong_induct) |
148 (auto simp add: abs_fresh fresh_nat fresh_atm) |
148 (auto simp add: abs_fresh fresh_nat fresh_atm) |
149 |
149 |
150 lemma fresh_subst': |
150 lemma fresh_subst': |
151 fixes z::"name" |
151 fixes z::"name" |
152 assumes "z\<sharp>[y].t\<^isub>1" "z\<sharp>t\<^isub>2" |
152 assumes "z\<sharp>[y].t\<^isub>1" "z\<sharp>t\<^isub>2" |
153 shows "z\<sharp>t\<^isub>1[y::=t\<^isub>2]" |
153 shows "z\<sharp>t\<^isub>1[y::=t\<^isub>2]" |
154 using assms |
154 using assms |
155 by (nominal_induct t\<^isub>1 avoiding: y t\<^isub>2 z rule: trm.induct) |
155 by (nominal_induct t\<^isub>1 avoiding: y t\<^isub>2 z rule: trm.strong_induct) |
156 (auto simp add: abs_fresh fresh_nat fresh_atm) |
156 (auto simp add: abs_fresh fresh_nat fresh_atm) |
157 |
157 |
158 lemma fresh_subst: |
158 lemma fresh_subst: |
159 fixes z::"name" |
159 fixes z::"name" |
160 assumes a: "z\<sharp>t\<^isub>1" "z\<sharp>t\<^isub>2" |
160 assumes a: "z\<sharp>t\<^isub>1" "z\<sharp>t\<^isub>2" |
164 |
164 |
165 lemma fresh_psubst_simp: |
165 lemma fresh_psubst_simp: |
166 assumes "x\<sharp>t" |
166 assumes "x\<sharp>t" |
167 shows "((x,u)#\<theta>)<t> = \<theta><t>" |
167 shows "((x,u)#\<theta>)<t> = \<theta><t>" |
168 using assms |
168 using assms |
169 proof (nominal_induct t avoiding: x u \<theta> rule: trm.induct) |
169 proof (nominal_induct t avoiding: x u \<theta> rule: trm.strong_induct) |
170 case (Lam y t x u) |
170 case (Lam y t x u) |
171 have fs: "y\<sharp>\<theta>" "y\<sharp>x" "y\<sharp>u" by fact+ |
171 have fs: "y\<sharp>\<theta>" "y\<sharp>x" "y\<sharp>u" by fact+ |
172 moreover have "x\<sharp> Lam [y].t" by fact |
172 moreover have "x\<sharp> Lam [y].t" by fact |
173 ultimately have "x\<sharp>t" by (simp add: abs_fresh fresh_atm) |
173 ultimately have "x\<sharp>t" by (simp add: abs_fresh fresh_atm) |
174 moreover have ih:"\<And>n T. n\<sharp>t \<Longrightarrow> ((n,T)#\<theta>)<t> = \<theta><t>" by fact |
174 moreover have ih:"\<And>n T. n\<sharp>t \<Longrightarrow> ((n,T)#\<theta>)<t> = \<theta><t>" by fact |
182 lemma forget: |
182 lemma forget: |
183 fixes x::"name" |
183 fixes x::"name" |
184 assumes a: "x\<sharp>t" |
184 assumes a: "x\<sharp>t" |
185 shows "t[x::=t'] = t" |
185 shows "t[x::=t'] = t" |
186 using a |
186 using a |
187 by (nominal_induct t avoiding: x t' rule: trm.induct) |
187 by (nominal_induct t avoiding: x t' rule: trm.strong_induct) |
188 (auto simp add: fresh_atm abs_fresh) |
188 (auto simp add: fresh_atm abs_fresh) |
189 |
189 |
190 lemma subst_fun_eq: |
190 lemma subst_fun_eq: |
191 fixes u::trm |
191 fixes u::trm |
192 assumes h:"[x].t\<^isub>1 = [y].t\<^isub>2" |
192 assumes h:"[x].t\<^isub>1 = [y].t\<^isub>2" |
205 ultimately show ?thesis using alpha h by blast |
205 ultimately show ?thesis using alpha h by blast |
206 qed |
206 qed |
207 |
207 |
208 lemma psubst_empty[simp]: |
208 lemma psubst_empty[simp]: |
209 shows "[]<t> = t" |
209 shows "[]<t> = t" |
210 by (nominal_induct t rule: trm.induct) |
210 by (nominal_induct t rule: trm.strong_induct) |
211 (auto simp add: fresh_list_nil) |
211 (auto simp add: fresh_list_nil) |
212 |
212 |
213 lemma psubst_subst_psubst: |
213 lemma psubst_subst_psubst: |
214 assumes h:"c\<sharp>\<theta>" |
214 assumes h:"c\<sharp>\<theta>" |
215 shows "\<theta><t>[c::=s] = ((c,s)#\<theta>)<t>" |
215 shows "\<theta><t>[c::=s] = ((c,s)#\<theta>)<t>" |
216 using h |
216 using h |
217 by (nominal_induct t avoiding: \<theta> c s rule: trm.induct) |
217 by (nominal_induct t avoiding: \<theta> c s rule: trm.strong_induct) |
218 (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh' fresh_psubst) |
218 (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh' fresh_psubst) |
219 |
219 |
220 lemma subst_fresh_simp: |
220 lemma subst_fresh_simp: |
221 assumes a: "x\<sharp>\<theta>" |
221 assumes a: "x\<sharp>\<theta>" |
222 shows "\<theta><Var x> = Var x" |
222 shows "\<theta><Var x> = Var x" |
225 |
225 |
226 lemma psubst_subst_propagate: |
226 lemma psubst_subst_propagate: |
227 assumes "x\<sharp>\<theta>" |
227 assumes "x\<sharp>\<theta>" |
228 shows "\<theta><t[x::=u]> = \<theta><t>[x::=\<theta><u>]" |
228 shows "\<theta><t[x::=u]> = \<theta><t>[x::=\<theta><u>]" |
229 using assms |
229 using assms |
230 proof (nominal_induct t avoiding: x u \<theta> rule: trm.induct) |
230 proof (nominal_induct t avoiding: x u \<theta> rule: trm.strong_induct) |
231 case (Var n x u \<theta>) |
231 case (Var n x u \<theta>) |
232 { assume "x=n" |
232 { assume "x=n" |
233 moreover have "x\<sharp>\<theta>" by fact |
233 moreover have "x\<sharp>\<theta>" by fact |
234 ultimately have "\<theta><Var n[x::=u]> = \<theta><Var n>[x::=\<theta><u>]" using subst_fresh_simp by auto |
234 ultimately have "\<theta><Var n[x::=u]> = \<theta><Var n>[x::=\<theta><u>]" using subst_fresh_simp by auto |
235 } |
235 } |
652 qed (auto) |
652 qed (auto) |
653 |
653 |
654 lemma main_lemma: |
654 lemma main_lemma: |
655 shows "\<Gamma> \<turnstile> s is t : T \<Longrightarrow> valid \<Gamma> \<Longrightarrow> \<Gamma> \<turnstile> s \<Leftrightarrow> t : T" |
655 shows "\<Gamma> \<turnstile> s is t : T \<Longrightarrow> valid \<Gamma> \<Longrightarrow> \<Gamma> \<turnstile> s \<Leftrightarrow> t : T" |
656 and "\<Gamma> \<turnstile> p \<leftrightarrow> q : T \<Longrightarrow> \<Gamma> \<turnstile> p is q : T" |
656 and "\<Gamma> \<turnstile> p \<leftrightarrow> q : T \<Longrightarrow> \<Gamma> \<turnstile> p is q : T" |
657 proof (nominal_induct T arbitrary: \<Gamma> s t p q rule: ty.induct) |
657 proof (nominal_induct T arbitrary: \<Gamma> s t p q rule: ty.strong_induct) |
658 case (Arrow T\<^isub>1 T\<^isub>2) |
658 case (Arrow T\<^isub>1 T\<^isub>2) |
659 { |
659 { |
660 case (1 \<Gamma> s t) |
660 case (1 \<Gamma> s t) |
661 have ih1:"\<And>\<Gamma> s t. \<lbrakk>\<Gamma> \<turnstile> s is t : T\<^isub>2; valid \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> s \<Leftrightarrow> t : T\<^isub>2" by fact |
661 have ih1:"\<And>\<Gamma> s t. \<lbrakk>\<Gamma> \<turnstile> s is t : T\<^isub>2; valid \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> s \<Leftrightarrow> t : T\<^isub>2" by fact |
662 have ih2:"\<And>\<Gamma> s t. \<Gamma> \<turnstile> s \<leftrightarrow> t : T\<^isub>1 \<Longrightarrow> \<Gamma> \<turnstile> s is t : T\<^isub>1" by fact |
662 have ih2:"\<And>\<Gamma> s t. \<Gamma> \<turnstile> s \<leftrightarrow> t : T\<^isub>1 \<Longrightarrow> \<Gamma> \<turnstile> s is t : T\<^isub>1" by fact |
702 |
702 |
703 lemma logical_symmetry: |
703 lemma logical_symmetry: |
704 assumes a: "\<Gamma> \<turnstile> s is t : T" |
704 assumes a: "\<Gamma> \<turnstile> s is t : T" |
705 shows "\<Gamma> \<turnstile> t is s : T" |
705 shows "\<Gamma> \<turnstile> t is s : T" |
706 using a |
706 using a |
707 by (nominal_induct arbitrary: \<Gamma> s t rule: ty.induct) |
707 by (nominal_induct arbitrary: \<Gamma> s t rule: ty.strong_induct) |
708 (auto simp add: algorithmic_symmetry) |
708 (auto simp add: algorithmic_symmetry) |
709 |
709 |
710 lemma logical_transitivity: |
710 lemma logical_transitivity: |
711 assumes "\<Gamma> \<turnstile> s is t : T" "\<Gamma> \<turnstile> t is u : T" |
711 assumes "\<Gamma> \<turnstile> s is t : T" "\<Gamma> \<turnstile> t is u : T" |
712 shows "\<Gamma> \<turnstile> s is u : T" |
712 shows "\<Gamma> \<turnstile> s is u : T" |
713 using assms |
713 using assms |
714 proof (nominal_induct arbitrary: \<Gamma> s t u rule:ty.induct) |
714 proof (nominal_induct arbitrary: \<Gamma> s t u rule:ty.strong_induct) |
715 case TBase |
715 case TBase |
716 then show "\<Gamma> \<turnstile> s is u : TBase" by (auto elim: algorithmic_transitivity) |
716 then show "\<Gamma> \<turnstile> s is u : TBase" by (auto elim: algorithmic_transitivity) |
717 next |
717 next |
718 case (Arrow T\<^isub>1 T\<^isub>2 \<Gamma> s t u) |
718 case (Arrow T\<^isub>1 T\<^isub>2 \<Gamma> s t u) |
719 have h1:"\<Gamma> \<turnstile> s is t : T\<^isub>1 \<rightarrow> T\<^isub>2" by fact |
719 have h1:"\<Gamma> \<turnstile> s is t : T\<^isub>1 \<rightarrow> T\<^isub>2" by fact |
736 assumes a: "\<Gamma> \<turnstile> s is t : T" |
736 assumes a: "\<Gamma> \<turnstile> s is t : T" |
737 and b: "s' \<leadsto> s" |
737 and b: "s' \<leadsto> s" |
738 and c: "t' \<leadsto> t" |
738 and c: "t' \<leadsto> t" |
739 shows "\<Gamma> \<turnstile> s' is t' : T" |
739 shows "\<Gamma> \<turnstile> s' is t' : T" |
740 using a b c algorithmic_weak_head_closure |
740 using a b c algorithmic_weak_head_closure |
741 by (nominal_induct arbitrary: \<Gamma> s t s' t' rule: ty.induct) |
741 by (nominal_induct arbitrary: \<Gamma> s t s' t' rule: ty.strong_induct) |
742 (auto, blast) |
742 (auto, blast) |
743 |
743 |
744 lemma logical_weak_head_closure': |
744 lemma logical_weak_head_closure': |
745 assumes "\<Gamma> \<turnstile> s is t : T" and "s' \<leadsto> s" |
745 assumes "\<Gamma> \<turnstile> s is t : T" and "s' \<leadsto> s" |
746 shows "\<Gamma> \<turnstile> s' is t : T" |
746 shows "\<Gamma> \<turnstile> s' is t : T" |
747 using assms |
747 using assms |
748 proof (nominal_induct arbitrary: \<Gamma> s t s' rule: ty.induct) |
748 proof (nominal_induct arbitrary: \<Gamma> s t s' rule: ty.strong_induct) |
749 case (TBase \<Gamma> s t s') |
749 case (TBase \<Gamma> s t s') |
750 then show ?case by force |
750 then show ?case by force |
751 next |
751 next |
752 case (TUnit \<Gamma> s t s') |
752 case (TUnit \<Gamma> s t s') |
753 then show ?case by auto |
753 then show ?case by auto |