60 |
60 |
61 fun mk_anot (AConn (ANot, [phi])) = phi |
61 fun mk_anot (AConn (ANot, [phi])) = phi |
62 | mk_anot phi = AConn (ANot, [phi]) |
62 | mk_anot phi = AConn (ANot, [phi]) |
63 fun mk_aconn c (phi1, phi2) = AConn (c, [phi1, phi2]) |
63 fun mk_aconn c (phi1, phi2) = AConn (c, [phi1, phi2]) |
64 |
64 |
|
65 datatype tstp_name = Str of string | Num of int |
|
66 |
|
67 fun tstp_name_ord (Str s, Str t) = string_ord (s, t) |
|
68 | tstp_name_ord (Str _, Num _) = LESS |
|
69 | tstp_name_ord (Num i, Num j) = int_ord (i, j) |
|
70 | tstp_name_ord (Num _, Str _) = GREATER |
|
71 |
65 fun index_in_shape x = find_index (exists (curry (op =) x)) |
72 fun index_in_shape x = find_index (exists (curry (op =) x)) |
66 fun is_axiom_number axiom_names num = |
73 fun resolve_axiom axiom_names (Str str) = |
67 num > 0 andalso num <= Vector.length axiom_names andalso |
74 (case find_first_in_list_vector axiom_names str of |
68 not (null (Vector.sub (axiom_names, num - 1))) |
75 SOME x => [(str, x)] |
69 fun is_conjecture_number conjecture_shape num = |
76 | NONE => []) |
70 index_in_shape num conjecture_shape >= 0 |
77 | resolve_axiom axiom_names (Num num) = |
|
78 if num > 0 andalso num <= Vector.length axiom_names then |
|
79 Vector.sub (axiom_names, num - 1) |
|
80 else |
|
81 [] |
|
82 val is_axiom_name = not o null oo resolve_axiom |
|
83 fun is_conjecture_name _ (Str str) = String.isPrefix conjecture_prefix str |
|
84 | is_conjecture_name conjecture_shape (Num num) = |
|
85 index_in_shape num conjecture_shape >= 0 |
71 |
86 |
72 fun negate_term (Const (@{const_name All}, T) $ Abs (s, T', t')) = |
87 fun negate_term (Const (@{const_name All}, T) $ Abs (s, T', t')) = |
73 Const (@{const_name Ex}, T) $ Abs (s, T', negate_term t') |
88 Const (@{const_name Ex}, T) $ Abs (s, T', negate_term t') |
74 | negate_term (Const (@{const_name Ex}, T) $ Abs (s, T', t')) = |
89 | negate_term (Const (@{const_name Ex}, T) $ Abs (s, T', t')) = |
75 Const (@{const_name All}, T) $ Abs (s, T', negate_term t') |
90 Const (@{const_name All}, T) $ Abs (s, T', negate_term t') |
182 >> (fn (((num, role), phi), deps) => |
197 >> (fn (((num, role), phi), deps) => |
183 case role of |
198 case role of |
184 "definition" => |
199 "definition" => |
185 (case phi of |
200 (case phi of |
186 AConn (AIff, [phi1 as AAtom _, phi2]) => |
201 AConn (AIff, [phi1 as AAtom _, phi2]) => |
187 Definition (num, phi1, phi2) |
202 Definition (Num num, phi1, phi2) |
188 | AAtom (ATerm ("c_equal", _)) => |
203 | AAtom (ATerm ("c_equal", _)) => |
189 Inference (num, phi, deps) (* Vampire's equality proxy axiom *) |
204 (* Vampire's equality proxy axiom *) |
|
205 Inference (Num num, phi, map Num deps) |
190 | _ => raise Fail "malformed definition") |
206 | _ => raise Fail "malformed definition") |
191 | _ => Inference (num, phi, deps)) |
207 | _ => Inference (Num num, phi, map Num deps)) |
192 |
208 |
193 (**** PARSING OF VAMPIRE OUTPUT ****) |
209 (**** PARSING OF VAMPIRE OUTPUT ****) |
194 |
210 |
195 (* Syntax: <num>. <formula> <annotation> *) |
211 (* Syntax: <num>. <formula> <annotation> *) |
196 fun parse_vampire_line pool = |
212 fun parse_vampire_line pool = |
197 scan_integer --| $$ "." -- parse_formula pool -- parse_annotation |
213 scan_integer --| $$ "." -- parse_formula pool -- parse_annotation |
198 >> (fn ((num, phi), deps) => Inference (num, phi, deps)) |
214 >> (fn ((num, phi), deps) => Inference (Num num, phi, map Num deps)) |
199 |
215 |
200 (**** PARSING OF SPASS OUTPUT ****) |
216 (**** PARSING OF SPASS OUTPUT ****) |
201 |
217 |
202 (* SPASS returns clause references of the form "x.y". We ignore "y", whose role |
218 (* SPASS returns clause references of the form "x.y". We ignore "y", whose role |
203 is not clear anyway. *) |
219 is not clear anyway. *) |
482 clsarity). *) |
498 clsarity). *) |
483 val is_only_type_information = curry (op aconv) HOLogic.true_const |
499 val is_only_type_information = curry (op aconv) HOLogic.true_const |
484 |
500 |
485 fun replace_one_dep (old, new) dep = if dep = old then new else [dep] |
501 fun replace_one_dep (old, new) dep = if dep = old then new else [dep] |
486 fun replace_deps_in_line _ (line as Definition _) = line |
502 fun replace_deps_in_line _ (line as Definition _) = line |
487 | replace_deps_in_line p (Inference (num, t, deps)) = |
503 | replace_deps_in_line p (Inference (name, t, deps)) = |
488 Inference (num, t, fold (union (op =) o replace_one_dep p) deps []) |
504 Inference (name, t, fold (union (op =) o replace_one_dep p) deps []) |
489 |
505 |
490 (* Discard axioms; consolidate adjacent lines that prove the same formula, since |
506 (* Discard axioms; consolidate adjacent lines that prove the same formula, since |
491 they differ only in type information.*) |
507 they differ only in type information.*) |
492 fun add_line _ _ (line as Definition _) lines = line :: lines |
508 fun add_line _ _ (line as Definition _) lines = line :: lines |
493 | add_line conjecture_shape axiom_names (Inference (num, t, [])) lines = |
509 | add_line conjecture_shape axiom_names (Inference (name, t, [])) lines = |
494 (* No dependencies: axiom, conjecture, or (for Vampire) internal axioms or |
510 (* No dependencies: axiom, conjecture, or (for Vampire) internal axioms or |
495 definitions. *) |
511 definitions. *) |
496 if is_axiom_number axiom_names num then |
512 if is_axiom_name axiom_names name then |
497 (* Axioms are not proof lines. *) |
513 (* Axioms are not proof lines. *) |
498 if is_only_type_information t then |
514 if is_only_type_information t then |
499 map (replace_deps_in_line (num, [])) lines |
515 map (replace_deps_in_line (name, [])) lines |
500 (* Is there a repetition? If so, replace later line by earlier one. *) |
516 (* Is there a repetition? If so, replace later line by earlier one. *) |
501 else case take_prefix (not o is_same_inference t) lines of |
517 else case take_prefix (not o is_same_inference t) lines of |
502 (_, []) => lines (*no repetition of proof line*) |
518 (_, []) => lines (*no repetition of proof line*) |
503 | (pre, Inference (num', _, _) :: post) => |
519 | (pre, Inference (name', _, _) :: post) => |
504 pre @ map (replace_deps_in_line (num', [num])) post |
520 pre @ map (replace_deps_in_line (name', [name])) post |
505 else if is_conjecture_number conjecture_shape num then |
521 else if is_conjecture_name conjecture_shape name then |
506 Inference (num, negate_term t, []) :: lines |
522 Inference (name, negate_term t, []) :: lines |
507 else |
523 else |
508 map (replace_deps_in_line (num, [])) lines |
524 map (replace_deps_in_line (name, [])) lines |
509 | add_line _ _ (Inference (num, t, deps)) lines = |
525 | add_line _ _ (Inference (name, t, deps)) lines = |
510 (* Type information will be deleted later; skip repetition test. *) |
526 (* Type information will be deleted later; skip repetition test. *) |
511 if is_only_type_information t then |
527 if is_only_type_information t then |
512 Inference (num, t, deps) :: lines |
528 Inference (name, t, deps) :: lines |
513 (* Is there a repetition? If so, replace later line by earlier one. *) |
529 (* Is there a repetition? If so, replace later line by earlier one. *) |
514 else case take_prefix (not o is_same_inference t) lines of |
530 else case take_prefix (not o is_same_inference t) lines of |
515 (* FIXME: Doesn't this code risk conflating proofs involving different |
531 (* FIXME: Doesn't this code risk conflating proofs involving different |
516 types? *) |
532 types? *) |
517 (_, []) => Inference (num, t, deps) :: lines |
533 (_, []) => Inference (name, t, deps) :: lines |
518 | (pre, Inference (num', t', _) :: post) => |
534 | (pre, Inference (name', t', _) :: post) => |
519 Inference (num, t', deps) :: |
535 Inference (name, t', deps) :: |
520 pre @ map (replace_deps_in_line (num', [num])) post |
536 pre @ map (replace_deps_in_line (name', [name])) post |
521 |
537 |
522 (* Recursively delete empty lines (type information) from the proof. *) |
538 (* Recursively delete empty lines (type information) from the proof. *) |
523 fun add_nontrivial_line (Inference (num, t, [])) lines = |
539 fun add_nontrivial_line (Inference (name, t, [])) lines = |
524 if is_only_type_information t then delete_dep num lines |
540 if is_only_type_information t then delete_dep name lines |
525 else Inference (num, t, []) :: lines |
541 else Inference (name, t, []) :: lines |
526 | add_nontrivial_line line lines = line :: lines |
542 | add_nontrivial_line line lines = line :: lines |
527 and delete_dep num lines = |
543 and delete_dep name lines = |
528 fold_rev add_nontrivial_line (map (replace_deps_in_line (num, [])) lines) [] |
544 fold_rev add_nontrivial_line (map (replace_deps_in_line (name, [])) lines) [] |
529 |
545 |
530 (* ATPs sometimes reuse free variable names in the strangest ways. Removing |
546 (* ATPs sometimes reuse free variable names in the strangest ways. Removing |
531 offending lines often does the trick. *) |
547 offending lines often does the trick. *) |
532 fun is_bad_free frees (Free x) = not (member (op =) frees x) |
548 fun is_bad_free frees (Free x) = not (member (op =) frees x) |
533 | is_bad_free _ _ = false |
549 | is_bad_free _ _ = false |
534 |
550 |
535 fun add_desired_line _ _ _ _ (line as Definition (num, _, _)) (j, lines) = |
551 fun add_desired_line _ _ _ _ (line as Definition (name, _, _)) (j, lines) = |
536 (j, line :: map (replace_deps_in_line (num, [])) lines) |
552 (j, line :: map (replace_deps_in_line (name, [])) lines) |
537 | add_desired_line isar_shrink_factor conjecture_shape axiom_names frees |
553 | add_desired_line isar_shrink_factor conjecture_shape axiom_names frees |
538 (Inference (num, t, deps)) (j, lines) = |
554 (Inference (name, t, deps)) (j, lines) = |
539 (j + 1, |
555 (j + 1, |
540 if is_axiom_number axiom_names num orelse |
556 if is_axiom_name axiom_names name orelse |
541 is_conjecture_number conjecture_shape num orelse |
557 is_conjecture_name conjecture_shape name orelse |
542 (not (is_only_type_information t) andalso |
558 (not (is_only_type_information t) andalso |
543 null (Term.add_tvars t []) andalso |
559 null (Term.add_tvars t []) andalso |
544 not (exists_subterm (is_bad_free frees) t) andalso |
560 not (exists_subterm (is_bad_free frees) t) andalso |
545 (null lines orelse (* last line must be kept *) |
561 (null lines orelse (* last line must be kept *) |
546 (length deps >= 2 andalso j mod isar_shrink_factor = 0))) then |
562 (length deps >= 2 andalso j mod isar_shrink_factor = 0))) then |
547 Inference (num, t, deps) :: lines (* keep line *) |
563 Inference (name, t, deps) :: lines (* keep line *) |
548 else |
564 else |
549 map (replace_deps_in_line (num, deps)) lines) (* drop line *) |
565 map (replace_deps_in_line (name, deps)) lines) (* drop line *) |
550 |
566 |
551 (** EXTRACTING LEMMAS **) |
567 (** EXTRACTING LEMMAS **) |
552 |
568 |
553 (* Like "split_line", but ignores "\n" that follow a comma (as in SNARK's |
569 (* Like "split_line", but ignores "\n" that follow a comma (as in SNARK's |
554 output). *) |
570 output). *) |
662 CaseSplit of step list list * facts |
680 CaseSplit of step list list * facts |
663 |
681 |
664 fun smart_case_split [] facts = ByMetis facts |
682 fun smart_case_split [] facts = ByMetis facts |
665 | smart_case_split proofs facts = CaseSplit (proofs, facts) |
683 | smart_case_split proofs facts = CaseSplit (proofs, facts) |
666 |
684 |
667 fun add_fact_from_dep axiom_names num = |
685 fun add_fact_from_dep axiom_names name = |
668 if is_axiom_number axiom_names num then |
686 if is_axiom_name axiom_names name then |
669 apsnd (union (op =) (map fst (Vector.sub (axiom_names, num - 1)))) |
687 apsnd (union (op =) (map fst (resolve_axiom axiom_names name))) |
670 else |
688 else |
671 apfst (insert (op =) (raw_prefix, num)) |
689 apfst (insert (op =) (raw_label_for_name name)) |
672 |
690 |
673 fun forall_of v t = HOLogic.all_const (fastype_of v) $ lambda v t |
691 fun forall_of v t = HOLogic.all_const (fastype_of v) $ lambda v t |
674 fun forall_vars t = fold_rev forall_of (map Var (Term.add_vars t [])) t |
692 fun forall_vars t = fold_rev forall_of (map Var (Term.add_vars t [])) t |
675 |
693 |
676 fun step_for_line _ _ (Definition (_, t1, t2)) = Let (t1, t2) |
694 fun step_for_line _ _ (Definition (_, t1, t2)) = Let (t1, t2) |
677 | step_for_line _ _ (Inference (num, t, [])) = Assume ((raw_prefix, num), t) |
695 | step_for_line _ _ (Inference (name, t, [])) = |
678 | step_for_line axiom_names j (Inference (num, t, deps)) = |
696 Assume (raw_label_for_name name, t) |
679 Have (if j = 1 then [Show] else [], (raw_prefix, num), |
697 | step_for_line axiom_names j (Inference (name, t, deps)) = |
|
698 Have (if j = 1 then [Show] else [], raw_label_for_name name, |
680 forall_vars t, |
699 forall_vars t, |
681 ByMetis (fold (add_fact_from_dep axiom_names) deps ([], []))) |
700 ByMetis (fold (add_fact_from_dep axiom_names) deps ([], []))) |
682 |
701 |
683 fun proof_from_atp_proof pool ctxt full_types tfrees isar_shrink_factor |
702 fun proof_from_atp_proof pool ctxt full_types tfrees isar_shrink_factor |
684 atp_proof conjecture_shape axiom_names params frees = |
703 atp_proof conjecture_shape axiom_names params frees = |
685 let |
704 let |
686 val lines = |
705 val lines = |
687 atp_proof ^ "$" (* the $ sign acts as a sentinel (FIXME: needed?) *) |
706 atp_proof ^ "$" (* the $ sign acts as a sentinel (FIXME: needed?) *) |
688 |> parse_proof pool |
707 |> parse_proof pool |
689 |> sort (int_ord o pairself raw_step_number) |
708 |> sort (tstp_name_ord o pairself raw_step_name) |
690 |> decode_lines ctxt full_types tfrees |
709 |> decode_lines ctxt full_types tfrees |
691 |> rpair [] |-> fold_rev (add_line conjecture_shape axiom_names) |
710 |> rpair [] |-> fold_rev (add_line conjecture_shape axiom_names) |
692 |> rpair [] |-> fold_rev add_nontrivial_line |
711 |> rpair [] |-> fold_rev add_nontrivial_line |
693 |> rpair (0, []) |-> fold_rev (add_desired_line isar_shrink_factor |
712 |> rpair (0, []) |-> fold_rev (add_desired_line isar_shrink_factor |
694 conjecture_shape axiom_names frees) |
713 conjecture_shape axiom_names frees) |