src/HOL/Tools/ATP_Manager/atp_manager.ML
changeset 35969 c9565298df9e
parent 35867 16279c4c7a33
child 36058 8256d5a185bd
equal deleted inserted replaced
35968:b7f98ff9c7d9 35969:c9565298df9e
     1 (*  Title:      HOL/Tools/ATP_Manager/atp_manager.ML
     1 (*  Title:      HOL/Tools/ATP_Manager/atp_manager.ML
     2     Author:     Fabian Immler, TU Muenchen
     2     Author:     Fabian Immler, TU Muenchen
     3     Author:     Makarius
     3     Author:     Makarius
       
     4     Author:     Jasmin Blanchette, TU Muenchen
     4 
     5 
     5 Central manager component for ATP threads.
     6 Central manager component for ATP threads.
     6 *)
     7 *)
     7 
     8 
     8 signature ATP_MANAGER =
     9 signature ATP_MANAGER =
     9 sig
    10 sig
       
    11   type relevance_override = Sledgehammer_Fact_Filter.relevance_override
       
    12   type params =
       
    13     {debug: bool,
       
    14      verbose: bool,
       
    15      atps: string list,
       
    16      full_types: bool,
       
    17      relevance_threshold: real,
       
    18      higher_order: bool option,
       
    19      respect_no_atp: bool,
       
    20      follow_defs: bool,
       
    21      isar_proof: bool,
       
    22      timeout: Time.time,
       
    23      minimize_timeout: Time.time}
    10   type problem =
    24   type problem =
    11    {with_full_types: bool,
    25     {subgoal: int,
    12     subgoal: int,
    26      goal: Proof.context * (thm list * thm),
    13     goal: Proof.context * (thm list * thm),
    27      relevance_override: relevance_override,
    14     axiom_clauses: (thm * (string * int)) list option,
    28      axiom_clauses: (thm * (string * int)) list option,
    15     filtered_clauses: (thm * (string * int)) list option}
    29      filtered_clauses: (thm * (string * int)) list option}
    16   val problem_of_goal: bool -> int -> Proof.context * (thm list * thm) -> problem
       
    17   type prover_result =
    30   type prover_result =
    18    {success: bool,
    31     {success: bool,
    19     message: string,
    32      message: string,
    20     theorem_names: string list,
    33      relevant_thm_names: string list,
    21     runtime: int,
    34      atp_run_time_in_msecs: int,
    22     proof: string,
    35      proof: string,
    23     internal_thm_names: string Vector.vector,
    36      internal_thm_names: string Vector.vector,
    24     filtered_clauses: (thm * (string * int)) list}
    37      filtered_clauses: (thm * (string * int)) list}
    25   type prover = int -> problem -> prover_result
    38   type prover = params -> Time.time -> problem -> prover_result
    26 
    39 
    27   val atps: string Unsynchronized.ref
    40   val atps: string Unsynchronized.ref
    28   val get_atps: unit -> string list
       
    29   val timeout: int Unsynchronized.ref
    41   val timeout: int Unsynchronized.ref
    30   val full_types: bool Unsynchronized.ref
    42   val full_types: bool Unsynchronized.ref
    31   val kill: unit -> unit
    43   val kill_atps: unit -> unit
    32   val info: unit -> unit
    44   val running_atps: unit -> unit
    33   val messages: int option -> unit
    45   val messages: int option -> unit
    34   val add_prover: string * prover -> theory -> theory
    46   val add_prover: string * prover -> theory -> theory
    35   val get_prover: theory -> string -> prover option
    47   val get_prover: theory -> string -> prover option
    36   val print_provers: theory -> unit
    48   val available_atps: theory -> unit
    37   val sledgehammer: string list -> Proof.state -> unit
    49   val sledgehammer: params -> int -> relevance_override -> Proof.state -> unit
    38 end;
    50 end;
    39 
    51 
    40 structure ATP_Manager : ATP_MANAGER =
    52 structure ATP_Manager : ATP_MANAGER =
    41 struct
    53 struct
    42 
    54 
    43 (** problems, results, and provers **)
    55 type relevance_override = Sledgehammer_Fact_Filter.relevance_override
       
    56 
       
    57 (** parameters, problems, results, and provers **)
       
    58 
       
    59 (* TODO: "theory_const", "blacklist_filter", "convergence" *)
       
    60 type params =
       
    61   {debug: bool,
       
    62    verbose: bool,
       
    63    atps: string list,
       
    64    full_types: bool,
       
    65    relevance_threshold: real,
       
    66    higher_order: bool option,
       
    67    respect_no_atp: bool,
       
    68    follow_defs: bool,
       
    69    isar_proof: bool,
       
    70    timeout: Time.time,
       
    71    minimize_timeout: Time.time}
    44 
    72 
    45 type problem =
    73 type problem =
    46  {with_full_types: bool,
    74   {subgoal: int,
    47   subgoal: int,
    75    goal: Proof.context * (thm list * thm),
    48   goal: Proof.context * (thm list * thm),
    76    relevance_override: relevance_override,
    49   axiom_clauses: (thm * (string * int)) list option,
    77    axiom_clauses: (thm * (string * int)) list option,
    50   filtered_clauses: (thm * (string * int)) list option};
    78    filtered_clauses: (thm * (string * int)) list option};
    51 
       
    52 fun problem_of_goal with_full_types subgoal goal : problem =
       
    53  {with_full_types = with_full_types,
       
    54   subgoal = subgoal,
       
    55   goal = goal,
       
    56   axiom_clauses = NONE,
       
    57   filtered_clauses = NONE};
       
    58 
    79 
    59 type prover_result =
    80 type prover_result =
    60  {success: bool,
    81   {success: bool,
    61   message: string,
    82    message: string,
    62   theorem_names: string list,  (*relevant theorems*)
    83    relevant_thm_names: string list,
    63   runtime: int,  (*user time of the ATP, in milliseconds*)
    84    atp_run_time_in_msecs: int,
    64   proof: string,
    85    proof: string,
    65   internal_thm_names: string Vector.vector,
    86    internal_thm_names: string Vector.vector,
    66   filtered_clauses: (thm * (string * int)) list};
    87    filtered_clauses: (thm * (string * int)) list};
    67 
    88 
    68 type prover = int -> problem -> prover_result;
    89 type prover = params -> Time.time -> problem -> prover_result;
    69 
    90 
    70 
    91 
    71 (** preferences **)
    92 (** preferences **)
    72 
    93 
    73 val message_store_limit = 20;
    94 val message_store_limit = 20;
    74 val message_display_limit = 5;
    95 val message_display_limit = 5;
    75 
    96 
    76 val atps = Unsynchronized.ref "e spass remote_vampire";
    97 val atps = Unsynchronized.ref "e spass remote_vampire";
    77 fun get_atps () = String.tokens (Symbol.is_ascii_blank o String.str) (! atps);
       
    78 
       
    79 val timeout = Unsynchronized.ref 60;
    98 val timeout = Unsynchronized.ref 60;
    80 val full_types = Unsynchronized.ref false;
    99 val full_types = Unsynchronized.ref false;
    81 
   100 
    82 val _ =
   101 val _ =
    83   ProofGeneralPgip.add_preference Preferences.category_proof
   102   ProofGeneralPgip.add_preference Preferences.category_proof
   216 
   235 
   217 
   236 
   218 
   237 
   219 (** user commands **)
   238 (** user commands **)
   220 
   239 
   221 (* kill *)
   240 (* kill ATPs *)
   222 
   241 
   223 fun kill () = Synchronized.change global_state
   242 fun kill_atps () = Synchronized.change global_state
   224   (fn {manager, timeout_heap, active, cancelling, messages, store} =>
   243   (fn {manager, timeout_heap, active, cancelling, messages, store} =>
   225     let
   244     let
   226       val killing = map (fn (th, (_, _, desc)) => (th, (Time.now (), desc))) active;
   245       val killing = map (fn (th, (_, _, desc)) => (th, (Time.now (), desc))) active;
   227       val state' = make_state manager timeout_heap [] (killing @ cancelling) messages store;
   246       val state' = make_state manager timeout_heap [] (killing @ cancelling) messages store;
   228     in state' end);
   247     in state' end);
   229 
   248 
   230 
   249 
   231 (* info *)
   250 (* running_atps *)
   232 
   251 
   233 fun seconds time = string_of_int (Time.toSeconds time) ^ "s";
   252 fun seconds time = string_of_int (Time.toSeconds time) ^ "s";
   234 
   253 
   235 fun info () =
   254 fun running_atps () =
   236   let
   255   let
   237     val {active, cancelling, ...} = Synchronized.value global_state;
   256     val {active, cancelling, ...} = Synchronized.value global_state;
   238 
   257 
   239     val now = Time.now ();
   258     val now = Time.now ();
   240     fun running_info (_, (birth_time, death_time, desc)) =
   259     fun running_info (_, (birth_time, death_time, desc)) =
   285     handle Symtab.DUP dup => err_dup_prover dup;
   304     handle Symtab.DUP dup => err_dup_prover dup;
   286 
   305 
   287 fun get_prover thy name =
   306 fun get_prover thy name =
   288   Option.map #1 (Symtab.lookup (Provers.get thy) name);
   307   Option.map #1 (Symtab.lookup (Provers.get thy) name);
   289 
   308 
   290 fun print_provers thy = Pretty.writeln
   309 fun available_atps thy = Pretty.writeln
   291   (Pretty.strs ("external provers:" :: sort_strings (Symtab.keys (Provers.get thy))));
   310   (Pretty.strs ("ATPs:" :: sort_strings (Symtab.keys (Provers.get thy))));
   292 
   311 
   293 
   312 
   294 (* start prover thread *)
   313 (* start prover thread *)
   295 
   314 
   296 fun start_prover name birth_time death_time i proof_state =
   315 fun start_prover (params as {timeout, ...}) birth_time death_time i
       
   316                  relevance_override proof_state name =
   297   (case get_prover (Proof.theory_of proof_state) name of
   317   (case get_prover (Proof.theory_of proof_state) name of
   298     NONE => warning ("Unknown external prover: " ^ quote name)
   318     NONE => warning ("Unknown ATP: " ^ quote name)
   299   | SOME prover =>
   319   | SOME prover =>
   300       let
   320       let
   301         val {context = ctxt, facts, goal} = Proof.goal proof_state;
   321         val {context = ctxt, facts, goal} = Proof.goal proof_state;
   302         val desc =
   322         val desc =
   303           "external prover " ^ quote name ^ " for subgoal " ^ string_of_int i ^ ":\n" ^
   323           "ATP " ^ quote name ^ " for subgoal " ^ string_of_int i ^ ":\n" ^
   304             Syntax.string_of_term ctxt (Thm.term_of (Thm.cprem_of goal i));
   324             Syntax.string_of_term ctxt (Thm.term_of (Thm.cprem_of goal i));
   305 
   325 
   306         val _ = Toplevel.thread true (fn () =>
   326         val _ = Toplevel.thread true (fn () =>
   307           let
   327           let
   308             val _ = register birth_time death_time (Thread.self (), desc);
   328             val _ = register birth_time death_time (Thread.self (), desc);
   309             val problem = problem_of_goal (! full_types) i (ctxt, (facts, goal));
   329             val problem =
   310             val message = #message (prover (! timeout) problem)
   330               {subgoal = i, goal = (ctxt, (facts, goal)),
       
   331                relevance_override = relevance_override, axiom_clauses = NONE,
       
   332                filtered_clauses = NONE}
       
   333             val message = #message (prover params timeout problem)
   311               handle Sledgehammer_HOL_Clause.TRIVIAL =>   (* FIXME !? *)
   334               handle Sledgehammer_HOL_Clause.TRIVIAL =>   (* FIXME !? *)
   312                   "Empty clause: Try this command: " ^ Markup.markup Markup.sendback "apply metis"
   335                   "Try this command: " ^
       
   336                   Markup.markup Markup.sendback "by metis" ^ "."
   313                 | ERROR msg => ("Error: " ^ msg);
   337                 | ERROR msg => ("Error: " ^ msg);
   314             val _ = unregister message (Thread.self ());
   338             val _ = unregister message (Thread.self ());
   315           in () end);
   339           in () end);
   316       in () end);
   340       in () end);
   317 
   341 
   318 
   342 
   319 (* sledghammer for first subgoal *)
   343 (* Sledgehammer the given subgoal *)
   320 
   344 
   321 fun sledgehammer names proof_state =
   345 fun sledgehammer (params as {atps, timeout, ...}) i relevance_override
       
   346                  proof_state =
   322   let
   347   let
   323     val provers = if null names then get_atps () else names;
   348     val birth_time = Time.now ()
   324     val birth_time = Time.now ();
   349     val death_time = Time.+ (birth_time, timeout)
   325     val death_time = Time.+ (birth_time, Time.fromSeconds (! timeout));
   350     val _ = kill_atps () (* RACE w.r.t. other invocations of Sledgehammer *)
   326     val _ = kill ();   (*RACE wrt. other invocations of sledgehammer*)
   351     val _ = priority "Sledgehammering..."
   327     val _ = List.app (fn name => start_prover name birth_time death_time 1 proof_state) provers;
   352     val _ = List.app (start_prover params birth_time death_time i
   328   in () end;
   353                                    relevance_override proof_state) atps
       
   354   in () end
   329 
   355 
   330 end;
   356 end;