src/HOL/Mirabelle/Tools/mirabelle_sledgehammer.ML
author boehmes
Wed, 02 Sep 2009 21:31:58 +0200
changeset 32498 1132c7c13f36
parent 32496 4ab00a2642c3
child 32503 14efbc20b708
permissions -rw-r--r--
Mirabelle: actions are responsible for handling exceptions,
Mirabelle core logs only structural information,
measuring running times for sledgehammer and subsequent metis invocation,
Mirabelle produces reports for every theory (only for sledgehammer at the moment)
     1 (* Title:  mirabelle_sledgehammer.ML
     2    Author: Jasmin Blanchette and Sascha Boehme
     3 *)
     4 
     5 structure Mirabelle_Sledgehammer : MIRABELLE_ACTION =
     6 struct
     7 
     8 fun thms_of_name ctxt name =
     9   let
    10     val lex = OuterKeyword.get_lexicons
    11     val get = maps (ProofContext.get_fact ctxt o fst)
    12   in
    13     Source.of_string name
    14     |> Symbol.source {do_recover=false}
    15     |> OuterLex.source {do_recover=SOME false} lex Position.start
    16     |> OuterLex.source_proper
    17     |> Source.source OuterLex.stopper (SpecParse.xthms1 >> get) NONE
    18     |> Source.exhaust
    19   end
    20 
    21 fun safe init done f x =
    22   let
    23     val y = init x
    24     val z = Exn.capture f y
    25     val _ = done y
    26   in Exn.release z end
    27 
    28 fun with_time true t = "succeeded (" ^ string_of_int t ^ ")"
    29   | with_time false t = "failed (" ^ string_of_int t ^ ")"
    30 
    31 val proverK = "prover"
    32 val keepK = "keep"
    33 val metisK = "metis"
    34 
    35 
    36 local
    37 
    38 fun init NONE = !AtpWrapper.destdir
    39   | init (SOME path) =
    40       let
    41         (* Warning: we implicitly assume single-threaded execution here! *)
    42         val old = !AtpWrapper.destdir
    43         val _ = AtpWrapper.destdir := path
    44       in old end
    45 
    46 fun done path = AtpWrapper.destdir := path
    47 
    48 fun run prover_name timeout st _ =
    49   let
    50     val prover = the (AtpManager.get_prover prover_name (Proof.theory_of st))
    51     val atp_timeout = AtpManager.get_timeout () 
    52     val atp = prover atp_timeout NONE NONE prover_name 1
    53     val (success, (message, thm_names), _, _, _) =
    54       TimeLimit.timeLimit timeout atp (Proof.get_goal st)
    55   in (success, message, SOME thm_names) end
    56   handle ResHolClause.TOO_TRIVIAL => (true, "trivial", SOME [])
    57        | TimeLimit.TimeOut => (false, "time out", NONE)
    58        | ERROR msg => (false, "error: " ^ msg, NONE)
    59 
    60 in
    61 
    62 fun run_sledgehammer (args, st, timeout, log) =
    63   let
    64     val prover_name =
    65       AList.lookup (op =) args proverK
    66       |> the_default (hd (space_explode " " (AtpManager.get_atps ())))
    67     val dir = AList.lookup (op =) args keepK
    68     val ((success, msg, thm_names), time) =
    69       safe init done (Mirabelle.cpu_time (run prover_name timeout st)) dir
    70     fun sh_log s = log ("sledgehammer: " ^ with_time success time ^ " [" ^
    71       prover_name ^ "]" ^ s)
    72     val _ = if success then sh_log (":\n" ^ msg) else sh_log ""
    73   in if success then thm_names else NONE end
    74 
    75 end
    76 
    77 
    78 fun run_metis (args, st, timeout, log) thm_names =
    79   let
    80     fun get_thms ctxt = maps (thms_of_name ctxt)
    81     fun metis thms ctxt = MetisTools.metis_tac ctxt thms
    82     fun apply_metis thms = Mirabelle.can_apply timeout (metis thms) st
    83     fun timed_metis thms =
    84       uncurry with_time (Mirabelle.cpu_time apply_metis thms)
    85       handle TimeLimit.TimeOut => "time out"
    86     fun log_metis s = log ("-----\nmetis (sledgehammer): " ^ s)
    87   in
    88     if not (AList.defined (op =) args metisK) then ()
    89     else if is_none thm_names then ()
    90     else
    91       these thm_names
    92       |> get_thms (Proof.context_of st)
    93       |> timed_metis
    94       |> log_metis
    95   end
    96 
    97 
    98 fun sledgehammer_action args {pre, timeout, log, ...} =
    99   run_sledgehammer (args, pre, timeout, log)
   100   |> run_metis (args, pre, timeout, log)
   101 
   102 fun invoke args = Mirabelle.register ("sledgehammer", sledgehammer_action args)
   103 
   104 end
   105