123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852open!Importopen!TmoduletypeElt_plain=sigtypet[@@deriving_inlinecompare,sexp_of]includePpx_compare_lib.Comparable.Swithtypet:=tvalsexp_of_t:t->Sexplib0.Sexp.t[@@@end]endmoduleWithout_comparator=Map_intf.Without_comparatormoduleWith_comparator=Map_intf.With_comparatormoduleWith_first_class_module=Map_intf.With_first_class_modulemoduleMerge_to_sequence_element=Sequence.Merge_with_duplicates_elementmoduleNamed=structtype'at={set:'a;name:string}endmoduletypeAccessors_generic=sigincludeContainer.Generictype('a,'cmp)tree(** The [access_options] type is used to make [Accessors_generic] flexible as to whether
a comparator is required to be passed to certain functions. *)type('a,'cmp,'z)access_optionstype'cmpcmpvalinvariants:('a,'cmp,('a,'cmp)t->bool)access_options(** override [Container]'s [mem] *)valmem:('a,'cmp,('a,'cmp)t->'aelt->bool)access_optionsvaladd:('a,'cmp,('a,'cmp)t->'aelt->('a,'cmp)t)access_optionsvalremove:('a,'cmp,('a,'cmp)t->'aelt->('a,'cmp)t)access_optionsvalunion:('a,'cmp,('a,'cmp)t->('a,'cmp)t->('a,'cmp)t)access_optionsvalinter:('a,'cmp,('a,'cmp)t->('a,'cmp)t->('a,'cmp)t)access_optionsvaldiff:('a,'cmp,('a,'cmp)t->('a,'cmp)t->('a,'cmp)t)access_optionsvalsymmetric_diff:('a,'cmp,('a,'cmp)t->('a,'cmp)t->('aelt,'aelt)Either.tSequence.t)access_optionsvalcompare_direct:('a,'cmp,('a,'cmp)t->('a,'cmp)t->int)access_optionsvalequal:('a,'cmp,('a,'cmp)t->('a,'cmp)t->bool)access_optionsvalis_subset:('a,'cmp,('a,'cmp)t->of_:('a,'cmp)t->bool)access_optionsvalare_disjoint:('a,'cmp,('a,'cmp)t->('a,'cmp)t->bool)access_optionsmoduleNamed:sigvalis_subset:('a,'cmp,('a,'cmp)tNamed.t->of_:('a,'cmp)tNamed.t->unitOr_error.t)access_optionsvalequal:('a,'cmp,('a,'cmp)tNamed.t->('a,'cmp)tNamed.t->unitOr_error.t)access_optionsendvalfold_until:('a,_)t->init:'acc->f:(('acc->'aelt->('acc,'final)Container.Continue_or_stop.t)[@local])->finish:(('acc->'final)[@local])->'finalvalfold_right:('a,_)t->init:'acc->f:(('aelt->'acc->'acc)[@local])->'accvaliter2:('a,'cmp,('a,'cmp)t->('a,'cmp)t->f:(([`Leftof'aelt|`Rightof'aelt|`Bothof'aelt*'aelt]->unit)[@local])->unit)access_optionsvalfilter:('a,'cmp)t->f:(('aelt->bool)[@local])->('a,'cmp)tvalpartition_tf:('a,'cmp)t->f:(('aelt->bool)[@local])->('a,'cmp)t*('a,'cmp)tvalelements:('a,_)t->'aeltlistvalmin_elt:('a,_)t->'aeltoptionvalmin_elt_exn:('a,_)t->'aeltvalmax_elt:('a,_)t->'aeltoptionvalmax_elt_exn:('a,_)t->'aeltvalchoose:('a,_)t->'aeltoptionvalchoose_exn:('a,_)t->'aeltvalsplit:('a,'cmp,('a,'cmp)t->'aelt->('a,'cmp)t*'aeltoption*('a,'cmp)t)access_optionsvalsplit_le_gt:('a,'cmp,('a,'cmp)t->'aelt->('a,'cmp)t*('a,'cmp)t)access_optionsvalsplit_lt_ge:('a,'cmp,('a,'cmp)t->'aelt->('a,'cmp)t*('a,'cmp)t)access_optionsvalgroup_by:('a,'cmp)t->equiv:(('aelt->'aelt->bool)[@local])->('a,'cmp)tlistvalfind_exn:('a,_)t->f:(('aelt->bool)[@local])->'aeltvalnth:('a,_)t->int->'aeltoptionvalremove_index:('a,'cmp,('a,'cmp)t->int->('a,'cmp)t)access_optionsvalto_tree:('a,'cmp)t->('aelt,'cmpcmp)treevalto_sequence:('a,'cmp,?order:[`Increasing|`Decreasing]->?greater_or_equal_to:'aelt->?less_or_equal_to:'aelt->('a,'cmp)t->'aeltSequence.t)access_optionsvalbinary_search:('a,'cmp,('a,'cmp)t->compare:(('aelt->'key->int)[@local])->Binary_searchable.Which_target_by_key.t->'key->'aeltoption)access_optionsvalbinary_search_segmented:('a,'cmp,('a,'cmp)t->segment_of:(('aelt->[`Left|`Right])[@local])->Binary_searchable.Which_target_by_segment.t->'aeltoption)access_optionsvalmerge_to_sequence:('a,'cmp,?order:[`Increasing|`Decreasing]->?greater_or_equal_to:'aelt->?less_or_equal_to:'aelt->('a,'cmp)t->('a,'cmp)t->('aelt,'aelt)Merge_to_sequence_element.tSequence.t)access_optionsendmoduletypeCreators_generic=sigtype('a,'cmp)ttype('a,'cmp)settype('a,'cmp)treetype'aelttype('a,'cmp,'z)create_optionstype'cmpcmpvalempty:('a,'cmp,('a,'cmp)t)create_optionsvalsingleton:('a,'cmp,'aelt->('a,'cmp)t)create_optionsvalunion_list:('a,'cmp,('a,'cmp)tlist->('a,'cmp)t)create_optionsvalof_list:('a,'cmp,'aeltlist->('a,'cmp)t)create_optionsvalof_sequence:('a,'cmp,'aeltSequence.t->('a,'cmp)t)create_optionsvalof_array:('a,'cmp,'aeltarray->('a,'cmp)t)create_optionsvalof_sorted_array:('a,'cmp,'aeltarray->('a,'cmp)tOr_error.t)create_optionsvalof_sorted_array_unchecked:('a,'cmp,'aeltarray->('a,'cmp)t)create_optionsvalof_increasing_iterator_unchecked:('a,'cmp,len:int->f:((int->'aelt)[@local])->('a,'cmp)t)create_optionsvalstable_dedup_list:('a,_,'aeltlist->'aeltlist)create_options(** The types of [map] and [filter_map] are subtle. The input set, [('a, _) set],
reflects the fact that these functions take a set of *any* type, with any
comparator, while the output set, [('b, 'cmp) t], reflects that the output set has
the particular ['cmp] of the creation function. The comparator can come in one of
three ways, depending on which set module is used
- [Set.map] -- comparator comes as an argument
- [Set.Poly.map] -- comparator is polymorphic comparison
- [Foo.Set.map] -- comparator is [Foo.comparator] *)valmap:('b,'cmp,('a,_)set->f:(('a->'belt)[@local])->('b,'cmp)t)create_optionsvalfilter_map:('b,'cmp,('a,_)set->f:(('a->'beltoption)[@local])->('b,'cmp)t)create_optionsvalof_tree:('a,'cmp,('aelt,'cmpcmp)tree->('a,'cmp)t)create_optionsendmoduletypeCreators_and_accessors_generic=sigtype('elt,'cmp)ttype('elt,'cmp)treetype'eltelttype'cmpcmpincludeAccessors_genericwithtype('a,'b)t:=('a,'b)twithtype('a,'b)tree:=('a,'b)treewithtype'aelt:='aeltwithtype'cmpcmp:='cmpcmpincludeCreators_genericwithtype('a,'b)t:=('a,'b)twithtype('a,'b)tree:=('a,'b)treewithtype'aelt:='aeltwithtype'cmpcmp:='cmpcmpendmoduletypeS_poly=sigtype'eltttype'elttreetypecomparator_witnessincludeCreators_and_accessors_genericwithtype('elt,'cmp)t:='elttwithtype('elt,'cmp)tree:='elttreewithtype'aelt:='awithtype'ccmp:=comparator_witnesswithtype('a,'b,'c)create_options:=('a,'b,'c)Without_comparator.twithtype('a,'b,'c)access_options:=('a,'b,'c)Without_comparator.tendmoduletypeFor_deriving=sigtype('a,'b)tmoduletypeSexp_of_m=sigtypet[@@deriving_inlinesexp_of]valsexp_of_t:t->Sexplib0.Sexp.t[@@@end]endmoduletypeM_of_sexp=sigtypet[@@deriving_inlineof_sexp]valt_of_sexp:Sexplib0.Sexp.t->t[@@@end]includeComparator.Swithtypet:=tendmoduletypeM_sexp_grammar=sigtypet[@@deriving_inlinesexp_grammar]valt_sexp_grammar:tSexplib0.Sexp_grammar.t[@@@end]endmoduletypeCompare_m=sigendmoduletypeEqual_m=sigendmoduletypeHash_fold_m=Hasher.Svalsexp_of_m__t:(moduleSexp_of_mwithtypet='elt)->('elt,'cmp)t->Sexp.tvalm__t_of_sexp:(moduleM_of_sexpwithtypet='eltandtypecomparator_witness='cmp)->Sexp.t->('elt,'cmp)tvalm__t_sexp_grammar:(moduleM_sexp_grammarwithtypet='elt)->('elt,'cmp)tSexplib0.Sexp_grammar.tvalcompare_m__t:(moduleCompare_m)->('elt,'cmp)t->('elt,'cmp)t->intvalequal_m__t:(moduleEqual_m)->('elt,'cmp)t->('elt,'cmp)t->boolvalhash_fold_m__t:(moduleHash_fold_mwithtypet='elt)->Hash.state->('elt,_)t->Hash.statevalhash_m__t:(moduleHash_fold_mwithtypet='elt)->('elt,_)t->intendmoduletypeSet=sig(** Sets based on {!Comparator.S}.
Creators require a comparator argument to be passed in, whereas accessors use the
comparator provided by the input set. *)(** The type of a set. The first type parameter identifies the type of the element, and
the second identifies the comparator, which determines the comparison function that
is used for ordering elements in this set. Many operations (e.g., {!union}),
require that they be passed sets with the same element type and the same comparator
type. *)type(!'elt,!'cmp)t[@@deriving_inlinecompare]includePpx_compare_lib.Comparable.S2withtype(!'elt,!'cmp)t:=('elt,'cmp)t[@@@end]type('k,'cmp)comparator=('k,'cmp)Comparator.Module.t[@@deprecated"[since 2021-12] use [Comparator.Module.t] instead"](** Tests internal invariants of the set data structure. Returns true on success. *)valinvariants:(_,_)t->bool(** Returns a first-class module that can be used to build other map/set/etc
with the same notion of comparison. *)valcomparator_s:('a,'cmp)t->('a,'cmp)Comparator.Module.tvalcomparator:('a,'cmp)t->('a,'cmp)Comparator.t(** Creates an empty set based on the provided comparator. *)valempty:('a,'cmp)Comparator.Module.t->('a,'cmp)t(** Creates a set based on the provided comparator that contains only the provided
element. *)valsingleton:('a,'cmp)Comparator.Module.t->'a->('a,'cmp)t(** Returns the cardinality of the set. [O(1)]. *)vallength:(_,_)t->int(** [is_empty t] is [true] iff [t] is empty. [O(1)]. *)valis_empty:(_,_)t->bool(** [mem t a] returns [true] iff [a] is in [t]. [O(log n)]. *)valmem:('a,_)t->'a->bool(** [add t a] returns a new set with [a] added to [t], or returns [t] if [mem t a].
[O(log n)]. *)valadd:('a,'cmp)t->'a->('a,'cmp)t(** [remove t a] returns a new set with [a] removed from [t] if [mem t a], or returns [t]
otherwise. [O(log n)]. *)valremove:('a,'cmp)t->'a->('a,'cmp)t(** [union t1 t2] returns the union of the two sets. [O(length t1 + length t2)]. *)valunion:('a,'cmp)t->('a,'cmp)t->('a,'cmp)t(** [union c list] returns the union of all the sets in [list]. The
[comparator] argument is required for the case where [list] is empty.
[O(max(List.length list, n log n))], where [n] is the sum of sizes of the input sets. *)valunion_list:('a,'cmp)Comparator.Module.t->('a,'cmp)tlist->('a,'cmp)t(** [inter t1 t2] computes the intersection of sets [t1] and [t2]. [O(length t1 +
length t2)]. *)valinter:('a,'cmp)t->('a,'cmp)t->('a,'cmp)t(** [diff t1 t2] computes the set difference [t1 - t2], i.e., the set containing all
elements in [t1] that are not in [t2]. [O(length t1 + length t2)]. *)valdiff:('a,'cmp)t->('a,'cmp)t->('a,'cmp)t(** [symmetric_diff t1 t2] returns a sequence of changes between [t1] and [t2]. It is
intended to be efficient in the case where [t1] and [t2] share a large amount of
structure. *)valsymmetric_diff:('a,'cmp)t->('a,'cmp)t->('a,'a)Either.tSequence.t(** [compare_direct t1 t2] compares the sets [t1] and [t2]. It returns the same result
as [compare], but unlike compare, doesn't require arguments to be passed in for the
type parameters of the set. [O(length t1 + length t2)]. *)valcompare_direct:('a,'cmp)t->('a,'cmp)t->int(** Hash function: a building block to use when hashing data structures containing sets in
them. [hash_fold_direct hash_fold_key] is compatible with [compare_direct] iff
[hash_fold_key] is compatible with [(comparator s).compare] of the set [s] being
hashed. *)valhash_fold_direct:'aHash.folder->('a,'cmp)tHash.folder(** [equal t1 t2] returns [true] iff the two sets have the same elements. [O(length t1 +
length t2)] *)valequal:('a,'cmp)t->('a,'cmp)t->bool(** [exists t ~f] returns [true] iff there exists an [a] in [t] for which [f a]. [O(n)],
but returns as soon as it finds an [a] for which [f a]. *)valexists:('a,_)t->f:(('a->bool)[@local])->bool(** [for_all t ~f] returns [true] iff for all [a] in [t], [f a]. [O(n)], but returns as
soon as it finds an [a] for which [not (f a)]. *)valfor_all:('a,_)t->f:(('a->bool)[@local])->bool(** [count t] returns the number of elements of [t] for which [f] returns [true].
[O(n)]. *)valcount:('a,_)t->f:(('a->bool)[@local])->int(** [sum t] returns the sum of [f t] for each [t] in the set.
[O(n)]. *)valsum:(moduleContainer.Summablewithtypet='sum)->('a,_)t->f:(('a->'sum)[@local])->'sum(** [find t f] returns an element of [t] for which [f] returns true, with no guarantee as
to which element is returned. [O(n)], but returns as soon as a suitable element is
found. *)valfind:('a,_)t->f:(('a->bool)[@local])->'aoption(** [find_map t f] returns [b] for some [a] in [t] for which [f a = Some b]. If no such
[a] exists, then [find] returns [None]. [O(n)], but returns as soon as a suitable
element is found. *)valfind_map:('a,_)t->f:(('a->'boption)[@local])->'boption(** Like [find], but throws an exception on failure. *)valfind_exn:('a,_)t->f:(('a->bool)[@local])->'a(** [nth t i] returns the [i]th smallest element of [t], in [O(log n)] time. The
smallest element has [i = 0]. Returns [None] if [i < 0] or [i >= length t]. *)valnth:('a,_)t->int->'aoption(** [remove_index t i] returns a version of [t] with the [i]th smallest element removed,
in [O(log n)] time. The smallest element has [i = 0]. Returns [t] if [i < 0] or
[i >= length t]. *)valremove_index:('a,'cmp)t->int->('a,'cmp)t(** [is_subset t1 ~of_:t2] returns true iff [t1] is a subset of [t2]. *)valis_subset:('a,'cmp)t->of_:('a,'cmp)t->bool(** [are_disjoint t1 t2] returns [true] iff [is_empty (inter t1 t2)], but is more
efficient. *)valare_disjoint:('a,'cmp)t->('a,'cmp)t->bool(** [Named] allows the validation of subset and equality relationships between sets. A
[Named.t] is a record of a set and a name, where the name is used in error messages,
and [Named.is_subset] and [Named.equal] validate subset and equality relationships
respectively.
The error message for, e.g.,
{[
Named.is_subset { set = set1; name = "set1" } ~of_:{set = set2; name = "set2" }
]}
looks like
{v
("set1 is not a subset of set2" (invalid_elements (...elements of set1 - set2...)))
v}
so [name] should be a noun phrase that doesn't sound awkward in the above error
message. Even though it adds verbosity, choosing [name]s that start with the phrase
"the set of" often makes the error message sound more natural.
*)moduleNamed:sigtype('a,'cmp)set:=('a,'cmp)ttype'at='aNamed.t={set:'a;name:string}(** [is_subset t1 ~of_:t2] returns [Ok ()] if [t1] is a subset of [t2] and a
human-readable error otherwise. *)valis_subset:('a,'cmp)sett->of_:('a,'cmp)sett->unitOr_error.t(** [equal t1 t2] returns [Ok ()] if [t1] is equal to [t2] and a human-readable
error otherwise. *)valequal:('a,'cmp)sett->('a,'cmp)sett->unitOr_error.tend(** The list or array given to [of_list] and [of_array] need not be sorted. *)valof_list:('a,'cmp)Comparator.Module.t->'alist->('a,'cmp)tvalof_sequence:('a,'cmp)Comparator.Module.t->'aSequence.t->('a,'cmp)tvalof_array:('a,'cmp)Comparator.Module.t->'aarray->('a,'cmp)t(** [to_list] and [to_array] produce sequences sorted in ascending order according to the
comparator. *)valto_list:('a,_)t->'alistvalto_array:('a,_)t->'aarray(** Create set from sorted array. The input must be sorted (either in ascending or
descending order as given by the comparator) and contain no duplicates, otherwise the
result is an error. The complexity of this function is [O(n)]. *)valof_sorted_array:('a,'cmp)Comparator.Module.t->'aarray->('a,'cmp)tOr_error.t(** Similar to [of_sorted_array], but without checking the input array. *)valof_sorted_array_unchecked:('a,'cmp)Comparator.Module.t->'aarray->('a,'cmp)t(** [of_increasing_iterator_unchecked c ~len ~f] behaves like [of_sorted_array_unchecked c
(Array.init len ~f)], with the additional restriction that a decreasing order is not
supported. The advantage is not requiring you to allocate an intermediate array. [f]
will be called with 0, 1, ... [len - 1], in order. *)valof_increasing_iterator_unchecked:('a,'cmp)Comparator.Module.t->len:int->f:((int->'a)[@local])->('a,'cmp)t(** [stable_dedup_list] is here rather than in the [List] module because the
implementation relies crucially on sets, and because doing so allows one to avoid uses
of polymorphic comparison by instantiating the functor at a different implementation
of [Comparator] and using the resulting [stable_dedup_list]. *)valstable_dedup_list:('a,_)Comparator.Module.t->'alist->'alist(** [map c t ~f] returns a new set created by applying [f] to every element in
[t]. The returned set is based on the provided [comparator]. [O(n log n)]. *)valmap:('b,'cmp)Comparator.Module.t->('a,_)t->f:(('a->'b)[@local])->('b,'cmp)t(** Like {!map}, except elements for which [f] returns [None] will be dropped. *)valfilter_map:('b,'cmp)Comparator.Module.t->('a,_)t->f:(('a->'boption)[@local])->('b,'cmp)t(** [filter t ~f] returns the subset of [t] for which [f] evaluates to true. [O(n log
n)]. *)valfilter:('a,'cmp)t->f:(('a->bool)[@local])->('a,'cmp)t(** [fold t ~init ~f] folds over the elements of the set from smallest to largest. *)valfold:('a,_)t->init:'acc->f:(('acc->'a->'acc)[@local])->'acc(** [fold_result ~init ~f] folds over the elements of the set from smallest to
largest, short circuiting the fold if [f accum x] is an [Error _] *)valfold_result:('a,_)t->init:'acc->f:(('acc->'a->('acc,'e)Result.t)[@local])->('acc,'e)Result.t(** [fold_until t ~init ~f] is a short-circuiting version of [fold]. If [f]
returns [Stop _] the computation ceases and results in that value. If [f] returns
[Continue _], the fold will proceed. *)valfold_until:('a,_)t->init:'acc->f:(('acc->'a->('acc,'final)Container.Continue_or_stop.t)[@local])->finish:(('acc->'final)[@local])->'final(** Like {!fold}, except that it goes from the largest to the smallest element. *)valfold_right:('a,_)t->init:'acc->f:(('a->'acc->'acc)[@local])->'acc(** [iter t ~f] calls [f] on every element of [t], going in order from the smallest to
largest. *)valiter:('a,_)t->f:(('a->unit)[@local])->unit(** Iterate two sets side by side. Complexity is [O(m+n)] where [m] and [n] are the sizes
of the two input sets. As an example, with the inputs [0; 1] and [1; 2], [f] will be
called with [`Left 0]; [`Both (1, 1)]; and [`Right 2]. *)valiter2:('a,'cmp)t->('a,'cmp)t->f:(([`Leftof'a|`Rightof'a|`Bothof'a*'a]->unit)[@local])->unit(** if [a, b = partition_tf set ~f] then [a] is the elements on which [f] produced [true],
and [b] is the elements on which [f] produces [false]. *)valpartition_tf:('a,'cmp)t->f:(('a->bool)[@local])->('a,'cmp)t*('a,'cmp)t(** Same as {!to_list}. *)valelements:('a,_)t->'alist(** Returns the smallest element of the set. [O(log n)]. *)valmin_elt:('a,_)t->'aoption(** Like {!min_elt}, but throws an exception when given an empty set. *)valmin_elt_exn:('a,_)t->'a(** Returns the largest element of the set. [O(log n)]. *)valmax_elt:('a,_)t->'aoption(** Like {!max_elt}, but throws an exception when given an empty set. *)valmax_elt_exn:('a,_)t->'a(** returns an arbitrary element, or [None] if the set is empty. *)valchoose:('a,_)t->'aoption(** Like {!choose}, but throws an exception on an empty set. *)valchoose_exn:('a,_)t->'a(** [split t x] produces a triple [(t1, maybe_x, t2)].
[t1] is the set of elements strictly less than [x],
[maybe_x] is the member (if any) of [t] which compares equal to [x],
[t2] is the set of elements strictly larger than [x]. *)valsplit:('a,'cmp)t->'a->('a,'cmp)t*'aoption*('a,'cmp)t(** [split_le_gt t x] produces a pair [(t1, t2)].
[t1] is the set of elements less than or equal to [x],
[t2] is the set of elements strictly greater than [x]. *)valsplit_le_gt:('a,'cmp)t->'a->('a,'cmp)t*('a,'cmp)t(** [split_lt_ge t x] produces a pair [(t1, t2)].
[t1] is the set of elements strictly less than [x],
[t2] is the set of elements greater than or equal to [x]. *)valsplit_lt_ge:('a,'cmp)t->'a->('a,'cmp)t*('a,'cmp)t(** if [equiv] is an equivalence predicate, then [group_by set ~equiv] produces a list
of equivalence classes (i.e., a set-theoretic quotient). E.g.,
{[
let chars = Set.of_list ['A'; 'a'; 'b'; 'c'] in
let equiv c c' = Char.equal (Char.uppercase c) (Char.uppercase c') in
group_by chars ~equiv
]}
produces:
{[
[Set.of_list ['A';'a']; Set.singleton 'b'; Set.singleton 'c']
]}
[group_by] runs in O(n^2) time, so if you have a comparison function, it's usually
much faster to use [Set.of_list]. *)valgroup_by:('a,'cmp)t->equiv:(('a->'a->bool)[@local])->('a,'cmp)tlist(** [to_sequence t] converts the set [t] to a sequence of the elements between
[greater_or_equal_to] and [less_or_equal_to] inclusive in the order indicated by
[order]. If [greater_or_equal_to > less_or_equal_to] the sequence is empty. Cost is
O(log n) up front and amortized O(1) for each element produced. *)valto_sequence:?order:[`Increasing(** default *)|`Decreasing]->?greater_or_equal_to:'a->?less_or_equal_to:'a->('a,'cmp)t->'aSequence.t(** [binary_search t ~compare which elt] returns the element in [t] specified by
[compare] and [which], if one exists.
[t] must be sorted in increasing order according to [compare], where [compare] and
[elt] divide [t] into three (possibly empty) segments:
{v
| < elt | = elt | > elt |
v}
[binary_search] returns an element on the boundary of segments as specified by
[which]. See the diagram below next to the [which] variants.
[binary_search] does not check that [compare] orders [t], and behavior is
unspecified if [compare] doesn't order [t]. Behavior is also unspecified if
[compare] mutates [t]. *)valbinary_search:('a,'cmp)t->compare:(('a->'key->int)[@local])->[`Last_strictly_less_than(** {v | < elt X | v} *)|`Last_less_than_or_equal_to(** {v | <= elt X | v} *)|`Last_equal_to(** {v | = elt X | v} *)|`First_equal_to(** {v | X = elt | v} *)|`First_greater_than_or_equal_to(** {v | X >= elt | v} *)|`First_strictly_greater_than(** {v | X > elt | v} *)]->'key->'aoption(** [binary_search_segmented t ~segment_of which] takes a [segment_of] function that
divides [t] into two (possibly empty) segments:
{v
| segment_of elt = `Left | segment_of elt = `Right |
v}
[binary_search_segmented] returns the element on the boundary of the segments as
specified by [which]: [`Last_on_left] yields the last element of the left segment,
while [`First_on_right] yields the first element of the right segment. It returns
[None] if the segment is empty.
[binary_search_segmented] does not check that [segment_of] segments [t] as in the
diagram, and behavior is unspecified if [segment_of] doesn't segment [t]. Behavior
is also unspecified if [segment_of] mutates [t]. *)valbinary_search_segmented:('a,'cmp)t->segment_of:(('a->[`Left|`Right])[@local])->[`Last_on_left|`First_on_right]->'aoption(** Produces the elements of the two sets between [greater_or_equal_to] and
[less_or_equal_to] in [order], noting whether each element appears in the left set,
the right set, or both. In the both case, both elements are returned, in case the
caller can distinguish between elements that are equal to the sets' comparator. Runs
in O(length t + length t'). *)moduleMerge_to_sequence_element:sigtype('a,'b)t=('a,'b)Sequence.Merge_with_duplicates_element.t=|Leftof'a|Rightof'b|Bothof'a*'b[@@deriving_inlinecompare,sexp]includePpx_compare_lib.Comparable.S2withtype('a,'b)t:=('a,'b)tincludeSexplib0.Sexpable.S2withtype('a,'b)t:=('a,'b)t[@@@end]endvalmerge_to_sequence:?order:[`Increasing(** default *)|`Decreasing]->?greater_or_equal_to:'a->?less_or_equal_to:'a->('a,'cmp)t->('a,'cmp)t->('a,'a)Merge_to_sequence_element.tSequence.t(** [M] is meant to be used in combination with OCaml applicative functor types:
{[
type string_set = Set.M(String).t
]}
which stands for:
{[
type string_set = (String.t, String.comparator_witness) Set.t
]}
The point is that [Set.M(String).t] supports deriving, whereas the second syntax
doesn't (because there is no such thing as, say, String.sexp_of_comparator_witness,
instead you would want to pass the comparator directly). *)moduleM(Elt:sigtypettypecomparator_witnessend):sigtypenonrect=(Elt.t,Elt.comparator_witness)tendincludeFor_derivingwithtype('a,'b)t:=('a,'b)t(** A polymorphic Set. *)modulePoly:S_polywithtype'eltt=('elt,Comparator.Poly.comparator_witness)t(** Using comparator is a similar interface as the toplevel of [Set], except the functions
take a [~comparator:('elt, 'cmp) Comparator.t] where the functions at the toplevel of
[Set] takes a [('elt, 'cmp) comparator]. *)moduleUsing_comparator:sigtypenonrec('elt,'cmp)t=('elt,'cmp)t[@@deriving_inlinesexp_of]valsexp_of_t:('elt->Sexplib0.Sexp.t)->('cmp->Sexplib0.Sexp.t)->('elt,'cmp)t->Sexplib0.Sexp.t[@@@end]valt_of_sexp_direct:comparator:('elt,'cmp)Comparator.t->(Sexp.t->'elt)->Sexp.t->('elt,'cmp)tmoduleTree:sig(** A [Tree.t] contains just the tree data structure that a set is based on, without
including the comparator. Accordingly, any operation on a [Tree.t] must also take
as an argument the corresponding comparator. *)type('a,'cmp)t[@@deriving_inlinesexp_of]valsexp_of_t:('a->Sexplib0.Sexp.t)->('cmp->Sexplib0.Sexp.t)->('a,'cmp)t->Sexplib0.Sexp.t[@@@end]valt_of_sexp_direct:comparator:('elt,'cmp)Comparator.t->(Sexp.t->'elt)->Sexp.t->('elt,'cmp)tincludeCreators_and_accessors_genericwithtype('a,'b)set:=('a,'b)twithtype('a,'b)t:=('a,'b)twithtype('a,'b)tree:=('a,'b)twithtype'aelt:='awithtype'ccmp:='cwithtype('a,'b,'c)create_options:=('a,'b,'c)With_comparator.twithtype('a,'b,'c)access_options:=('a,'b,'c)With_comparator.tvalempty_without_value_restriction:(_,_)tendincludeCreators_and_accessors_genericwithtype('a,'b)t:=('a,'b)twithtype('a,'b)tree:=('a,'b)Tree.twithtype('a,'b)set:=('a,'b)twithtype'aelt:='awithtype'ccmp:='cwithtype('a,'b,'c)access_options:=('a,'b,'c)Without_comparator.twithtype('a,'b,'c)create_options:=('a,'b,'c)With_comparator.tvalcomparator_s:('a,'cmp)t->('a,'cmp)Comparator.Module.tvalcomparator:('a,'cmp)t->('a,'cmp)Comparator.tvalhash_fold_direct:'eltHash.folder->('elt,'cmp)tHash.foldermoduleEmpty_without_value_restriction(Elt:Comparator.S1):sigvalempty:('aElt.t,Elt.comparator_witness)tendendvalto_tree:('a,'cmp)t->('a,'cmp)Using_comparator.Tree.tvalof_tree:('a,'cmp)Comparator.Module.t->('a,'cmp)Using_comparator.Tree.t->('a,'cmp)t(** {2 Modules and module types for extending [Set]}
For use in extensions of Base, like [Core]. *)moduleWith_comparator=With_comparatormoduleWith_first_class_module=With_first_class_modulemoduleWithout_comparator=Without_comparatormoduletypeFor_deriving=For_derivingmoduletypeS_poly=S_polymoduletypeAccessors_generic=Accessors_genericmoduletypeCreators_generic=Creators_genericmoduletypeCreators_and_accessors_generic=Creators_and_accessors_genericmoduletypeElt_plain=Elt_plainend