author | paulson |
Fri, 08 Apr 2005 18:43:39 +0200 | |
changeset 15684 | 5ec4d21889d6 |
parent 15642 | 028059faa963 |
child 15697 | 681bcb7f0389 |
permissions | -rw-r--r-- |
15642 | 1 |
|
2 |
||
3 |
(*----------------------------------------------*) |
|
4 |
(* Reorder clauses for use in binary resolution *) |
|
5 |
(*----------------------------------------------*) |
|
6 |
fun take n [] = [] |
|
7 |
| take n (x::xs) = (if n = 0 then [] else (x::(take (n - 1) xs))) |
|
8 |
||
9 |
fun drop n [] = [] |
|
10 |
| drop n (x::xs) = (if n = 0 then (x::xs) else drop (n-1) xs) |
|
11 |
||
12 |
fun remove n [] = [] |
|
13 |
| remove n (x::xs) = List.filter (not_equal n) (x::xs); |
|
14 |
||
15 |
fun remove_nth n [] = [] |
|
16 |
| remove_nth n (x::xs) = (take (n -1) (x::xs))@(drop n (x::xs)) |
|
17 |
||
18 |
fun get_nth n (x::xs) = hd (drop (n-1) (x::xs)) |
|
19 |
||
20 |
||
21 |
fun literals (Const("Trueprop",_) $ P) = literals P |
|
22 |
| literals (Const("op |",_) $ P $ Q) = literals P @ literals Q |
|
23 |
| literals (Const("Not",_) $ P) = [(false,P)] |
|
24 |
| literals P = [(true,P)]; |
|
25 |
||
26 |
(*number of literals in a term*) |
|
27 |
val nliterals = length o literals; |
|
28 |
||
29 |
exception Not_in_list; |
|
30 |
||
31 |
||
32 |
||
33 |
||
34 |
(* get the literals from a disjunctive clause *) |
|
35 |
||
36 |
(*fun get_disj_literals t = if is_disj t then |
|
37 |
let |
|
38 |
val {disj1, disj2} = dest_disj t |
|
39 |
in |
|
40 |
disj1::(get_disj_literals disj2) |
|
41 |
end |
|
42 |
else |
|
43 |
([t]) |
|
44 |
||
45 |
*) |
|
46 |
||
47 |
(* |
|
48 |
(* gives horn clause with kth disj as concl (starting at 1) *) |
|
49 |
fun rots (0,th) = (Meson.make_horn Meson.crules th) |
|
50 |
| rots (k,th) = rots(k-1, assoc_right (th RS disj_comm)) |
|
51 |
||
52 |
||
53 |
||
54 |
Goal " (~~P) == P"; |
|
55 |
by Auto_tac; |
|
56 |
qed "notnotEq"; |
|
57 |
||
58 |
Goal "A | A ==> A"; |
|
59 |
by Auto_tac; |
|
60 |
qed "rem_dup_disj"; |
|
61 |
||
62 |
||
63 |
||
64 |
||
65 |
(* New Meson code Versions of make_neg_rule and make_pos_rule that don't insert new *) |
|
66 |
(* assumptions, for ordinary resolution. *) |
|
67 |
||
68 |
||
69 |
||
70 |
||
71 |
val not_conjD = thm "meson_not_conjD"; |
|
72 |
val not_disjD = thm "meson_not_disjD"; |
|
73 |
val not_notD = thm "meson_not_notD"; |
|
74 |
val not_allD = thm "meson_not_allD"; |
|
75 |
val not_exD = thm "meson_not_exD"; |
|
76 |
val imp_to_disjD = thm "meson_imp_to_disjD"; |
|
77 |
val not_impD = thm "meson_not_impD"; |
|
78 |
val iff_to_disjD = thm "meson_iff_to_disjD"; |
|
79 |
val not_iffD = thm "meson_not_iffD"; |
|
80 |
val conj_exD1 = thm "meson_conj_exD1"; |
|
81 |
val conj_exD2 = thm "meson_conj_exD2"; |
|
82 |
val disj_exD = thm "meson_disj_exD"; |
|
83 |
val disj_exD1 = thm "meson_disj_exD1"; |
|
84 |
val disj_exD2 = thm "meson_disj_exD2"; |
|
85 |
val disj_assoc = thm "meson_disj_assoc"; |
|
86 |
val disj_comm = thm "meson_disj_comm"; |
|
87 |
val disj_FalseD1 = thm "meson_disj_FalseD1"; |
|
88 |
val disj_FalseD2 = thm "meson_disj_FalseD2"; |
|
89 |
||
90 |
||
91 |
fun literals (Const("Trueprop",_) $ P) = literals P |
|
92 |
| literals (Const("op |",_) $ P $ Q) = literals P @ literals Q |
|
93 |
| literals (Const("Not",_) $ P) = [(false,P)] |
|
94 |
| literals P = [(true,P)]; |
|
95 |
||
96 |
(*number of literals in a term*) |
|
97 |
val nliterals = length o literals; |
|
98 |
||
99 |
exception Not_in_list; |
|
100 |
||
101 |
||
102 |
(*Permute a rule's premises to move the i-th premise to the last position.*) |
|
103 |
fun make_last i th = |
|
104 |
let val n = nprems_of th |
|
105 |
in if 1 <= i andalso i <= n |
|
106 |
then Thm.permute_prems (i-1) 1 th |
|
107 |
else raise THM("make_last", i, [th]) |
|
108 |
end; |
|
109 |
||
110 |
(*Maps a rule that ends "... ==> P ==> False" to "... ==> ~P" while suppressing |
|
111 |
double-negations.*) |
|
112 |
val negate_head = rewrite_rule [atomize_not, not_not RS eq_reflection]; |
|
113 |
||
114 |
(*Maps the clause [P1,...Pn]==>False to [P1,...,P(i-1),P(i+1),...Pn] ==> ~P*) |
|
115 |
fun select_literal i cl = negate_head (make_last i cl); |
|
116 |
||
117 |
||
118 |
(* get a meta-clause for resolution with correct order of literals *) |
|
119 |
fun get_meta_cl (th,n) = let val lits = nliterals(prop_of th) |
|
120 |
val contra = if lits = 1 |
|
121 |
then |
|
122 |
th |
|
123 |
else |
|
124 |
rots (n,th) |
|
125 |
in |
|
126 |
if lits = 1 |
|
127 |
then |
|
128 |
||
129 |
contra |
|
130 |
else |
|
131 |
rotate_prems (lits - n) contra |
|
132 |
end |
|
133 |
||
134 |
||
135 |
||
136 |
||
137 |
||
138 |
||
139 |
||
140 |
fun zip xs [] = [] |
|
141 |
| zip xs (y::ys) = (case xs of [] => [] | (z::zs) => ((z,y)::zip zs ys)) |
|
142 |
||
143 |
||
144 |
fun unzip [] = ([],[]) |
|
145 |
| unzip((x,y)::pairs) = |
|
146 |
let val (xs,ys) = unzip pairs |
|
147 |
in (x::xs, y::ys) end; |
|
148 |
||
149 |
fun numlist 0 = [] |
|
150 |
| numlist n = (numlist (n - 1))@[n] |
|
151 |
||
152 |
||
153 |
||
154 |
||
155 |
fun last(x::xs) = if xs=[] then x else last xs |
|
156 |
fun butlast []= [] |
|
157 |
| butlast(x::xs) = if xs=[] then [] else (x::(butlast xs)) |
|
158 |
||
159 |
||
160 |
fun minus a b = b - a; |
|
161 |
||
162 |
||
163 |
||
164 |
||
165 |
(* gives meta clause with kth disj as concl (starting at 1) *) |
|
166 |
(*fun rots (0,th) = negate_nead (make_horn resolution_clause_rules th) |
|
167 |
| rots (k,th) = rots(k-1, assoc_right (th RS disj_comm))*) |
|
168 |
||
169 |
||
170 |
(* get a meta-clause for resolution with correct order of literals *) |
|
171 |
fun get_meta_cl (th,n) = let val lits = nliterals(prop_of th) |
|
172 |
val contra = if lits = 1 |
|
173 |
then |
|
174 |
th |
|
175 |
else |
|
176 |
rots (n,th) |
|
177 |
in |
|
178 |
if lits = 1 |
|
179 |
then |
|
180 |
||
181 |
contra |
|
182 |
else |
|
183 |
rotate_prems (lits - n) contra |
|
184 |
end |
|
185 |
*) |
|
186 |
||
187 |
||
188 |
||
189 |
||
190 |
fun zip xs [] = [] |
|
191 |
| zip xs (y::ys) = (case xs of [] => [] | (z::zs) => ((z,y)::zip zs ys)) |
|
192 |
||
193 |
||
194 |
fun unzip [] = ([],[]) |
|
195 |
| unzip((x,y)::pairs) = |
|
196 |
let val (xs,ys) = unzip pairs |
|
197 |
in (x::xs, y::ys) end; |
|
198 |
||
199 |
fun numlist 0 = [] |
|
200 |
| numlist n = (numlist (n - 1))@[n] |
|
201 |
||
202 |
||
203 |
||
204 |
||
205 |
fun last(x::xs) = if xs=[] then x else last xs |
|
206 |
fun butlast []= [] |
|
207 |
| butlast(x::xs) = if xs=[] then [] else (x::(butlast xs)) |
|
208 |
||
209 |
||
210 |
fun minus a b = b - a; |
|
211 |
||
212 |
||
213 |
(* code to rearrange clauses so that they're the same as the parsed in SPASS version *) |
|
214 |
||
15684
5ec4d21889d6
Reconstruction code, now packaged to avoid name clashes
paulson
parents:
15642
diff
changeset
|
215 |
fun assoc3 a [] = raise Recon_Base.Noassoc |
15642 | 216 |
| assoc3 a ((x, y, z)::t) = if a = x then z else assoc3 a t; |
217 |
||
218 |
||
219 |
fun third (a,b,c) = c; |
|
220 |
||
221 |
||
222 |
fun takeUntil ch [] res = (res, []) |
|
223 |
| takeUntil ch (x::xs) res = if x = ch |
|
224 |
then |
|
225 |
(res, xs) |
|
226 |
else |
|
227 |
takeUntil ch xs (res@[x]) |
|
228 |
fun contains_eq str = inlist "=" str |
|
229 |
||
230 |
fun eq_not_neq str = let val uptoeq = fst(takeUntil "=" str []) |
|
231 |
in |
|
232 |
if ((last uptoeq) = "~") |
|
233 |
then |
|
234 |
false |
|
235 |
else |
|
236 |
true |
|
237 |
end |
|
238 |
||
239 |
||
240 |
||
241 |
||
242 |
fun get_eq_strs str = if eq_not_neq str (*not an inequality *) |
|
243 |
then |
|
244 |
let val (left, right) = takeUntil "=" str [] |
|
245 |
in |
|
246 |
((butlast left), (drop 1 right)) |
|
247 |
end |
|
248 |
else (* is an inequality *) |
|
249 |
let val (left, right) = takeUntil "~" str [] |
|
250 |
in |
|
251 |
((butlast left), (drop 2 right)) |
|
252 |
end |
|
253 |
||
254 |
||
255 |
||
256 |
fun switch_equal a x = let val (a_lhs, a_rhs) = get_eq_strs a |
|
257 |
val (x_lhs, x_rhs) = get_eq_strs x |
|
258 |
||
259 |
in |
|
260 |
(a_lhs = x_rhs) andalso (a_rhs = x_lhs) |
|
261 |
end |
|
262 |
||
263 |
fun equal_pair (a,b) = equal a b |
|
264 |
||
265 |
fun is_var_pair (a,b) vars = (a mem vars) andalso (b mem vars) |
|
266 |
||
267 |
fun var_equiv vars (a,b) = (equal_pair (a,b)) orelse (is_var_pair (a,b) vars) |
|
268 |
||
269 |
fun all_true [] = false |
|
270 |
| all_true xs = let val falselist = List.filter (equal false ) xs |
|
271 |
in |
|
272 |
falselist = [] |
|
273 |
end |
|
274 |
||
275 |
||
276 |
||
277 |
fun var_pos_eq vars x y = let val xs = explode x |
|
278 |
val ys = explode y |
|
279 |
in |
|
280 |
if not_equal (length xs) (length ys) |
|
281 |
then |
|
282 |
false |
|
283 |
else |
|
284 |
let val xsys = zip xs ys |
|
285 |
val are_var_pairs = map (var_equiv vars) xsys |
|
286 |
in |
|
287 |
all_true are_var_pairs |
|
288 |
end |
|
289 |
end |
|
290 |
||
291 |
||
292 |
||
293 |
||
294 |
fun pos_in_list a [] allvars (pos_num, symlist, nsymlist) = raise Not_in_list |
|
295 |
|pos_in_list a (x::[]) allvars (pos_num , symlist, nsymlist) = |
|
296 |
let val y = explode x |
|
297 |
val b = explode a |
|
298 |
in |
|
299 |
if b = y |
|
300 |
then |
|
301 |
(pos_num, symlist, nsymlist) |
|
302 |
else |
|
303 |
if (var_pos_eq allvars a x) (* Equal apart from meta-vars having different names *) |
|
304 |
then |
|
305 |
(pos_num, symlist, nsymlist) |
|
306 |
else |
|
307 |
if (contains_eq b) andalso (contains_eq y) |
|
308 |
then |
|
309 |
if (eq_not_neq b) andalso (eq_not_neq y) andalso (switch_equal b y ) (* both are equalities and equal under sym*) |
|
310 |
then |
|
311 |
(pos_num, (pos_num::symlist), nsymlist) (* add pos to symlist *) else |
|
312 |
if not(eq_not_neq b) andalso not(eq_not_neq y) andalso (switch_equal b y ) (* if they're equal under not_sym *) |
|
313 |
then |
|
314 |
(pos_num, (symlist), (pos_num::nsymlist))(* add pos to nsymlist *) |
|
315 |
else |
|
316 |
raise Not_in_list |
|
317 |
else |
|
318 |
raise Not_in_list |
|
319 |
||
320 |
end |
|
321 |
||
322 |
| pos_in_list a (x::xs) allvars (pos_num, symlist, nsymlist) = |
|
323 |
let val y = explode x |
|
324 |
val b = explode a |
|
325 |
in |
|
326 |
if b = y |
|
327 |
then |
|
328 |
(pos_num, symlist, nsymlist) |
|
329 |
||
330 |
else |
|
331 |
if (var_pos_eq allvars a x) (* Equal apart from meta-vars having different names *) |
|
332 |
then |
|
333 |
(pos_num, symlist, nsymlist) |
|
334 |
else |
|
335 |
if (contains_eq b) andalso (contains_eq y) |
|
336 |
then |
|
337 |
if (eq_not_neq b) andalso (eq_not_neq y) andalso (switch_equal b y ) (* both are equalities and equal under sym*) |
|
338 |
then |
|
339 |
(pos_num, (pos_num::symlist), nsymlist) (* add pos to symlist *) else |
|
340 |
if not(eq_not_neq b) andalso not(eq_not_neq y) andalso (switch_equal b y ) (* if they're equal under not_sym *) |
|
341 |
then |
|
342 |
(pos_num, (symlist), (pos_num::nsymlist))(* add pos to nsymlist *) |
|
343 |
else |
|
344 |
pos_in_list a xs allvars((pos_num + 1), symlist, nsymlist) |
|
345 |
else |
|
346 |
pos_in_list a xs allvars((pos_num + 1), symlist, nsymlist) |
|
347 |
||
348 |
end |
|
349 |
||
350 |
||
351 |
||
352 |
||
353 |
||
354 |
||
355 |
||
356 |
(* in |
|
357 |
if b = y |
|
358 |
then |
|
359 |
(pos_num, symlist, nsymlist) |
|
360 |
else if (contains_eq b) andalso (contains_eq y) |
|
361 |
then if (eq_not_neq b) andalso (eq_not_neq y) (* both are equalities*) |
|
362 |
then if (switch_equal b y ) (* if they're equal under sym *) |
|
363 |
then |
|
364 |
(pos_num, (pos_num::symlist), nsymlist) (* add pos to symlist *) |
|
365 |
else |
|
366 |
pos_in_list a xs ((pos_num + 1), symlist, nsymlist) |
|
367 |
else if not(eq_not_neq b) andalso not(eq_not_neq y) (* both are inequalities *) |
|
368 |
then if (switch_equal b y ) (* if they're equal under not_sym *) |
|
369 |
then |
|
370 |
(pos_num, (symlist), (pos_num::nsymlist))(* add pos to nsymlist *) |
|
371 |
else |
|
372 |
pos_in_list a xs ((pos_num + 1), symlist, nsymlist) |
|
373 |
else |
|
374 |
pos_in_list a xs ((pos_num + 1), symlist, nsymlist) |
|
375 |
else |
|
376 |
pos_in_list a xs ((pos_num + 1), symlist, nsymlist) |
|
377 |
else |
|
378 |
pos_in_list a xs ((pos_num + 1), symlist, nsymlist) |
|
379 |
end |
|
380 |
||
381 |
*) |
|
382 |
||
383 |
||
384 |
||
385 |
||
386 |
||
387 |
||
388 |
||
389 |
||
390 |
||
391 |
||
392 |
(* checkorder Spass Isabelle [] *) |
|
393 |
||
394 |
fun checkorder [] strlist allvars (numlist, symlist, not_symlist)= (numlist,symlist, not_symlist) |
|
395 |
| checkorder (x::xs) strlist allvars (numlist, symlist, not_symlist) = |
|
396 |
let val (posnum, symlist', not_symlist') = pos_in_list x strlist allvars (0, symlist, not_symlist) |
|
397 |
in |
|
398 |
checkorder xs strlist allvars ((numlist@[posnum]), symlist', not_symlist') |
|
399 |
end |
|
400 |
||
401 |
fun is_digit ch = |
|
402 |
( ch >= "0" andalso ch <= "9") |
|
403 |
||
404 |
||
405 |
fun is_alpha ch = |
|
406 |
(ch >= "A" andalso ch <= "Z") orelse |
|
407 |
(ch >= "a" andalso ch <= "z") |
|
408 |
||
409 |
||
410 |
fun is_alpha_space_or_neg_or_eq ch = (ch = "~") orelse (is_alpha ch) orelse ( ch = " ")orelse ( ch = "=") |
|
411 |
||
412 |
fun lit_string t = let val termstr = (Sign.string_of_term Mainsign ) t |
|
413 |
val exp_term = explode termstr |
|
414 |
in |
|
415 |
implode(List.filter is_alpha_space_or_neg_or_eq exp_term) |
|
416 |
end |
|
417 |
||
418 |
fun get_meta_lits thm = map lit_string (prems_of thm) |
|
419 |
||
420 |
||
421 |
||
422 |
||
423 |
fun is_alpha_space_or_neg_or_eq_or_bracket ch = (ch = "~") orelse (is_alpha ch) orelse ( ch = " ")orelse ( ch = "=") orelse (ch= "(") orelse (ch = ")") |
|
424 |
||
425 |
fun lit_string_bracket t = let val termstr = (Sign.string_of_term Mainsign ) t |
|
426 |
val exp_term = explode termstr |
|
427 |
in |
|
428 |
implode(List.filter is_alpha_space_or_neg_or_eq_or_bracket exp_term) |
|
429 |
end |
|
430 |
||
431 |
fun get_meta_lits_bracket thm = map lit_string_bracket (prems_of thm) |
|
432 |
||
433 |
||
434 |
||
435 |
||
436 |
fun apply_rule rule [] thm = thm |
|
437 |
| apply_rule rule (x::xs) thm = let val thm' = rule RSN ((x+1),thm) |
|
438 |
in |
|
439 |
apply_rule rule xs thm' |
|
440 |
end |
|
441 |
||
442 |
||
443 |
||
444 |
(* resulting thm, clause-strs in spass order, vars *) |
|
445 |
||
446 |
fun rearrange_clause thm res_strlist allvars = |
|
447 |
let val isa_strlist = get_meta_lits thm |
|
448 |
val (posns, symlist, not_symlist) = checkorder res_strlist isa_strlist allvars([],[],[]) |
|
449 |
val symmed = apply_rule sym symlist thm |
|
450 |
val not_symmed = apply_rule not_sym not_symlist symmed |
|
451 |
||
452 |
in |
|
453 |
((rearrange_prems posns not_symmed), posns, symlist,not_symlist) |
|
454 |
end |