[bugfix] Do not forget conflict at level 0

In add_clause, a conflcit at level 0 raised Unsat, but was forgotten,
which is obviously incorrect as succesive solving of the same problem
would yield different results.
This commit is contained in:
Guillaume Bury 2016-11-22 16:53:47 +01:00
parent e3d8513286
commit 9a6d07e097

View file

@ -710,34 +710,38 @@ module Make
in in
Log.debugf 4 "New clause: @[<hov>%a@]" (fun k->k St.pp_clause clause); Log.debugf 4 "New clause: @[<hov>%a@]" (fun k->k St.pp_clause clause);
Array.iter (fun x -> insert_var_order (elt_of_var x.var)) clause.atoms; Array.iter (fun x -> insert_var_order (elt_of_var x.var)) clause.atoms;
Vec.push vec clause;
match atoms with match atoms with
| [] -> | [] ->
(* Report_unsat will raise, and the current clause will be lost if we do not
store it somewhere. Since the proof search will end, any of env.clauses_to_add
or env.clauses_root is adequate. *)
Stack.push clause env.clauses_root;
report_unsat clause report_unsat clause
| [a] -> | [a] ->
Log.debugf 5 "New unit clause, propagating : %a" (fun k->k St.pp_atom a);
cancel_until (base_level ()); cancel_until (base_level ());
if a.neg.is_true then begin if a.neg.is_true then begin
(* Since we cannot propagate the atom [a], in order to not lose (* Since we cannot propagate the atom [a], in order to not lose
the information that [a] must be true, we add clause to the list the information that [a] must be true, we add clause to the list
of clauses to add, so that it will be e-examined later. of clauses to add, so that it will be e-examined later. *)
Also, in order to avoid it being twice in a clause vector, we pop Log.debugf 5 "Unit clause, adding to clauses to add" (fun k -> k);
the vector where it was added. *)
Stack.push clause env.clauses_to_add; Stack.push clause env.clauses_to_add;
Vec.pop vec;
report_unsat clause report_unsat clause
end else if a.is_true then begin end else if a.is_true then begin
(* If the atom is already true, then it should be because of a local hyp. (* If the atom is already true, then it should be because of a local hyp.
However it means we can't propagate it at level 0. In order to not lose However it means we can't propagate it at level 0. In order to not lose
that information, we store the clause in a stack of clauses that we will that information, we store the clause in a stack of clauses that we will
add to the solver at the next pop. *) add to the solver at the next pop. *)
Log.debugf 5 "Unit clause, adding to root clauses" (fun k -> k);
assert (0 < a.var.v_level && a.var.v_level <= base_level ()); assert (0 < a.var.v_level && a.var.v_level <= base_level ());
Stack.push clause env.clauses_root; Stack.push clause env.clauses_root;
Vec.pop vec;
() ()
end else end else begin
Log.debugf 5 "Unit clause, propagating: %a" (fun k->k St.pp_atom a);
Vec.push vec clause;
enqueue_bool a ~level:0 (Bcp clause) enqueue_bool a ~level:0 (Bcp clause)
end
| a::b::_ -> | a::b::_ ->
Vec.push vec clause;
if a.neg.is_true then begin if a.neg.is_true then begin
(* Atoms need to be sorted in decreasing order of decision level, (* Atoms need to be sorted in decreasing order of decision level,
or we might watch the wrong literals. *) or we might watch the wrong literals. *)