| author | nipkow | 
| Thu, 13 Sep 2018 15:15:50 +0200 | |
| changeset 68989 | d6d5fb521896 | 
| parent 67559 | 833d154ab189 | 
| child 69593 | 3dda49e08b9d | 
| permissions | -rw-r--r-- | 
| 55239 | 1 | (* Title: HOL/Tools/sat.ML | 
| 17618 | 2 | Author: Stephan Merz and Alwen Tiu, QSL Team, LORIA (http://qsl.loria.fr) | 
| 29269 
5c25a2012975
moved term order operations to structure TermOrd (cf. Pure/term_ord.ML);
 wenzelm parents: 
27115diff
changeset | 3 | Author: Tjark Weber, TU Muenchen | 
| 17618 | 4 | |
| 5 | Proof reconstruction from SAT solvers. | |
| 6 | ||
| 7 | Description: | |
| 8 | This file defines several tactics to invoke a proof-producing | |
| 9 | SAT solver on a propositional goal in clausal form. | |
| 10 | ||
| 11 | We use a sequent presentation of clauses to speed up resolution | |
| 17695 | 12 | proof reconstruction. | 
| 13 | We call such clauses "raw clauses", which are of the form | |
| 20440 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 14 | [x1, ..., xn, P] |- False | 
| 19236 
150e8b0fb991
clauses now use (meta-)hyps instead of (meta-)implications; significant speedup
 webertj parents: 
17843diff
changeset | 15 | (note the use of |- instead of ==>, i.e. of Isabelle's (meta-)hyps here), | 
| 55239 | 16 | where each xi is a literal (see also comments in cnf.ML). | 
| 17618 | 17 | |
| 19236 
150e8b0fb991
clauses now use (meta-)hyps instead of (meta-)implications; significant speedup
 webertj parents: 
17843diff
changeset | 18 | This does not work for goals containing schematic variables! | 
| 
150e8b0fb991
clauses now use (meta-)hyps instead of (meta-)implications; significant speedup
 webertj parents: 
17843diff
changeset | 19 | |
| 20039 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 20 | The tactic produces a clause representation of the given goal | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 21 | in DIMACS format and invokes a SAT solver, which should return | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 22 | a proof consisting of a sequence of resolution steps, indicating | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 23 | the two input clauses, and resulting in new clauses, leading to | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 24 | the empty clause (i.e. "False"). The tactic replays this proof | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 25 | in Isabelle and thus solves the overall goal. | 
| 17618 | 26 | |
| 20440 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 27 | There are three SAT tactics available. They differ in the CNF transformation | 
| 20039 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 28 | used. "sat_tac" uses naive CNF transformation to transform the theorem to be | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 29 | proved before giving it to the SAT solver. The naive transformation in the | 
| 20440 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 30 | worst case can lead to an exponential blow up in formula size. Another | 
| 20039 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 31 | tactic, "satx_tac", uses "definitional CNF transformation" which attempts to | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 32 | produce a formula of linear size increase compared to the input formula, at | 
| 55239 | 33 | the cost of possibly introducing new variables. See cnf.ML for more | 
| 20440 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 34 | comments on the CNF transformation. "rawsat_tac" should be used with | 
| 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 35 | caution: no CNF transformation is performed, and the tactic's behavior is | 
| 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 36 | undefined if the subgoal is not already given as [| C1; ...; Cn |] ==> False, | 
| 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 37 | where each Ci is a disjunction. | 
| 17618 | 38 | |
| 20039 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 39 | The SAT solver to be used can be set via the "solver" reference. See | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 40 | sat_solvers.ML for possible values, and etc/settings for required (solver- | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 41 | dependent) configuration settings. To replay SAT proofs in Isabelle, you | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 42 | must of course use a proof-producing SAT solver in the first place. | 
| 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 43 | |
| 52059 | 44 | Proofs are replayed only if "quick_and_dirty" is false. If | 
| 45 | "quick_and_dirty" is true, the theorem (in case the SAT solver claims its | |
| 20039 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 46 | negation to be unsatisfiable) is proved via an oracle. | 
| 17618 | 47 | *) | 
| 48 | ||
| 49 | signature SAT = | |
| 50 | sig | |
| 55240 | 51 | val trace: bool Config.T (* print trace messages *) | 
| 52 | val solver: string Config.T (* name of SAT solver to be used *) | |
| 41447 | 53 | val counter: int Unsynchronized.ref (* output: number of resolution steps during last proof replay *) | 
| 54 | val rawsat_thm: Proof.context -> cterm list -> thm | |
| 55 | val rawsat_tac: Proof.context -> int -> tactic | |
| 56 | val sat_tac: Proof.context -> int -> tactic | |
| 57 | val satx_tac: Proof.context -> int -> tactic | |
| 17618 | 58 | end | 
| 59 | ||
| 55239 | 60 | structure SAT : SAT = | 
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 61 | struct | 
| 17618 | 62 | |
| 67149 | 63 | val trace = Attrib.setup_config_bool \<^binding>\<open>sat_trace\<close> (K false); | 
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 64 | |
| 55240 | 65 | fun cond_tracing ctxt msg = | 
| 66 | if Config.get ctxt trace then tracing (msg ()) else (); | |
| 67 | ||
| 67149 | 68 | val solver = Attrib.setup_config_string \<^binding>\<open>sat_solver\<close> (K "cdclite"); | 
| 32740 | 69 | (*see HOL/Tools/sat_solver.ML for possible values*) | 
| 20039 
4293f932fe83
"solver" reference added to make the SAT solver configurable
 webertj parents: 
19976diff
changeset | 70 | |
| 32740 | 71 | val counter = Unsynchronized.ref 0; | 
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 72 | |
| 32010 | 73 | val resolution_thm = | 
| 67091 | 74 |   @{lemma "(P \<Longrightarrow> False) \<Longrightarrow> (\<not> P \<Longrightarrow> False) \<Longrightarrow> False" by (rule case_split)}
 | 
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 75 | |
| 20278 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 76 | (* ------------------------------------------------------------------------- *) | 
| 21768 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 77 | (* lit_ord: an order on integers that considers their absolute values only, *) | 
| 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 78 | (* thereby treating integers that represent the same atom (positively *) | 
| 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 79 | (* or negatively) as equal *) | 
| 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 80 | (* ------------------------------------------------------------------------- *) | 
| 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 81 | |
| 41447 | 82 | fun lit_ord (i, j) = int_ord (abs i, abs j); | 
| 21768 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 83 | |
| 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 84 | (* ------------------------------------------------------------------------- *) | 
| 20278 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 85 | (* CLAUSE: during proof reconstruction, three kinds of clauses are *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 86 | (* distinguished: *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 87 | (* 1. NO_CLAUSE: clause not proved (yet) *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 88 | (* 2. ORIG_CLAUSE: a clause as it occurs in the original problem *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 89 | (* 3. RAW_CLAUSE: a raw clause, with additional precomputed information *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 90 | (* (a mapping from int's to its literals) for faster proof *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 91 | (* reconstruction *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 92 | (* ------------------------------------------------------------------------- *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 93 | |
| 41447 | 94 | datatype CLAUSE = | 
| 95 | NO_CLAUSE | |
| 96 | | ORIG_CLAUSE of thm | |
| 97 | | RAW_CLAUSE of thm * (int * cterm) list; | |
| 20278 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 98 | |
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 99 | (* ------------------------------------------------------------------------- *) | 
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 100 | (* resolve_raw_clauses: given a non-empty list of raw clauses, we fold *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 101 | (* resolution over the list (starting with its head), i.e. with two raw *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 102 | (* clauses *) | 
| 20440 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 103 | (* [P, x1, ..., a, ..., xn] |- False *) | 
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 104 | (* and *) | 
| 20440 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 105 | (* [Q, y1, ..., a', ..., ym] |- False *) | 
| 19976 
aa35f8e27c73
comments fixed, minor optimization wrt. certifying terms
 webertj parents: 
19553diff
changeset | 106 | (* (where a and a' are dual to each other), we convert the first clause *) | 
| 
aa35f8e27c73
comments fixed, minor optimization wrt. certifying terms
 webertj parents: 
19553diff
changeset | 107 | (* to *) | 
| 20440 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 108 | (* [P, x1, ..., xn] |- a ==> False , *) | 
| 19976 
aa35f8e27c73
comments fixed, minor optimization wrt. certifying terms
 webertj parents: 
19553diff
changeset | 109 | (* the second clause to *) | 
| 20440 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 110 | (* [Q, y1, ..., ym] |- a' ==> False *) | 
| 19976 
aa35f8e27c73
comments fixed, minor optimization wrt. certifying terms
 webertj parents: 
19553diff
changeset | 111 | (* and then perform resolution with *) | 
| 
aa35f8e27c73
comments fixed, minor optimization wrt. certifying terms
 webertj parents: 
19553diff
changeset | 112 | (* [| ?P ==> False; ~?P ==> False |] ==> False *) | 
| 
aa35f8e27c73
comments fixed, minor optimization wrt. certifying terms
 webertj parents: 
19553diff
changeset | 113 | (* to produce *) | 
| 20440 
e6fe74eebda3
faster clause representation (again): full CNF formula as a hypothesis, instead of separate clauses
 webertj parents: 
20371diff
changeset | 114 | (* [P, Q, x1, ..., xn, y1, ..., ym] |- False *) | 
| 21768 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 115 | (* Each clause is accompanied with an association list mapping integers *) | 
| 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 116 | (* (positive for positive literals, negative for negative literals, and *) | 
| 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 117 | (* the same absolute value for dual literals) to the actual literals as *) | 
| 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 118 | (* cterms. *) | 
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 119 | (* ------------------------------------------------------------------------- *) | 
| 17618 | 120 | |
| 55236 | 121 | fun resolve_raw_clauses _ [] = | 
| 32091 
30e2ffbba718
proper context for Display.pretty_thm etc. or old-style versions Display.pretty_thm_global, Display.pretty_thm_without_context etc.;
 wenzelm parents: 
32010diff
changeset | 122 |       raise THM ("Proof reconstruction failed (empty list of resolvents)!", 0, [])
 | 
| 55236 | 123 | | resolve_raw_clauses ctxt (c::cs) = | 
| 41447 | 124 | let | 
| 125 | (* merges two sorted lists wrt. 'lit_ord', suppressing duplicates *) | |
| 126 | fun merge xs [] = xs | |
| 127 | | merge [] ys = ys | |
| 128 | | merge (x :: xs) (y :: ys) = | |
| 59058 
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
 wenzelm parents: 
58839diff
changeset | 129 | (case lit_ord (apply2 fst (x, y)) of | 
| 41447 | 130 | LESS => x :: merge xs (y :: ys) | 
| 131 | | EQUAL => x :: merge xs ys | |
| 132 | | GREATER => y :: merge (x :: xs) ys) | |
| 21768 
69165d27b55b
ordered lists instead of tables for resolving hyps; speedup
 webertj parents: 
21756diff
changeset | 133 | |
| 41447 | 134 | (* find out which two hyps are used in the resolution *) | 
| 135 | fun find_res_hyps ([], _) _ = | |
| 136 |               raise THM ("Proof reconstruction failed (no literal for resolution)!", 0, [])
 | |
| 137 | | find_res_hyps (_, []) _ = | |
| 138 |               raise THM ("Proof reconstruction failed (no literal for resolution)!", 0, [])
 | |
| 139 | | find_res_hyps (h1 :: hyps1, h2 :: hyps2) acc = | |
| 59058 
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
 wenzelm parents: 
58839diff
changeset | 140 | (case lit_ord (apply2 fst (h1, h2)) of | 
| 41447 | 141 | LESS => find_res_hyps (hyps1, h2 :: hyps2) (h1 :: acc) | 
| 142 | | EQUAL => | |
| 143 | let | |
| 144 | val (i1, chyp1) = h1 | |
| 145 | val (i2, chyp2) = h2 | |
| 146 | in | |
| 147 | if i1 = ~ i2 then | |
| 148 | (i1 < 0, chyp1, chyp2, rev acc @ merge hyps1 hyps2) | |
| 149 | else (* i1 = i2 *) | |
| 150 | find_res_hyps (hyps1, hyps2) (h1 :: acc) | |
| 151 | end | |
| 152 | | GREATER => find_res_hyps (h1 :: hyps1, hyps2) (h2 :: acc)) | |
| 19976 
aa35f8e27c73
comments fixed, minor optimization wrt. certifying terms
 webertj parents: 
19553diff
changeset | 153 | |
| 41447 | 154 | fun resolution (c1, hyps1) (c2, hyps2) = | 
| 155 | let | |
| 156 | val _ = | |
| 55240 | 157 | cond_tracing ctxt (fn () => | 
| 61268 | 158 | "Resolving clause: " ^ Thm.string_of_thm ctxt c1 ^ | 
| 55240 | 159 | " (hyps: " ^ ML_Syntax.print_list (Syntax.string_of_term ctxt) (Thm.hyps_of c1) ^ | 
| 61268 | 160 | ")\nwith clause: " ^ Thm.string_of_thm ctxt c2 ^ | 
| 55240 | 161 | " (hyps: " ^ ML_Syntax.print_list (Syntax.string_of_term ctxt) (Thm.hyps_of c2) ^ ")") | 
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 162 | |
| 41447 | 163 | (* the two literals used for resolution *) | 
| 164 | val (hyp1_is_neg, hyp1, hyp2, new_hyps) = find_res_hyps (hyps1, hyps2) [] | |
| 19236 
150e8b0fb991
clauses now use (meta-)hyps instead of (meta-)implications; significant speedup
 webertj parents: 
17843diff
changeset | 165 | |
| 41447 | 166 | val c1' = Thm.implies_intr hyp1 c1 (* Gamma1 |- hyp1 ==> False *) | 
| 167 | val c2' = Thm.implies_intr hyp2 c2 (* Gamma2 |- hyp2 ==> False *) | |
| 17618 | 168 | |
| 41447 | 169 | val res_thm = (* |- (lit ==> False) ==> (~lit ==> False) ==> False *) | 
| 170 | let | |
| 171 | val cLit = | |
| 172 | snd (Thm.dest_comb (if hyp1_is_neg then hyp2 else hyp1)) (* strip Trueprop *) | |
| 173 | in | |
| 60642 
48dd1cefb4ae
simplified Thm.instantiate and derivatives: the LHS refers to non-certified variables -- this merely serves as index into already certified structures (or is ignored);
 wenzelm parents: 
59642diff
changeset | 174 |                 Thm.instantiate ([], [((("P", 0), HOLogic.boolT), cLit)]) resolution_thm
 | 
| 41447 | 175 | end | 
| 19236 
150e8b0fb991
clauses now use (meta-)hyps instead of (meta-)implications; significant speedup
 webertj parents: 
17843diff
changeset | 176 | |
| 41447 | 177 | val _ = | 
| 55240 | 178 | cond_tracing ctxt | 
| 61268 | 179 | (fn () => "Resolution theorem: " ^ Thm.string_of_thm ctxt res_thm) | 
| 19236 
150e8b0fb991
clauses now use (meta-)hyps instead of (meta-)implications; significant speedup
 webertj parents: 
17843diff
changeset | 180 | |
| 41447 | 181 | (* Gamma1, Gamma2 |- False *) | 
| 182 | val c_new = | |
| 183 | Thm.implies_elim | |
| 184 | (Thm.implies_elim res_thm (if hyp1_is_neg then c2' else c1')) | |
| 185 | (if hyp1_is_neg then c1' else c2') | |
| 20278 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 186 | |
| 41447 | 187 | val _ = | 
| 55240 | 188 | cond_tracing ctxt (fn () => | 
| 61268 | 189 | "Resulting clause: " ^ Thm.string_of_thm ctxt c_new ^ | 
| 55240 | 190 | " (hyps: " ^ | 
| 191 | ML_Syntax.print_list (Syntax.string_of_term ctxt) (Thm.hyps_of c_new) ^ ")") | |
| 192 | ||
| 41447 | 193 | val _ = Unsynchronized.inc counter | 
| 194 | in | |
| 195 | (c_new, new_hyps) | |
| 196 | end | |
| 197 | in | |
| 198 | fold resolution cs c | |
| 199 | end; | |
| 17618 | 200 | |
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 201 | (* ------------------------------------------------------------------------- *) | 
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 202 | (* replay_proof: replays the resolution proof returned by the SAT solver; *) | 
| 56853 | 203 | (* cf. SAT_Solver.proof for details of the proof format. Updates the *) | 
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 204 | (* 'clauses' array with derived clauses, and returns the derived clause *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 205 | (* at index 'empty_id' (which should just be "False" if proof *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 206 | (* reconstruction was successful, with the used clauses as hyps). *) | 
| 20278 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 207 | (* 'atom_table' must contain an injective mapping from all atoms that *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 208 | (* occur (as part of a literal) in 'clauses' to positive integers. *) | 
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 209 | (* ------------------------------------------------------------------------- *) | 
| 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 210 | |
| 55236 | 211 | fun replay_proof ctxt atom_table clauses (clause_table, empty_id) = | 
| 41447 | 212 | let | 
| 213 | fun index_of_literal chyp = | |
| 214 | (case (HOLogic.dest_Trueprop o Thm.term_of) chyp of | |
| 67149 | 215 | (Const (\<^const_name>\<open>Not\<close>, _) $ atom) => | 
| 41447 | 216 | SOME (~ (the (Termtab.lookup atom_table atom))) | 
| 217 | | atom => SOME (the (Termtab.lookup atom_table atom))) | |
| 218 | handle TERM _ => NONE; (* 'chyp' is not a literal *) | |
| 20278 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 219 | |
| 41447 | 220 | fun prove_clause id = | 
| 221 | (case Array.sub (clauses, id) of | |
| 222 | RAW_CLAUSE clause => clause | |
| 223 | | ORIG_CLAUSE thm => | |
| 224 | (* convert the original clause *) | |
| 225 | let | |
| 55240 | 226 | val _ = cond_tracing ctxt (fn () => "Using original clause #" ^ string_of_int id) | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59352diff
changeset | 227 | val raw = CNF.clause2raw_thm ctxt thm | 
| 59058 
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
 wenzelm parents: 
58839diff
changeset | 228 | val hyps = sort (lit_ord o apply2 fst) (map_filter (fn chyp => | 
| 60949 | 229 | Option.map (rpair chyp) (index_of_literal chyp)) (Thm.chyps_of raw)) | 
| 41447 | 230 | val clause = (raw, hyps) | 
| 231 | val _ = Array.update (clauses, id, RAW_CLAUSE clause) | |
| 232 | in | |
| 233 | clause | |
| 234 | end | |
| 235 | | NO_CLAUSE => | |
| 236 | (* prove the clause, using information from 'clause_table' *) | |
| 237 | let | |
| 55240 | 238 | val _ = cond_tracing ctxt (fn () => "Proving clause #" ^ string_of_int id ^ " ...") | 
| 41447 | 239 | val ids = the (Inttab.lookup clause_table id) | 
| 55236 | 240 | val clause = resolve_raw_clauses ctxt (map prove_clause ids) | 
| 41447 | 241 | val _ = Array.update (clauses, id, RAW_CLAUSE clause) | 
| 242 | val _ = | |
| 55240 | 243 | cond_tracing ctxt | 
| 244 | (fn () => "Replay chain successful; clause stored at #" ^ string_of_int id) | |
| 41447 | 245 | in | 
| 246 | clause | |
| 247 | end) | |
| 17618 | 248 | |
| 41447 | 249 | val _ = counter := 0 | 
| 250 | val empty_clause = fst (prove_clause empty_id) | |
| 251 | val _ = | |
| 55240 | 252 | cond_tracing ctxt (fn () => | 
| 253 | "Proof reconstruction successful; " ^ | |
| 254 | string_of_int (!counter) ^ " resolution step(s) total.") | |
| 41447 | 255 | in | 
| 256 | empty_clause | |
| 257 | end; | |
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 258 | |
| 20278 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 259 | (* ------------------------------------------------------------------------- *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 260 | (* string_of_prop_formula: return a human-readable string representation of *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 261 | (* a 'prop_formula' (just for tracing) *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 262 | (* ------------------------------------------------------------------------- *) | 
| 
28be10991666
proof reconstruction now uses its own data structure to manage hyps; should be both faster and more robust
 webertj parents: 
20170diff
changeset | 263 | |
| 41471 | 264 | fun string_of_prop_formula Prop_Logic.True = "True" | 
| 265 | | string_of_prop_formula Prop_Logic.False = "False" | |
| 266 | | string_of_prop_formula (Prop_Logic.BoolVar i) = "x" ^ string_of_int i | |
| 267 | | string_of_prop_formula (Prop_Logic.Not fm) = "~" ^ string_of_prop_formula fm | |
| 268 | | string_of_prop_formula (Prop_Logic.Or (fm1, fm2)) = | |
| 41447 | 269 |       "(" ^ string_of_prop_formula fm1 ^ " v " ^ string_of_prop_formula fm2 ^ ")"
 | 
| 41471 | 270 | | string_of_prop_formula (Prop_Logic.And (fm1, fm2)) = | 
| 41447 | 271 |       "(" ^ string_of_prop_formula fm1 ^ " & " ^ string_of_prop_formula fm2 ^ ")";
 | 
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 272 | |
| 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 273 | (* ------------------------------------------------------------------------- *) | 
| 21267 | 274 | (* rawsat_thm: run external SAT solver with the given clauses. Reconstructs *) | 
| 275 | (* a proof from the resulting proof trace of the SAT solver. The *) | |
| 276 | (* theorem returned is just "False" (with some of the given clauses as *) | |
| 277 | (* hyps). *) | |
| 278 | (* ------------------------------------------------------------------------- *) | |
| 279 | ||
| 32432 
64f30bdd3ba1
modernized messages -- eliminated ctyp/cterm operations;
 wenzelm parents: 
32283diff
changeset | 280 | fun rawsat_thm ctxt clauses = | 
| 41447 | 281 | let | 
| 282 | (* remove premises that equal "True" *) | |
| 283 | val clauses' = filter (fn clause => | |
| 67149 | 284 | (not_equal \<^term>\<open>True\<close> o HOLogic.dest_Trueprop o Thm.term_of) clause | 
| 41447 | 285 |         handle TERM ("dest_Trueprop", _) => true) clauses
 | 
| 286 | (* remove non-clausal premises -- of course this shouldn't actually *) | |
| 287 | (* remove anything as long as 'rawsat_tac' is only called after the *) | |
| 288 | (* premises have been converted to clauses *) | |
| 289 | val clauses'' = filter (fn clause => | |
| 55239 | 290 | ((CNF.is_clause o HOLogic.dest_Trueprop o Thm.term_of) clause | 
| 41447 | 291 |         handle TERM ("dest_Trueprop", _) => false)
 | 
| 59352 
63c02d051661
tuned warnings: observe Context_Position.is_visible;
 wenzelm parents: 
59058diff
changeset | 292 | orelse | 
| 
63c02d051661
tuned warnings: observe Context_Position.is_visible;
 wenzelm parents: 
59058diff
changeset | 293 | (if Context_Position.is_visible ctxt then | 
| 
63c02d051661
tuned warnings: observe Context_Position.is_visible;
 wenzelm parents: 
59058diff
changeset | 294 |           warning ("Ignoring non-clausal premise " ^ Syntax.string_of_term ctxt (Thm.term_of clause))
 | 
| 
63c02d051661
tuned warnings: observe Context_Position.is_visible;
 wenzelm parents: 
59058diff
changeset | 295 | else (); false)) clauses' | 
| 41447 | 296 | (* remove trivial clauses -- this is necessary because zChaff removes *) | 
| 297 | (* trivial clauses during preprocessing, and otherwise our clause *) | |
| 298 | (* numbering would be off *) | |
| 299 | val nontrivial_clauses = | |
| 55239 | 300 | filter (not o CNF.clause_is_trivial o HOLogic.dest_Trueprop o Thm.term_of) clauses'' | 
| 41447 | 301 | (* sort clauses according to the term order -- an optimization, *) | 
| 302 | (* useful because forming the union of hypotheses, as done by *) | |
| 303 | (* Conjunction.intr_balanced and fold Thm.weaken below, is quadratic for *) | |
| 304 | (* terms sorted in descending order, while only linear for terms *) | |
| 305 | (* sorted in ascending order *) | |
| 67559 | 306 | val sorted_clauses = sort Thm.fast_term_ord nontrivial_clauses | 
| 41447 | 307 | val _ = | 
| 55240 | 308 | cond_tracing ctxt (fn () => | 
| 309 | "Sorted non-trivial clauses:\n" ^ | |
| 310 | cat_lines (map (Syntax.string_of_term ctxt o Thm.term_of) sorted_clauses)) | |
| 41471 | 311 | (* translate clauses from HOL terms to Prop_Logic.prop_formula *) | 
| 41447 | 312 | val (fms, atom_table) = | 
| 41471 | 313 | fold_map (Prop_Logic.prop_formula_of_term o HOLogic.dest_Trueprop o Thm.term_of) | 
| 41447 | 314 | sorted_clauses Termtab.empty | 
| 315 | val _ = | |
| 55240 | 316 | cond_tracing ctxt | 
| 317 | (fn () => "Invoking SAT solver on clauses:\n" ^ cat_lines (map string_of_prop_formula fms)) | |
| 41471 | 318 | val fm = Prop_Logic.all fms | 
| 41447 | 319 | fun make_quick_and_dirty_thm () = | 
| 320 | let | |
| 321 | val _ = | |
| 55240 | 322 | cond_tracing ctxt | 
| 323 | (fn () => "quick_and_dirty is set: proof reconstruction skipped, using oracle instead") | |
| 67149 | 324 | val False_thm = Skip_Proof.make_thm_cterm \<^cprop>\<open>False\<close> | 
| 41447 | 325 | in | 
| 326 | (* 'fold Thm.weaken (rev sorted_clauses)' is linear, while 'fold *) | |
| 327 | (* Thm.weaken sorted_clauses' would be quadratic, since we sorted *) | |
| 328 | (* clauses in ascending order (which is linear for *) | |
| 329 | (* 'Conjunction.intr_balanced', used below) *) | |
| 330 | fold Thm.weaken (rev sorted_clauses) False_thm | |
| 331 | end | |
| 332 | in | |
| 333 | case | |
| 56817 | 334 | let | 
| 335 | val the_solver = Config.get ctxt solver | |
| 336 | val _ = cond_tracing ctxt (fn () => "Invoking solver " ^ the_solver) | |
| 56853 | 337 | in SAT_Solver.invoke_solver the_solver fm end | 
| 41447 | 338 | of | 
| 56853 | 339 | SAT_Solver.UNSATISFIABLE (SOME (clause_table, empty_id)) => | 
| 55240 | 340 | (cond_tracing ctxt (fn () => | 
| 341 | "Proof trace from SAT solver:\n" ^ | |
| 342 | "clauses: " ^ ML_Syntax.print_list | |
| 343 | (ML_Syntax.print_pair ML_Syntax.print_int (ML_Syntax.print_list ML_Syntax.print_int)) | |
| 344 | (Inttab.dest clause_table) ^ "\n" ^ | |
| 345 | "empty clause: " ^ string_of_int empty_id); | |
| 52059 | 346 | if Config.get ctxt quick_and_dirty then | 
| 41447 | 347 | make_quick_and_dirty_thm () | 
| 348 | else | |
| 349 | let | |
| 350 | (* optimization: convert the given clauses to "[c_1 && ... && c_n] |- c_i"; *) | |
| 351 | (* this avoids accumulation of hypotheses during resolution *) | |
| 352 | (* [c_1, ..., c_n] |- c_1 && ... && c_n *) | |
| 353 | val clauses_thm = Conjunction.intr_balanced (map Thm.assume sorted_clauses) | |
| 354 | (* [c_1 && ... && c_n] |- c_1 && ... && c_n *) | |
| 59582 | 355 | val cnf_cterm = Thm.cprop_of clauses_thm | 
| 41447 | 356 | val cnf_thm = Thm.assume cnf_cterm | 
| 357 | (* [[c_1 && ... && c_n] |- c_1, ..., [c_1 && ... && c_n] |- c_n] *) | |
| 358 | val cnf_clauses = Conjunction.elim_balanced (length sorted_clauses) cnf_thm | |
| 359 | (* initialize the clause array with the given clauses *) | |
| 52049 | 360 | val max_idx = fst (the (Inttab.max clause_table)) | 
| 41447 | 361 | val clause_arr = Array.array (max_idx + 1, NO_CLAUSE) | 
| 362 | val _ = | |
| 363 | fold (fn thm => fn idx => (Array.update (clause_arr, idx, ORIG_CLAUSE thm); idx+1)) | |
| 364 | cnf_clauses 0 | |
| 365 | (* replay the proof to derive the empty clause *) | |
| 366 | (* [c_1 && ... && c_n] |- False *) | |
| 55236 | 367 | val raw_thm = replay_proof ctxt atom_table clause_arr (clause_table, empty_id) | 
| 41447 | 368 | in | 
| 369 | (* [c_1, ..., c_n] |- False *) | |
| 370 | Thm.implies_elim (Thm.implies_intr cnf_cterm raw_thm) clauses_thm | |
| 371 | end) | |
| 56853 | 372 | | SAT_Solver.UNSATISFIABLE NONE => | 
| 52059 | 373 | if Config.get ctxt quick_and_dirty then | 
| 59352 
63c02d051661
tuned warnings: observe Context_Position.is_visible;
 wenzelm parents: 
59058diff
changeset | 374 | (if Context_Position.is_visible ctxt then | 
| 
63c02d051661
tuned warnings: observe Context_Position.is_visible;
 wenzelm parents: 
59058diff
changeset | 375 | warning "SAT solver claims the formula to be unsatisfiable, but did not provide a proof" | 
| 
63c02d051661
tuned warnings: observe Context_Position.is_visible;
 wenzelm parents: 
59058diff
changeset | 376 | else (); | 
| 41447 | 377 | make_quick_and_dirty_thm ()) | 
| 378 | else | |
| 379 |           raise THM ("SAT solver claims the formula to be unsatisfiable, but did not provide a proof", 0, [])
 | |
| 56853 | 380 | | SAT_Solver.SATISFIABLE assignment => | 
| 41447 | 381 | let | 
| 382 | val msg = | |
| 383 | "SAT solver found a countermodel:\n" ^ | |
| 384 | (commas o map (fn (term, idx) => | |
| 385 |                 Syntax.string_of_term_global @{theory} term ^ ": " ^
 | |
| 386 | (case assignment idx of NONE => "arbitrary" | |
| 387 | | SOME true => "true" | SOME false => "false"))) | |
| 388 | (Termtab.dest atom_table) | |
| 389 | in | |
| 390 | raise THM (msg, 0, []) | |
| 391 | end | |
| 56853 | 392 | | SAT_Solver.UNKNOWN => | 
| 41447 | 393 |         raise THM ("SAT solver failed to decide the formula", 0, [])
 | 
| 394 | end; | |
| 17618 | 395 | |
| 17622 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 396 | (* ------------------------------------------------------------------------- *) | 
| 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 397 | (* Tactics *) | 
| 
5d03a69481b6
code reformatted and restructured, many minor modifications
 webertj parents: 
17618diff
changeset | 398 | (* ------------------------------------------------------------------------- *) | 
| 17618 | 399 | |
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 400 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 401 | (* rawsat_tac: solves the i-th subgoal of the proof state; this subgoal *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 402 | (* should be of the form *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 403 | (* [| c1; c2; ...; ck |] ==> False *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 404 | (* where each cj is a non-empty clause (i.e. a disjunction of literals) *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 405 | (* or "True" *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 406 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 407 | |
| 32232 | 408 | fun rawsat_tac ctxt i = | 
| 32432 
64f30bdd3ba1
modernized messages -- eliminated ctyp/cterm operations;
 wenzelm parents: 
32283diff
changeset | 409 |   Subgoal.FOCUS (fn {context = ctxt', prems, ...} =>
 | 
| 59582 | 410 | resolve_tac ctxt' [rawsat_thm ctxt' (map Thm.cprop_of prems)] 1) ctxt i; | 
| 17618 | 411 | |
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 412 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 413 | (* pre_cnf_tac: converts the i-th subgoal *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 414 | (* [| A1 ; ... ; An |] ==> B *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 415 | (* to *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 416 | (* [| A1; ... ; An ; ~B |] ==> False *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 417 | (* (handling meta-logical connectives in B properly before negating), *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 418 | (* then replaces meta-logical connectives in the premises (i.e. "==>", *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 419 | (* "!!" and "==") by connectives of the HOL object-logic (i.e. by *) | 
| 19553 
9d15911f1893
pre_cnf_tac: beta-eta-normalization restricted to the current subgoal
 webertj parents: 
19534diff
changeset | 420 | (* "-->", "!", and "="), then performs beta-eta-normalization on the *) | 
| 
9d15911f1893
pre_cnf_tac: beta-eta-normalization restricted to the current subgoal
 webertj parents: 
19534diff
changeset | 421 | (* subgoal *) | 
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 422 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 423 | |
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52059diff
changeset | 424 | fun pre_cnf_tac ctxt = | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59352diff
changeset | 425 |   resolve_tac ctxt @{thms ccontr} THEN'
 | 
| 54742 
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
 wenzelm parents: 
52059diff
changeset | 426 | Object_Logic.atomize_prems_tac ctxt THEN' | 
| 41447 | 427 | CONVERSION Drule.beta_eta_conversion; | 
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 428 | |
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 429 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 430 | (* cnfsat_tac: checks if the empty clause "False" occurs among the premises; *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 431 | (* if not, eliminates conjunctions (i.e. each clause of the CNF formula *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 432 | (* becomes a separate premise), then applies 'rawsat_tac' to solve the *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 433 | (* subgoal *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 434 | (* ------------------------------------------------------------------------- *) | 
| 17697 | 435 | |
| 32232 | 436 | fun cnfsat_tac ctxt i = | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59352diff
changeset | 437 | (eresolve_tac ctxt [FalseE] i) ORELSE | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59352diff
changeset | 438 | (REPEAT_DETERM (eresolve_tac ctxt [conjE] i) THEN rawsat_tac ctxt i); | 
| 17618 | 439 | |
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 440 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 441 | (* cnfxsat_tac: checks if the empty clause "False" occurs among the *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 442 | (* premises; if not, eliminates conjunctions (i.e. each clause of the *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 443 | (* CNF formula becomes a separate premise) and existential quantifiers, *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 444 | (* then applies 'rawsat_tac' to solve the subgoal *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 445 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 446 | |
| 32232 | 447 | fun cnfxsat_tac ctxt i = | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59352diff
changeset | 448 | (eresolve_tac ctxt [FalseE] i) ORELSE | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59352diff
changeset | 449 | (REPEAT_DETERM (eresolve_tac ctxt [conjE] i ORELSE eresolve_tac ctxt [exE] i) THEN | 
| 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59352diff
changeset | 450 | rawsat_tac ctxt i); | 
| 17618 | 451 | |
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 452 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 453 | (* sat_tac: tactic for calling an external SAT solver, taking as input an *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 454 | (* arbitrary formula. The input is translated to CNF, possibly causing *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 455 | (* an exponential blowup. *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 456 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 457 | |
| 32232 | 458 | fun sat_tac ctxt i = | 
| 55239 | 459 | pre_cnf_tac ctxt i THEN CNF.cnf_rewrite_tac ctxt i THEN cnfsat_tac ctxt i; | 
| 17809 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 460 | |
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 461 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 462 | (* satx_tac: tactic for calling an external SAT solver, taking as input an *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 463 | (* arbitrary formula. The input is translated to CNF, possibly *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 464 | (* introducing new literals. *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 465 | (* ------------------------------------------------------------------------- *) | 
| 
195045659c06
Tactics sat and satx reimplemented, several improvements
 webertj parents: 
17697diff
changeset | 466 | |
| 32232 | 467 | fun satx_tac ctxt i = | 
| 55239 | 468 | pre_cnf_tac ctxt i THEN CNF.cnfx_rewrite_tac ctxt i THEN cnfxsat_tac ctxt i; | 
| 17618 | 469 | |
| 23533 | 470 | end; |