author | blanchet |
Tue, 24 Feb 2009 16:12:27 +0100 | |
changeset 30237 | e6f76bf0e067 |
parent 29872 | 14e208d607af |
child 30240 | 5b25fee0362c |
permissions | -rw-r--r-- |
14453 | 1 |
(* Title: HOL/Tools/sat_solver.ML |
2 |
ID: $Id$ |
|
3 |
Author: Tjark Weber |
|
21267 | 4 |
Copyright 2004-2006 |
14453 | 5 |
|
6 |
Interface to external SAT solvers, and (simple) built-in SAT solvers. |
|
7 |
*) |
|
8 |
||
9 |
signature SAT_SOLVER = |
|
10 |
sig |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
11 |
exception NOT_CONFIGURED |
14453 | 12 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
13 |
type assignment = int -> bool option |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
14 |
type proof = int list Inttab.table * int |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
15 |
datatype result = SATISFIABLE of assignment |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
16 |
| UNSATISFIABLE of proof option |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
17 |
| UNKNOWN |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
18 |
type solver = PropLogic.prop_formula -> result |
14965 | 19 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
20 |
(* auxiliary functions to create external SAT solvers *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
21 |
val write_dimacs_cnf_file : Path.T -> PropLogic.prop_formula -> unit |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
22 |
val write_dimacs_sat_file : Path.T -> PropLogic.prop_formula -> unit |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
23 |
val read_std_result_file : Path.T -> string * string * string -> result |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
24 |
val make_external_solver : string -> (PropLogic.prop_formula -> unit) -> (unit -> result) -> solver |
14453 | 25 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
26 |
val read_dimacs_cnf_file : Path.T -> PropLogic.prop_formula |
15040 | 27 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
28 |
(* generic solver interface *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
29 |
val solvers : (string * solver) list ref |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
30 |
val add_solver : string * solver -> unit |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
31 |
val invoke_solver : string -> solver (* exception Option *) |
14453 | 32 |
end; |
33 |
||
34 |
structure SatSolver : SAT_SOLVER = |
|
35 |
struct |
|
36 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
37 |
open PropLogic; |
14453 | 38 |
|
39 |
(* ------------------------------------------------------------------------- *) |
|
14965 | 40 |
(* should be raised by an external SAT solver to indicate that the solver is *) |
41 |
(* not configured properly *) |
|
42 |
(* ------------------------------------------------------------------------- *) |
|
43 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
44 |
exception NOT_CONFIGURED; |
14965 | 45 |
|
46 |
(* ------------------------------------------------------------------------- *) |
|
15531 | 47 |
(* type of partial (satisfying) assignments: 'a i = NONE' means that 'a' is *) |
19190 | 48 |
(* a satisfying assignment regardless of the value of variable 'i' *) |
14453 | 49 |
(* ------------------------------------------------------------------------- *) |
50 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
51 |
type assignment = int -> bool option; |
14965 | 52 |
|
53 |
(* ------------------------------------------------------------------------- *) |
|
17493
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
54 |
(* a proof of unsatisfiability, to be interpreted as follows: each integer *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
55 |
(* is a clause ID, each list 'xs' stored under the key 'x' in the table *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
56 |
(* contains the IDs of clauses that must be resolved (in the given *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
57 |
(* order) to obtain the new clause 'x'. Each list 'xs' must be *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
58 |
(* non-empty, and the literal to be resolved upon must always be unique *) |
17494 | 59 |
(* (e.g. "A | ~B" must not be resolved with "~A | B"). Circular *) |
17493
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
60 |
(* dependencies of clauses are not allowed. (At least) one of the *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
61 |
(* clauses in the table must be the empty clause (i.e. contain no *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
62 |
(* literals); its ID is given by the second component of the proof. *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
63 |
(* The clauses of the original problem passed to the SAT solver have *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
64 |
(* consecutive IDs starting with 0. Clause IDs must be non-negative, *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
65 |
(* but do not need to be consecutive. *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
66 |
(* ------------------------------------------------------------------------- *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
67 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
68 |
type proof = int list Inttab.table * int; |
17493
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
69 |
|
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
70 |
(* ------------------------------------------------------------------------- *) |
14965 | 71 |
(* return type of SAT solvers: if the result is 'SATISFIABLE', a satisfying *) |
17493
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
72 |
(* assignment must be returned as well; if the result is *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
73 |
(* 'UNSATISFIABLE', a proof of unsatisfiability may be returned *) |
14965 | 74 |
(* ------------------------------------------------------------------------- *) |
75 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
76 |
datatype result = SATISFIABLE of assignment |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
77 |
| UNSATISFIABLE of proof option |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
78 |
| UNKNOWN; |
14965 | 79 |
|
80 |
(* ------------------------------------------------------------------------- *) |
|
81 |
(* type of SAT solvers: given a propositional formula, a satisfying *) |
|
82 |
(* assignment may be returned *) |
|
83 |
(* ------------------------------------------------------------------------- *) |
|
84 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
85 |
type solver = prop_formula -> result; |
14453 | 86 |
|
87 |
(* ------------------------------------------------------------------------- *) |
|
88 |
(* write_dimacs_cnf_file: serializes a formula 'fm' of propositional logic *) |
|
89 |
(* to a file in DIMACS CNF format (see "Satisfiability Suggested *) |
|
90 |
(* Format", May 8 1993, Section 2.1) *) |
|
91 |
(* Note: 'fm' must not contain a variable index less than 1. *) |
|
14965 | 92 |
(* Note: 'fm' must be given in CNF. *) |
14453 | 93 |
(* ------------------------------------------------------------------------- *) |
94 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
95 |
(* Path.T -> prop_formula -> unit *) |
14453 | 96 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
97 |
fun write_dimacs_cnf_file path fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
98 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
99 |
(* prop_formula -> prop_formula *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
100 |
fun cnf_True_False_elim True = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
101 |
Or (BoolVar 1, Not (BoolVar 1)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
102 |
| cnf_True_False_elim False = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
103 |
And (BoolVar 1, Not (BoolVar 1)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
104 |
| cnf_True_False_elim fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
105 |
fm (* since 'fm' is in CNF, either 'fm'='True'/'False', or 'fm' does not contain 'True'/'False' at all *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
106 |
(* prop_formula -> int *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
107 |
fun cnf_number_of_clauses (And (fm1,fm2)) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
108 |
(cnf_number_of_clauses fm1) + (cnf_number_of_clauses fm2) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
109 |
| cnf_number_of_clauses _ = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
110 |
1 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
111 |
(* prop_formula -> string list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
112 |
fun cnf_string fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
113 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
114 |
(* prop_formula -> string list -> string list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
115 |
fun cnf_string_acc True acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
116 |
error "formula is not in CNF" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
117 |
| cnf_string_acc False acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
118 |
error "formula is not in CNF" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
119 |
| cnf_string_acc (BoolVar i) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
120 |
(i>=1 orelse error "formula contains a variable index less than 1"; |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
121 |
string_of_int i :: acc) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
122 |
| cnf_string_acc (Not (BoolVar i)) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
123 |
"-" :: cnf_string_acc (BoolVar i) acc |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
124 |
| cnf_string_acc (Not _) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
125 |
error "formula is not in CNF" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
126 |
| cnf_string_acc (Or (fm1,fm2)) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
127 |
cnf_string_acc fm1 (" " :: cnf_string_acc fm2 acc) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
128 |
| cnf_string_acc (And (fm1,fm2)) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
129 |
cnf_string_acc fm1 (" 0\n" :: cnf_string_acc fm2 acc) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
130 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
131 |
cnf_string_acc fm [] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
132 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
133 |
val fm' = cnf_True_False_elim fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
134 |
val number_of_vars = maxidx fm' |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
135 |
val number_of_clauses = cnf_number_of_clauses fm' |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
136 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
137 |
File.write path |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
138 |
("c This file was generated by SatSolver.write_dimacs_cnf_file\n" ^ |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
139 |
"p cnf " ^ string_of_int number_of_vars ^ " " ^ string_of_int number_of_clauses ^ "\n"); |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
140 |
File.append_list path |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
141 |
(cnf_string fm'); |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
142 |
File.append path |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
143 |
" 0\n" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
144 |
end; |
14453 | 145 |
|
146 |
(* ------------------------------------------------------------------------- *) |
|
147 |
(* write_dimacs_sat_file: serializes a formula 'fm' of propositional logic *) |
|
148 |
(* to a file in DIMACS SAT format (see "Satisfiability Suggested *) |
|
149 |
(* Format", May 8 1993, Section 2.2) *) |
|
150 |
(* Note: 'fm' must not contain a variable index less than 1. *) |
|
151 |
(* ------------------------------------------------------------------------- *) |
|
152 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
153 |
(* Path.T -> prop_formula -> unit *) |
14453 | 154 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
155 |
fun write_dimacs_sat_file path fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
156 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
157 |
(* prop_formula -> string list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
158 |
fun sat_string fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
159 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
160 |
(* prop_formula -> string list -> string list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
161 |
fun sat_string_acc True acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
162 |
"*()" :: acc |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
163 |
| sat_string_acc False acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
164 |
"+()" :: acc |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
165 |
| sat_string_acc (BoolVar i) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
166 |
(i>=1 orelse error "formula contains a variable index less than 1"; |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
167 |
string_of_int i :: acc) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
168 |
| sat_string_acc (Not (BoolVar i)) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
169 |
"-" :: sat_string_acc (BoolVar i) acc |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
170 |
| sat_string_acc (Not fm) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
171 |
"-(" :: sat_string_acc fm (")" :: acc) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
172 |
| sat_string_acc (Or (fm1,fm2)) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
173 |
"+(" :: sat_string_acc_or fm1 (" " :: sat_string_acc_or fm2 (")" :: acc)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
174 |
| sat_string_acc (And (fm1,fm2)) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
175 |
"*(" :: sat_string_acc_and fm1 (" " :: sat_string_acc_and fm2 (")" :: acc)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
176 |
(* optimization to make use of n-ary disjunction/conjunction *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
177 |
(* prop_formula -> string list -> string list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
178 |
and sat_string_acc_or (Or (fm1,fm2)) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
179 |
sat_string_acc_or fm1 (" " :: sat_string_acc_or fm2 acc) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
180 |
| sat_string_acc_or fm acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
181 |
sat_string_acc fm acc |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
182 |
(* prop_formula -> string list -> string list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
183 |
and sat_string_acc_and (And (fm1,fm2)) acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
184 |
sat_string_acc_and fm1 (" " :: sat_string_acc_and fm2 acc) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
185 |
| sat_string_acc_and fm acc = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
186 |
sat_string_acc fm acc |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
187 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
188 |
sat_string_acc fm [] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
189 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
190 |
val number_of_vars = Int.max (maxidx fm, 1) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
191 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
192 |
File.write path |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
193 |
("c This file was generated by SatSolver.write_dimacs_sat_file\n" ^ |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
194 |
"p sat " ^ string_of_int number_of_vars ^ "\n" ^ |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
195 |
"("); |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
196 |
File.append_list path |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
197 |
(sat_string fm); |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
198 |
File.append path |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
199 |
")\n" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
200 |
end; |
14453 | 201 |
|
202 |
(* ------------------------------------------------------------------------- *) |
|
17620
49568e5e0450
parse_std_result_file renamed to read_std_result_file
webertj
parents:
17581
diff
changeset
|
203 |
(* read_std_result_file: scans a SAT solver's output file for a satisfying *) |
14965 | 204 |
(* variable assignment. Returns the assignment, or 'UNSATISFIABLE' if *) |
205 |
(* the file contains 'unsatisfiable', or 'UNKNOWN' if the file contains *) |
|
206 |
(* neither 'satisfiable' nor 'unsatisfiable'. Empty lines are ignored. *) |
|
207 |
(* The assignment must be given in one or more lines immediately after *) |
|
208 |
(* the line that contains 'satisfiable'. These lines must begin with *) |
|
209 |
(* 'assignment_prefix'. Variables must be separated by " ". Non- *) |
|
210 |
(* integer strings are ignored. If variable i is contained in the *) |
|
211 |
(* assignment, then i is interpreted as 'true'. If ~i is contained in *) |
|
212 |
(* the assignment, then i is interpreted as 'false'. Otherwise the *) |
|
213 |
(* value of i is taken to be unspecified. *) |
|
14453 | 214 |
(* ------------------------------------------------------------------------- *) |
215 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
216 |
(* Path.T -> string * string * string -> result *) |
14453 | 217 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
218 |
fun read_std_result_file path (satisfiable, assignment_prefix, unsatisfiable) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
219 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
220 |
(* string -> int list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
221 |
fun int_list_from_string s = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
222 |
List.mapPartial Int.fromString (space_explode " " s) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
223 |
(* int list -> assignment *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
224 |
fun assignment_from_list [] i = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
225 |
NONE (* the SAT solver didn't provide a value for this variable *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
226 |
| assignment_from_list (x::xs) i = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
227 |
if x=i then (SOME true) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
228 |
else if x=(~i) then (SOME false) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
229 |
else assignment_from_list xs i |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
230 |
(* int list -> string list -> assignment *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
231 |
fun parse_assignment xs [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
232 |
assignment_from_list xs |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
233 |
| parse_assignment xs (line::lines) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
234 |
if String.isPrefix assignment_prefix line then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
235 |
parse_assignment (xs @ int_list_from_string line) lines |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
236 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
237 |
assignment_from_list xs |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
238 |
(* string -> string -> bool *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
239 |
fun is_substring needle haystack = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
240 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
241 |
val length1 = String.size needle |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
242 |
val length2 = String.size haystack |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
243 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
244 |
if length2 < length1 then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
245 |
false |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
246 |
else if needle = String.substring (haystack, 0, length1) then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
247 |
true |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
248 |
else is_substring needle (String.substring (haystack, 1, length2-1)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
249 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
250 |
(* string list -> result *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
251 |
fun parse_lines [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
252 |
UNKNOWN |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
253 |
| parse_lines (line::lines) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
254 |
if is_substring unsatisfiable line then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
255 |
UNSATISFIABLE NONE |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
256 |
else if is_substring satisfiable line then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
257 |
SATISFIABLE (parse_assignment [] lines) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
258 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
259 |
parse_lines lines |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
260 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
261 |
(parse_lines o (List.filter (fn l => l <> "")) o split_lines o File.read) path |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
262 |
end; |
14453 | 263 |
|
264 |
(* ------------------------------------------------------------------------- *) |
|
265 |
(* make_external_solver: call 'writefn', execute 'cmd', call 'readfn' *) |
|
266 |
(* ------------------------------------------------------------------------- *) |
|
267 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
268 |
(* string -> (PropLogic.prop_formula -> unit) -> (unit -> result) -> solver *) |
14453 | 269 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
270 |
fun make_external_solver cmd writefn readfn fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
271 |
(writefn fm; system cmd; readfn ()); |
14453 | 272 |
|
273 |
(* ------------------------------------------------------------------------- *) |
|
15040 | 274 |
(* read_dimacs_cnf_file: returns a propositional formula that corresponds to *) |
275 |
(* a SAT problem given in DIMACS CNF format *) |
|
276 |
(* ------------------------------------------------------------------------- *) |
|
277 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
278 |
(* Path.T -> PropLogic.prop_formula *) |
15040 | 279 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
280 |
fun read_dimacs_cnf_file path = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
281 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
282 |
(* string list -> string list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
283 |
fun filter_preamble [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
284 |
error "problem line not found in DIMACS CNF file" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
285 |
| filter_preamble (line::lines) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
286 |
if String.isPrefix "c " line orelse line = "c" then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
287 |
(* ignore comments *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
288 |
filter_preamble lines |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
289 |
else if String.isPrefix "p " line then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
290 |
(* ignore the problem line (which must be the last line of the preamble) *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
291 |
(* Ignoring the problem line implies that if the file contains more clauses *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
292 |
(* or variables than specified in its preamble, we will accept it anyway. *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
293 |
lines |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
294 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
295 |
error "preamble in DIMACS CNF file contains a line that does not begin with \"c \" or \"p \"" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
296 |
(* string -> int *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
297 |
fun int_from_string s = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
298 |
case Int.fromString s of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
299 |
SOME i => i |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
300 |
| NONE => error ("token " ^ quote s ^ "in DIMACS CNF file is not a number") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
301 |
(* int list -> int list list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
302 |
fun clauses xs = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
303 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
304 |
val (xs1, xs2) = take_prefix (fn i => i <> 0) xs |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
305 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
306 |
case xs2 of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
307 |
[] => [xs1] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
308 |
| (0::[]) => [xs1] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
309 |
| (0::tl) => xs1 :: clauses tl |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
310 |
| _ => sys_error "this cannot happen" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
311 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
312 |
(* int -> PropLogic.prop_formula *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
313 |
fun literal_from_int i = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
314 |
(i<>0 orelse error "variable index in DIMACS CNF file is 0"; |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
315 |
if i>0 then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
316 |
PropLogic.BoolVar i |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
317 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
318 |
PropLogic.Not (PropLogic.BoolVar (~i))) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
319 |
(* PropLogic.prop_formula list -> PropLogic.prop_formula *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
320 |
fun disjunction [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
321 |
error "empty clause in DIMACS CNF file" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
322 |
| disjunction (x::xs) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
323 |
(case xs of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
324 |
[] => x |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
325 |
| _ => PropLogic.Or (x, disjunction xs)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
326 |
(* PropLogic.prop_formula list -> PropLogic.prop_formula *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
327 |
fun conjunction [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
328 |
error "no clause in DIMACS CNF file" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
329 |
| conjunction (x::xs) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
330 |
(case xs of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
331 |
[] => x |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
332 |
| _ => PropLogic.And (x, conjunction xs)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
333 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
334 |
(conjunction |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
335 |
o (map disjunction) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
336 |
o (map (map literal_from_int)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
337 |
o clauses |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
338 |
o (map int_from_string) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
339 |
o List.concat |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
340 |
o (map (String.fields (fn c => c mem [#" ", #"\t", #"\n"]))) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
341 |
o filter_preamble |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
342 |
o (List.filter (fn l => l <> "")) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
343 |
o split_lines |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
344 |
o File.read) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
345 |
path |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
346 |
end; |
15040 | 347 |
|
348 |
(* ------------------------------------------------------------------------- *) |
|
14453 | 349 |
(* solvers: a (reference to a) table of all registered SAT solvers *) |
350 |
(* ------------------------------------------------------------------------- *) |
|
351 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
352 |
val solvers = ref ([] : (string * solver) list); |
14453 | 353 |
|
354 |
(* ------------------------------------------------------------------------- *) |
|
355 |
(* add_solver: updates 'solvers' by adding a new solver *) |
|
356 |
(* ------------------------------------------------------------------------- *) |
|
357 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
358 |
(* string * solver -> unit *) |
14453 | 359 |
|
22220 | 360 |
fun add_solver (name, new_solver) = |
361 |
let |
|
362 |
val the_solvers = !solvers; |
|
363 |
val _ = if AList.defined (op =) the_solvers name |
|
364 |
then warning ("SAT solver " ^ quote name ^ " was defined before") |
|
365 |
else (); |
|
366 |
in solvers := AList.update (op =) (name, new_solver) the_solvers end; |
|
14453 | 367 |
|
368 |
(* ------------------------------------------------------------------------- *) |
|
369 |
(* invoke_solver: returns the solver associated with the given 'name' *) |
|
15605 | 370 |
(* Note: If no solver is associated with 'name', exception 'Option' will be *) |
14453 | 371 |
(* raised. *) |
372 |
(* ------------------------------------------------------------------------- *) |
|
373 |
||
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
374 |
(* string -> solver *) |
14453 | 375 |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
376 |
fun invoke_solver name = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
377 |
(the o AList.lookup (op =) (!solvers)) name; |
14453 | 378 |
|
379 |
end; (* SatSolver *) |
|
380 |
||
381 |
||
382 |
(* ------------------------------------------------------------------------- *) |
|
383 |
(* Predefined SAT solvers *) |
|
384 |
(* ------------------------------------------------------------------------- *) |
|
385 |
||
386 |
(* ------------------------------------------------------------------------- *) |
|
14753 | 387 |
(* Internal SAT solver, available as 'SatSolver.invoke_solver "enumerate"' *) |
388 |
(* -- simply enumerates assignments until a satisfying assignment is found *) |
|
14453 | 389 |
(* ------------------------------------------------------------------------- *) |
390 |
||
391 |
let |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
392 |
fun enum_solver fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
393 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
394 |
(* int list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
395 |
val indices = PropLogic.indices fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
396 |
(* int list -> int list -> int list option *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
397 |
(* binary increment: list 'xs' of current bits, list 'ys' of all bits (lower bits first) *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
398 |
fun next_list _ ([]:int list) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
399 |
NONE |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
400 |
| next_list [] (y::ys) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
401 |
SOME [y] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
402 |
| next_list (x::xs) (y::ys) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
403 |
if x=y then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
404 |
(* reset the bit, continue *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
405 |
next_list xs ys |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
406 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
407 |
(* set the lowest bit that wasn't set before, keep the higher bits *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
408 |
SOME (y::x::xs) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
409 |
(* int list -> int -> bool *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
410 |
fun assignment_from_list xs i = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
411 |
i mem xs |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
412 |
(* int list -> SatSolver.result *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
413 |
fun solver_loop xs = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
414 |
if PropLogic.eval (assignment_from_list xs) fm then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
415 |
SatSolver.SATISFIABLE (SOME o (assignment_from_list xs)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
416 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
417 |
(case next_list xs indices of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
418 |
SOME xs' => solver_loop xs' |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
419 |
| NONE => SatSolver.UNSATISFIABLE NONE) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
420 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
421 |
(* start with the "first" assignment (all variables are interpreted as 'false') *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
422 |
solver_loop [] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
423 |
end |
14453 | 424 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
425 |
SatSolver.add_solver ("enumerate", enum_solver) |
14453 | 426 |
end; |
427 |
||
428 |
(* ------------------------------------------------------------------------- *) |
|
14753 | 429 |
(* Internal SAT solver, available as 'SatSolver.invoke_solver "dpll"' -- a *) |
430 |
(* simple implementation of the DPLL algorithm (cf. L. Zhang, S. Malik: "The *) |
|
431 |
(* Quest for Efficient Boolean Satisfiability Solvers", July 2002, Fig. 1). *) |
|
14453 | 432 |
(* ------------------------------------------------------------------------- *) |
433 |
||
434 |
let |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
435 |
local |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
436 |
open PropLogic |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
437 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
438 |
fun dpll_solver fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
439 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
440 |
(* We could use 'PropLogic.defcnf fm' instead of 'PropLogic.nnf fm' *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
441 |
(* but that sometimes leads to worse performance due to the *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
442 |
(* introduction of additional variables. *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
443 |
val fm' = PropLogic.nnf fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
444 |
(* int list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
445 |
val indices = PropLogic.indices fm' |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
446 |
(* int list -> int -> prop_formula *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
447 |
fun partial_var_eval [] i = BoolVar i |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
448 |
| partial_var_eval (x::xs) i = if x=i then True else if x=(~i) then False else partial_var_eval xs i |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
449 |
(* int list -> prop_formula -> prop_formula *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
450 |
fun partial_eval xs True = True |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
451 |
| partial_eval xs False = False |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
452 |
| partial_eval xs (BoolVar i) = partial_var_eval xs i |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
453 |
| partial_eval xs (Not fm) = SNot (partial_eval xs fm) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
454 |
| partial_eval xs (Or (fm1, fm2)) = SOr (partial_eval xs fm1, partial_eval xs fm2) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
455 |
| partial_eval xs (And (fm1, fm2)) = SAnd (partial_eval xs fm1, partial_eval xs fm2) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
456 |
(* prop_formula -> int list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
457 |
fun forced_vars True = [] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
458 |
| forced_vars False = [] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
459 |
| forced_vars (BoolVar i) = [i] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
460 |
| forced_vars (Not (BoolVar i)) = [~i] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
461 |
| forced_vars (Or (fm1, fm2)) = (forced_vars fm1) inter_int (forced_vars fm2) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
462 |
| forced_vars (And (fm1, fm2)) = (forced_vars fm1) union_int (forced_vars fm2) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
463 |
(* Above, i *and* ~i may be forced. In this case the first occurrence takes *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
464 |
(* precedence, and the next partial evaluation of the formula returns 'False'. *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
465 |
| forced_vars _ = error "formula is not in negation normal form" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
466 |
(* int list -> prop_formula -> (int list * prop_formula) *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
467 |
fun eval_and_force xs fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
468 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
469 |
val fm' = partial_eval xs fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
470 |
val xs' = forced_vars fm' |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
471 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
472 |
if null xs' then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
473 |
(xs, fm') |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
474 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
475 |
eval_and_force (xs@xs') fm' (* xs and xs' should be distinct, so '@' here should have *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
476 |
(* the same effect as 'union_int' *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
477 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
478 |
(* int list -> int option *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
479 |
fun fresh_var xs = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
480 |
Library.find_first (fn i => not (i mem_int xs) andalso not ((~i) mem_int xs)) indices |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
481 |
(* int list -> prop_formula -> int list option *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
482 |
(* partial assignment 'xs' *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
483 |
fun dpll xs fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
484 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
485 |
val (xs', fm') = eval_and_force xs fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
486 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
487 |
case fm' of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
488 |
True => SOME xs' |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
489 |
| False => NONE |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
490 |
| _ => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
491 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
492 |
val x = valOf (fresh_var xs') (* a fresh variable must exist since 'fm' did not evaluate to 'True'/'False' *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
493 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
494 |
case dpll (x::xs') fm' of (* passing fm' rather than fm should save some simplification work *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
495 |
SOME xs'' => SOME xs'' |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
496 |
| NONE => dpll ((~x)::xs') fm' (* now try interpreting 'x' as 'False' *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
497 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
498 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
499 |
(* int list -> assignment *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
500 |
fun assignment_from_list [] i = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
501 |
NONE (* the DPLL procedure didn't provide a value for this variable *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
502 |
| assignment_from_list (x::xs) i = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
503 |
if x=i then (SOME true) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
504 |
else if x=(~i) then (SOME false) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
505 |
else assignment_from_list xs i |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
506 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
507 |
(* initially, no variable is interpreted yet *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
508 |
case dpll [] fm' of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
509 |
SOME assignment => SatSolver.SATISFIABLE (assignment_from_list assignment) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
510 |
| NONE => SatSolver.UNSATISFIABLE NONE |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
511 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
512 |
end (* local *) |
14453 | 513 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
514 |
SatSolver.add_solver ("dpll", dpll_solver) |
14453 | 515 |
end; |
516 |
||
517 |
(* ------------------------------------------------------------------------- *) |
|
14753 | 518 |
(* Internal SAT solver, available as 'SatSolver.invoke_solver "auto"': uses *) |
17577
e87bf1d8f17a
zchaff_with_proofs does not delete zChaff\s resolve_trace file anymore
webertj
parents:
17541
diff
changeset
|
519 |
(* the last installed solver (other than "auto" itself) that does not raise *) |
15299
576fd0b65ed8
solver auto now returns the result of the first solver that does not raise NOT_CONFIGURED (which may be UNKNOWN)
webertj
parents:
15128
diff
changeset
|
520 |
(* 'NOT_CONFIGURED'. (However, the solver may return 'UNKNOWN'.) *) |
14453 | 521 |
(* ------------------------------------------------------------------------- *) |
522 |
||
523 |
let |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
524 |
fun auto_solver fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
525 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
526 |
fun loop [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
527 |
SatSolver.UNKNOWN |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
528 |
| loop ((name, solver)::solvers) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
529 |
if name="auto" then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
530 |
(* do not call solver "auto" from within "auto" *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
531 |
loop solvers |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
532 |
else ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
533 |
(if name="dpll" orelse name="enumerate" then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
534 |
warning ("Using SAT solver " ^ quote name ^ "; for better performance, consider using an external solver.") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
535 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
536 |
tracing ("Using SAT solver " ^ quote name ^ ".")); |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
537 |
(* apply 'solver' to 'fm' *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
538 |
solver fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
539 |
handle SatSolver.NOT_CONFIGURED => loop solvers |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
540 |
) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
541 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
542 |
loop (!SatSolver.solvers) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
543 |
end |
14453 | 544 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
545 |
SatSolver.add_solver ("auto", auto_solver) |
14453 | 546 |
end; |
547 |
||
548 |
(* ------------------------------------------------------------------------- *) |
|
20033 | 549 |
(* MiniSat 1.14 *) |
550 |
(* (http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/) *) |
|
551 |
(* ------------------------------------------------------------------------- *) |
|
552 |
||
20135 | 553 |
(* ------------------------------------------------------------------------- *) |
554 |
(* "minisat_with_proofs" requires a modified version of MiniSat 1.14 by John *) |
|
555 |
(* Matthews, which can output ASCII proof traces. Replaying binary proof *) |
|
556 |
(* traces generated by MiniSat-p_v1.14 has _not_ been implemented. *) |
|
557 |
(* ------------------------------------------------------------------------- *) |
|
558 |
||
559 |
(* add "minisat_with_proofs" _before_ "minisat" to the available solvers, so *) |
|
560 |
(* that the latter is preferred by the "auto" solver *) |
|
561 |
||
20152
b6373fe199e1
MiniSat proof trace format changed; MiniSat is now expected to produce a proof also for "trivial" problems
webertj
parents:
20137
diff
changeset
|
562 |
(* There is a complication that is dealt with in the code below: MiniSat *) |
b6373fe199e1
MiniSat proof trace format changed; MiniSat is now expected to produce a proof also for "trivial" problems
webertj
parents:
20137
diff
changeset
|
563 |
(* introduces IDs for original clauses in the proof trace. It does not (in *) |
b6373fe199e1
MiniSat proof trace format changed; MiniSat is now expected to produce a proof also for "trivial" problems
webertj
parents:
20137
diff
changeset
|
564 |
(* general) follow the convention that the original clauses are numbered *) |
b6373fe199e1
MiniSat proof trace format changed; MiniSat is now expected to produce a proof also for "trivial" problems
webertj
parents:
20137
diff
changeset
|
565 |
(* from 0 to n-1 (where n is the number of clauses in the formula). *) |
20135 | 566 |
|
567 |
let |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
568 |
exception INVALID_PROOF of string |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
569 |
fun minisat_with_proofs fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
570 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
571 |
val _ = if (getenv "MINISAT_HOME") = "" then raise SatSolver.NOT_CONFIGURED else () |
29872
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
572 |
val serial_str = serial_string () |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
573 |
val inpath = File.tmp_path (Path.explode ("isabelle" ^ serial_str ^ ".cnf")) |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
574 |
val outpath = File.tmp_path (Path.explode ("result" ^ serial_str)) |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
575 |
val proofpath = File.tmp_path (Path.explode ("result" ^ serial_str ^ ".prf")) |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
576 |
val cmd = (getenv "MINISAT_HOME") ^ "/minisat " ^ (Path.implode inpath) ^ " -r " ^ (Path.implode outpath) ^ " -t " ^ (Path.implode proofpath) ^ "> /dev/null" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
577 |
fun writefn fm = SatSolver.write_dimacs_cnf_file inpath fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
578 |
fun readfn () = SatSolver.read_std_result_file outpath ("SAT", "", "UNSAT") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
579 |
val _ = if File.exists inpath then warning ("overwriting existing file " ^ quote (Path.implode inpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
580 |
val _ = if File.exists outpath then warning ("overwriting existing file " ^ quote (Path.implode outpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
581 |
val cnf = PropLogic.defcnf fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
582 |
val result = SatSolver.make_external_solver cmd writefn readfn cnf |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
583 |
val _ = try File.rm inpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
584 |
val _ = try File.rm outpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
585 |
in case result of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
586 |
SatSolver.UNSATISFIABLE NONE => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
587 |
(let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
588 |
(* string list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
589 |
val proof_lines = (split_lines o File.read) proofpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
590 |
handle IO.Io _ => raise INVALID_PROOF "Could not read file \"result.prf\"" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
591 |
(* representation of clauses as ordered lists of literals (with duplicates removed) *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
592 |
(* prop_formula -> int list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
593 |
fun clause_to_lit_list (PropLogic.Or (fm1, fm2)) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
594 |
OrdList.union int_ord (clause_to_lit_list fm1) (clause_to_lit_list fm2) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
595 |
| clause_to_lit_list (PropLogic.BoolVar i) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
596 |
[i] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
597 |
| clause_to_lit_list (PropLogic.Not (PropLogic.BoolVar i)) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
598 |
[~i] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
599 |
| clause_to_lit_list _ = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
600 |
raise INVALID_PROOF "Error: invalid clause in CNF formula." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
601 |
(* prop_formula -> int *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
602 |
fun cnf_number_of_clauses (PropLogic.And (fm1, fm2)) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
603 |
cnf_number_of_clauses fm1 + cnf_number_of_clauses fm2 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
604 |
| cnf_number_of_clauses _ = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
605 |
1 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
606 |
val number_of_clauses = cnf_number_of_clauses cnf |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
607 |
(* int list array *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
608 |
val clauses = Array.array (number_of_clauses, []) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
609 |
(* initialize the 'clauses' array *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
610 |
(* prop_formula * int -> int *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
611 |
fun init_array (PropLogic.And (fm1, fm2), n) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
612 |
init_array (fm2, init_array (fm1, n)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
613 |
| init_array (fm, n) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
614 |
(Array.update (clauses, n, clause_to_lit_list fm); n+1) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
615 |
val _ = init_array (cnf, 0) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
616 |
(* optimization for the common case where MiniSat "R"s clauses in their *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
617 |
(* original order: *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
618 |
val last_ref_clause = ref (number_of_clauses - 1) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
619 |
(* search the 'clauses' array for the given list of literals 'lits', *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
620 |
(* starting at index '!last_ref_clause + 1' *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
621 |
(* int list -> int option *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
622 |
fun original_clause_id lits = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
623 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
624 |
fun original_clause_id_from index = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
625 |
if index = number_of_clauses then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
626 |
(* search from beginning again *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
627 |
original_clause_id_from 0 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
628 |
(* both 'lits' and the list of literals used in 'clauses' are sorted, so *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
629 |
(* testing for equality should suffice -- barring duplicate literals *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
630 |
else if Array.sub (clauses, index) = lits then ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
631 |
(* success *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
632 |
last_ref_clause := index; |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
633 |
SOME index |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
634 |
) else if index = !last_ref_clause then |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
635 |
(* failure *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
636 |
NONE |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
637 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
638 |
(* continue search *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
639 |
original_clause_id_from (index + 1) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
640 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
641 |
original_clause_id_from (!last_ref_clause + 1) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
642 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
643 |
(* string -> int *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
644 |
fun int_from_string s = ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
645 |
case Int.fromString s of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
646 |
SOME i => i |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
647 |
| NONE => raise INVALID_PROOF ("File format error: number expected (" ^ quote s ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
648 |
) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
649 |
(* parse the proof file *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
650 |
val clause_table = ref (Inttab.empty : int list Inttab.table) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
651 |
val empty_id = ref ~1 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
652 |
(* contains a mapping from clause IDs as used by MiniSat to clause IDs in *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
653 |
(* our proof format, where original clauses are numbered starting from 0 *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
654 |
val clause_id_map = ref (Inttab.empty : int Inttab.table) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
655 |
fun sat_to_proof id = ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
656 |
case Inttab.lookup (!clause_id_map) id of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
657 |
SOME id' => id' |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
658 |
| NONE => raise INVALID_PROOF ("Clause ID " ^ Int.toString id ^ " used, but not defined.") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
659 |
) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
660 |
val next_id = ref (number_of_clauses - 1) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
661 |
(* string list -> unit *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
662 |
fun process_tokens [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
663 |
() |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
664 |
| process_tokens (tok::toks) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
665 |
if tok="R" then ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
666 |
case toks of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
667 |
id::sep::lits => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
668 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
669 |
val _ = if !empty_id = ~1 then () else raise INVALID_PROOF "File format error: \"R\" disallowed after \"X\"." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
670 |
val cid = int_from_string id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
671 |
val _ = if sep = "<=" then () else raise INVALID_PROOF ("File format error: \"<=\" expected (" ^ quote sep ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
672 |
val ls = sort int_ord (map int_from_string lits) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
673 |
val proof_id = case original_clause_id ls of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
674 |
SOME orig_id => orig_id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
675 |
| NONE => raise INVALID_PROOF ("Original clause (new ID is " ^ id ^ ") not found.") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
676 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
677 |
(* extend the mapping of clause IDs with this newly defined ID *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
678 |
clause_id_map := Inttab.update_new (cid, proof_id) (!clause_id_map) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
679 |
handle Inttab.DUP _ => raise INVALID_PROOF ("File format error: clause " ^ id ^ " defined more than once (in \"R\").") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
680 |
(* the proof itself doesn't change *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
681 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
682 |
| _ => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
683 |
raise INVALID_PROOF "File format error: \"R\" followed by an insufficient number of tokens." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
684 |
) else if tok="C" then ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
685 |
case toks of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
686 |
id::sep::ids => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
687 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
688 |
val _ = if !empty_id = ~1 then () else raise INVALID_PROOF "File format error: \"C\" disallowed after \"X\"." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
689 |
val cid = int_from_string id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
690 |
val _ = if sep = "<=" then () else raise INVALID_PROOF ("File format error: \"<=\" expected (" ^ quote sep ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
691 |
(* ignore the pivot literals in MiniSat's trace *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
692 |
fun unevens [] = raise INVALID_PROOF "File format error: \"C\" followed by an even number of IDs." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
693 |
| unevens (x :: []) = x :: [] |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
694 |
| unevens (x :: _ :: xs) = x :: unevens xs |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
695 |
val rs = (map sat_to_proof o unevens o map int_from_string) ids |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
696 |
(* extend the mapping of clause IDs with this newly defined ID *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
697 |
val proof_id = inc next_id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
698 |
val _ = clause_id_map := Inttab.update_new (cid, proof_id) (!clause_id_map) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
699 |
handle Inttab.DUP _ => raise INVALID_PROOF ("File format error: clause " ^ id ^ " defined more than once (in \"C\").") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
700 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
701 |
(* update clause table *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
702 |
clause_table := Inttab.update_new (proof_id, rs) (!clause_table) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
703 |
handle Inttab.DUP _ => raise INVALID_PROOF ("Error: internal ID for clause " ^ id ^ " already used.") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
704 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
705 |
| _ => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
706 |
raise INVALID_PROOF "File format error: \"C\" followed by an insufficient number of tokens." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
707 |
) else if tok="D" then ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
708 |
case toks of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
709 |
[id] => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
710 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
711 |
val _ = if !empty_id = ~1 then () else raise INVALID_PROOF "File format error: \"D\" disallowed after \"X\"." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
712 |
val _ = sat_to_proof (int_from_string id) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
713 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
714 |
(* simply ignore "D" *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
715 |
() |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
716 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
717 |
| _ => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
718 |
raise INVALID_PROOF "File format error: \"D\" followed by an illegal number of tokens." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
719 |
) else if tok="X" then ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
720 |
case toks of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
721 |
[id1, id2] => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
722 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
723 |
val _ = if !empty_id = ~1 then () else raise INVALID_PROOF "File format error: more than one end-of-proof statement." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
724 |
val _ = sat_to_proof (int_from_string id1) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
725 |
val new_empty_id = sat_to_proof (int_from_string id2) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
726 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
727 |
(* update conflict id *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
728 |
empty_id := new_empty_id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
729 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
730 |
| _ => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
731 |
raise INVALID_PROOF "File format error: \"X\" followed by an illegal number of tokens." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
732 |
) else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
733 |
raise INVALID_PROOF ("File format error: unknown token " ^ quote tok ^ " encountered.") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
734 |
(* string list -> unit *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
735 |
fun process_lines [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
736 |
() |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
737 |
| process_lines (l::ls) = ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
738 |
process_tokens (String.tokens (fn c => c = #" " orelse c = #"\t") l); |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
739 |
process_lines ls |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
740 |
) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
741 |
(* proof *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
742 |
val _ = process_lines proof_lines |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
743 |
val _ = if !empty_id <> ~1 then () else raise INVALID_PROOF "File format error: no conflicting clause specified." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
744 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
745 |
SatSolver.UNSATISFIABLE (SOME (!clause_table, !empty_id)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
746 |
end handle INVALID_PROOF reason => (warning reason; SatSolver.UNSATISFIABLE NONE)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
747 |
| result => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
748 |
result |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
749 |
end |
20135 | 750 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
751 |
SatSolver.add_solver ("minisat_with_proofs", minisat_with_proofs) |
20135 | 752 |
end; |
753 |
||
20033 | 754 |
let |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
755 |
fun minisat fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
756 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
757 |
val _ = if (getenv "MINISAT_HOME") = "" then raise SatSolver.NOT_CONFIGURED else () |
29872
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
758 |
val serial_str = serial_string () |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
759 |
val inpath = File.tmp_path (Path.explode ("isabelle" ^ serial_str ^ ".cnf")) |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
760 |
val outpath = File.tmp_path (Path.explode ("result" ^ serial_str)) |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
761 |
val cmd = (getenv "MINISAT_HOME") ^ "/minisat " ^ (Path.implode inpath) ^ " -r " ^ (Path.implode outpath) ^ " > /dev/null" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
762 |
fun writefn fm = SatSolver.write_dimacs_cnf_file inpath (PropLogic.defcnf fm) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
763 |
fun readfn () = SatSolver.read_std_result_file outpath ("SAT", "", "UNSAT") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
764 |
val _ = if File.exists inpath then warning ("overwriting existing file " ^ quote (Path.implode inpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
765 |
val _ = if File.exists outpath then warning ("overwriting existing file " ^ quote (Path.implode outpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
766 |
val result = SatSolver.make_external_solver cmd writefn readfn fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
767 |
val _ = try File.rm inpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
768 |
val _ = try File.rm outpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
769 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
770 |
result |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
771 |
end |
20033 | 772 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
773 |
SatSolver.add_solver ("minisat", minisat) |
20033 | 774 |
end; |
775 |
||
776 |
(* ------------------------------------------------------------------------- *) |
|
15332 | 777 |
(* zChaff (http://www.princeton.edu/~chaff/zchaff.html) *) |
14453 | 778 |
(* ------------------------------------------------------------------------- *) |
779 |
||
17493
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
780 |
(* ------------------------------------------------------------------------- *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
781 |
(* 'zchaff_with_proofs' applies the "zchaff" prover to a formula, and if *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
782 |
(* zChaff finds that the formula is unsatisfiable, a proof of this is read *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
783 |
(* from a file "resolve_trace" that was generated by zChaff. See the code *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
784 |
(* below for the expected format of the "resolve_trace" file. Aside from *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
785 |
(* some basic syntactic checks, no verification of the proof is performed. *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
786 |
(* ------------------------------------------------------------------------- *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
787 |
|
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
788 |
(* add "zchaff_with_proofs" _before_ "zchaff" to the available solvers, so *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
789 |
(* that the latter is preferred by the "auto" solver *) |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
790 |
|
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
791 |
let |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
792 |
exception INVALID_PROOF of string |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
793 |
fun zchaff_with_proofs fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
794 |
case SatSolver.invoke_solver "zchaff" fm of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
795 |
SatSolver.UNSATISFIABLE NONE => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
796 |
(let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
797 |
(* string list *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
798 |
val proof_lines = ((split_lines o File.read) (Path.explode "resolve_trace")) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
799 |
handle IO.Io _ => raise INVALID_PROOF "Could not read file \"resolve_trace\"" |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
800 |
(* PropLogic.prop_formula -> int *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
801 |
fun cnf_number_of_clauses (PropLogic.And (fm1, fm2)) = cnf_number_of_clauses fm1 + cnf_number_of_clauses fm2 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
802 |
| cnf_number_of_clauses _ = 1 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
803 |
(* string -> int *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
804 |
fun int_from_string s = ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
805 |
case Int.fromString s of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
806 |
SOME i => i |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
807 |
| NONE => raise INVALID_PROOF ("File format error: number expected (" ^ quote s ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
808 |
) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
809 |
(* parse the "resolve_trace" file *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
810 |
val clause_offset = ref ~1 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
811 |
val clause_table = ref (Inttab.empty : int list Inttab.table) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
812 |
val empty_id = ref ~1 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
813 |
(* string list -> unit *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
814 |
fun process_tokens [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
815 |
() |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
816 |
| process_tokens (tok::toks) = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
817 |
if tok="CL:" then ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
818 |
case toks of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
819 |
id::sep::ids => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
820 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
821 |
val _ = if !clause_offset = ~1 then () else raise INVALID_PROOF ("File format error: \"CL:\" disallowed after \"VAR:\".") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
822 |
val _ = if !empty_id = ~1 then () else raise INVALID_PROOF ("File format error: \"CL:\" disallowed after \"CONF:\".") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
823 |
val cid = int_from_string id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
824 |
val _ = if sep = "<=" then () else raise INVALID_PROOF ("File format error: \"<=\" expected (" ^ quote sep ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
825 |
val rs = map int_from_string ids |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
826 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
827 |
(* update clause table *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
828 |
clause_table := Inttab.update_new (cid, rs) (!clause_table) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
829 |
handle Inttab.DUP _ => raise INVALID_PROOF ("File format error: clause " ^ id ^ " defined more than once.") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
830 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
831 |
| _ => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
832 |
raise INVALID_PROOF "File format error: \"CL:\" followed by an insufficient number of tokens." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
833 |
) else if tok="VAR:" then ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
834 |
case toks of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
835 |
id::levsep::levid::valsep::valid::antesep::anteid::litsep::lits => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
836 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
837 |
val _ = if !empty_id = ~1 then () else raise INVALID_PROOF ("File format error: \"VAR:\" disallowed after \"CONF:\".") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
838 |
(* set 'clause_offset' to the largest used clause ID *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
839 |
val _ = if !clause_offset = ~1 then clause_offset := |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
840 |
(case Inttab.max_key (!clause_table) of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
841 |
SOME id => id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
842 |
| NONE => cnf_number_of_clauses (PropLogic.defcnf fm) - 1 (* the first clause ID is 0, not 1 *)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
843 |
else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
844 |
() |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
845 |
val vid = int_from_string id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
846 |
val _ = if levsep = "L:" then () else raise INVALID_PROOF ("File format error: \"L:\" expected (" ^ quote levsep ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
847 |
val _ = int_from_string levid |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
848 |
val _ = if valsep = "V:" then () else raise INVALID_PROOF ("File format error: \"V:\" expected (" ^ quote valsep ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
849 |
val _ = int_from_string valid |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
850 |
val _ = if antesep = "A:" then () else raise INVALID_PROOF ("File format error: \"A:\" expected (" ^ quote antesep ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
851 |
val aid = int_from_string anteid |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
852 |
val _ = if litsep = "Lits:" then () else raise INVALID_PROOF ("File format error: \"Lits:\" expected (" ^ quote litsep ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
853 |
val ls = map int_from_string lits |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
854 |
(* convert the data provided by zChaff to our resolution-style proof format *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
855 |
(* each "VAR:" line defines a unit clause, the resolvents are implicitly *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
856 |
(* given by the literals in the antecedent clause *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
857 |
(* we use the sum of '!clause_offset' and the variable ID as clause ID for the unit clause *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
858 |
val cid = !clause_offset + vid |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
859 |
(* the low bit of each literal gives its sign (positive/negative), therefore *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
860 |
(* we have to divide each literal by 2 to obtain the proper variable ID; then *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
861 |
(* we add '!clause_offset' to obtain the ID of the corresponding unit clause *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
862 |
val vids = filter (not_equal vid) (map (fn l => l div 2) ls) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
863 |
val rs = aid :: map (fn v => !clause_offset + v) vids |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
864 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
865 |
(* update clause table *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
866 |
clause_table := Inttab.update_new (cid, rs) (!clause_table) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
867 |
handle Inttab.DUP _ => raise INVALID_PROOF ("File format error: clause " ^ string_of_int cid ^ " (derived from antecedent for variable " ^ id ^ ") already defined.") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
868 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
869 |
| _ => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
870 |
raise INVALID_PROOF "File format error: \"VAR:\" followed by an insufficient number of tokens." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
871 |
) else if tok="CONF:" then ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
872 |
case toks of |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
873 |
id::sep::ids => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
874 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
875 |
val _ = if !empty_id = ~1 then () else raise INVALID_PROOF "File format error: more than one conflicting clause specified." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
876 |
val cid = int_from_string id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
877 |
val _ = if sep = "==" then () else raise INVALID_PROOF ("File format error: \"==\" expected (" ^ quote sep ^ " encountered).") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
878 |
val ls = map int_from_string ids |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
879 |
(* the conflict clause must be resolved with the unit clauses *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
880 |
(* for its literals to obtain the empty clause *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
881 |
val vids = map (fn l => l div 2) ls |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
882 |
val rs = cid :: map (fn v => !clause_offset + v) vids |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
883 |
val new_empty_id = getOpt (Inttab.max_key (!clause_table), !clause_offset) + 1 |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
884 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
885 |
(* update clause table and conflict id *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
886 |
clause_table := Inttab.update_new (new_empty_id, rs) (!clause_table) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
887 |
handle Inttab.DUP _ => raise INVALID_PROOF ("File format error: clause " ^ string_of_int new_empty_id ^ " (empty clause derived from clause " ^ id ^ ") already defined."); |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
888 |
empty_id := new_empty_id |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
889 |
end |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
890 |
| _ => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
891 |
raise INVALID_PROOF "File format error: \"CONF:\" followed by an insufficient number of tokens." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
892 |
) else |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
893 |
raise INVALID_PROOF ("File format error: unknown token " ^ quote tok ^ " encountered.") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
894 |
(* string list -> unit *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
895 |
fun process_lines [] = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
896 |
() |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
897 |
| process_lines (l::ls) = ( |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
898 |
process_tokens (String.tokens (fn c => c = #" " orelse c = #"\t") l); |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
899 |
process_lines ls |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
900 |
) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
901 |
(* proof *) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
902 |
val _ = process_lines proof_lines |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
903 |
val _ = if !empty_id <> ~1 then () else raise INVALID_PROOF "File format error: no conflicting clause specified." |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
904 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
905 |
SatSolver.UNSATISFIABLE (SOME (!clause_table, !empty_id)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
906 |
end handle INVALID_PROOF reason => (warning reason; SatSolver.UNSATISFIABLE NONE)) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
907 |
| result => |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
908 |
result |
17493
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
909 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
910 |
SatSolver.add_solver ("zchaff_with_proofs", zchaff_with_proofs) |
17493
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
911 |
end; |
cf8713d880b1
SAT solver interface modified to support proofs of unsatisfiability
webertj
parents:
16915
diff
changeset
|
912 |
|
14487
157d0ea7b2da
Installed solvers now determined at call time (as opposed to compile time)
webertj
parents:
14460
diff
changeset
|
913 |
let |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
914 |
fun zchaff fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
915 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
916 |
val _ = if (getenv "ZCHAFF_HOME") = "" then raise SatSolver.NOT_CONFIGURED else () |
29872
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
917 |
val serial_str = serial_string () |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
918 |
val inpath = File.tmp_path (Path.explode ("isabelle" ^ serial_str ^ ".cnf")) |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
919 |
val outpath = File.tmp_path (Path.explode ("result" ^ serial_str)) |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
920 |
val cmd = (getenv "ZCHAFF_HOME") ^ "/zchaff " ^ (Path.implode inpath) ^ " > " ^ (Path.implode outpath) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
921 |
fun writefn fm = SatSolver.write_dimacs_cnf_file inpath (PropLogic.defcnf fm) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
922 |
fun readfn () = SatSolver.read_std_result_file outpath ("Instance Satisfiable", "", "Instance Unsatisfiable") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
923 |
val _ = if File.exists inpath then warning ("overwriting existing file " ^ quote (Path.implode inpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
924 |
val _ = if File.exists outpath then warning ("overwriting existing file " ^ quote (Path.implode outpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
925 |
val result = SatSolver.make_external_solver cmd writefn readfn fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
926 |
val _ = try File.rm inpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
927 |
val _ = try File.rm outpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
928 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
929 |
result |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
930 |
end |
14487
157d0ea7b2da
Installed solvers now determined at call time (as opposed to compile time)
webertj
parents:
14460
diff
changeset
|
931 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
932 |
SatSolver.add_solver ("zchaff", zchaff) |
14965 | 933 |
end; |
934 |
||
935 |
(* ------------------------------------------------------------------------- *) |
|
936 |
(* BerkMin 561 (http://eigold.tripod.com/BerkMin.html) *) |
|
937 |
(* ------------------------------------------------------------------------- *) |
|
938 |
||
939 |
let |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
940 |
fun berkmin fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
941 |
let |
30237
e6f76bf0e067
Eliminated ZCHAFF_VERSION configuration variable, since zChaff's output format is identical in all versions since March 2003 (at least), and also because it forces users who want to use the latest versions to lie about the version number.
blanchet
parents:
29872
diff
changeset
|
942 |
val _ = if (getenv "BERKMIN_HOME") = "" then raise SatSolver.NOT_CONFIGURED else () |
29872
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
943 |
val serial_str = serial_string () |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
944 |
val inpath = File.tmp_path (Path.explode ("isabelle" ^ serial_str ^ ".cnf")) |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
945 |
val outpath = File.tmp_path (Path.explode ("result" ^ serial_str)) |
30237
e6f76bf0e067
Eliminated ZCHAFF_VERSION configuration variable, since zChaff's output format is identical in all versions since March 2003 (at least), and also because it forces users who want to use the latest versions to lie about the version number.
blanchet
parents:
29872
diff
changeset
|
946 |
val exec = getenv "BERKMIN_EXE" |
e6f76bf0e067
Eliminated ZCHAFF_VERSION configuration variable, since zChaff's output format is identical in all versions since March 2003 (at least), and also because it forces users who want to use the latest versions to lie about the version number.
blanchet
parents:
29872
diff
changeset
|
947 |
val cmd = (getenv "BERKMIN_HOME") ^ "/" ^ (if exec = "" then "BerkMin561" else exec) ^ " " ^ (Path.implode inpath) ^ " > " ^ (Path.implode outpath) |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
948 |
fun writefn fm = SatSolver.write_dimacs_cnf_file inpath (PropLogic.defcnf fm) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
949 |
fun readfn () = SatSolver.read_std_result_file outpath ("Satisfiable !!", "solution =", "UNSATISFIABLE !!") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
950 |
val _ = if File.exists inpath then warning ("overwriting existing file " ^ quote (Path.implode inpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
951 |
val _ = if File.exists outpath then warning ("overwriting existing file " ^ quote (Path.implode outpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
952 |
val result = SatSolver.make_external_solver cmd writefn readfn fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
953 |
val _ = try File.rm inpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
954 |
val _ = try File.rm outpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
955 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
956 |
result |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
957 |
end |
14965 | 958 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
959 |
SatSolver.add_solver ("berkmin", berkmin) |
14965 | 960 |
end; |
961 |
||
962 |
(* ------------------------------------------------------------------------- *) |
|
963 |
(* Jerusat 1.3 (http://www.cs.tau.ac.il/~ale1/) *) |
|
964 |
(* ------------------------------------------------------------------------- *) |
|
965 |
||
966 |
let |
|
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
967 |
fun jerusat fm = |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
968 |
let |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
969 |
val _ = if (getenv "JERUSAT_HOME") = "" then raise SatSolver.NOT_CONFIGURED else () |
29872
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
970 |
val serial_str = serial_string () |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
971 |
val inpath = File.tmp_path (Path.explode ("isabelle" ^ serial_str ^ ".cnf")) |
14e208d607af
Added serial_string to SAT solver input and output files, to prevent multithreading chaos.
blanchet
parents:
22567
diff
changeset
|
972 |
val outpath = File.tmp_path (Path.explode ("result" ^ serial_str)) |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
973 |
val cmd = (getenv "JERUSAT_HOME") ^ "/Jerusat1.3 " ^ (Path.implode inpath) ^ " > " ^ (Path.implode outpath) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
974 |
fun writefn fm = SatSolver.write_dimacs_cnf_file inpath (PropLogic.defcnf fm) |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
975 |
fun readfn () = SatSolver.read_std_result_file outpath ("s SATISFIABLE", "v ", "s UNSATISFIABLE") |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
976 |
val _ = if File.exists inpath then warning ("overwriting existing file " ^ quote (Path.implode inpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
977 |
val _ = if File.exists outpath then warning ("overwriting existing file " ^ quote (Path.implode outpath)) else () |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
978 |
val result = SatSolver.make_external_solver cmd writefn readfn fm |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
979 |
val _ = try File.rm inpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
980 |
val _ = try File.rm outpath |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
981 |
in |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
982 |
result |
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
983 |
end |
14965 | 984 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
985 |
SatSolver.add_solver ("jerusat", jerusat) |
14487
157d0ea7b2da
Installed solvers now determined at call time (as opposed to compile time)
webertj
parents:
14460
diff
changeset
|
986 |
end; |
14453 | 987 |
|
988 |
(* ------------------------------------------------------------------------- *) |
|
989 |
(* Add code for other SAT solvers below. *) |
|
990 |
(* ------------------------------------------------------------------------- *) |
|
991 |
||
992 |
(* |
|
14487
157d0ea7b2da
Installed solvers now determined at call time (as opposed to compile time)
webertj
parents:
14460
diff
changeset
|
993 |
let |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
994 |
fun mysolver fm = ... |
14487
157d0ea7b2da
Installed solvers now determined at call time (as opposed to compile time)
webertj
parents:
14460
diff
changeset
|
995 |
in |
22567
1565d476a9e2
removed assert/deny (avoid clash with Alice keywords and confusion due to strict evaluation);
wenzelm
parents:
22220
diff
changeset
|
996 |
SatSolver.add_solver ("myname", (fn fm => if mysolver_is_configured then mysolver fm else raise SatSolver.NOT_CONFIGURED)); -- register the solver |
14487
157d0ea7b2da
Installed solvers now determined at call time (as opposed to compile time)
webertj
parents:
14460
diff
changeset
|
997 |
end; |
14453 | 998 |
|
999 |
-- the solver is now available as SatSolver.invoke_solver "myname" |
|
1000 |
*) |