(* Red-black trees according to the following classic paper: Chris Okasaki, Red-Black Trees in a Functional Setting. J. Funct. Program. 9(4): 471-477 (1999) *) type colour = Red | Black type 'a t = private Ext | Int of colour * 'a t * 'a * 'a t val empty: 'a t val is_empty: 'a t -> bool (* The value of the call [add ~cmp choice x t] is a red-black tree augmenting the tree [t] with a node containing the element [x], using the comparison function [cmp] (following the same convention as [Pervasives.compare]) and, if a value [y] such that [x = y] is already present in a node of [t], then the value [choice] denotes whether [x] ([New]) or [y] ([Old]) remains in the value of the call. Moreover, if [x == y], then [add ~cmp choice x t == t]. *) type choice = Old | New val add: cmp:('a -> 'a -> int) -> choice -> 'a -> 'a t -> 'a t (* The value of the call [remove ~cmp x t] is a red-black tree containing the same elements as [t] with the exception of the element identified by [x]. The type of [x] can be different from that of the elements of the tree, for example if the tree is used to implement a map, x would be a [key], whereas the elements of the tree would be [key, value] pairs. *) val remove: cmp:('a -> 'b -> int) -> 'a -> 'b t -> 'b t (* The value of the call [find ~cmp x t] is the element [y] belonging to a node of the tree [t], such that [cmp x y = true]. If none, the exception [Not_found] is raised. *) val find: cmp:('a -> 'b -> int) -> 'a -> 'b t -> 'b (* The value of call [find_opt ~cmp x t] is [Some y] if there is an element [y] in a node of the tree [t] such that [cmp x y = true], and [None] otherwise. *) val find_opt: cmp:('a -> 'b -> int) -> 'a -> 'b t -> 'b option (* The value of the call [elements t] is the list of elements in the nodes of the tree [t], sorted by increasing order. *) val elements: 'a t -> 'a list (* The side-effect of evaluating the call [iter f t] is the successive side-effects of the calls [f x], for all elements [x] belonging to the nodes of [t], visited in increasing order. *) val iter: ('a -> unit) -> 'a t -> unit (* The value of the call [fold_inc f ~init t] is the iteration of the function [f] on increasing elements of the nodes of tree [t], accumulating the partial results from the initial value of [init]. *) val fold_inc: (elt:'a -> acc:'b -> 'b) -> init:'b -> 'a t -> 'b (* The value of the call [fold_dec f ~init t] is the iteration of the function [f] on decreasing elements of the nodes of tree [t], accumulating the partial results from the initial value of [init]. *) val fold_dec: (elt:'a -> acc:'b -> 'b) -> init:'b -> 'a t -> 'b