-
Notifications
You must be signed in to change notification settings - Fork 0
/
Soundness.thy
323 lines (311 loc) · 15.9 KB
/
Soundness.thy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
section \<open>Soundness\<close>
theory Soundness
imports ProverLemmas
begin
text \<open>In this theory, we prove that the prover is sound with regards to the SeCaV proof system
using the abstract soundness framework.\<close>
text \<open>If some suffix of the sequents in all of the children of a state are provable, so is some
suffix of the sequent in the current state, with the prefix in each sequent being the same.
(As a side condition, the lists of terms need to be compatible.)\<close>
lemma SeCaV_children_pre:
assumes \<open>\<forall>z' \<in> set (children A r z). (\<tturnstile> pre @ z')\<close>
and \<open>paramss (pre @ z) \<subseteq> paramsts A\<close>
shows \<open>\<tturnstile> pre @ z\<close>
using assms
proof (induct z arbitrary: pre A)
case Nil
then show ?case
by simp
next
case (Cons p z)
then have ih: \<open>\<forall>z' \<in> set (children A r z). (\<tturnstile> pre @ z') \<Longrightarrow> (\<tturnstile> pre @ z)\<close>
if \<open>paramss (pre @ z) \<subseteq> paramsts A\<close> for pre A
using that by simp
let ?A = \<open>remdups (A @ subtermFms (concat (parts A r p)))\<close>
have A: \<open>paramss (pre @ p # z) \<subseteq> paramsts ?A\<close>
using paramsts_subset Cons.prems(2) by fastforce
have \<open>\<forall>z' \<in> set (list_prod (parts A r p) (children ?A r z)). (\<tturnstile> pre @ z')\<close>
using Cons.prems by (metis children.simps(2))
then have \<open>\<forall>z' \<in> {hs @ ts |hs ts. hs \<in> set (parts A r p) \<and> ts \<in> set (children ?A r z)}.
(\<tturnstile> pre @ z')\<close>
using list_prod_is_cartesian by blast
then have *:
\<open>\<forall>hs \<in> set (parts A r p). \<forall>ts \<in> set (children ?A r z). (\<tturnstile> pre @ hs @ ts)\<close>
by blast
then show ?case
proof (cases r p rule: parts_exhaust)
case (AlphaDis p q)
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ p # q # z')\<close>
using * unfolding parts_def by simp
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [p, q]) @ z')\<close>
by simp
then have \<open>\<tturnstile> pre @ p # q # z\<close>
using AlphaDis ih[where pre=\<open>pre @ [p, q]\<close> and A=\<open>?A\<close>] A by simp
then have \<open>\<tturnstile> p # q # pre @ z\<close>
using Ext by simp
then have \<open>\<tturnstile> Dis p q # pre @ z\<close>
using SeCaV.AlphaDis by blast
then show ?thesis
using AlphaDis Ext by simp
next
case (AlphaImp p q)
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ Neg p # q # z')\<close>
using * unfolding parts_def by simp
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [Neg p, q]) @ z')\<close>
by simp
then have \<open>\<tturnstile> pre @ Neg p # q # z\<close>
using AlphaImp ih[where pre=\<open>pre @ [Neg p, q]\<close> and A=\<open>?A\<close>] A by simp
then have \<open>\<tturnstile> Neg p # q # pre @ z\<close>
using Ext by simp
then have \<open>\<tturnstile> Imp p q # pre @ z\<close>
using SeCaV.AlphaImp by blast
then show ?thesis
using AlphaImp Ext by simp
next
case (AlphaCon p q)
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ Neg p # Neg q # z')\<close>
using * unfolding parts_def by simp
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [Neg p, Neg q]) @ z')\<close>
by simp
then have \<open>\<tturnstile> pre @ Neg p # Neg q # z\<close>
using AlphaCon ih[where pre=\<open>pre @ [Neg p, Neg q]\<close> and A=\<open>?A\<close>] A by simp
then have \<open>\<tturnstile> Neg p # Neg q # pre @ z\<close>
using Ext by simp
then have \<open>\<tturnstile> Neg (Con p q) # pre @ z\<close>
using SeCaV.AlphaCon by blast
then show ?thesis
using AlphaCon Ext by simp
next
case (BetaCon p q)
then have
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ p # z')\<close>
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ q # z')\<close>
using * unfolding parts_def by simp_all
then have
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [p]) @ z')\<close>
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [q]) @ z')\<close>
by simp_all
then have \<open>\<tturnstile> pre @ p # z\<close> \<open>\<tturnstile> pre @ q # z\<close>
using BetaCon ih[where pre=\<open>pre @ [_]\<close> and A=\<open>?A\<close>] A by simp_all
then have \<open>\<tturnstile> p # pre @ z\<close> \<open>\<tturnstile> q # pre @ z\<close>
using Ext by simp_all
then have \<open>\<tturnstile> Con p q # pre @ z\<close>
using SeCaV.BetaCon by blast
then show ?thesis
using BetaCon Ext by simp
next
case (BetaImp p q)
then have
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ p # z')\<close>
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ Neg q # z')\<close>
using * unfolding parts_def by simp_all
then have
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [p]) @ z')\<close>
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [Neg q]) @ z')\<close>
by simp_all
then have \<open>\<tturnstile> pre @ p # z\<close> \<open>\<tturnstile> pre @ Neg q # z\<close>
using BetaImp ih ih[where pre=\<open>pre @ [_]\<close> and A=\<open>?A\<close>] A by simp_all
then have \<open>\<tturnstile> p # pre @ z\<close> \<open>\<tturnstile> Neg q # pre @ z\<close>
using Ext by simp_all
then have \<open>\<tturnstile> Neg (Imp p q) # pre @ z\<close>
using SeCaV.BetaImp by blast
then show ?thesis
using BetaImp Ext by simp
next
case (BetaDis p q)
then have
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ Neg p # z')\<close>
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ Neg q # z')\<close>
using * unfolding parts_def by simp_all
then have
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [Neg p]) @ z')\<close>
\<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [Neg q]) @ z')\<close>
by simp_all
then have \<open>\<tturnstile> pre @ Neg p # z\<close> \<open>\<tturnstile> pre @ Neg q # z\<close>
using BetaDis ih[where pre=\<open>pre @ [_]\<close> and A=\<open>?A\<close>] A by simp_all
then have \<open>\<tturnstile> Neg p # pre @ z\<close> \<open>\<tturnstile> Neg q # pre @ z\<close>
using Ext by simp_all
then have \<open>\<tturnstile> Neg (Dis p q) # pre @ z\<close>
using SeCaV.BetaDis by blast
then show ?thesis
using BetaDis Ext by simp
next
case (DeltaUni p)
let ?i = \<open>generateNew A\<close>
have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ sub 0 (Fun ?i []) p # z')\<close>
using DeltaUni * unfolding parts_def by simp
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [sub 0 (Fun ?i []) p]) @ z')\<close>
by simp
moreover have \<open>set (subtermFm (sub 0 (Fun ?i []) p)) \<subseteq> set ?A\<close>
using DeltaUni unfolding parts_def by simp
then have \<open>params (sub 0 (Fun ?i []) p) \<subseteq> paramsts ?A\<close>
using subtermFm_subset_params by blast
ultimately have \<open>\<tturnstile> pre @ sub 0 (Fun ?i []) p # z\<close>
using DeltaUni ih[where pre=\<open>pre @ [_]\<close> and A=\<open>?A\<close>] A by simp
then have \<open>\<tturnstile> sub 0 (Fun ?i []) p # pre @ z\<close>
using Ext by simp
moreover have \<open>?i \<notin> paramsts A\<close>
by (induct A) (metis Suc_max_new generateNew_def listFunTm_paramst(2) plus_1_eq_Suc)+
then have \<open>news ?i (p # pre @ z)\<close>
using DeltaUni Cons.prems(2) news_paramss by auto
ultimately have \<open>\<tturnstile> Uni p # pre @ z\<close>
using SeCaV.DeltaUni by blast
then show ?thesis
using DeltaUni Ext by simp
next
case (DeltaExi p)
let ?i = \<open>generateNew A\<close>
have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ Neg (sub 0 (Fun ?i []) p) # z')\<close>
using DeltaExi * unfolding parts_def by simp
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [Neg (sub 0 (Fun ?i []) p)]) @ z')\<close>
by simp
moreover have \<open>set (subtermFm (sub 0 (Fun ?i []) p)) \<subseteq> set ?A\<close>
using DeltaExi unfolding parts_def by simp
then have \<open>params (sub 0 (Fun ?i []) p) \<subseteq> paramsts ?A\<close>
using subtermFm_subset_params by blast
ultimately have \<open>\<tturnstile> pre @ Neg (sub 0 (Fun ?i []) p) # z\<close>
using DeltaExi ih[where pre=\<open>pre @ [_]\<close> and A=\<open>?A\<close>] A by simp
then have \<open>\<tturnstile> Neg (sub 0 (Fun ?i []) p) # pre @ z\<close>
using Ext by simp
moreover have \<open>?i \<notin> paramsts A\<close>
by (induct A) (metis Suc_max_new generateNew_def listFunTm_paramst(2) plus_1_eq_Suc)+
then have \<open>news ?i (p # pre @ z)\<close>
using DeltaExi Cons.prems(2) news_paramss by auto
ultimately have \<open>\<tturnstile> Neg (Exi p) # pre @ z\<close>
using SeCaV.DeltaExi by blast
then show ?thesis
using DeltaExi Ext by simp
next
case (NegNeg p)
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ p # z')\<close>
using * unfolding parts_def by simp
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [p]) @ z')\<close>
by simp
then have \<open>\<tturnstile> pre @ p # z\<close>
using NegNeg ih[where pre=\<open>pre @ [_]\<close> and A=\<open>?A\<close>] A by simp
then have \<open>\<tturnstile> p # pre @ z\<close>
using Ext by simp
then have \<open>\<tturnstile> Neg (Neg p) # pre @ z\<close>
using SeCaV.Neg by blast
then show ?thesis
using NegNeg Ext by simp
next
case (GammaExi p)
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ Exi p # map (\<lambda>t. sub 0 t p) A @ z')\<close>
using * unfolding parts_def by simp
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> ((pre @ Exi p # map (\<lambda>t. sub 0 t p) A) @ z'))\<close>
by simp
moreover have \<open>\<forall>t \<in> set A. params (sub 0 t p) \<subseteq> paramsts A \<union> params p\<close>
using params_sub by fastforce
then have \<open>\<forall>t \<in> set A. params (sub 0 t p) \<subseteq> paramsts ?A\<close>
using GammaExi A by fastforce
then have \<open>paramss (map (\<lambda>t. sub 0 t p) A) \<subseteq> paramsts ?A\<close>
by auto
ultimately have \<open>\<tturnstile> pre @ Exi p # map (\<lambda>t. sub 0 t p) A @ z\<close>
using GammaExi ih[where pre=\<open>pre @ Exi p # map _ A\<close> and A=\<open>?A\<close>] A by simp
moreover have \<open>ext (map (\<lambda>t. sub 0 t p) A @ Exi p # pre @ z)
(pre @ Exi p # map (\<lambda>t. sub 0 t p) A @ z)\<close>
by auto
ultimately have \<open>\<tturnstile> map (\<lambda>t. sub 0 t p) A @ Exi p # pre @ z\<close>
using Ext by blast
then have \<open>\<tturnstile> Exi p # pre @ z\<close>
proof (induct A)
case Nil
then show ?case
by simp
next
case (Cons a A)
then have \<open>\<tturnstile> Exi p # map (\<lambda>t. sub 0 t p) A @ Exi p # pre @ z\<close>
using SeCaV.GammaExi by simp
then have \<open>\<tturnstile> map (\<lambda>t. sub 0 t p) A @ Exi p # pre @ z\<close>
using Ext by simp
then show ?case
using Cons.hyps by blast
qed
then show ?thesis
using GammaExi Ext by simp
next
case (GammaUni p)
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> pre @ Neg (Uni p) # map (\<lambda>t. Neg (sub 0 t p)) A @ z')\<close>
using * unfolding parts_def by simp
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> ((pre @ Neg (Uni p) # map (\<lambda>t. Neg (sub 0 t p)) A) @ z'))\<close>
by simp
moreover have \<open>\<forall>t \<in> set A. params (sub 0 t p) \<subseteq> paramsts A \<union> params p\<close>
using params_sub by fastforce
then have \<open>\<forall>t \<in> set A. params (sub 0 t p) \<subseteq> paramsts ?A\<close>
using GammaUni A by fastforce
then have \<open>paramss (map (\<lambda>t. sub 0 t p) A) \<subseteq> paramsts ?A\<close>
by auto
ultimately have \<open>\<tturnstile> pre @ Neg (Uni p) # map (\<lambda>t. Neg (sub 0 t p)) A @ z\<close>
using GammaUni ih[where pre=\<open>pre @ Neg (Uni p) # map _ A\<close> and A=\<open>?A\<close>] A by simp
moreover have \<open>ext (map (\<lambda>t. Neg (sub 0 t p)) A @ Neg (Uni p) # pre @ z)
(pre @ Neg (Uni p) # map (\<lambda>t. Neg (sub 0 t p)) A @ z)\<close>
by auto
ultimately have \<open>\<tturnstile> map (\<lambda>t. Neg (sub 0 t p)) A @ Neg (Uni p) # pre @ z\<close>
using Ext by blast
then have \<open>\<tturnstile> Neg (Uni p) # pre @ z\<close>
proof (induct A)
case Nil
then show ?case
by simp
next
case (Cons a A)
then have \<open>\<tturnstile> Neg (Uni p) # map (\<lambda>t. Neg (sub 0 t p)) A @ Neg (Uni p) # pre @ z\<close>
using SeCaV.GammaUni by simp
then have \<open>\<tturnstile> map (\<lambda>t. Neg (sub 0 t p)) A @ Neg (Uni p) # pre @ z\<close>
using Ext by simp
then show ?case
using Cons.hyps by blast
qed
then show ?thesis
using GammaUni Ext by simp
next
case Other
then have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> (pre @ [p]) @ z')\<close>
using * by simp
then show ?thesis
using ih[where pre=\<open>pre @ [p]\<close> and A=\<open>?A\<close>] A by simp
qed
qed
text \<open>As a special case, the prefix can be empty.\<close>
corollary SeCaV_children:
assumes \<open>\<forall>z' \<in> set (children A r z). (\<tturnstile> z')\<close> and \<open>paramss z \<subseteq> paramsts A\<close>
shows \<open>\<tturnstile> z\<close>
using SeCaV_children_pre assms by (metis append_Nil)
text \<open>Using this lemma, we can instantiate the abstract soundness framework.\<close>
interpretation Soundness eff rules UNIV \<open>\<lambda>_ (A, z). (\<tturnstile> z)\<close>
unfolding Soundness_def
proof safe
fix r A z ss S
assume r_enabled: \<open>eff r (A, z) ss\<close>
assume \<open>\<forall>s'. s' |\<in>| ss \<longrightarrow> (\<forall>S \<in> UNIV. case s' of (A, z) \<Rightarrow> \<tturnstile> z)\<close>
then have next_sound: \<open>\<forall>B z. (B, z) |\<in>| ss \<longrightarrow> (\<tturnstile> z)\<close>
by simp
show \<open>\<tturnstile> z\<close>
proof (cases \<open>branchDone z\<close>)
case True
then obtain p where \<open>p \<in> set z\<close> \<open>Neg p \<in> set z\<close>
using branchDone_contradiction by blast
then show ?thesis
using Ext Basic by fastforce
next
case False
let ?A = \<open>remdups (A @ subtermFms z)\<close>
have \<open>\<forall>z' \<in> set (children ?A r z). (\<tturnstile> z')\<close>
using False r_enabled eff_children next_sound by blast
moreover have \<open>set (subtermFms z) \<subseteq> set ?A\<close>
by simp
then have \<open>paramss z \<subseteq> paramsts ?A\<close>
using subtermFm_subset_params by fastforce
ultimately show \<open>\<tturnstile> z\<close>
using SeCaV_children by blast
qed
qed
text \<open>Using the result from the abstract soundness framework, we can finally state our soundness
result: for a finite, well-formed proof tree, the sequent at the root of the tree is provable in
the SeCaV proof system.\<close>
theorem prover_soundness_SeCaV:
assumes \<open>tfinite t\<close> and \<open>wf t\<close>
shows \<open>\<tturnstile> rootSequent t\<close>
using assms soundness by fastforce
end