src/HOL/Tools/Sledgehammer/sledgehammer_prover_minimize.ML
changeset 57732 e1b2442dc629
parent 57723 668322cd58f4
child 57734 18bb3e1ff6f6
equal deleted inserted replaced
57731:d99080b7f961 57732:e1b2442dc629
    46 open Sledgehammer_Isar
    46 open Sledgehammer_Isar
    47 open Sledgehammer_Prover
    47 open Sledgehammer_Prover
    48 open Sledgehammer_Prover_ATP
    48 open Sledgehammer_Prover_ATP
    49 open Sledgehammer_Prover_SMT2
    49 open Sledgehammer_Prover_SMT2
    50 
    50 
    51 fun run_proof_method mode name (params as {timeout, type_enc, lam_trans, ...})
       
    52     minimize_command
       
    53     ({state, subgoal, subgoal_count, factss = (_, facts) :: _, ...} : prover_problem) =
       
    54   let
       
    55     val meth =
       
    56       if name = metisN then Metis_Method (type_enc, lam_trans)
       
    57       else if name = smtN then SMT2_Method
       
    58       else raise Fail ("unknown proof_method: " ^ quote name)
       
    59     val used_facts = facts |> map fst
       
    60   in
       
    61     (case play_one_line_proof (if mode = Minimize then Normal else mode) timeout facts state subgoal
       
    62         meth [meth] of
       
    63       play as (_, Played time) =>
       
    64       {outcome = NONE, used_facts = used_facts, used_from = facts, run_time = time,
       
    65        preplay = Lazy.value play,
       
    66        message = fn play =>
       
    67           let
       
    68             val ctxt = Proof.context_of state
       
    69             val (_, override_params) = extract_proof_method params meth
       
    70             val one_line_params =
       
    71               (play, proof_banner mode name, used_facts, minimize_command override_params name,
       
    72                subgoal, subgoal_count)
       
    73             val num_chained = length (#facts (Proof.goal state))
       
    74           in
       
    75             one_line_proof_text ctxt num_chained one_line_params
       
    76           end,
       
    77        message_tail = ""}
       
    78     | play =>
       
    79       let
       
    80         val failure = (case play of (_, Play_Failed) => GaveUp | _ => TimedOut)
       
    81       in
       
    82         {outcome = SOME failure, used_facts = [], used_from = [],
       
    83          run_time = Time.zeroTime, preplay = Lazy.value play,
       
    84          message = fn _ => string_of_atp_failure failure, message_tail = ""}
       
    85       end)
       
    86   end
       
    87 
       
    88 fun is_prover_supported ctxt =
    51 fun is_prover_supported ctxt =
    89   let val thy = Proof_Context.theory_of ctxt in
    52   let val thy = Proof_Context.theory_of ctxt in
    90     is_proof_method orf is_atp thy orf is_smt2_prover ctxt
    53     is_atp thy orf is_smt2_prover ctxt
    91   end
    54   end
    92 
    55 
    93 fun is_prover_installed ctxt =
    56 fun is_prover_installed ctxt =
    94   is_proof_method orf is_smt2_prover ctxt orf
    57   is_smt2_prover ctxt orf is_atp_installed (Proof_Context.theory_of ctxt)
    95   is_atp_installed (Proof_Context.theory_of ctxt)
       
    96 
       
    97 val proof_method_default_max_facts = 20
       
    98 
    58 
    99 fun default_max_facts_of_prover ctxt name =
    59 fun default_max_facts_of_prover ctxt name =
   100   let val thy = Proof_Context.theory_of ctxt in
    60   let val thy = Proof_Context.theory_of ctxt in
   101     if is_proof_method name then
    61     if is_atp thy name then
   102       proof_method_default_max_facts
       
   103     else if is_atp thy name then
       
   104       fold (Integer.max o fst o #1 o fst o snd) (#best_slices (get_atp thy name ()) ctxt) 0
    62       fold (Integer.max o fst o #1 o fst o snd) (#best_slices (get_atp thy name ()) ctxt) 0
   105     else if is_smt2_prover ctxt name then
    63     else if is_smt2_prover ctxt name then
   106       SMT2_Solver.default_max_relevant ctxt name
    64       SMT2_Solver.default_max_relevant ctxt name
   107     else
    65     else
   108       error ("No such prover: " ^ name ^ ".")
    66       error ("No such prover: " ^ name ^ ".")
   109   end
    67   end
   110 
    68 
   111 fun get_prover ctxt mode name =
    69 fun get_prover ctxt mode name =
   112   let val thy = Proof_Context.theory_of ctxt in
    70   let val thy = Proof_Context.theory_of ctxt in
   113     if is_proof_method name then run_proof_method mode name
    71     if is_atp thy name then run_atp mode name
   114     else if is_atp thy name then run_atp mode name
       
   115     else if is_smt2_prover ctxt name then run_smt2_solver mode name
    72     else if is_smt2_prover ctxt name then run_smt2_solver mode name
   116     else error ("No such prover: " ^ name ^ ".")
    73     else error ("No such prover: " ^ name ^ ".")
   117   end
    74   end
   118 
    75 
   119 (* wrapper for calling external prover *)
    76 (* wrapper for calling external prover *)
   276      | {preplay, message, ...} => (NONE, (preplay, prefix "Prover error: " o message, ""))))
   233      | {preplay, message, ...} => (NONE, (preplay, prefix "Prover error: " o message, ""))))
   277     handle ERROR msg =>
   234     handle ERROR msg =>
   278       (NONE, (Lazy.value (Metis_Method (NONE, NONE), Play_Failed), fn _ => "Error: " ^ msg, ""))
   235       (NONE, (Lazy.value (Metis_Method (NONE, NONE), Play_Failed), fn _ => "Error: " ^ msg, ""))
   279   end
   236   end
   280 
   237 
   281 fun adjust_proof_method_params override_params
   238 fun maybe_minimize mode do_learn name (params as {verbose, minimize, ...})
   282     ({debug, verbose, overlord, spy, blocking, provers, type_enc, strict, lam_trans,
       
   283       uncurried_aliases, learn, fact_filter, max_facts, fact_thresholds, max_mono_iters,
       
   284       max_new_mono_instances, isar_proofs, compress, try0, smt_proofs, slice, minimize, timeout,
       
   285       preplay_timeout, expect} : params) =
       
   286   let
       
   287     fun lookup_override name default_value =
       
   288       (case AList.lookup (op =) override_params name of
       
   289         SOME [s] => SOME s
       
   290       | _ => default_value)
       
   291     (* Only those options that proof_methods are interested in are considered here. *)
       
   292     val type_enc = lookup_override "type_enc" type_enc
       
   293     val lam_trans = lookup_override "lam_trans" lam_trans
       
   294   in
       
   295     {debug = debug, verbose = verbose, overlord = overlord, spy = spy, blocking = blocking,
       
   296      provers = provers, type_enc = type_enc, strict = strict, lam_trans = lam_trans,
       
   297      uncurried_aliases = uncurried_aliases, learn = learn, fact_filter = fact_filter,
       
   298      max_facts = max_facts, fact_thresholds = fact_thresholds, max_mono_iters = max_mono_iters,
       
   299      max_new_mono_instances = max_new_mono_instances, isar_proofs = isar_proofs,
       
   300      compress = compress, try0 = try0, smt_proofs = smt_proofs, slice = slice, minimize = minimize,
       
   301      timeout = timeout, preplay_timeout = preplay_timeout, expect = expect}
       
   302   end
       
   303 
       
   304 fun maybe_minimize ctxt mode do_learn name (params as {verbose, isar_proofs, minimize, ...})
       
   305     ({state, goal, subgoal, subgoal_count, ...} : prover_problem)
   239     ({state, goal, subgoal, subgoal_count, ...} : prover_problem)
   306     (result as {outcome, used_facts, used_from, run_time, preplay, message, message_tail} :
   240     (result as {outcome, used_facts, used_from, run_time, preplay, message, message_tail} :
   307      prover_result) =
   241      prover_result) =
   308   if is_some outcome orelse null used_facts then
   242   if is_some outcome orelse null used_facts then
   309     result
   243     result
   310   else
   244   else
   311     let
   245     let
   312       val thy = Proof_Context.theory_of ctxt
       
   313 
       
   314       val (minimize_name, params) =
       
   315         if mode = Normal then
       
   316           (case Lazy.force preplay of
       
   317             (meth as Metis_Method _, Played _) =>
       
   318             if isar_proofs = SOME true then
       
   319               (* Cheat: Assume the selected ATP is as fast as "metis" for the goal it proved
       
   320                  itself. *)
       
   321               (isar_supported_prover_of thy name, params)
       
   322             else
       
   323               extract_proof_method params meth
       
   324               ||> (fn override_params => adjust_proof_method_params override_params params)
       
   325           | _ => (name, params))
       
   326         else
       
   327           (name, params)
       
   328 
       
   329       val (used_facts, (preplay, message, _)) =
   246       val (used_facts, (preplay, message, _)) =
   330         if minimize then
   247         if minimize then
   331           minimize_facts do_learn minimize_name params
   248           minimize_facts do_learn name params
   332             (not verbose orelse (mode <> Normal andalso mode <> MaSh)) subgoal subgoal_count state
   249             (not verbose orelse (mode <> Normal andalso mode <> MaSh)) subgoal subgoal_count state
   333             goal (SOME preplay) (filter_used_facts true used_facts (map (apsnd single) used_from))
   250             goal (SOME preplay) (filter_used_facts true used_facts (map (apsnd single) used_from))
   334           |>> Option.map (map fst)
   251           |>> Option.map (map fst)
   335         else
   252         else
   336           (SOME used_facts, (preplay, message, ""))
   253           (SOME used_facts, (preplay, message, ""))
   342       | NONE => result)
   259       | NONE => result)
   343     end
   260     end
   344 
   261 
   345 fun get_minimizing_prover ctxt mode do_learn name params minimize_command problem =
   262 fun get_minimizing_prover ctxt mode do_learn name params minimize_command problem =
   346   get_prover ctxt mode name params minimize_command problem
   263   get_prover ctxt mode name params minimize_command problem
   347   |> maybe_minimize ctxt mode do_learn name params problem
   264   |> maybe_minimize mode do_learn name params problem
   348 
   265 
   349 fun run_minimize (params as {provers, ...}) do_learn i refs state =
   266 fun run_minimize (params as {provers, ...}) do_learn i refs state =
   350   let
   267   let
   351     val ctxt = Proof.context_of state
   268     val ctxt = Proof.context_of state
   352     val {goal, facts = chained_ths, ...} = Proof.goal state
   269     val {goal, facts = chained_ths, ...} = Proof.goal state