signature SLEDGEHAMMER_PROVER_MINIMIZE = sig type stature = ATP_Problem_Generate.stature type proof_method = Sledgehammer_Proof_Methods.proof_method type play_outcome = Sledgehammer_Proof_Methods.play_outcome type mode = Sledgehammer_Prover.mode type params = Sledgehammer_Prover.params type prover = Sledgehammer_Prover.prover type prover_slice = Sledgehammer_Prover.prover_slice type prover_result = Sledgehammer_Prover.prover_result
val is_prover_supported : Proof.context -> string -> bool val is_prover_installed : Proof.context -> string -> bool val get_prover : Proof.context -> mode -> string -> prover val get_slices : Proof.context -> string -> prover_slice list
val binary_min_facts : int Config.T val minimize_facts : (thm list -> unit) -> string -> params -> prover_slice -> bool -> int ->
int -> Proof.state -> thm -> ((string * stature) * thm list) list -> prover_result ->
((string * stature) * thm list) listoption
* (((Pretty.T * stature) list * (proof_method * play_outcome)) option -> string) val get_minimizing_prover : Proof.context -> mode -> (thm list -> unit) -> string -> prover end;
open ATP_Util open ATP_Proof open ATP_Problem_Generate open ATP_Proof_Reconstruct open Sledgehammer_Util open Sledgehammer_Fact open Sledgehammer_Proof_Methods open Sledgehammer_Isar open Sledgehammer_ATP_Systems open Sledgehammer_Prover open Sledgehammer_Prover_ATP open Sledgehammer_Prover_SMT open Sledgehammer_Prover_Tactic
fun is_prover_supported ctxt =
is_atp orf is_smt_solver ctxt orf is_tactic_prover
fun is_prover_installed ctxt prover_name = if is_atp prover_name then letval thy = Proof_Context.theory_of ctxt in
is_atp_installed thy prover_name end elseif is_smt_solver ctxt prover_name then
is_smt_solver_installed ctxt prover_name else true
fun get_prover ctxt mode name = if is_atp name then run_atp mode name elseif is_smt_solver ctxt name then run_smt_solver mode name elseif is_tactic_prover name then run_tactic_prover mode name else error ("No such prover: " ^ name)
fun get_slices ctxt name = letval thy = Proof_Context.theory_of ctxt in if is_atp name then map (apsnd ATP_Slice) (#good_slices (get_atp thy name ()) ctxt) elseif is_smt_solver ctxt name then map (apsnd SMT_Slice) (SMT_Solver.good_slices ctxt name) elseif is_tactic_prover name then map (rpair No_Slice) (good_slices_of_tactic_prover name) else
error ("No such prover: " ^ name) end
(* wrapper for calling external prover *)
fun n_facts names = letval n = length names in
string_of_int n ^ " fact" ^ plural_s n ^
(if n > 0then": " ^ (names |> map fst |> sort string_ord |> implode_space) else"") end
funprint silent f = if silent then () else writeln (f ())
val facts = facts |> maps (fn (n, ths) => map (pair n) ths) val params =
{debug = debug, verbose = verbose, overlord = overlord, spy = spy, provers = provers,
type_enc = type_enc, abduce = SOME 0, falsify = SOME false, strict = strict,
lam_trans = lam_trans, uncurried_aliases = uncurried_aliases, learn = false,
fact_filter = NONE, induction_rules = induction_rules, max_facts = SOME (length facts),
fact_thresholds = (1.01, 1.01), max_mono_iters = max_mono_iters,
max_new_mono_instances = max_new_mono_instances, max_proofs = 1,
isar_proofs = isar_proofs, compress = compress, try0 = try0, smt_proofs = smt_proofs,
instantiate = instantiate, minimize = minimize, slices = 1, timeout = timeout,
preplay_timeout = preplay_timeout, expect = "", cache_dir = cache_dir} val problem =
{comment = "", state = state, goal = goal, subgoal = i, subgoal_count = n,
factss = [("", facts)], has_already_found_something = K false, found_something = K (),
memoize_fun_call = (fn f => f)} val result0 as {outcome = outcome0, used_facts, used_from, preferred_methss, run_time,
message} =
prover params problem ((1, false, false, length facts, fact_filter), slice_extra) val result as {outcome, ...} = if is_none outcome0 andalso
forall (member (fn ((s, _), ((s', _), _)) => s = s') used_from) used_facts then
result0 else
{outcome = SOME MaybeUnprovable, used_facts = [], used_from = used_from,
preferred_methss = preferred_methss, run_time = run_time, message = message} in print silent (fn () =>
(case outcome of
SOME failure => string_of_atp_failure failure
| NONE => "Found " ^ (if falsify then"falsification"else"proof") ^
(if length used_facts = length facts then""else" with " ^ n_facts used_facts) ^ " (" ^ string_of_time run_time ^ ")"));
result end
(* Give the external prover some slack. The ATP gets further slack because the Sledgehammerpreprocessingtimeisincludedintheestimatebelowbutisn't
part of the timeout. *) val slack_msecs = 200
(* The linear algorithm usually outperforms the binary algorithm when over 60% ofthefactsareactuallyneeded.Thebinaryalgorithmismuchmore appropriateforproversthatcannotreturnthelistofusedfactsandhence returnsallfactsasused.Sincewecannotknowinadvancehowmanyfactsare
actually needed, we heuristically set the threshold. *) val binary_min_facts =
Attrib.setup_config_int \<^binding>\<open>sledgehammer_minimize_binary_min_facts\<close> (K 20)
fun linear_minimize test timeout result xs = let fun min _ [] p = p
| min timeout (x :: xs) (seen, result) =
(casetest timeout (seen @ xs) of
result as {outcome = NONE, used_facts, run_time, ...} : prover_result =>
min (new_timeout timeout run_time) (filter_used_facts true used_facts xs)
(filter_used_facts false used_facts seen, result)
| _ => min timeout xs (seen @ [x], result)) in
min timeout xs ([], result) end
fun binary_minimize test timeout result xs = let fun min depth (result as {run_time, ...} : prover_result) sup (xs as _ :: _ :: _) = let val (l0, r0) = chop (length xs div 2) xs (* val_=warning(Symbol.spacesdepth^"{"^"sup:"^n_facts(mapfstsup)) val_=warning(Symbol.spacesdepth^""^"xs:"^n_facts(mapfstxs)) val_=warning(Symbol.spacesdepth^""^"l0:"^n_facts(mapfstl0)) val_=warning(Symbol.spacesdepth^""^"r0:"^n_facts(mapfstr0))
*) val depth = depth + 1 val timeout = new_timeout timeout run_time in
(casetest timeout (sup @ l0) of
result as {outcome = NONE, used_facts, ...} =>
min depth result (filter_used_facts true used_facts sup)
(filter_used_facts true used_facts l0)
| _ =>
(casetest timeout (sup @ r0) of
result as {outcome = NONE, used_facts, ...} =>
min depth result (filter_used_facts true used_facts sup)
(filter_used_facts true used_facts r0)
| _ => let val (sup_r0, (l, result)) = min depth result (sup @ r0) l0 val (sup, r0) = (sup, r0) |> apply2 (filter_used_facts true (map fst sup_r0)) val (sup_l, (r, result)) = min depth result (sup @ l) r0 val sup = sup |> filter_used_facts true (map fst sup_l) in (sup, (l @ r, result)) end)) end (* |>tap(fn_=>warning(Symbol.spacesdepth^"}"))
*)
| min _ result sup xs = (sup, (xs, result)) in
(case snd (min 0 result [] xs) of
([x], result as {run_time, ...}) =>
(casetest (new_timeout timeout run_time) [] of
result as {outcome = NONE, ...} => ([], result)
| _ => ([x], result))
| p => p) end
fun minimize_facts do_learn prover_name (params as {learn, timeout, ...}) slice silent i n state
goal facts result = let val ctxt = Proof.context_of state val prover = get_prover ctxt Minimize prover_name val (chained, non_chained) = List.partition is_fact_chained facts
funtest timeout non_chained =
test_facts params slice silent prover timeout i n state goal (chained @ non_chained)
fun minimize used_facts (result as {run_time, ...}) = let val non_chained = filter_used_facts true used_facts non_chained val min = if length non_chained >= Config.get ctxt binary_min_facts then binary_minimize else linear_minimize val (min_facts, {message, ...}) =
min test (new_timeout timeout run_time) result non_chained val min_facts_and_chained = chained @ min_facts in print silent (fn () => cat_lines
["Minimized to " ^ n_facts (map fst min_facts)] ^
(case length chained of 0 => ""
| n => " (plus " ^ string_of_int n ^ " chained)"));
(if learn then do_learn (maps snd min_facts_and_chained) else ());
(SOME min_facts_and_chained, message) end in
(print silent (fn () => "Sledgehammer minimizer: " ^ prover_name); if is_tactic_prover prover_name then
minimize (map fst facts) result else
(casetest timeout non_chained of
result as {outcome = NONE, used_facts, ...} => minimize used_facts result
| {outcome = SOME TimedOut, ...} =>
(NONE, fn _ => "Timeout: You can increase the time limit using the \"timeout\" option (e.g., \
\timeout = " ^ string_of_int (10 + Time.toMilliseconds timeout div 1000) ^ "\")")
| {message, ...} => (NONE, (prefix "Prover error: " o message)))) handle ERROR msg => (NONE, fn _ => "Warning: " ^ msg) end
fun maybe_minimize mode do_learn name (params as {verbose, minimize, ...})
({state, goal, subgoal, subgoal_count, ...} : prover_problem) slice
(result as {outcome, used_facts, used_from, preferred_methss, run_time, message}
: prover_result) = if is_some outcome then
result else let val (used_facts, message) = if minimize then
minimize_facts do_learn name params slice
(not verbose orelse (mode <> Normal andalso mode <> MaSh)) subgoal subgoal_count state
goal (filter_used_facts true used_facts (map (apsnd single) used_from)) result
|>> Option.map (map fst) else
(SOME used_facts, message) in
(case used_facts of
SOME used_facts =>
{outcome = NONE, used_facts = sort_by fst used_facts, used_from = used_from,
preferred_methss = preferred_methss, run_time = run_time, message = message}
| NONE => result) end
fun get_minimizing_prover ctxt mode do_learn name params problem slice =
get_prover ctxt mode name params problem slice
|> maybe_minimize mode do_learn name params problem slice
end;
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.