mirror of
https://github.com/c-cube/sidekick.git
synced 2025-12-06 03:05:31 -05:00
97 lines
3 KiB
OCaml
97 lines
3 KiB
OCaml
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
|