23 val escape_meta : string -> string |
23 val escape_meta : string -> string |
24 val escape_metas : string list -> string |
24 val escape_metas : string list -> string |
25 val unescape_meta : string -> string |
25 val unescape_meta : string -> string |
26 val unescape_metas : string -> string list |
26 val unescape_metas : string -> string list |
27 val extract_query : string -> string * string list |
27 val extract_query : string -> string * string list |
|
28 val nickname_of : thm -> string |
28 val suggested_facts : string list -> ('a * thm) list -> ('a * thm) list |
29 val suggested_facts : string list -> ('a * thm) list -> ('a * thm) list |
29 val mesh_facts : |
30 val mesh_facts : |
30 int -> (('a * thm) list * ('a * thm) list) list -> ('a * thm) list |
31 int -> (('a * thm) list * ('a * thm) list) list -> ('a * thm) list |
31 val is_likely_tautology_or_too_meta : thm -> bool |
32 val is_likely_tautology_or_too_meta : thm -> bool |
32 val theory_ord : theory * theory -> order |
33 val theory_ord : theory * theory -> order |
120 fun extract_query line = |
121 fun extract_query line = |
121 case space_explode ":" line of |
122 case space_explode ":" line of |
122 [goal_name, suggs] => (unescape_meta goal_name, unescape_metas suggs) |
123 [goal_name, suggs] => (unescape_meta goal_name, unescape_metas suggs) |
123 | _ => ("", []) |
124 | _ => ("", []) |
124 |
125 |
|
126 fun parent_of_local_thm th = |
|
127 let |
|
128 val thy = th |> Thm.theory_of_thm |
|
129 val facts = thy |> Global_Theory.facts_of |
|
130 val space = facts |> Facts.space_of |
|
131 fun id_of s = #id (Name_Space.the_entry space s) |
|
132 fun max_id (s', _) (s, id) = |
|
133 let val id' = id_of s' in if id > id' then (s, id) else (s', id') end |
|
134 in ("", ~1) |> Facts.fold_static max_id facts |> fst end |
|
135 |
|
136 val local_prefix = "local" ^ Long_Name.separator |
|
137 |
|
138 fun nickname_of th = |
|
139 let val hint = Thm.get_name_hint th in |
|
140 (* FIXME: There must be a better way to detect local facts. *) |
|
141 case try (unprefix local_prefix) hint of |
|
142 SOME suff => |
|
143 parent_of_local_thm th ^ Long_Name.separator ^ Long_Name.separator ^ suff |
|
144 | NONE => hint |
|
145 end |
|
146 |
125 fun suggested_facts suggs facts = |
147 fun suggested_facts suggs facts = |
126 let |
148 let |
127 fun add_fact (fact as (_, th)) = Symtab.default (Thm.get_name_hint th, fact) |
149 fun add_fact (fact as (_, th)) = Symtab.default (nickname_of th, fact) |
128 val tab = Symtab.empty |> fold add_fact facts |
150 val tab = Symtab.empty |> fold add_fact facts |
129 in map_filter (Symtab.lookup tab) suggs end |
151 in map_filter (Symtab.lookup tab) suggs end |
130 |
152 |
131 (* Ad hoc score function roughly based on Blanchette's Ringberg 2011 data. *) |
153 (* Ad hoc score function roughly based on Blanchette's Ringberg 2011 data. *) |
132 fun score x = Math.pow (1.5, 15.5 - 0.05 * Real.fromInt x) + 15.0 |
154 fun score x = Math.pow (1.5, 15.5 - 0.05 * Real.fromInt x) + 15.0 |
466 fun mash_can_suggest_facts ctxt = |
488 fun mash_can_suggest_facts ctxt = |
467 not (Graph.is_empty (#fact_graph (mash_get ctxt))) |
489 not (Graph.is_empty (#fact_graph (mash_get ctxt))) |
468 |
490 |
469 fun parents_wrt_facts facts fact_graph = |
491 fun parents_wrt_facts facts fact_graph = |
470 let |
492 let |
471 val facts = [] |> fold (cons o Thm.get_name_hint o snd) facts |
493 val facts = [] |> fold (cons o nickname_of o snd) facts |
472 val tab = Symtab.empty |> fold (fn name => Symtab.update (name, ())) facts |
494 val tab = Symtab.empty |> fold (fn name => Symtab.update (name, ())) facts |
473 fun insert_not_seen seen name = |
495 fun insert_not_seen seen name = |
474 not (member (op =) seen name) ? insert (op =) name |
496 not (member (op =) seen name) ? insert (op =) name |
475 fun parents_of seen parents [] = parents |
497 fun parents_of _ parents [] = parents |
476 | parents_of seen parents (name :: names) = |
498 | parents_of seen parents (name :: names) = |
477 if Symtab.defined tab name then |
499 if Symtab.defined tab name then |
478 parents_of (name :: seen) (name :: parents) names |
500 parents_of (name :: seen) (name :: parents) names |
479 else |
501 else |
480 parents_of (name :: seen) parents |
502 parents_of (name :: seen) parents |
486 later for various reasons and "meshing" gives better results with some |
508 later for various reasons and "meshing" gives better results with some |
487 slack. *) |
509 slack. *) |
488 fun max_suggs_of max_facts = max_facts + Int.min (200, max_facts) |
510 fun max_suggs_of max_facts = max_facts + Int.min (200, max_facts) |
489 |
511 |
490 fun is_fact_in_graph fact_graph (_, th) = |
512 fun is_fact_in_graph fact_graph (_, th) = |
491 can (Graph.get_node fact_graph) (Thm.get_name_hint th) |
513 can (Graph.get_node fact_graph) (nickname_of th) |
492 |
514 |
493 fun mash_suggest_facts ctxt ({overlord, ...} : params) prover max_facts hyp_ts |
515 fun mash_suggest_facts ctxt ({overlord, ...} : params) prover max_facts hyp_ts |
494 concl_t facts = |
516 concl_t facts = |
495 let |
517 let |
496 val thy = Proof_Context.theory_of ctxt |
518 val thy = Proof_Context.theory_of ctxt |
543 else |
565 else |
544 let |
566 let |
545 val ths = facts |> map snd |
567 val ths = facts |> map snd |
546 val all_names = |
568 val all_names = |
547 ths |> filter_out is_likely_tautology_or_too_meta |
569 ths |> filter_out is_likely_tautology_or_too_meta |
548 |> map (rpair () o Thm.get_name_hint) |
570 |> map (rpair () o nickname_of) |
549 |> Symtab.make |
571 |> Symtab.make |
550 fun trim_deps deps = if length deps > max_dependencies then [] else deps |
572 fun trim_deps deps = if length deps > max_dependencies then [] else deps |
551 fun do_fact _ (accum as (_, true)) = accum |
573 fun do_fact _ (accum as (_, true)) = accum |
552 | do_fact ((_, (_, status)), th) ((parents, upds), false) = |
574 | do_fact ((_, (_, status)), th) ((parents, upds), false) = |
553 let |
575 let |
554 val name = Thm.get_name_hint th |
576 val name = nickname_of th |
555 val feats = |
577 val feats = |
556 features_of ctxt prover (theory_of_thm th) status [prop_of th] |
578 features_of ctxt prover (theory_of_thm th) status [prop_of th] |
557 val deps = isabelle_dependencies_of all_names th |> trim_deps |
579 val deps = isabelle_dependencies_of all_names th |> trim_deps |
558 val upd = (name, parents, feats, deps) |
580 val upd = (name, parents, feats, deps) |
559 in (([name], upd :: upds), timed_out pass1_learn_timeout_factor) end |
581 in (([name], upd :: upds), timed_out pass1_learn_timeout_factor) end |
589 let |
611 let |
590 val thy = Proof_Context.theory_of ctxt |
612 val thy = Proof_Context.theory_of ctxt |
591 val prover = hd provers |
613 val prover = hd provers |
592 val name = ATP_Util.timestamp () ^ " " ^ serial_string () (* fresh enough *) |
614 val name = ATP_Util.timestamp () ^ " " ^ serial_string () (* fresh enough *) |
593 val feats = features_of ctxt prover thy General [t] |
615 val feats = features_of ctxt prover thy General [t] |
594 val deps = used_ths |> map Thm.get_name_hint |
616 val deps = used_ths |> map nickname_of |
595 in |
617 in |
596 mash_map ctxt (fn {thys, fact_graph} => |
618 mash_map ctxt (fn {thys, fact_graph} => |
597 let |
619 let |
598 val parents = parents_wrt_facts facts fact_graph |
620 val parents = parents_wrt_facts facts fact_graph |
599 val upds = [(name, parents, feats, deps)] |
621 val upds = [(name, parents, feats, deps)] |