27 isar_proof: bool, |
27 isar_proof: bool, |
28 isar_shrink_factor: int, |
28 isar_shrink_factor: int, |
29 timeout: Time.time, |
29 timeout: Time.time, |
30 expect: string} |
30 expect: string} |
31 |
31 |
32 type atp_problem = |
32 datatype axiom = |
|
33 Unprepared of (string * locality) * thm | |
|
34 Prepared of term * ((string * locality) * fol_formula) option |
|
35 |
|
36 type prover_problem = |
33 {state: Proof.state, |
37 {state: Proof.state, |
34 goal: thm, |
38 goal: thm, |
35 subgoal: int, |
39 subgoal: int, |
36 axioms: (term * ((string * locality) * fol_formula) option) list, |
40 axioms: axiom list, |
37 only: bool} |
41 only: bool} |
38 |
42 |
39 type atp_result = |
43 type prover_result = |
40 {outcome: failure option, |
44 {outcome: failure option, |
41 message: string, |
45 message: string, |
42 pool: string Symtab.table, |
46 used_axioms: (string * locality) list, |
43 used_thm_names: (string * locality) list, |
47 run_time_in_msecs: int} |
44 atp_run_time_in_msecs: int, |
48 |
45 output: string, |
49 type prover = params -> minimize_command -> prover_problem -> prover_result |
46 tstplike_proof: string, |
|
47 axiom_names: (string * locality) list vector, |
|
48 conjecture_shape: int list list} |
|
49 |
|
50 type atp = params -> minimize_command -> atp_problem -> atp_result |
|
51 |
50 |
52 val smtN : string |
51 val smtN : string |
53 val dest_dir : string Config.T |
52 val dest_dir : string Config.T |
54 val problem_prefix : string Config.T |
53 val problem_prefix : string Config.T |
55 val measure_run_time : bool Config.T |
54 val measure_run_time : bool Config.T |
56 val available_provers : theory -> unit |
55 val available_provers : theory -> unit |
57 val kill_provers : unit -> unit |
56 val kill_provers : unit -> unit |
58 val running_provers : unit -> unit |
57 val running_provers : unit -> unit |
59 val messages : int option -> unit |
58 val messages : int option -> unit |
60 val run_atp : theory -> string -> atp |
59 val run_atp : theory -> string -> prover |
|
60 val is_smt_solver_installed : unit -> bool |
61 val run_smt_solver : |
61 val run_smt_solver : |
62 Proof.context -> bool -> Time.time -> ('a * thm) list -> string * 'a list |
62 bool -> params -> minimize_command -> prover_problem |
63 val is_smt_solver_installed : unit -> bool |
63 -> string * (string * locality) list |
64 val run_sledgehammer : |
64 val run_sledgehammer : |
65 params -> bool -> int -> relevance_override -> (string -> minimize_command) |
65 params -> bool -> int -> relevance_override -> (string -> minimize_command) |
66 -> Proof.state -> bool * Proof.state |
66 -> Proof.state -> bool * Proof.state |
67 val setup : theory -> theory |
67 val setup : theory -> theory |
68 end; |
68 end; |
118 isar_proof: bool, |
118 isar_proof: bool, |
119 isar_shrink_factor: int, |
119 isar_shrink_factor: int, |
120 timeout: Time.time, |
120 timeout: Time.time, |
121 expect: string} |
121 expect: string} |
122 |
122 |
123 type atp_problem = |
123 datatype axiom = |
|
124 Unprepared of (string * locality) * thm | |
|
125 Prepared of term * ((string * locality) * fol_formula) option |
|
126 |
|
127 type prover_problem = |
124 {state: Proof.state, |
128 {state: Proof.state, |
125 goal: thm, |
129 goal: thm, |
126 subgoal: int, |
130 subgoal: int, |
127 axioms: (term * ((string * locality) * fol_formula) option) list, |
131 axioms: axiom list, |
128 only: bool} |
132 only: bool} |
129 |
133 |
130 type atp_result = |
134 type prover_result = |
131 {outcome: failure option, |
135 {outcome: failure option, |
132 message: string, |
136 message: string, |
133 pool: string Symtab.table, |
137 used_axioms: (string * locality) list, |
134 used_thm_names: (string * locality) list, |
138 run_time_in_msecs: int} |
135 atp_run_time_in_msecs: int, |
139 |
136 output: string, |
140 type prover = params -> minimize_command -> prover_problem -> prover_result |
137 tstplike_proof: string, |
|
138 axiom_names: (string * locality) list vector, |
|
139 conjecture_shape: int list list} |
|
140 |
|
141 type atp = params -> minimize_command -> atp_problem -> atp_result |
|
142 |
141 |
143 (* configuration attributes *) |
142 (* configuration attributes *) |
144 |
143 |
145 val (dest_dir, dest_dir_setup) = |
144 val (dest_dir, dest_dir_setup) = |
146 Attrib.config_string "sledgehammer_dest_dir" (K "") |
145 Attrib.config_string "sledgehammer_dest_dir" (K "") |
174 fun proof_banner auto = |
173 fun proof_banner auto = |
175 if auto then "Sledgehammer found a proof" else "Try this command" |
174 if auto then "Sledgehammer found a proof" else "Try this command" |
176 |
175 |
177 (* generic TPTP-based ATPs *) |
176 (* generic TPTP-based ATPs *) |
178 |
177 |
|
178 fun dest_Unprepared (Unprepared p) = p |
|
179 | dest_Unprepared (Prepared _) = raise Fail "dest_Unprepared" |
|
180 fun prepared_axiom ctxt (Unprepared p) = prepare_axiom ctxt p |
|
181 | prepared_axiom _ (Prepared p) = p |
|
182 |
179 (* Important messages are important but not so important that users want to see |
183 (* Important messages are important but not so important that users want to see |
180 them each time. *) |
184 them each time. *) |
181 val important_message_keep_factor = 0.1 |
185 val important_message_keep_factor = 0.1 |
182 |
186 |
183 fun atp_fun auto atp_name |
187 fun atp_fun auto atp_name |
184 {exec, required_execs, arguments, has_incomplete_mode, proof_delims, |
188 {exec, required_execs, arguments, has_incomplete_mode, proof_delims, |
185 known_failures, default_max_relevant, explicit_forall, |
189 known_failures, default_max_relevant, explicit_forall, |
186 use_conjecture_for_hypotheses} |
190 use_conjecture_for_hypotheses} |
187 ({debug, verbose, overlord, full_types, explicit_apply, |
191 ({debug, verbose, overlord, full_types, explicit_apply, |
188 max_relevant, isar_proof, isar_shrink_factor, timeout, ...} : params) |
192 max_relevant, isar_proof, isar_shrink_factor, timeout, ...} : params) |
189 minimize_command ({state, goal, subgoal, axioms, only} : atp_problem) = |
193 minimize_command |
|
194 ({state, goal, subgoal, axioms, only} : prover_problem) = |
190 let |
195 let |
191 val ctxt = Proof.context_of state |
196 val ctxt = Proof.context_of state |
192 val (_, hyp_ts, concl_t) = strip_subgoal goal subgoal |
197 val (_, hyp_ts, concl_t) = strip_subgoal goal subgoal |
193 val axioms = axioms |> not only |
198 val axioms = |
194 ? take (the_default default_max_relevant max_relevant) |
199 axioms |> not only ? take (the_default default_max_relevant max_relevant) |
|
200 |> map (prepared_axiom ctxt) |
195 val dest_dir = if overlord then getenv "ISABELLE_HOME_USER" |
201 val dest_dir = if overlord then getenv "ISABELLE_HOME_USER" |
196 else Config.get ctxt dest_dir |
202 else Config.get ctxt dest_dir |
197 val problem_prefix = Config.get ctxt problem_prefix |
203 val problem_prefix = Config.get ctxt problem_prefix |
198 val atp_problem_file_name = |
204 val problem_file_name = |
199 Path.basic ((if overlord then "prob_" ^ atp_name |
205 Path.basic ((if overlord then "prob_" ^ atp_name |
200 else problem_prefix ^ serial_string ()) |
206 else problem_prefix ^ serial_string ()) |
201 ^ "_" ^ string_of_int subgoal) |
207 ^ "_" ^ string_of_int subgoal) |
202 val atp_problem_path_name = |
208 val problem_path_name = |
203 if dest_dir = "" then |
209 if dest_dir = "" then |
204 File.tmp_path atp_problem_file_name |
210 File.tmp_path problem_file_name |
205 else if File.exists (Path.explode dest_dir) then |
211 else if File.exists (Path.explode dest_dir) then |
206 Path.append (Path.explode dest_dir) atp_problem_file_name |
212 Path.append (Path.explode dest_dir) problem_file_name |
207 else |
213 else |
208 error ("No such directory: " ^ quote dest_dir ^ ".") |
214 error ("No such directory: " ^ quote dest_dir ^ ".") |
209 val measure_run_time = verbose orelse Config.get ctxt measure_run_time |
215 val measure_run_time = verbose orelse Config.get ctxt measure_run_time |
210 val command = Path.explode (getenv (fst exec) ^ "/" ^ snd exec) |
216 val command = Path.explode (getenv (fst exec) ^ "/" ^ snd exec) |
211 (* write out problem file and call ATP *) |
217 (* write out problem file and call ATP *) |
286 () |
292 () |
287 else |
293 else |
288 File.write (Path.explode (Path.implode probfile ^ "_proof")) output |
294 File.write (Path.explode (Path.implode probfile ^ "_proof")) output |
289 val ((pool, conjecture_shape, axiom_names), |
295 val ((pool, conjecture_shape, axiom_names), |
290 (output, msecs, tstplike_proof, outcome)) = |
296 (output, msecs, tstplike_proof, outcome)) = |
291 with_path cleanup export run_on atp_problem_path_name |
297 with_path cleanup export run_on problem_path_name |
292 val (conjecture_shape, axiom_names) = |
298 val (conjecture_shape, axiom_names) = |
293 repair_conjecture_shape_and_axiom_names output conjecture_shape |
299 repair_conjecture_shape_and_axiom_names output conjecture_shape |
294 axiom_names |
300 axiom_names |
295 val important_message = |
301 val important_message = |
296 if random () <= important_message_keep_factor then |
302 if random () <= important_message_keep_factor then |
297 extract_important_message output |
303 extract_important_message output |
298 else |
304 else |
299 "" |
305 "" |
300 val (message, used_thm_names) = |
306 val (message, used_axioms) = |
301 case outcome of |
307 case outcome of |
302 NONE => |
308 NONE => |
303 proof_text isar_proof |
309 proof_text isar_proof |
304 (pool, debug, isar_shrink_factor, ctxt, conjecture_shape) |
310 (pool, debug, isar_shrink_factor, ctxt, conjecture_shape) |
305 (proof_banner auto, full_types, minimize_command, tstplike_proof, |
311 (proof_banner auto, full_types, minimize_command, tstplike_proof, |
315 important_message |
321 important_message |
316 else |
322 else |
317 "")) |
323 "")) |
318 | SOME failure => (string_for_failure failure, []) |
324 | SOME failure => (string_for_failure failure, []) |
319 in |
325 in |
320 {outcome = outcome, message = message, pool = pool, |
326 {outcome = outcome, message = message, used_axioms = used_axioms, |
321 used_thm_names = used_thm_names, atp_run_time_in_msecs = msecs, |
327 run_time_in_msecs = msecs} |
322 output = output, tstplike_proof = tstplike_proof, |
|
323 axiom_names = axiom_names, conjecture_shape = conjecture_shape} |
|
324 end |
328 end |
325 |
329 |
326 fun run_atp thy name = atp_fun false name (get_atp thy name) |
330 fun run_atp thy name = atp_fun false name (get_atp thy name) |
327 |
331 |
328 fun run_atp_somehow (params as {blocking, debug, max_relevant, timeout, |
332 fun run_atp_somehow (params as {blocking, debug, max_relevant, timeout, |
329 expect, ...}) |
333 expect, ...}) |
330 auto i n minimize_command |
334 auto i n minimize_command |
331 (atp_problem as {state, goal, axioms, ...}) |
335 (prover_problem as {state, goal, axioms, ...}) |
332 (atp as {default_max_relevant, ...}, atp_name) = |
336 (prover as {default_max_relevant, ...}, atp_name) = |
333 let |
337 let |
334 val ctxt = Proof.context_of state |
338 val ctxt = Proof.context_of state |
335 val birth_time = Time.now () |
339 val birth_time = Time.now () |
336 val death_time = Time.+ (birth_time, timeout) |
340 val death_time = Time.+ (birth_time, timeout) |
337 val max_relevant = the_default default_max_relevant max_relevant |
341 val max_relevant = the_default default_max_relevant max_relevant |
338 val num_axioms = Int.min (length axioms, max_relevant) |
342 val num_axioms = Int.min (length axioms, max_relevant) |
339 val desc = prover_description ctxt params atp_name num_axioms i n goal |
343 val desc = prover_description ctxt params atp_name num_axioms i n goal |
340 fun go () = |
344 fun go () = |
341 let |
345 let |
342 fun really_go () = |
346 fun really_go () = |
343 atp_fun auto atp_name atp params (minimize_command atp_name) |
347 atp_fun auto atp_name prover params (minimize_command atp_name) |
344 atp_problem |
348 prover_problem |
345 |> (fn {outcome, message, ...} => |
349 |> (fn {outcome, message, ...} => |
346 (if is_some outcome then "none" else "some", message)) |
350 (if is_some outcome then "none" else "some", message)) |
347 val (outcome_code, message) = |
351 val (outcome_code, message) = |
348 if debug then |
352 if debug then |
349 really_go () |
353 really_go () |
377 (Async_Manager.launch das_Tool birth_time death_time desc (snd o go); |
381 (Async_Manager.launch das_Tool birth_time death_time desc (snd o go); |
378 (false, state)) |
382 (false, state)) |
379 end |
383 end |
380 |
384 |
381 (* FIXME: dummy *) |
385 (* FIXME: dummy *) |
382 fun run_smt_solver ctxt remote timeout axioms = |
386 fun is_smt_solver_installed () = true |
|
387 |
|
388 (* FIXME: dummy *) |
|
389 fun raw_run_smt_solver remote timeout state axioms i = |
383 ("", axioms |> take 5 |> map fst) |
390 ("", axioms |> take 5 |> map fst) |
384 |
391 |
385 (* FIXME: dummy *) |
392 fun run_smt_solver remote ({timeout, ...} : params) minimize_command |
386 fun is_smt_solver_installed () = true |
393 ({state, subgoal, axioms, ...} : prover_problem) = |
387 |
394 raw_run_smt_solver remote timeout state |
388 fun run_smt_solver_somehow ctxt (params as {timeout, ...}) i n goal axioms |
395 (map_filter (try dest_Unprepared) axioms) subgoal |
|
396 |
|
397 fun run_smt_solver_somehow state (params as {timeout, ...}) i n goal axioms |
389 (remote, name) = |
398 (remote, name) = |
390 let |
399 let |
391 val desc = |
400 val ctxt = Proof.context_of state |
392 prover_description ctxt params name (length axioms) i n goal |
401 val desc = prover_description ctxt params name (length axioms) i n goal |
393 val (failure, used_thm_names) = run_smt_solver ctxt remote timeout axioms |
402 val (failure, used_axioms) = |
|
403 raw_run_smt_solver remote timeout state axioms i |
394 val success = (failure = "") |
404 val success = (failure = "") |
395 val message = |
405 val message = |
396 das_Tool ^ ": " ^ desc ^ "\n" ^ |
406 das_Tool ^ ": " ^ desc ^ "\n" ^ |
397 (if success then |
407 (if success then |
398 sendback_line (proof_banner false) |
408 sendback_line (proof_banner false) |
399 (apply_on_subgoal i n ^ |
409 (apply_on_subgoal i n ^ |
400 command_call "smt" (map fst used_thm_names)) |
410 command_call "smt" (map fst used_axioms)) |
401 else |
411 else |
402 "Error: " ^ failure) |
412 "Error: " ^ failure) |
403 in priority message; success end |
413 in priority message; success end |
404 |
414 |
405 val smt_default_max_relevant = 300 (* FUDGE *) |
415 val smt_default_max_relevant = 300 (* FUDGE *) |
439 |> auto ? (fn n => n div auto_max_relevant_divisor) |
449 |> auto ? (fn n => n div auto_max_relevant_divisor) |
440 val axioms = |
450 val axioms = |
441 relevant_facts ctxt full_types relevance_thresholds |
451 relevant_facts ctxt full_types relevance_thresholds |
442 max_max_relevant relevance_override chained_ths |
452 max_max_relevant relevance_override chained_ths |
443 hyp_ts concl_t |
453 hyp_ts concl_t |
444 val atp_problem = |
454 val prover_problem = |
445 {state = state, goal = goal, subgoal = i, |
455 {state = state, goal = goal, subgoal = i, |
446 axioms = map (prepare_axiom ctxt) axioms, only = only} |
456 axioms = axioms |> map (Prepared o prepare_axiom ctxt), |
|
457 only = only} |
447 val run_atp_somehow = |
458 val run_atp_somehow = |
448 run_atp_somehow params auto i n minimize_command atp_problem |
459 run_atp_somehow params auto i n minimize_command prover_problem |
449 in |
460 in |
450 if auto then |
461 if auto then |
451 fold (fn atp => fn (true, state) => (true, state) |
462 fold (fn prover => fn (true, state) => (true, state) |
452 | (false, _) => run_atp_somehow atp) |
463 | (false, _) => run_atp_somehow prover) |
453 atps (false, state) |
464 atps (false, state) |
454 else |
465 else |
455 atps |> (if blocking then Par_List.map else map) run_atp_somehow |
466 atps |> (if blocking then Par_List.map else map) run_atp_somehow |
456 |> exists fst |> rpair state |
467 |> exists fst |> rpair state |
457 end |
468 end |