6 Abstract representation of ATP proofs and TSTP/SPASS syntax. |
6 Abstract representation of ATP proofs and TSTP/SPASS syntax. |
7 *) |
7 *) |
8 |
8 |
9 signature ATP_PROOF = |
9 signature ATP_PROOF = |
10 sig |
10 sig |
|
11 type 'a atp_type = 'a ATP_Problem.atp_type |
11 type ('a, 'b) atp_term = ('a, 'b) ATP_Problem.atp_term |
12 type ('a, 'b) atp_term = ('a, 'b) ATP_Problem.atp_term |
12 type atp_formula_role = ATP_Problem.atp_formula_role |
13 type atp_formula_role = ATP_Problem.atp_formula_role |
13 type ('a, 'b, 'c, 'd) atp_formula = ('a, 'b, 'c, 'd) ATP_Problem.atp_formula |
14 type ('a, 'b, 'c, 'd) atp_formula = ('a, 'b, 'c, 'd) ATP_Problem.atp_formula |
14 type 'a atp_problem = 'a ATP_Problem.atp_problem |
15 type 'a atp_problem = 'a ATP_Problem.atp_problem |
15 |
16 |
36 |
37 |
37 type atp_step_name = string * string list |
38 type atp_step_name = string * string list |
38 type ('a, 'b) atp_step = |
39 type ('a, 'b) atp_step = |
39 atp_step_name * atp_formula_role * 'a * 'b * atp_step_name list |
40 atp_step_name * atp_formula_role * 'a * 'b * atp_step_name list |
40 |
41 |
41 type 'a atp_proof = |
42 type 'a atp_proof = (('a, 'a, ('a, 'a atp_type) atp_term, 'a) atp_formula, string) atp_step list |
42 (('a, 'a, ('a, 'a) atp_term, 'a) atp_formula, string) atp_step list |
|
43 |
43 |
44 val agsyhol_core_rule : string |
44 val agsyhol_core_rule : string |
45 val satallax_core_rule : string |
45 val satallax_core_rule : string |
46 val spass_input_rule : string |
46 val spass_input_rule : string |
47 val spass_skolemize_rule : string |
47 val spass_skolemize_rule : string |
48 val z3_tptp_core_rule : string |
48 val z3_tptp_core_rule : string |
49 |
49 |
50 val short_output : bool -> string -> string |
50 val short_output : bool -> string -> string |
51 val string_of_atp_failure : atp_failure -> string |
51 val string_of_atp_failure : atp_failure -> string |
52 val extract_important_message : string -> string |
52 val extract_important_message : string -> string |
53 val extract_known_atp_failure : |
53 val extract_known_atp_failure : (atp_failure * string) list -> string -> atp_failure option |
54 (atp_failure * string) list -> string -> atp_failure option |
|
55 val extract_tstplike_proof_and_outcome : |
54 val extract_tstplike_proof_and_outcome : |
56 bool -> (string * string) list -> (atp_failure * string) list -> string |
55 bool -> (string * string) list -> (atp_failure * string) list -> string |
57 -> string * atp_failure option |
56 -> string * atp_failure option |
58 val is_same_atp_step : atp_step_name -> atp_step_name -> bool |
57 val is_same_atp_step : atp_step_name -> atp_step_name -> bool |
59 val scan_general_id : string list -> string * string list |
58 val scan_general_id : string list -> string * string list |
60 val parse_formula : |
59 val parse_formula : string list -> |
61 string list |
60 (string, string atp_type, (string, string atp_type) atp_term, string) atp_formula * string list |
62 -> (string, 'a, (string, 'a) atp_term, string) atp_formula * string list |
61 val atp_proof_of_tstplike_proof : string atp_problem -> string -> string atp_proof |
63 val atp_proof_of_tstplike_proof : |
|
64 string atp_problem -> string -> string atp_proof |
|
65 val clean_up_atp_proof_dependencies : string atp_proof -> string atp_proof |
62 val clean_up_atp_proof_dependencies : string atp_proof -> string atp_proof |
66 val map_term_names_in_atp_proof : |
63 val map_term_names_in_atp_proof : (string -> string) -> string atp_proof -> string atp_proof |
67 (string -> string) -> string atp_proof -> string atp_proof |
64 val nasty_atp_proof : string Symtab.table -> string atp_proof -> string atp_proof |
68 val nasty_atp_proof : |
|
69 string Symtab.table -> string atp_proof -> string atp_proof |
|
70 end; |
65 end; |
71 |
66 |
72 structure ATP_Proof : ATP_PROOF = |
67 structure ATP_Proof : ATP_PROOF = |
73 struct |
68 struct |
74 |
69 |
201 (case pairself (Int.fromString o perhaps (try (unprefix vampire_fact_prefix))) q of |
196 (case pairself (Int.fromString o perhaps (try (unprefix vampire_fact_prefix))) q of |
202 (SOME i, SOME j) => int_ord (i, j) |
197 (SOME i, SOME j) => int_ord (i, j) |
203 | _ => raise Fail "not Vampire") |
198 | _ => raise Fail "not Vampire") |
204 end |
199 end |
205 |
200 |
206 type ('a, 'b) atp_step = |
201 type ('a, 'b) atp_step = atp_step_name * atp_formula_role * 'a * 'b * atp_step_name list |
207 atp_step_name * atp_formula_role * 'a * 'b * atp_step_name list |
202 |
208 |
203 type 'a atp_proof = (('a, 'a, ('a, 'a atp_type) atp_term, 'a) atp_formula, string) atp_step list |
209 type 'a atp_proof = |
|
210 (('a, 'a, ('a, 'a) atp_term, 'a) atp_formula, string) atp_step list |
|
211 |
204 |
212 (**** PARSING OF TSTP FORMAT ****) |
205 (**** PARSING OF TSTP FORMAT ****) |
213 |
206 |
214 (* Strings enclosed in single quotes (e.g., file names) *) |
207 (* Strings enclosed in single quotes (e.g., file names) *) |
215 val scan_general_id = |
208 val scan_general_id = |
243 (* "skip_term" is there to cope with Waldmeister nonsense such as "theory(equality)". *) |
236 (* "skip_term" is there to cope with Waldmeister nonsense such as "theory(equality)". *) |
244 fun parse_dependency x = |
237 fun parse_dependency x = |
245 (parse_inference_source >> snd |
238 (parse_inference_source >> snd |
246 || scan_general_id --| skip_term >> single) x |
239 || scan_general_id --| skip_term >> single) x |
247 and parse_dependencies x = |
240 and parse_dependencies x = |
248 (parse_dependency ::: Scan.repeat ($$ "," |-- parse_dependency) |
241 (parse_dependency ::: Scan.repeat ($$ "," |-- parse_dependency) >> flat) x |
249 >> flat) x |
|
250 and parse_file_source x = |
242 and parse_file_source x = |
251 (Scan.this_string "file" |-- $$ "(" |-- scan_general_id |
243 (Scan.this_string "file" |-- $$ "(" |-- scan_general_id |
252 -- Scan.option ($$ "," |-- scan_general_id) --| $$ ")") x |
244 -- Scan.option ($$ "," |-- scan_general_id) --| $$ ")") x |
253 and parse_inference_source x = |
245 and parse_inference_source x = |
254 (Scan.this_string "inference" |-- $$ "(" |-- scan_general_id |
246 (Scan.this_string "inference" |-- $$ "(" |-- scan_general_id |
264 || scan_general_id >> (fn s => Inference_Source ("", [s])) (* for E *) |
256 || scan_general_id >> (fn s => Inference_Source ("", [s])) (* for E *) |
265 || skip_term >> K dummy_inference) x |
257 || skip_term >> K dummy_inference) x |
266 |
258 |
267 fun list_app (f, args) = fold (fn arg => fn f => ATerm ((tptp_app, []), [f, arg])) args f |
259 fun list_app (f, args) = fold (fn arg => fn f => ATerm ((tptp_app, []), [f, arg])) args f |
268 |
260 |
|
261 fun parse_sort x = scan_general_id x |
|
262 and parse_sorts x = (parse_sort ::: Scan.repeat ($$ "&" |-- parse_sort)) x |
|
263 |
|
264 fun parse_type x = |
|
265 (scan_general_id --| Scan.option ($$ "{" |-- parse_sorts --| $$ "}") |
|
266 -- Scan.optional ($$ "(" |-- parse_types --| $$ ")") [] |
|
267 >> AType) x |
|
268 and parse_types x = (parse_type ::: Scan.repeat ($$ "," |-- parse_type)) x |
|
269 |
269 (* We currently ignore TFF and THF types. *) |
270 (* We currently ignore TFF and THF types. *) |
270 fun parse_type_stuff x = Scan.repeat (($$ tptp_has_type || $$ tptp_fun_type) |-- parse_arg) x |
271 fun parse_type_signature x = Scan.repeat (($$ tptp_has_type || $$ tptp_fun_type) |-- parse_arg) x |
271 and parse_arg x = |
272 and parse_arg x = |
272 ($$ "(" |-- parse_term --| $$ ")" --| parse_type_stuff |
273 ($$ "(" |-- parse_term --| $$ ")" --| parse_type_signature |
273 || scan_general_id --| parse_type_stuff |
274 || scan_general_id --| parse_type_signature |
274 -- Scan.optional ($$ "(" |-- parse_terms --| $$ ")") [] |
275 -- Scan.optional ($$ "<" |-- parse_types --| $$ ">") [] |
275 >> (ATerm o apfst (rpair []))) x |
276 -- Scan.optional ($$ "(" |-- parse_terms --| $$ ")") [] |
|
277 >> ATerm) x |
276 and parse_term x = (parse_arg -- Scan.repeat ($$ tptp_app |-- parse_arg) >> list_app) x |
278 and parse_term x = (parse_arg -- Scan.repeat ($$ tptp_app |-- parse_arg) >> list_app) x |
277 and parse_terms x = (parse_term ::: Scan.repeat ($$ "," |-- parse_term)) x |
279 and parse_terms x = (parse_term ::: Scan.repeat ($$ "," |-- parse_term)) x |
278 |
280 |
279 fun parse_atom x = |
281 fun parse_atom x = |
280 (parse_term -- Scan.option (Scan.option ($$ tptp_not_infix) --| $$ tptp_equal |
282 (parse_term -- Scan.option (Scan.option ($$ tptp_not_infix) --| $$ tptp_equal -- parse_term) |
281 -- parse_term) |
|
282 >> (fn (u1, NONE) => AAtom u1 |
283 >> (fn (u1, NONE) => AAtom u1 |
283 | (u1, SOME (neg, u2)) => |
284 | (u1, SOME (neg, u2)) => |
284 AAtom (ATerm (("equal", []), [u1, u2])) |> is_some neg ? mk_anot)) x |
285 AAtom (ATerm (("equal", []), [u1, u2])) |> is_some neg ? mk_anot)) x |
285 |
286 |
286 (* TPTP formulas are fully parenthesized, so we don't need to worry about operator precedence. *) |
287 (* TPTP formulas are fully parenthesized, so we don't need to worry about operator precedence. *) |
422 (* SPASS returns clause references of the form "x.y". We ignore "y", whose role |
423 (* SPASS returns clause references of the form "x.y". We ignore "y", whose role |
423 is not clear anyway. *) |
424 is not clear anyway. *) |
424 val parse_dot_name = scan_general_id --| $$ "." --| scan_general_id |
425 val parse_dot_name = scan_general_id --| $$ "." --| scan_general_id |
425 |
426 |
426 val parse_spass_annotations = |
427 val parse_spass_annotations = |
427 Scan.optional ($$ ":" |-- Scan.repeat (parse_dot_name |
428 Scan.optional ($$ ":" |-- Scan.repeat (parse_dot_name --| Scan.option ($$ ","))) [] |
428 --| Scan.option ($$ ","))) [] |
|
429 |
429 |
430 (* It is not clear why some literals are followed by sequences of stars and/or |
430 (* It is not clear why some literals are followed by sequences of stars and/or |
431 pluses. We ignore them. *) |
431 pluses. We ignore them. *) |
432 fun parse_decorated_atom x = |
432 fun parse_decorated_atom x = |
433 (parse_atom --| Scan.repeat ($$ "*" || $$ "+" || $$ " ")) x |
433 (parse_atom --| Scan.repeat ($$ "*" || $$ "+" || $$ " ")) x |
458 >> (fn ((((num, rule), deps), u), names) => |
458 >> (fn ((((num, rule), deps), u), names) => |
459 ((num, these names), Unknown, u, rule, map (rpair []) deps))) x |
459 ((num, these names), Unknown, u, rule, map (rpair []) deps))) x |
460 |
460 |
461 fun parse_spass_pirate_dependency x = (Scan.option ($$ "-") |-- scan_general_id) x |
461 fun parse_spass_pirate_dependency x = (Scan.option ($$ "-") |-- scan_general_id) x |
462 fun parse_spass_pirate_dependencies x = |
462 fun parse_spass_pirate_dependencies x = |
463 (parse_spass_pirate_dependency ::: Scan.repeat ($$ "," |-- parse_spass_pirate_dependency)) x |
463 Scan.repeat (parse_spass_pirate_dependency --| Scan.option ($$ "," || $$ " ")) x |
464 fun parse_spass_pirate_file_source x = |
464 fun parse_spass_pirate_file_source x = |
465 ((Scan.this_string "Input" || Scan.this_string "Conj") |-- $$ "(" |-- scan_general_id |
465 ((Scan.this_string "Input" || Scan.this_string "Conj") |-- $$ "(" |-- scan_general_id |
466 --| $$ ")") x |
466 --| $$ ")") x |
467 fun parse_spass_pirate_inference_source x = |
467 fun parse_spass_pirate_inference_source x = |
468 (scan_general_id |-- $$ "(" -- parse_spass_pirate_dependencies --| $$ ")") x |
468 (scan_general_id |-- $$ "(" -- parse_spass_pirate_dependencies --| $$ ")") x |
515 fun atp_proof_of_tstplike_proof _ "" = [] |
515 fun atp_proof_of_tstplike_proof _ "" = [] |
516 | atp_proof_of_tstplike_proof problem tstp = |
516 | atp_proof_of_tstplike_proof problem tstp = |
517 (case core_of_agsyhol_proof tstp of |
517 (case core_of_agsyhol_proof tstp of |
518 SOME facts => facts |> map (core_inference agsyhol_core_rule) |
518 SOME facts => facts |> map (core_inference agsyhol_core_rule) |
519 | NONE => |
519 | NONE => |
520 tstp ^ "$" (* the $ sign acts as a sentinel (FIXME: needed?) *) |
520 tstp ^ "$" (* the $ sign acts as a sentinel (FIXME: needed?) *) |
521 |> parse_proof problem |
521 |> parse_proof problem |
522 |> perhaps (try (sort (vampire_step_name_ord o pairself #1)))) |
522 |> perhaps (try (sort (vampire_step_name_ord o pairself #1)))) |
523 |
523 |
524 fun clean_up_dependencies _ [] = [] |
524 fun clean_up_dependencies _ [] = [] |
525 | clean_up_dependencies seen ((name, role, u, rule, deps) :: steps) = |
525 | clean_up_dependencies seen ((name, role, u, rule, deps) :: steps) = |
526 (name, role, u, rule, |
526 (name, role, u, rule, map_filter (fn dep => find_first (is_same_atp_step dep) seen) deps) :: |
527 map_filter (fn dep => find_first (is_same_atp_step dep) seen) deps) :: |
|
528 clean_up_dependencies (name :: seen) steps |
527 clean_up_dependencies (name :: seen) steps |
529 |
528 |
530 fun clean_up_atp_proof_dependencies proof = clean_up_dependencies [] proof |
529 fun clean_up_atp_proof_dependencies proof = clean_up_dependencies [] proof |
531 |
530 |
532 fun map_term_names_in_atp_proof f = |
531 fun map_term_names_in_atp_proof f = |
533 let |
532 let |
534 fun do_term (ATerm ((s, tys), ts)) = ATerm ((f s, tys), map do_term ts) |
533 fun map_type (AType (s, tys)) = AType (f s, map map_type tys) |
535 fun do_formula (AQuant (q, xs, phi)) = |
534 | map_type (AFun (ty, ty')) = AFun (map_type ty, map_type ty') |
536 AQuant (q, map (apfst f) xs, do_formula phi) |
535 | map_type (APi (ss, ty)) = APi (map f ss, map_type ty) |
537 | do_formula (AConn (c, phis)) = AConn (c, map do_formula phis) |
536 |
538 | do_formula (AAtom t) = AAtom (do_term t) |
537 fun map_term (ATerm ((s, tys), ts)) = ATerm ((f s, map map_type tys), map map_term ts) |
539 fun do_step (name, role, phi, rule, deps) = |
538 | map_term (AAbs (((s, ty), tm), args)) = |
540 (name, role, do_formula phi, rule, deps) |
539 AAbs (((f s, map_type ty), map_term tm), map map_term args) |
541 in map do_step end |
540 |
|
541 fun map_formula (AQuant (q, xs, phi)) = |
|
542 AQuant (q, map (apfst f) xs, map_formula phi) |
|
543 | map_formula (AConn (c, phis)) = AConn (c, map map_formula phis) |
|
544 | map_formula (AAtom t) = AAtom (map_term t) |
|
545 |
|
546 fun map_step (name, role, phi, rule, deps) = |
|
547 (name, role, map_formula phi, rule, deps) |
|
548 in |
|
549 map map_step |
|
550 end |
542 |
551 |
543 fun nasty_name pool s = s |> Symtab.lookup pool |> the_default s |
552 fun nasty_name pool s = s |> Symtab.lookup pool |> the_default s |
544 |
553 |
545 fun nasty_atp_proof pool = |
554 fun nasty_atp_proof pool = |
546 not (Symtab.is_empty pool) ? map_term_names_in_atp_proof (nasty_name pool) |
555 not (Symtab.is_empty pool) ? map_term_names_in_atp_proof (nasty_name pool) |