1 (* Title: Tools/auto_solve.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 AUTO_SOLVE =
13 val auto : bool Unsynchronized.ref
14 val max_solutions : int Unsynchronized.ref
15 val setup : theory -> theory
18 structure Auto_Solve : AUTO_SOLVE =
23 val auto = Unsynchronized.ref false;
24 val max_solutions = Unsynchronized.ref 5;
27 ProofGeneralPgip.add_preference Preferences.category_tracing
28 (Unsynchronized.setmp auto true (fn () =>
29 Preferences.bool_pref auto
30 "auto-solve" "Try to solve conjectures with existing theorems.") ());
35 fun auto_solve state =
37 val ctxt = Proof.context_of state;
39 val crits = [(true, Find_Theorems.Solves)];
40 fun find g = snd (Find_Theorems.find_theorems ctxt (SOME g) (SOME (! max_solutions)) false crits);
42 fun prt_result (goal, results) =
46 NONE => "The current goal"
47 | SOME sg => Syntax.string_of_term ctxt (Thm.term_of sg));
50 (msg ^ " could be solved directly with:")
51 (map (Find_Theorems.pretty_thm ctxt) results)
54 fun seek_against_goal () =
55 (case try Proof.simple_goal state of
57 | SOME {goal = st, ...} =>
59 val subgoals = Drule.strip_imp_prems (Thm.cprop_of st);
61 if length subgoals = 1
62 then [(NONE, find st)]
63 else map (fn sg => (SOME sg, find (Goal.init sg))) subgoals;
64 val results = filter_out (null o snd) rs;
65 in if null results then NONE else SOME results end);
68 (case try seek_against_goal () of
69 SOME (SOME results) =>
70 (true, state |> Proof.goal_message
71 (fn () => Pretty.chunks
73 Pretty.markup Markup.hilite
74 (separate (Pretty.brk 0) (map prt_result results))]))
75 | _ => (false, state));
76 in if not (!auto) then (false, state) else go () end;
78 val setup = Auto_Tools.register_tool ("solve", auto_solve)