src/HOL/Tools/Sledgehammer/sledgehammer_util.ML
author blanchet
Wed, 18 Jul 2012 08:44:03 +0200
changeset 49307 7fcee834c7f5
parent 49266 6cdcfbddc077
child 49331 252f45c04042
permissions -rw-r--r--
more code rationalization in relevance filter
     1 (*  Title:      HOL/Tools/Sledgehammer/sledgehammer_util.ML
     2     Author:     Jasmin Blanchette, TU Muenchen
     3 
     4 General-purpose functions used by the Sledgehammer modules.
     5 *)
     6 
     7 signature SLEDGEHAMMER_UTIL =
     8 sig
     9   val plural_s : int -> string
    10   val serial_commas : string -> string list -> string list
    11   val simplify_spaces : string -> string
    12   val parse_bool_option : bool -> string -> string -> bool option
    13   val parse_time_option : string -> string -> Time.time option
    14   val subgoal_count : Proof.state -> int
    15   val reserved_isar_keyword_table : unit -> unit Symtab.table
    16   val thms_in_proof : string list option -> thm -> string list
    17 end;
    18 
    19 structure Sledgehammer_Util : SLEDGEHAMMER_UTIL =
    20 struct
    21 
    22 open ATP_Util
    23 
    24 fun plural_s n = if n = 1 then "" else "s"
    25 
    26 val serial_commas = Try.serial_commas
    27 val simplify_spaces = strip_spaces false (K true)
    28 
    29 fun parse_bool_option option name s =
    30   (case s of
    31      "smart" => if option then NONE else raise Option
    32    | "false" => SOME false
    33    | "true" => SOME true
    34    | "" => SOME true
    35    | _ => raise Option)
    36   handle Option.Option =>
    37          let val ss = map quote ((option ? cons "smart") ["true", "false"]) in
    38            error ("Parameter " ^ quote name ^ " must be assigned " ^
    39                   space_implode " " (serial_commas "or" ss) ^ ".")
    40          end
    41 
    42 val has_junk =
    43   exists (fn s => not (Symbol.is_digit s) andalso s <> ".") o raw_explode (* FIXME Symbol.explode (?) *)
    44 
    45 fun parse_time_option _ "none" = NONE
    46   | parse_time_option name s =
    47     let val secs = if has_junk s then NONE else Real.fromString s in
    48       if is_none secs orelse Real.< (the secs, 0.0) then
    49         error ("Parameter " ^ quote name ^ " must be assigned a nonnegative \
    50                \number of seconds (e.g., \"60\", \"0.5\") or \"none\".")
    51       else
    52         SOME (seconds (the secs))
    53     end
    54 
    55 val subgoal_count = Try.subgoal_count
    56 
    57 fun reserved_isar_keyword_table () =
    58   Keyword.dest () |-> union (op =) |> map (rpair ()) |> Symtab.make
    59 
    60 (* FIXME: Similar yet different code in "mirabelle.ML". The code here has a few
    61    fixes that seem to be missing over there; or maybe the two code portions are
    62    not doing the same? *)
    63 fun fold_body_thms thm_name f =
    64   let
    65     fun app n (PBody {thms, ...}) =
    66       thms |> fold (fn (_, (name, prop, body)) => fn x =>
    67         let
    68           val body' = Future.join body
    69           val n' =
    70             n + (if name = "" orelse
    71                     (* uncommon case where the proved theorem occurs twice
    72                        (e.g., "Transitive_Closure.trancl_into_trancl") *)
    73                     (n = 1 andalso name = thm_name) then
    74                    0
    75                  else
    76                    1)
    77           val x' = x |> n' <= 1 ? app n' body'
    78         in (x' |> n = 1 ? f (name, prop, body')) end)
    79   in fold (app 0) end
    80 
    81 fun thms_in_proof all_names th =
    82   let
    83     val is_name_ok =
    84       case all_names of
    85         SOME names => member (op =) names
    86       | NONE => (fn s => s <> "" andalso not (String.isPrefix "Pure." s))
    87     fun collect (s, _, _) = is_name_ok s ? insert (op =) s
    88     val names =
    89       [] |> fold_body_thms (Thm.get_name_hint th) collect [Thm.proof_body_of th]
    90   in names end
    91 
    92 end;