refactor(mini-cc): remove distinct API

This commit is contained in:
Simon Cruanes 2019-10-30 13:41:09 -05:00
parent 44e168495b
commit 17aba9461c
3 changed files with 25 additions and 44 deletions

View file

@ -16,7 +16,6 @@ module type S = sig
val create : term_state -> t val create : term_state -> t
val add_lit : t -> term -> bool -> unit val add_lit : t -> term -> bool -> unit
val distinct : t -> term list -> unit
val check_sat : t -> bool val check_sat : t -> bool
@ -123,9 +122,8 @@ module Make(A: ARG) = struct
mutable ok: bool; (* unsat? *) mutable ok: bool; (* unsat? *)
tbl: node T_tbl.t; tbl: node T_tbl.t;
sig_tbl: node Sig_tbl.t; sig_tbl: node Sig_tbl.t;
combine: (node * node) Vec.t; mutable combine: (node * node) list;
pending: node Vec.t; (* refresh signature *) mutable pending: node list; (* refresh signature *)
distinct: node list ref Vec.t; (* disjoint sets *)
true_: node; true_: node;
false_: node; false_: node;
} }
@ -137,9 +135,8 @@ module Make(A: ARG) = struct
ok=true; ok=true;
tbl= T_tbl.create 128; tbl= T_tbl.create 128;
sig_tbl=Sig_tbl.create 128; sig_tbl=Sig_tbl.create 128;
combine=Vec.create(); combine=[];
pending=Vec.create(); pending=[];
distinct=Vec.create();
true_=Node.make true_; true_=Node.make true_;
false_=Node.make false_; false_=Node.make false_;
} in } in
@ -168,7 +165,7 @@ module Make(A: ARG) = struct
let n_u = Node.root @@ add_t self u in let n_u = Node.root @@ add_t self u in
Node.add_parent n_u ~p:node); Node.add_parent n_u ~p:node);
(* need to compute signature *) (* need to compute signature *)
Vec.push self.pending node; self.pending <- node :: self.pending;
node node
let find_t_ (self:t) (t:term): node = let find_t_ (self:t) (t:term): node =
@ -182,13 +179,6 @@ module Make(A: ARG) = struct
exception E_unsat exception E_unsat
let check_distinct_ self : unit =
Vec.iter
(fun r ->
r := List.rev_map Node.root !r;
if has_dups !r then raise_notrace E_unsat)
self.distinct
let compute_sig (self:t) (n:node) : Signature.t option = let compute_sig (self:t) (n:node) : Signature.t option =
let[@inline] return x = Some x in let[@inline] return x = Some x in
match A.cc_view n.n_t with match A.cc_view n.n_t with
@ -218,7 +208,7 @@ module Make(A: ARG) = struct
let n2 = self.true_ in let n2 = self.true_ in
Log.debugf 5 Log.debugf 5
(fun k->k "(@[mini-cc.congruence-by-eq@ %a@ %a@])" Node.pp n Node.pp n2); (fun k->k "(@[mini-cc.congruence-by-eq@ %a@ %a@])" Node.pp n Node.pp n2);
Vec.push self.combine (n,n2) self.combine <- (n,n2) :: self.combine;
) )
| Some s -> | Some s ->
Log.debugf 5 (fun k->k "(@[mini-cc.update-sig@ %a@])" Signature.pp s); Log.debugf 5 (fun k->k "(@[mini-cc.update-sig@ %a@])" Signature.pp s);
@ -228,14 +218,14 @@ module Make(A: ARG) = struct
(* collision, merge *) (* collision, merge *)
Log.debugf 5 Log.debugf 5
(fun k->k "(@[mini-cc.congruence-by-sig@ %a@ %a@])" Node.pp n Node.pp n2); (fun k->k "(@[mini-cc.congruence-by-sig@ %a@ %a@])" Node.pp n Node.pp n2);
Vec.push self.combine (n,n2) self.combine <- (n,n2) :: self.combine;
| exception Not_found -> | exception Not_found ->
Sig_tbl.add self.sig_tbl s n Sig_tbl.add self.sig_tbl s n
let[@inline] is_bool self n = Node.equal self.true_ n || Node.equal self.false_ n let[@inline] is_bool self n = Node.equal self.true_ n || Node.equal self.false_ n
(* merge the two classes *) (* merge the two classes *)
let merge_ self (n1,n2) : unit = let merge_ self n1 n2 : unit =
let n1 = Node.root n1 in let n1 = Node.root n1 in
let n2 = Node.root n2 in let n2 = Node.root n2 in
if not @@ Node.equal n1 n2 then ( if not @@ Node.equal n1 n2 then (
@ -253,7 +243,7 @@ module Make(A: ARG) = struct
raise E_unsat raise E_unsat
); );
List.iter (Vec.push self.pending) n2.n_parents; (* will change signature *) self.pending <- List.rev_append n2.n_parents self.pending; (* will change signature *)
(* merge parent lists *) (* merge parent lists *)
n1.n_parents <- List.rev_append n2.n_parents n1.n_parents; n1.n_parents <- List.rev_append n2.n_parents n1.n_parents;
@ -273,16 +263,19 @@ module Make(A: ARG) = struct
(* fixpoint of the congruence closure *) (* fixpoint of the congruence closure *)
let fixpoint (self:t) : unit = let fixpoint (self:t) : unit =
while not (Vec.is_empty self.pending && Vec.is_empty self.combine) do while not (CCList.is_empty self.pending && CCList.is_empty self.combine) do
check_ok_ self; check_ok_ self;
while not @@ Vec.is_empty self.pending do while not @@ CCList.is_empty self.pending do
update_sig_ self @@ Vec.pop self.pending let n = List.hd self.pending in
self.pending <- List.tl self.pending;
update_sig_ self n
done; done;
while not @@ Vec.is_empty self.combine do while not @@ CCList.is_empty self.combine do
merge_ self @@ Vec.pop self.combine let (n1,n2) = List.hd self.combine in
self.combine <- List.tl self.combine;
merge_ self n1 n2
done done
done; done
check_distinct_ self
(* API *) (* API *)
@ -291,19 +284,12 @@ module Make(A: ARG) = struct
| Eq (t1,t2) when sign -> | Eq (t1,t2) when sign ->
let n1 = add_t self t1 in let n1 = add_t self t1 in
let n2 = add_t self t2 in let n2 = add_t self t2 in
Vec.push self.combine (n1,n2) self.combine <- (n1,n2) :: self.combine
| _ -> | _ ->
(* just merge with true/false *) (* just merge with true/false *)
let n = add_t self p in let n = add_t self p in
let n2 = if sign then self.true_ else self.false_ in let n2 = if sign then self.true_ else self.false_ in
Vec.push self.combine (n,n2) self.combine <- (n,n2) :: self.combine
let distinct (self:t) l =
match l with
| [] | [_] -> () (* trivial *)
| _ ->
let l = List.rev_map (add_t self) l in
Vec.push self.distinct (ref l)
let check_sat (self:t) : bool = let check_sat (self:t) : bool =
try fixpoint self; true try fixpoint self; true

View file

@ -25,9 +25,6 @@ module type S = sig
val add_lit : t -> term -> bool -> unit val add_lit : t -> term -> bool -> unit
(** [add_lit cc p sign] asserts that [p=sign] *) (** [add_lit cc p sign] asserts that [p=sign] *)
val distinct : t -> term list -> unit
(** [distinct cc l] asserts that all terms in [l] are distinct *)
val check_sat : t -> bool val check_sat : t -> bool
(** [check_sat cc] returns [true] if the current state is satisfiable, [false] (** [check_sat cc] returns [true] if the current state is satisfiable, [false]
if it's unsatisfiable *) if it's unsatisfiable *)

View file

@ -1,7 +1,5 @@
(library (library
(name Sidekick_mini_cc) (name Sidekick_mini_cc)
(public_name sidekick.mini-cc) (public_name sidekick.mini-cc)
(libraries containers iter sidekick.core sidekick.util) (libraries containers iter sidekick.core sidekick.util)
(flags :standard -open Sidekick_util)) (flags :standard -open Sidekick_util))