diff --git a/src/sat/solver.ml b/src/sat/solver.ml index 5b399074..c751536e 100644 --- a/src/sat/solver.ml +++ b/src/sat/solver.ml @@ -1600,11 +1600,14 @@ let pick_branch_lit ~full self : bool = | [] -> (match H.remove_min self.order with | v -> - pick_with_given_atom - (if Var.default_pol self.store v then + let pol = Var.last_pol self.store v in + let atom = + if pol then Atom.pa v else - Atom.na v) + Atom.na v + in + pick_with_given_atom atom | exception Not_found -> false) (* pick a decision, trying [atom] first if it's not assigned yet. *) and pick_with_given_atom (atom : atom) : bool = @@ -1615,9 +1618,12 @@ let pick_branch_lit ~full self : bool = || Atom.is_true self.store (Atom.na v)); pick_lit () ) else ( + (* [atom] is not assigned, we can decide it *) new_decision_level self; let current_level = decision_level self in enqueue_bool self atom ~level:current_level Decision; + (* remember polarity *) + Var.set_last_pol self.store v (Atom.sign atom); Stat.incr self.n_decisions; Event.emit self.on_decision (Atom.lit self.store atom); true diff --git a/src/sat/store.ml b/src/sat/store.ml index a91447e2..e7d42b4a 100644 --- a/src/sat/store.ml +++ b/src/sat/store.ml @@ -23,6 +23,7 @@ type t = { v_reason: var_reason option Vec.t; (* reason for assignment *) v_seen: Bitvec.t; (* generic temporary marker *) v_default_polarity: Bitvec.t; (* default polarity in decisions *) + v_last_polarity: Bitvec.t; (* last polarity when deciding this *) mutable v_count: int; (* atoms *) a_is_true: Bitvec.t; @@ -55,6 +56,7 @@ let create ?(size = `Big) ~stat () : t = v_reason = Vec.create (); v_seen = Bitvec.create (); v_default_polarity = Bitvec.create (); + v_last_polarity = Bitvec.create (); v_count = 0; a_is_true = Bitvec.create (); a_form = Vec.create (); @@ -95,8 +97,16 @@ module Var = struct let[@inline] unmark self v = Bitvec.set self.v_seen (v : var :> int) false let[@inline] marked self v = Bitvec.get self.v_seen (v : var :> int) + let[@inline] set_last_pol self v b = + Bitvec.set self.v_last_polarity (v : var :> int) b + + let[@inline] last_pol self v = + Bitvec.get self.v_last_polarity (v : var :> int) + let[@inline] set_default_pol self v b = - Bitvec.set self.v_default_polarity (v : var :> int) b + Bitvec.set self.v_default_polarity (v : var :> int) b; + (* also update last polarity *) + set_last_pol self v b let[@inline] default_pol self v = Bitvec.get self.v_default_polarity (v : var :> int) @@ -340,6 +350,7 @@ let alloc_var_uncached_ ?default_pol:(pol = true) self (form : Lit.t) : var = v_reason; v_seen; v_default_polarity; + v_last_polarity; stat_n_atoms; a_is_true; a_seen; @@ -365,6 +376,8 @@ let alloc_var_uncached_ ?default_pol:(pol = true) self (form : Lit.t) : var = Bitvec.ensure_size v_seen v_idx; Bitvec.ensure_size v_default_polarity v_idx; Bitvec.set v_default_polarity v_idx pol; + Bitvec.ensure_size v_last_polarity v_idx; + Bitvec.set v_last_polarity v_idx pol; assert (Vec.size a_form = 2 * (v : var :> int)); Bitvec.ensure_size a_is_true (2 * (v : var :> int)); diff --git a/src/sat/store.mli b/src/sat/store.mli index d4628187..73be49e3 100644 --- a/src/sat/store.mli +++ b/src/sat/store.mli @@ -37,6 +37,8 @@ module Var : sig val marked : store -> var -> bool val set_default_pol : store -> var -> bool -> unit val default_pol : store -> var -> bool + val set_last_pol : store -> var -> bool -> unit + val last_pol : store -> var -> bool val heap_idx : store -> var -> int val set_heap_idx : store -> var -> int -> unit end