sidekick/src/cc/sigs_plugin.ml
2022-08-14 23:21:49 -04:00

97 lines
3 KiB
OCaml
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

open Types_
(* TODO: full EGG, also have a function to update the value when
the subterms (produced in [of_term]) are updated *)
(** Data attached to the congruence closure classes.
This helps theories keeping track of some state for each class.
The state of a class is the monoidal combination of the state for each
Term.t in the class (for example, the set of terms in the
class whose head symbol is a datatype constructor). *)
module type MONOID_PLUGIN_ARG = sig
type t
(** Some type with a monoid structure *)
include Sidekick_sigs.PRINT with type t := t
type state
val create : CC.t -> state
(** Initialize state from the congruence closure *)
val name : string
(** name of the monoid structure (short) *)
(* FIXME: for subs, return list of e_nodes, and assume of_term already
returned data for them. *)
val of_term :
CC.t -> state -> E_node.t -> Term.t -> t option * (E_node.t * t) list
(** [of_term n t], where [t] is the Term.t annotating node [n],
must return [maybe_m, l], where:
- [maybe_m = Some m] if [t] has monoid value [m];
otherwise [maybe_m=None]
- [l] is a list of [(u, m_u)] where each [u]'s Term.t
is a direct subterm of [t]
and [m_u] is the monoid value attached to [u].
*)
val merge :
CC.t ->
state ->
E_node.t ->
t ->
E_node.t ->
t ->
Expl.t ->
(t * CC.Handler_action.t list, CC.Handler_action.conflict) result
(** Monoidal combination of two values.
[merge cc n1 mon1 n2 mon2 expl] returns the result of merging
monoid values [mon1] (for class [n1]) and [mon2] (for class [n2])
when [n1] and [n2] are merged with explanation [expl].
@return [Ok mon] if the merge is acceptable, annotating the class of [n1 n2];
or [Error expl'] if the merge is unsatisfiable. [expl'] can then be
used to trigger a conflict and undo the merge.
*)
end
(** Stateful plugin holding a per-equivalence-class monoid.
Helps keep track of monoid state per equivalence class.
A theory might use one or more instance(s) of this to
aggregate some theory-specific state over all terms, with
the information of what terms are already known to be equal
potentially saving work for the theory. *)
module type DYN_MONOID_PLUGIN = sig
module M : MONOID_PLUGIN_ARG
include Sidekick_sigs.DYN_BACKTRACKABLE
val pp : unit Fmt.printer
val mem : E_node.t -> bool
(** Does the CC E_node.t have a monoid value? *)
val get : E_node.t -> M.t option
(** Get monoid value for this CC E_node.t, if any *)
val iter_all : (CC.repr * M.t) Iter.t
end
(** Builder for a plugin.
The builder takes a congruence closure, and instantiate the
plugin on it. *)
module type MONOID_PLUGIN_BUILDER = sig
module M : MONOID_PLUGIN_ARG
module type DYN_PL_FOR_M = DYN_MONOID_PLUGIN with module M = M
type t = (module DYN_PL_FOR_M)
val create_and_setup : ?size:int -> CC.t -> t
(** Create a new monoid state *)
end