1 (* Title: HOL/Tools/Nitpick/kodkod_sat.ML
2 Author: Jasmin Blanchette, TU Muenchen
5 Kodkod SAT solver integration.
10 val configured_sat_solvers : bool -> string list
11 val smart_sat_solver_name : bool -> string
12 val sat_solver_spec : string -> string * string list
15 structure Kodkod_SAT : KODKOD_SAT =
20 datatype sink = ToStdout | ToFile
21 datatype availability =
24 datatype mode = Batch | Incremental
26 datatype sat_solver_info =
27 Internal of availability * mode * string list |
28 External of string * string * string list |
29 ExternalV2 of sink * string * string * string list * string * string * string
31 (* for compatibility with "SatSolver" *)
32 val berkmin_exec = getenv "BERKMIN_EXE"
35 [("Lingeling_JNI", Internal (JNI [1, 5], Batch, ["Lingeling"])),
36 ("CryptoMiniSat", External ("CRYPTOMINISAT_HOME", "cryptominisat", [])),
37 ("CryptoMiniSat_JNI", Internal (JNI [1, 5], Batch, ["CryptoMiniSat"])),
38 ("MiniSat", ExternalV2 (ToFile, "MINISAT_HOME", "minisat", [], "SAT", "",
40 ("MiniSat_JNI", Internal (JNI [], Incremental, ["MiniSat"])),
41 ("zChaff", ExternalV2 (ToStdout, "ZCHAFF_HOME", "zchaff", [],
42 "Instance Satisfiable", "",
43 "Instance Unsatisfiable")),
44 ("RSat", ExternalV2 (ToStdout, "RSAT_HOME", "rsat", ["-s"],
45 "s SATISFIABLE", "v ", "s UNSATISFIABLE")),
46 ("Riss3g", External ("RISS3G_HOME", "riss3g", [])),
47 ("BerkMin", ExternalV2 (ToStdout, "BERKMIN_HOME",
48 if berkmin_exec = "" then "BerkMin561"
49 else berkmin_exec, [], "Satisfiable !!",
50 "solution =", "UNSATISFIABLE !!")),
51 ("BerkMin_Alloy", External ("BERKMINALLOY_HOME", "berkmin", [])),
52 ("SAT4J", Internal (Java, Incremental, ["DefaultSAT4J"])),
53 ("SAT4J_Light", Internal (Java, Incremental, ["LightSAT4J"]))]
55 fun dynamic_entry_for_external name dev home exec args markers =
61 val serial_str = serial_string ()
62 val base = name ^ serial_str
63 val out_file = base ^ ".out"
65 if String.isSubstring "\\" dir andalso
66 not (String.isSubstring "/" dir) then
71 [if null markers then "External" else "ExternalV2",
72 dir ^ dir_sep ^ exec, base ^ ".cnf"] @
73 (if null markers then []
74 else [if dev = ToFile then out_file else ""]) @ markers @
75 (if dev = ToFile then [out_file] else []) @ args
77 fun dynamic_entry_for_info incremental (name, Internal (Java, mode, ss)) =
78 if incremental andalso mode = Batch then NONE else SOME (name, K ss)
79 | dynamic_entry_for_info incremental
80 (name, Internal (JNI from_version, mode, ss)) =
81 if (incremental andalso mode = Batch) orelse
82 dict_ord int_ord (kodkodi_version (), from_version) = LESS then
86 val lib_paths = getenv "KODKODI_JAVA_LIBRARY_PATH"
89 if exists (fn path => File.exists (Path.explode (path ^ "/")))
95 | dynamic_entry_for_info false (name, External (home, exec, args)) =
96 dynamic_entry_for_external name ToStdout home exec args []
97 | dynamic_entry_for_info false
98 (name, ExternalV2 (dev, home, exec, args, m1, m2, m3)) =
99 dynamic_entry_for_external name dev home exec args [m1, m2, m3]
100 | dynamic_entry_for_info true _ = NONE
101 fun dynamic_list incremental =
102 map_filter (dynamic_entry_for_info incremental) static_list
104 val configured_sat_solvers = map fst o dynamic_list
105 val smart_sat_solver_name = fst o hd o dynamic_list
107 fun sat_solver_spec name =
109 val dyns = dynamic_list false
110 fun enum_solvers solvers =
111 commas (distinct (op =) (map (quote o fst) solvers))
113 (name, the (AList.lookup (op =) dyns name) ())
114 handle Option.Option =>
115 error (if AList.defined (op =) static_list name then
116 "The SAT solver " ^ quote name ^ " is not configured. The \
117 \following solvers are configured:\n" ^
118 enum_solvers dyns ^ "."
120 "Unknown SAT solver " ^ quote name ^ ". The following \
121 \solvers are supported:\n" ^ enum_solvers static_list ^ ".")