176 " >& " ^ err_file ^ |
176 " >& " ^ err_file ^ |
177 (if background then " &" else "") |
177 (if background then " &" else "") |
178 fun run_on () = |
178 fun run_on () = |
179 (Isabelle_System.bash command |
179 (Isabelle_System.bash command |
180 |> tap (fn _ => |
180 |> tap (fn _ => |
181 case try File.read (Path.explode err_file) |> the_default "" of |
181 (case try File.read (Path.explode err_file) |> the_default "" of |
182 "" => trace_msg ctxt (K "Done") |
182 "" => trace_msg ctxt (K "Done") |
183 | s => warning ("MaSh error: " ^ elide_string 1000 s)); |
183 | s => warning ("MaSh error: " ^ elide_string 1000 s))); |
184 read_suggs (fn () => try File.read_lines sugg_path |> these)) |
184 read_suggs (fn () => try File.read_lines sugg_path |> these)) |
185 fun clean_up () = |
185 fun clean_up () = |
186 if overlord then () |
186 if overlord then () |
187 else List.app wipe_out_file [err_file, sugg_file, cmd_file] |
187 else List.app wipe_out_file [err_file, sugg_file, cmd_file] |
188 in |
188 in |
241 encode_features feats ^ |
241 encode_features feats ^ |
242 (if null hints then "" else "; " ^ encode_strs hints) ^ "\n" |
242 (if null hints then "" else "; " ^ encode_strs hints) ^ "\n" |
243 |
243 |
244 (* The suggested weights don't make much sense. *) |
244 (* The suggested weights don't make much sense. *) |
245 fun extract_suggestion sugg = |
245 fun extract_suggestion sugg = |
246 case space_explode "=" sugg of |
246 (case space_explode "=" sugg of |
247 [name, _ (* weight *)] => |
247 [name, _ (* weight *)] => |
248 SOME (unencode_str name (* , Real.fromString weight |> the_default 1.0 *)) |
248 SOME (unencode_str name (* , Real.fromString weight |> the_default 1.0 *)) |
249 | [name] => SOME (unencode_str name (* , 1.0 *)) |
249 | [name] => SOME (unencode_str name (* , 1.0 *)) |
250 | _ => NONE |
250 | _ => NONE) |
251 |
251 |
252 fun extract_suggestions line = |
252 fun extract_suggestions line = |
253 case space_explode ":" line of |
253 (case space_explode ":" line of |
254 [goal, suggs] => |
254 [goal, suggs] => (unencode_str goal, map_filter extract_suggestion (space_explode " " suggs)) |
255 (unencode_str goal, map_filter extract_suggestion (space_explode " " suggs)) |
255 | _ => ("", [])) |
256 | _ => ("", []) |
|
257 |
256 |
258 structure MaSh = |
257 structure MaSh = |
259 struct |
258 struct |
260 |
259 |
261 fun shutdown ctxt overlord = |
260 fun shutdown ctxt overlord = |
292 run_mash_tool ctxt overlord ([] |> save ? cons save_models_arg) false |
291 run_mash_tool ctxt overlord ([] |> save ? cons save_models_arg) false |
293 (relearns, str_of_relearn) (K ())) |
292 (relearns, str_of_relearn) (K ())) |
294 |
293 |
295 fun query ctxt overlord max_suggs (query as (_, _, _, feats)) = |
294 fun query ctxt overlord max_suggs (query as (_, _, _, feats)) = |
296 (trace_msg ctxt (fn () => "MaSh query " ^ encode_features feats); |
295 (trace_msg ctxt (fn () => "MaSh query " ^ encode_features feats); |
297 run_mash_tool ctxt overlord [] false ([query], str_of_query max_suggs) |
296 run_mash_tool ctxt overlord [] false ([query], str_of_query max_suggs) (fn suggs => |
298 (fn suggs => |
297 (case suggs () of |
299 case suggs () of |
298 [] => [] |
300 [] => [] |
299 | suggs => snd (extract_suggestions (List.last suggs)))) |
301 | suggs => snd (extract_suggestions (List.last suggs))) |
|
302 handle List.Empty => []) |
300 handle List.Empty => []) |
303 |
301 |
304 end; |
302 end; |
305 |
303 |
306 |
304 |
360 val version = "*** MaSh version 20131206 ***" |
358 val version = "*** MaSh version 20131206 ***" |
361 |
359 |
362 exception FILE_VERSION_TOO_NEW of unit |
360 exception FILE_VERSION_TOO_NEW of unit |
363 |
361 |
364 fun extract_node line = |
362 fun extract_node line = |
365 case space_explode ":" line of |
363 (case space_explode ":" line of |
366 [head, parents] => |
364 [head, parents] => |
367 (case space_explode " " head of |
365 (case space_explode " " head of |
368 [kind, name] => |
366 [kind, name] => |
369 SOME (unencode_str name, unencode_strs parents, |
367 SOME (unencode_str name, unencode_strs parents, |
370 try proof_kind_of_str kind |> the_default Isar_Proof) |
368 try proof_kind_of_str kind |> the_default Isar_Proof) |
371 | _ => NONE) |
369 | _ => NONE) |
372 | _ => NONE |
370 | _ => NONE) |
373 |
371 |
374 fun load_state _ _ (state as (true, _)) = state |
372 fun load_state _ _ (state as (true, _)) = state |
375 | load_state ctxt overlord _ = |
373 | load_state ctxt overlord _ = |
376 let val path = mash_state_file () in |
374 let val path = mash_state_file () in |
377 (true, |
375 (true, |
378 case try File.read_lines path of |
376 (case try File.read_lines path of |
379 SOME (version' :: node_lines) => |
377 SOME (version' :: node_lines) => |
380 let |
378 let |
381 fun add_edge_to name parent = |
379 fun add_edge_to name parent = |
382 Graph.default_node (parent, Isar_Proof) |
380 Graph.default_node (parent, Isar_Proof) |
383 #> Graph.add_edge (parent, name) |
381 #> Graph.add_edge (parent, name) |
384 fun add_node line = |
382 fun add_node line = |
385 case extract_node line of |
383 (case extract_node line of |
386 NONE => I (* shouldn't happen *) |
384 NONE => I (* shouldn't happen *) |
387 | SOME (name, parents, kind) => |
385 | SOME (name, parents, kind) => |
388 update_access_graph_node (name, kind) |
386 update_access_graph_node (name, kind) #> fold (add_edge_to name) parents) |
389 #> fold (add_edge_to name) parents |
|
390 val (access_G, num_known_facts) = |
387 val (access_G, num_known_facts) = |
391 case string_ord (version', version) of |
388 (case string_ord (version', version) of |
392 EQUAL => |
389 EQUAL => |
393 (try_graph ctxt "loading state" Graph.empty (fn () => |
390 (try_graph ctxt "loading state" Graph.empty (fn () => |
394 fold add_node node_lines Graph.empty), |
391 fold add_node node_lines Graph.empty), |
395 length node_lines) |
392 length node_lines) |
396 | LESS => |
393 | LESS => |
397 (* can't parse old file *) |
394 (* can't parse old file *) |
398 (MaSh.unlearn ctxt overlord; (Graph.empty, 0)) |
395 (MaSh.unlearn ctxt overlord; (Graph.empty, 0)) |
399 | GREATER => raise FILE_VERSION_TOO_NEW () |
396 | GREATER => raise FILE_VERSION_TOO_NEW ()) |
400 in |
397 in |
401 trace_msg ctxt (fn () => |
398 trace_msg ctxt (fn () => |
402 "Loaded fact graph (" ^ graph_info access_G ^ ")"); |
399 "Loaded fact graph (" ^ graph_info access_G ^ ")"); |
403 {access_G = access_G, num_known_facts = num_known_facts, |
400 {access_G = access_G, num_known_facts = num_known_facts, |
404 dirty = SOME []} |
401 dirty = SOME []} |
405 end |
402 end |
406 | _ => empty_state) |
403 | _ => empty_state)) |
407 end |
404 end |
408 |
405 |
409 fun save_state _ (state as {dirty = SOME [], ...}) = state |
406 fun save_state _ (state as {dirty = SOME [], ...}) = state |
410 | save_state ctxt {access_G, num_known_facts, dirty} = |
407 | save_state ctxt {access_G, num_known_facts, dirty} = |
411 let |
408 let |
413 str_of_proof_kind kind ^ " " ^ encode_str name ^ ": " ^ |
410 str_of_proof_kind kind ^ " " ^ encode_str name ^ ": " ^ |
414 encode_strs parents ^ "\n" |
411 encode_strs parents ^ "\n" |
415 fun append_entry (name, (kind, (parents, _))) = |
412 fun append_entry (name, (kind, (parents, _))) = |
416 cons (name, Graph.Keys.dest parents, kind) |
413 cons (name, Graph.Keys.dest parents, kind) |
417 val (banner, entries) = |
414 val (banner, entries) = |
418 case dirty of |
415 (case dirty of |
419 SOME names => |
416 SOME names => (NONE, fold (append_entry o Graph.get_entry access_G) names []) |
420 (NONE, fold (append_entry o Graph.get_entry access_G) names []) |
417 | NONE => (SOME (version ^ "\n"), Graph.fold append_entry access_G [])) |
421 | NONE => (SOME (version ^ "\n"), Graph.fold append_entry access_G []) |
|
422 in |
418 in |
423 write_file banner (entries, str_of_entry) (mash_state_file ()); |
419 write_file banner (entries, str_of_entry) (mash_state_file ()); |
424 trace_msg ctxt (fn () => |
420 trace_msg ctxt (fn () => |
425 "Saved fact graph (" ^ graph_info access_G ^ |
421 "Saved fact graph (" ^ graph_info access_G ^ |
426 (case dirty of |
422 (case dirty of |
469 |
465 |
470 fun nickname_of_thm th = |
466 fun nickname_of_thm th = |
471 if Thm.has_name_hint th then |
467 if Thm.has_name_hint th then |
472 let val hint = Thm.get_name_hint th in |
468 let val hint = Thm.get_name_hint th in |
473 (* There must be a better way to detect local facts. *) |
469 (* There must be a better way to detect local facts. *) |
474 case try (unprefix local_prefix) hint of |
470 (case try (unprefix local_prefix) hint of |
475 SOME suf => |
471 SOME suf => |
476 thy_name_of_thm th ^ Long_Name.separator ^ suf ^ |
472 thy_name_of_thm th ^ Long_Name.separator ^ suf ^ Long_Name.separator ^ |
477 Long_Name.separator ^ elided_backquote_thm 50 th |
473 elided_backquote_thm 50 th |
478 | NONE => hint |
474 | NONE => hint) |
479 end |
475 end |
480 else |
476 else |
481 elided_backquote_thm 200 th |
477 elided_backquote_thm 200 th |
482 |
478 |
483 fun find_suggested_facts ctxt facts = |
479 fun find_suggested_facts ctxt facts = |
510 val mess = mess |> map (apsnd (apfst (normalize_scores max_facts))) |
506 val mess = mess |> map (apsnd (apfst (normalize_scores max_facts))) |
511 fun score_in fact (global_weight, (sels, unks)) = |
507 fun score_in fact (global_weight, (sels, unks)) = |
512 let |
508 let |
513 val score_at = try (nth sels) #> Option.map (fn (_, score) => global_weight * score) |
509 val score_at = try (nth sels) #> Option.map (fn (_, score) => global_weight * score) |
514 in |
510 in |
515 case find_index (curry fact_eq fact o fst) sels of |
511 (case find_index (curry fact_eq fact o fst) sels of |
516 ~1 => if member fact_eq unks fact then NONE else SOME 0.0 |
512 ~1 => if member fact_eq unks fact then NONE else SOME 0.0 |
517 | rank => score_at rank |
513 | rank => score_at rank) |
518 end |
514 end |
519 fun weight_of fact = mess |> map_filter (score_in fact) |> scaled_avg |
515 fun weight_of fact = mess |> map_filter (score_in fact) |> scaled_avg |
520 val facts = fold (union fact_eq o map fst o take max_facts o fst o snd) mess [] |
516 val facts = fold (union fact_eq o map fst o take max_facts o fst o snd) mess [] |
521 in |
517 in |
522 facts |> map (`weight_of) |> sort (int_ord o swap o pairself fst) |
518 facts |> map (`weight_of) |> sort (int_ord o swap o pairself fst) |
534 fun crude_theory_ord p = |
530 fun crude_theory_ord p = |
535 if Theory.subthy p then |
531 if Theory.subthy p then |
536 if Theory.eq_thy p then EQUAL else LESS |
532 if Theory.eq_thy p then EQUAL else LESS |
537 else if Theory.subthy (swap p) then |
533 else if Theory.subthy (swap p) then |
538 GREATER |
534 GREATER |
539 else case int_ord (pairself (length o Theory.ancestors_of) p) of |
535 else |
540 EQUAL => string_ord (pairself Context.theory_name p) |
536 (case int_ord (pairself (length o Theory.ancestors_of) p) of |
541 | order => order |
537 EQUAL => string_ord (pairself Context.theory_name p) |
|
538 | order => order) |
542 |
539 |
543 fun crude_thm_ord p = |
540 fun crude_thm_ord p = |
544 case crude_theory_ord (pairself theory_of_thm p) of |
541 (case crude_theory_ord (pairself theory_of_thm p) of |
545 EQUAL => |
542 EQUAL => |
546 let val q = pairself nickname_of_thm p in |
543 let val q = pairself nickname_of_thm p in |
547 (* Hack to put "xxx_def" before "xxxI" and "xxxE" *) |
544 (* Hack to put "xxx_def" before "xxxI" and "xxxE" *) |
548 case bool_ord (pairself (String.isSuffix "_def") (swap q)) of |
545 (case bool_ord (pairself (String.isSuffix "_def") (swap q)) of |
549 EQUAL => string_ord q |
546 EQUAL => string_ord q |
550 | ord => ord |
547 | ord => ord) |
551 end |
548 end |
552 | ord => ord |
549 | ord => ord) |
553 |
550 |
554 val thm_less_eq = Theory.subthy o pairself theory_of_thm |
551 val thm_less_eq = Theory.subthy o pairself theory_of_thm |
555 fun thm_less p = thm_less_eq p andalso not (thm_less_eq (swap p)) |
552 fun thm_less p = thm_less_eq p andalso not (thm_less_eq (swap p)) |
556 |
553 |
557 val freezeT = Type.legacy_freeze_type |
554 val freezeT = Type.legacy_freeze_type |
722 fun add_term_pats _ 0 _ = I |
719 fun add_term_pats _ 0 _ = I |
723 | add_term_pats Ts depth t = |
720 | add_term_pats Ts depth t = |
724 add_term_pat Ts depth t #> add_term_pats Ts (depth - 1) t |
721 add_term_pat Ts depth t #> add_term_pats Ts (depth - 1) t |
725 fun add_term Ts = add_term_pats Ts term_max_depth |
722 fun add_term Ts = add_term_pats Ts term_max_depth |
726 fun add_subterms Ts t = |
723 fun add_subterms Ts t = |
727 case strip_comb t of |
724 (case strip_comb t of |
728 (Const (s, T), args) => |
725 (Const (s, T), args) => |
729 (not (is_widely_irrelevant_const s) ? add_term Ts t) |
726 (not (is_widely_irrelevant_const s) ? add_term Ts t) |
730 #> add_subtypes T |
727 #> add_subtypes T |
731 #> fold (add_subterms Ts) args |
728 #> fold (add_subterms Ts) args |
732 | (head, args) => |
729 | (head, args) => |
733 (case head of |
730 (case head of |
734 Free (_, T) => add_term Ts t #> add_subtypes T |
731 Free (_, T) => add_term Ts t #> add_subtypes T |
735 | Var (_, T) => add_subtypes T |
732 | Var (_, T) => add_subtypes T |
736 | Abs (_, T, body) => add_subtypes T #> add_subterms (T :: Ts) body |
733 | Abs (_, T, body) => add_subtypes T #> add_subterms (T :: Ts) body |
737 | _ => I) |
734 | _ => I) |
738 #> fold (add_subterms Ts) args |
735 #> fold (add_subterms Ts) args) |
739 in [] |> fold (add_subterms []) ts end |
736 in [] |> fold (add_subterms []) ts end |
740 |
737 |
741 val term_max_depth = 2 |
738 val term_max_depth = 2 |
742 val type_max_depth = 1 |
739 val type_max_depth = 1 |
743 |
740 |
817 fun nickify ((_, stature), th) = ((nickname_of_thm th, stature), th) |
814 fun nickify ((_, stature), th) = ((nickname_of_thm th, stature), th) |
818 fun is_dep dep (_, th) = nickname_of_thm th = dep |
815 fun is_dep dep (_, th) = nickname_of_thm th = dep |
819 fun add_isar_dep facts dep accum = |
816 fun add_isar_dep facts dep accum = |
820 if exists (is_dep dep) accum then |
817 if exists (is_dep dep) accum then |
821 accum |
818 accum |
822 else case find_first (is_dep dep) facts of |
819 else |
823 SOME ((_, status), th) => accum @ [(("", status), th)] |
820 (case find_first (is_dep dep) facts of |
824 | NONE => accum (* shouldn't happen *) |
821 SOME ((_, status), th) => accum @ [(("", status), th)] |
|
822 | NONE => accum (* shouldn't happen *)) |
825 val mepo_facts = |
823 val mepo_facts = |
826 facts |
824 facts |
827 |> mepo_suggested_facts ctxt params (max_facts |> the_default prover_default_max_facts) NONE |
825 |> mepo_suggested_facts ctxt params (max_facts |> the_default prover_default_max_facts) NONE |
828 hyp_ts concl_t |
826 hyp_ts concl_t |
829 val facts = |
827 val facts = |
836 "MaSh: " ^ quote prover ^ " on " ^ quote name ^ " with " ^ string_of_int num_isar_deps ^ |
834 "MaSh: " ^ quote prover ^ " on " ^ quote name ^ " with " ^ string_of_int num_isar_deps ^ |
837 " + " ^ string_of_int (length facts - num_isar_deps) ^ " facts." |
835 " + " ^ string_of_int (length facts - num_isar_deps) ^ " facts." |
838 |> Output.urgent_message |
836 |> Output.urgent_message |
839 else |
837 else |
840 (); |
838 (); |
841 case run_prover_for_mash ctxt params prover name facts goal of |
839 (case run_prover_for_mash ctxt params prover name facts goal of |
842 {outcome = NONE, used_facts, ...} => |
840 {outcome = NONE, used_facts, ...} => |
843 (if verbose andalso auto_level = 0 then |
841 (if verbose andalso auto_level = 0 then |
844 let val num_facts = length used_facts in |
842 let val num_facts = length used_facts in |
845 "Found proof with " ^ string_of_int num_facts ^ " fact" ^ |
843 "Found proof with " ^ string_of_int num_facts ^ " fact" ^ |
846 plural_s num_facts ^ "." |
844 plural_s num_facts ^ "." |
847 |> Output.urgent_message |
845 |> Output.urgent_message |
848 end |
846 end |
849 else |
847 else |
850 (); |
848 (); |
851 (true, map fst used_facts)) |
849 (true, map fst used_facts)) |
852 | _ => (false, isar_deps) |
850 | _ => (false, isar_deps)) |
853 end |
851 end) |
854 |
852 |
855 |
853 |
856 (*** High-level communication with MaSh ***) |
854 (*** High-level communication with MaSh ***) |
857 |
855 |
858 (* In the following functions, chunks are risers w.r.t. "thm_less_eq". *) |
856 (* In the following functions, chunks are risers w.r.t. "thm_less_eq". *) |
1138 val (relearns, access_G) = |
1136 val (relearns, access_G) = |
1139 ([], access_G) |> fold (relearn_wrt_access_graph ctxt) relearns |
1137 ([], access_G) |> fold (relearn_wrt_access_graph ctxt) relearns |
1140 val access_G = access_G |> fold flop_wrt_access_graph flops |
1138 val access_G = access_G |> fold flop_wrt_access_graph flops |
1141 val num_known_facts = num_known_facts + length learns |
1139 val num_known_facts = num_known_facts + length learns |
1142 val dirty = |
1140 val dirty = |
1143 case (was_empty, dirty, relearns) of |
1141 (case (was_empty, dirty, relearns) of |
1144 (false, SOME names, []) => SOME (map #1 learns @ names) |
1142 (false, SOME names, []) => SOME (map #1 learns @ names) |
1145 | _ => NONE |
1143 | _ => NONE) |
1146 in |
1144 in |
1147 MaSh.learn ctxt overlord (save andalso null relearns) (rev learns); |
1145 MaSh.learn ctxt overlord (save andalso null relearns) (rev learns); |
1148 MaSh.relearn ctxt overlord save relearns; |
1146 MaSh.relearn ctxt overlord save relearns; |
1149 {access_G = access_G, num_known_facts = num_known_facts, |
1147 {access_G = access_G, num_known_facts = num_known_facts, |
1150 dirty = dirty} |
1148 dirty = dirty} |
1200 | relearn_old_fact ((_, (_, status)), th) |
1198 | relearn_old_fact ((_, (_, status)), th) |
1201 ((relearns, flops), (n, next_commit, _)) = |
1199 ((relearns, flops), (n, next_commit, _)) = |
1202 let |
1200 let |
1203 val name = nickname_of_thm th |
1201 val name = nickname_of_thm th |
1204 val (n, relearns, flops) = |
1202 val (n, relearns, flops) = |
1205 case deps_of status th of |
1203 (case deps_of status th of |
1206 SOME deps => (n + 1, (name, deps) :: relearns, flops) |
1204 SOME deps => (n + 1, (name, deps) :: relearns, flops) |
1207 | NONE => (n, relearns, name :: flops) |
1205 | NONE => (n, relearns, name :: flops)) |
1208 val (relearns, flops, next_commit) = |
1206 val (relearns, flops, next_commit) = |
1209 if Time.> (Timer.checkRealTimer timer, next_commit) then |
1207 if Time.> (Timer.checkRealTimer timer, next_commit) then |
1210 (commit false [] relearns flops; |
1208 (commit false [] relearns flops; |
1211 ([], [], next_commit_time ())) |
1209 ([], [], next_commit_time ())) |
1212 else |
1210 else |
1323 val {access_G, num_known_facts, ...} = peek_state ctxt overlord I |
1321 val {access_G, num_known_facts, ...} = peek_state ctxt overlord I |
1324 val is_in_access_G = is_fact_in_graph access_G o snd |
1322 val is_in_access_G = is_fact_in_graph access_G o snd |
1325 in |
1323 in |
1326 if length facts - num_known_facts |
1324 if length facts - num_known_facts |
1327 <= max_facts_to_learn_before_query then |
1325 <= max_facts_to_learn_before_query then |
1328 case length (filter_out is_in_access_G facts) of |
1326 (case length (filter_out is_in_access_G facts) of |
1329 0 => false |
1327 0 => false |
1330 | num_facts_to_learn => |
1328 | num_facts_to_learn => |
1331 if num_facts_to_learn <= max_facts_to_learn_before_query then |
1329 if num_facts_to_learn <= max_facts_to_learn_before_query then |
1332 (mash_learn_facts ctxt params prover false 2 false timeout facts |
1330 (mash_learn_facts ctxt params prover false 2 false timeout facts |
1333 |> (fn "" => () | s => Output.urgent_message (MaShN ^ ": " ^ s)); |
1331 |> (fn "" => () | s => Output.urgent_message (MaShN ^ ": " ^ s)); |
1334 true) |
1332 true) |
1335 else |
1333 else |
1336 (maybe_launch_thread (); false) |
1334 (maybe_launch_thread (); false)) |
1337 else |
1335 else |
1338 (maybe_launch_thread (); false) |
1336 (maybe_launch_thread (); false) |
1339 end |
1337 end |
1340 else |
1338 else |
1341 false |
1339 false |
1342 val (save, effective_fact_filter) = |
1340 val (save, effective_fact_filter) = |
1343 case fact_filter of |
1341 (case fact_filter of |
1344 SOME ff => (ff <> mepoN andalso maybe_learn (), ff) |
1342 SOME ff => (ff <> mepoN andalso maybe_learn (), ff) |
1345 | NONE => |
1343 | NONE => |
1346 if is_mash_enabled () then |
1344 if is_mash_enabled () then |
1347 (maybe_learn (), |
1345 (maybe_learn (), |
1348 if mash_can_suggest_facts ctxt overlord then meshN else mepoN) |
1346 if mash_can_suggest_facts ctxt overlord then meshN else mepoN) |
1349 else |
1347 else |
1350 (false, mepoN) |
1348 (false, mepoN)) |
1351 |
1349 |
1352 val unique_facts = drop_duplicate_facts facts |
1350 val unique_facts = drop_duplicate_facts facts |
1353 val add_ths = Attrib.eval_thms ctxt add |
1351 val add_ths = Attrib.eval_thms ctxt add |
1354 |
1352 |
1355 fun in_add (_, th) = member Thm.eq_thm_prop add_ths th |
1353 fun in_add (_, th) = member Thm.eq_thm_prop add_ths th |
1371 |> effective_fact_filter <> mashN ? cons (mepo_weight, mepo) |
1369 |> effective_fact_filter <> mashN ? cons (mepo_weight, mepo) |
1372 |> Par_List.map (apsnd (fn f => f ())) |
1370 |> Par_List.map (apsnd (fn f => f ())) |
1373 val mesh = mesh_facts (eq_snd Thm.eq_thm_prop) max_facts mess |> add_and_take |
1371 val mesh = mesh_facts (eq_snd Thm.eq_thm_prop) max_facts mess |> add_and_take |
1374 in |
1372 in |
1375 if save then MaSh.save ctxt overlord else (); |
1373 if save then MaSh.save ctxt overlord else (); |
1376 case (fact_filter, mess) of |
1374 (case (fact_filter, mess) of |
1377 (NONE, [(_, (mepo, _)), (_, (mash, _))]) => |
1375 (NONE, [(_, (mepo, _)), (_, (mash, _))]) => |
1378 [(meshN, mesh), (mepoN, mepo |> map fst |> add_and_take), |
1376 [(meshN, mesh), (mepoN, mepo |> map fst |> add_and_take), |
1379 (mashN, mash |> map fst |> add_and_take)] |
1377 (mashN, mash |> map fst |> add_and_take)] |
1380 | _ => [(effective_fact_filter, mesh)] |
1378 | _ => [(effective_fact_filter, mesh)]) |
1381 end |
1379 end |
1382 |
1380 |
1383 fun kill_learners ctxt ({overlord, ...} : params) = |
1381 fun kill_learners ctxt ({overlord, ...} : params) = |
1384 (Async_Manager.kill_threads MaShN "learner"; MaSh.shutdown ctxt overlord) |
1382 (Async_Manager.kill_threads MaShN "learner"; MaSh.shutdown ctxt overlord) |
1385 fun running_learners () = Async_Manager.running_threads MaShN "learner" |
1383 fun running_learners () = Async_Manager.running_threads MaShN "learner" |