24 val unescape_meta : string -> string |
24 val unescape_meta : string -> string |
25 val unescape_metas : string -> string list |
25 val unescape_metas : string -> string list |
26 val extract_query : string -> string * string list |
26 val extract_query : string -> string * string list |
27 val suggested_facts : string list -> fact list -> fact list |
27 val suggested_facts : string list -> fact list -> fact list |
28 val mesh_facts : int -> (fact list * int option) list -> fact list |
28 val mesh_facts : int -> (fact list * int option) list -> fact list |
29 val is_likely_tautology : thm -> bool |
29 val is_likely_tautology : Proof.context -> string -> thm -> bool |
30 val is_too_meta : thm -> bool |
30 val is_too_meta : thm -> bool |
31 val theory_ord : theory * theory -> order |
31 val theory_ord : theory * theory -> order |
32 val thm_ord : thm * thm -> order |
32 val thm_ord : thm * thm -> order |
33 val features_of : theory -> status -> term list -> string list |
33 val features_of : |
|
34 Proof.context -> string -> theory -> status -> term list -> string list |
34 val isabelle_dependencies_of : unit Symtab.table -> thm -> string list |
35 val isabelle_dependencies_of : unit Symtab.table -> thm -> string list |
35 val goal_of_thm : theory -> thm -> thm |
36 val goal_of_thm : theory -> thm -> thm |
36 val run_prover : Proof.context -> params -> fact list -> thm -> prover_result |
37 val run_prover : |
|
38 Proof.context -> params -> string -> fact list -> thm -> prover_result |
37 val mash_RESET : Proof.context -> unit |
39 val mash_RESET : Proof.context -> unit |
38 val mash_INIT : |
40 val mash_INIT : |
39 Proof.context -> bool |
41 Proof.context -> bool |
40 -> (string * string list * string list * string list) list -> unit |
42 -> (string * string list * string list * string list) list -> unit |
41 val mash_ADD : |
43 val mash_ADD : |
42 Proof.context -> bool |
44 Proof.context -> bool |
43 -> (string * string list * string list * string list) list -> unit |
45 -> (string * string list * string list * string list) list -> unit |
44 val mash_QUERY : |
46 val mash_QUERY : |
45 Proof.context -> bool -> string list * string list -> string list |
47 Proof.context -> bool -> int -> string list * string list -> string list |
46 val mash_reset : Proof.context -> unit |
48 val mash_reset : Proof.context -> unit |
47 val mash_can_suggest_facts : Proof.context -> bool |
49 val mash_could_suggest_facts : unit -> bool |
|
50 val mash_can_suggest_facts : unit -> bool |
48 val mash_suggest_facts : |
51 val mash_suggest_facts : |
49 Proof.context -> params -> string -> term list -> term -> fact list |
52 Proof.context -> params -> string -> int -> term list -> term -> fact list |
50 -> fact list |
53 -> fact list |
51 val mash_learn_thy : Proof.context -> params -> theory -> real -> unit |
54 val mash_learn_thy : Proof.context -> params -> theory -> Time.time -> unit |
52 val mash_learn_proof : |
55 val mash_learn_proof : |
53 Proof.context -> params -> term -> thm list -> fact list -> unit |
56 Proof.context -> params -> term -> thm list -> fact list -> unit |
54 val relevant_facts : |
57 val relevant_facts : |
55 Proof.context -> params -> string -> int -> fact_override -> term list |
58 Proof.context -> params -> string -> int -> fact_override -> term list |
56 -> term -> fact list -> fact list |
59 -> term -> fact list -> fact list |
184 has_bool_arg_const t orelse exists_Const (higher_inst_const thy) t) |
188 has_bool_arg_const t orelse exists_Const (higher_inst_const thy) t) |
185 end |
189 end |
186 |
190 |
187 end |
191 end |
188 |
192 |
189 fun interesting_terms_types_and_classes term_max_depth type_max_depth ts = |
193 fun interesting_terms_types_and_classes ctxt prover term_max_depth |
|
194 type_max_depth ts = |
190 let |
195 let |
191 val bad_types = [@{type_name prop}, @{type_name bool}, @{type_name fun}] |
196 val bad_types = [@{type_name prop}, @{type_name bool}, @{type_name fun}] |
192 val bad_consts = atp_widely_irrelevant_consts |
197 fun is_bad_const (x as (s, _)) args = |
|
198 member (op =) atp_logical_consts s orelse |
|
199 fst (is_built_in_const_for_prover ctxt prover x args) |
193 fun add_classes @{sort type} = I |
200 fun add_classes @{sort type} = I |
194 | add_classes S = union (op =) (map class_name_of S) |
201 | add_classes S = union (op =) (map class_name_of S) |
195 fun do_add_type (Type (s, Ts)) = |
202 fun do_add_type (Type (s, Ts)) = |
196 (not (member (op =) bad_types s) ? insert (op =) (type_name_of s)) |
203 (not (member (op =) bad_types s) ? insert (op =) (type_name_of s)) |
197 #> fold do_add_type Ts |
204 #> fold do_add_type Ts |
213 #> add_term_patterns (depth - 1) t |
220 #> add_term_patterns (depth - 1) t |
214 val add_term = add_term_patterns term_max_depth |
221 val add_term = add_term_patterns term_max_depth |
215 fun add_patterns t = |
222 fun add_patterns t = |
216 let val (head, args) = strip_comb t in |
223 let val (head, args) = strip_comb t in |
217 (case head of |
224 (case head of |
218 Const (s, T) => |
225 Const (x as (_, T)) => |
219 not (member (op =) bad_consts s) ? (add_term t #> add_type T) |
226 not (is_bad_const x args) ? (add_term t #> add_type T) |
220 | Free (_, T) => add_type T |
227 | Free (_, T) => add_type T |
221 | Var (_, T) => add_type T |
228 | Var (_, T) => add_type T |
222 | Abs (_, T, body) => add_type T #> add_patterns body |
229 | Abs (_, T, body) => add_type T #> add_patterns body |
223 | _ => I) |
230 | _ => I) |
224 #> fold add_patterns args |
231 #> fold add_patterns args |
225 end |
232 end |
226 in [] |> fold add_patterns ts |> sort string_ord end |
233 in [] |> fold add_patterns ts |> sort string_ord end |
227 |
234 |
228 fun is_likely_tautology th = |
235 fun is_likely_tautology ctxt prover th = |
229 null (interesting_terms_types_and_classes 0 ~1 [prop_of th]) andalso |
236 null (interesting_terms_types_and_classes ctxt prover 0 ~1 [prop_of th]) |
230 not (Thm.eq_thm_prop (@{thm ext}, th)) |
237 andalso not (Thm.eq_thm_prop (@{thm ext}, th)) |
231 |
238 |
232 (* ### FIXME: optimize *) |
239 (* ### FIXME: optimize *) |
233 fun is_too_meta th = |
240 fun is_too_meta th = |
234 fastype_of (Object_Logic.atomize_term (theory_of_thm th) (prop_of th)) |
241 fastype_of (Object_Logic.atomize_term (theory_of_thm th) (prop_of th)) |
235 <> @{typ bool} |
242 <> @{typ bool} |
280 | freeze (Free (s, T)) = Free (s, freezeT T) |
288 | freeze (Free (s, T)) = Free (s, freezeT T) |
281 | freeze t = t |
289 | freeze t = t |
282 |
290 |
283 fun goal_of_thm thy = prop_of #> freeze #> cterm_of thy #> Goal.init |
291 fun goal_of_thm thy = prop_of #> freeze #> cterm_of thy #> Goal.init |
284 |
292 |
285 fun run_prover ctxt (params as {provers, ...}) facts goal = |
293 fun run_prover ctxt params prover facts goal = |
286 let |
294 let |
287 val problem = |
295 val problem = |
288 {state = Proof.init ctxt, goal = goal, subgoal = 1, subgoal_count = 1, |
296 {state = Proof.init ctxt, goal = goal, subgoal = 1, subgoal_count = 1, |
289 facts = facts |> map (apfst (apfst (fn name => name ()))) |
297 facts = facts |> map (apfst (apfst (fn name => name ()))) |
290 |> map Sledgehammer_Provers.Untranslated_Fact} |
298 |> map Untranslated_Fact} |
291 val prover = |
299 val prover = get_minimizing_prover ctxt Normal prover |
292 Sledgehammer_Minimize.get_minimizing_prover ctxt |
|
293 Sledgehammer_Provers.Normal (hd provers) |
|
294 in prover params (K (K (K ""))) problem end |
300 in prover params (K (K (K ""))) problem end |
295 |
301 |
296 |
302 |
297 (*** Low-level communication with MaSh ***) |
303 (*** Low-level communication with MaSh ***) |
298 |
304 |
299 val max_preds = 500 |
305 fun write_file write file = |
|
306 let val path = Path.explode file in |
|
307 File.write path ""; write (File.append path) |
|
308 end |
300 |
309 |
301 fun mash_info overlord = |
310 fun mash_info overlord = |
302 if overlord then (getenv "ISABELLE_HOME_USER", "") |
311 if overlord then (getenv "ISABELLE_HOME_USER", "") |
303 else (getenv "ISABELLE_TMP", serial_string ()) |
312 else (getenv "ISABELLE_TMP", serial_string ()) |
304 |
313 |
329 write_file write_feats (in_dir ^ "/mash_features"); |
335 write_file write_feats (in_dir ^ "/mash_features"); |
330 write_file write_deps (in_dir ^ "/mash_dependencies"); |
336 write_file write_deps (in_dir ^ "/mash_dependencies"); |
331 run_mash ctxt info ("--init --inputDir " ^ in_dir) |
337 run_mash ctxt info ("--init --inputDir " ^ in_dir) |
332 end |
338 end |
333 |
339 |
334 fun run_mash_commands ctxt overlord save write_cmds read_preds = |
340 fun run_mash_commands ctxt overlord save max_suggs write_cmds read_suggs = |
335 let |
341 let |
336 val info as (temp_dir, serial) = mash_info overlord |
342 val info as (temp_dir, serial) = mash_info overlord |
|
343 val sugg_file = temp_dir ^ "/mash_suggs" ^ serial |
337 val cmd_file = temp_dir ^ "/mash_commands" ^ serial |
344 val cmd_file = temp_dir ^ "/mash_commands" ^ serial |
338 val pred_file = temp_dir ^ "/mash_preds" ^ serial |
|
339 in |
345 in |
|
346 write_file (K ()) sugg_file; |
340 write_file write_cmds cmd_file; |
347 write_file write_cmds cmd_file; |
341 run_mash ctxt info |
348 run_mash ctxt info |
342 ("--inputFile " ^ cmd_file ^ " --predictions " ^ pred_file ^ |
349 ("--inputFile " ^ cmd_file ^ " --predictions " ^ sugg_file ^ |
343 " --numberOfPredictions " ^ string_of_int max_preds ^ |
350 " --numberOfPredictions " ^ string_of_int max_suggs ^ |
344 (if save then " --saveModel" else "")); |
351 (if save then " --saveModel" else "")); |
345 read_preds (fn () => File.read_lines (Path.explode pred_file)) |
352 read_suggs (fn () => File.read_lines (Path.explode sugg_file)) |
346 end |
353 end |
347 |
354 |
348 fun str_of_update (name, parents, feats, deps) = |
355 fun str_of_update (name, parents, feats, deps) = |
349 "! " ^ escape_meta name ^ ": " ^ escape_metas parents ^ "; " ^ |
356 "! " ^ escape_meta name ^ ": " ^ escape_metas parents ^ "; " ^ |
350 escape_metas feats ^ "; " ^ escape_metas deps ^ "\n" |
357 escape_metas feats ^ "; " ^ escape_metas deps ^ "\n" |
374 |
381 |
375 fun mash_ADD _ _ [] = () |
382 fun mash_ADD _ _ [] = () |
376 | mash_ADD ctxt overlord upds = |
383 | mash_ADD ctxt overlord upds = |
377 (trace_msg ctxt (fn () => "MaSh ADD " ^ |
384 (trace_msg ctxt (fn () => "MaSh ADD " ^ |
378 elide_string 1000 (space_implode " " (map #1 upds))); |
385 elide_string 1000 (space_implode " " (map #1 upds))); |
379 run_mash_commands ctxt overlord true |
386 run_mash_commands ctxt overlord true 0 |
380 (fn append => List.app (append o str_of_update) upds) (K ())) |
387 (fn append => List.app (append o str_of_update) upds) (K ())) |
381 |
388 |
382 fun mash_QUERY ctxt overlord (query as (_, feats)) = |
389 fun mash_QUERY ctxt overlord max_suggs (query as (_, feats)) = |
383 (trace_msg ctxt (fn () => "MaSh QUERY " ^ space_implode " " feats); |
390 (trace_msg ctxt (fn () => "MaSh QUERY " ^ space_implode " " feats); |
384 run_mash_commands ctxt overlord false |
391 run_mash_commands ctxt overlord false max_suggs |
385 (fn append => append (str_of_query query)) |
392 (fn append => append (str_of_query query)) |
386 (fn preds => snd (extract_query (List.last (preds ())))) |
393 (fn suggs => snd (extract_query (List.last (suggs ())))) |
387 handle List.Empty => []) |
394 handle List.Empty => []) |
388 |
395 |
389 |
396 |
390 (*** High-level communication with MaSh ***) |
397 (*** High-level communication with MaSh ***) |
391 |
398 |
421 |
428 |
422 fun mash_save ({thys, fact_graph, ...} : mash_state) = |
429 fun mash_save ({thys, fact_graph, ...} : mash_state) = |
423 let |
430 let |
424 val path = mash_state_path () |
431 val path = mash_state_path () |
425 val thys = Symtab.dest thys |
432 val thys = Symtab.dest thys |
426 fun line_for_thys comp = AList.find (op =) thys comp |> escape_metas |
433 val line_for_thys = escape_metas o AList.find (op =) thys |
427 fun fact_line_for name parents = name :: parents |> escape_metas |
434 fun fact_line_for name parents = |
|
435 escape_meta name ^ ": " ^ escape_metas parents |
428 val append_fact = File.append path o suffix "\n" oo fact_line_for |
436 val append_fact = File.append path o suffix "\n" oo fact_line_for |
429 in |
437 in |
430 File.write path (line_for_thys true ^ "\n" ^ line_for_thys false ^ "\n"); |
438 File.write path (line_for_thys true ^ "\n" ^ line_for_thys false ^ "\n"); |
431 Graph.fold (fn (name, ((), (parents, _))) => fn () => |
439 Graph.fold (fn (name, ((), (parents, _))) => fn () => |
432 append_fact name (Graph.Keys.dest parents)) |
440 append_fact name (Graph.Keys.dest parents)) |
448 (mash_RESET ctxt; File.write (mash_state_path ()) ""; |
456 (mash_RESET ctxt; File.write (mash_state_path ()) ""; |
449 (true, empty_state))) |
457 (true, empty_state))) |
450 |
458 |
451 end |
459 end |
452 |
460 |
453 fun mash_can_suggest_facts (_ : Proof.context) = |
461 fun mash_could_suggest_facts () = mash_home () <> "" |
454 mash_home () <> "" andalso not (Graph.is_empty (#fact_graph (mash_get ()))) |
462 fun mash_can_suggest_facts () = not (Graph.is_empty (#fact_graph (mash_get ()))) |
455 |
463 |
456 fun parents_wrt facts fact_graph = |
464 fun parents_wrt_facts facts fact_graph = |
457 let |
465 let |
|
466 val graph_facts = Symtab.make (map (rpair ()) (Graph.keys fact_graph)) |
458 val facts = |
467 val facts = |
459 Symtab.empty |
468 [] |> fold (cons o Thm.get_name_hint o snd) facts |
460 |> fold (fn (_, th) => Symtab.update (Thm.get_name_hint th, ())) facts |
469 |> filter (Symtab.defined graph_facts) |
|
470 |> Graph.all_preds fact_graph |
|
471 val facts = Symtab.empty |> fold (fn name => Symtab.update (name, ())) facts |
461 in fact_graph |> Graph.restrict (Symtab.defined facts) |> Graph.maximals end |
472 in fact_graph |> Graph.restrict (Symtab.defined facts) |> Graph.maximals end |
462 |
473 |
463 fun mash_suggest_facts ctxt ({overlord, ...} : params) prover hyp_ts concl_t |
474 (* Generate more suggestions than requested, because some might be thrown out |
464 facts = |
475 later for various reasons and "meshing" gives better results with some |
|
476 slack. *) |
|
477 fun max_suggs_of max_facts = max_facts + Int.min (200, max_facts) |
|
478 |
|
479 fun mash_suggest_facts ctxt ({overlord, ...} : params) prover max_facts hyp_ts |
|
480 concl_t facts = |
465 let |
481 let |
466 val thy = Proof_Context.theory_of ctxt |
482 val thy = Proof_Context.theory_of ctxt |
467 val fact_graph = #fact_graph (mash_get ()) |
483 val fact_graph = #fact_graph (mash_get ()) |
468 val parents = parents_wrt facts fact_graph |
484 val _ = warning (PolyML.makestring (length (fact_graph |> Graph.keys), length (fact_graph |> Graph.maximals), |
469 val feats = features_of thy General (concl_t :: hyp_ts) |
485 length (fact_graph |> Graph.minimals))) (*###*) |
470 val suggs = mash_QUERY ctxt overlord (parents, feats) |
486 val parents = parents_wrt_facts facts fact_graph |
|
487 val feats = features_of ctxt prover thy General (concl_t :: hyp_ts) |
|
488 val suggs = |
|
489 mash_QUERY ctxt overlord (max_suggs_of max_facts) (parents, feats) |
471 in suggested_facts suggs facts end |
490 in suggested_facts suggs facts end |
472 |
491 |
473 fun add_thys_for thy = |
492 fun add_thys_for thy = |
474 let fun add comp thy = Symtab.update (Context.theory_name thy, comp) in |
493 let fun add comp thy = Symtab.update (Context.theory_name thy, comp) in |
475 add false thy #> fold (add true) (Theory.ancestors_of thy) |
494 add false thy #> fold (add true) (Theory.ancestors_of thy) |
487 val graph = graph |> Graph.new_node (name, ()) |
506 val graph = graph |> Graph.new_node (name, ()) |
488 val (parents, graph) = ([], graph) |> fold maybe_add_from parents |
507 val (parents, graph) = ([], graph) |> fold maybe_add_from parents |
489 val (deps, graph) = ([], graph) |> fold maybe_add_from deps |
508 val (deps, graph) = ([], graph) |> fold maybe_add_from deps |
490 in ((name, parents, feats, deps) :: upds, graph) end |
509 in ((name, parents, feats, deps) :: upds, graph) end |
491 |
510 |
492 fun mash_learn_thy ctxt ({overlord, ...} : params) thy timeout = |
511 val pass1_learn_timeout_factor = 0.5 |
493 let |
512 val pass2_learn_timeout_factor = 10.0 |
494 val css_table = Sledgehammer_Fact.clasimpset_rule_table_of ctxt |
513 |
|
514 (* The timeout is understood in a very slack fashion. *) |
|
515 fun mash_learn_thy ctxt ({provers, verbose, overlord, ...} : params) thy |
|
516 timeout = |
|
517 let |
|
518 val timer = Timer.startRealTimer () |
|
519 val prover = hd provers |
|
520 fun timed_out frac = |
|
521 Time.> (Timer.checkRealTimer timer, time_mult frac timeout) |
|
522 val css_table = clasimpset_rule_table_of ctxt |
495 val facts = all_facts_of thy css_table |
523 val facts = all_facts_of thy css_table |
496 val {fact_graph, ...} = mash_get () |
524 val {fact_graph, ...} = mash_get () |
497 fun is_old (_, th) = can (Graph.get_node fact_graph) (Thm.get_name_hint th) |
525 fun is_old (_, th) = can (Graph.get_node fact_graph) (Thm.get_name_hint th) |
498 val new_facts = facts |> filter_out is_old |> sort (thm_ord o pairself snd) |
526 val new_facts = facts |> filter_out is_old |> sort (thm_ord o pairself snd) |
499 in |
527 in |
500 if null new_facts then |
528 if null new_facts then |
501 () |
529 () |
502 else |
530 else |
503 let |
531 let |
|
532 val n = length new_facts |
|
533 val _ = |
|
534 if verbose then |
|
535 "MaShing " ^ string_of_int n ^ " fact" ^ plural_s n ^ |
|
536 " (advisory timeout: " ^ string_from_time timeout ^ ")..." |
|
537 |> Output.urgent_message |
|
538 else |
|
539 () |
504 val ths = facts |> map snd |
540 val ths = facts |> map snd |
505 val all_names = |
541 val all_names = |
506 ths |> filter_out (is_likely_tautology orf is_too_meta) |
542 ths |> filter_out (is_likely_tautology ctxt prover orf is_too_meta) |
507 |> map (rpair () o Thm.get_name_hint) |
543 |> map (rpair () o Thm.get_name_hint) |
508 |> Symtab.make |
544 |> Symtab.make |
509 fun do_fact ((_, (_, status)), th) (parents, upds) = |
545 fun do_fact _ (accum as (_, true)) = accum |
510 let |
546 | do_fact ((_, (_, status)), th) ((parents, upds), false) = |
511 val name = Thm.get_name_hint th |
547 let |
512 val feats = features_of thy status [prop_of th] |
548 val name = Thm.get_name_hint th |
513 val deps = isabelle_dependencies_of all_names th |
549 val feats = features_of ctxt prover thy status [prop_of th] |
514 val upd = (name, parents, feats, deps) |
550 val deps = isabelle_dependencies_of all_names th |
515 in ([name], upd :: upds) end |
551 val upd = (name, parents, feats, deps) |
516 val parents = parents_wrt facts fact_graph |
552 in (([name], upd :: upds), timed_out pass1_learn_timeout_factor) end |
517 val (_, upds) = (parents, []) |> fold do_fact new_facts ||> rev |
553 val parents = parents_wrt_facts facts fact_graph |
|
554 val ((_, upds), _) = |
|
555 ((parents, []), false) |> fold do_fact new_facts |>> apsnd rev |
|
556 val n = length upds |
518 fun trans {thys, fact_graph} = |
557 fun trans {thys, fact_graph} = |
519 let |
558 let |
520 val mash_INIT_or_ADD = |
559 val mash_INIT_or_ADD = |
521 if Graph.is_empty fact_graph then mash_INIT else mash_ADD |
560 if Graph.is_empty fact_graph then mash_INIT else mash_ADD |
522 val (upds, fact_graph) = |
561 val (upds, fact_graph) = |
524 in |
563 in |
525 (mash_INIT_or_ADD ctxt overlord (rev upds); |
564 (mash_INIT_or_ADD ctxt overlord (rev upds); |
526 {thys = thys |> add_thys_for thy, |
565 {thys = thys |> add_thys_for thy, |
527 fact_graph = fact_graph}) |
566 fact_graph = fact_graph}) |
528 end |
567 end |
529 in mash_map trans end |
568 in |
530 end |
569 TimeLimit.timeLimit (time_mult pass2_learn_timeout_factor timeout) |
531 |
570 mash_map trans |
532 fun mash_learn_proof ctxt ({overlord, ...} : params) t used_ths facts = |
571 handle TimeLimit.TimeOut => |
|
572 (if verbose then |
|
573 "MaSh timed out trying to learn " ^ string_of_int n ^ |
|
574 " fact" ^ plural_s n ^ " in " ^ |
|
575 string_from_time (Timer.checkRealTimer timer) ^ "." |
|
576 |> Output.urgent_message |
|
577 else |
|
578 ()); |
|
579 (if verbose then |
|
580 "MaSh learned " ^ string_of_int n ^ " fact" ^ plural_s n ^ " in " ^ |
|
581 string_from_time (Timer.checkRealTimer timer) ^ "." |
|
582 |> Output.urgent_message |
|
583 else |
|
584 ()) |
|
585 end |
|
586 end |
|
587 |
|
588 fun mash_learn_proof ctxt ({provers, overlord, ...} : params) t used_ths facts = |
533 let |
589 let |
534 val thy = Proof_Context.theory_of ctxt |
590 val thy = Proof_Context.theory_of ctxt |
535 val name = ATP_Util.timestamp () (* should be fairly fresh *) |
591 val prover = hd provers |
536 val feats = features_of thy General [t] |
592 val name = ATP_Util.timestamp () ^ serial_string () (* fresh enough *) |
|
593 val feats = features_of ctxt prover thy General [t] |
537 val deps = used_ths |> map Thm.get_name_hint |
594 val deps = used_ths |> map Thm.get_name_hint |
538 in |
595 in |
539 mash_map (fn {thys, fact_graph} => |
596 mash_map (fn {thys, fact_graph} => |
540 let |
597 let |
541 val parents = parents_wrt facts fact_graph |
598 val parents = parents_wrt_facts facts fact_graph |
542 val upds = [(name, parents, feats, deps)] |
599 val upds = [(name, parents, feats, deps)] |
543 val (upds, fact_graph) = |
600 val (upds, fact_graph) = |
544 ([], fact_graph) |> fold (update_fact_graph ctxt) upds |
601 ([], fact_graph) |> fold (update_fact_graph ctxt) upds |
545 in |
602 in |
546 mash_ADD ctxt overlord upds; |
603 mash_ADD ctxt overlord upds; |
547 {thys = thys, fact_graph = fact_graph} |
604 {thys = thys, fact_graph = fact_graph} |
548 end) |
605 end) |
549 end |
606 end |
550 |
607 |
551 fun relevant_facts ctxt (params as {fact_filter, ...}) prover max_facts |
608 (* The threshold should be large enough so that MaSh doesn't kick in for Auto |
|
609 Sledgehammer and Try. *) |
|
610 val min_secs_for_learning = 15 |
|
611 val short_learn_timeout_factor = 0.2 |
|
612 val long_learn_timeout_factor = 4.0 |
|
613 |
|
614 fun relevant_facts ctxt (params as {fact_filter, timeout, ...}) prover max_facts |
552 ({add, only, ...} : fact_override) hyp_ts concl_t facts = |
615 ({add, only, ...} : fact_override) hyp_ts concl_t facts = |
553 if not (subset (op =) (the_list fact_filter, fact_filters)) then |
616 if not (subset (op =) (the_list fact_filter, fact_filters)) then |
554 error ("Unknown fact filter: " ^ quote (the fact_filter) ^ ".") |
617 error ("Unknown fact filter: " ^ quote (the fact_filter) ^ ".") |
555 else if only then |
618 else if only then |
556 facts |
619 facts |
557 else if max_facts <= 0 then |
620 else if max_facts <= 0 then |
558 [] |
621 [] |
559 else |
622 else |
560 let |
623 let |
|
624 val thy = Proof_Context.theory_of ctxt |
|
625 fun maybe_learn can_suggest = |
|
626 if Time.toSeconds timeout >= min_secs_for_learning then |
|
627 if Multithreading.enabled () then |
|
628 let |
|
629 val factor = |
|
630 if can_suggest then short_learn_timeout_factor |
|
631 else long_learn_timeout_factor |
|
632 in |
|
633 Future.fork (fn () => mash_learn_thy ctxt params thy |
|
634 (time_mult factor timeout)); () |
|
635 end |
|
636 else |
|
637 mash_learn_thy ctxt params thy |
|
638 (time_mult short_learn_timeout_factor timeout) |
|
639 else |
|
640 () |
561 val fact_filter = |
641 val fact_filter = |
562 case fact_filter of |
642 case fact_filter of |
563 SOME ff => ff |
643 SOME ff => |
564 | NONE => if mash_can_suggest_facts ctxt then meshN else iterN |
644 (if ff <> iterN then maybe_learn (mash_can_suggest_facts ()) else (); |
|
645 ff) |
|
646 | NONE => |
|
647 if mash_can_suggest_facts () then (maybe_learn true; meshN) |
|
648 else if mash_could_suggest_facts () then (maybe_learn false; iterN) |
|
649 else iterN |
565 val add_ths = Attrib.eval_thms ctxt add |
650 val add_ths = Attrib.eval_thms ctxt add |
566 fun prepend_facts ths accepts = |
651 fun prepend_facts ths accepts = |
567 ((facts |> filter (member Thm.eq_thm_prop ths o snd)) @ |
652 ((facts |> filter (member Thm.eq_thm_prop ths o snd)) @ |
568 (accepts |> filter_out (member Thm.eq_thm_prop ths o snd))) |
653 (accepts |> filter_out (member Thm.eq_thm_prop ths o snd))) |
569 |> take max_facts |
654 |> take max_facts |
570 fun iter () = |
655 fun iter () = |
571 iterative_relevant_facts ctxt params prover max_facts NONE hyp_ts |
656 iterative_relevant_facts ctxt params prover max_facts NONE hyp_ts |
572 concl_t facts |
657 concl_t facts |
573 |> (fn facts => (facts, SOME (length facts))) |
658 |> (fn facts => (facts, SOME (length facts))) |
574 fun mash () = |
659 fun mash () = |
575 (facts |> mash_suggest_facts ctxt params prover hyp_ts concl_t, NONE) |
660 (mash_suggest_facts ctxt params prover max_facts hyp_ts concl_t facts, |
|
661 NONE) |
576 val mess = |
662 val mess = |
577 [] |> (if fact_filter <> mashN then cons (iter ()) else I) |
663 [] |> (if fact_filter <> mashN then cons (iter ()) else I) |
578 |> (if fact_filter <> iterN then cons (mash ()) else I) |
664 |> (if fact_filter <> iterN then cons (mash ()) else I) |
579 in |
665 in |
580 mesh_facts max_facts mess |
666 mesh_facts max_facts mess |