author | webertj |
Sat, 24 Sep 2005 07:21:46 +0200 | |
changeset 17622 | 5d03a69481b6 |
parent 17618 | 1330157e156a |
child 17623 | ae4af66b3072 |
permissions | -rw-r--r-- |
17618 | 1 |
(* Title: HOL/Tools/sat_funcs.ML |
2 |
ID: $Id$ |
|
3 |
Author: Stephan Merz and Alwen Tiu, QSL Team, LORIA (http://qsl.loria.fr) |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
4 |
Author: Tjark Weber |
17618 | 5 |
Copyright 2005 |
6 |
||
7 |
||
8 |
Proof reconstruction from SAT solvers. |
|
9 |
||
10 |
Description: |
|
11 |
This file defines several tactics to invoke a proof-producing |
|
12 |
SAT solver on a propositional goal in clausal form. |
|
13 |
||
14 |
We use a sequent presentation of clauses to speed up resolution |
|
15 |
proof reconstruction. |
|
16 |
We call such clauses as "raw clauses", which are of the form |
|
17 |
[| c1; c2; ...; ck |] ==> False |
|
18 |
where each clause ci is of the form |
|
19 |
[|l1, l2, ..., lm |] ==> False, |
|
20 |
where li is a literal (see also comments in cnf_funcs.ML). |
|
21 |
||
22 |
-- observe that this is the "dualized" version of the standard |
|
23 |
clausal form |
|
24 |
l1' \/ l2' \/ ... \/ lm', where li is the negation normal |
|
25 |
form of ~li'. |
|
26 |
The tactic produces a clause representation of the given goal |
|
27 |
in DIMACS format and invokes a SAT solver, which should return |
|
28 |
a proof consisting of a sequence of resolution steps, indicating |
|
29 |
the two input clauses and the variable resolved upon, and resulting |
|
30 |
in new clauses, leading to the empty clause (i.e., False). |
|
31 |
The tactic replays this proof in Isabelle and thus solves the |
|
32 |
overall goal. |
|
33 |
||
34 |
There are two SAT tactics available. They differ in the CNF transformation |
|
35 |
used. The "sat_tac" uses naive CNF transformation to transform the theorem |
|
36 |
to be proved before giving it to SAT solver. The naive transformation in |
|
37 |
some worst case can lead to explonential blow up in formula size. |
|
38 |
The other tactic, the "satx_tac" uses the "definitional CNF transformation" |
|
39 |
which produces formula of linear size increase compared to the input formula. |
|
40 |
This transformation introduces new variables. See also cnf_funcs.ML for |
|
41 |
more comments. |
|
42 |
||
43 |
Notes for the current revision: |
|
44 |
- The current version supports only zChaff prover. |
|
45 |
- The environment variable ZCHAFF_HOME must be set to point to |
|
46 |
the directory where zChaff executable resides |
|
47 |
- The environment variable ZCHAFF_VERSION must be set according to |
|
48 |
the version of zChaff used. Current supported version of zChaff: |
|
49 |
zChaff version 2004.11.15 |
|
50 |
*) |
|
51 |
||
52 |
signature SAT = |
|
53 |
sig |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
54 |
val trace_sat : bool ref (* print trace messages *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
55 |
val sat_tac : Tactical.tactic |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
56 |
val satx_tac : Tactical.tactic |
17618 | 57 |
end |
58 |
||
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
59 |
functor SATFunc (structure cnf : CNF) : SAT = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
60 |
struct |
17618 | 61 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
62 |
val trace_sat = ref false; |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
63 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
64 |
val counter = ref 0; |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
65 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
66 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
67 |
(* rev_lookup: look up the Isabelle/HOL atom corresponding to a DIMACS *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
68 |
(* variable index in the dictionary. This index should exist in the *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
69 |
(* dictionary, otherwise exception Option is raised. *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
70 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
71 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
72 |
(* 'b -> ('a * 'b) list -> 'a *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
73 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
74 |
fun rev_lookup idx [] = raise Option |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
75 |
| rev_lookup idx ((key, entry)::dict) = if entry=idx then key else rev_lookup idx dict; |
17618 | 76 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
77 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
78 |
(* swap_prem: convert rules of the form *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
79 |
(* l1 ==> l2 ==> .. ==> li ==> .. ==> False *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
80 |
(* to *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
81 |
(* l1 ==> l2 ==> .... ==> ~li *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
82 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
83 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
84 |
fun swap_prem rslv c = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
85 |
let |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
86 |
val thm1 = rule_by_tactic (metacut_tac c 1 THEN (atac 1) THEN (REPEAT_SOME atac)) rslv |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
87 |
in |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
88 |
rule_by_tactic (ALLGOALS (cnf.weakening_tac)) thm1 |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
89 |
end; |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
90 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
91 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
92 |
(* is_dual: check if two atoms are dual to each other *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
93 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
94 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
95 |
(* Term.term -> Term.term -> bool *) |
17618 | 96 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
97 |
fun is_dual (Const ("Trueprop", _) $ x) y = is_dual x y |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
98 |
| is_dual x (Const ("Trueprop", _) $ y) = is_dual x y |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
99 |
| is_dual (Const ("Not", _) $ x) y = (x = y) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
100 |
| is_dual x (Const ("Not", _) $ y) = (x = y) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
101 |
| is_dual x y = false; |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
102 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
103 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
104 |
(* dual_mem: check if an atom has a dual in a list of atoms *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
105 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
106 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
107 |
(* Term.term -> Term.term list -> bool *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
108 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
109 |
fun dual_mem x [] = false |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
110 |
| dual_mem x (y::ys) = is_dual x y orelse dual_mem x ys; |
17618 | 111 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
112 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
113 |
(* replay_chain: proof reconstruction: given two clauses *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
114 |
(* [| x1 ; .. ; a ; .. ; xn |] ==> False *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
115 |
(* and *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
116 |
(* [| y1 ; .. ; ~a ; .. ; ym |] ==> False , *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
117 |
(* we first convert the first clause into *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
118 |
(* [| x1 ; ... ; xn |] ==> ~a (using swap_prem) *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
119 |
(* and do a resolution with the second clause to produce *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
120 |
(* [| y1 ; ... ; x1 ; ... ; xn ; ... ; yn |] ==> False *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
121 |
(* ------------------------------------------------------------------------- *) |
17618 | 122 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
123 |
(* Theory.theory -> Thm.thm option Array.array -> int -> int list -> unit *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
124 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
125 |
fun replay_chain sg clauses idx (c::cs) = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
126 |
let |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
127 |
val (SOME fc) = Array.sub (clauses, c) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
128 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
129 |
fun strip_neg (Const ("Trueprop", _) $ x) = strip_neg x |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
130 |
| strip_neg (Const ("Not", _) $ x) = x |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
131 |
| strip_neg x = x |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
132 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
133 |
(* find out which atom (literal) is used in the resolution *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
134 |
fun res_atom [] _ = raise THM ("Proof reconstruction failed!", 0, []) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
135 |
| res_atom (x::xs) ys = if dual_mem x ys then strip_neg x else res_atom xs ys |
17618 | 136 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
137 |
fun replay old [] = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
138 |
old |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
139 |
| replay old (cl::cls) = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
140 |
let |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
141 |
val icl = (valOf o Array.sub) (clauses, cl) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
142 |
val var = res_atom (prems_of old) (prems_of icl) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
143 |
val atom = cterm_of sg var |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
144 |
val rslv = instantiate' [] [SOME atom] notI |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
145 |
val _ = if !trace_sat then |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
146 |
tracing ("Resolving clause: " ^ string_of_thm old ^ |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
147 |
"\nwith clause: " ^ string_of_thm icl ^ |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
148 |
"\nusing literal " ^ string_of_cterm atom ^ ".") |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
149 |
else () |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
150 |
val thm1 = (rule_by_tactic (REPEAT_SOME (rtac (swap_prem rslv old))) icl |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
151 |
handle THM _ => rule_by_tactic (REPEAT_SOME (rtac (swap_prem rslv icl))) old) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
152 |
val new = rule_by_tactic distinct_subgoals_tac thm1 |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
153 |
val _ = if !trace_sat then tracing ("Resulting clause: " ^ string_of_thm new) else () |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
154 |
val _ = inc counter |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
155 |
in |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
156 |
replay new cls |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
157 |
end |
17618 | 158 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
159 |
val _ = Array.update (clauses, idx, SOME (replay fc cs)) |
17618 | 160 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
161 |
val _ = if !trace_sat then |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
162 |
tracing ("Replay chain successful; clause stored at #" ^ string_of_int idx) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
163 |
else () |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
164 |
in |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
165 |
() |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
166 |
end; |
17618 | 167 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
168 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
169 |
(* replay_proof: replay the resolution proof returned by the SAT solver; cf. *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
170 |
(* SatSolver.proof for details of the proof format. Returns the *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
171 |
(* theorem established by the proof (which is just False). *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
172 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
173 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
174 |
(* Theory.theory -> Thm.thm option Array.array -> SatSolver.proof -> Thm.thm *) |
17618 | 175 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
176 |
fun replay_proof sg clauses (clause_table, empty_id) = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
177 |
let |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
178 |
fun complete [] = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
179 |
true |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
180 |
| complete (x::xs) = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
181 |
(isSome o Array.sub) (clauses, x) andalso complete xs |
17618 | 182 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
183 |
fun do_chains [] = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
184 |
() |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
185 |
| do_chains (ch::chs) = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
186 |
let |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
187 |
val (idx, cls) = ch |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
188 |
in |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
189 |
if complete cls then ( |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
190 |
replay_chain sg clauses idx cls; |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
191 |
do_chains chs |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
192 |
) else |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
193 |
do_chains (chs @ [ch]) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
194 |
end |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
195 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
196 |
val _ = do_chains (Inttab.dest clause_table) |
17618 | 197 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
198 |
val _ = if !trace_sat then |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
199 |
tracing (string_of_int (!counter) ^ " resolution steps total.") |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
200 |
else () |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
201 |
in |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
202 |
(valOf o Array.sub) (clauses, empty_id) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
203 |
end; |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
204 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
205 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
206 |
(* Functions to build the sat tactic *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
207 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
208 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
209 |
(* A trivial tactic, used in preprocessing before calling the main tactic *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
210 |
val pre_sat_tac = (REPEAT (etac conjE 1)) THEN (REPEAT ((atac 1) ORELSE (etac FalseE 1))); |
17618 | 211 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
212 |
fun collect_atoms (Const ("Trueprop", _) $ x) ls = collect_atoms x ls |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
213 |
| collect_atoms (Const ("op |", _) $ x $ y) ls = collect_atoms x (collect_atoms y ls) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
214 |
| collect_atoms x ls = x ins ls; |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
215 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
216 |
fun has_duals [] = false |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
217 |
| has_duals (x::xs) = dual_mem x xs orelse has_duals xs; |
17618 | 218 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
219 |
fun is_trivial_clause (Const ("True", _)) = true |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
220 |
| is_trivial_clause c = has_duals (collect_atoms c []); |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
221 |
|
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
222 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
223 |
(* rawsat_thm: run external SAT solver with the given clauses. Reconstructs *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
224 |
(* a proof from the resulting proof trace of the SAT solver. *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
225 |
(* ------------------------------------------------------------------------- *) |
17618 | 226 |
|
227 |
fun rawsat_thm sg prems = |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
228 |
let |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
229 |
val thms = filter (not o is_trivial_clause o term_of o cprop_of) prems (* remove trivial clauses *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
230 |
val (fm, dict) = cnf.cnf2prop thms |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
231 |
val _ = if !trace_sat then tracing "Invoking SAT solver ..." else () |
17618 | 232 |
in |
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
233 |
case SatSolver.invoke_solver "zchaff_with_proofs" fm of |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
234 |
SatSolver.UNSATISFIABLE (SOME (clause_table, empty_id)) => |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
235 |
let |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
236 |
val _ = if !trace_sat then |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
237 |
tracing ("Proof trace from SAT solver:\n" ^ |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
238 |
"clauses: [" ^ commas (map (fn (c, cs) => |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
239 |
"(" ^ string_of_int c ^ ", [" ^ commas (map string_of_int cs) ^ "])") (Inttab.dest clause_table)) ^ "]\n" ^ |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
240 |
"empty clause: " ^ string_of_int empty_id) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
241 |
else () |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
242 |
val raw_thms = cnf.cnf2raw_thms thms |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
243 |
val raw_thms' = map (rule_by_tactic distinct_subgoals_tac) raw_thms |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
244 |
(* initialize the clause array with the original clauses *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
245 |
val max_idx = valOf (Inttab.max_key clause_table) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
246 |
val clauses = Array.array (max_idx + 1, NONE) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
247 |
val _ = fold (fn thm => fn idx => (Array.update (clauses, idx, SOME thm); idx+1)) raw_thms' 0 |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
248 |
in |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
249 |
replay_proof sg clauses (clause_table, empty_id) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
250 |
end |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
251 |
| SatSolver.UNSATISFIABLE NONE => |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
252 |
raise THM ("SAT solver claims the formula to be unsatisfiable, but did not provide a proof", 0, []) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
253 |
| SatSolver.SATISFIABLE assignment => |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
254 |
let |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
255 |
val msg = "SAT solver found a countermodel:\n" |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
256 |
^ (enclose "{" "}" |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
257 |
o commas |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
258 |
o map (Sign.string_of_term sg o fst) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
259 |
o filter (fn (_, idx) => getOpt (assignment idx, false))) dict |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
260 |
in |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
261 |
raise THM (msg, 0, []) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
262 |
end |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
263 |
| SatSolver.UNKNOWN => |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
264 |
raise THM ("SAT solver failed to decide the formula", 0, []) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
265 |
end; |
17618 | 266 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
267 |
(* ------------------------------------------------------------------------- *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
268 |
(* Tactics *) |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
269 |
(* ------------------------------------------------------------------------- *) |
17618 | 270 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
271 |
fun cnfsat_basic_tac state = |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
272 |
let |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
273 |
val sg = Thm.sign_of_thm state |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
274 |
in |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
275 |
METAHYPS (fn prems => rtac (rawsat_thm sg prems) 1) 1 state |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
276 |
end; |
17618 | 277 |
|
278 |
(* Tactic for calling external SAT solver, taking as input CNF clauses *) |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
279 |
val cnfsat_tac = pre_sat_tac THEN (IF_UNSOLVED cnfsat_basic_tac); |
17618 | 280 |
|
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
281 |
(* Tactic for calling external SAT solver, taking as input arbitrary formula *) |
17618 | 282 |
val sat_tac = cnf.cnf_thin_tac THEN cnfsat_tac; |
283 |
||
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
284 |
(* |
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
285 |
Tactic for calling external SAT solver, taking as input arbitrary formula. |
17618 | 286 |
The input is translated to CNF (in primitive form), possibly introducing |
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
287 |
new literals. |
17618 | 288 |
*) |
289 |
val satx_tac = cnf.cnfx_thin_tac THEN cnfsat_tac; |
|
290 |
||
17622
5d03a69481b6
code reformatted and restructured, many minor modifications
webertj
parents:
17618
diff
changeset
|
291 |
end; (* of structure *) |