454 Inference_Step (name, role, t, rule, deps) :: lines (* keep line *) |
454 Inference_Step (name, role, t, rule, deps) :: lines (* keep line *) |
455 else |
455 else |
456 map (replace_dependencies_in_line (name, deps)) lines) (* drop line *) |
456 map (replace_dependencies_in_line (name, deps)) lines) (* drop line *) |
457 |
457 |
458 val indent_size = 2 |
458 val indent_size = 2 |
459 val no_label = ("", ~1) |
|
460 |
459 |
461 fun string_for_proof ctxt type_enc lam_trans i n = |
460 fun string_for_proof ctxt type_enc lam_trans i n = |
462 let |
461 let |
|
462 fun maybe_show qs = if member (op =) qs Show then "show" else "have" |
463 fun of_indent ind = replicate_string (ind * indent_size) " " |
463 fun of_indent ind = replicate_string (ind * indent_size) " " |
464 fun of_free (s, T) = |
464 fun of_free (s, T) = |
465 maybe_quote s ^ " :: " ^ |
465 maybe_quote s ^ " :: " ^ |
466 maybe_quote (simplify_spaces (with_vanilla_print_mode |
466 maybe_quote (simplify_spaces (with_vanilla_print_mode |
467 (Syntax.string_of_typ ctxt) T)) |
467 (Syntax.string_of_typ ctxt) T)) |
468 val of_frees = space_implode " and " o map of_free |
468 val of_frees = space_implode " and " o map of_free |
|
469 fun maybe_moreover ind qs nr_subproofs = |
|
470 if member (op =) qs Then andalso nr_subproofs > 0 |
|
471 then of_indent ind ^ "moreover\n" |
|
472 else "" |
469 fun of_label l = if l = no_label then "" else string_for_label l ^ ": " |
473 fun of_label l = if l = no_label then "" else string_for_label l ^ ": " |
470 fun of_have qs = |
474 fun of_have qs nr_subproofs = |
471 (if member (op =) qs Ultimately then "ultimately " else "") ^ |
475 if (member (op =) qs Then andalso nr_subproofs>0) orelse (nr_subproofs>1) |
472 (if member (op =) qs Then then |
476 then "ultimately " ^ maybe_show qs |
473 if member (op =) qs Show then "thus" else "hence" |
477 else |
474 else |
478 (if member (op =) qs Then orelse nr_subproofs>0 then |
475 if member (op =) qs Show then "show" else "have") |
479 if member (op =) qs Show then "thus" else "hence" |
|
480 else |
|
481 maybe_show qs) |
476 fun of_obtain qs xs = |
482 fun of_obtain qs xs = |
477 (if member (op =) qs Then then "then " else "") ^ "obtain " ^ |
483 (if member (op =) qs Then then "then " else "") ^ "obtain " ^ |
478 of_frees xs ^ " where" |
484 of_frees xs ^ " where" |
479 val of_term = |
485 val of_term = |
480 annotate_types ctxt |
486 annotate_types ctxt |
490 and of_step ind (Fix xs) = of_indent ind ^ "fix " ^ of_frees xs ^ "\n" |
496 and of_step ind (Fix xs) = of_indent ind ^ "fix " ^ of_frees xs ^ "\n" |
491 | of_step ind (Let (t1, t2)) = |
497 | of_step ind (Let (t1, t2)) = |
492 of_indent ind ^ "let " ^ of_term t1 ^ " = " ^ of_term t2 ^ "\n" |
498 of_indent ind ^ "let " ^ of_term t1 ^ " = " ^ of_term t2 ^ "\n" |
493 | of_step ind (Assume (l, t)) = |
499 | of_step ind (Assume (l, t)) = |
494 of_indent ind ^ "assume " ^ of_label l ^ of_term t ^ "\n" |
500 of_indent ind ^ "assume " ^ of_label l ^ of_term t ^ "\n" |
495 | of_step ind (Obtain (qs, xs, l, t, By_Metis facts)) = |
501 | of_step ind (Obtain (qs, xs, l, t, By_Metis (subproofs, facts))) = (* FIXME *) |
|
502 maybe_moreover ind qs (length subproofs) ^ |
|
503 of_subproofs ind subproofs ^ |
496 of_indent ind ^ of_obtain qs xs ^ " " ^ |
504 of_indent ind ^ of_obtain qs xs ^ " " ^ |
497 of_label l ^ of_term t ^ |
505 of_label l ^ of_term t ^ |
498 (* The new skolemizer puts the arguments in the same order as the ATPs |
506 (* The new skolemizer puts the arguments in the same order as the ATPs |
499 (E and Vampire -- but see also "atp_proof_reconstruct.ML" regarding |
507 (E and Vampire -- but see also "atp_proof_reconstruct.ML" regarding |
500 Vampire). *) |
508 Vampire). *) |
501 of_metis ind "using [[metis_new_skolem]] " facts ^ "\n" |
509 of_metis ind "using [[metis_new_skolem]] " facts ^ "\n" |
502 | of_step ind (Prove (qs, l, t, By_Metis facts)) = |
510 | of_step ind (Prove (qs, l, t, By_Metis (subproofs, facts))) = |
503 of_prove ind qs l t facts |
511 maybe_moreover ind qs (length subproofs) ^ |
504 | of_step ind (Prove (qs, l, t, Case_Split proofs)) = |
512 of_subproofs ind subproofs ^ |
505 implode (map (prefix (of_indent ind ^ "moreover\n") o of_block ind) |
513 of_prove ind qs (length subproofs) l t facts |
506 proofs) ^ |
|
507 of_prove ind qs l t ([], []) |
|
508 | of_step ind (Prove (qs, l, t, Subblock proof)) = |
|
509 of_block ind proof ^ of_prove ind qs l t ([], []) |
|
510 and of_steps prefix suffix ind steps = |
514 and of_steps prefix suffix ind steps = |
511 let val s = implode (map (of_step ind) steps) in |
515 let val s = implode (map (of_step ind) steps) in |
512 replicate_string (ind * indent_size - size prefix) " " ^ prefix ^ |
516 replicate_string (ind * indent_size - size prefix) " " ^ prefix ^ |
513 String.extract (s, ind * indent_size, |
517 String.extract (s, ind * indent_size, |
514 SOME (size s - ind * indent_size - 1)) ^ |
518 SOME (size s - ind * indent_size - 1)) ^ |
515 suffix ^ "\n" |
519 suffix ^ "\n" |
516 end |
520 end |
517 and of_block ind proof = of_steps "{ " " }" (ind + 1) proof |
521 and of_block ind proof = of_steps "{ " " }" (ind + 1) proof |
518 and of_prove ind qs l t facts = |
522 and of_subproofs ind subproofs = |
519 of_indent ind ^ of_have qs ^ " " ^ of_label l ^ of_term t ^ |
523 subproofs |
|
524 |> map (of_block ind) |
|
525 |> space_implode (of_indent ind ^ "moreover\n") |
|
526 and of_prove ind qs nr_subproofs l t facts = |
|
527 of_indent ind ^ of_have qs nr_subproofs ^ " " ^ of_label l ^ of_term t ^ |
520 of_metis ind "" facts ^ "\n" |
528 of_metis ind "" facts ^ "\n" |
521 (* One-step proofs are pointless; better use the Metis one-liner |
529 (* One-step proofs are pointless; better use the Metis one-liner |
522 directly. *) |
530 directly. *) |
523 and of_proof [Prove (_, _, _, By_Metis _)] = "" |
531 and of_proof [Prove (_, _, _, By_Metis ([], _))] = "" |
524 | of_proof proof = |
532 | of_proof proof = |
525 (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^ |
533 (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^ |
526 of_indent 0 ^ "proof -\n" ^ of_steps "" "" 1 proof ^ of_indent 0 ^ |
534 of_indent 0 ^ "proof -\n" ^ of_steps "" "" 1 proof ^ of_indent 0 ^ |
527 (if n <> 1 then "next" else "qed") |
535 (if n <> 1 then "next" else "qed") |
528 in of_proof end |
536 in of_proof end |
529 |
537 |
530 fun used_labels_of_step (Obtain (_, _, _, _, By_Metis (ls, _))) = ls |
538 fun add_labels_of_step (Obtain (_, _, _, _, By_Metis (subproofs, (ls, _)))) = |
531 | used_labels_of_step (Prove (_, _, _, by)) = |
539 union (op =) (add_labels_of_proofs subproofs ls) |
532 (case by of |
540 | add_labels_of_step (Prove (_, _, _, By_Metis (subproofs, (ls, _)))) = |
533 By_Metis (ls, _) => ls |
541 union (op =) (add_labels_of_proofs subproofs ls) |
534 | Case_Split proofs => fold (union (op =) o used_labels_of) proofs [] |
542 | add_labels_of_step _ = I |
535 | Subblock proof => used_labels_of proof) |
543 and add_labels_of_proof proof = fold add_labels_of_step proof |
536 | used_labels_of_step _ = [] |
544 and add_labels_of_proofs proofs = fold add_labels_of_proof proofs |
537 and used_labels_of proof = fold (union (op =) o used_labels_of_step) proof [] |
|
538 |
545 |
539 fun kill_useless_labels_in_proof proof = |
546 fun kill_useless_labels_in_proof proof = |
540 let |
547 let |
541 val used_ls = used_labels_of proof |
548 val used_ls = add_labels_of_proof proof [] |
542 fun do_label l = if member (op =) used_ls l then l else no_label |
549 fun do_label l = if member (op =) used_ls l then l else no_label |
543 fun do_step (Assume (l, t)) = Assume (do_label l, t) |
550 fun do_step (Assume (l, t)) = Assume (do_label l, t) |
544 | do_step (Obtain (qs, xs, l, t, by)) = Obtain (qs, xs, do_label l, t, by) |
551 | do_step (Obtain (qs, xs, l, t, By_Metis (subproofs, facts))) = |
545 | do_step (Prove (qs, l, t, by)) = |
552 Obtain (qs, xs, do_label l, t, By_Metis (map do_proof subproofs, facts)) |
546 Prove (qs, do_label l, t, |
553 | do_step (Prove (qs, l, t, By_Metis (subproofs, facts))) = |
547 case by of |
554 Prove (qs, do_label l, t, By_Metis (map do_proof subproofs, facts)) |
548 Case_Split proofs => Case_Split (map do_proof proofs) |
|
549 | Subblock proof => Subblock (do_proof proof) |
|
550 | _ => by) |
|
551 | do_step step = step |
555 | do_step step = step |
552 and do_proof proof = map do_step proof |
556 and do_proof proof = map do_step proof |
553 in do_proof proof end |
557 in do_proof proof end |
554 |
558 |
555 fun prefix_for_depth n = replicate_string (n + 1) |
559 fun prefix_for_depth n = replicate_string (n + 1) |
606 let |
607 let |
607 fun label_of (Assume (l, _)) = SOME l |
608 fun label_of (Assume (l, _)) = SOME l |
608 | label_of (Obtain (_, _, l, _, _)) = SOME l |
609 | label_of (Obtain (_, _, l, _, _)) = SOME l |
609 | label_of (Prove (_, l, _, _)) = SOME l |
610 | label_of (Prove (_, l, _, _)) = SOME l |
610 | label_of _ = NONE |
611 | label_of _ = NONE |
611 fun chain_step (SOME l0) |
612 fun do_qs_lfs NONE lfs = ([], lfs) |
612 (step as Obtain (qs, xs, l, t, By_Metis (lfs, gfs))) = |
613 | do_qs_lfs (SOME l0) lfs = |
613 if member (op =) lfs l0 then |
614 if member (op =) lfs l0 then ([Then], lfs |> remove (op =) l0) |
614 Obtain (Then :: qs, xs, l, t, By_Metis (lfs |> remove (op =) l0, gfs)) |
615 else ([], lfs) |
615 else |
616 fun chain_step lbl (Obtain (qs, xs, l, t, |
616 step |
617 By_Metis (subproofs, (lfs, gfs)))) = |
617 | chain_step (SOME l0) |
618 let val (qs', lfs) = do_qs_lfs lbl lfs in |
618 (step as Prove (qs, l, t, By_Metis (lfs, gfs))) = |
619 Obtain (qs' @ qs, xs, l, t, |
619 if member (op =) lfs l0 then |
620 By_Metis (chain_proofs subproofs, (lfs, gfs))) |
620 Prove (Then :: qs, l, t, By_Metis (lfs |> remove (op =) l0, gfs)) |
621 end |
621 else |
622 | chain_step lbl (Prove (qs, l, t, By_Metis (subproofs, (lfs, gfs)))) = |
622 step |
623 let val (qs', lfs) = do_qs_lfs lbl lfs in |
623 | chain_step _ (Prove (qs, l, t, Case_Split proofs)) = |
624 Prove (qs' @ qs, l, t, |
624 Prove (qs, l, t, Case_Split (map (chain_proof NONE) proofs)) |
625 By_Metis (chain_proofs subproofs, (lfs, gfs))) |
625 | chain_step _ (Prove (qs, l, t, Subblock proof)) = |
626 end |
626 Prove (qs, l, t, Subblock (chain_proof NONE proof)) |
|
627 | chain_step _ step = step |
627 | chain_step _ step = step |
628 and chain_proof _ [] = [] |
628 and chain_proof _ [] = [] |
629 | chain_proof (prev as SOME _) (i :: is) = |
629 | chain_proof (prev as SOME _) (i :: is) = |
630 chain_step prev i :: chain_proof (label_of i) is |
630 chain_step prev i :: chain_proof (label_of i) is |
631 | chain_proof _ (i :: is) = i :: chain_proof (label_of i) is |
631 | chain_proof _ (i :: is) = i :: chain_proof (label_of i) is |
|
632 and chain_proofs proofs = map (chain_proof NONE) proofs |
632 in chain_proof NONE end |
633 in chain_proof NONE end |
633 |
634 |
634 type isar_params = |
635 type isar_params = |
635 bool * bool * Time.time option * real * string Symtab.table |
636 bool * bool * Time.time option * real * string Symtab.table |
636 * (string * stature) list vector * int Symtab.table * string proof * thm |
637 * (string * stature) list vector * int Symtab.table * string proof * thm |
719 (Library.foldr1 s_conj (map HOLogic.dest_not negs), |
720 (Library.foldr1 s_conj (map HOLogic.dest_not negs), |
720 Library.foldr1 s_disj pos) |
721 Library.foldr1 s_disj pos) |
721 | _ => fold (curry s_disj) lits @{term False} |
722 | _ => fold (curry s_disj) lits @{term False} |
722 end |
723 end |
723 |> HOLogic.mk_Trueprop |> close_form |
724 |> HOLogic.mk_Trueprop |> close_form |
724 fun isar_proof_of_direct_proof outer accum [] = |
725 fun isar_proof_of_direct_proof outer predecessor accum [] = |
725 rev accum |> outer ? (append assms |
726 rev accum |> outer ? (append assms |
726 #> not (null params) ? cons (Fix params)) |
727 #> not (null params) ? cons (Fix params)) |
727 | isar_proof_of_direct_proof outer accum (inf :: infs) = |
728 | isar_proof_of_direct_proof outer predecessor accum (inf :: infs) = |
728 let |
729 let |
729 fun maybe_show outer c = |
730 fun maybe_show outer c = |
730 (outer andalso length c = 1 andalso subset (op =) (c, conjs)) |
731 (outer andalso length c = 1 andalso subset (op =) (c, conjs)) |
731 ? cons Show |
732 ? cons Show |
732 fun do_rest step = |
733 fun do_rest lbl step = |
733 isar_proof_of_direct_proof outer (step :: accum) infs |
734 isar_proof_of_direct_proof outer lbl (step :: accum) infs |
734 val is_fixed = Variable.is_declared ctxt orf can Name.dest_skolem |
735 val is_fixed = Variable.is_declared ctxt orf can Name.dest_skolem |
735 fun skolems_of t = |
736 fun skolems_of t = |
736 Term.add_frees t [] |> filter_out (is_fixed o fst) |> rev |
737 Term.add_frees t [] |> filter_out (is_fixed o fst) |> rev |
737 in |
738 in |
738 case inf of |
739 case inf of |
739 Have (gamma, c) => |
740 Have (gamma, c) => |
740 let |
741 let |
741 val l = label_of_clause c |
742 val l = label_of_clause c |
742 val t = prop_of_clause c |
743 val t = prop_of_clause c |
743 val by = |
744 val by = |
744 By_Metis (fold (add_fact_from_dependencies fact_names) gamma |
745 By_Metis ([], |
745 ([], [])) |
746 (fold (add_fact_from_dependencies fact_names) |
|
747 gamma no_facts)) |
746 fun prove outer = Prove (maybe_show outer c [], l, t, by) |
748 fun prove outer = Prove (maybe_show outer c [], l, t, by) |
747 in |
749 in |
748 if is_clause_tainted c then |
750 if is_clause_tainted c then |
749 case gamma of |
751 case gamma of |
750 [g] => |
752 [g] => |
751 if is_clause_skolemize_rule g andalso |
753 if is_clause_skolemize_rule g andalso |
752 is_clause_tainted g then |
754 is_clause_tainted g then |
753 let |
755 let |
754 val proof = |
756 val subproof = |
755 Fix (skolems_of (prop_of_clause g)) :: rev accum |
757 Fix (skolems_of (prop_of_clause g)) :: rev accum |
756 in |
758 in |
757 isar_proof_of_direct_proof outer |
759 isar_proof_of_direct_proof outer l |
758 [Prove (maybe_show outer c [Then], |
760 [Prove (maybe_show outer c [], |
759 label_of_clause c, prop_of_clause c, |
761 label_of_clause c, prop_of_clause c, |
760 Subblock proof)] [] |
762 By_Metis ([subproof], no_facts))] [] |
761 end |
763 end |
762 else |
764 else |
763 do_rest (prove outer) |
765 do_rest l (prove outer) |
764 | _ => do_rest (prove outer) |
766 | _ => do_rest l (prove outer) |
765 else |
767 else |
766 if is_clause_skolemize_rule c then |
768 if is_clause_skolemize_rule c then |
767 do_rest (Obtain ([], skolems_of t, l, t, by)) |
769 do_rest l (Obtain ([], skolems_of t, l, t, by)) |
768 else |
770 else |
769 do_rest (prove outer) |
771 do_rest l (prove outer) |
770 end |
772 end |
771 | Cases cases => |
773 | Cases cases => |
772 let |
774 let |
773 fun do_case (c, infs) = |
775 fun do_case (c, infs) = |
774 Assume (label_of_clause c, prop_of_clause c) :: |
776 Assume (label_of_clause c, prop_of_clause c) :: |
775 isar_proof_of_direct_proof false [] infs |
777 isar_proof_of_direct_proof false no_label [] infs |
776 val c = succedent_of_cases cases |
778 val c = succedent_of_cases cases |
|
779 val l = label_of_clause c |
777 in |
780 in |
778 do_rest (Prove (maybe_show outer c [Ultimately], |
781 do_rest l |
779 label_of_clause c, prop_of_clause c, |
782 (Prove (maybe_show outer c [], |
780 Case_Split (map do_case cases))) |
783 l, prop_of_clause c, |
|
784 By_Metis (map do_case cases, ([predecessor], [])))) |
781 end |
785 end |
782 end |
786 end |
783 val cleanup_labels_in_proof = |
787 val cleanup_labels_in_proof = |
784 chain_direct_proof |
788 chain_direct_proof |
785 #> kill_useless_labels_in_proof |
789 #> kill_useless_labels_in_proof |
786 #> relabel_proof |
790 #> relabel_proof |
787 val (isar_proof, (preplay_fail, preplay_time)) = |
791 val (isar_proof, (preplay_fail, preplay_time)) = |
788 refute_graph |
792 refute_graph |
789 |> redirect_graph axioms tainted bot |
793 |> redirect_graph axioms tainted bot |
790 |> isar_proof_of_direct_proof true [] |
794 |> isar_proof_of_direct_proof true no_label [] |
791 |> (if not preplay andalso isar_compress <= 1.0 then |
795 |> (if not preplay andalso isar_compress <= 1.0 then |
792 rpair (false, (true, seconds 0.0)) |
796 rpair (false, (true, seconds 0.0)) |
793 else |
797 else |
794 compress_proof debug ctxt type_enc lam_trans preplay |
798 compress_proof debug ctxt type_enc lam_trans preplay |
795 preplay_timeout |
799 preplay_timeout |