36 val trace_path = Path.basic "atp_trace"; |
36 val trace_path = Path.basic "atp_trace"; |
37 |
37 |
38 fun trace s = if !Output.debugging then File.append (File.tmp_path trace_path) s |
38 fun trace s = if !Output.debugging then File.append (File.tmp_path trace_path) s |
39 else (); |
39 else (); |
40 |
40 |
|
41 val string_of_thm = PrintMode.setmp [] string_of_thm; |
|
42 |
41 (*For generating structured proofs: keep every nth proof line*) |
43 (*For generating structured proofs: keep every nth proof line*) |
42 val (modulus, modulus_setup) = Attrib.config_int "reconstruction_modulus" 1; |
44 val (modulus, modulus_setup) = Attrib.config_int "sledgehammer_modulus" 1; |
43 |
45 |
44 (*Indicates whether to include sort information in generated proofs*) |
46 (*Indicates whether to include sort information in generated proofs*) |
45 val (recon_sorts, recon_sorts_setup) = Attrib.config_bool "reconstruction_sorts" true; |
47 val (recon_sorts, recon_sorts_setup) = Attrib.config_bool "sledgehammer_sorts" true; |
46 |
48 |
47 val setup = modulus_setup #> recon_sorts_setup; |
49 (*Indicates whether to generate full proofs or just lemma lists*) |
|
50 val (full_proofs, full_proofs_setup) = Attrib.config_bool "sledgehammer_full" false; |
|
51 |
|
52 val setup = modulus_setup #> recon_sorts_setup #> full_proofs_setup; |
48 |
53 |
49 datatype atp = E | SPASS | Vampire; |
54 datatype atp = E | SPASS | Vampire; |
50 |
55 |
51 (**** PARSING OF TSTP FORMAT ****) |
56 (**** PARSING OF TSTP FORMAT ****) |
52 |
57 |
350 |
355 |
351 (*ctms is a list of conjecture clauses as yielded by Isabelle. Those returned by the |
356 (*ctms is a list of conjecture clauses as yielded by Isabelle. Those returned by the |
352 ATP may have their literals reordered.*) |
357 ATP may have their literals reordered.*) |
353 fun isar_lines ctxt ctms = |
358 fun isar_lines ctxt ctms = |
354 let val string_of = Syntax.string_of_term ctxt |
359 let val string_of = Syntax.string_of_term ctxt |
|
360 val _ = trace ("\n\nisar_lines: start\n") |
355 fun doline have (lname, t, []) = (*No deps: it's a conjecture clause, with no proof.*) |
361 fun doline have (lname, t, []) = (*No deps: it's a conjecture clause, with no proof.*) |
356 (case permuted_clause t ctms of |
362 (case permuted_clause t ctms of |
357 SOME u => "assume " ^ lname ^ ": \"" ^ string_of u ^ "\"\n" |
363 SOME u => "assume " ^ lname ^ ": \"" ^ string_of u ^ "\"\n" |
358 | NONE => "assume? " ^ lname ^ ": \"" ^ string_of t ^ "\"\n") (*no match!!*) |
364 | NONE => "assume? " ^ lname ^ ": \"" ^ string_of t ^ "\"\n") (*no match!!*) |
359 | doline have (lname, t, deps) = |
365 | doline have (lname, t, deps) = |
438 |
444 |
439 fun isar_header [] = proofstart |
445 fun isar_header [] = proofstart |
440 | isar_header ts = proofstart ^ "fix " ^ space_implode " " ts ^ "\n"; |
446 | isar_header ts = proofstart ^ "fix " ^ space_implode " " ts ^ "\n"; |
441 |
447 |
442 fun decode_tstp_file cnfs ctxt th sgno thm_names = |
448 fun decode_tstp_file cnfs ctxt th sgno thm_names = |
443 let val tuples = map (dest_tstp o tstp_line o explode) cnfs |
449 let val _ = trace "\ndecode_tstp_file: start\n" |
|
450 val tuples = map (dest_tstp o tstp_line o explode) cnfs |
|
451 val _ = trace (Int.toString (length tuples) ^ " tuples extracted\n") |
444 val ctxt = ProofContext.set_mode ProofContext.mode_schematic ctxt |
452 val ctxt = ProofContext.set_mode ProofContext.mode_schematic ctxt |
445 val nonnull_lines = |
453 val raw_lines = foldr add_prfline [] (decode_tstp_list ctxt tuples) |
446 foldr add_nonnull_prfline [] |
454 val _ = trace (Int.toString (length raw_lines) ^ " raw_lines extracted\n") |
447 (foldr add_prfline [] (decode_tstp_list ctxt tuples)) |
455 val nonnull_lines = foldr add_nonnull_prfline [] raw_lines |
|
456 val _ = trace (Int.toString (length nonnull_lines) ^ " nonnull_lines extracted\n") |
448 val (_,lines) = foldr (add_wanted_prfline ctxt) (0,[]) nonnull_lines |
457 val (_,lines) = foldr (add_wanted_prfline ctxt) (0,[]) nonnull_lines |
|
458 val _ = trace (Int.toString (length lines) ^ " lines extracted\n") |
449 val (ccls,fixes) = ResAxioms.neg_conjecture_clauses th sgno |
459 val (ccls,fixes) = ResAxioms.neg_conjecture_clauses th sgno |
|
460 val _ = trace (Int.toString (length ccls) ^ " conjecture clauses\n") |
450 val ccls = map forall_intr_vars ccls |
461 val ccls = map forall_intr_vars ccls |
|
462 val _ = if !Output.debugging then app (fn th => trace ("\nccl: " ^ string_of_thm th)) ccls |
|
463 else () |
|
464 val ilines = isar_lines ctxt (map prop_of ccls) (stringify_deps thm_names [] lines) |
|
465 val _ = trace "\ndecode_tstp_file: finishing\n" |
451 in |
466 in |
452 app (fn th => Output.debug (fn () => string_of_thm th)) ccls; |
467 isar_header (map #1 fixes) ^ String.concat ilines ^ "qed\n" |
453 isar_header (map #1 fixes) ^ |
|
454 String.concat (isar_lines ctxt (map prop_of ccls) (stringify_deps thm_names [] lines)) ^ |
|
455 "qed\n" |
|
456 end |
468 end |
457 handle e => (*FIXME: exn handler is too general!*) |
469 handle e => (*FIXME: exn handler is too general!*) |
458 "Translation of TSTP raised an exception: " ^ Toplevel.exn_message e; |
470 let val msg = "Translation of TSTP raised an exception: " ^ Toplevel.exn_message e |
|
471 in trace msg; msg end; |
459 |
472 |
460 (*Could use split_lines, but it can return blank lines...*) |
473 (*Could use split_lines, but it can return blank lines...*) |
461 val lines = String.tokens (equal #"\n"); |
474 val lines = String.tokens (equal #"\n"); |
462 |
475 |
463 val nospaces = String.translate (fn c => if Char.isSpace c then "" else str c); |
476 val nospaces = String.translate (fn c => if Char.isSpace c then "" else str c); |
550 |
563 |
551 val nochained = filter_out (fn y => y = chained_hint); |
564 val nochained = filter_out (fn y => y = chained_hint); |
552 |
565 |
553 (*The signal handler in watcher.ML must be able to read the output of this.*) |
566 (*The signal handler in watcher.ML must be able to read the output of this.*) |
554 fun lemma_list atp proofextract thm_names probfile toParent ppid = |
567 fun lemma_list atp proofextract thm_names probfile toParent ppid = |
|
568 (trace "\nlemma_list: ready to signal success"; |
555 signal_success probfile toParent ppid |
569 signal_success probfile toParent ppid |
556 (metis_line (nochained (get_axiom_names_for atp proofextract thm_names))); |
570 (metis_line (nochained (get_axiom_names_for atp proofextract thm_names)))); |
557 |
571 |
558 fun tstp_extract proofextract thm_names probfile toParent ppid ctxt th sgno = |
572 fun tstp_extract proofextract thm_names probfile toParent ppid ctxt th sgno = |
559 let val cnfs = filter (String.isPrefix "cnf(") (map nospaces (lines proofextract)) |
573 let val _ = trace "\nAttempting to extract structured proof from TSTP\n" |
|
574 val cnfs = filter (String.isPrefix "cnf(") (map nospaces (lines proofextract)) |
|
575 val _ = trace (Int.toString (length cnfs) ^ " cnfs found") |
560 val names = get_axiom_names_tstp proofextract thm_names |
576 val names = get_axiom_names_tstp proofextract thm_names |
561 val line1 = metis_line (nochained names) |
577 val line1 = metis_line (nochained names) |
|
578 val _ = trace ("\nExtracted one-line proof: " ^ line1) |
562 val line2 = if chained_hint mem_string names then "" |
579 val line2 = if chained_hint mem_string names then "" |
563 else decode_tstp_file cnfs ctxt th sgno thm_names |
580 else decode_tstp_file cnfs ctxt th sgno thm_names |
|
581 val _ = trace "\ntstp_extract: ready to signal success" |
564 in |
582 in |
565 signal_success probfile toParent ppid (line1 ^ "\n" ^ line2) |
583 signal_success probfile toParent ppid (line1 ^ "\n" ^ line2) |
566 end; |
584 end; |
567 |
585 |
568 (**** Extracting proofs from an ATP's output ****) |
586 (**** Extracting proofs from an ATP's output ****) |
597 false) |
615 false) |
598 | SOME thisLine => |
616 | SOME thisLine => |
599 if any_substring [endS,end_TSTP] thisLine |
617 if any_substring [endS,end_TSTP] thisLine |
600 then |
618 then |
601 (trace ("\nExtracted proof:\n" ^ proofextract); |
619 (trace ("\nExtracted proof:\n" ^ proofextract); |
602 if String.isPrefix "cnf(" proofextract |
620 if Config.get ctxt full_proofs andalso String.isPrefix "cnf(" proofextract |
603 then tstp_extract proofextract thm_names probfile toParent ppid ctxt th sgno |
621 then tstp_extract proofextract thm_names probfile toParent ppid ctxt th sgno |
604 else lemma_list atp proofextract thm_names probfile toParent ppid; |
622 else lemma_list atp proofextract thm_names probfile toParent ppid; |
605 true) |
623 true) |
606 else transferInput (proofextract ^ thisLine) |
624 else transferInput (proofextract ^ thisLine) |
607 in |
625 in |