1 (* Title: mirabelle_sledgehammer.ML
2 Author: Jasmin Blanchette and Sascha Boehme
5 structure Mirabelle_Sledgehammer : MIRABELLE_ACTION =
8 fun thms_of_name ctxt name =
10 val lex = OuterKeyword.get_lexicons
11 val get = maps (ProofContext.get_fact ctxt o fst)
14 |> Symbol.source {do_recover=false}
15 |> OuterLex.source {do_recover=SOME false} lex Position.start
16 |> OuterLex.source_proper
17 |> Source.source OuterLex.stopper (SpecParse.xthms1 >> get) NONE
21 fun safe init done f x =
24 val z = Exn.capture f y
28 fun with_time true t = "succeeded (" ^ string_of_int t ^ ")"
29 | with_time false t = "failed (" ^ string_of_int t ^ ")"
31 val proverK = "prover"
38 fun init NONE = !AtpWrapper.destdir
41 (* Warning: we implicitly assume single-threaded execution here! *)
42 val old = !AtpWrapper.destdir
43 val _ = AtpWrapper.destdir := path
46 fun done path = AtpWrapper.destdir := path
48 fun run prover_name timeout st _ =
50 val prover = the (AtpManager.get_prover prover_name (Proof.theory_of st))
51 val atp_timeout = AtpManager.get_timeout ()
52 val atp = prover atp_timeout NONE NONE prover_name 1
53 val (success, (message, thm_names), _, _, _) =
54 TimeLimit.timeLimit timeout atp (Proof.get_goal st)
55 in (success, message, SOME thm_names) end
56 handle ResHolClause.TOO_TRIVIAL => (true, "trivial", SOME [])
57 | TimeLimit.TimeOut => (false, "time out", NONE)
58 | ERROR msg => (false, "error: " ^ msg, NONE)
62 fun run_sledgehammer (args, st, timeout, log) =
65 AList.lookup (op =) args proverK
66 |> the_default (hd (space_explode " " (AtpManager.get_atps ())))
67 val dir = AList.lookup (op =) args keepK
68 val ((success, msg, thm_names), time) =
69 safe init done (Mirabelle.cpu_time (run prover_name timeout st)) dir
70 fun sh_log s = log ("sledgehammer: " ^ with_time success time ^ " [" ^
71 prover_name ^ "]" ^ s)
72 val _ = if success then sh_log (":\n" ^ msg) else sh_log ""
73 in if success then thm_names else NONE end
78 fun run_metis (args, st, timeout, log) thm_names =
80 fun get_thms ctxt = maps (thms_of_name ctxt)
81 fun metis thms ctxt = MetisTools.metis_tac ctxt thms
82 fun apply_metis thms = Mirabelle.can_apply timeout (metis thms) st
83 fun timed_metis thms =
84 uncurry with_time (Mirabelle.cpu_time apply_metis thms)
85 handle TimeLimit.TimeOut => "time out"
86 fun log_metis s = log ("-----\nmetis (sledgehammer): " ^ s)
88 if not (AList.defined (op =) args metisK) then ()
89 else if is_none thm_names then ()
92 |> get_thms (Proof.context_of st)
98 fun sledgehammer_action args {pre, timeout, log, ...} =
99 run_sledgehammer (args, pre, timeout, log)
100 |> run_metis (args, pre, timeout, log)
102 fun invoke args = Mirabelle.register ("sledgehammer", sledgehammer_action args)