224 fixes = fixes} |
228 fixes = fixes} |
225 |
229 |
226 val step_prefix = ".c" |
230 val step_prefix = ".c" |
227 val input_rule = "input" |
231 val input_rule = "input" |
228 val la_generic_rule = "la_generic" |
232 val la_generic_rule = "la_generic" |
229 val normalized_input_rule = "__normalized_input" (* arbitrary *) |
233 val normalized_input_rule = "__normalized_input" (*arbitrary*) |
230 val rewrite_rule = "__rewrite" (* arbitrary *) |
234 val rewrite_rule = "__rewrite" (*arbitrary*) |
231 val subproof_rule = "subproof" |
235 val subproof_rule = "subproof" |
232 val local_input_rule = "__local_input" (* arbitrary *) |
236 val local_input_rule = "__local_input" (*arbitrary*) |
233 val simp_arith_rule = "simp_arith" |
237 val simp_arith_rule = "simp_arith" |
234 val veriT_def = "__skolem_definition" (*arbitrary*) |
238 val veriT_def = "__skolem_definition" (*arbitrary*) |
235 |
239 val not_not_rule = "not_not" |
236 val is_skolemisation = member (op =) ["sko_forall", "sko_ex"] |
240 val contract_rule = "contraction" |
237 val keep_app_symbols = member (op =) ["eq_congruent_pred", "eq_congruent", "ite_intro"] |
241 val eq_congruent_pred_rule = "eq_congruent_pred" |
238 val keep_raw_lifting = member (op =) ["eq_congruent_pred", "eq_congruent", "ite_intro"] |
242 val eq_congruent_rule = "eq_congruent" |
239 |
243 val ite_intro_rule = "ite_intro" |
240 fun is_skolemisation_step (VeriT_Replay_Node {id, ...}) = is_skolemisation id |
244 val default_skolem_rule = "sko_forall" (*arbitrary, but must be one of the skolems*) |
|
245 |
|
246 val skolemization_steps = ["sko_forall", "sko_ex"] |
|
247 val is_skolemization = member (op =) skolemization_steps |
|
248 val keep_app_symbols = member (op =) [eq_congruent_pred_rule, eq_congruent_rule, ite_intro_rule] |
|
249 val keep_raw_lifting = member (op =) [eq_congruent_pred_rule, eq_congruent_rule, ite_intro_rule] |
|
250 val is_SH_trivial = member (op =) [not_not_rule, contract_rule] |
|
251 |
|
252 fun is_skolemization_step (VeriT_Replay_Node {id, ...}) = is_skolemization id |
241 |
253 |
242 (* Even the veriT developers do not know if the following rule can still appear in proofs: *) |
254 (* Even the veriT developers do not know if the following rule can still appear in proofs: *) |
243 val veriT_deep_skolemize_rule = "deep_skolemize" |
255 val veriT_deep_skolemize_rule = "deep_skolemize" |
244 |
256 |
245 fun number_of_steps [] = 0 |
257 fun number_of_steps [] = 0 |
673 end |
685 end |
674 |
686 |
675 |
687 |
676 val linearize_proof = |
688 val linearize_proof = |
677 let |
689 let |
|
690 fun map_node_concl f (VeriT_Node {id, rule, prems, proof_ctxt, concl}) = |
|
691 mk_node id rule prems proof_ctxt (f concl) |
678 fun linearize (VeriT_Replay_Node {id = id, rule = rule, args = _, prems = prems, |
692 fun linearize (VeriT_Replay_Node {id = id, rule = rule, args = _, prems = prems, |
679 proof_ctxt = proof_ctxt, concl = concl, bounds = bounds, insts = _, declarations = _, |
693 proof_ctxt = proof_ctxt, concl = concl, bounds = bounds, insts = _, declarations = _, |
680 subproof = (_, _, _, subproof)}) = |
694 subproof = (bounds', assms, inputs, subproof)}) = |
681 let |
695 let |
|
696 val bounds = distinct (op =) bounds |
|
697 val bounds' = distinct (op =) bounds' |
682 fun mk_prop_of_term concl = |
698 fun mk_prop_of_term concl = |
683 concl |> fastype_of concl = \<^typ>\<open>bool\<close> ? curry (op $) \<^term>\<open>Trueprop\<close> |
699 concl |> fastype_of concl = \<^typ>\<open>bool\<close> ? curry (op $) \<^term>\<open>Trueprop\<close> |
684 fun remove_assumption_id assumption_id prems = |
700 fun remove_assumption_id assumption_id prems = |
685 filter_out (curry (op =) assumption_id) prems |
701 filter_out (curry (op =) assumption_id) prems |
|
702 fun add_assumption assumption concl = |
|
703 \<^const>\<open>Pure.imp\<close> $ mk_prop_of_term assumption $ mk_prop_of_term concl |
686 fun inline_assumption assumption assumption_id |
704 fun inline_assumption assumption assumption_id |
687 (VeriT_Node {id, rule, prems, proof_ctxt, concl, bounds}) = |
705 (VeriT_Node {id, rule, prems, proof_ctxt, concl}) = |
688 mk_node id rule (remove_assumption_id assumption_id prems) proof_ctxt |
706 mk_node id rule (remove_assumption_id assumption_id prems) proof_ctxt |
689 (\<^const>\<open>Pure.imp\<close> $ mk_prop_of_term assumption $ mk_prop_of_term concl) bounds |
707 (add_assumption assumption concl) |
690 fun find_input_steps_and_inline [] = [] |
708 fun find_input_steps_and_inline [] = [] |
691 | find_input_steps_and_inline |
709 | find_input_steps_and_inline |
692 (VeriT_Node {id = id', rule, prems, concl, bounds, ...} :: steps) = |
710 (VeriT_Node {id = id', rule, prems, concl, ...} :: steps) = |
693 if rule = input_rule then |
711 if rule = input_rule then |
694 find_input_steps_and_inline (map (inline_assumption concl id') steps) |
712 find_input_steps_and_inline (map (inline_assumption concl id') steps) |
695 else |
713 else |
696 mk_node (id') rule prems [] concl bounds :: find_input_steps_and_inline steps |
714 mk_node (id') rule prems [] concl :: find_input_steps_and_inline steps |
697 |
715 |
698 val subproof = flat (map linearize subproof) |
716 fun free_bounds bounds (concl) = |
699 val subproof' = find_input_steps_and_inline subproof |
717 fold (fn (var, typ) => fn t => Logic.all (Free (var, typ)) t) bounds concl |
|
718 val subproof = subproof |
|
719 |> flat o map linearize |
|
720 |> map (map_node_concl (fold add_assumption (assms @ inputs))) |
|
721 |> map (map_node_concl (free_bounds (bounds @ bounds'))) |
|
722 |> find_input_steps_and_inline |
|
723 val concl = free_bounds bounds concl |
700 in |
724 in |
701 subproof' @ [mk_node id rule prems proof_ctxt concl (map fst bounds)] |
725 subproof @ [mk_node id rule prems proof_ctxt concl] |
702 end |
726 end |
703 in linearize end |
727 in linearize end |
|
728 |
|
729 fun rule_of (VeriT_Replay_Node {rule,...}) = rule |
|
730 fun subproof_of (VeriT_Replay_Node {subproof = (_, _, _, subproof),...}) = subproof |
|
731 |
|
732 |
|
733 (* Massage Skolems for Sledgehammer. |
|
734 |
|
735 We have to make sure that there is an "arrow" in the graph for skolemization steps. |
|
736 |
|
737 |
|
738 A. The normal easy case |
|
739 |
|
740 This function detects the steps of the form |
|
741 P \<longleftrightarrow> Q :skolemization |
|
742 Q :resolution with P |
|
743 and replace them by |
|
744 Q :skolemization |
|
745 Throwing away the step "P \<longleftrightarrow> Q" completely. This throws away a lot of information, but it does not |
|
746 matter too much for Sledgehammer. |
|
747 |
|
748 |
|
749 B. Skolems in subproofs |
|
750 Supporting this is more or less hopeless as long as the Isar reconstruction of Sledgehammer |
|
751 does not support more features like definitions. veriT is able to generate proofs with skolemization |
|
752 happening in subproofs inside the formula. |
|
753 (assume "A \<or> P" |
|
754 ... |
|
755 P \<longleftrightarrow> Q :skolemization in the subproof |
|
756 ...) |
|
757 hence A \<or> P \<longrightarrow> A \<or> Q :lemma |
|
758 ... |
|
759 R :something with some rule |
|
760 and replace them by |
|
761 R :skolemization with some rule |
|
762 Without any subproof |
|
763 *) |
|
764 fun remove_skolem_definitions_proof steps = |
|
765 let |
|
766 fun replace_equivalent_by_imp (judgement $ ((Const(\<^const_name>\<open>HOL.eq\<close>, typ) $ arg1) $ arg2)) = |
|
767 judgement $ ((Const(\<^const_name>\<open>HOL.implies\<close>, typ) $ arg1) $ arg2) |
|
768 | replace_equivalent_by_imp a = a (*This case is probably wrong*) |
|
769 fun remove_skolem_definitions (VeriT_Replay_Node {id = id, rule = rule, args = args, |
|
770 prems = prems, |
|
771 proof_ctxt = proof_ctxt, concl = concl, bounds = bounds, insts = insts, |
|
772 declarations = declarations, |
|
773 subproof = (vars, assms', extra_assms', subproof)}) (prems_to_remove, skolems) = |
|
774 let |
|
775 val prems = prems |
|
776 |> filter_out (member (op =) prems_to_remove) |
|
777 val trivial_step = is_SH_trivial rule |
|
778 fun has_skolem_substep st NONE = if is_skolemization (rule_of st) then SOME (rule_of st) |
|
779 else fold has_skolem_substep (subproof_of st) NONE |
|
780 | has_skolem_substep _ a = a |
|
781 val promote_to_skolem = exists (fn t => member (op =) skolems t) prems |
|
782 val promote_from_assms = fold has_skolem_substep subproof NONE <> NONE |
|
783 val promote_step = promote_to_skolem orelse promote_from_assms |
|
784 val skolem_step_to_skip = is_skolemization rule orelse |
|
785 (promote_from_assms andalso length prems > 1) |
|
786 val is_skolem = is_skolemization rule orelse promote_step |
|
787 val prems = prems |
|
788 |> filter_out (fn t => member (op =) skolems t) |
|
789 |> is_skolem ? filter_out (String.isPrefix id) |
|
790 val rule = (if promote_step then default_skolem_rule else rule) |
|
791 val subproof = subproof |
|
792 |> (is_skolem ? K []) (*subproofs of skolemization steps are useless for SH*) |
|
793 |> map (fst o (fn st => remove_skolem_definitions st (prems_to_remove, skolems))) |
|
794 (*no new definitions in subproofs*) |
|
795 |> flat |
|
796 val concl = concl |
|
797 |> is_skolem ? replace_equivalent_by_imp |
|
798 val step = (if skolem_step_to_skip orelse rule = veriT_def orelse trivial_step then [] |
|
799 else mk_replay_node id rule args prems proof_ctxt concl bounds insts declarations |
|
800 (vars, assms', extra_assms', subproof) |
|
801 |> single) |
|
802 val defs = (if rule = veriT_def orelse trivial_step then id :: prems_to_remove |
|
803 else prems_to_remove) |
|
804 val skolems = (if skolem_step_to_skip then id :: skolems else skolems) |
|
805 in |
|
806 (step, (defs, skolems)) |
|
807 end |
|
808 in |
|
809 fold_map remove_skolem_definitions steps ([], []) |
|
810 |> fst |
|
811 |> flat |
|
812 end |
704 |
813 |
705 local |
814 local |
706 fun import_proof_and_post_process typs funs lines ctxt = |
815 fun import_proof_and_post_process typs funs lines ctxt = |
707 let |
816 let |
708 val compress = SMT_Config.compress_verit_proofs ctxt |
817 val compress = SMT_Config.compress_verit_proofs ctxt |
717 fun process step (cx, cx') = |
826 fun process step (cx, cx') = |
718 let fun postprocess step (cx, cx') = |
827 let fun postprocess step (cx, cx') = |
719 let val (step, cx) = postprocess_proof compress ctxt step cx |
828 let val (step, cx) = postprocess_proof compress ctxt step cx |
720 in (step, (cx, cx')) end |
829 in (step, (cx, cx')) end |
721 in uncurry (fold_map postprocess) (preprocess compress step (cx, cx')) end |
830 in uncurry (fold_map postprocess) (preprocess compress step (cx, cx')) end |
722 val step = |
831 val step = |
723 (empty_context ctxt typs funs, []) |
832 (empty_context ctxt typs funs, []) |
724 |> fold_map process raw_steps |
833 |> fold_map process raw_steps |
725 |> (fn (steps, (cx, _)) => (flat steps, cx)) |
834 |> (fn (steps, (cx, _)) => (flat steps, cx)) |
726 in step end |
835 in step end |
727 in |
836 in |
728 |
837 |
729 fun parse typs funs lines ctxt = |
838 fun parse typs funs lines ctxt = |
730 let |
839 let |
731 val (u, env) = import_proof_and_post_process typs funs lines ctxt |
840 val (u, env) = import_proof_and_post_process typs funs lines ctxt |
732 val t = flat (map linearize_proof u) |
841 val t = u |
733 fun node_to_step (VeriT_Node {id, rule, prems, concl, bounds, ...}) = |
842 |> remove_skolem_definitions_proof |
734 mk_step id rule prems [] concl bounds |
843 |> flat o (map linearize_proof) |
|
844 fun node_to_step (VeriT_Node {id, rule, prems, concl, ...}) = |
|
845 mk_step id rule prems [] concl [] |
735 in |
846 in |
736 (map node_to_step t, ctxt_of env) |
847 (map node_to_step t, ctxt_of env) |
737 end |
848 end |
738 |
849 |
739 fun parse_replay typs funs lines ctxt = |
850 fun parse_replay typs funs lines ctxt = |