-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_dpll.ml
More file actions
65 lines (55 loc) · 1.66 KB
/
test_dpll.ml
File metadata and controls
65 lines (55 loc) · 1.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
open Format
let run f =
let t = Unix.gettimeofday () in
f ();
let t = Unix.gettimeofday () -. t in
printf "%2.2f s@." t
let z = Z.of_int
type dimacs = { nb_variables: int; clauses: int list list }
let read_cnf (file: string) : dimacs =
let c = open_in file in
let rec read_p () =
let s = input_line c in
if s = "" || s.[0] = 'c' then read_p () else
Scanf.sscanf s "p cnf %d %d" (fun nv nc -> nv, nc) in
let nv, nc = read_p () in
let rec read_c cl b =
let l = Scanf.bscanf b " %d" (fun i -> i) in
if l = 0 then List.rev cl else read_c (l :: cl) b in
let cnf = ref [] in
for _ = 1 to nc do
let b = Scanf.Scanning.from_string (input_line c) in
cnf := read_c [] b :: !cnf
done;
{ nb_variables = nv; clauses = List.rev !cnf }
open Dpll
let make_3sat dimacs : int * int * cls array =
let nv = ref dimacs.nb_variables in
let clause3 acc cl =
let rec split acc = function
| [] -> assert false
| [a] -> (z a, z 0, z 0) :: acc
| [a; b] -> (z a, z b, z 0) :: acc
| [a; b; c] -> (z a, z b, z c) :: acc
| a :: b :: cl ->
incr nv; split ((z a, z b, z !nv) :: acc) (- !nv :: cl)
in
split acc cl
in
let cl = List.fold_left clause3 [] dimacs.clauses in
dimacs.nb_variables, !nv, Array.of_list cl
let file = Sys.argv.(1)
let dimacs = read_cnf file
let ov, nv, cl = make_3sat dimacs
let () = printf "%d variables, %d clauses@." nv (Array.length cl)
let is_sat () =
let v = Array.make (1 + nv) Z.zero in
if sat v cl then (
printf "SAT@.";
for i = 1 to ov do
printf "%a " Z.pp_print v.(i)
done;
printf "0@.";
) else
printf "UNSAT@."
let () = run is_sat