perf: exit early from propagation loop in case of conflict

This commit is contained in:
Simon Cruanes 2019-01-18 23:27:54 -06:00 committed by Guillaume Bury
parent 1655d09035
commit df9538a91e

View file

@ -1550,7 +1550,7 @@ module Make(Plugin : PLUGIN)
if first.neg.is_true then ( if first.neg.is_true then (
(* clause is false *) (* clause is false *)
st.elt_head <- Vec.size st.trail; st.elt_head <- Vec.size st.trail;
raise (Conflict c) raise_notrace (Conflict c)
) else ( ) else (
match th_eval st first with match th_eval st first with
| None -> (* clause is unit, keep the same watches, but propagate *) | None -> (* clause is unit, keep the same watches, but propagate *)
@ -1558,7 +1558,7 @@ module Make(Plugin : PLUGIN)
| Some true -> () | Some true -> ()
| Some false -> | Some false ->
st.elt_head <- Vec.size st.trail; st.elt_head <- Vec.size st.trail;
raise (Conflict c) raise_notrace (Conflict c)
); );
Watch_kept Watch_kept
with Exit -> with Exit ->
@ -1569,28 +1569,21 @@ module Make(Plugin : PLUGIN)
clause watching [a] to see if the clause is false, unit, or has clause watching [a] to see if the clause is false, unit, or has
other possible watches other possible watches
@param res the optional conflict clause that the propagation might trigger *) @param res the optional conflict clause that the propagation might trigger *)
let propagate_atom st a (res:clause option ref) : unit = let propagate_atom st a : unit =
let watched = a.watched in let watched = a.watched in
begin let rec aux i =
try if i >= Vec.size watched then ()
let rec aux i = else (
if i >= Vec.size watched then () let c = Vec.get watched i in
else ( assert c.attached;
let c = Vec.get watched i in let j = match propagate_in_clause st a c i with
assert c.attached; | Watch_kept -> i+1
let j = match propagate_in_clause st a c i with | Watch_removed -> i (* clause at this index changed *)
| Watch_kept -> i+1
| Watch_removed -> i (* clause at this index changed *)
in
aux j
)
in in
aux 0 aux j
with Conflict c -> )
assert (!res = None); in
res := Some c aux 0
end;
()
(* Propagation (boolean and theory) *) (* Propagation (boolean and theory) *)
let create_atom st f = let create_atom st f =
@ -1684,23 +1677,23 @@ module Make(Plugin : PLUGIN)
flush_clauses st; flush_clauses st;
(* Now, check that the situation is sane *) (* Now, check that the situation is sane *)
assert (st.elt_head <= Vec.size st.trail); assert (st.elt_head <= Vec.size st.trail);
if st.elt_head = Vec.size st.trail then if st.elt_head = Vec.size st.trail then (
theory_propagate st theory_propagate st
else ( ) else (
let num_props = ref 0 in let num_props = ref 0 in
let res = ref None in match
while st.elt_head < Vec.size st.trail do while st.elt_head < Vec.size st.trail do
begin match Vec.get st.trail st.elt_head with begin match Vec.get st.trail st.elt_head with
| Lit _ -> () | Lit _ -> ()
| Atom a -> | Atom a ->
incr num_props; incr num_props;
propagate_atom st a res propagate_atom st a
end; end;
st.elt_head <- st.elt_head + 1; st.elt_head <- st.elt_head + 1;
done; done;
match !res with with
| None -> theory_propagate st | () -> theory_propagate st
| _ -> !res | exception Conflict c -> Some c
) )
(* remove some learnt clauses (* remove some learnt clauses