[bugfix] Attempt at fixing enqueue bug

When we enqueue an atom at level 0, we expect it to stay unconditionally
true whatever happens. However, if it happens that the atom is alrady
true at a level strictly greater than 0 (but lower than base_level),
then enqueue_bool would simply do nothing. To fix this, there is a new
function enqueue_root which modifies in place the level and reason of
the propagated atom if it is already true.
Additionally, enqueue_bool now requires that the atom be undecided,
since if it not (i.e if it is propagated while already decided) it is
most likely a bug.
This commit is contained in:
Guillaume Bury 2016-11-09 00:24:41 +01:00
parent d681e247ed
commit 443a3b0731

View file

@ -473,8 +473,8 @@ module Make
Log.debugf 0 "Trying to enqueue a false literal: %a" (fun k->k St.pp_atom a);
assert false
end;
if not a.is_true then begin
assert (a.var.v_level < 0 && a.var.reason = None && lvl >= 0);
assert (not a.is_true && a.var.v_level < 0 &&
a.var.reason = None && lvl >= 0);
let reason =
if lvl > 0 then reason
else simpl_reason reason
@ -485,7 +485,18 @@ module Make
Vec.push env.elt_queue (of_atom a);
Log.debugf 20 "Enqueue (%d): %a"
(fun k->k (Vec.size env.elt_queue) pp_atom a)
end
(* Special case for atoms enqueued at level 0
Indeed atoms true at level 0 are supposed to never disappear, because
we cannot watch a clause with only one atom. This causes a problem when
the atom [a] is already propagated at a level 0 < l <= base_level
In that case, we simply change the level and reason of the propagation. *)
let enqueue_root a clause : unit =
if a.is_true then begin
a.var.v_level <- 0;
a.var.reason <- Some (Bcp clause)
end else
enqueue_bool a ~level:0 (Bcp clause)
(* MCsat semantic assignment *)
let enqueue_assign l value lvl =
@ -787,7 +798,7 @@ module Make
Vec.pop vec;
report_unsat clause
end else
enqueue_bool a 0 (Bcp clause)
enqueue_root a clause
| a::b::_ ->
if a.neg.is_true then begin
(* Atoms need to be sorted in decreasing order of decision level,