mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 11:15:43 -05:00
Propagation reasons are now far more explicit
This commit is contained in:
parent
0186edbf34
commit
815098dde4
5 changed files with 42 additions and 40 deletions
|
|
@ -288,9 +288,10 @@ module Make
|
||||||
if a.is_true then raise Trivial;
|
if a.is_true then raise Trivial;
|
||||||
if a.neg.is_true then begin
|
if a.neg.is_true then begin
|
||||||
match a.var.reason with
|
match a.var.reason with
|
||||||
| Bcp (Some cl) -> atoms, cl :: history, max lvl cl.c_level
|
| None | Some Decision -> assert false
|
||||||
| Semantic 0 -> atoms, history, lvl
|
| Some (Bcp cl) -> atoms, cl :: history, max lvl cl.c_level
|
||||||
| _ ->
|
| Some (Semantic 0) -> atoms, history, lvl
|
||||||
|
| Some (Semantic _) ->
|
||||||
Log.debugf 0 "Unexpected semantic propagation at level 0: %a"
|
Log.debugf 0 "Unexpected semantic propagation at level 0: %a"
|
||||||
(fun k->k St.pp_atom a);
|
(fun k->k St.pp_atom a);
|
||||||
assert false
|
assert false
|
||||||
|
|
@ -311,9 +312,9 @@ module Make
|
||||||
else if a.neg.is_true then
|
else if a.neg.is_true then
|
||||||
if a.var.v_level = 0 then begin
|
if a.var.v_level = 0 then begin
|
||||||
match a.var.reason with
|
match a.var.reason with
|
||||||
| Bcp (Some cl) ->
|
| Some (Bcp cl) ->
|
||||||
partition_aux trues unassigned falses (cl :: history) (max lvl cl.c_level) r
|
partition_aux trues unassigned falses (cl :: history) (max lvl cl.c_level) r
|
||||||
| Semantic 0 ->
|
| Some (Semantic 0) ->
|
||||||
partition_aux trues unassigned falses history lvl r
|
partition_aux trues unassigned falses history lvl r
|
||||||
| _ -> assert false
|
| _ -> assert false
|
||||||
end else
|
end else
|
||||||
|
|
@ -393,7 +394,7 @@ module Make
|
||||||
a.is_true <- false;
|
a.is_true <- false;
|
||||||
a.neg.is_true <- false;
|
a.neg.is_true <- false;
|
||||||
a.var.v_level <- -1;
|
a.var.v_level <- -1;
|
||||||
a.var.reason <- Bcp None;
|
a.var.reason <- None;
|
||||||
insert_var_order (elt_of_var a.var)
|
insert_var_order (elt_of_var a.var)
|
||||||
end
|
end
|
||||||
done;
|
done;
|
||||||
|
|
@ -411,14 +412,14 @@ module Make
|
||||||
raise Unsat
|
raise Unsat
|
||||||
|
|
||||||
let simpl_reason = function
|
let simpl_reason = function
|
||||||
| (Bcp Some cl) as r ->
|
| (Bcp cl) as r ->
|
||||||
let l, history, c_lvl = partition (Vec.to_list cl.atoms) 0 in
|
let l, history, c_lvl = partition (Vec.to_list cl.atoms) 0 in
|
||||||
begin match l with
|
begin match l with
|
||||||
| [ a ] ->
|
| [ a ] ->
|
||||||
if history = [] then r
|
if history = [] then r
|
||||||
else
|
else
|
||||||
let tmp_cl = make_clause (fresh_tname ()) l 1 true (History (cl :: history)) c_lvl in
|
let tmp_cl = make_clause (fresh_tname ()) l 1 true (History (cl :: history)) c_lvl in
|
||||||
Bcp (Some tmp_cl)
|
Bcp tmp_cl
|
||||||
| _ -> assert false
|
| _ -> assert false
|
||||||
end
|
end
|
||||||
| r -> r
|
| r -> r
|
||||||
|
|
@ -429,14 +430,14 @@ module Make
|
||||||
assert false
|
assert false
|
||||||
end;
|
end;
|
||||||
if not a.is_true then begin
|
if not a.is_true then begin
|
||||||
assert (a.var.v_level < 0 && a.var.reason = Bcp None && lvl >= 0);
|
assert (a.var.v_level < 0 && a.var.reason = None && lvl >= 0);
|
||||||
let reason =
|
let reason =
|
||||||
if lvl > 0 then reason
|
if lvl > 0 then reason
|
||||||
else simpl_reason reason
|
else simpl_reason reason
|
||||||
in
|
in
|
||||||
a.is_true <- true;
|
a.is_true <- true;
|
||||||
a.var.v_level <- lvl;
|
a.var.v_level <- lvl;
|
||||||
a.var.reason <- reason;
|
a.var.reason <- Some reason;
|
||||||
Vec.push env.elt_queue (of_atom a);
|
Vec.push env.elt_queue (of_atom a);
|
||||||
Log.debugf 20 "Enqueue (%d): %a"
|
Log.debugf 20 "Enqueue (%d): %a"
|
||||||
(fun k->k (Vec.size env.elt_queue) pp_atom a)
|
(fun k->k (Vec.size env.elt_queue) pp_atom a)
|
||||||
|
|
@ -480,7 +481,7 @@ module Make
|
||||||
let c_level = ref 0 in
|
let c_level = ref 0 in
|
||||||
clause_bump_activity c_clause;
|
clause_bump_activity c_clause;
|
||||||
let is_semantic a = match a.var.reason with
|
let is_semantic a = match a.var.reason with
|
||||||
| Semantic _ -> true
|
| Some Semantic _ -> true
|
||||||
| _ -> false
|
| _ -> false
|
||||||
in
|
in
|
||||||
try while true do
|
try while true do
|
||||||
|
|
@ -499,7 +500,7 @@ module Make
|
||||||
| Either.Left _ -> ()
|
| Either.Left _ -> ()
|
||||||
| Either.Right a ->
|
| Either.Right a ->
|
||||||
begin match a.var.reason with
|
begin match a.var.reason with
|
||||||
| Bcp (Some d) ->
|
| Some (Bcp d) ->
|
||||||
let tmp, res = Proof.resolve (Proof.merge !c (Proof.to_list d)) in
|
let tmp, res = Proof.resolve (Proof.merge !c (Proof.to_list d)) in
|
||||||
begin match tmp with
|
begin match tmp with
|
||||||
| [] -> ()
|
| [] -> ()
|
||||||
|
|
@ -511,8 +512,7 @@ module Make
|
||||||
c := res
|
c := res
|
||||||
| _ -> assert false
|
| _ -> assert false
|
||||||
end
|
end
|
||||||
| Bcp None -> ()
|
| None | Some Decision | Some Semantic _ -> ()
|
||||||
| Semantic _ -> ()
|
|
||||||
end
|
end
|
||||||
done; assert false
|
done; assert false
|
||||||
with Exit ->
|
with Exit ->
|
||||||
|
|
@ -546,7 +546,7 @@ module Make
|
||||||
if q.var.v_level = 0 then begin
|
if q.var.v_level = 0 then begin
|
||||||
assert (q.neg.is_true);
|
assert (q.neg.is_true);
|
||||||
match q.var.reason with
|
match q.var.reason with
|
||||||
| Bcp Some cl -> history := cl :: !history
|
| Some Bcp cl -> history := cl :: !history
|
||||||
| _ -> assert false
|
| _ -> assert false
|
||||||
end;
|
end;
|
||||||
if not q.var.seen then begin
|
if not q.var.seen then begin
|
||||||
|
|
@ -574,7 +574,7 @@ module Make
|
||||||
| 0, _ ->
|
| 0, _ ->
|
||||||
cond := false;
|
cond := false;
|
||||||
learnt := p.neg :: (List.rev !learnt)
|
learnt := p.neg :: (List.rev !learnt)
|
||||||
| n, Bcp Some cl ->
|
| n, Some Bcp cl ->
|
||||||
c_level := max !c_level cl.c_level;
|
c_level := max !c_level cl.c_level;
|
||||||
c := cl
|
c := cl
|
||||||
| n, _ -> assert false
|
| n, _ -> assert false
|
||||||
|
|
@ -599,7 +599,7 @@ module Make
|
||||||
let name = fresh_lname () in
|
let name = fresh_lname () in
|
||||||
let uclause = make_clause name learnt (List.length learnt) true history lvl in
|
let uclause = make_clause name learnt (List.length learnt) true history lvl in
|
||||||
Vec.push env.clauses_learnt uclause;
|
Vec.push env.clauses_learnt uclause;
|
||||||
enqueue_bool fuip 0 (Bcp (Some uclause))
|
enqueue_bool fuip 0 (Bcp uclause)
|
||||||
end
|
end
|
||||||
| fuip :: _ ->
|
| fuip :: _ ->
|
||||||
let name = fresh_lname () in
|
let name = fresh_lname () in
|
||||||
|
|
@ -608,7 +608,7 @@ module Make
|
||||||
attach_clause lclause;
|
attach_clause lclause;
|
||||||
clause_bump_activity lclause;
|
clause_bump_activity lclause;
|
||||||
if is_uip then
|
if is_uip then
|
||||||
enqueue_bool fuip blevel (Bcp (Some lclause))
|
enqueue_bool fuip blevel (Bcp lclause)
|
||||||
else begin
|
else begin
|
||||||
env.next_decision <- Some fuip.neg
|
env.next_decision <- Some fuip.neg
|
||||||
end
|
end
|
||||||
|
|
@ -656,12 +656,12 @@ module Make
|
||||||
end else if b.neg.is_true && not a.is_true && not a.neg.is_true then begin
|
end else if b.neg.is_true && not a.is_true && not a.neg.is_true then begin
|
||||||
let lvl = List.fold_left (fun m a -> max m a.var.v_level) 0 atoms in
|
let lvl = List.fold_left (fun m a -> max m a.var.v_level) 0 atoms in
|
||||||
cancel_until lvl;
|
cancel_until lvl;
|
||||||
enqueue_bool a lvl (Bcp (Some clause))
|
enqueue_bool a lvl (Bcp clause)
|
||||||
end
|
end
|
||||||
| [a] ->
|
| [a] ->
|
||||||
Log.debugf 5 "New unit clause, propagating : %a" (fun k->k St.pp_atom a);
|
Log.debugf 5 "New unit clause, propagating : %a" (fun k->k St.pp_atom a);
|
||||||
cancel_until 0;
|
cancel_until 0;
|
||||||
enqueue_bool a 0 (Bcp (Some init0))
|
enqueue_bool a 0 (Bcp init0)
|
||||||
with Trivial ->
|
with Trivial ->
|
||||||
Log.debugf 5 "Trivial clause ignored : @[%a@]" (fun k->k St.pp_clause init0)
|
Log.debugf 5 "Trivial clause ignored : @[%a@]" (fun k->k St.pp_clause init0)
|
||||||
|
|
||||||
|
|
@ -703,7 +703,7 @@ module Make
|
||||||
(* clause is unit *)
|
(* clause is unit *)
|
||||||
Vec.set watched !new_sz c;
|
Vec.set watched !new_sz c;
|
||||||
incr new_sz;
|
incr new_sz;
|
||||||
enqueue_bool first (decision_level ()) (Bcp (Some c))
|
enqueue_bool first (decision_level ()) (Bcp c)
|
||||||
end
|
end
|
||||||
with Exit -> ()
|
with Exit -> ()
|
||||||
|
|
||||||
|
|
@ -887,7 +887,7 @@ module Make
|
||||||
env.decisions <- env.decisions + 1;
|
env.decisions <- env.decisions + 1;
|
||||||
new_decision_level();
|
new_decision_level();
|
||||||
let current_level = decision_level () in
|
let current_level = decision_level () in
|
||||||
enqueue_bool atom current_level (Bcp None)
|
enqueue_bool atom current_level Decision
|
||||||
| Th.Valued (b, lvl) ->
|
| Th.Valued (b, lvl) ->
|
||||||
let a = if b then atom else atom.neg in
|
let a = if b then atom else atom.neg in
|
||||||
enqueue_bool a lvl (Semantic lvl)
|
enqueue_bool a lvl (Semantic lvl)
|
||||||
|
|
@ -1040,11 +1040,11 @@ module Make
|
||||||
insert_var_order (elt_of_lit l)
|
insert_var_order (elt_of_lit l)
|
||||||
| Either.Right a ->
|
| Either.Right a ->
|
||||||
begin match a.var.reason with
|
begin match a.var.reason with
|
||||||
| Bcp Some { c_level } when c_level > push_lvl ->
|
| Some Bcp { c_level } when c_level > push_lvl ->
|
||||||
a.is_true <- false;
|
a.is_true <- false;
|
||||||
a.neg.is_true <- false;
|
a.neg.is_true <- false;
|
||||||
a.var.v_level <- -1;
|
a.var.v_level <- -1;
|
||||||
a.var.reason <- Bcp None;
|
a.var.reason <- None;
|
||||||
insert_var_order (elt_of_var a.var)
|
insert_var_order (elt_of_var a.var)
|
||||||
| _ ->
|
| _ ->
|
||||||
if a.var.v_level = 0 then begin
|
if a.var.v_level = 0 then begin
|
||||||
|
|
@ -1054,7 +1054,7 @@ module Make
|
||||||
a.is_true <- false;
|
a.is_true <- false;
|
||||||
a.neg.is_true <- false;
|
a.neg.is_true <- false;
|
||||||
a.var.v_level <- -1;
|
a.var.v_level <- -1;
|
||||||
a.var.reason <- Bcp None;
|
a.var.reason <- None;
|
||||||
insert_var_order (elt_of_var a.var)
|
insert_var_order (elt_of_var a.var)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ module Make(St : Solver_types.S) = struct
|
||||||
let l = Vec.to_list c.St.atoms in
|
let l = Vec.to_list c.St.atoms in
|
||||||
let l = List.map (fun a ->
|
let l = List.map (fun a ->
|
||||||
match St.(a.var.reason) with
|
match St.(a.var.reason) with
|
||||||
| St.Bcp Some d -> d
|
| Some St.Bcp d -> d
|
||||||
| _ -> assert false) l
|
| _ -> assert false) l
|
||||||
in
|
in
|
||||||
St.make_clause (fresh_pcl_name ()) [] 0 true (St.History (c :: l))
|
St.make_clause (fresh_pcl_name ()) [] 0 true (St.History (c :: l))
|
||||||
|
|
@ -99,7 +99,7 @@ module Make(St : Solver_types.S) = struct
|
||||||
let prove_atom a =
|
let prove_atom a =
|
||||||
if St.(a.is_true && a.var.v_level = 0) then begin
|
if St.(a.is_true && a.var.v_level = 0) then begin
|
||||||
match St.(a.var.reason) with
|
match St.(a.var.reason) with
|
||||||
| St.Bcp Some c ->
|
| Some St.Bcp c ->
|
||||||
assert (Vec.size St.(c.atoms) = 1 && equal_atoms a (Vec.get St.(c.atoms) 0));
|
assert (Vec.size St.(c.atoms) = 1 && equal_atoms a (Vec.get St.(c.atoms) 0));
|
||||||
Some c
|
Some c
|
||||||
| _ -> assert false
|
| _ -> assert false
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ module McMake (E : Expr_intf.S) = struct
|
||||||
mutable seen : bool;
|
mutable seen : bool;
|
||||||
mutable v_level : int;
|
mutable v_level : int;
|
||||||
mutable v_weight : float;
|
mutable v_weight : float;
|
||||||
mutable reason : reason;
|
mutable reason : reason option;
|
||||||
}
|
}
|
||||||
|
|
||||||
and atom = {
|
and atom = {
|
||||||
|
|
@ -66,8 +66,9 @@ module McMake (E : Expr_intf.S) = struct
|
||||||
}
|
}
|
||||||
|
|
||||||
and reason =
|
and reason =
|
||||||
|
| Decision
|
||||||
|
| Bcp of clause
|
||||||
| Semantic of int
|
| Semantic of int
|
||||||
| Bcp of clause option
|
|
||||||
|
|
||||||
and premise =
|
and premise =
|
||||||
| Lemma of proof
|
| Lemma of proof
|
||||||
|
|
@ -85,7 +86,7 @@ module McMake (E : Expr_intf.S) = struct
|
||||||
seen = false;
|
seen = false;
|
||||||
v_level = -1;
|
v_level = -1;
|
||||||
v_weight = -1.;
|
v_weight = -1.;
|
||||||
reason = Bcp None;
|
reason = None;
|
||||||
}
|
}
|
||||||
and dummy_atom =
|
and dummy_atom =
|
||||||
{ var = dummy_var;
|
{ var = dummy_var;
|
||||||
|
|
@ -151,7 +152,7 @@ module McMake (E : Expr_intf.S) = struct
|
||||||
seen = false;
|
seen = false;
|
||||||
v_level = -1;
|
v_level = -1;
|
||||||
v_weight = 0.;
|
v_weight = 0.;
|
||||||
reason = Bcp None;
|
reason = None;
|
||||||
}
|
}
|
||||||
and pa =
|
and pa =
|
||||||
{ var = var;
|
{ var = var;
|
||||||
|
|
@ -257,11 +258,11 @@ module McMake (E : Expr_intf.S) = struct
|
||||||
let level a =
|
let level a =
|
||||||
match a.var.v_level, a.var.reason with
|
match a.var.v_level, a.var.reason with
|
||||||
| n, _ when n < 0 -> assert false
|
| n, _ when n < 0 -> assert false
|
||||||
| 0, Bcp (Some c) -> sprintf "->0/%s" c.name
|
| 0, Some (Bcp c) -> sprintf "->0/%s" c.name
|
||||||
| 0, Bcp None -> "@0"
|
| 0, None -> "@0"
|
||||||
| n, Bcp (Some c) -> sprintf "->%d/%s" n c.name
|
| n, Some (Bcp c) -> sprintf "->%d/%s" n c.name
|
||||||
| n, Bcp None -> sprintf "@@%d" n
|
| n, None -> sprintf "@@%d" n
|
||||||
| n, Semantic lvl -> sprintf "::%d/%d" n lvl
|
| n, Some (Semantic lvl) -> sprintf "::%d/%d" n lvl
|
||||||
|
|
||||||
let value a =
|
let value a =
|
||||||
if a.is_true then sprintf "[T%s]" (level a)
|
if a.is_true then sprintf "[T%s]" (level a)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ module type S = sig
|
||||||
mutable seen : bool;
|
mutable seen : bool;
|
||||||
mutable v_level : int;
|
mutable v_level : int;
|
||||||
mutable v_weight : float;
|
mutable v_weight : float;
|
||||||
mutable reason : reason;
|
mutable reason : reason option;
|
||||||
}
|
}
|
||||||
|
|
||||||
and atom = {
|
and atom = {
|
||||||
|
|
@ -61,8 +61,9 @@ module type S = sig
|
||||||
}
|
}
|
||||||
|
|
||||||
and reason =
|
and reason =
|
||||||
|
| Decision
|
||||||
|
| Bcp of clause
|
||||||
| Semantic of int
|
| Semantic of int
|
||||||
| Bcp of clause option
|
|
||||||
|
|
||||||
and premise =
|
and premise =
|
||||||
| Lemma of proof
|
| Lemma of proof
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue