ocaml-containers/puf.mli
Simon Cruanes 7a0605d96f added CC (congruence closure with curryfied terms);
added Puf (persistent Union-Find, used in CC);
added their unit tests
2013-04-17 15:43:19 +02:00

138 lines
4.8 KiB
OCaml

(*
Copyright (c) 2013, Simon Cruanes
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer. Redistributions in binary
form must reproduce the above copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other materials provided with
the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)
(** {1 Functional (persistent) extensible union-find} *)
(** {2 Persistent array} *)
module PArray : sig
type 'a t
val make : int -> 'a -> 'a t
val init : int -> (int -> 'a) -> 'a t
val get : 'a t -> int -> 'a
val set : 'a t -> int -> 'a -> 'a t
val length : 'a t -> int
val fold_left : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
val extend : 'a t -> int -> 'a -> unit
(** Extend [t] to the given [size], initializing new elements with [elt] *)
val extend_init : 'a t -> int -> (int -> 'a) -> unit
(** Extend [t] to the given [size], initializing elements with [f] *)
end
(** {2 Persistent Bitvector} *)
module PBitVector : sig
type t
val make : int -> t
(** Create a new bitvector of the given initial size (in words) *)
val get : t -> int -> bool
(** [get bv i] gets the value of the [i]-th element of [bv] *)
val set : t -> int -> bool -> t
(** [set bv i v] sets the value of the [i]-th element of [bv] to [v] *)
val clear : t -> t
(** Bitvector with all bits set to 0 *)
val set_true : t -> int -> t
val set_false : t -> int -> t
end
(** {2 Type with unique identifier} *)
module type ID = sig
type t
val get_id : t -> int
(** Unique integer ID for the element. Must be >= 0. *)
end
(** {2 Persistent Union-Find with explanations} *)
module type S = sig
type elt
(** Elements of the Union-find *)
type 'e t
(** An instance of the union-find, ie a set of equivalence classes; It
is parametrized by the type of explanations. *)
val create : int -> 'e t
(** Create a union-find of the given size. *)
val find : 'e t -> elt -> elt
(** [find uf a] returns the current representative of [a] in the given
union-find structure [uf]. By default, [find uf a = a]. *)
val union : 'e t -> elt -> elt -> 'e -> 'e t
(** [union uf a b why] returns an update of [uf] where [find a = find b],
the merge being justified by [why]. *)
val distinct : 'e t -> elt -> elt -> 'e t
(** Ensure that the two elements are distinct. *)
val must_be_distinct : _ t -> elt -> elt -> bool
(** Should the two elements be distinct? *)
val fold_equiv_class : _ t -> elt -> ('a -> elt -> 'a) -> 'a -> 'a
(** [fold_equiv_class uf a f acc] folds on [acc] and every element
that is congruent to [a] with [f]. *)
val iter_equiv_class : _ t -> elt -> (elt -> unit) -> unit
(** [iter_equiv_class uf a f] calls [f] on every element of [uf] that
is congruent to [a], including [a] itself. *)
val inconsistent : _ t -> (elt * elt * elt * elt) option
(** Check whether the UF is inconsistent. It returns [Some (a, b, a', b')]
in case of inconsistency, where a = b, a = a' and b = b' by congruence,
and a' != b' was a call to [distinct]. *)
val common_ancestor : 'e t -> elt -> elt -> elt
(** Closest common ancestor of the two elements in the proof forest *)
val explain_step : 'e t -> elt -> (elt * 'e) option
(** Edge from the element to its parent in the proof forest; Returns
None if the element is a root of the forest. *)
val explain : 'e t -> elt -> elt -> 'e list
(** [explain uf a b] returns a list of labels that justify why
[find uf a = find uf b]. Such labels were provided by [union]. *)
val explain_distinct : 'e t -> elt -> elt -> elt * elt
(** [explain_distinct uf a b] gives the original pair [a', b'] that
made [a] and [b] distinct by calling [distinct a' b']. The
terms must be distinct, otherwise Failure is raised. *)
end
module Make(X : ID) : S with type elt = X.t