mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 11:15:43 -05:00
Fix mcsat conflict analysis
When analyzing an mcst conflict clause and looking at a semantic propagation in the trail, the last resolved clause was looked at again, which caused an invalid history to be generated (the computation of the backtrack clause was not affected because the second resolution of the clause was basically a no-op thanks to the 'seen' field), thus it did not introduce any soundness bug, just a faulty clause history which was caught during proof expansion.
This commit is contained in:
parent
8eee822ad6
commit
4989026f06
1 changed files with 43 additions and 32 deletions
|
|
@ -617,47 +617,57 @@ module Make
|
||||||
let cond = ref true in
|
let cond = ref true in
|
||||||
let blevel = ref 0 in
|
let blevel = ref 0 in
|
||||||
let seen = ref [] in
|
let seen = ref [] in
|
||||||
let c = ref c_clause in
|
let c = ref (Some c_clause) in
|
||||||
let tr_ind = ref (Vec.size env.elt_queue - 1) in
|
let tr_ind = ref (Vec.size env.elt_queue - 1) in
|
||||||
let history = ref [] in
|
let history = ref [] in
|
||||||
assert (decision_level () > 0);
|
assert (decision_level () > 0);
|
||||||
let conflict_level =
|
let conflict_level =
|
||||||
Array.fold_left (fun acc p -> max acc p.var.v_level) 0 c_clause.atoms
|
Array.fold_left (fun acc p -> max acc p.var.v_level) 0 c_clause.atoms
|
||||||
in
|
in
|
||||||
|
Log.debugf debug "Analyzing conflict (%d): %a"
|
||||||
|
(fun k -> k conflict_level St.pp_clause c_clause);
|
||||||
while !cond do
|
while !cond do
|
||||||
begin match !c.cpremise with
|
begin match !c with
|
||||||
| History _ -> clause_bump_activity !c
|
| None ->
|
||||||
| Hyp | Local | Lemma _ -> ()
|
Log.debugf debug " skipping resolution for semantic propagation" (fun k->k)
|
||||||
end;
|
| Some clause ->
|
||||||
history := !c :: !history;
|
Log.debugf debug " Resolving clause: %a" (fun k->k St.pp_clause clause);
|
||||||
(* visit the current predecessors *)
|
begin match clause.cpremise with
|
||||||
for j = 0 to Array.length !c.atoms - 1 do
|
| History _ -> clause_bump_activity clause
|
||||||
let q = !c.atoms.(j) in
|
| Hyp | Local | Lemma _ -> ()
|
||||||
assert (q.is_true || q.neg.is_true && q.var.v_level >= 0); (* unsure? *)
|
end;
|
||||||
if q.var.v_level <= 0 then begin
|
history := clause :: !history;
|
||||||
assert (q.neg.is_true);
|
(* visit the current predecessors *)
|
||||||
match q.var.reason with
|
for j = 0 to Array.length clause.atoms - 1 do
|
||||||
| Some Bcp cl -> history := cl :: !history
|
let q = clause.atoms.(j) in
|
||||||
| _ -> assert false
|
assert (q.is_true || q.neg.is_true && q.var.v_level >= 0); (* unsure? *)
|
||||||
end;
|
if q.var.v_level <= 0 then begin
|
||||||
if not (q.var.seen = Both) then begin
|
assert (q.neg.is_true);
|
||||||
q.var.seen <- Both;
|
match q.var.reason with
|
||||||
seen := q :: !seen;
|
| Some Bcp cl -> history := cl :: !history
|
||||||
if q.var.v_level > 0 then begin
|
| _ -> assert false
|
||||||
var_bump_activity q.var;
|
end;
|
||||||
if q.var.v_level >= conflict_level then begin
|
if not (q.var.seen = Both) then begin
|
||||||
incr pathC;
|
q.var.seen <- Both;
|
||||||
end else begin
|
seen := q :: !seen;
|
||||||
learnt := q :: !learnt;
|
if q.var.v_level > 0 then begin
|
||||||
blevel := max !blevel q.var.v_level
|
var_bump_activity q.var;
|
||||||
|
if q.var.v_level >= conflict_level then begin
|
||||||
|
incr pathC;
|
||||||
|
end else begin
|
||||||
|
learnt := q :: !learnt;
|
||||||
|
blevel := max !blevel q.var.v_level
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
done
|
||||||
end
|
end;
|
||||||
done;
|
|
||||||
|
|
||||||
(* look for the next node to expand *)
|
(* look for the next node to expand *)
|
||||||
while
|
while
|
||||||
match Vec.get env.elt_queue !tr_ind with
|
let a = Vec.get env.elt_queue !tr_ind in
|
||||||
|
Log.debugf debug " looking at: %a" (fun k -> k St.pp a);
|
||||||
|
match a with
|
||||||
| Atom q ->
|
| Atom q ->
|
||||||
(not (q.var.seen = Both)) ||
|
(not (q.var.seen = Both)) ||
|
||||||
(q.var.v_level < conflict_level)
|
(q.var.v_level < conflict_level)
|
||||||
|
|
@ -674,11 +684,12 @@ module Make
|
||||||
learnt := p.neg :: (List.rev !learnt)
|
learnt := p.neg :: (List.rev !learnt)
|
||||||
| n, Some Semantic ->
|
| n, Some Semantic ->
|
||||||
assert (n > 0);
|
assert (n > 0);
|
||||||
learnt := p.neg :: !learnt
|
learnt := p.neg :: !learnt;
|
||||||
|
c := None
|
||||||
| n, Some Bcp cl ->
|
| n, Some Bcp cl ->
|
||||||
assert (n > 0);
|
assert (n > 0);
|
||||||
assert (p.var.v_level >= conflict_level);
|
assert (p.var.v_level >= conflict_level);
|
||||||
c := cl
|
c := Some cl
|
||||||
| n, _ -> assert false
|
| n, _ -> assert false
|
||||||
done;
|
done;
|
||||||
List.iter (fun q -> clear q.var) !seen;
|
List.iter (fun q -> clear q.var) !seen;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue