added support for nonstandard models to Nitpick (based on an idea by Koen Claessen) and did other fixes to Nitpick
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 =
18 datatype sink = ToStdout | ToFile
19 datatype availability = Java | JNI
20 datatype mode = Batch | Incremental
22 datatype sat_solver_info =
23 Internal of availability * mode * string list |
24 External of sink * string * string * string list |
25 ExternalV2 of sink * string * string * string list * string * string * string
27 val berkmin_exec = getenv "BERKMIN_EXE"
29 (* (string * sat_solver_info) list *)
31 [("MiniSat", ExternalV2 (ToFile, "MINISAT_HOME", "minisat", [], "SAT", "",
33 ("PicoSAT", External (ToStdout, "PICOSAT_HOME", "picosat", [])),
34 ("zChaff", ExternalV2 (ToStdout, "ZCHAFF_HOME", "zchaff", [],
35 "Instance Satisfiable", "",
36 "Instance Unsatisfiable")),
37 ("RSat", ExternalV2 (ToStdout, "RSAT_HOME", "rsat", ["-s"],
38 "s SATISFIABLE", "v ", "s UNSATISFIABLE")),
39 ("BerkMin", ExternalV2 (ToStdout, "BERKMIN_HOME",
40 if berkmin_exec = "" then "BerkMin561"
41 else berkmin_exec, [], "Satisfiable !!",
42 "solution =", "UNSATISFIABLE !!")),
43 ("BerkMinAlloy", External (ToStdout, "BERKMINALLOY_HOME", "berkmin", [])),
44 ("Jerusat", External (ToStdout, "JERUSAT_HOME", "Jerusat1.3", [])),
45 ("MiniSatJNI", Internal (JNI, Incremental, ["MiniSat"])),
46 ("zChaffJNI", Internal (JNI, Batch, ["zChaff"])),
47 ("SAT4J", Internal (Java, Incremental, ["DefaultSAT4J"])),
48 ("SAT4JLight", Internal (Java, Incremental, ["LightSAT4J"])),
49 ("HaifaSat", ExternalV2 (ToStdout, "HAIFASAT_HOME", "HaifaSat", ["-p", "1"],
50 "s SATISFIABLE", "v ", "s UNSATISFIABLE"))]
52 val created_temp_dir = Unsynchronized.ref false
54 (* string -> sink -> string -> string -> string list -> string list
55 -> (string * (unit -> string list)) option *)
56 fun dynamic_entry_for_external name dev home exec args markers =
59 | dir => SOME (name, fn () =>
61 val temp_dir = getenv "ISABELLE_TMP"
62 val _ = if !created_temp_dir then
65 (created_temp_dir := true;
66 File.mkdir (Path.explode temp_dir))
67 val temp = temp_dir ^ "/" ^ name ^ serial_string ()
68 val out_file = temp ^ ".out"
70 [if null markers then "External" else "ExternalV2",
71 dir ^ "/" ^ exec, temp ^ ".cnf",
72 if dev = ToFile then out_file else ""] @ markers @
73 (if dev = ToFile then [out_file] else []) @ args
75 (* bool -> string * sat_solver_info
76 -> (string * (unit -> string list)) option *)
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 (name, Internal (JNI, mode, ss)) =
80 if incremental andalso mode = Batch then
84 val lib_paths = getenv "KODKODI_JAVA_LIBRARY_PATH"
87 if exists (fn path => File.exists (Path.explode (path ^ "/")))
93 | dynamic_entry_for_info false (name, External (dev, home, exec, args)) =
94 dynamic_entry_for_external name dev home exec args []
95 | dynamic_entry_for_info false (name, ExternalV2 (dev, home, exec, args,
97 dynamic_entry_for_external name dev home exec args [m1, m2, m3]
98 | dynamic_entry_for_info true _ = NONE
99 (* bool -> (string * (unit -> string list)) list *)
100 fun dynamic_list incremental =
101 map_filter (dynamic_entry_for_info incremental) static_list
103 (* bool -> string list *)
104 val configured_sat_solvers = map fst o dynamic_list
107 val smart_sat_solver_name = dynamic_list #> hd #> fst
109 (* (string * 'a) list -> string *)
110 fun enum_solvers xs = commas (map (quote o fst) xs |> distinct (op =))
111 (* string -> string * string list *)
112 fun sat_solver_spec name =
113 let val dynamic_list = dynamic_list false in
114 (name, the (AList.lookup (op =) dynamic_list name) ())
115 handle Option.Option =>
116 error (if AList.defined (op =) static_list name then
117 "The SAT solver " ^ quote name ^ " is not configured. The \
118 \following solvers are configured:\n" ^
119 enum_solvers dynamic_list ^ "."
121 "Unknown SAT solver " ^ quote name ^ ". The following \
122 \solvers are supported:\n" ^ enum_solvers static_list ^ ".")