Module PatriciaTree.MakeHashconsedHeterogeneousSet
Hash-consed version of HETEROGENEOUS_SET. See Hash-consed maps and sets for the differences between hash-consed and non hash-consed sets.
This is a generative functor, as calling it creates a new hash-table to store the created nodes, and a reference to store the next unallocated identifier. Maps/sets from different hash-consing functors (even if these functors have the same arguments) will have different (incompatible) numbering systems and be stored in different hash-tables (thus they will never be physically equal).
Warning: not thread-safe. For a thread-safe version, use MakeHashconsedHeterogeneousSetWithMutex.
Parameters
module Key : HETEROGENEOUS_KEYSignature
include HETEROGENEOUS_SET with type 'a elt = 'a Key.t
type 'a elt = 'a Key.tElements of the set
module BaseMap :
HETEROGENEOUS_MAP with type 'a key = 'a elt and type (_, _) value = unitUnderlying basemap, for cross map/set operations
type t = unit BaseMap.tThe type of our set
type 'a key = 'a eltAlias for elements, for compatibility with other PatriciaTrees
Basic functions
val empty : tThe empty set
val is_empty : t -> boolis_empty st is true if st contains no elements, false otherwise
add elt set adds element elt to the set. Preserves physical equality if elt was already present. O(log(n)) complexity.
val cardinal : t -> intthe size of the set (number of elements), O(n) complexity.
is_singleton set is Some (Any elt) if set is singleton elt and None otherwise. O(1) complexity.
remove elt set returns a set containing all elements of set except elt. Returns a value physically equal to set if elt is not present.
The minimal element if non empty, according to the unsigned order on elements.
The maximal element if non empty, according to the unsigned order on elements.
pop_unsigned_minimum s is Some (elt, s') where elt = unsigned_min_elt s and s' = remove elt s if s is non empty. Uses the unsigned order on elements.
pop_unsigned_maximum s is Some (elt, s') where elt = unsigned_max_elt s and s' = remove elt s if s is non empty. Uses the unsigned order on elements.
Functions on pairs of sets
union a b is the set union of a and b, i.e. the set containing all elements that are either in a or b.
inter a b is the set intersection of a and b, i.e. the set containing all elements that are in both a or b.
split elt set returns s_lt, present, s_gt where s_lt contains all elements of set smaller than elt, s_gt all those greater than elt, and present is true if elt is in set. Uses the unsigned order on elements.
min_elt_inter s1 s2 is unsigned_min_elt of inter s1 s2, but faster as it does not require computing the whole intersection. Returns None when the intersection is empty.
max_elt_inter s1 s2 is unsigned_max_elt of inter s1 s2, but faster as it does not require computing the whole intersection. Returns None when the intersection is empty.
Iterators
iter f set calls f.f on all elements of set, in the unsigned order of KEY.to_int.
filter f set is the subset of set that only contains the elements that satisfy f.f. f.f is called in the unsigned order of KEY.to_int.
for_all f set is true if f.f is true on all elements of set. Short-circuits on first false. f.f is called in the unsigned order of KEY.to_int.
fold f set acc returns f.f elt_n (... (f.f elt_1 acc) ...), where elt_1, ..., elt_n are the elements of set, in increasing unsigned order of KEY.to_int
val pretty :
?pp_sep:(Stdlib.Format.formatter -> unit -> unit) ->
polypretty ->
Stdlib.Format.formatter ->
t ->
unitPretty prints the set, pp_sep is called once between each element, it defaults to Format.pp_print_cut
Iterators on pairs of sets
val for_all2 :
left_only:bool polyfold forall2_pred ->
common:bool polyfold forall2_pred ->
right_only:bool polyfold forall2_pred ->
t ->
t ->
boolfor_all2 ~reflexive ~left_only ~common ~right_only s1 s2 evaluates predicates on the elements of s1 and s2.
left_only k v1is called for elements ofs1that don't appear ins2;right_only k v2is called for eleemnts ofs2that don't appear ins1;common k v1 v2is called for shared elements.
All three of these parameters can be either True, False, or a user supplied function (using F). The True and False constructors are faster, as knowing these values in advance avoids having to explore the relevant branches.
for_all2 explores elements in the unsigned order of KEY.to_int. It also has early-return: any false evaluation will stop exploration.
val exists2 :
left_only:bool polyfold forall2_pred ->
common:bool polyfold forall2_pred ->
right_only:bool polyfold forall2_pred ->
t ->
t ->
boolval fold2 :
left_only:('r -> 'r) polyfold option ->
common:('r -> 'r) polyfold option ->
right_only:('r -> 'r) polyfold option ->
t ->
t ->
'r ->
'rfold2 ~reflexive ~left_only ~common ~right_only s1 s2 r iterates two sets s1 and s2 simultaneously, updating the accumulator r at each binding:
left_only x ris called on elementsxpresent ins1but nots2;right_only k v2 ris called on elements present ins2but nots1common k v1 v2 ris called on shared elements.
Each of these can be None instead of a function, in which case the corresponding bindings are ignored. This can dramatically speed up the fold, as it then skips exploration of unneeded subtrees.
fold2 explores bindings in the unsigned order of KEY.to_int.
Conversion functions
to_seq st iterates the whole set, in increasing unsigned order of KEY.to_int
to_rev_seq st iterates the whole set, in decreasing unsigned order of KEY.to_int
add_seq s st adds all elements of the sequence s to st in order.
to_list s returns the elements of s as a list, in increasing unsigned order of KEY.to_int
Hash-consing specific operations
val to_int : t -> intReturns the hash-consed id of the map. Unlike NODE_WITH_ID.to_int, hash-consing ensures that maps which contain the same keys (compared by KEY.to_int) and values (compared by HASHED_VALUE.polyeq) will always be physically equal and have the same identifier.
Note that when using physical equality as HASHED_VALUE.polyeq, some maps of different types a t and b t may be given the same identifier. See the end of the documentation of HASHED_VALUE.polyeq for details.
Constant time equality using the hash-consed nodes identifiers. This is equivalent to physical equality. Two nodes are equal if their trees contain the same bindings, where keys are compared by KEY.to_int and values are compared by HASHED_VALUE.polyeq.
Constant time comparison using the hash-consed node identifiers. This order is fully arbitrary, but it is total and can be used to sort nodes. It is based on node ids which depend on the order in which the nodes where created (older nodes having smaller ids).
One useful property of this order is that child nodes will always have a smaller identifier than their parents.