123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769(******************************************************************************)(* *)(* Baby *)(* *)(* François Pottier, Inria Paris *)(* *)(* Copyright 2024--2024 Inria. All rights reserved. This file is *)(* distributed under the terms of the GNU Library General Public *)(* License, with an exception, as described in the file LICENSE. *)(* *)(******************************************************************************)(**The signature [Baby.OrderedType] describes a type equipped
with a total ordering function. *)moduletypeOrderedType=sig(**The type of the set elements. *)typet(** A total ordering function over values of type [t].
[compare x1 x2] must be zero if [x1] and [x2] are equal.
It must be strictly negative if [x1] is smaller than [x2].
It must be strictly positive if [x1] is greater than [x2]. *)valcompare:t->t->intend(* OrderedType *)(**The signature [Baby.CORE] describes the interface that must be offered by
the balancing code to the rest of the balanced binary search tree library.
Most operations on binary search tree are built on top of this interface,
and are oblivious to the balancing criterion. *)moduletypeCORE=sig(**Keys, or elements. *)typekey(**Balanced binary search trees. *)typetree(**A view on a balanced binary search tree indicates whether this tree
is a leaf or a node, and, if it is a node, gives access to its left
child, its key, and its right child. A view does not give access to
balancing information, such as the tree's height or weight. *)typeview=|Leaf|Nodeoftree*key*tree(**[view] turns a tree into a view. *)valview:tree->view(* In the reverse direction, one could imagine a conversion function
[make : view -> tree]. In order to avoid a memory allocation, we
replace this function with a constant [leaf] and a function [join]. *)(**[leaf] is the empty tree; a leaf. *)valleaf:tree(**[join l v r] expects a subtree [l], a key [v], and a subtree [r] such
that [l < v < r] holds. It returns a new tree whose elements are the
elements of [l], [v], and [r]. If needed, it performs rebalancing, so the
key [v] is not necessarily found at the root of the new tree. *)valjoin:tree->key->tree->tree(* Regarding computational complexity, BFS write: the cost of [join] must be
proportional to the difference in ranks of two trees, and the rank of the
result of a join must be at most one more than the maximum rank of the
two arguments. *)(* The following functions are not part of the minimal interface proposed
by BFS. Exposing these functions allow us to gain efficiency in various
situations. *)(**[join_neighbors l v r] is analogous to [join l v r]. Like [join], it
requires [l < v < r]. Furthermore, it assumes that the trees [l] and [r]
have been obtained by taking two siblings in a well-formed tree and by
adding or removing one element in one of them. *)valjoin_neighbors:tree->key->tree->tree(**[join_weight_balanced l v r] is analogous to [join l v r]. Like [join],
it requires [l < v < r]. Furthermore, it assumes that the weights of the
trees [l] and [r] differ by at most one. *)valjoin_weight_balanced:tree->key->tree->tree(**If the weight of a tree can be determined in constant time, then
[weight t] returns the weight of the tree [t]. If the weight of a
tree cannot be efficiently determined, then it is acceptable for
[weight] to always return zero. The function [weight] is used to
implement fast paths in subset and equality tests: it must be the
case that [subset t1 t2] implies [weight t1 <= weight t2]. *)valweight:tree->int(**[cardinal t] returns the number of elements in the tree. Depending on the
internal representation of trees, the function [cardinal] may have time
complexity O(1) or O(n). This is indicated by [constant_time_cardinal]. *)valcardinal:tree->int(**[constant_time_cardinal] indicates whether [cardinal] constant time
complexity. *)valconstant_time_cardinal:bool(**[singleton x] constructs a tree whose sole element is [x]. *)valsingleton:key->tree(**[doubleton x y] requires [x < y]. It constructs a tree whose elements are
[x] and [y]. *)valdoubleton:key->key->tree(**[tripleton x y z] requires [x < y < z]. It constructs a tree whose
elements are [x], [y], and [z]. *)valtripleton:key->key->key->tree(**[seems_smaller t1 t2] indicates which of the trees [t1] and [t2] seems
smaller, based on height or weight. This function is used as part of a
heuristic choice, so no correctness obligation bears on it; its
postcondition is [true]. *)valseems_smaller:tree->tree->bool(**[check t] checks that the tree [t] is well-formed: that is, [t] is a
balanced binary search tree. This function is used while testing only. *)valcheck:tree->unitend(* CORE *)(**The signature [Baby.SET] describes an abstract data type of sets,
equipped with a wide array of efficient operations. *)moduletypeSET=sig(**The type of elements. *)typeelt(**The abstract type of sets. A set is an immutable data structure. *)typeset(**A synonym for the type [set]. *)typet=set(** {1:construct Constructing sets} *)(**[empty] is the empty set. *)valempty:set(**[singleton x] returns a set whose sole element is [x]. *)valsingleton:elt->t(**[add x s] returns a set that contains all elements of the set
[s], plus [x].
Thus, it is logically equal to [union (singleton x) s].
If the result is logically equal to [s], then
the result is physically equal to [s].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valadd:elt->set->set(**[remove x s] returns a set that contains all elements of the set
[s], except [x].
It is equivalent to [diff s (singleton x)].
If the result is logically equal to [s], then
the result is physically equal to [s].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valremove:elt->set->set(**If the set [s] is nonempty, then [remove_min_elt s] returns the
set [s], deprived of its minimum element. Otherwise, it raises
[Not_found].
It is equivalent to [remove (min_elt s) s].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valremove_min_elt:set->set(**If the set [s] is nonempty, then [remove_max_elt s] returns the
set [s], deprived of its maximum element. Otherwise, it raises
[Not_found].
It is equivalent to [remove (max_elt s) s].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valremove_max_elt:set->set(**[union s1 s2] returns the union of the sets [s1] and [s2], that
is, a set that contains all elements of the set [s1] and all
elements of the set [s2].
The weight-balanced-tree implementation ({!Baby.W}) offers
the following guarantee:
if the result is logically equal to [s1] or to [s2], then
the result is physically equal to [s1] or to [s2].
The height-balanced tree implementation ({!Baby.H}) does
not offer this guarantee.
Time complexity: {m O(m.\log (\frac{n}{m}))},
where {m m} is the size of the smaller set
and {m n} is the size of the larger set. *)valunion:set->set->set(**[inter s1 s2] returns the intersection of the sets [s1] and [s2],
that is, a set that contains the common elements of the sets [s1]
and [s2].
The weight-balanced-tree implementation ({!Baby.W}) offers
the following guarantee:
if the result is logically equal to [s1] or to [s2], then
the result is physically equal to [s1] or to [s2].
The height-balanced tree implementation ({!Baby.H}) does
not offer this guarantee.
Time complexity: {m O(m.\log (\frac{n}{m}))},
where {m m} is the size of the smaller set
and {m n} is the size of the larger set. *)valinter:set->set->set(**[diff s1 s2] returns the difference of the sets [s1] and [s2],
that is, a set that contains the elements of the set [s1]
that do not appear in the set [s2].
if the result is logically equal to [s1], then
the result is physically equal to [s1].
Time complexity: {m O(m.\log (\frac{n}{m}))},
where {m m} is the size of the smaller set
and {m n} is the size of the larger set. *)valdiff:set->set->set(**[xor s1 s2] returns the symmetric difference of the sets [s1] and [s2],
that is, a set that contains the elements of the set [s1]
that do not appear in the set [s2]
and the elements of the set [s2]
that do not appear in the set [s1].
Time complexity: {m O(m.\log (\frac{n}{m}))},
where {m m} is the size of the smaller set
and {m n} is the size of the larger set. *)valxor:set->set->set(**[split x s] returns a triple [(l, present, r)], where
[l] is the set of the elements of [s] that are strictly less than [x],
[r] is the set of the elements of [s] that are strictly greater than [x],
and [present] is [true] if and only if [x] is a member of the set [s].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valsplit:elt->set->set*bool*set(** {1:query Querying sets} *)(**[is_empty s] determines whether the set [s] is the empty set.
Time complexity: {m O(1)}. *)valis_empty:set->bool(**If the set [s] is nonempty, [min_elt s] returns the minimum
element of this set. Otherwise, it raises [Not_found].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valmin_elt:set->elt(**If the set [s] is nonempty, [min_elt_opt s] returns [Some x],
where [x] is the minimum element of this set. Otherwise, it
returns [None].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valmin_elt_opt:set->eltoption(**If the set [s] is nonempty, [max_elt s] returns the maximum
element of this set. Otherwise, it raises [Not_found].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valmax_elt:set->elt(**If the set [s] is nonempty, [max_elt_opt s] returns [Some x],
where [x] is the maximum element of this set. Otherwise, it
returns [None].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valmax_elt_opt:set->eltoption(**If the set [s] is nonempty, [choose s] returns an arbitrary
element of this set. Otherwise, it raises [Not_found].
[choose] respects equality: if the sets [s1] and [s2] are equal
then [choose s1] and [choose s2] are equal.
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valchoose:set->elt(**If the set [s] is nonempty, [choose_opt s] returns [Some x],
where [x] is an arbitrary element of this set.
Otherwise, it returns [None].
[choose_opt] respects equality: if the sets [s1] and [s2] are equal
then [choose_opt s1] and [choose_opt s2] are equal.
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valchoose_opt:set->eltoption(**[mem x s] determines whether the element [x] is a member of the
set [s].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valmem:elt->set->bool(**If [x] is a member of the set [s], then [find x s] returns the unique
element [x'] of the set [s] such that [x] and [x'] are equivalent. (We
say that [x] and [x'] are equivalent if [compare x x' = 0] holds.)
Otherwise, it raises [Not_found].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valfind:elt->set->elt(* The specification of [find] feels weird, because we have assumed and
indicated everywhere that [compare] must be an order, as opposed to a
preorder. Yet, [find] is useful only if [compare] is a preorder, so
that the equivalence relation [compare x x' = 0] is coarser than
equality. *)(**If [x] is a member of the set [s], then [find_opt x s] returns [Some x'],
where [x'] is the unique element of the set [s] such that [x] and [x']
are equivalent. (We say that [x] and [x'] are equivalent if
[compare x x' = 0] holds.) Otherwise, it returns [None].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valfind_opt:elt->set->eltoption(**[disjoint s1 s2] determines whether the sets [s1] and [s2] are
disjoint, that is, whether their intersection is empty. It is
equivalent to [is_empty (inter s1 s2)].
Time complexity: {m O(m.\log (\frac{n}{m}))},
where {m m} is the size of the smaller set
and {m n} is the size of the larger set. *)valdisjoint:set->set->bool(**[subset s1 s2] determines whether the set [s1] is a subset of the set
[s2], that is, whether their difference is empty. It is equivalent to
[is_empty (diff s1 s2)].
Time complexity: {m O(m.\log (\frac{n}{m}))},
where {m m} is the size of the smaller set
and {m n} is the size of the larger set. *)valsubset:set->set->bool(**[equal s1 s2] determines whether the sets [s1] and [s2] are equal, that
is, whether their symmetric difference is empty. It is equivalent to
[is_empty (xor s1 s2)].
Time complexity: {m O(m)},
where {m m} is the size of the smaller set
and {m n} is the size of the larger set. *)valequal:set->set->bool(**[compare] is a total ordering function over sets. (Which specific
ordering is used is unspecified.)
Time complexity: {m O(m)},
where {m m} is the size of the smaller set
and {m n} is the size of the larger set. *)valcompare:set->set->int(**[cardinal s] returns the cardinal of the set [s], that is,
the number of its elements.
Time complexity:
in the weight-balanced-tree implementation ({!Baby.W}),
{m O(1)};
in the height-balanced-tree implementation ({!Baby.H}),
{m O(n)},
where {m n} is the size of the set [s]. *)valcardinal:set->int(** {1:conversions Conversions to and from sets} *)(**[of_list xs] constructs a set whose elements are the elements
of the list [xs].
This function has adaptive time complexity.
In the worst case, its complexity is {m O(n.\log n)},
where {m n} is the length of the list [xs].
However, if the list [xs] is sorted,
then its complexity is only {m O(n)}.
In between these extremes, its complexity degrades gracefully. *)valof_list:eltlist->set(**[to_list s] constructs a list whose elements are the elements
of the set [s], in increasing order.
Time complexity: {m O(n)},
where {m n} is the size of the set [s]. *)valto_list:set->eltlist(**[elements] is a synonym for [to_list]. *)valelements:set->eltlist(**[of_array xs] constructs a set whose elements are the elements
of the array [xs].
This function has adaptive time complexity.
In the worst case, its complexity is {m O(n.\log n)},
where {m n} is the length of the array [xs].
However, if the array [xs] is sorted,
then its complexity is only {m O(n)}.
In between these extremes, its complexity degrades gracefully. *)valof_array:eltarray->set(**[to_array s] constructs an array whose elements are the elements
of the set [s], in increasing order.
Time complexity: {m O(n)},
where {m n} is the size of the set [s]. *)valto_array:set->eltarray(**[of_seq xs] constructs a set whose elements are the elements of the
sequence [xs]. (The whole sequence is immediately consumed.)
This function has adaptive time complexity.
In the worst case, its complexity is {m O(n.\log n)},
where {m n} is the length of the list [xs].
However, if the sequence [xs] is sorted,
then its complexity is only {m O(n)}.
In between these extremes, its complexity degrades gracefully. *)valof_seq:eltSeq.t->set(**[add_seq xs s] constructs a set whose elements are the elements
of the sequence [xs] and the elements of the set [s].
It is equivalent to [union (of_seq xs) s].
Its time complexity is the combined time complexity of [of_seq] and
[union]. *)valadd_seq:eltSeq.t->set->set(**[to_seq s] constructs a (persistent) increasing sequence whose elements
are the elements of the set [s].
The time complexity of consuming the entire sequence is {m O(n)}, where
{m n} is the size of the set [s]. The worst-case time complexity of
demanding one element is {m O(\log n)}. *)valto_seq:set->eltSeq.t(**[to_seq_from x s] constructs a (persistent) increasing sequence whose
elements are the elements of the set [s] that are greater than or equal
to [x].
The time complexity of consuming the entire sequence is {m O(n)},
where {m n} is the size of the set [s]. The time complexity of
demanding one element is {m O(\log n)}. *)valto_seq_from:elt->set->eltSeq.t(**[to_rev_seq s] constructs a (persistent) decreasing sequence whose
elements are the elements of the set [s].
The time complexity of consuming the entire sequence is {m O(n)},
where {m n} is the size of the set [s]. The time complexity of
demanding one element is {m O(\log n)}. *)valto_rev_seq:set->eltSeq.t(** {1:iter Iterating, searching, transforming sets} *)(**[iter yield s] produces an increasing sequence whose elements are
the elements of the set [s].
This is achieved by applying the function [yield] in turn to each
element of the sequence.
Time complexity: {m O(n)},
where {m n} is the size of the set [s]. *)valiter:(elt->unit)->set->unit(**[fold yield s accu] produces an increasing sequence whose elements
are the elements of the set [s].
This is achieved by applying the function [yield] in turn to each
element of the sequence. An accumulator, whose initial value is
[accu], is threaded through this sequence of function invocations.
Time complexity: {m O(n)},
where {m n} is the size of the set [s]. *)valfold:(elt->'a->'a)->set->'a->'a(**[for_all p s] tests whether all elements [x] of the set [s]
satisfy [p x = true].
Time complexity: {m O(n)},
where {m n} is the size of the set [s]. *)valfor_all:(elt->bool)->set->bool(**[exists p s] tests whether at least one element [x] of the set [s]
satisfies [p x = true].
Time complexity: {m O(n)},
where {m n} is the size of the set [s]. *)valexists:(elt->bool)->set->bool(**[find_first f s] requires the function [f] to be a monotonically
increasing function of elements to Boolean values. It returns the
least element [x] of the set [s] such that [f x] is [true], if
there is such an element. If there is none, it raises [Not_found].
In other words, when the elements of the set are enumerated as an
increasing sequence, [find_first f s] returns the {i first} element
of the sequence that follows the threshold of the function [f].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valfind_first:(elt->bool)->t->elt(**[find_first_opt f s] requires the function [f] to be a monotonically
increasing function of elements to Boolean values. It returns [Some x],
where [x] is the least element of the set [s] such that [f x] is
[true], if there is such an element. If there is none, it returns
[None].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valfind_first_opt:(elt->bool)->t->eltoption(**[find_last f s] requires the function [f] to be a monotonically
decreasing function of elements to Boolean values. It returns the
greatest element [x] of the set [s] such that [f x] is [true], if
there is such an element. If there is none, it raises [Not_found].
In other words, when the elements of the set are enumerated as an
increasing sequence, [find_last f s] returns the {i last} element
of the sequence that precedes the threshold of the function [f].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valfind_last:(elt->bool)->t->elt(**[find_last_opt f s] requires the function [f] to be a monotonically
decreasing function of elements to Boolean values. It returns [Some x],
where [x] is the greatest element of the set [s] such that [f x] is
[true], if there is such an element. If there is none, it returns
[None].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valfind_last_opt:(elt->bool)->t->eltoption(**[map f s] computes the image of the set [s] through the function [f],
that is, in mathematical notation,
the set {m \{ y \mid y = f(x) \wedge x \in s \}}.
If, for every element [x] of the set [s],
[f x] is [x],
then the result is physically equal to [s].
If the function [f] is monotonically increasing,
then the time complexity is
{m O(n)}, where {m n} is the size of the set [s];
otherwise, it is {m O(n.\log n)}. *)valmap:(elt->elt)->set->set(**[filter p s] returns the set of the elements [x] of the set [s]
such that [p x] is [true].
If, for every element [x] of the set [s],
[p x] is [true],
then the result of [filter p s] is physically equal to [s].
Time complexity: {m O(n)},
where {m n} is the size of the set [s]. *)valfilter:(elt->bool)->set->set(**[filter_map f s] computes
the set {m \{ y \mid \mathit{Some}\; y = f(x) \wedge x \in s \}}.
If, for every element [x] of the set [s],
[f x] is [Some x],
then the result is physically equal to [s].
If the function [f]
(restricted to the elements that it retains)
is monotonically increasing,
then the time complexity is
{m O(n)}, where {m n} is the size of the set [s];
otherwise, it is {m O(n.\log n)}. *)valfilter_map:(elt->eltoption)->set->set(**[partition p s] returns a pair [(s1, s2)], where
[s1] is the set of the elements [x] of [s] such that
[p x] is [true], and [s2] is the set of the elements of
[s] such that [p x] is [false].
Time complexity: {m O(n)},
where {m n} is the size of the set [s]. *)valpartition:(elt->bool)->set->set*set(** {1:random Random access} *)(**{b Caution:} the following functions exist only in the
weight-balanced-tree implementation ({!Baby.W}).
In the height-balanced tree implementation ({!Baby.H}),
they raise an exception of the form [Failure _]. *)(**In the following descriptions, a set is viewed as an increasing
sequence of elements. Thus, the {i index} of an element is its
index in the sequence. The valid indices in a set [s] are the
integers in the semi-open interval of [0] to [cardinal s]. *)(**[get s i] requires [0 <= i && i < cardinal s]. It returns
the element that lies at index [i] in the set [s].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valget:set->int->elt(**If [x] is a member of the set [s], then [index x s] returns the index
[i] where this element lies in the set [s]. (Thus, [get s i] is [x].)
Otherwise, it raises [Not_found].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valindex:elt->set->int(**[cut s i] requires [0 <= i && i <= cardinal s]. It returns a pair
[(s1, s2)], where [s1] is the set of the elements of [s] whose index
is less than [i], and [s2] is the set of the elements of [s] whose
index is greater than or equal to [i].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valcut:set->int->set*set(**[cut_and_get s i] requires [0 <= i && i < cardinal s]. It returns a
triple [(s1, x, s2)], where [s1] is the set of the elements of [s]
whose index is less than [i], [x] is the element of [s] at index [i],
and [s2] is the set of the elements of [s] whose index is greater
than [i].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valcut_and_get:set->int->set*elt*set(** {1:enum Enumerations} *)(**The submodule {!Enum} offers an abstract data type of {i enumerations},
which allow efficient iteration over a set. *)moduleEnum:sig(**The type of enumerations. An enumeration an immutable data structure.
An enumeration represents an increasing sequence of elements. It can
also be thought of as a set.
Enumerations and sets represent the same abstract object (namely, a
mathematical set), but have different internal representations, and
support a different array of operations. In particular, enumerations
support {!head}, {!tail}, and {!from}, which allow efficient
iteration. *)typeenum(**The type [t] is a synonym for the type [enum]. *)typet=enum(**[empty] is the empty enumeration. *)valempty:enum(**[is_empty e] determines whether the enumeration [e] is empty.
Time complexity: {m O(1)}. *)valis_empty:enum->bool(**[enum s] returns an enumeration of the set [s]. This enumeration
can be thought of as an increasing sequence whose elements are
the elements of the set [s].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valenum:set->enum(**[from_enum x s] returns an enumeration whose elements are the
elements of the set [s] that are greater than or equal to [x].
It is equivalent to [from x (enum s)].
Time complexity: {m O(\log n)},
where {m n} is the size of the set [s]. *)valfrom_enum:elt->set->enum(**If the enumeration [e] is nonempty, then [head e] returns its first
element (that is, its least element). Otherwise, it raises [Not_found].
Time complexity: {m O(1)}. *)valhead:enum->elt(**If the enumeration [e] is nonempty, then [tail e] returns this
enumeration, deprived of its first element (that is, its least
element). Otherwise, it raises [Not_found].
The worst-case time complexity of this operation is {m O(\log n)},
where {m n} is the size of the enumeration [e].
However, its amortized time complexity is only {m O(1)}: that is,
the cost of enumerating all elements of a set of size {m n},
using [head] and [tail], is only {m O(n)}. *)valtail:enum->enum(**If the enumeration [e] is nonempty, then [head_opt e] returns its first
element (that is, its least element). Otherwise, it returns [None].
Time complexity: {m O(1)}. *)valhead_opt:enum->eltoption(**If the enumeration [e] is nonempty, then [tail_opt e] returns this
enumeration, deprived of its first element (that is, its least
element). Otherwise, it returns [None].
The worst-case time complexity of this operation is {m O(\log n)},
where {m n} is the size of the enumeration [e].
However, its amortized time complexity is only {m O(1)}: that is,
the cost of enumerating all elements of a set of size {m n},
using [head_opt] and [tail_opt], is only {m O(n)}. *)valtail_opt:enum->enumoption(**[from x e] returns the enumeration obtained from the enumeration [e]
by skipping (removing) the elements that are less than [x].
Time complexity: {m O(\log k)},
where {m k} is the number of elements that are skipped. *)valfrom:elt->enum->enum(**[to_seq e] constructs a (persistent) increasing sequence whose elements
are the elements of the enumeration [e].
The time complexity of consuming the entire sequence is {m O(n)}, where
{m n} is the size of the enumeration [e]. The worst-case time
complexity of demanding one element is {m O(\log n)}. *)valto_seq:enum->eltSeq.t(**[elements e] returns a set whose elements are the elements of the
enumeration [e].
Time complexity: {m O(\log n)},
where {m n} is the size of the enumeration [e]. *)valelements:enum->set(**[length e] returns the length of the enumeration [e],
that is, the number of its elements.
Time complexity:
in the weight-balanced-tree implementation ({!Baby.W}),
{m O(\log n)},
where {m n} is the size of the enumeration [e];
in the height-balanced-tree implementation ({!Baby.H}),
{m O(n)}. *)vallength:enum->intend(* Enum *)(**/**)(* The function [check] is used while testing the library.
If the library is built in release mode, this function
has no effect. *)valcheck:set->unit(**/**)end(* SET *)