50 begin |
50 begin |
51 |
51 |
52 |
52 |
53 section "Setup" |
53 section "Setup" |
54 |
54 |
55 ML {* |
55 ML \<open> |
56 val tptp_unexceptional_reconstruction = Attrib.setup_config_bool @{binding tptp_unexceptional_reconstruction} (K false) |
56 val tptp_unexceptional_reconstruction = Attrib.setup_config_bool @{binding tptp_unexceptional_reconstruction} (K false) |
57 fun unexceptional_reconstruction ctxt = Config.get ctxt tptp_unexceptional_reconstruction |
57 fun unexceptional_reconstruction ctxt = Config.get ctxt tptp_unexceptional_reconstruction |
58 val tptp_informative_failure = Attrib.setup_config_bool @{binding tptp_informative_failure} (K false) |
58 val tptp_informative_failure = Attrib.setup_config_bool @{binding tptp_informative_failure} (K false) |
59 fun informative_failure ctxt = Config.get ctxt tptp_informative_failure |
59 fun informative_failure ctxt = Config.get ctxt tptp_informative_failure |
60 val tptp_trace_reconstruction = Attrib.setup_config_bool @{binding tptp_trace_reconstruction} (K false) |
60 val tptp_trace_reconstruction = Attrib.setup_config_bool @{binding tptp_trace_reconstruction} (K false) |
65 val max = Config.get ctxt tptp_max_term_size |
65 val max = Config.get ctxt tptp_max_term_size |
66 in |
66 in |
67 if max = 0 then false |
67 if max = 0 then false |
68 else size > max |
68 else size > max |
69 end |
69 end |
70 *} |
70 \<close> |
71 |
71 |
72 (*FIXME move to TPTP_Proof_Reconstruction_Test_Units*) |
72 (*FIXME move to TPTP_Proof_Reconstruction_Test_Units*) |
73 declare [[ |
73 declare [[ |
74 tptp_unexceptional_reconstruction = false, (*NOTE should be "false" while testing*) |
74 tptp_unexceptional_reconstruction = false, (*NOTE should be "false" while testing*) |
75 tptp_informative_failure = true |
75 tptp_informative_failure = true |
85 unify_search_bound = 5 |
85 unify_search_bound = 5 |
86 ]] |
86 ]] |
87 |
87 |
88 |
88 |
89 section "Proof reconstruction" |
89 section "Proof reconstruction" |
90 text {*There are two parts to proof reconstruction: |
90 text \<open>There are two parts to proof reconstruction: |
91 \begin{itemize} |
91 \begin{itemize} |
92 \item interpreting the inferences |
92 \item interpreting the inferences |
93 \item building the skeleton, which indicates how to compose |
93 \item building the skeleton, which indicates how to compose |
94 individual inferences into subproofs, and then compose the |
94 individual inferences into subproofs, and then compose the |
95 subproofs to give the proof). |
95 subproofs to give the proof). |
142 |
142 |
143 It is hoped that this setup can target other provers by modifying the |
143 It is hoped that this setup can target other provers by modifying the |
144 clause representation to fit them, and adapting the inference |
144 clause representation to fit them, and adapting the inference |
145 interpretation to handle the rules used by the prover. It should also |
145 interpretation to handle the rules used by the prover. It should also |
146 facilitate composing together proofs found by different provers. |
146 facilitate composing together proofs found by different provers. |
147 *} |
147 \<close> |
148 |
148 |
149 |
149 |
150 subsection "Instantiation" |
150 subsection "Instantiation" |
151 |
151 |
152 lemma polar_allE [rule_format]: |
152 lemma polar_allE [rule_format]: |
157 lemma polar_exE [rule_format]: |
157 lemma polar_exE [rule_format]: |
158 "\<lbrakk>(\<exists>x. P x) = True; \<And>x. (P x) = True \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" |
158 "\<lbrakk>(\<exists>x. P x) = True; \<And>x. (P x) = True \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" |
159 "\<lbrakk>(\<forall>x. P x) = False; \<And>x. (P x) = False \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" |
159 "\<lbrakk>(\<forall>x. P x) = False; \<And>x. (P x) = False \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" |
160 by auto |
160 by auto |
161 |
161 |
162 ML {* |
162 ML \<open> |
163 (*This carries out an allE-like rule but on (polarised) literals. |
163 (*This carries out an allE-like rule but on (polarised) literals. |
164 Instead of yielding a free variable (which is a hell for the |
164 Instead of yielding a free variable (which is a hell for the |
165 matcher) it seeks to use one of the subgoals' parameters. |
165 matcher) it seeks to use one of the subgoals' parameters. |
166 This ought to be sufficient for emulating extcnf_combined, |
166 This ought to be sufficient for emulating extcnf_combined, |
167 but note that the complexity of the problem can be enormous.*) |
167 but note that the complexity of the problem can be enormous.*) |
193 end |
193 end |
194 end |
194 end |
195 |
195 |
196 (*Attempts to use the polar_allE theorems on a specific subgoal.*) |
196 (*Attempts to use the polar_allE theorems on a specific subgoal.*) |
197 fun forall_pos_tac ctxt = inst_parametermatch_tac ctxt @{thms polar_allE} |
197 fun forall_pos_tac ctxt = inst_parametermatch_tac ctxt @{thms polar_allE} |
198 *} |
198 \<close> |
199 |
199 |
200 ML {* |
200 ML \<open> |
201 (*This is similar to inst_parametermatch_tac, but prefers to |
201 (*This is similar to inst_parametermatch_tac, but prefers to |
202 match variables having identical names. Logically, this is |
202 match variables having identical names. Logically, this is |
203 a hack. But it reduces the complexity of the problem.*) |
203 a hack. But it reduces the complexity of the problem.*) |
204 fun nominal_inst_parametermatch_tac ctxt thm i = fn st => |
204 fun nominal_inst_parametermatch_tac ctxt thm i = fn st => |
205 let |
205 let |
289 THEN HEADGOAL (assume_tac ctxt)) |
289 THEN HEADGOAL (assume_tac ctxt)) |
290 in |
290 in |
291 dresolve_tac ctxt [thm] i st |
291 dresolve_tac ctxt [thm] i st |
292 end |
292 end |
293 end |
293 end |
294 *} |
294 \<close> |
295 |
295 |
296 |
296 |
297 subsection "Some general rules and congruences" |
297 subsection "Some general rules and congruences" |
298 |
298 |
299 (*this isn't an actual rule used in Leo2, but it seems to be |
299 (*this isn't an actual rule used in Leo2, but it seems to be |
300 applied implicitly during some Leo2 inferences.*) |
300 applied implicitly during some Leo2 inferences.*) |
301 lemma polarise: "P ==> P = True" by auto |
301 lemma polarise: "P ==> P = True" by auto |
302 |
302 |
303 ML {* |
303 ML \<open> |
304 fun is_polarised t = |
304 fun is_polarised t = |
305 (TPTP_Reconstruct.remove_polarity true t; true) |
305 (TPTP_Reconstruct.remove_polarity true t; true) |
306 handle TPTP_Reconstruct.UNPOLARISED _ => false |
306 handle TPTP_Reconstruct.UNPOLARISED _ => false |
307 |
307 |
308 fun polarise_subgoal_hyps ctxt = |
308 fun polarise_subgoal_hyps ctxt = |
309 COND' (SOME #> TERMPRED is_polarised (fn _ => true)) (K no_tac) (dresolve_tac ctxt @{thms polarise}) |
309 COND' (SOME #> TERMPRED is_polarised (fn _ => true)) (K no_tac) (dresolve_tac ctxt @{thms polarise}) |
310 *} |
310 \<close> |
311 |
311 |
312 lemma simp_meta [rule_format]: |
312 lemma simp_meta [rule_format]: |
313 "(A --> B) == (~A | B)" |
313 "(A --> B) == (~A | B)" |
314 "(A | B) | C == A | B | C" |
314 "(A | B) | C == A | B | C" |
315 "(A & B) & C == A & B & C" |
315 "(A & B) & C == A & B & C" |
333 "P = False \<Longrightarrow> (\<not> P) = True" |
333 "P = False \<Longrightarrow> (\<not> P) = True" |
334 "P = True \<Longrightarrow> (\<not> P) = False" |
334 "P = True \<Longrightarrow> (\<not> P) = False" |
335 by auto |
335 by auto |
336 |
336 |
337 lemma solved_all_splits: "False = True \<Longrightarrow> False" by simp |
337 lemma solved_all_splits: "False = True \<Longrightarrow> False" by simp |
338 ML {* |
338 ML \<open> |
339 fun solved_all_splits_tac ctxt = |
339 fun solved_all_splits_tac ctxt = |
340 TRY (eresolve_tac ctxt @{thms conjE} 1) |
340 TRY (eresolve_tac ctxt @{thms conjE} 1) |
341 THEN resolve_tac ctxt @{thms solved_all_splits} 1 |
341 THEN resolve_tac ctxt @{thms solved_all_splits} 1 |
342 THEN assume_tac ctxt 1 |
342 THEN assume_tac ctxt 1 |
343 *} |
343 \<close> |
344 |
344 |
345 lemma lots_of_logic_expansions_meta [rule_format]: |
345 lemma lots_of_logic_expansions_meta [rule_format]: |
346 "(((A :: bool) = B) = True) == (((A \<longrightarrow> B) = True) & ((B \<longrightarrow> A) = True))" |
346 "(((A :: bool) = B) = True) == (((A \<longrightarrow> B) = True) & ((B \<longrightarrow> A) = True))" |
347 "((A :: bool) = B) = False == (((~A) | B) = False) | (((~B) | A) = False)" |
347 "((A :: bool) = B) = False == (((~A) | B) = False) | (((~B) | A) = False)" |
348 |
348 |
406 lemma extuni_func [rule_format]: "(F = G) = False \<Longrightarrow> (! X. (F X = G X)) = False" by auto |
406 lemma extuni_func [rule_format]: "(F = G) = False \<Longrightarrow> (! X. (F X = G X)) = False" by auto |
407 |
407 |
408 |
408 |
409 subsection "Emulation: tactics" |
409 subsection "Emulation: tactics" |
410 |
410 |
411 ML {* |
411 ML \<open> |
412 (*Instantiate a variable according to the info given in the |
412 (*Instantiate a variable according to the info given in the |
413 proof annotation. Through this we avoid having to come up |
413 proof annotation. Through this we avoid having to come up |
414 with instantiations during reconstruction.*) |
414 with instantiations during reconstruction.*) |
415 fun bind_tac ctxt prob_name ordered_binds = |
415 fun bind_tac ctxt prob_name ordered_binds = |
416 let |
416 let |
439 THEN (REPEAT_DETERM (HEADGOAL (resolve_tac ctxt @{thms allI}))) |
439 THEN (REPEAT_DETERM (HEADGOAL (resolve_tac ctxt @{thms allI}))) |
440 THEN REPEAT_DETERM (HEADGOAL (nominal_inst_parametermatch_tac ctxt @{thm allE})) |
440 THEN REPEAT_DETERM (HEADGOAL (nominal_inst_parametermatch_tac ctxt @{thm allE})) |
441 (*now only the variable to instantiate should be left*) |
441 (*now only the variable to instantiate should be left*) |
442 THEN FIRST (map instantiate_tac ordered_instances) |
442 THEN FIRST (map instantiate_tac ordered_instances) |
443 end |
443 end |
444 *} |
444 \<close> |
445 |
445 |
446 ML {* |
446 ML \<open> |
447 (*Simplification tactics*) |
447 (*Simplification tactics*) |
448 local |
448 local |
449 fun rew_goal_tac thms ctxt i = |
449 fun rew_goal_tac thms ctxt i = |
450 rewrite_goal_tac ctxt thms i |
450 rewrite_goal_tac ctxt thms i |
451 |> CHANGED |
451 |> CHANGED |
454 rew_goal_tac (@{thms simp_meta} @ @{thms lots_of_logic_expansions_meta}) |
454 rew_goal_tac (@{thms simp_meta} @ @{thms lots_of_logic_expansions_meta}) |
455 |
455 |
456 val simper_animal = |
456 val simper_animal = |
457 rew_goal_tac @{thms simp_meta} |
457 rew_goal_tac @{thms simp_meta} |
458 end |
458 end |
459 *} |
459 \<close> |
460 |
460 |
461 lemma prop_normalise [rule_format]: |
461 lemma prop_normalise [rule_format]: |
462 "(A | B) | C == A | B | C" |
462 "(A | B) | C == A | B | C" |
463 "(A & B) & C == A & B & C" |
463 "(A & B) & C == A & B & C" |
464 "A | B == ~(~A & ~B)" |
464 "A | B == ~(~A & ~B)" |
465 "~~ A == A" |
465 "~~ A == A" |
466 by auto |
466 by auto |
467 ML {* |
467 ML \<open> |
468 (*i.e., break_conclusion*) |
468 (*i.e., break_conclusion*) |
469 fun flip_conclusion_tac ctxt = |
469 fun flip_conclusion_tac ctxt = |
470 let |
470 let |
471 val default_tac = |
471 val default_tac = |
472 (TRY o CHANGED o (rewrite_goal_tac ctxt @{thms prop_normalise})) |
472 (TRY o CHANGED o (rewrite_goal_tac ctxt @{thms prop_normalise})) |
474 THEN' (REPEAT_DETERM o eresolve_tac ctxt @{thms conjE}) |
474 THEN' (REPEAT_DETERM o eresolve_tac ctxt @{thms conjE}) |
475 THEN' (TRY o (expander_animal ctxt)) |
475 THEN' (TRY o (expander_animal ctxt)) |
476 in |
476 in |
477 default_tac ORELSE' resolve_tac ctxt @{thms flip} |
477 default_tac ORELSE' resolve_tac ctxt @{thms flip} |
478 end |
478 end |
479 *} |
479 \<close> |
480 |
480 |
481 |
481 |
482 subsection "Skolemisation" |
482 subsection "Skolemisation" |
483 |
483 |
484 lemma skolemise [rule_format]: |
484 lemma skolemise [rule_format]: |
539 "\<lbrakk>(Ex P) = True; sk = (SOME x. P x)\<rbrakk> \<Longrightarrow> P sk = True" |
539 "\<lbrakk>(Ex P) = True; sk = (SOME x. P x)\<rbrakk> \<Longrightarrow> P sk = True" |
540 apply (drule polar_skolemise, simp) |
540 apply (drule polar_skolemise, simp) |
541 apply (simp, drule someI_ex, simp) |
541 apply (simp, drule someI_ex, simp) |
542 done |
542 done |
543 |
543 |
544 ML {* |
544 ML \<open> |
545 (*FIXME LHS should be constant. Currently allow variables for testing. Probably should still allow Vars (but not Frees) since they'll act as intermediate values*) |
545 (*FIXME LHS should be constant. Currently allow variables for testing. Probably should still allow Vars (but not Frees) since they'll act as intermediate values*) |
546 fun conc_is_skolem_def t = |
546 fun conc_is_skolem_def t = |
547 case t of |
547 case t of |
548 Const (@{const_name HOL.eq}, _) $ t' $ (Const (@{const_name Hilbert_Choice.Eps}, _) $ _) => |
548 Const (@{const_name HOL.eq}, _) $ t' $ (Const (@{const_name Hilbert_Choice.Eps}, _) $ _) => |
549 let |
549 let |
572 b andalso is_Free t) args true |
572 b andalso is_Free t) args true |
573 in |
573 in |
574 h_property andalso args_property |
574 h_property andalso args_property |
575 end |
575 end |
576 | _ => false |
576 | _ => false |
577 *} |
577 \<close> |
578 |
578 |
579 ML {* |
579 ML \<open> |
580 (*Hack used to detect if a Skolem definition, with an LHS Var, has had the LHS instantiated into an unacceptable term.*) |
580 (*Hack used to detect if a Skolem definition, with an LHS Var, has had the LHS instantiated into an unacceptable term.*) |
581 fun conc_is_bad_skolem_def t = |
581 fun conc_is_bad_skolem_def t = |
582 case t of |
582 case t of |
583 Const (@{const_name HOL.eq}, _) $ t' $ (Const (@{const_name Hilbert_Choice.Eps}, _) $ _) => |
583 Const (@{const_name HOL.eq}, _) $ t' $ (Const (@{const_name Hilbert_Choice.Eps}, _) $ _) => |
584 let |
584 let |
631 head_of t' |
631 head_of t' |
632 |> strip_abs_body |
632 |> strip_abs_body |
633 |> head_of |
633 |> head_of |
634 |> dest_Const) |
634 |> dest_Const) |
635 (get_skolem_conc t) |
635 (get_skolem_conc t) |
636 *} |
636 \<close> |
637 |
637 |
638 (* |
638 (* |
639 Technique for handling quantifiers: |
639 Technique for handling quantifiers: |
640 Principles: |
640 Principles: |
641 * allE should always match with a !! |
641 * allE should always match with a !! |
642 * exE should match with a constant, |
642 * exE should match with a constant, |
643 or bind a fresh !! -- currently not doing the latter since it never seems to arised in normal Leo2 proofs. |
643 or bind a fresh !! -- currently not doing the latter since it never seems to arised in normal Leo2 proofs. |
644 *) |
644 *) |
645 |
645 |
646 ML {* |
646 ML \<open> |
647 fun forall_neg_tac candidate_consts ctxt i = fn st => |
647 fun forall_neg_tac candidate_consts ctxt i = fn st => |
648 let |
648 let |
649 val gls = |
649 val gls = |
650 Thm.prop_of st |
650 Thm.prop_of st |
651 |> Logic.strip_horn |
651 |> Logic.strip_horn |
676 val attempts = map instantiate candidate_consts |
676 val attempts = map instantiate candidate_consts |
677 in |
677 in |
678 (fold (curry (op APPEND')) attempts (K no_tac)) i st |
678 (fold (curry (op APPEND')) attempts (K no_tac)) i st |
679 end |
679 end |
680 end |
680 end |
681 *} |
681 \<close> |
682 |
682 |
683 ML {* |
683 ML \<open> |
684 exception SKOLEM_DEF of term (*The tactic wasn't pointed at a skolem definition*) |
684 exception SKOLEM_DEF of term (*The tactic wasn't pointed at a skolem definition*) |
685 exception NO_SKOLEM_DEF of (*skolem const name*)string * Binding.binding * term (*The tactic could not find a skolem definition in the theory*) |
685 exception NO_SKOLEM_DEF of (*skolem const name*)string * Binding.binding * term (*The tactic could not find a skolem definition in the theory*) |
686 fun absorb_skolem_def ctxt prob_name_opt i = fn st => |
686 fun absorb_skolem_def ctxt prob_name_opt i = fn st => |
687 let |
687 let |
688 val thy = Proof_Context.theory_of ctxt |
688 val thy = Proof_Context.theory_of ctxt |
748 raise (NO_SKOLEM_DEF (def_name, bnd_name, conclusion))) |
748 raise (NO_SKOLEM_DEF (def_name, bnd_name, conclusion))) |
749 in |
749 in |
750 resolve_tac ctxt [Drule.export_without_context thm] i st |
750 resolve_tac ctxt [Drule.export_without_context thm] i st |
751 end |
751 end |
752 handle SKOLEM_DEF _ => no_tac st |
752 handle SKOLEM_DEF _ => no_tac st |
753 *} |
753 \<close> |
754 |
754 |
755 ML {* |
755 ML \<open> |
756 (* |
756 (* |
757 In current system, there should only be 2 subgoals: the one where |
757 In current system, there should only be 2 subgoals: the one where |
758 the skolem definition is being built (with a Var in the LHS), and the other subgoal using Var. |
758 the skolem definition is being built (with a Var in the LHS), and the other subgoal using Var. |
759 *) |
759 *) |
760 (*arity must be greater than 0. if arity=0 then |
760 (*arity must be greater than 0. if arity=0 then |
951 fold (curry (op APPEND)) |
951 fold (curry (op APPEND)) |
952 (map (instantiate_tac (dest_Var (Thm.term_of (the var_opt)))) skolem_cts) no_tac |
952 (map (instantiate_tac (dest_Var (Thm.term_of (the var_opt)))) skolem_cts) no_tac |
953 in |
953 in |
954 tactic st |
954 tactic st |
955 end |
955 end |
956 *} |
956 \<close> |
957 |
957 |
958 ML {* |
958 ML \<open> |
959 fun new_skolem_tac ctxt consts_candidates = |
959 fun new_skolem_tac ctxt consts_candidates = |
960 let |
960 let |
961 fun tac thm = |
961 fun tac thm = |
962 dresolve_tac ctxt [thm] |
962 dresolve_tac ctxt [thm] |
963 THEN' instantiate_skols ctxt consts_candidates |
963 THEN' instantiate_skols ctxt consts_candidates |
964 in |
964 in |
965 if null consts_candidates then K no_tac |
965 if null consts_candidates then K no_tac |
966 else FIRST' (map tac @{thms lift_exists}) |
966 else FIRST' (map tac @{thms lift_exists}) |
967 end |
967 end |
968 *} |
968 \<close> |
969 |
969 |
970 (* |
970 (* |
971 need a tactic to expand "? x . P" to "~ ! x. ~ P" |
971 need a tactic to expand "? x . P" to "~ ! x. ~ P" |
972 *) |
972 *) |
973 ML {* |
973 ML \<open> |
974 fun ex_expander_tac ctxt i = |
974 fun ex_expander_tac ctxt i = |
975 let |
975 let |
976 val simpset = |
976 val simpset = |
977 empty_simpset ctxt (*NOTE for some reason, Bind exception gets raised if ctxt's simpset isn't emptied*) |
977 empty_simpset ctxt (*NOTE for some reason, Bind exception gets raised if ctxt's simpset isn't emptied*) |
978 |> Simplifier.add_simp @{lemma "Ex P == (~ (! x. ~ P x))" by auto} |
978 |> Simplifier.add_simp @{lemma "Ex P == (~ (! x. ~ P x))" by auto} |
979 in |
979 in |
980 CHANGED (asm_full_simp_tac simpset i) |
980 CHANGED (asm_full_simp_tac simpset i) |
981 end |
981 end |
982 *} |
982 \<close> |
983 |
983 |
984 |
984 |
985 subsubsection "extuni_dec" |
985 subsubsection "extuni_dec" |
986 |
986 |
987 ML {* |
987 ML \<open> |
988 (*n-ary decomposition. Code is based on the n-ary arg_cong generator*) |
988 (*n-ary decomposition. Code is based on the n-ary arg_cong generator*) |
989 fun extuni_dec_n ctxt arity = |
989 fun extuni_dec_n ctxt arity = |
990 let |
990 let |
991 val _ = @{assert} (arity > 0) |
991 val _ = @{assert} (arity > 0) |
992 val is = |
992 val is = |
1033 Logic.mk_implies (hyp, HOLogic.mk_Trueprop conc) |
1033 Logic.mk_implies (hyp, HOLogic.mk_Trueprop conc) |
1034 in |
1034 in |
1035 Goal.prove ctxt [] [] t (fn _ => auto_tac ctxt) |
1035 Goal.prove ctxt [] [] t (fn _ => auto_tac ctxt) |
1036 |> Drule.export_without_context |
1036 |> Drule.export_without_context |
1037 end |
1037 end |
1038 *} |
1038 \<close> |
1039 |
1039 |
1040 ML {* |
1040 ML \<open> |
1041 (*Determine the arity of a function which the "dec" |
1041 (*Determine the arity of a function which the "dec" |
1042 unification rule is about to be applied. |
1042 unification rule is about to be applied. |
1043 NOTE: |
1043 NOTE: |
1044 * Assumes that there is a single hypothesis |
1044 * Assumes that there is a single hypothesis |
1045 *) |
1045 *) |
1155 dresolve_tac ctxt @{thms dec_commut_disj}, |
1155 dresolve_tac ctxt @{thms dec_commut_disj}, |
1156 elim_tac])) |
1156 elim_tac])) |
1157 in |
1157 in |
1158 (CHANGED o search_tac) i st |
1158 (CHANGED o search_tac) i st |
1159 end |
1159 end |
1160 *} |
1160 \<close> |
1161 |
1161 |
1162 |
1162 |
1163 subsubsection "standard_cnf" |
1163 subsubsection "standard_cnf" |
1164 (*Given a standard_cnf inference, normalise it |
1164 (*Given a standard_cnf inference, normalise it |
1165 e.g. ((A & B) & C \<longrightarrow> D & E \<longrightarrow> F \<longrightarrow> G) = False |
1165 e.g. ((A & B) & C \<longrightarrow> D & E \<longrightarrow> F \<longrightarrow> G) = False |
1176 e.g., "(A \<longrightarrow> B) = True \<Longrightarrow> A = False | (A = True & B = True)" |
1176 e.g., "(A \<longrightarrow> B) = True \<Longrightarrow> A = False | (A = True & B = True)" |
1177 since "standard_cnf" seems to be applied at the preprocessing |
1177 since "standard_cnf" seems to be applied at the preprocessing |
1178 stage, together with splitting. |
1178 stage, together with splitting. |
1179 *) |
1179 *) |
1180 |
1180 |
1181 ML {* |
1181 ML \<open> |
1182 (*Conjunctive counterparts to Term.disjuncts_aux and Term.disjuncts*) |
1182 (*Conjunctive counterparts to Term.disjuncts_aux and Term.disjuncts*) |
1183 fun conjuncts_aux (Const (@{const_name HOL.conj}, _) $ t $ t') conjs = |
1183 fun conjuncts_aux (Const (@{const_name HOL.conj}, _) $ t $ t') conjs = |
1184 conjuncts_aux t (conjuncts_aux t' conjs) |
1184 conjuncts_aux t (conjuncts_aux t' conjs) |
1185 | conjuncts_aux t conjs = t :: conjs |
1185 | conjuncts_aux t conjs = t :: conjs |
1186 |
1186 |
1194 in |
1194 in |
1195 fun imp_strip_horn t = |
1195 fun imp_strip_horn t = |
1196 imp_strip_horn' [] t |
1196 imp_strip_horn' [] t |
1197 |> apfst rev |
1197 |> apfst rev |
1198 end |
1198 end |
1199 *} |
1199 \<close> |
1200 |
1200 |
1201 ML {* |
1201 ML \<open> |
1202 (*Returns whether the antecedents are separated by conjunctions |
1202 (*Returns whether the antecedents are separated by conjunctions |
1203 or implications; the number of antecedents; and the polarity |
1203 or implications; the number of antecedents; and the polarity |
1204 of the original clause -- I think this will always be "false".*) |
1204 of the original clause -- I think this will always be "false".*) |
1205 fun standard_cnf_type ctxt i : thm -> (TPTP_Reconstruct.formula_kind * int * bool) option = fn st => |
1205 fun standard_cnf_type ctxt i : thm -> (TPTP_Reconstruct.formula_kind * int * bool) option = fn st => |
1206 let |
1206 let |
1252 antes) |
1252 antes) |
1253 in |
1253 in |
1254 if null antes then NONE |
1254 if null antes then NONE |
1255 else SOME (ante_type, length antes', pol) |
1255 else SOME (ante_type, length antes', pol) |
1256 end |
1256 end |
1257 *} |
1257 \<close> |
1258 |
1258 |
1259 ML {* |
1259 ML \<open> |
1260 (*Given a certain standard_cnf type, build a metatheorem that would |
1260 (*Given a certain standard_cnf type, build a metatheorem that would |
1261 validate it*) |
1261 validate it*) |
1262 fun mk_standard_cnf ctxt kind arity = |
1262 fun mk_standard_cnf ctxt kind arity = |
1263 let |
1263 let |
1264 val _ = @{assert} (arity > 0) |
1264 val _ = @{assert} (arity > 0) |
1292 Logic.mk_implies (HOLogic.mk_Trueprop hyp, HOLogic.mk_Trueprop conc) |
1292 Logic.mk_implies (HOLogic.mk_Trueprop hyp, HOLogic.mk_Trueprop conc) |
1293 in |
1293 in |
1294 Goal.prove ctxt [] [] t (fn _ => HEADGOAL (blast_tac ctxt)) |
1294 Goal.prove ctxt [] [] t (fn _ => HEADGOAL (blast_tac ctxt)) |
1295 |> Drule.export_without_context |
1295 |> Drule.export_without_context |
1296 end |
1296 end |
1297 *} |
1297 \<close> |
1298 |
1298 |
1299 ML {* |
1299 ML \<open> |
1300 (*Applies a d-tactic, then breaks it up conjunctively. |
1300 (*Applies a d-tactic, then breaks it up conjunctively. |
1301 This can be used to transform subgoals as follows: |
1301 This can be used to transform subgoals as follows: |
1302 (A \<longrightarrow> B) = False \<Longrightarrow> R |
1302 (A \<longrightarrow> B) = False \<Longrightarrow> R |
1303 | |
1303 | |
1304 v |
1304 v |
1305 \<lbrakk>A = True; B = False\<rbrakk> \<Longrightarrow> R |
1305 \<lbrakk>A = True; B = False\<rbrakk> \<Longrightarrow> R |
1306 *) |
1306 *) |
1307 fun weak_conj_tac ctxt drule = |
1307 fun weak_conj_tac ctxt drule = |
1308 dresolve_tac ctxt [drule] THEN' |
1308 dresolve_tac ctxt [drule] THEN' |
1309 (REPEAT_DETERM o eresolve_tac ctxt @{thms conjE}) |
1309 (REPEAT_DETERM o eresolve_tac ctxt @{thms conjE}) |
1310 *} |
1310 \<close> |
1311 |
1311 |
1312 ML {* |
1312 ML \<open> |
1313 fun uncurry_lit_neg_tac ctxt = |
1313 fun uncurry_lit_neg_tac ctxt = |
1314 REPEAT_DETERM o |
1314 REPEAT_DETERM o |
1315 dresolve_tac ctxt [@{lemma "(A \<longrightarrow> B \<longrightarrow> C) = False \<Longrightarrow> (A & B \<longrightarrow> C) = False" by auto}] |
1315 dresolve_tac ctxt [@{lemma "(A \<longrightarrow> B \<longrightarrow> C) = False \<Longrightarrow> (A & B \<longrightarrow> C) = False" by auto}] |
1316 *} |
1316 \<close> |
1317 |
1317 |
1318 ML {* |
1318 ML \<open> |
1319 fun standard_cnf_tac ctxt i = fn st => |
1319 fun standard_cnf_tac ctxt i = fn st => |
1320 let |
1320 let |
1321 fun core_tactic i = fn st => |
1321 fun core_tactic i = fn st => |
1322 case standard_cnf_type ctxt i st of |
1322 case standard_cnf_type ctxt i st of |
1323 NONE => no_tac st |
1323 NONE => no_tac st |
1330 in |
1330 in |
1331 (uncurry_lit_neg_tac ctxt |
1331 (uncurry_lit_neg_tac ctxt |
1332 THEN' TPTP_Reconstruct_Library.reassociate_conjs_tac ctxt |
1332 THEN' TPTP_Reconstruct_Library.reassociate_conjs_tac ctxt |
1333 THEN' core_tactic) i st |
1333 THEN' core_tactic) i st |
1334 end |
1334 end |
1335 *} |
1335 \<close> |
1336 |
1336 |
1337 |
1337 |
1338 subsubsection "Emulator prep" |
1338 subsubsection "Emulator prep" |
1339 |
1339 |
1340 ML {* |
1340 ML \<open> |
1341 datatype cleanup_feature = |
1341 datatype cleanup_feature = |
1342 RemoveHypothesesFromSkolemDefs |
1342 RemoveHypothesesFromSkolemDefs |
1343 | RemoveDuplicates |
1343 | RemoveDuplicates |
1344 |
1344 |
1345 datatype loop_feature = |
1345 datatype loop_feature = |
1378 | Loop of loop_feature list |
1378 | Loop of loop_feature list |
1379 | LoopOnce of loop_feature list |
1379 | LoopOnce of loop_feature list |
1380 | InnerLoopOnce of loop_feature list |
1380 | InnerLoopOnce of loop_feature list |
1381 | CleanUp of cleanup_feature list |
1381 | CleanUp of cleanup_feature list |
1382 | AbsorbSkolemDefs |
1382 | AbsorbSkolemDefs |
1383 *} |
1383 \<close> |
1384 |
1384 |
1385 ML {* |
1385 ML \<open> |
1386 fun can_feature x l = |
1386 fun can_feature x l = |
1387 let |
1387 let |
1388 fun sublist_of_clean_up el = |
1388 fun sublist_of_clean_up el = |
1389 case el of |
1389 case el of |
1390 CleanUp l'' => SOME l'' |
1390 CleanUp l'' => SOME l'' |
1440 @{assert} |
1440 @{assert} |
1441 (can_feature (Loop []) [Loop [Existential_Var]]); |
1441 (can_feature (Loop []) [Loop [Existential_Var]]); |
1442 |
1442 |
1443 @{assert} |
1443 @{assert} |
1444 (not (can_feature (Loop []) [InnerLoopOnce [Existential_Var]])); |
1444 (not (can_feature (Loop []) [InnerLoopOnce [Existential_Var]])); |
1445 *} |
1445 \<close> |
1446 |
1446 |
1447 ML {* |
1447 ML \<open> |
1448 exception NO_LOOP_FEATS |
1448 exception NO_LOOP_FEATS |
1449 fun get_loop_feats (feats : feature list) = |
1449 fun get_loop_feats (feats : feature list) = |
1450 let |
1450 let |
1451 val loop_find = |
1451 val loop_find = |
1452 fold (fn x => fn loop_feats_acc => |
1452 fold (fn x => fn loop_feats_acc => |
1465 end; |
1465 end; |
1466 |
1466 |
1467 @{assert} |
1467 @{assert} |
1468 (get_loop_feats [Loop [King_Cong, Break_Hypotheses, Existential_Free, Existential_Var, Universal]] = |
1468 (get_loop_feats [Loop [King_Cong, Break_Hypotheses, Existential_Free, Existential_Var, Universal]] = |
1469 [King_Cong, Break_Hypotheses, Existential_Free, Existential_Var, Universal]) |
1469 [King_Cong, Break_Hypotheses, Existential_Free, Existential_Var, Universal]) |
1470 *} |
1470 \<close> |
1471 |
1471 |
1472 (*use as elim rule to remove premises*) |
1472 (*use as elim rule to remove premises*) |
1473 lemma insa_prems: "\<lbrakk>Q; P\<rbrakk> \<Longrightarrow> P" by auto |
1473 lemma insa_prems: "\<lbrakk>Q; P\<rbrakk> \<Longrightarrow> P" by auto |
1474 ML {* |
1474 ML \<open> |
1475 fun cleanup_skolem_defs ctxt feats = |
1475 fun cleanup_skolem_defs ctxt feats = |
1476 let |
1476 let |
1477 (*remove hypotheses from skolem defs, |
1477 (*remove hypotheses from skolem defs, |
1478 after testing that they look like skolem defs*) |
1478 after testing that they look like skolem defs*) |
1479 val dehypothesise_skolem_defs = |
1479 val dehypothesise_skolem_defs = |
1483 in |
1483 in |
1484 if can_feature (CleanUp [RemoveHypothesesFromSkolemDefs]) feats then |
1484 if can_feature (CleanUp [RemoveHypothesesFromSkolemDefs]) feats then |
1485 ALLGOALS (TRY o dehypothesise_skolem_defs) |
1485 ALLGOALS (TRY o dehypothesise_skolem_defs) |
1486 else all_tac |
1486 else all_tac |
1487 end |
1487 end |
1488 *} |
1488 \<close> |
1489 |
1489 |
1490 ML {* |
1490 ML \<open> |
1491 fun remove_duplicates_tac feats = |
1491 fun remove_duplicates_tac feats = |
1492 (if can_feature (CleanUp [RemoveDuplicates]) feats then |
1492 (if can_feature (CleanUp [RemoveDuplicates]) feats then |
1493 ALLGOALS distinct_subgoal_tac |
1493 ALLGOALS distinct_subgoal_tac |
1494 else all_tac) |
1494 else all_tac) |
1495 *} |
1495 \<close> |
1496 |
1496 |
1497 ML {* |
1497 ML \<open> |
1498 (*given a goal state, indicates the skolem constants committed-to in it (i.e. appearing in LHS of a skolem definition)*) |
1498 (*given a goal state, indicates the skolem constants committed-to in it (i.e. appearing in LHS of a skolem definition)*) |
1499 fun which_skolem_concs_used ctxt = fn st => |
1499 fun which_skolem_concs_used ctxt = fn st => |
1500 let |
1500 let |
1501 val feats = [CleanUp [RemoveHypothesesFromSkolemDefs, RemoveDuplicates]] |
1501 val feats = [CleanUp [RemoveHypothesesFromSkolemDefs, RemoveDuplicates]] |
1502 val scrubup_tac = |
1502 val scrubup_tac = |
1510 |> TERMFUN (snd (*discard hypotheses*) |
1510 |> TERMFUN (snd (*discard hypotheses*) |
1511 #> get_skolem_conc_const) NONE |
1511 #> get_skolem_conc_const) NONE |
1512 |> switch (fold (fn x => fn l => if is_some x then the x :: l else l)) [] |
1512 |> switch (fold (fn x => fn l => if is_some x then the x :: l else l)) [] |
1513 |> map Const |
1513 |> map Const |
1514 end |
1514 end |
1515 *} |
1515 \<close> |
1516 |
1516 |
1517 ML {* |
1517 ML \<open> |
1518 fun exists_tac ctxt feats consts_diff = |
1518 fun exists_tac ctxt feats consts_diff = |
1519 let |
1519 let |
1520 val ex_var = |
1520 val ex_var = |
1521 if loop_can_feature [Existential_Var] feats andalso consts_diff <> [] then |
1521 if loop_can_feature [Existential_Var] feats andalso consts_diff <> [] then |
1522 new_skolem_tac ctxt consts_diff |
1522 new_skolem_tac ctxt consts_diff |
1533 |
1533 |
1534 fun forall_tac ctxt feats = |
1534 fun forall_tac ctxt feats = |
1535 if loop_can_feature [Universal] feats then |
1535 if loop_can_feature [Universal] feats then |
1536 forall_pos_tac ctxt |
1536 forall_pos_tac ctxt |
1537 else K no_tac |
1537 else K no_tac |
1538 *} |
1538 \<close> |
1539 |
1539 |
1540 |
1540 |
1541 subsubsection "Finite types" |
1541 subsubsection "Finite types" |
1542 (*lift quantification from a singleton literal to a singleton clause*) |
1542 (*lift quantification from a singleton literal to a singleton clause*) |
1543 lemma forall_pos_lift: |
1543 lemma forall_pos_lift: |
1544 "\<lbrakk>(! X. P X) = True; ! X. (P X = True) \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" by auto |
1544 "\<lbrakk>(! X. P X) = True; ! X. (P X = True) \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" by auto |
1545 |
1545 |
1546 (*predicate over the type of the leading quantified variable*) |
1546 (*predicate over the type of the leading quantified variable*) |
1547 |
1547 |
1548 ML {* |
1548 ML \<open> |
1549 fun extcnf_forall_special_pos_tac ctxt = |
1549 fun extcnf_forall_special_pos_tac ctxt = |
1550 let |
1550 let |
1551 val bool = |
1551 val bool = |
1552 ["True", "False"] |
1552 ["True", "False"] |
1553 |
1553 |
1563 THEN' (assume_tac ctxt |
1563 THEN' (assume_tac ctxt |
1564 ORELSE' FIRST' |
1564 ORELSE' FIRST' |
1565 (*FIXME could check the type of the leading quantified variable, instead of trying everything*) |
1565 (*FIXME could check the type of the leading quantified variable, instead of trying everything*) |
1566 (tacs (bool @ bool_to_bool))) |
1566 (tacs (bool @ bool_to_bool))) |
1567 end |
1567 end |
1568 *} |
1568 \<close> |
1569 |
1569 |
1570 |
1570 |
1571 subsubsection "Emulator" |
1571 subsubsection "Emulator" |
1572 |
1572 |
1573 lemma efq: "[|A = True; A = False|] ==> R" by auto |
1573 lemma efq: "[|A = True; A = False|] ==> R" by auto |
1574 ML {* |
1574 ML \<open> |
1575 fun efq_tac ctxt = |
1575 fun efq_tac ctxt = |
1576 (eresolve_tac ctxt @{thms efq} THEN' assume_tac ctxt) |
1576 (eresolve_tac ctxt @{thms efq} THEN' assume_tac ctxt) |
1577 ORELSE' assume_tac ctxt |
1577 ORELSE' assume_tac ctxt |
1578 *} |
1578 \<close> |
1579 |
1579 |
1580 ML {* |
1580 ML \<open> |
1581 (*This is applied to all subgoals, repeatedly*) |
1581 (*This is applied to all subgoals, repeatedly*) |
1582 fun extcnf_combined_main ctxt feats consts_diff = |
1582 fun extcnf_combined_main ctxt feats consts_diff = |
1583 let |
1583 let |
1584 (*This is applied to subgoals which don't have a conclusion |
1584 (*This is applied to subgoals which don't have a conclusion |
1585 consisting of a Skolem definition*) |
1585 consisting of a Skolem definition*) |
1738 Rule_Insts.eres_inst_tac ctxt [((("x", 0), Position.none), "(@X. False)")] [] |
1738 Rule_Insts.eres_inst_tac ctxt [((("x", 0), Position.none), "(@X. False)")] [] |
1739 @{thm allE} i st |
1739 @{thm allE} i st |
1740 end |
1740 end |
1741 end |
1741 end |
1742 end |
1742 end |
1743 *} |
1743 \<close> |
1744 |
1744 |
1745 ML {* |
1745 ML \<open> |
1746 fun remove_redundant_quantification_ignore_skolems ctxt i = |
1746 fun remove_redundant_quantification_ignore_skolems ctxt i = |
1747 COND (TERMPRED (fn _ => true) conc_is_skolem_def (SOME i)) |
1747 COND (TERMPRED (fn _ => true) conc_is_skolem_def (SOME i)) |
1748 no_tac |
1748 no_tac |
1749 (remove_redundant_quantification ctxt i) |
1749 (remove_redundant_quantification ctxt i) |
1750 *} |
1750 \<close> |
1751 |
1751 |
1752 lemma drop_redundant_literal_qtfr: |
1752 lemma drop_redundant_literal_qtfr: |
1753 "(! X. P) = True \<Longrightarrow> P = True" |
1753 "(! X. P) = True \<Longrightarrow> P = True" |
1754 "(? X. P) = True \<Longrightarrow> P = True" |
1754 "(? X. P) = True \<Longrightarrow> P = True" |
1755 "(! X. P) = False \<Longrightarrow> P = False" |
1755 "(! X. P) = False \<Longrightarrow> P = False" |
1756 "(? X. P) = False \<Longrightarrow> P = False" |
1756 "(? X. P) = False \<Longrightarrow> P = False" |
1757 by auto |
1757 by auto |
1758 |
1758 |
1759 ML {* |
1759 ML \<open> |
1760 (*remove quantification in the literal "(! X. t) = True/False" |
1760 (*remove quantification in the literal "(! X. t) = True/False" |
1761 in the singleton hypothesis clause, if X not free in t*) |
1761 in the singleton hypothesis clause, if X not free in t*) |
1762 fun remove_redundant_quantification_in_lit ctxt i = fn st => |
1762 fun remove_redundant_quantification_in_lit ctxt i = fn st => |
1763 let |
1763 let |
1764 val gls = |
1764 val gls = |
1806 dresolve_tac ctxt @{thms drop_redundant_literal_qtfr} i st |
1806 dresolve_tac ctxt @{thms drop_redundant_literal_qtfr} i st |
1807 end |
1807 end |
1808 end |
1808 end |
1809 end |
1809 end |
1810 end |
1810 end |
1811 *} |
1811 \<close> |
1812 |
1812 |
1813 ML {* |
1813 ML \<open> |
1814 fun remove_redundant_quantification_in_lit_ignore_skolems ctxt i = |
1814 fun remove_redundant_quantification_in_lit_ignore_skolems ctxt i = |
1815 COND (TERMPRED (fn _ => true) conc_is_skolem_def (SOME i)) |
1815 COND (TERMPRED (fn _ => true) conc_is_skolem_def (SOME i)) |
1816 no_tac |
1816 no_tac |
1817 (remove_redundant_quantification_in_lit ctxt i) |
1817 (remove_redundant_quantification_in_lit ctxt i) |
1818 *} |
1818 \<close> |
1819 |
1819 |
1820 ML {* |
1820 ML \<open> |
1821 fun extcnf_combined_tac ctxt prob_name_opt feats skolem_consts = fn st => |
1821 fun extcnf_combined_tac ctxt prob_name_opt feats skolem_consts = fn st => |
1822 let |
1822 let |
1823 val thy = Proof_Context.theory_of ctxt |
1823 val thy = Proof_Context.theory_of ctxt |
1824 |
1824 |
1825 (*Initially, st consists of a single goal, showing the |
1825 (*Initially, st consists of a single goal, showing the |
1887 THEN IF_UNSOLVED cleanup |
1887 THEN IF_UNSOLVED cleanup |
1888 |
1888 |
1889 in |
1889 in |
1890 DEPTH_SOLVE (CHANGED tec) st |
1890 DEPTH_SOLVE (CHANGED tec) st |
1891 end |
1891 end |
1892 *} |
1892 \<close> |
1893 |
1893 |
1894 |
1894 |
1895 subsubsection "unfold_def" |
1895 subsubsection "unfold_def" |
1896 |
1896 |
1897 (*this is used when handling unfold_tac, because the skeleton includes the definitions conjoined with the goal. it turns out that, for my tactic, the definitions are harmful. instead of modifying the skeleton (which may be nontrivial) i'm just dropping the information using this lemma. obviously, and from the name, order matters here.*) |
1897 (*this is used when handling unfold_tac, because the skeleton includes the definitions conjoined with the goal. it turns out that, for my tactic, the definitions are harmful. instead of modifying the skeleton (which may be nontrivial) i'm just dropping the information using this lemma. obviously, and from the name, order matters here.*) |
1902 or reflexive, or else turned back into an object equation |
1902 or reflexive, or else turned back into an object equation |
1903 and broken down further.*) |
1903 and broken down further.*) |
1904 lemma un_meta_polarise: "(X \<equiv> True) \<Longrightarrow> X" by auto |
1904 lemma un_meta_polarise: "(X \<equiv> True) \<Longrightarrow> X" by auto |
1905 lemma meta_polarise: "X \<Longrightarrow> X \<equiv> True" by auto |
1905 lemma meta_polarise: "X \<Longrightarrow> X \<equiv> True" by auto |
1906 |
1906 |
1907 ML {* |
1907 ML \<open> |
1908 fun unfold_def_tac ctxt depends_on_defs = fn st => |
1908 fun unfold_def_tac ctxt depends_on_defs = fn st => |
1909 let |
1909 let |
1910 (*This is used when we end up with something like |
1910 (*This is used when we end up with something like |
1911 (A & B) \<equiv> True \<Longrightarrow> (B & A) \<equiv> True. |
1911 (A & B) \<equiv> True \<Longrightarrow> (B & A) \<equiv> True. |
1912 It breaks down this subgoal until it can be trivially |
1912 It breaks down this subgoal until it can be trivially |
1958 "(A & B) & C \<equiv> A & B & C" |
1958 "(A & B) & C \<equiv> A & B & C" |
1959 "A = B \<equiv> (A --> B) & (B --> A)" |
1959 "A = B \<equiv> (A --> B) & (B --> A)" |
1960 by (rule eq_reflection, auto)+ |
1960 by (rule eq_reflection, auto)+ |
1961 |
1961 |
1962 (*Same idiom as ex_expander_tac*) |
1962 (*Same idiom as ex_expander_tac*) |
1963 ML {* |
1963 ML \<open> |
1964 fun split_simp_tac (ctxt : Proof.context) i = |
1964 fun split_simp_tac (ctxt : Proof.context) i = |
1965 let |
1965 let |
1966 val simpset = |
1966 val simpset = |
1967 fold Simplifier.add_simp @{thms split_tranfs} (empty_simpset ctxt) |
1967 fold Simplifier.add_simp @{thms split_tranfs} (empty_simpset ctxt) |
1968 in |
1968 in |
1969 CHANGED (asm_full_simp_tac simpset i) |
1969 CHANGED (asm_full_simp_tac simpset i) |
1970 end |
1970 end |
1971 *} |
1971 \<close> |
1972 |
1972 |
1973 |
1973 |
1974 subsection "Alternative reconstruction tactics" |
1974 subsection "Alternative reconstruction tactics" |
1975 ML {* |
1975 ML \<open> |
1976 (*An "auto"-based proof reconstruction, where we attempt to reconstruct each inference |
1976 (*An "auto"-based proof reconstruction, where we attempt to reconstruct each inference |
1977 using auto_tac. A realistic tactic would inspect the inference name and act |
1977 using auto_tac. A realistic tactic would inspect the inference name and act |
1978 accordingly.*) |
1978 accordingly.*) |
1979 fun auto_based_reconstruction_tac ctxt prob_name n = |
1979 fun auto_based_reconstruction_tac ctxt prob_name n = |
1980 let |
1980 let |
1987 |> the |
1987 |> the |
1988 |> (fn {inference_fmla, ...} => |
1988 |> (fn {inference_fmla, ...} => |
1989 Goal.prove ctxt [] [] inference_fmla |
1989 Goal.prove ctxt [] [] inference_fmla |
1990 (fn pdata => auto_tac (#context pdata))) |
1990 (fn pdata => auto_tac (#context pdata))) |
1991 end |
1991 end |
1992 *} |
1992 \<close> |
1993 |
1993 |
1994 (*An oracle-based reconstruction, which is only used to test the shunting part of the system*) |
1994 (*An oracle-based reconstruction, which is only used to test the shunting part of the system*) |
1995 oracle oracle_iinterp = "fn t => t" |
1995 oracle oracle_iinterp = "fn t => t" |
1996 ML {* |
1996 ML \<open> |
1997 fun oracle_based_reconstruction_tac ctxt prob_name n = |
1997 fun oracle_based_reconstruction_tac ctxt prob_name n = |
1998 let |
1998 let |
1999 val thy = Proof_Context.theory_of ctxt |
1999 val thy = Proof_Context.theory_of ctxt |
2000 val pannot = TPTP_Reconstruct.get_pannot_of_prob thy prob_name |
2000 val pannot = TPTP_Reconstruct.get_pannot_of_prob thy prob_name |
2001 in |
2001 in |
2004 prob_name (#meta pannot) n |
2004 prob_name (#meta pannot) n |
2005 |> the |
2005 |> the |
2006 |> (fn {inference_fmla, ...} => Thm.cterm_of ctxt inference_fmla) |
2006 |> (fn {inference_fmla, ...} => Thm.cterm_of ctxt inference_fmla) |
2007 |> oracle_iinterp |
2007 |> oracle_iinterp |
2008 end |
2008 end |
2009 *} |
2009 \<close> |
2010 |
2010 |
2011 |
2011 |
2012 subsection "Leo2 reconstruction tactic" |
2012 subsection "Leo2 reconstruction tactic" |
2013 |
2013 |
2014 ML {* |
2014 ML \<open> |
2015 exception UNSUPPORTED_ROLE |
2015 exception UNSUPPORTED_ROLE |
2016 exception INTERPRET_INFERENCE |
2016 exception INTERPRET_INFERENCE |
2017 |
2017 |
2018 (*Failure reports can be adjusted to avoid interrupting |
2018 (*Failure reports can be adjusted to avoid interrupting |
2019 an overall reconstruction process*) |
2019 an overall reconstruction process*) |
2169 | "res" => default_tac |
2169 | "res" => default_tac |
2170 | "rename" => default_tac |
2170 | "rename" => default_tac |
2171 | "flexflex" => default_tac |
2171 | "flexflex" => default_tac |
2172 | other => fail ctxt ("Unknown inference rule: " ^ other) |
2172 | other => fail ctxt ("Unknown inference rule: " ^ other) |
2173 end |
2173 end |
2174 *} |
2174 \<close> |
2175 |
2175 |
2176 ML {* |
2176 ML \<open> |
2177 fun interpret_leo2_inference ctxt prob_name node = |
2177 fun interpret_leo2_inference ctxt prob_name node = |
2178 let |
2178 let |
2179 val thy = Proof_Context.theory_of ctxt |
2179 val thy = Proof_Context.theory_of ctxt |
2180 val pannot = TPTP_Reconstruct.get_pannot_of_prob thy prob_name |
2180 val pannot = TPTP_Reconstruct.get_pannot_of_prob thy prob_name |
2181 |
2181 |
2202 [Pretty.str ("Failed inference reconstruction for '" ^ |
2202 [Pretty.str ("Failed inference reconstruction for '" ^ |
2203 inference_name ^ "' at node " ^ node ^ ":\n"), |
2203 inference_name ^ "' at node " ^ node ^ ":\n"), |
2204 Syntax.pretty_term ctxt inference_fmla])) |
2204 Syntax.pretty_term ctxt inference_fmla])) |
2205 | SOME thm => thm |
2205 | SOME thm => thm |
2206 end |
2206 end |
2207 *} |
2207 \<close> |
2208 |
2208 |
2209 ML {* |
2209 ML \<open> |
2210 (*filter a set of nodes based on which inference rule was used to |
2210 (*filter a set of nodes based on which inference rule was used to |
2211 derive a node*) |
2211 derive a node*) |
2212 fun nodes_by_inference (fms : TPTP_Reconstruct.formula_meaning list) inference_rule = |
2212 fun nodes_by_inference (fms : TPTP_Reconstruct.formula_meaning list) inference_rule = |
2213 let |
2213 let |
2214 fun fold_fun n l = |
2214 fun fold_fun n l = |
2219 if rule_name = inference_rule then n :: l |
2219 if rule_name = inference_rule then n :: l |
2220 else l |
2220 else l |
2221 in |
2221 in |
2222 fold fold_fun (map fst fms) [] |
2222 fold fold_fun (map fst fms) [] |
2223 end |
2223 end |
2224 *} |
2224 \<close> |
2225 |
2225 |
2226 |
2226 |
2227 section "Importing proofs and reconstructing theorems" |
2227 section "Importing proofs and reconstructing theorems" |
2228 |
2228 |
2229 ML {* |
2229 ML \<open> |
2230 (*Preprocessing carried out on a LEO-II proof.*) |
2230 (*Preprocessing carried out on a LEO-II proof.*) |
2231 fun leo2_on_load (pannot : TPTP_Reconstruct.proof_annotation) thy = |
2231 fun leo2_on_load (pannot : TPTP_Reconstruct.proof_annotation) thy = |
2232 let |
2232 let |
2233 val ctxt = Proof_Context.init_global thy |
2233 val ctxt = Proof_Context.init_global thy |
2234 val dud = ("", Binding.empty, @{term False}) |
2234 val dud = ("", Binding.empty, @{term False}) |
2254 defs = #defs pannot, |
2254 defs = #defs pannot, |
2255 axs = #axs pannot, |
2255 axs = #axs pannot, |
2256 meta = #meta pannot}, |
2256 meta = #meta pannot}, |
2257 thy') |
2257 thy') |
2258 end |
2258 end |
2259 *} |
2259 \<close> |
2260 |
2260 |
2261 ML {* |
2261 ML \<open> |
2262 (*Imports and reconstructs a LEO-II proof.*) |
2262 (*Imports and reconstructs a LEO-II proof.*) |
2263 fun reconstruct_leo2 path thy = |
2263 fun reconstruct_leo2 path thy = |
2264 let |
2264 let |
2265 val prob_file = Path.base path |
2265 val prob_file = Path.base path |
2266 val dir = Path.dir path |
2266 val dir = Path.dir path |