src/HOL/Tools/sat_funcs.ML
author webertj
Sat, 24 Sep 2005 07:21:46 +0200
changeset 17622 5d03a69481b6
parent 17618 1330157e156a
child 17623 ae4af66b3072
permissions -rw-r--r--
code reformatted and restructured, many minor modifications
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17618
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
     1
(*  Title:      HOL/Tools/sat_funcs.ML
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
     2
    ID:         $Id$
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
     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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
     5
    Copyright   2005
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
     6
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
     7
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
     8
Proof reconstruction from SAT solvers.
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
     9
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    10
  Description:
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    11
    This file defines several tactics to invoke a proof-producing
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    12
    SAT solver on a propositional goal in clausal form.
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    13
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    14
    We use a sequent presentation of clauses to speed up resolution
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    15
    proof reconstruction. 
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    16
    We call such clauses as "raw clauses", which are of the form
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    17
          [| c1; c2; ...; ck |] ==> False
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    18
    where each clause ci is of the form
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    19
          [|l1,  l2,  ..., lm |] ==> False,
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    20
    where li is a literal  (see also comments in cnf_funcs.ML).
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    21
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    22
    -- observe that this is the "dualized" version of the standard
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    23
       clausal form
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    24
           l1' \/ l2' \/ ... \/ lm', where li is the negation normal
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    25
       form of ~li'.
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    26
       The tactic produces a clause representation of the given goal
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    27
       in DIMACS format and invokes a SAT solver, which should return
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    28
       a proof consisting of a sequence of resolution steps, indicating
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    29
       the two input clauses and the variable resolved upon, and resulting
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    30
       in new clauses, leading to the empty clause (i.e., False).
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    31
       The tactic replays this proof in Isabelle and thus solves the
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    32
       overall goal.
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    33
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    34
   There are two SAT tactics available. They differ in the CNF transformation
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    35
   used. The "sat_tac" uses naive CNF transformation to transform the theorem
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    36
   to be proved before giving it to SAT solver. The naive transformation in 
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    37
   some worst case can lead to explonential blow up in formula size.
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    38
   The other tactic, the "satx_tac" uses the "definitional CNF transformation"
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    39
   which produces formula of linear size increase compared to the input formula.
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    40
   This transformation introduces new variables. See also cnf_funcs.ML for
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    41
   more comments.
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    42
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    43
 Notes for the current revision:
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    44
   - The current version supports only zChaff prover.
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    45
   - The environment variable ZCHAFF_HOME must be set to point to
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    46
     the directory where zChaff executable resides
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    47
   - The environment variable ZCHAFF_VERSION must be set according to
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    48
     the version of zChaff used. Current supported version of zChaff:
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    49
     zChaff version 2004.11.15
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    50
*)
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    51
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    52
signature SAT =
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    57
end
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
    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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   226
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   277
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   282
val sat_tac = cnf.cnf_thin_tac THEN cnfsat_tac;
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   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
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   288
*)
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   289
val satx_tac = cnf.cnfx_thin_tac THEN cnfsat_tac;
1330157e156a new sat tactic imports resolution proofs from zChaff
webertj
parents:
diff changeset
   290
17622
5d03a69481b6 code reformatted and restructured, many minor modifications
webertj
parents: 17618
diff changeset
   291
end;  (* of structure *)