src/HOL/Tools/Sledgehammer/sledgehammer_filter_mash.ML
changeset 48378 9e96486d53ad
parent 48377 4a11914fd530
child 48379 2b5ad61e2ccc
equal deleted inserted replaced
48377:4a11914fd530 48378:9e96486d53ad
    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)]