src/HOL/Tools/Sledgehammer/sledgehammer_provers.ML
changeset 41432 3214c39777ab
parent 41336 0ea5b9c7d233
child 41723 bb366da22483
equal deleted inserted replaced
41431:138f414f14cb 41432:3214c39777ab
    40     {state: Proof.state,
    40     {state: Proof.state,
    41      goal: thm,
    41      goal: thm,
    42      subgoal: int,
    42      subgoal: int,
    43      subgoal_count: int,
    43      subgoal_count: int,
    44      facts: prover_fact list,
    44      facts: prover_fact list,
    45      smt_head: (string * locality) SMT_Solver.smt_filter_head_result option}
    45      smt_head: (string * locality) SMT_Solver.smt_filter_data option}
    46 
    46 
    47   type prover_result =
    47   type prover_result =
    48     {outcome: failure option,
    48     {outcome: failure option,
    49      used_facts: (string * locality) list,
    49      used_facts: (string * locality) list,
    50      run_time_in_msecs: int option,
    50      run_time_in_msecs: int option,
   113 
   113 
   114 (* Identifier to distinguish Sledgehammer from other tools using
   114 (* Identifier to distinguish Sledgehammer from other tools using
   115    "Async_Manager". *)
   115    "Async_Manager". *)
   116 val das_Tool = "Sledgehammer"
   116 val das_Tool = "Sledgehammer"
   117 
   117 
   118 val unremotify = perhaps (try (unprefix remote_prefix))
       
   119 
       
   120 val select_smt_solver =
   118 val select_smt_solver =
   121   Context.proof_map o SMT_Config.select_solver o unremotify
   119   Context.proof_map o SMT_Config.select_solver
   122 
   120 
   123 fun is_smt_prover ctxt name =
   121 fun is_smt_prover ctxt name =
   124   let val smts = SMT_Solver.available_solvers_of ctxt in
   122   member (op =) (SMT_Solver.available_solvers_of ctxt) name
   125     case try (unprefix remote_prefix) name of
       
   126       SOME base => member (op =) smts base andalso
       
   127                    SMT_Solver.is_remotely_available ctxt base
       
   128     | NONE => member (op =) smts name
       
   129   end
       
   130 
   123 
   131 fun is_prover_available ctxt name =
   124 fun is_prover_available ctxt name =
   132   let val thy = ProofContext.theory_of ctxt in
   125   let val thy = ProofContext.theory_of ctxt in
   133     is_smt_prover ctxt name orelse member (op =) (available_atps thy) name
   126     is_smt_prover ctxt name orelse member (op =) (available_atps thy) name
   134   end
   127   end
   135 
   128 
   136 fun is_prover_installed ctxt name =
   129 fun is_prover_installed ctxt =
   137   let val thy = ProofContext.theory_of ctxt in
   130   is_smt_prover ctxt orf is_atp_installed (ProofContext.theory_of ctxt)
   138     if is_smt_prover ctxt name then
   131 
   139       String.isPrefix remote_prefix name orelse
   132 fun available_smt_solvers ctxt = SMT_Solver.available_solvers_of ctxt
   140       SMT_Solver.is_locally_installed ctxt name
       
   141     else
       
   142       is_atp_installed thy name
       
   143   end
       
   144 
       
   145 fun available_smt_solvers ctxt =
       
   146   let val smts = SMT_Solver.available_solvers_of ctxt in
       
   147     smts @ map (prefix remote_prefix)
       
   148                (filter (SMT_Solver.is_remotely_available ctxt) smts)
       
   149   end
       
   150 
   133 
   151 fun default_max_relevant_for_prover ctxt name =
   134 fun default_max_relevant_for_prover ctxt name =
   152   let val thy = ProofContext.theory_of ctxt in
   135   let val thy = ProofContext.theory_of ctxt in
   153     if is_smt_prover ctxt name then
   136     if is_smt_prover ctxt name then
   154       SMT_Solver.default_max_relevant ctxt (unremotify name)
   137       SMT_Solver.default_max_relevant ctxt name
   155     else
   138     else
   156       #default_max_relevant (get_atp thy name)
   139       #default_max_relevant (get_atp thy name)
   157   end
   140   end
   158 
   141 
   159 (* These are either simplified away by "Meson.presimplify" (most of the time) or
   142 (* These are either simplified away by "Meson.presimplify" (most of the time) or
   265   {state: Proof.state,
   248   {state: Proof.state,
   266    goal: thm,
   249    goal: thm,
   267    subgoal: int,
   250    subgoal: int,
   268    subgoal_count: int,
   251    subgoal_count: int,
   269    facts: prover_fact list,
   252    facts: prover_fact list,
   270    smt_head: (string * locality) SMT_Solver.smt_filter_head_result option}
   253    smt_head: (string * locality) SMT_Solver.smt_filter_data option}
   271 
   254 
   272 type prover_result =
   255 type prover_result =
   273   {outcome: failure option,
   256   {outcome: failure option,
   274    message: string,
   257    message: string,
   275    used_facts: (string * locality) list,
   258    used_facts: (string * locality) list,
   535 
   518 
   536 fun smt_filter_loop name ({debug, verbose, overlord, timeout, ...} : params)
   519 fun smt_filter_loop name ({debug, verbose, overlord, timeout, ...} : params)
   537                     state i smt_head =
   520                     state i smt_head =
   538   let
   521   let
   539     val ctxt = Proof.context_of state
   522     val ctxt = Proof.context_of state
   540     val (remote, base) =
       
   541       case try (unprefix remote_prefix) name of
       
   542         SOME base => (true, base)
       
   543       | NONE => (false, name)
       
   544     val repair_context =
   523     val repair_context =
   545       select_smt_solver base
   524       select_smt_solver name
   546       #> Config.put SMT_Config.verbose debug
   525       #> Config.put SMT_Config.verbose debug
   547       #> (if overlord then
   526       #> (if overlord then
   548             Config.put SMT_Config.debug_files
   527             Config.put SMT_Config.debug_files
   549                        (overlord_file_location_for_prover name
   528                        (overlord_file_location_for_prover name
   550                         |> (fn (path, base) => path ^ "/" ^ base))
   529                         |> (fn (path, name) => path ^ "/" ^ name))
   551           else
   530           else
   552             I)
   531             I)
   553       #> Config.put SMT_Config.infer_triggers (!smt_triggers)
   532       #> Config.put SMT_Config.infer_triggers (!smt_triggers)
   554       #> Config.put SMT_Config.monomorph_limit (!smt_monomorphize_limit)
   533       #> Config.put SMT_Config.monomorph_limit (!smt_monomorphize_limit)
   555     val state = state |> Proof.map_context repair_context
   534     val state = state |> Proof.map_context repair_context
   577         val birth = Timer.checkRealTimer timer
   556         val birth = Timer.checkRealTimer timer
   578         val _ =
   557         val _ =
   579           if debug then Output.urgent_message "Invoking SMT solver..." else ()
   558           if debug then Output.urgent_message "Invoking SMT solver..." else ()
   580         val (outcome, used_facts) =
   559         val (outcome, used_facts) =
   581           (case (iter_num, smt_head) of
   560           (case (iter_num, smt_head) of
   582              (1, SOME head) => head |> apsnd (apfst (apsnd repair_context))
   561              (1, SOME head) => head |> apsnd (apsnd repair_context)
   583            | _ => SMT_Solver.smt_filter_head state facts i)
   562            | _ => SMT_Solver.smt_filter_preprocess state facts i)
   584           |> SMT_Solver.smt_filter_tail iter_timeout remote
   563           |> SMT_Solver.smt_filter_apply iter_timeout
   585           |> (fn {outcome, used_facts} => (outcome, used_facts))
   564           |> (fn {outcome, used_facts} => (outcome, used_facts))
   586           handle exn => if Exn.is_interrupt exn then
   565           handle exn => if Exn.is_interrupt exn then
   587                           reraise exn
   566                           reraise exn
   588                         else
   567                         else
   589                           (internal_error_prefix ^ ML_Compiler.exn_message exn
   568                           (internal_error_prefix ^ ML_Compiler.exn_message exn
   666         let
   645         let
   667           val (method, settings) =
   646           val (method, settings) =
   668             if can_apply_metis debug state subgoal (map snd used_facts) then
   647             if can_apply_metis debug state subgoal (map snd used_facts) then
   669               ("metis", "")
   648               ("metis", "")
   670             else
   649             else
   671               let val base = unremotify name in
   650               ("smt", if name = SMT_Solver.solver_name_of ctxt then ""
   672                 ("smt", if base = SMT_Config.solver_of ctxt then ""
   651                       else "smt_solver = " ^ maybe_quote name)
   673                         else "smt_solver = " ^ maybe_quote base)
       
   674               end
       
   675         in
   652         in
   676           try_command_line (proof_banner auto)
   653           try_command_line (proof_banner auto)
   677               (apply_on_subgoal settings subgoal subgoal_count ^
   654               (apply_on_subgoal settings subgoal subgoal_count ^
   678                command_call method (map fst other_lemmas)) ^
   655                command_call method (map fst other_lemmas)) ^
   679           minimize_line minimize_command
   656           minimize_line minimize_command