blanchet@38255
|
1 |
(* Title: HOL/Tools/Sledgehammer/sledgehammer.ML
|
wenzelm@28477
|
2 |
Author: Fabian Immler, TU Muenchen
|
wenzelm@32996
|
3 |
Author: Makarius
|
blanchet@35967
|
4 |
Author: Jasmin Blanchette, TU Muenchen
|
wenzelm@28477
|
5 |
|
blanchet@38255
|
6 |
Sledgehammer's heart.
|
wenzelm@28477
|
7 |
*)
|
wenzelm@28477
|
8 |
|
blanchet@38255
|
9 |
signature SLEDGEHAMMER =
|
wenzelm@28477
|
10 |
sig
|
blanchet@38257
|
11 |
type failure = ATP_Systems.failure
|
blanchet@38991
|
12 |
type locality = Sledgehammer_Fact_Filter.locality
|
blanchet@35967
|
13 |
type relevance_override = Sledgehammer_Fact_Filter.relevance_override
|
blanchet@36281
|
14 |
type minimize_command = Sledgehammer_Proof_Reconstruct.minimize_command
|
blanchet@35967
|
15 |
type params =
|
blanchet@35967
|
16 |
{debug: bool,
|
blanchet@35967
|
17 |
verbose: bool,
|
blanchet@36141
|
18 |
overlord: bool,
|
blanchet@35967
|
19 |
atps: string list,
|
blanchet@35967
|
20 |
full_types: bool,
|
blanchet@36235
|
21 |
explicit_apply: bool,
|
blanchet@38984
|
22 |
relevance_thresholds: real * real,
|
blanchet@38983
|
23 |
max_relevant: int option,
|
blanchet@36220
|
24 |
theory_relevant: bool option,
|
blanchet@35967
|
25 |
isar_proof: bool,
|
blanchet@36916
|
26 |
isar_shrink_factor: int,
|
blanchet@38813
|
27 |
timeout: Time.time}
|
blanchet@35867
|
28 |
type problem =
|
blanchet@35967
|
29 |
{subgoal: int,
|
blanchet@35967
|
30 |
goal: Proof.context * (thm list * thm),
|
blanchet@35967
|
31 |
relevance_override: relevance_override,
|
blanchet@38991
|
32 |
axioms: ((string * locality) * thm) list option}
|
blanchet@35867
|
33 |
type prover_result =
|
blanchet@36370
|
34 |
{outcome: failure option,
|
blanchet@35967
|
35 |
message: string,
|
blanchet@38166
|
36 |
pool: string Symtab.table,
|
blanchet@38991
|
37 |
used_thm_names: (string * locality) list,
|
blanchet@35967
|
38 |
atp_run_time_in_msecs: int,
|
blanchet@36369
|
39 |
output: string,
|
blanchet@35967
|
40 |
proof: string,
|
blanchet@38991
|
41 |
axiom_names: (string * locality) vector,
|
blanchet@38329
|
42 |
conjecture_shape: int list list}
|
blanchet@38346
|
43 |
type prover = params -> minimize_command -> problem -> prover_result
|
blanchet@35867
|
44 |
|
blanchet@38257
|
45 |
val dest_dir : string Config.T
|
blanchet@38257
|
46 |
val problem_prefix : string Config.T
|
blanchet@38257
|
47 |
val measure_runtime : bool Config.T
|
blanchet@35967
|
48 |
val kill_atps: unit -> unit
|
blanchet@35967
|
49 |
val running_atps: unit -> unit
|
wenzelm@29112
|
50 |
val messages: int option -> unit
|
blanchet@38257
|
51 |
val get_prover_fun : theory -> string -> prover
|
blanchet@38290
|
52 |
val run_sledgehammer :
|
blanchet@38290
|
53 |
params -> int -> relevance_override -> (string -> minimize_command)
|
blanchet@38290
|
54 |
-> Proof.state -> unit
|
blanchet@38257
|
55 |
val setup : theory -> theory
|
wenzelm@28477
|
56 |
end;
|
wenzelm@28477
|
57 |
|
blanchet@38255
|
58 |
structure Sledgehammer : SLEDGEHAMMER =
|
wenzelm@28477
|
59 |
struct
|
wenzelm@28477
|
60 |
|
blanchet@38262
|
61 |
open ATP_Problem
|
blanchet@38262
|
62 |
open ATP_Systems
|
blanchet@37578
|
63 |
open Metis_Clauses
|
blanchet@38257
|
64 |
open Sledgehammer_Util
|
blanchet@36063
|
65 |
open Sledgehammer_Fact_Filter
|
blanchet@38506
|
66 |
open Sledgehammer_Translate
|
blanchet@36063
|
67 |
open Sledgehammer_Proof_Reconstruct
|
blanchet@37583
|
68 |
|
blanchet@38257
|
69 |
|
blanchet@37583
|
70 |
(** The Sledgehammer **)
|
blanchet@37583
|
71 |
|
blanchet@38348
|
72 |
(* Identifier to distinguish Sledgehammer from other tools using
|
blanchet@38348
|
73 |
"Async_Manager". *)
|
blanchet@37585
|
74 |
val das_Tool = "Sledgehammer"
|
blanchet@37585
|
75 |
|
blanchet@37585
|
76 |
fun kill_atps () = Async_Manager.kill_threads das_Tool "ATPs"
|
blanchet@37585
|
77 |
fun running_atps () = Async_Manager.running_threads das_Tool "ATPs"
|
blanchet@37585
|
78 |
val messages = Async_Manager.thread_messages das_Tool "ATP"
|
blanchet@35967
|
79 |
|
blanchet@36281
|
80 |
(** problems, results, provers, etc. **)
|
blanchet@35967
|
81 |
|
blanchet@35967
|
82 |
type params =
|
blanchet@35967
|
83 |
{debug: bool,
|
blanchet@35967
|
84 |
verbose: bool,
|
blanchet@36141
|
85 |
overlord: bool,
|
blanchet@35967
|
86 |
atps: string list,
|
blanchet@35967
|
87 |
full_types: bool,
|
blanchet@36235
|
88 |
explicit_apply: bool,
|
blanchet@38984
|
89 |
relevance_thresholds: real * real,
|
blanchet@38983
|
90 |
max_relevant: int option,
|
blanchet@36220
|
91 |
theory_relevant: bool option,
|
blanchet@35967
|
92 |
isar_proof: bool,
|
blanchet@36916
|
93 |
isar_shrink_factor: int,
|
blanchet@38813
|
94 |
timeout: Time.time}
|
blanchet@35867
|
95 |
|
blanchet@35867
|
96 |
type problem =
|
blanchet@35967
|
97 |
{subgoal: int,
|
blanchet@35967
|
98 |
goal: Proof.context * (thm list * thm),
|
blanchet@35967
|
99 |
relevance_override: relevance_override,
|
blanchet@38991
|
100 |
axioms: ((string * locality) * thm) list option}
|
blanchet@35867
|
101 |
|
blanchet@35867
|
102 |
type prover_result =
|
blanchet@36370
|
103 |
{outcome: failure option,
|
blanchet@35967
|
104 |
message: string,
|
blanchet@38166
|
105 |
pool: string Symtab.table,
|
blanchet@38991
|
106 |
used_thm_names: (string * locality) list,
|
blanchet@35967
|
107 |
atp_run_time_in_msecs: int,
|
blanchet@36369
|
108 |
output: string,
|
blanchet@35967
|
109 |
proof: string,
|
blanchet@38991
|
110 |
axiom_names: (string * locality) vector,
|
blanchet@38329
|
111 |
conjecture_shape: int list list}
|
blanchet@35867
|
112 |
|
blanchet@38346
|
113 |
type prover = params -> minimize_command -> problem -> prover_result
|
blanchet@35867
|
114 |
|
blanchet@38257
|
115 |
(* configuration attributes *)
|
wenzelm@28484
|
116 |
|
blanchet@38257
|
117 |
val (dest_dir, dest_dir_setup) = Attrib.config_string "atp_dest_dir" (K "");
|
blanchet@38257
|
118 |
(*Empty string means create files in Isabelle's temporary files directory.*)
|
wenzelm@28484
|
119 |
|
blanchet@38257
|
120 |
val (problem_prefix, problem_prefix_setup) =
|
blanchet@38257
|
121 |
Attrib.config_string "atp_problem_prefix" (K "prob");
|
wenzelm@28477
|
122 |
|
blanchet@38257
|
123 |
val (measure_runtime, measure_runtime_setup) =
|
blanchet@38257
|
124 |
Attrib.config_bool "atp_measure_runtime" (K false);
|
wenzelm@32995
|
125 |
|
blanchet@38257
|
126 |
fun with_path cleanup after f path =
|
blanchet@38257
|
127 |
Exn.capture f path
|
blanchet@38257
|
128 |
|> tap (fn _ => cleanup path)
|
blanchet@38257
|
129 |
|> Exn.release
|
blanchet@38257
|
130 |
|> tap (after path)
|
wenzelm@28484
|
131 |
|
blanchet@38257
|
132 |
(* Splits by the first possible of a list of delimiters. *)
|
blanchet@38257
|
133 |
fun extract_proof delims output =
|
blanchet@38257
|
134 |
case pairself (find_first (fn s => String.isSubstring s output))
|
blanchet@38257
|
135 |
(ListPair.unzip delims) of
|
blanchet@38257
|
136 |
(SOME begin_delim, SOME end_delim) =>
|
blanchet@38257
|
137 |
(output |> first_field begin_delim |> the |> snd
|
blanchet@38257
|
138 |
|> first_field end_delim |> the |> fst
|
blanchet@38257
|
139 |
|> first_field "\n" |> the |> snd
|
blanchet@38257
|
140 |
handle Option.Option => "")
|
blanchet@38257
|
141 |
| _ => ""
|
blanchet@38257
|
142 |
|
blanchet@38257
|
143 |
fun extract_proof_and_outcome complete res_code proof_delims known_failures
|
blanchet@38257
|
144 |
output =
|
blanchet@38307
|
145 |
case known_failure_in_output output known_failures of
|
blanchet@38307
|
146 |
NONE => (case extract_proof proof_delims output of
|
blanchet@38307
|
147 |
"" => ("", SOME MalformedOutput)
|
blanchet@38257
|
148 |
| proof => if res_code = 0 then (proof, NONE)
|
blanchet@38257
|
149 |
else ("", SOME UnknownError))
|
blanchet@38307
|
150 |
| SOME failure =>
|
blanchet@38257
|
151 |
("", SOME (if failure = IncompleteUnprovable andalso complete then
|
blanchet@38257
|
152 |
Unprovable
|
blanchet@38257
|
153 |
else
|
blanchet@38257
|
154 |
failure))
|
blanchet@38257
|
155 |
|
blanchet@38257
|
156 |
fun extract_clause_sequence output =
|
blanchet@38257
|
157 |
let
|
blanchet@38257
|
158 |
val tokens_of = String.tokens (not o Char.isAlphaNum)
|
blanchet@38257
|
159 |
fun extract_num ("clause" :: (ss as _ :: _)) =
|
blanchet@38257
|
160 |
Int.fromString (List.last ss)
|
blanchet@38257
|
161 |
| extract_num _ = NONE
|
blanchet@38257
|
162 |
in output |> split_lines |> map_filter (extract_num o tokens_of) end
|
blanchet@38257
|
163 |
|
blanchet@38257
|
164 |
val set_ClauseFormulaRelationN = "set_ClauseFormulaRelation"
|
blanchet@38257
|
165 |
|
blanchet@38257
|
166 |
val parse_clause_formula_pair =
|
blanchet@38740
|
167 |
$$ "(" |-- scan_integer --| $$ ","
|
blanchet@38740
|
168 |
-- (Symbol.scan_id ::: Scan.repeat ($$ "," |-- Symbol.scan_id)) --| $$ ")"
|
blanchet@38257
|
169 |
--| Scan.option ($$ ",")
|
blanchet@38257
|
170 |
val parse_clause_formula_relation =
|
blanchet@38257
|
171 |
Scan.this_string set_ClauseFormulaRelationN |-- $$ "("
|
blanchet@38257
|
172 |
|-- Scan.repeat parse_clause_formula_pair
|
blanchet@38257
|
173 |
val extract_clause_formula_relation =
|
blanchet@38977
|
174 |
Substring.full #> Substring.position set_ClauseFormulaRelationN
|
blanchet@38977
|
175 |
#> snd #> Substring.string #> strip_spaces_except_between_ident_chars
|
blanchet@38977
|
176 |
#> explode #> parse_clause_formula_relation #> fst
|
blanchet@38257
|
177 |
|
blanchet@38257
|
178 |
fun repair_conjecture_shape_and_theorem_names output conjecture_shape
|
blanchet@38937
|
179 |
axiom_names =
|
blanchet@38257
|
180 |
if String.isSubstring set_ClauseFormulaRelationN output then
|
blanchet@38257
|
181 |
(* This is a hack required for keeping track of axioms after they have been
|
blanchet@38937
|
182 |
clausified by SPASS's Flotter tool. The "ATP/scripts/spass" script is
|
blanchet@38937
|
183 |
also part of this hack. *)
|
blanchet@38257
|
184 |
let
|
blanchet@38286
|
185 |
val j0 = hd (hd conjecture_shape)
|
blanchet@38257
|
186 |
val seq = extract_clause_sequence output
|
blanchet@38257
|
187 |
val name_map = extract_clause_formula_relation output
|
blanchet@38257
|
188 |
fun renumber_conjecture j =
|
blanchet@38983
|
189 |
conjecture_prefix ^ string_of_int (j - j0)
|
blanchet@38740
|
190 |
|> AList.find (fn (s, ss) => member (op =) ss s) name_map
|
blanchet@38286
|
191 |
|> map (fn s => find_index (curry (op =) s) seq + 1)
|
blanchet@38937
|
192 |
fun name_for_number j =
|
blanchet@38937
|
193 |
let
|
blanchet@38937
|
194 |
val axioms =
|
blanchet@38987
|
195 |
j |> AList.lookup (op =) name_map |> these
|
blanchet@38987
|
196 |
|> map_filter (try (unprefix axiom_prefix)) |> map unascii_of
|
blanchet@38991
|
197 |
val loc =
|
blanchet@38991
|
198 |
case axioms of
|
blanchet@38991
|
199 |
[axiom] => find_first_in_vector axiom_names axiom General
|
blanchet@38991
|
200 |
| _ => General
|
blanchet@38991
|
201 |
in (axioms |> space_implode " ", loc) end
|
blanchet@38257
|
202 |
in
|
blanchet@38286
|
203 |
(conjecture_shape |> map (maps renumber_conjecture),
|
blanchet@38937
|
204 |
seq |> map name_for_number |> Vector.fromList)
|
blanchet@38257
|
205 |
end
|
blanchet@38257
|
206 |
else
|
blanchet@38937
|
207 |
(conjecture_shape, axiom_names)
|
blanchet@38257
|
208 |
|
blanchet@38257
|
209 |
|
blanchet@38257
|
210 |
(* generic TPTP-based provers *)
|
blanchet@38257
|
211 |
|
blanchet@38699
|
212 |
fun prover_fun atp_name
|
blanchet@38883
|
213 |
{exec, required_execs, arguments, has_incomplete_mode, proof_delims,
|
blanchet@38983
|
214 |
known_failures, default_max_relevant, default_theory_relevant,
|
blanchet@38854
|
215 |
explicit_forall, use_conjecture_for_hypotheses}
|
blanchet@38699
|
216 |
({debug, verbose, overlord, full_types, explicit_apply,
|
blanchet@38984
|
217 |
relevance_thresholds, max_relevant, theory_relevant, isar_proof,
|
blanchet@38984
|
218 |
isar_shrink_factor, timeout, ...} : params)
|
blanchet@38346
|
219 |
minimize_command
|
blanchet@38330
|
220 |
({subgoal, goal, relevance_override, axioms} : problem) =
|
blanchet@38257
|
221 |
let
|
blanchet@38257
|
222 |
val (ctxt, (_, th)) = goal;
|
blanchet@38257
|
223 |
val thy = ProofContext.theory_of ctxt
|
blanchet@38257
|
224 |
val (params, hyp_ts, concl_t) = strip_subgoal th subgoal
|
blanchet@38699
|
225 |
|
blanchet@38983
|
226 |
val print = priority
|
blanchet@38699
|
227 |
fun print_v f = () |> verbose ? print o f
|
blanchet@38699
|
228 |
fun print_d f = () |> debug ? print o f
|
blanchet@38699
|
229 |
|
blanchet@38330
|
230 |
val the_axioms =
|
blanchet@38330
|
231 |
case axioms of
|
blanchet@38329
|
232 |
SOME axioms => axioms
|
blanchet@38699
|
233 |
| NONE =>
|
blanchet@38984
|
234 |
(relevant_facts full_types relevance_thresholds
|
blanchet@38983
|
235 |
(the_default default_max_relevant max_relevant)
|
blanchet@38812
|
236 |
(the_default default_theory_relevant theory_relevant)
|
blanchet@38699
|
237 |
relevance_override goal hyp_ts concl_t
|
blanchet@38699
|
238 |
|> tap ((fn n => print_v (fn () =>
|
blanchet@38984
|
239 |
"Selected " ^ string_of_int n ^ " fact" ^ plural_s n ^
|
blanchet@38984
|
240 |
" for " ^ quote atp_name ^ ".")) o length))
|
blanchet@38257
|
241 |
|
blanchet@38257
|
242 |
(* path to unique problem file *)
|
blanchet@38257
|
243 |
val the_dest_dir = if overlord then getenv "ISABELLE_HOME_USER"
|
blanchet@38257
|
244 |
else Config.get ctxt dest_dir;
|
blanchet@38257
|
245 |
val the_problem_prefix = Config.get ctxt problem_prefix;
|
blanchet@38257
|
246 |
fun prob_pathname nr =
|
blanchet@38257
|
247 |
let
|
blanchet@38257
|
248 |
val probfile =
|
blanchet@38699
|
249 |
Path.basic ((if overlord then "prob_" ^ atp_name
|
blanchet@38257
|
250 |
else the_problem_prefix ^ serial_string ())
|
blanchet@38257
|
251 |
^ "_" ^ string_of_int nr)
|
blanchet@38257
|
252 |
in
|
blanchet@38257
|
253 |
if the_dest_dir = "" then File.tmp_path probfile
|
blanchet@38257
|
254 |
else if File.exists (Path.explode the_dest_dir)
|
blanchet@38257
|
255 |
then Path.append (Path.explode the_dest_dir) probfile
|
blanchet@38257
|
256 |
else error ("No such directory: " ^ the_dest_dir ^ ".")
|
blanchet@38257
|
257 |
end;
|
blanchet@38257
|
258 |
|
blanchet@38983
|
259 |
val measure_run_time = verbose orelse Config.get ctxt measure_runtime
|
blanchet@38338
|
260 |
val command = Path.explode (getenv (fst exec) ^ "/" ^ snd exec)
|
blanchet@38257
|
261 |
(* write out problem file and call prover *)
|
blanchet@38883
|
262 |
fun command_line complete timeout probfile =
|
blanchet@38257
|
263 |
let
|
blanchet@38257
|
264 |
val core = File.shell_path command ^ " " ^ arguments complete timeout ^
|
blanchet@38257
|
265 |
" " ^ File.shell_path probfile
|
blanchet@38257
|
266 |
in
|
blanchet@38983
|
267 |
(if measure_run_time then "TIMEFORMAT='%3U'; { time " ^ core ^ " ; }"
|
blanchet@38983
|
268 |
else "exec " ^ core) ^ " 2>&1"
|
blanchet@38257
|
269 |
end
|
blanchet@38257
|
270 |
fun split_time s =
|
blanchet@38257
|
271 |
let
|
blanchet@38257
|
272 |
val split = String.tokens (fn c => str c = "\n");
|
blanchet@38257
|
273 |
val (output, t) = s |> split |> split_last |> apfst cat_lines;
|
blanchet@38257
|
274 |
fun as_num f = f >> (fst o read_int);
|
blanchet@38257
|
275 |
val num = as_num (Scan.many1 Symbol.is_ascii_digit);
|
blanchet@38257
|
276 |
val digit = Scan.one Symbol.is_ascii_digit;
|
blanchet@38257
|
277 |
val num3 = as_num (digit ::: digit ::: (digit >> single));
|
blanchet@38257
|
278 |
val time = num --| Scan.$$ "." -- num3 >> (fn (a, b) => a * 1000 + b);
|
blanchet@38257
|
279 |
val as_time = the_default 0 o Scan.read Symbol.stopper time o explode;
|
blanchet@38257
|
280 |
in (output, as_time t) end;
|
blanchet@38257
|
281 |
fun run_on probfile =
|
blanchet@38338
|
282 |
case filter (curry (op =) "" o getenv o fst) (exec :: required_execs) of
|
blanchet@38278
|
283 |
(home_var, _) :: _ =>
|
blanchet@38257
|
284 |
error ("The environment variable " ^ quote home_var ^ " is not set.")
|
blanchet@38278
|
285 |
| [] =>
|
blanchet@38278
|
286 |
if File.exists command then
|
blanchet@38278
|
287 |
let
|
blanchet@38883
|
288 |
fun do_run complete timeout =
|
blanchet@38278
|
289 |
let
|
blanchet@38883
|
290 |
val command = command_line complete timeout probfile
|
blanchet@38278
|
291 |
val ((output, msecs), res_code) =
|
blanchet@38278
|
292 |
bash_output command
|
blanchet@38278
|
293 |
|>> (if overlord then
|
blanchet@38278
|
294 |
prefix ("% " ^ command ^ "\n% " ^ timestamp () ^ "\n")
|
blanchet@38278
|
295 |
else
|
blanchet@38278
|
296 |
I)
|
blanchet@38983
|
297 |
|>> (if measure_run_time then split_time else rpair 0)
|
blanchet@38278
|
298 |
val (proof, outcome) =
|
blanchet@38278
|
299 |
extract_proof_and_outcome complete res_code proof_delims
|
blanchet@38278
|
300 |
known_failures output
|
blanchet@38278
|
301 |
in (output, msecs, proof, outcome) end
|
blanchet@38278
|
302 |
val readable_names = debug andalso overlord
|
blanchet@38506
|
303 |
val (problem, pool, conjecture_offset, axiom_names) =
|
blanchet@38506
|
304 |
prepare_problem ctxt readable_names explicit_forall full_types
|
blanchet@38506
|
305 |
explicit_apply hyp_ts concl_t the_axioms
|
blanchet@38854
|
306 |
val ss = strings_for_tptp_problem use_conjecture_for_hypotheses
|
blanchet@38854
|
307 |
problem
|
blanchet@38854
|
308 |
val _ = File.write_list probfile ss
|
blanchet@38278
|
309 |
val conjecture_shape =
|
blanchet@38278
|
310 |
conjecture_offset + 1 upto conjecture_offset + length hyp_ts + 1
|
blanchet@38286
|
311 |
|> map single
|
blanchet@38699
|
312 |
val _ = print_d (fn () => "Running " ^ quote atp_name ^ "...")
|
blanchet@38883
|
313 |
val timer = Timer.startRealTimer ()
|
blanchet@38278
|
314 |
val result =
|
blanchet@38883
|
315 |
do_run false (if has_incomplete_mode then
|
blanchet@38883
|
316 |
Time.fromMilliseconds
|
blanchet@38883
|
317 |
(2 * Time.toMilliseconds timeout div 3)
|
blanchet@38883
|
318 |
else
|
blanchet@38883
|
319 |
timeout)
|
blanchet@38883
|
320 |
|> has_incomplete_mode
|
blanchet@38883
|
321 |
? (fn (_, msecs0, _, SOME _) =>
|
blanchet@38883
|
322 |
do_run true
|
blanchet@38883
|
323 |
(Time.- (timeout, Timer.checkRealTimer timer))
|
blanchet@38883
|
324 |
|> (fn (output, msecs, proof, outcome) =>
|
blanchet@38883
|
325 |
(output, msecs0 + msecs, proof, outcome))
|
blanchet@38883
|
326 |
| result => result)
|
blanchet@38506
|
327 |
in ((pool, conjecture_shape, axiom_names), result) end
|
blanchet@38278
|
328 |
else
|
blanchet@38278
|
329 |
error ("Bad executable: " ^ Path.implode command ^ ".")
|
blanchet@38257
|
330 |
|
blanchet@38257
|
331 |
(* If the problem file has not been exported, remove it; otherwise, export
|
blanchet@38257
|
332 |
the proof file too. *)
|
blanchet@38257
|
333 |
fun cleanup probfile =
|
blanchet@38257
|
334 |
if the_dest_dir = "" then try File.rm probfile else NONE
|
blanchet@38257
|
335 |
fun export probfile (_, (output, _, _, _)) =
|
blanchet@38257
|
336 |
if the_dest_dir = "" then
|
blanchet@38257
|
337 |
()
|
blanchet@38257
|
338 |
else
|
blanchet@38257
|
339 |
File.write (Path.explode (Path.implode probfile ^ "_proof")) output
|
blanchet@38506
|
340 |
val ((pool, conjecture_shape, axiom_names),
|
blanchet@38506
|
341 |
(output, msecs, proof, outcome)) =
|
blanchet@38257
|
342 |
with_path cleanup export run_on (prob_pathname subgoal)
|
blanchet@38506
|
343 |
val (conjecture_shape, axiom_names) =
|
blanchet@38257
|
344 |
repair_conjecture_shape_and_theorem_names output conjecture_shape
|
blanchet@38506
|
345 |
axiom_names
|
blanchet@38257
|
346 |
val (message, used_thm_names) =
|
blanchet@38257
|
347 |
case outcome of
|
blanchet@38257
|
348 |
NONE =>
|
blanchet@38257
|
349 |
proof_text isar_proof
|
blanchet@38257
|
350 |
(pool, debug, isar_shrink_factor, ctxt, conjecture_shape)
|
blanchet@38506
|
351 |
(full_types, minimize_command, proof, axiom_names, th, subgoal)
|
blanchet@38983
|
352 |
|>> (fn message =>
|
blanchet@38983
|
353 |
message ^ (if verbose then
|
blanchet@38983
|
354 |
"\nATP CPU time: " ^ string_of_int msecs ^ " ms."
|
blanchet@38983
|
355 |
else
|
blanchet@38983
|
356 |
""))
|
blanchet@38820
|
357 |
| SOME failure => (string_for_failure failure, [])
|
blanchet@38257
|
358 |
in
|
blanchet@38257
|
359 |
{outcome = outcome, message = message, pool = pool,
|
blanchet@38257
|
360 |
used_thm_names = used_thm_names, atp_run_time_in_msecs = msecs,
|
blanchet@38506
|
361 |
output = output, proof = proof, axiom_names = axiom_names,
|
blanchet@38329
|
362 |
conjecture_shape = conjecture_shape}
|
blanchet@38257
|
363 |
end
|
blanchet@38257
|
364 |
|
blanchet@38257
|
365 |
fun get_prover_fun thy name = prover_fun name (get_prover thy name)
|
wenzelm@28586
|
366 |
|
blanchet@37584
|
367 |
fun start_prover_thread (params as {verbose, full_types, timeout, ...}) i n
|
blanchet@38699
|
368 |
relevance_override minimize_command proof_state
|
blanchet@38699
|
369 |
atp_name =
|
blanchet@36379
|
370 |
let
|
blanchet@38257
|
371 |
val thy = Proof.theory_of proof_state
|
blanchet@37584
|
372 |
val birth_time = Time.now ()
|
blanchet@37584
|
373 |
val death_time = Time.+ (birth_time, timeout)
|
blanchet@38699
|
374 |
val prover = get_prover_fun thy atp_name
|
blanchet@36379
|
375 |
val {context = ctxt, facts, goal} = Proof.goal proof_state;
|
blanchet@36379
|
376 |
val desc =
|
blanchet@38699
|
377 |
"ATP " ^ quote atp_name ^ " for subgoal " ^ string_of_int i ^ ":\n" ^
|
blanchet@36392
|
378 |
Syntax.string_of_term ctxt (Thm.term_of (Thm.cprem_of goal i));
|
blanchet@37584
|
379 |
in
|
blanchet@37585
|
380 |
Async_Manager.launch das_Tool verbose birth_time death_time desc
|
blanchet@37584
|
381 |
(fn () =>
|
blanchet@37584
|
382 |
let
|
blanchet@37584
|
383 |
val problem =
|
blanchet@37584
|
384 |
{subgoal = i, goal = (ctxt, (facts, goal)),
|
blanchet@38330
|
385 |
relevance_override = relevance_override, axioms = NONE}
|
blanchet@37584
|
386 |
in
|
blanchet@38699
|
387 |
prover params (minimize_command atp_name) problem |> #message
|
blanchet@38228
|
388 |
handle ERROR message => "Error: " ^ message ^ "\n"
|
blanchet@38514
|
389 |
| exn => "Internal error: \n" ^ ML_Compiler.exn_message exn ^
|
blanchet@38514
|
390 |
"\n"
|
blanchet@37584
|
391 |
end)
|
blanchet@37584
|
392 |
end
|
wenzelm@28582
|
393 |
|
blanchet@38290
|
394 |
fun run_sledgehammer {atps = [], ...} _ _ _ _ = error "No ATP is set."
|
blanchet@38290
|
395 |
| run_sledgehammer (params as {atps, ...}) i relevance_override
|
blanchet@38290
|
396 |
minimize_command state =
|
blanchet@38290
|
397 |
case subgoal_count state of
|
blanchet@38290
|
398 |
0 => priority "No subgoal!"
|
blanchet@38290
|
399 |
| n =>
|
blanchet@38290
|
400 |
let
|
blanchet@38290
|
401 |
val _ = kill_atps ()
|
blanchet@38290
|
402 |
val _ = priority "Sledgehammering..."
|
blanchet@38290
|
403 |
val _ = app (start_prover_thread params i n relevance_override
|
blanchet@38290
|
404 |
minimize_command state) atps
|
blanchet@38290
|
405 |
in () end
|
blanchet@38290
|
406 |
|
blanchet@38257
|
407 |
val setup =
|
blanchet@38257
|
408 |
dest_dir_setup
|
blanchet@38257
|
409 |
#> problem_prefix_setup
|
blanchet@38257
|
410 |
#> measure_runtime_setup
|
blanchet@38257
|
411 |
|
wenzelm@28582
|
412 |
end;
|