1 (* Title: HOL/Tools/ATP_Manager/atp_manager.ML |
1 (* Title: HOL/Tools/ATP_Manager/atp_manager.ML |
2 Author: Fabian Immler, TU Muenchen |
2 Author: Fabian Immler, TU Muenchen |
3 Author: Makarius |
3 Author: Makarius |
|
4 Author: Jasmin Blanchette, TU Muenchen |
4 |
5 |
5 Central manager component for ATP threads. |
6 Central manager component for ATP threads. |
6 *) |
7 *) |
7 |
8 |
8 signature ATP_MANAGER = |
9 signature ATP_MANAGER = |
9 sig |
10 sig |
|
11 type relevance_override = Sledgehammer_Fact_Filter.relevance_override |
|
12 type params = |
|
13 {debug: bool, |
|
14 verbose: bool, |
|
15 atps: string list, |
|
16 full_types: bool, |
|
17 relevance_threshold: real, |
|
18 higher_order: bool option, |
|
19 respect_no_atp: bool, |
|
20 follow_defs: bool, |
|
21 isar_proof: bool, |
|
22 timeout: Time.time, |
|
23 minimize_timeout: Time.time} |
10 type problem = |
24 type problem = |
11 {with_full_types: bool, |
25 {subgoal: int, |
12 subgoal: int, |
26 goal: Proof.context * (thm list * thm), |
13 goal: Proof.context * (thm list * thm), |
27 relevance_override: relevance_override, |
14 axiom_clauses: (thm * (string * int)) list option, |
28 axiom_clauses: (thm * (string * int)) list option, |
15 filtered_clauses: (thm * (string * int)) list option} |
29 filtered_clauses: (thm * (string * int)) list option} |
16 val problem_of_goal: bool -> int -> Proof.context * (thm list * thm) -> problem |
|
17 type prover_result = |
30 type prover_result = |
18 {success: bool, |
31 {success: bool, |
19 message: string, |
32 message: string, |
20 theorem_names: string list, |
33 relevant_thm_names: string list, |
21 runtime: int, |
34 atp_run_time_in_msecs: int, |
22 proof: string, |
35 proof: string, |
23 internal_thm_names: string Vector.vector, |
36 internal_thm_names: string Vector.vector, |
24 filtered_clauses: (thm * (string * int)) list} |
37 filtered_clauses: (thm * (string * int)) list} |
25 type prover = int -> problem -> prover_result |
38 type prover = params -> Time.time -> problem -> prover_result |
26 |
39 |
27 val atps: string Unsynchronized.ref |
40 val atps: string Unsynchronized.ref |
28 val get_atps: unit -> string list |
|
29 val timeout: int Unsynchronized.ref |
41 val timeout: int Unsynchronized.ref |
30 val full_types: bool Unsynchronized.ref |
42 val full_types: bool Unsynchronized.ref |
31 val kill: unit -> unit |
43 val kill_atps: unit -> unit |
32 val info: unit -> unit |
44 val running_atps: unit -> unit |
33 val messages: int option -> unit |
45 val messages: int option -> unit |
34 val add_prover: string * prover -> theory -> theory |
46 val add_prover: string * prover -> theory -> theory |
35 val get_prover: theory -> string -> prover option |
47 val get_prover: theory -> string -> prover option |
36 val print_provers: theory -> unit |
48 val available_atps: theory -> unit |
37 val sledgehammer: string list -> Proof.state -> unit |
49 val sledgehammer: params -> int -> relevance_override -> Proof.state -> unit |
38 end; |
50 end; |
39 |
51 |
40 structure ATP_Manager : ATP_MANAGER = |
52 structure ATP_Manager : ATP_MANAGER = |
41 struct |
53 struct |
42 |
54 |
43 (** problems, results, and provers **) |
55 type relevance_override = Sledgehammer_Fact_Filter.relevance_override |
|
56 |
|
57 (** parameters, problems, results, and provers **) |
|
58 |
|
59 (* TODO: "theory_const", "blacklist_filter", "convergence" *) |
|
60 type params = |
|
61 {debug: bool, |
|
62 verbose: bool, |
|
63 atps: string list, |
|
64 full_types: bool, |
|
65 relevance_threshold: real, |
|
66 higher_order: bool option, |
|
67 respect_no_atp: bool, |
|
68 follow_defs: bool, |
|
69 isar_proof: bool, |
|
70 timeout: Time.time, |
|
71 minimize_timeout: Time.time} |
44 |
72 |
45 type problem = |
73 type problem = |
46 {with_full_types: bool, |
74 {subgoal: int, |
47 subgoal: int, |
75 goal: Proof.context * (thm list * thm), |
48 goal: Proof.context * (thm list * thm), |
76 relevance_override: relevance_override, |
49 axiom_clauses: (thm * (string * int)) list option, |
77 axiom_clauses: (thm * (string * int)) list option, |
50 filtered_clauses: (thm * (string * int)) list option}; |
78 filtered_clauses: (thm * (string * int)) list option}; |
51 |
|
52 fun problem_of_goal with_full_types subgoal goal : problem = |
|
53 {with_full_types = with_full_types, |
|
54 subgoal = subgoal, |
|
55 goal = goal, |
|
56 axiom_clauses = NONE, |
|
57 filtered_clauses = NONE}; |
|
58 |
79 |
59 type prover_result = |
80 type prover_result = |
60 {success: bool, |
81 {success: bool, |
61 message: string, |
82 message: string, |
62 theorem_names: string list, (*relevant theorems*) |
83 relevant_thm_names: string list, |
63 runtime: int, (*user time of the ATP, in milliseconds*) |
84 atp_run_time_in_msecs: int, |
64 proof: string, |
85 proof: string, |
65 internal_thm_names: string Vector.vector, |
86 internal_thm_names: string Vector.vector, |
66 filtered_clauses: (thm * (string * int)) list}; |
87 filtered_clauses: (thm * (string * int)) list}; |
67 |
88 |
68 type prover = int -> problem -> prover_result; |
89 type prover = params -> Time.time -> problem -> prover_result; |
69 |
90 |
70 |
91 |
71 (** preferences **) |
92 (** preferences **) |
72 |
93 |
73 val message_store_limit = 20; |
94 val message_store_limit = 20; |
74 val message_display_limit = 5; |
95 val message_display_limit = 5; |
75 |
96 |
76 val atps = Unsynchronized.ref "e spass remote_vampire"; |
97 val atps = Unsynchronized.ref "e spass remote_vampire"; |
77 fun get_atps () = String.tokens (Symbol.is_ascii_blank o String.str) (! atps); |
|
78 |
|
79 val timeout = Unsynchronized.ref 60; |
98 val timeout = Unsynchronized.ref 60; |
80 val full_types = Unsynchronized.ref false; |
99 val full_types = Unsynchronized.ref false; |
81 |
100 |
82 val _ = |
101 val _ = |
83 ProofGeneralPgip.add_preference Preferences.category_proof |
102 ProofGeneralPgip.add_preference Preferences.category_proof |
216 |
235 |
217 |
236 |
218 |
237 |
219 (** user commands **) |
238 (** user commands **) |
220 |
239 |
221 (* kill *) |
240 (* kill ATPs *) |
222 |
241 |
223 fun kill () = Synchronized.change global_state |
242 fun kill_atps () = Synchronized.change global_state |
224 (fn {manager, timeout_heap, active, cancelling, messages, store} => |
243 (fn {manager, timeout_heap, active, cancelling, messages, store} => |
225 let |
244 let |
226 val killing = map (fn (th, (_, _, desc)) => (th, (Time.now (), desc))) active; |
245 val killing = map (fn (th, (_, _, desc)) => (th, (Time.now (), desc))) active; |
227 val state' = make_state manager timeout_heap [] (killing @ cancelling) messages store; |
246 val state' = make_state manager timeout_heap [] (killing @ cancelling) messages store; |
228 in state' end); |
247 in state' end); |
229 |
248 |
230 |
249 |
231 (* info *) |
250 (* running_atps *) |
232 |
251 |
233 fun seconds time = string_of_int (Time.toSeconds time) ^ "s"; |
252 fun seconds time = string_of_int (Time.toSeconds time) ^ "s"; |
234 |
253 |
235 fun info () = |
254 fun running_atps () = |
236 let |
255 let |
237 val {active, cancelling, ...} = Synchronized.value global_state; |
256 val {active, cancelling, ...} = Synchronized.value global_state; |
238 |
257 |
239 val now = Time.now (); |
258 val now = Time.now (); |
240 fun running_info (_, (birth_time, death_time, desc)) = |
259 fun running_info (_, (birth_time, death_time, desc)) = |
285 handle Symtab.DUP dup => err_dup_prover dup; |
304 handle Symtab.DUP dup => err_dup_prover dup; |
286 |
305 |
287 fun get_prover thy name = |
306 fun get_prover thy name = |
288 Option.map #1 (Symtab.lookup (Provers.get thy) name); |
307 Option.map #1 (Symtab.lookup (Provers.get thy) name); |
289 |
308 |
290 fun print_provers thy = Pretty.writeln |
309 fun available_atps thy = Pretty.writeln |
291 (Pretty.strs ("external provers:" :: sort_strings (Symtab.keys (Provers.get thy)))); |
310 (Pretty.strs ("ATPs:" :: sort_strings (Symtab.keys (Provers.get thy)))); |
292 |
311 |
293 |
312 |
294 (* start prover thread *) |
313 (* start prover thread *) |
295 |
314 |
296 fun start_prover name birth_time death_time i proof_state = |
315 fun start_prover (params as {timeout, ...}) birth_time death_time i |
|
316 relevance_override proof_state name = |
297 (case get_prover (Proof.theory_of proof_state) name of |
317 (case get_prover (Proof.theory_of proof_state) name of |
298 NONE => warning ("Unknown external prover: " ^ quote name) |
318 NONE => warning ("Unknown ATP: " ^ quote name) |
299 | SOME prover => |
319 | SOME prover => |
300 let |
320 let |
301 val {context = ctxt, facts, goal} = Proof.goal proof_state; |
321 val {context = ctxt, facts, goal} = Proof.goal proof_state; |
302 val desc = |
322 val desc = |
303 "external prover " ^ quote name ^ " for subgoal " ^ string_of_int i ^ ":\n" ^ |
323 "ATP " ^ quote name ^ " for subgoal " ^ string_of_int i ^ ":\n" ^ |
304 Syntax.string_of_term ctxt (Thm.term_of (Thm.cprem_of goal i)); |
324 Syntax.string_of_term ctxt (Thm.term_of (Thm.cprem_of goal i)); |
305 |
325 |
306 val _ = Toplevel.thread true (fn () => |
326 val _ = Toplevel.thread true (fn () => |
307 let |
327 let |
308 val _ = register birth_time death_time (Thread.self (), desc); |
328 val _ = register birth_time death_time (Thread.self (), desc); |
309 val problem = problem_of_goal (! full_types) i (ctxt, (facts, goal)); |
329 val problem = |
310 val message = #message (prover (! timeout) problem) |
330 {subgoal = i, goal = (ctxt, (facts, goal)), |
|
331 relevance_override = relevance_override, axiom_clauses = NONE, |
|
332 filtered_clauses = NONE} |
|
333 val message = #message (prover params timeout problem) |
311 handle Sledgehammer_HOL_Clause.TRIVIAL => (* FIXME !? *) |
334 handle Sledgehammer_HOL_Clause.TRIVIAL => (* FIXME !? *) |
312 "Empty clause: Try this command: " ^ Markup.markup Markup.sendback "apply metis" |
335 "Try this command: " ^ |
|
336 Markup.markup Markup.sendback "by metis" ^ "." |
313 | ERROR msg => ("Error: " ^ msg); |
337 | ERROR msg => ("Error: " ^ msg); |
314 val _ = unregister message (Thread.self ()); |
338 val _ = unregister message (Thread.self ()); |
315 in () end); |
339 in () end); |
316 in () end); |
340 in () end); |
317 |
341 |
318 |
342 |
319 (* sledghammer for first subgoal *) |
343 (* Sledgehammer the given subgoal *) |
320 |
344 |
321 fun sledgehammer names proof_state = |
345 fun sledgehammer (params as {atps, timeout, ...}) i relevance_override |
|
346 proof_state = |
322 let |
347 let |
323 val provers = if null names then get_atps () else names; |
348 val birth_time = Time.now () |
324 val birth_time = Time.now (); |
349 val death_time = Time.+ (birth_time, timeout) |
325 val death_time = Time.+ (birth_time, Time.fromSeconds (! timeout)); |
350 val _ = kill_atps () (* RACE w.r.t. other invocations of Sledgehammer *) |
326 val _ = kill (); (*RACE wrt. other invocations of sledgehammer*) |
351 val _ = priority "Sledgehammering..." |
327 val _ = List.app (fn name => start_prover name birth_time death_time 1 proof_state) provers; |
352 val _ = List.app (start_prover params birth_time death_time i |
328 in () end; |
353 relevance_override proof_state) atps |
|
354 in () end |
329 |
355 |
330 end; |
356 end; |