src/Tools/try.ML
author blanchet
Fri, 27 May 2011 10:30:08 +0200
changeset 43865 58150aa44941
parent 43862 5910dd009d0e
child 43869 1c451bbb3ad7
permissions -rw-r--r--
prioritize try and auto try's tools, with fast ones first, with a slight preference for provers vs. counterexample generators
blanchet@43859
     1
(*  Title:      Tools/try.ML
blanchet@33552
     2
    Author:     Jasmin Blanchette, TU Muenchen
blanchet@33552
     3
blanchet@43859
     4
Manager for tools that should be tried on conjectures.
blanchet@33552
     5
*)
blanchet@33552
     6
blanchet@43859
     7
signature TRY =
blanchet@33552
     8
sig
blanchet@43861
     9
  type tool =
blanchet@43865
    10
    string * (int * bool Unsynchronized.ref
blanchet@43861
    11
              * (bool -> Proof.state -> bool * (string * Proof.state)))
blanchet@43861
    12
blanchet@43861
    13
  val tryN : string
blanchet@43859
    14
  val auto_time_limit: real Unsynchronized.ref
blanchet@33552
    15
blanchet@43861
    16
  val register_tool : tool -> theory -> theory
blanchet@43861
    17
  val get_tools : theory -> tool list
blanchet@43861
    18
  val try_tools : Proof.state -> (string * string) option
blanchet@33552
    19
end;
blanchet@33552
    20
blanchet@43859
    21
structure Try : TRY =
blanchet@33552
    22
struct
blanchet@33552
    23
blanchet@43861
    24
type tool =
blanchet@43865
    25
  string * (int * bool Unsynchronized.ref
blanchet@43861
    26
            * (bool -> Proof.state -> bool * (string * Proof.state)))
blanchet@43861
    27
blanchet@43861
    28
val tryN = "try"
blanchet@43861
    29
blanchet@43861
    30
blanchet@33552
    31
(* preferences *)
blanchet@33552
    32
blanchet@43859
    33
val auto_time_limit = Unsynchronized.ref 4.0
blanchet@33552
    34
blanchet@43859
    35
val auto_try_time_limitN = "auto-try-time-limit"
blanchet@33552
    36
val _ =
blanchet@33552
    37
  ProofGeneralPgip.add_preference Preferences.category_tracing
blanchet@43859
    38
    (Preferences.real_pref auto_time_limit
blanchet@43859
    39
      auto_try_time_limitN "Time limit for automatically tried tools (in seconds).")
blanchet@33552
    40
blanchet@33552
    41
blanchet@33552
    42
(* configuration *)
blanchet@33552
    43
wenzelm@33600
    44
structure Data = Theory_Data
wenzelm@33600
    45
(
blanchet@43861
    46
  type T = tool list
blanchet@33552
    47
  val empty = []
blanchet@33552
    48
  val extend = I
wenzelm@33600
    49
  fun merge data : T = AList.merge (op =) (K true) data
blanchet@33552
    50
)
blanchet@33552
    51
blanchet@43861
    52
val get_tools = Data.get
blanchet@43861
    53
blanchet@43865
    54
val register_tool = Data.map o Ord_List.insert (int_ord o pairself (#1 o snd))
blanchet@33552
    55
blanchet@43861
    56
(* try command *)
blanchet@33552
    57
blanchet@43861
    58
fun try_tools state =
blanchet@43861
    59
  get_tools (Proof.theory_of state)
blanchet@43865
    60
  |> tap (fn tools => "Trying " ^ commas_quote (map fst tools) ^ "..."
blanchet@43865
    61
                      |> Output.urgent_message)
blanchet@43861
    62
  |> Par_List.get_some
blanchet@43865
    63
         (fn (name, (_, _, tool)) =>
blanchet@43861
    64
             case try (tool false) state of
blanchet@43861
    65
               SOME (true, (outcome_code, _)) => SOME (name, outcome_code)
blanchet@43861
    66
             | _ => NONE)
blanchet@33552
    67
blanchet@43861
    68
val _ =
blanchet@43861
    69
  Outer_Syntax.improper_command tryN
blanchet@43861
    70
      "try a combination of automatic proving and disproving tools" Keyword.diag
blanchet@43861
    71
      (Scan.succeed (Toplevel.keep (ignore o try_tools o Toplevel.proof_of)))
blanchet@43861
    72
blanchet@43861
    73
blanchet@43861
    74
(* automatic try *)
blanchet@43861
    75
blanchet@43861
    76
fun auto_try state =
blanchet@43861
    77
  get_tools (Proof.theory_of state)
blanchet@43865
    78
  |> map_filter (fn (_, (_, auto, tool)) => if !auto then SOME tool else NONE)
blanchet@43861
    79
  |> Par_List.get_some (fn tool =>
blanchet@43861
    80
                           case try (tool true) state of
blanchet@43861
    81
                             SOME (true, (_, state)) => SOME state
blanchet@43861
    82
                           | _ => NONE)
blanchet@43861
    83
  |> the_default state
blanchet@41175
    84
blanchet@41175
    85
(* Too large values are understood as milliseconds, ensuring compatibility with
blanchet@41175
    86
   old setting files. No users can possibly in their right mind want the user
blanchet@41175
    87
   interface to block for more than 100 seconds. *)
blanchet@41175
    88
fun smart_seconds r =
blanchet@41175
    89
  seconds (if r >= 100.0 then
blanchet@43859
    90
             (legacy_feature (quote auto_try_time_limitN ^
blanchet@41175
    91
                " expressed in milliseconds -- use seconds instead"); 0.001 * r)
blanchet@41175
    92
           else
blanchet@41175
    93
             r)
blanchet@41175
    94
blanchet@33552
    95
val _ = Context.>> (Specification.add_theorem_hook (fn interact => fn state =>
blanchet@43859
    96
  if interact andalso not (!Toplevel.quiet) andalso !auto_time_limit > 0.0 then
blanchet@43861
    97
    TimeLimit.timeLimit (smart_seconds (!auto_time_limit)) auto_try state
blanchet@41175
    98
    handle TimeLimit.TimeOut => state
blanchet@41175
    99
  else
blanchet@41175
   100
    state))
blanchet@33552
   101
blanchet@33552
   102
end;