(* Title: HOL/Tools/SMT/smt_systems.ML Author: Sascha Boehme, TU Muenchen
Setup SMT solvers.
*)
signature SMT_SYSTEMS = sig val cvc_extensions: bool Config.T val z3_extensions: bool Config.T end;
structure SMT_Systems: SMT_SYSTEMS = struct
val mashN = "mash" val mepoN = "mepo" val meshN = "mesh"
(* helper functions *)
fun check_tool var () =
(case getenv var of "" => NONE
| s => if File.is_file (Path.variable var |> Path.expand |> Path.platform_exe) then SOME [s] else NONE);
fun make_avail name () = getenv (name ^ "_SOLVER") <> ""
fun make_command name () = [getenv (name ^ "_SOLVER")]
fun outcome_of unsat sat unknown timeout solver_name line = ifString.isPrefix unsat line then SMT_Solver.Unsat elseifString.isPrefix sat line then SMT_Solver.Sat elseifString.isPrefix unknown line then SMT_Solver.Unknown elseifString.isPrefix timeout line then SMT_Solver.Time_Out elseraise SMT_Failure.SMT (SMT_Failure.Other_Failure ("Solver " ^ quote solver_name ^ " failed -- enable tracing using the " ^ quote (Config.name_of SMT_Config.trace) ^ " option for details"))
(* When used with bitvectors, CVC4 can produce error messages like:
$ISABELLE_TMP_PREFIX/... No set-logic command was given before this point.
These message should be ignored.
*) fun is_blank_or_error_line "" = true
| is_blank_or_error_line s = String.isPrefix "(error " s orelse String.isPrefix (getenv "ISABELLE_TMP_PREFIX") s
fun on_first_line test_outcome solver_name lines = let val split_first = (fn [] => ("", []) | l :: ls => (l, ls)) val (l, ls) = split_first (drop_prefix is_blank_or_error_line lines) in (test_outcome solver_name l, ls) end
val cvc_extensions = Attrib.setup_config_bool \<^binding>\<open>cvc_extensions\<close> (K false)
local fun cvc4_options ctxt =
["--no-stats", "--random-seed=" ^ string_of_int (Config.get ctxt SMT_Config.random_seed), "--lang=smt2"] @
(case SMT_Config.get_timeout ctxt of
NONE => []
| SOME t => ["--tlimit", string_of_int (Time.toMilliseconds t)])
fun cvc5_options ctxt =
["--no-stats", "--sat-random-seed=" ^ string_of_int (Config.get ctxt SMT_Config.random_seed), "--lang=smt2"] @
(case SMT_Config.get_timeout ctxt of
NONE => []
| SOME t => ["--tlimit", string_of_int (Time.toMilliseconds t)])
fun select_class ctxt = if Config.get ctxt cvc_extensions then if Config.get ctxt SMT_Config.higher_order then
CVC_Interface.hosmtlib_cvcC else
CVC_Interface.smtlib_cvcC else if Config.get ctxt SMT_Config.higher_order then
SMTLIB_Interface.hosmtlibC elseif Config.get ctxt SMT_Config.native_bv then
SMTLIB_Interface.bvsmlibC else
SMTLIB_Interface.smtlibC in
val z3_extensions = Attrib.setup_config_bool \<^binding>\<open>z3_extensions\<close> (K false)
local fun z3_options ctxt =
["smt.random_seed=" ^ string_of_int (Config.get ctxt SMT_Config.random_seed), "smt.refine_inj_axioms=false"] @
(case SMT_Config.get_timeout ctxt of
NONE => []
| SOME t => ["-T:" ^ string_of_int (Real.ceil (Time.toReal t))]) @
["-smt2"]
fun select_class ctxt = if Config.get ctxt z3_extensions then Z3_Interface.smtlib_z3C elseif Config.get ctxt SMT_Config.native_bv then SMTLIB_Interface.bvsmlibC else SMTLIB_Interface.smtlibC in
fun smt_method ((solver, stgy), thms) ctxt facts = let val default_solver = SMT_Config.solver_of ctxt val solver =
(case solver of
NONE => default_solver
| SOME "cvc5" => "cvc5_proof"
| SOME a => a) val _ = if solver = "z3" andalso stgy <> NONE then warning ("No strategy is available for z3. Ignoring " ^ quote (the stgy)) else () val ctxt =
ctxt
|> (if stgy <> NONE then Context.proof_map (Verit_Strategies.select_veriT_stgy (the stgy)) else I)
|> Context.Proof
|> SMT_Config.select_solver solver
|> Context.proof_of in
HEADGOAL (SOLVED' (SMT_Solver.smt_tac ctxt (thms @ facts))) end
val _ =
Theory.setup
(Method.setup \<^binding>\<open>smt\<close>
(Scan.lift parse_smt_options -- Attrib.thms >> (METHOD oo smt_method)) "Call to the SMT solver veriT or z3")
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.