Add forgetful propagation

This may be not really needed if late propagations can be done, as the
current code could allow. To think about...
This commit is contained in:
Guillaume Bury 2016-08-04 22:18:39 +02:00
parent 7d57b3f1b5
commit 035002fd95
4 changed files with 38 additions and 9 deletions

View file

@ -905,10 +905,20 @@ module Make
be done *) be done *)
Stack.push c env.clauses_to_add Stack.push c env.clauses_to_add
let slice_propagate f lvl = let slice_propagate f = function
| Plugin_intf.Eval lvl ->
let a = atom f in let a = atom f in
Iheap.grow_to_by_double env.order (St.nb_elt ()); Iheap.grow_to_by_double env.order (St.nb_elt ());
enqueue_bool a lvl (Semantic lvl) enqueue_bool a lvl (Semantic lvl)
| Plugin_intf.Consequence (causes, proof) ->
let l = List.rev_map atom causes in
if List.for_all (fun a -> a.is_true) l then
let p = atom f in
let c = make_clause (fresh_tname ())
(p :: List.map (fun a -> a.neg) l) (Lemma proof) in
enqueue_bool p (decision_level ()) (Bcp c)
else
raise (Invalid_argument "Msat.Internal.slice_propagate")
let current_slice (): (_,_,_) Plugin_intf.slice = { let current_slice (): (_,_,_) Plugin_intf.slice = {
Plugin_intf.start = env.th_head; Plugin_intf.start = env.th_head;

View file

@ -34,12 +34,20 @@ type ('term, 'formula) assumption =
(** Asusmptions made by the core SAT solver. Can be either a formula, or an assignment. (** Asusmptions made by the core SAT solver. Can be either a formula, or an assignment.
Assignemnt are given a level. *) Assignemnt are given a level. *)
type ('formula, 'proof) reason =
| Eval of int
| Consequence of 'formula list * 'proof
(** The type of reasons for propagations of a formula [f].
[Semantic lvl] means that [f] is true because of the assignments whose level is [<= lvl].
[Consequence (l, p)] means that the formulas in [l] imply [f]. The proof should be a proof
of the clause [l] implies [f]. *)
type ('term, 'formula, 'proof) slice = { type ('term, 'formula, 'proof) slice = {
start : int; start : int;
length : int; length : int;
get : int -> ('term, 'formula) assumption; get : int -> ('term, 'formula) assumption;
push : 'formula list -> 'proof -> unit; push : 'formula list -> 'proof -> unit;
propagate : 'formula -> int -> unit; propagate : 'formula -> ('formula, 'proof) reason -> unit;
} }
(** The type for a slice of litterals to assume/propagate in the theory. (** The type for a slice of litterals to assume/propagate in the theory.
[get] operations should only be used for integers [ start <= i < start + length]. [get] operations should only be used for integers [ start <= i < start + length].

View file

@ -25,10 +25,15 @@ type ('form, 'proof) slice = {
length : int; length : int;
get : int -> 'form; get : int -> 'form;
push : 'form list -> 'proof -> unit; push : 'form list -> 'proof -> unit;
propagate : 'form -> 'form list -> 'proof -> unit;
} }
(** The type for a slice of literals to assume/propagate in the theory. (** The type for a slice of literals to assume/propagate in the theory.
[get] operations should only be used for integers [ start <= i < start + length]. [get] operations should only be used for integers [ start <= i < start + length].
[push clause proof] allows to add a tautological clause to the sat solver. *) [push clause proof] allows to add a tautological clause to the sat solver.
[propagate lit causes proof] informs the solver to propagate [lit], with the reason
that the clause [causes => lit] is a theory tautology. It is faster than pushing
the associated clause but the clause will not be remembered by the sat solver,
i.e it will not be used by the solver to do boolean propagation. *)
module type S = sig module type S = sig
(** Signature for theories to be given to the Solver. *) (** Signature for theories to be given to the Solver. *)

View file

@ -39,16 +39,22 @@ module Plugin(E : Formula_intf.S)
let current_level = Th.current_level let current_level = Th.current_level
let assume_get s i = let assume_get get =
match s.Plugin_intf.get i with function i ->
match get i with
| Plugin_intf.Lit f -> f | Plugin_intf.Lit f -> f
| _ -> assert false | _ -> assert false
let assume_propagate propagate =
fun f l proof ->
propagate f (Plugin_intf.Consequence (l, proof))
let mk_slice s = { let mk_slice s = {
Theory_intf.start = s.Plugin_intf.start; Theory_intf.start = s.Plugin_intf.start;
length = s.Plugin_intf.length; length = s.Plugin_intf.length;
get = assume_get s; get = assume_get s.Plugin_intf.get;
push = s.Plugin_intf.push; push = s.Plugin_intf.push;
propagate = assume_propagate s.Plugin_intf.propagate;
} }
let assume s = Th.assume (mk_slice s) let assume s = Th.assume (mk_slice s)