show time taken for reconstruction
authorblanchet
Fri, 27 May 2011 10:30:08 +0200
changeset 43874c4b9b4be90c4
parent 43873 f617a5323d07
child 43875 18259246abb5
show time taken for reconstruction
src/HOL/Tools/Sledgehammer/sledgehammer_atp_reconstruct.ML
src/HOL/Tools/Sledgehammer/sledgehammer_minimize.ML
src/HOL/Tools/Sledgehammer/sledgehammer_provers.ML
src/HOL/Tools/Sledgehammer/sledgehammer_util.ML
     1.1 --- a/src/HOL/Tools/Sledgehammer/sledgehammer_atp_reconstruct.ML	Fri May 27 10:30:08 2011 +0200
     1.2 +++ b/src/HOL/Tools/Sledgehammer/sledgehammer_atp_reconstruct.ML	Fri May 27 10:30:08 2011 +0200
     1.3 @@ -11,14 +11,23 @@
     1.4    type 'a proof = 'a ATP_Proof.proof
     1.5    type locality = Sledgehammer_Filter.locality
     1.6    type type_system = Sledgehammer_ATP_Translate.type_system
     1.7 +
     1.8 +  datatype reconstructor =
     1.9 +    Metis |
    1.10 +    MetisFT |
    1.11 +    SMT of string
    1.12 +
    1.13 +  datatype preplay =
    1.14 +    Preplayed of reconstructor * Time.time |
    1.15 +    Trust_Playable of reconstructor * Time.time option|
    1.16 +    Preplay_Failed
    1.17 +
    1.18    type minimize_command = string list -> string
    1.19 -  type metis_params =
    1.20 -    string * minimize_command * type_system * string proof * int
    1.21 -    * (string * locality) list vector * int list * thm * int
    1.22 +  type one_line_params =
    1.23 +    preplay * string * (string * locality) list * minimize_command * thm * int
    1.24    type isar_params =
    1.25 -    bool * int * string Symtab.table * int list list * int Symtab.table
    1.26 -  type text_result = string * (string * locality) list
    1.27 -
    1.28 +    bool * bool * int * type_system * string Symtab.table * int list list
    1.29 +    * int * (string * locality) list vector * int Symtab.table * string proof
    1.30    val repair_conjecture_shape_and_fact_names :
    1.31      type_system -> string -> int list list -> int
    1.32      -> (string * locality) list vector -> int list
    1.33 @@ -28,19 +37,22 @@
    1.34      -> string proof -> (string * locality) list
    1.35    val used_facts_in_unsound_atp_proof :
    1.36      Proof.context -> type_system -> int list list -> int
    1.37 -    -> (string * locality) list vector -> string proof -> string list option
    1.38 +    -> (string * locality) list vector -> 'a proof -> string list option
    1.39 +  val uses_typed_helpers : int list -> 'a proof -> bool
    1.40 +  val reconstructor_name : reconstructor -> string
    1.41 +  val reconstructor_settings : reconstructor -> string
    1.42    val apply_on_subgoal : string -> int -> int -> string
    1.43    val command_call : string -> string list -> string
    1.44 -  val try_command_line : string -> string -> string
    1.45 +  val try_command_line : string -> (bool * Time.time) option -> string -> string
    1.46    val minimize_line : ('a list -> string) -> 'a list -> string
    1.47    val split_used_facts :
    1.48      (string * locality) list
    1.49      -> (string * locality) list * (string * locality) list
    1.50 -  val metis_proof_text : Proof.context -> metis_params -> text_result
    1.51 +  val one_line_proof_text : one_line_params -> string
    1.52    val isar_proof_text :
    1.53 -    Proof.context -> isar_params -> metis_params -> text_result
    1.54 +    Proof.context -> isar_params -> one_line_params -> string
    1.55    val proof_text :
    1.56 -    Proof.context -> bool -> isar_params -> metis_params -> text_result
    1.57 +    Proof.context -> bool -> isar_params -> one_line_params -> string
    1.58  end;
    1.59  
    1.60  structure Sledgehammer_ATP_Reconstruct : SLEDGEHAMMER_ATP_RECONSTRUCT =
    1.61 @@ -53,13 +65,22 @@
    1.62  open Sledgehammer_Filter
    1.63  open Sledgehammer_ATP_Translate
    1.64  
    1.65 +datatype reconstructor =
    1.66 +  Metis |
    1.67 +  MetisFT |
    1.68 +  SMT of string
    1.69 +
    1.70 +datatype preplay =
    1.71 +  Preplayed of reconstructor * Time.time |
    1.72 +  Trust_Playable of reconstructor * Time.time option |
    1.73 +  Preplay_Failed
    1.74 +
    1.75  type minimize_command = string list -> string
    1.76 -type metis_params =
    1.77 -  string * minimize_command * type_system * string proof * int
    1.78 -  * (string * locality) list vector * int list * thm * int
    1.79 +type one_line_params =
    1.80 +  preplay * string * (string * locality) list * minimize_command * thm * int
    1.81  type isar_params =
    1.82 -  bool * int * string Symtab.table * int list list * int Symtab.table
    1.83 -type text_result = string * (string * locality) list
    1.84 +  bool * bool * int * type_system * string Symtab.table * int list list * int
    1.85 +  * (string * locality) list vector * int Symtab.table * string proof
    1.86  
    1.87  fun is_head_digit s = Char.isDigit (String.sub (s, 0))
    1.88  val scan_integer = Scan.many1 is_head_digit >> (the o Int.fromString o implode)
    1.89 @@ -223,10 +244,25 @@
    1.90        NONE
    1.91    end
    1.92  
    1.93 +fun uses_typed_helpers typed_helpers =
    1.94 +  exists (fn Inference (name, _, []) => is_typed_helper typed_helpers name
    1.95 +           | _ => false)
    1.96 +
    1.97 +
    1.98  (** Soft-core proof reconstruction: Metis one-liner **)
    1.99  
   1.100 +fun reconstructor_name Metis = "metis"
   1.101 +  | reconstructor_name MetisFT = "metisFT"
   1.102 +  | reconstructor_name (SMT _) = "smt"
   1.103 +
   1.104 +fun reconstructor_settings (SMT settings) = settings
   1.105 +  | reconstructor_settings _ = ""
   1.106 +
   1.107  fun string_for_label (s, num) = s ^ string_of_int num
   1.108  
   1.109 +fun show_time NONE = ""
   1.110 +  | show_time (SOME ext_time) = " ~ " ^ string_from_ext_time ext_time
   1.111 +
   1.112  fun set_settings "" = ""
   1.113    | set_settings settings = "using [[" ^ settings ^ "]] "
   1.114  fun apply_on_subgoal settings _ 1 = set_settings settings ^ "by "
   1.115 @@ -235,15 +271,15 @@
   1.116      "prefer " ^ string_of_int i ^ " " ^ apply_on_subgoal settings 1 n
   1.117  fun command_call name [] = name
   1.118    | command_call name args = "(" ^ name ^ " " ^ space_implode " " args ^ ")"
   1.119 -fun try_command_line banner command =
   1.120 -  banner ^ ": " ^ Markup.markup Markup.sendback command ^ "."
   1.121 +fun try_command_line banner time command =
   1.122 +  banner ^ ": " ^ Markup.markup Markup.sendback command ^ show_time time ^ "."
   1.123  fun using_labels [] = ""
   1.124    | using_labels ls =
   1.125      "using " ^ space_implode " " (map string_for_label ls) ^ " "
   1.126 -fun metis_name full_types = if full_types then "metisFT" else "metis"
   1.127 -fun metis_call full_types ss = command_call (metis_name full_types) ss
   1.128 -fun metis_command full_types i n (ls, ss) =
   1.129 -  using_labels ls ^ apply_on_subgoal "" i n ^ metis_call full_types ss
   1.130 +fun reconstructor_command reconstructor i n (ls, ss) =
   1.131 +  using_labels ls ^
   1.132 +  apply_on_subgoal (reconstructor_settings reconstructor) i n ^
   1.133 +  command_call (reconstructor_name reconstructor) ss
   1.134  fun minimize_line _ [] = ""
   1.135    | minimize_line minimize_command ss =
   1.136      case minimize_command ss of
   1.137 @@ -254,24 +290,28 @@
   1.138    List.partition (curry (op =) Chained o snd)
   1.139    #> pairself (sort_distinct (string_ord o pairself fst))
   1.140  
   1.141 -fun uses_typed_helpers typed_helpers =
   1.142 -  exists (fn Inference (name, _, []) => is_typed_helper typed_helpers name
   1.143 -           | _ => false)
   1.144 -
   1.145 -fun metis_proof_text ctxt (banner, minimize_command, type_sys, atp_proof,
   1.146 -                           facts_offset, fact_names, typed_helpers, goal, i) =
   1.147 +fun one_line_proof_text (preplay, banner, used_facts, minimize_command,
   1.148 +                         goal, i) =
   1.149    let
   1.150 -    val (chained, extra) =
   1.151 -      atp_proof |> used_facts_in_atp_proof ctxt type_sys facts_offset fact_names
   1.152 -                |> split_used_facts
   1.153 -    val full_types = uses_typed_helpers typed_helpers atp_proof
   1.154 +    val (chained, extra) = split_used_facts used_facts
   1.155 +    val (reconstructor, ext_time) =
   1.156 +      case preplay of
   1.157 +        Preplayed (reconstructor, time) =>
   1.158 +        (SOME reconstructor, (SOME (false, time)))
   1.159 +      | Trust_Playable (reconstructor, time) =>
   1.160 +        (SOME reconstructor,
   1.161 +         case time of
   1.162 +           NONE => NONE
   1.163 +         | SOME time =>
   1.164 +           if time = Time.zeroTime then NONE else SOME (true, time))
   1.165 +      | Preplay_Failed => (NONE, NONE)
   1.166      val n = Logic.count_prems (prop_of goal)
   1.167 -    val metis = metis_command full_types i n ([], map fst extra)
   1.168 -  in
   1.169 -    (try_command_line banner metis ^
   1.170 -     minimize_line minimize_command (map fst (extra @ chained)),
   1.171 -     extra @ chained)
   1.172 -  end
   1.173 +    val try_line =
   1.174 +      case reconstructor of
   1.175 +        SOME r => reconstructor_command r i n ([], map fst extra)
   1.176 +                  |> try_command_line banner ext_time
   1.177 +      | NONE => "Proof reconstruction failed."
   1.178 +  in try_line ^ minimize_line minimize_command (map fst (extra @ chained)) end
   1.179  
   1.180  (** Hard-core proof reconstruction: structured Isar proofs **)
   1.181  
   1.182 @@ -702,8 +742,8 @@
   1.183        s
   1.184  
   1.185  fun isar_proof_from_atp_proof pool ctxt type_sys tfrees isar_shrink_factor
   1.186 -        atp_proof conjecture_shape facts_offset fact_names sym_tab params
   1.187 -        frees =
   1.188 +        conjecture_shape facts_offset fact_names sym_tab params frees
   1.189 +        atp_proof =
   1.190    let
   1.191      val lines =
   1.192        atp_proof
   1.193 @@ -976,10 +1016,11 @@
   1.194         else
   1.195           if member (op =) qs Show then "show" else "have")
   1.196      val do_term = maybe_quote o fix_print_mode (Syntax.string_of_term ctxt)
   1.197 +    val reconstructor = if full_types then MetisFT else Metis
   1.198      fun do_facts (ls, ss) =
   1.199 -      metis_command full_types 1 1
   1.200 -                    (ls |> sort_distinct (prod_ord string_ord int_ord),
   1.201 -                     ss |> sort_distinct string_ord)
   1.202 +      reconstructor_command reconstructor 1 1
   1.203 +          (ls |> sort_distinct (prod_ord string_ord int_ord),
   1.204 +           ss |> sort_distinct string_ord)
   1.205      and do_step ind (Fix xs) =
   1.206          do_indent ind ^ "fix " ^ space_implode " and " (map do_free xs) ^ "\n"
   1.207        | do_step ind (Let (t1, t2)) =
   1.208 @@ -1012,20 +1053,20 @@
   1.209    in do_proof end
   1.210  
   1.211  fun isar_proof_text ctxt
   1.212 -        (debug, isar_shrink_factor, pool, conjecture_shape, sym_tab)
   1.213 -        (metis_params as (_, _, type_sys, atp_proof, facts_offset, fact_names,
   1.214 -                          typed_helpers, goal, i)) =
   1.215 +        (debug, full_types, isar_shrink_factor, type_sys, pool,
   1.216 +         conjecture_shape, facts_offset, fact_names, sym_tab, atp_proof)
   1.217 +        (one_line_params as (_, _, _, _, goal, i)) =
   1.218    let
   1.219      val (params, hyp_ts, concl_t) = strip_subgoal ctxt goal i
   1.220      val frees = fold Term.add_frees (concl_t :: hyp_ts) []
   1.221      val tfrees = fold Term.add_tfrees (concl_t :: hyp_ts) []
   1.222 -    val full_types = uses_typed_helpers typed_helpers atp_proof
   1.223      val n = Logic.count_prems (prop_of goal)
   1.224 -    val (one_line_proof, lemma_names) = metis_proof_text ctxt metis_params
   1.225 +    val one_line_proof = one_line_proof_text one_line_params
   1.226      fun isar_proof_for () =
   1.227 -      case isar_proof_from_atp_proof pool ctxt type_sys tfrees
   1.228 -               isar_shrink_factor atp_proof conjecture_shape facts_offset
   1.229 -               fact_names sym_tab params frees
   1.230 +      case atp_proof
   1.231 +           |> isar_proof_from_atp_proof pool ctxt type_sys tfrees
   1.232 +                  isar_shrink_factor conjecture_shape facts_offset
   1.233 +                  fact_names sym_tab params frees
   1.234             |> redirect_proof hyp_ts concl_t
   1.235             |> kill_duplicate_assumptions_in_proof
   1.236             |> then_chain_proof
   1.237 @@ -1040,9 +1081,13 @@
   1.238        else
   1.239          try isar_proof_for ()
   1.240          |> the_default "\nWarning: The Isar proof construction failed."
   1.241 -  in (one_line_proof ^ isar_proof, lemma_names) end
   1.242 +  in one_line_proof ^ isar_proof end
   1.243  
   1.244 -fun proof_text ctxt isar_proof isar_params =
   1.245 -  if isar_proof then isar_proof_text ctxt isar_params else metis_proof_text ctxt
   1.246 +fun proof_text ctxt isar_proof isar_params
   1.247 +               (one_line_params as (preplay, _, _, _, _, _)) =
   1.248 +  (if isar_proof orelse preplay = Preplay_Failed then
   1.249 +     isar_proof_text ctxt isar_params
   1.250 +   else
   1.251 +     one_line_proof_text) one_line_params
   1.252  
   1.253  end;
     2.1 --- a/src/HOL/Tools/Sledgehammer/sledgehammer_minimize.ML	Fri May 27 10:30:08 2011 +0200
     2.2 +++ b/src/HOL/Tools/Sledgehammer/sledgehammer_minimize.ML	Fri May 27 10:30:08 2011 +0200
     2.3 @@ -11,7 +11,6 @@
     2.4    type params = Sledgehammer_Provers.params
     2.5  
     2.6    val binary_min_facts : int Config.T
     2.7 -  val filter_used_facts : ''a list -> (''a * 'b) list -> (''a * 'b) list
     2.8    val minimize_facts :
     2.9      string -> params -> bool option -> bool -> int -> int -> Proof.state
    2.10      -> ((string * locality) * thm list) list
    2.11 @@ -97,8 +96,6 @@
    2.12    Attrib.setup_config_int @{binding sledgehammer_minimize_binary_min_facts}
    2.13                            (K 20)
    2.14  
    2.15 -fun filter_used_facts used = filter (member (op =) used o fst)
    2.16 -
    2.17  fun sublinear_minimize _ [] p = p
    2.18    | sublinear_minimize test (x :: xs) (seen, result) =
    2.19      case test (xs @ seen) of
    2.20 @@ -204,7 +201,7 @@
    2.21             | prover :: _ =>
    2.22               (kill_provers ();
    2.23                minimize_facts prover params NONE false i n state facts
    2.24 -              |> #2 |> Output.urgent_message)
    2.25 +              |> snd |> Output.urgent_message)
    2.26    end
    2.27  
    2.28  end;
     3.1 --- a/src/HOL/Tools/Sledgehammer/sledgehammer_provers.ML	Fri May 27 10:30:08 2011 +0200
     3.2 +++ b/src/HOL/Tools/Sledgehammer/sledgehammer_provers.ML	Fri May 27 10:30:08 2011 +0200
     3.3 @@ -99,6 +99,7 @@
     3.4    val kill_provers : unit -> unit
     3.5    val running_provers : unit -> unit
     3.6    val messages : int option -> unit
     3.7 +  val filter_used_facts : ''a list -> (''a * 'b) list -> (''a * 'b) list
     3.8    val get_prover : Proof.context -> mode -> string -> prover
     3.9  end;
    3.10  
    3.11 @@ -306,6 +307,7 @@
    3.12  
    3.13  type prover = params -> minimize_command -> prover_problem -> prover_result
    3.14  
    3.15 +
    3.16  (* configuration attributes *)
    3.17  
    3.18  val dest_dir =
    3.19 @@ -318,20 +320,6 @@
    3.20  val measure_run_time =
    3.21    Attrib.setup_config_bool @{binding sledgehammer_measure_run_time} (K false)
    3.22  
    3.23 -fun with_path cleanup after f path =
    3.24 -  Exn.capture f path
    3.25 -  |> tap (fn _ => cleanup path)
    3.26 -  |> Exn.release
    3.27 -  |> tap (after path)
    3.28 -
    3.29 -fun proof_banner mode blocking name =
    3.30 -  case mode of
    3.31 -    Auto_Try => "Auto Sledgehammer (" ^ quote name ^ ") found a proof"
    3.32 -  | Try => "Sledgehammer (" ^ quote name ^ ") found a proof"
    3.33 -  | Normal => if blocking then quote name ^ " found a proof"
    3.34 -              else "Try this"
    3.35 -  | Minimize => "Try this"
    3.36 -
    3.37  val smt_triggers =
    3.38    Attrib.setup_config_bool @{binding sledgehammer_smt_triggers} (K true)
    3.39  val smt_weights =
    3.40 @@ -379,6 +367,41 @@
    3.41  fun overlord_file_location_for_prover prover =
    3.42    (getenv "ISABELLE_HOME_USER", "prob_" ^ prover)
    3.43  
    3.44 +fun with_path cleanup after f path =
    3.45 +  Exn.capture f path
    3.46 +  |> tap (fn _ => cleanup path)
    3.47 +  |> Exn.release
    3.48 +  |> tap (after path)
    3.49 +
    3.50 +fun proof_banner mode blocking name =
    3.51 +  case mode of
    3.52 +    Auto_Try => "Auto Sledgehammer (" ^ quote name ^ ") found a proof"
    3.53 +  | Try => "Sledgehammer (" ^ quote name ^ ") found a proof"
    3.54 +  | Normal => if blocking then quote name ^ " found a proof"
    3.55 +              else "Try this"
    3.56 +  | Minimize => "Try this"
    3.57 +
    3.58 +(* based on "Mirabelle.can_apply" and generalized *)
    3.59 +fun try_apply timeout tac state i =
    3.60 +  let
    3.61 +    val {context = ctxt, facts, goal} = Proof.goal state
    3.62 +    val full_tac = Method.insert_tac facts i THEN tac ctxt i
    3.63 +  in try (TimeLimit.timeLimit timeout (Seq.pull o full_tac)) goal end
    3.64 +
    3.65 +fun try_metis debug timeout ths =
    3.66 +  try_apply timeout (Config.put Metis_Tactics.verbose debug
    3.67 +                     #> (fn ctxt => Metis_Tactics.metis_tac ctxt ths))
    3.68 +
    3.69 +fun filter_used_facts used = filter (member (op =) used o fst)
    3.70 +
    3.71 +fun preplay_one_line_proof debug reconstructor_guess timeout ths state i =
    3.72 +  let val timer = Timer.startRealTimer () in
    3.73 +    case try_metis debug timeout ths state i of
    3.74 +      SOME (SOME _) => Preplayed (Metis, Timer.checkRealTimer timer)
    3.75 +    | SOME NONE => Preplay_Failed
    3.76 +    | NONE => Trust_Playable (reconstructor_guess, SOME timeout)
    3.77 +  end
    3.78 +
    3.79  
    3.80  (* generic TPTP-based ATPs *)
    3.81  
    3.82 @@ -485,7 +508,7 @@
    3.83            conj_sym_kind, prem_kind, formats, best_slices, ...} : atp_config)
    3.84          ({debug, verbose, overlord, blocking, type_sys, max_relevant,
    3.85            max_mono_iters, max_new_mono_instances, explicit_apply, isar_proof,
    3.86 -          isar_shrink_factor, slicing, timeout, ...} : params)
    3.87 +          isar_shrink_factor, slicing, timeout, preplay_timeout, ...} : params)
    3.88          minimize_command ({state, goal, subgoal, facts, ...} : prover_problem) =
    3.89    let
    3.90      val thy = Proof.theory_of state
    3.91 @@ -708,7 +731,7 @@
    3.92          extract_important_message output
    3.93        else
    3.94          ""
    3.95 -    fun append_to_message message =
    3.96 +    fun complete_message message =
    3.97        message ^
    3.98        (if verbose then
    3.99           "\nATP real CPU time: " ^
   3.100 @@ -719,21 +742,34 @@
   3.101           "\n\nImportant message from Dr. Geoff Sutcliffe:\n" ^ important_message
   3.102         else
   3.103           "")
   3.104 -    val isar_params =
   3.105 -      (debug, isar_shrink_factor, pool, conjecture_shape, sym_tab)
   3.106 -    val metis_params =
   3.107 -      (proof_banner mode blocking name, minimize_command, type_sys, atp_proof,
   3.108 -       facts_offset, fact_names, typed_helpers, goal, subgoal)
   3.109      val (outcome, (message, used_facts)) =
   3.110        case outcome of
   3.111          NONE =>
   3.112 -        (NONE, proof_text ctxt isar_proof isar_params metis_params
   3.113 -               |>> append_to_message)
   3.114 -      | SOME failure =>
   3.115 -        if failure = ProofMissing orelse failure = ProofIncomplete then
   3.116 -          (NONE, metis_proof_text ctxt metis_params |>> append_to_message)
   3.117 -        else
   3.118 -          (outcome, (string_for_failure failure, []))
   3.119 +        let
   3.120 +          val used_facts =
   3.121 +            used_facts_in_atp_proof ctxt type_sys facts_offset fact_names
   3.122 +                                    atp_proof
   3.123 +          val reconstructor_guess =
   3.124 +            if uses_typed_helpers typed_helpers atp_proof then MetisFT
   3.125 +            else Metis
   3.126 +          val ths = facts |> map untranslated_fact
   3.127 +                          |> filter_used_facts used_facts
   3.128 +                          |> map snd
   3.129 +          val preplay =
   3.130 +            preplay_one_line_proof debug reconstructor_guess preplay_timeout ths
   3.131 +                                   state subgoal
   3.132 +          val full_types = uses_typed_helpers typed_helpers atp_proof
   3.133 +          val isar_params =
   3.134 +            (debug, full_types, isar_shrink_factor, type_sys, pool,
   3.135 +             conjecture_shape, facts_offset, fact_names, sym_tab, atp_proof)
   3.136 +          val one_line_params =
   3.137 +            (preplay, proof_banner mode blocking name, used_facts,
   3.138 +             minimize_command, goal, subgoal)
   3.139 +        in
   3.140 +          (NONE, (proof_text ctxt isar_proof isar_params one_line_params
   3.141 +                  |> complete_message, used_facts))
   3.142 +        end
   3.143 +      | SOME failure => (outcome, (string_for_failure failure, []))
   3.144    in
   3.145      {outcome = outcome, message = message, used_facts = used_facts,
   3.146       run_time_in_msecs = msecs}
   3.147 @@ -877,30 +913,6 @@
   3.148        end
   3.149    in do_slice timeout 1 NONE Time.zeroTime end
   3.150  
   3.151 -(* based on "Mirabelle.can_apply" and generalized *)
   3.152 -fun try_apply timeout tac state i =
   3.153 -  let
   3.154 -    val {context = ctxt, facts, goal} = Proof.goal state
   3.155 -    val full_tac = Method.insert_tac facts i THEN tac ctxt i
   3.156 -  in try (TimeLimit.timeLimit timeout (Seq.pull o full_tac)) goal end
   3.157 -
   3.158 -fun try_metis debug timeout ths =
   3.159 -  try_apply timeout (Config.put Metis_Tactics.verbose debug
   3.160 -                     #> (fn ctxt => Metis_Tactics.metis_tac ctxt ths))
   3.161 -
   3.162 -datatype metis_try =
   3.163 -  Preplayed of string * Time.time |
   3.164 -  Preplay_Timed_Out |
   3.165 -  Preplay_Failed
   3.166 -
   3.167 -fun preplay debug timeout ths state i =
   3.168 -  let val timer = Timer.startRealTimer () in
   3.169 -    case try_metis debug timeout ths state i of
   3.170 -      SOME (SOME _) => Preplayed ("metis", Timer.checkRealTimer timer)
   3.171 -    | SOME NONE => Preplay_Failed
   3.172 -    | NONE => Preplay_Timed_Out
   3.173 -  end
   3.174 -
   3.175  fun run_smt_solver mode name
   3.176          (params as {debug, verbose, blocking, preplay_timeout, ...})
   3.177          minimize_command
   3.178 @@ -920,14 +932,15 @@
   3.179          NONE =>
   3.180          let
   3.181            val (settings, method, time) =
   3.182 -            case preplay debug preplay_timeout (map snd used_facts) state
   3.183 -                         subgoal of
   3.184 -              Preplayed (method, time) => (method, "", SOME time)
   3.185 +            case preplay_one_line_proof debug Metis preplay_timeout
   3.186 +                    (map snd used_facts) state subgoal of
   3.187 +              Preplayed (method, time) =>
   3.188 +              ("", reconstructor_name method, SOME (false, time))
   3.189              | _ => (if name = SMT_Solver.solver_name_of ctxt then ""
   3.190                      else "smt_solver = " ^ maybe_quote name,
   3.191                      "smt", NONE)
   3.192          in
   3.193 -          try_command_line (proof_banner mode blocking name)
   3.194 +          try_command_line (proof_banner mode blocking name) time
   3.195                (apply_on_subgoal settings subgoal subgoal_count ^
   3.196                 command_call method (map fst other_lemmas)) ^
   3.197            minimize_line minimize_command
     4.1 --- a/src/HOL/Tools/Sledgehammer/sledgehammer_util.ML	Fri May 27 10:30:08 2011 +0200
     4.2 +++ b/src/HOL/Tools/Sledgehammer/sledgehammer_util.ML	Fri May 27 10:30:08 2011 +0200
     4.3 @@ -11,6 +11,7 @@
     4.4    val simplify_spaces : string -> string
     4.5    val parse_bool_option : bool -> string -> string -> bool option
     4.6    val parse_time_option : string -> string -> Time.time option
     4.7 +  val string_from_ext_time : bool * Time.time -> string
     4.8    val string_from_time : Time.time -> string
     4.9    val nat_subscript : int -> string
    4.10    val unyxml : string -> string
    4.11 @@ -67,8 +68,14 @@
    4.12          SOME (seconds (the secs))
    4.13      end
    4.14  
    4.15 -fun string_from_time t =
    4.16 -  string_of_real (0.01 * Real.fromInt (Time.toMilliseconds t div 10)) ^ " s"
    4.17 +fun string_from_ext_time (plus, time) =
    4.18 +  let val ms = Time.toMilliseconds time in
    4.19 +    if plus then signed_string_of_int ((ms + 999) div 1000) ^ "+ s"
    4.20 +    else if ms < 1000 then signed_string_of_int ms ^ " ms"
    4.21 +    else string_of_real (0.01 * Real.fromInt (ms div 10)) ^ " s"
    4.22 +  end
    4.23 +
    4.24 +val string_from_time = string_from_ext_time o pair false
    4.25  
    4.26  val subscript = implode o map (prefix "\<^isub>") o raw_explode  (* FIXME Symbol.explode (?) *)
    4.27  fun nat_subscript n =