prioritize try and auto try's tools, with fast ones first, with a slight preference for provers vs. counterexample generators
1 (* Title: Tools/solve_direct.ML
2 Author: Timothy Bourke and Gerwin Klein, NICTA
4 Check whether a newly stated theorem can be solved directly by an
5 existing theorem. Duplicate lemmas can be detected in this way.
7 The implementation relies critically on the Find_Theorems solves
11 signature SOLVE_DIRECT =
13 val solve_directN: string
17 val auto: bool Unsynchronized.ref
18 val max_solutions: int Unsynchronized.ref
19 val solve_direct: bool -> Proof.state -> bool * (string * Proof.state)
20 val setup: theory -> theory
23 structure Solve_Direct: SOLVE_DIRECT =
26 val solve_directN = "solve_direct";
30 val unknownN = "none";
34 val auto = Unsynchronized.ref false;
35 val max_solutions = Unsynchronized.ref 5;
38 ProofGeneralPgip.add_preference Preferences.category_tracing
39 (Unsynchronized.setmp auto true (fn () =>
40 Preferences.bool_pref auto
42 ("Run " ^ quote solve_directN ^ " automatically.")) ());
45 (* solve_direct command *)
47 fun solve_direct auto state =
49 val ctxt = Proof.context_of state;
51 val crits = [(true, Find_Theorems.Solves)];
53 snd (Find_Theorems.find_theorems ctxt (SOME g) (SOME (! max_solutions)) false crits);
55 fun prt_result (goal, results) =
58 (if auto then "Auto " else "") ^ solve_directN ^ ": " ^
60 NONE => "The current goal"
61 | SOME sg => Syntax.string_of_term ctxt (Thm.term_of sg));
64 (msg ^ " can be solved directly with")
65 (map (Find_Theorems.pretty_thm ctxt) results)
68 fun seek_against_goal () =
69 (case try Proof.simple_goal state of
71 | SOME {goal = st, ...} =>
73 val subgoals = Drule.strip_imp_prems (Thm.cprop_of st);
75 if length subgoals = 1
76 then [(NONE, find st)]
77 else map (fn sg => (SOME sg, find (Goal.init sg))) subgoals;
78 val results = filter_out (null o snd) rs;
79 in if null results then NONE else SOME results end);
80 fun message results = separate (Pretty.brk 0) (map prt_result results);
82 (case try seek_against_goal () of
83 SOME (SOME results) =>
91 Pretty.markup Markup.hilite (message results)])
94 Output.urgent_message (Pretty.string_of (Pretty.chunks (message results))))))
95 | SOME NONE => (noneN, state)
96 | NONE => (unknownN, state))
98 |> `(fn (outcome_code, _) => outcome_code = someN);
101 Outer_Syntax.improper_command solve_directN
102 "try to solve conjectures directly with existing theorems" Keyword.diag
104 (Toplevel.keep (fn state => ignore (solve_direct false (Toplevel.proof_of state)))));
109 val setup = Try.register_tool (solve_directN, (10, auto, solve_direct));