src/HOL/Tools/try.ML
changeset 39336 1899349a5026
parent 39334 c0bb925ae912
child 39547 5df45da44bfb
equal deleted inserted replaced
39335:87a9ff4d5817 39336:1899349a5026
     5 *)
     5 *)
     6 
     6 
     7 signature TRY =
     7 signature TRY =
     8 sig
     8 sig
     9   val auto : bool Unsynchronized.ref
     9   val auto : bool Unsynchronized.ref
    10   val invoke_try : Proof.state -> unit
    10   val invoke_try : Time.time option -> Proof.state -> bool
    11   val setup : theory -> theory
    11   val setup : theory -> theory
    12 end;
    12 end;
    13 
    13 
    14 structure Try : TRY =
    14 structure Try : TRY =
    15 struct
    15 struct
    20   ProofGeneralPgip.add_preference Preferences.category_tracing
    20   ProofGeneralPgip.add_preference Preferences.category_tracing
    21   (setmp_noncritical auto true (fn () =>
    21   (setmp_noncritical auto true (fn () =>
    22     Preferences.bool_pref auto
    22     Preferences.bool_pref auto
    23       "auto-try" "Try standard proof methods.") ());
    23       "auto-try" "Try standard proof methods.") ());
    24 
    24 
    25 val timeout = Time.fromSeconds 5
    25 val default_timeout = Time.fromSeconds 5
    26 
    26 
    27 fun can_apply auto pre post tac st =
    27 fun can_apply timeout_opt pre post tac st =
    28   let val {goal, ...} = Proof.goal st in
    28   let val {goal, ...} = Proof.goal st in
    29     case (if auto then fn f => fn x => f x
    29     case (case timeout_opt of
    30           else TimeLimit.timeLimit timeout) (Seq.pull o tac) (pre st) of
    30             SOME timeout => TimeLimit.timeLimit timeout
       
    31           | NONE => fn f => fn x => f x) (Seq.pull o tac) (pre st) of
    31       SOME (x, _) => nprems_of (post x) < nprems_of goal
    32       SOME (x, _) => nprems_of (post x) < nprems_of goal
    32     | NONE => false
    33     | NONE => false
    33   end
    34   end
    34 
    35 
    35 fun do_generic auto command pre post apply st =
    36 fun do_generic timeout_opt command pre post apply st =
    36   let val timer = Timer.startRealTimer () in
    37   let val timer = Timer.startRealTimer () in
    37     if can_apply auto pre post apply st then
    38     if can_apply timeout_opt pre post apply st then
    38       SOME (command, Time.toMilliseconds (Timer.checkRealTimer timer))
    39       SOME (command, Time.toMilliseconds (Timer.checkRealTimer timer))
    39     else
    40     else
    40       NONE
    41       NONE
    41   end
    42   end
    42 
    43 
    46 fun apply_named_method name ctxt =
    47 fun apply_named_method name ctxt =
    47   let val thy = ProofContext.theory_of ctxt in
    48   let val thy = ProofContext.theory_of ctxt in
    48     Method.apply (named_method thy name) ctxt []
    49     Method.apply (named_method thy name) ctxt []
    49   end
    50   end
    50 
    51 
    51 fun do_named_method name auto st =
    52 fun do_named_method name timeout_opt st =
    52   do_generic auto name (#goal o Proof.goal) snd
    53   do_generic timeout_opt name (#goal o Proof.goal) snd
    53              (apply_named_method name (Proof.context_of st)) st
    54              (apply_named_method name (Proof.context_of st)) st
    54 
    55 
    55 fun apply_named_method_on_first_goal name ctxt =
    56 fun apply_named_method_on_first_goal name ctxt =
    56   let val thy = ProofContext.theory_of ctxt in
    57   let val thy = ProofContext.theory_of ctxt in
    57     Proof.refine (Method.SelectGoals (1, Method.Basic (named_method thy name)))
    58     Proof.refine (Method.SelectGoals (1, Method.Basic (named_method thy name)))
    58   end
    59   end
    59 
    60 
    60 fun do_named_method_on_first_goal name auto st =
    61 fun do_named_method_on_first_goal name timeout_opt st =
    61   do_generic auto (name ^ (if nprems_of (#goal (Proof.goal st)) > 1 then "[1]"
    62   do_generic timeout_opt
       
    63              (name ^ (if nprems_of (#goal (Proof.goal st)) > 1 then "[1]"
    62                       else "")) I (#goal o Proof.goal)
    64                       else "")) I (#goal o Proof.goal)
    63              (apply_named_method_on_first_goal name (Proof.context_of st)) st
    65              (apply_named_method_on_first_goal name (Proof.context_of st)) st
    64 
    66 
    65 val all_goals_named_methods = ["auto"]
    67 val all_goals_named_methods = ["auto"]
    66 val first_goal_named_methods =
    68 val first_goal_named_methods =
    69   map do_named_method_on_first_goal all_goals_named_methods @
    71   map do_named_method_on_first_goal all_goals_named_methods @
    70   map do_named_method first_goal_named_methods
    72   map do_named_method first_goal_named_methods
    71 
    73 
    72 fun time_string (s, ms) = s ^ ": " ^ string_of_int ms ^ " ms"
    74 fun time_string (s, ms) = s ^ ": " ^ string_of_int ms ^ " ms"
    73 
    75 
    74 fun do_try auto st =
    76 fun do_try auto timeout_opt st =
    75   case do_methods |> Par_List.map (fn f => f auto st)
    77   case do_methods |> Par_List.map (fn f => f timeout_opt st)
    76                   |> map_filter I |> sort (int_ord o pairself snd) of
    78                   |> map_filter I |> sort (int_ord o pairself snd) of
    77     [] => (if auto then () else writeln "No proof found."; (false, st))
    79     [] => (if auto then () else writeln "No proof found."; (false, st))
    78   | xs as (s, _) :: _ =>
    80   | xs as (s, _) :: _ =>
    79     let
    81     let
    80       val xs = xs |> map swap |> AList.coalesce (op =)
    82       val xs = xs |> map swap |> AList.coalesce (op =)
    93                                                   [Pretty.str message]])
    95                                                   [Pretty.str message]])
    94                     else
    96                     else
    95                       tap (fn _ => priority message)))
    97                       tap (fn _ => priority message)))
    96     end
    98     end
    97 
    99 
    98 val invoke_try = do_try false #> K ()
   100 val invoke_try = fst oo do_try false
    99 
   101 
   100 val tryN = "try"
   102 val tryN = "try"
   101 
   103 
   102 val _ =
   104 val _ =
   103   Outer_Syntax.improper_command tryN
   105   Outer_Syntax.improper_command tryN
   104       "try a combination of proof methods" Keyword.diag
   106       "try a combination of proof methods" Keyword.diag
   105       (Scan.succeed (Toplevel.keep (invoke_try o Toplevel.proof_of)))
   107       (Scan.succeed (Toplevel.keep (K () o do_try false (SOME default_timeout)
       
   108                                     o Toplevel.proof_of)))
   106 
   109 
   107 fun auto_try st = if not (!auto) then (false, st) else do_try true st
   110 fun auto_try st = if not (!auto) then (false, st) else do_try true NONE st
   108 
   111 
   109 val setup = Auto_Tools.register_tool (tryN, auto_try)
   112 val setup = Auto_Tools.register_tool (tryN, auto_try)
   110 
   113 
   111 end;
   114 end;