File ‹sat_problem.ML›
signature SAT_PROBLEM =
sig
type T = {
n_vars : int,
vars : cterm option array,
n_clauses : int,
clauses : (int list * thm) Array_Map.T
}
val mk_dimacs : T -> Bytes.T
val write_dimacs : T -> Path.T -> unit
end
structure SAT_Problem : SAT_PROBLEM =
struct
type T = {
n_vars : int,
vars : cterm option array,
n_clauses : int,
clauses : (int list * thm) Array_Map.T
}
fun dimacs_gen st put {n_vars, n_clauses, clauses, ...} =
let
fun write_clause st (cs, _) =
put st (implode_space (map signed_string_of_int cs) ^ " 0")
val st = put st ("p cnf " ^ string_of_int n_vars ^ " " ^ string_of_int n_clauses ^ "")
fun write_clauses st i = if i > n_clauses then st else
let
val st =
case Array_Map.sub (clauses, i) of
SOME c => write_clause st c
| NONE => raise Match
in
write_clauses st (i + 1)
end
val st = write_clauses st 1
in
st
end
fun write_dimacs sat dimacs_file =
dimacs_file |> File_Stream.open_output (fn out =>
dimacs_gen () (fn _ => fn s => File_Stream.output out (s ^ "\n")) sat)
fun mk_dimacs sat =
dimacs_gen Bytes.empty (fn buf => fn s => Bytes.add (s ^ "\n") buf) sat
end