sidekick/src/smt/th_combination.ml
2022-09-16 19:49:58 -04:00

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