mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-10 13:14:09 -05:00
62 lines
1.7 KiB
OCaml
62 lines
1.7 KiB
OCaml
open Sidekick_core
|
|
module T = Term
|
|
|
|
type t = {
|
|
tst: Term.store;
|
|
processed: T.Set.t T.Tbl.t; (** type -> set of terms *)
|
|
unprocessed: T.t Vec.t;
|
|
n_terms: int Stat.counter;
|
|
n_lits: int Stat.counter;
|
|
}
|
|
|
|
let create ?(stat = Stat.global) tst : t =
|
|
{
|
|
tst;
|
|
processed = T.Tbl.create 8;
|
|
unprocessed = Vec.create ();
|
|
n_terms = Stat.mk_int stat "smt.thcomb.terms";
|
|
n_lits = Stat.mk_int stat "smt.thcomb.intf-lits";
|
|
}
|
|
|
|
let processed_ (self : t) t : bool =
|
|
let ty = T.ty t in
|
|
match T.Tbl.find_opt self.processed ty with
|
|
| None -> false
|
|
| Some set -> T.Set.mem t set
|
|
|
|
let add_term_needing_combination (self : t) (t : T.t) : unit =
|
|
if (not (processed_ self t)) && not (T.is_bool @@ T.ty t) then (
|
|
Log.debugf 50 (fun k -> k "(@[th.comb.add-term-needing-comb@ %a@])" T.pp t);
|
|
Vec.push self.unprocessed t
|
|
)
|
|
|
|
let pop_new_lits (self : t) : Lit.t list =
|
|
let lits = ref [] in
|
|
|
|
(* first, process new terms, if any *)
|
|
while not (Vec.is_empty self.unprocessed) do
|
|
let t = Vec.pop_exn self.unprocessed in
|
|
let ty = T.ty t in
|
|
let set_for_ty =
|
|
try T.Tbl.find self.processed ty with Not_found -> T.Set.empty
|
|
in
|
|
if not (T.Set.mem t set_for_ty) then (
|
|
Stat.incr self.n_terms;
|
|
Log.debugf 10 (fun k ->
|
|
k "(@[th-comb.term.need-th-combination@ %a@])" T.pp t);
|
|
|
|
(* now create [t=u] for each [u] in [set_for_ty], and add it to [lits] *)
|
|
T.Set.iter
|
|
(fun u ->
|
|
let lit = Lit.make_eq self.tst t u in
|
|
Stat.incr self.n_lits;
|
|
lits := lit :: !lits)
|
|
set_for_ty;
|
|
|
|
(* add [t] to the set of processed terms *)
|
|
let new_set_for_ty = T.Set.add t set_for_ty in
|
|
T.Tbl.replace self.processed ty new_set_for_ty
|
|
)
|
|
done;
|
|
|
|
!lits
|