src/HOL/Tools/Sledgehammer/sledgehammer.ML
changeset 75029 dc6769b86fd6
parent 75027 a8efa30c380d
child 75030 919fb49ba201
equal deleted inserted replaced
75028:b49329185b82 75029:dc6769b86fd6
    36 
    36 
    37 structure Sledgehammer : SLEDGEHAMMER =
    37 structure Sledgehammer : SLEDGEHAMMER =
    38 struct
    38 struct
    39 
    39 
    40 open ATP_Util
    40 open ATP_Util
       
    41 open ATP_Problem
    41 open ATP_Proof
    42 open ATP_Proof
    42 open ATP_Problem_Generate
    43 open ATP_Problem_Generate
    43 open Sledgehammer_Util
    44 open Sledgehammer_Util
    44 open Sledgehammer_Fact
    45 open Sledgehammer_Fact
    45 open Sledgehammer_Proof_Methods
    46 open Sledgehammer_Proof_Methods
    46 open Sledgehammer_Isar_Proof
    47 open Sledgehammer_Isar_Proof
    47 open Sledgehammer_Isar_Preplay
    48 open Sledgehammer_Isar_Preplay
    48 open Sledgehammer_Isar_Minimize
    49 open Sledgehammer_Isar_Minimize
       
    50 open Sledgehammer_ATP_Systems
    49 open Sledgehammer_Prover
    51 open Sledgehammer_Prover
    50 open Sledgehammer_Prover_ATP
    52 open Sledgehammer_Prover_ATP
    51 open Sledgehammer_Prover_Minimize
    53 open Sledgehammer_Prover_Minimize
    52 open Sledgehammer_MaSh
    54 open Sledgehammer_MaSh
    53 
    55 
    78     |> alternative snd unknown
    80     |> alternative snd unknown
    79     |> alternative snd timeout
    81     |> alternative snd timeout
    80     |> alternative snd none
    82     |> alternative snd none
    81     |> the_default (SH_Unknown, "")
    83     |> the_default (SH_Unknown, "")
    82   end
    84   end
    83 
       
    84 fun is_metis_method (Metis_Method _) = true
       
    85   | is_metis_method _ = false
       
    86 
    85 
    87 fun play_one_line_proof minimize timeout used_facts state i (preferred_meth, methss) =
    86 fun play_one_line_proof minimize timeout used_facts state i (preferred_meth, methss) =
    88   (if timeout = Time.zeroTime then
    87   (if timeout = Time.zeroTime then
    89      (used_facts, (preferred_meth, Play_Timed_Out Time.zeroTime))
    88      (used_facts, (preferred_meth, Play_Timed_Out Time.zeroTime))
    90    else
    89    else
   114                  proof_methods = meths,
   113                  proof_methods = meths,
   115                  comment = ""}
   114                  comment = ""}
   116            in
   115            in
   117              (case preplay_isar_step ctxt chained timeout [] (mk_step fact_names meths) of
   116              (case preplay_isar_step ctxt chained timeout [] (mk_step fact_names meths) of
   118                (res as (meth, Played time)) :: _ =>
   117                (res as (meth, Played time)) :: _ =>
   119                (* if a fact is needed by an ATP, it will be needed by "metis" *)
   118                if not minimize then
   120                if not minimize orelse is_metis_method meth then
       
   121                  (used_facts, res)
   119                  (used_facts, res)
   122                else
   120                else
   123                  let
   121                  let
   124                    val (time', used_names') =
   122                    val (time', used_names') =
   125                      minimized_isar_step ctxt chained time (mk_step fact_names [meth])
   123                      minimized_isar_step ctxt chained time (mk_step fact_names [meth])
   263     "Found no relevant facts"
   261     "Found no relevant facts"
   264   else
   262   else
   265     cat_lines (map (fn (filter, facts) =>
   263     cat_lines (map (fn (filter, facts) =>
   266       (if filter = "" then "" else filter ^ ": ") ^ string_of_facts facts) factss)
   264       (if filter = "" then "" else filter ^ ": ") ^ string_of_facts facts) factss)
   267 
   265 
       
   266 val default_slice_schedule =
       
   267   (* FUDGE (based on Seventeen evaluation) *)
       
   268   [cvc4N, zipperpositionN, vampireN, veritN, eN, cvc4N, zipperpositionN, cvc4N, vampireN, cvc4N,
       
   269    cvc4N, vampireN, cvc4N, eN, iproverN, zipperpositionN, vampireN, eN, vampireN, zipperpositionN,
       
   270    z3N, cvc4N, vampireN, iproverN, vampireN, zipperpositionN, z3N, z3N, cvc4N, cvc4N]
       
   271 
       
   272 fun schedule_of_provers provers num_slices =
       
   273   let
       
   274     val num_default_slices = length default_slice_schedule
       
   275     val unknown_provers = filter_out (member (op =) default_slice_schedule) provers
       
   276 
       
   277     fun round_robin _ [] = []
       
   278       | round_robin 0 _ = []
       
   279       | round_robin n (prover :: provers) = prover :: round_robin (n - 1) (provers @ [prover])
       
   280   in
       
   281     if num_slices <= num_default_slices then
       
   282       take num_slices default_slice_schedule
       
   283     else
       
   284       default_slice_schedule @ round_robin (num_slices - num_default_slices) unknown_provers
       
   285   end
       
   286 
       
   287 fun prover_slices_of_schedule ctxt schedule =
       
   288   let
       
   289     fun triplicate_slices original =
       
   290       let
       
   291         val shift =
       
   292           map (apfst (apsnd (fn fact_filter =>
       
   293             if fact_filter = mashN then mepoN
       
   294             else if fact_filter = mepoN then meshN
       
   295             else mashN)))
       
   296 
       
   297         val shifted_once = shift original
       
   298         val shifted_twice = shift shifted_once
       
   299       in
       
   300         original @ shifted_once @ shifted_twice
       
   301       end
       
   302 
       
   303     val provers = distinct (op =) schedule
       
   304     val prover_slices =
       
   305       map (fn prover => (prover, triplicate_slices (get_slices ctxt prover))) provers
       
   306 
       
   307     fun translate _ [] = []
       
   308       | translate prover_slices (prover :: schedule) =
       
   309         (case AList.lookup (op =) prover_slices prover of
       
   310           SOME (slice :: slices) =>
       
   311           let val prover_slices' = AList.update (op =) (prover, slices) prover_slices in
       
   312             (prover, slice) :: translate prover_slices' schedule
       
   313           end
       
   314         | _ => translate prover_slices schedule)
       
   315   in
       
   316     translate prover_slices schedule
       
   317   end
       
   318 
   268 fun run_sledgehammer (params as {verbose, spy, provers, induction_rules, max_facts, ...}) mode
   319 fun run_sledgehammer (params as {verbose, spy, provers, induction_rules, max_facts, ...}) mode
   269     writeln_result i (fact_override as {only, ...}) state =
   320     writeln_result i (fact_override as {only, ...}) state =
   270   if null provers then
   321   if null provers then
   271     error "No prover is set"
   322     error "No prover is set"
   272   else
   323   else
   307           let
   358           let
   308             val max_max_facts =
   359             val max_max_facts =
   309               (case max_facts of
   360               (case max_facts of
   310                 SOME n => n
   361                 SOME n => n
   311               | NONE =>
   362               | NONE =>
   312                 fold (fn prover => Integer.max (fst (fst (get_default_slice ctxt prover)))) provers
   363                 fold (fn prover =>
   313                   0)
   364                     fold (fn ((n, _), _) => Integer.max n) (get_slices ctxt prover))
       
   365                   provers 0)
   314 
   366 
   315             val ({elapsed, ...}, factss) = Timing.timing
   367             val ({elapsed, ...}, factss) = Timing.timing
   316               (relevant_facts ctxt params (hd provers) max_max_facts fact_override hyp_ts concl_t)
   368               (relevant_facts ctxt params (hd provers) max_max_facts fact_override hyp_ts concl_t)
   317               all_facts
   369               all_facts
   318 
   370 
   334             val problem =
   386             val problem =
   335               {comment = "", state = state, goal = goal, subgoal = i, subgoal_count = n,
   387               {comment = "", state = state, goal = goal, subgoal = i, subgoal_count = n,
   336                factss = get_factss provers, found_proof = found_proof}
   388                factss = get_factss provers, found_proof = found_proof}
   337             val learn = mash_learn_proof ctxt params (Thm.prop_of goal)
   389             val learn = mash_learn_proof ctxt params (Thm.prop_of goal)
   338             val launch = launch_prover_and_preplay params mode writeln_result learn
   390             val launch = launch_prover_and_preplay params mode writeln_result learn
       
   391 
       
   392             val schedule =
       
   393               if mode = Auto_Try then
       
   394                 provers
       
   395               else
       
   396                 let val num_slices = 50 (* FIXME *) in
       
   397                   schedule_of_provers provers num_slices
       
   398                 end
       
   399             val prover_slices = prover_slices_of_schedule ctxt schedule
   339           in
   400           in
   340             if mode = Auto_Try then
   401             if mode = Auto_Try then
   341               (SH_Unknown, "")
   402               (SH_Unknown, "")
   342               |> fold (fn prover =>
   403               |> fold (fn (prover, slice) =>
   343                   fn accum as (SH_Some _, _) => accum
   404                   fn accum as (SH_Some _, _) => accum
   344                     | _ => launch problem (get_default_slice ctxt prover) prover)
   405                     | _ => launch problem slice prover)
   345                 provers
   406                 prover_slices
   346             else
   407             else
   347               (learn chained_thms;
   408               (learn chained_thms;
   348                provers
   409                Par_List.map (fn (prover, slice) => launch problem slice prover) prover_slices
   349                |> Par_List.map (fn prover => launch problem (get_default_slice ctxt prover) prover)
       
   350                |> max_outcome)
   410                |> max_outcome)
   351           end
   411           end
   352       in
   412       in
   353         (launch_provers ()
   413         (launch_provers ()
   354          handle Timeout.TIMEOUT _ => (SH_Timeout, ""))
   414          handle Timeout.TIMEOUT _ => (SH_Timeout, ""))