2 * Build a set using a red-black tree.
3 * Every node in the tree is colored either black or red.
4 * A red-black tree has the following invariants:
5 * 1. Every leaf is colored black
6 * 2. All children of every red node are black.
7 * 3. Every path from the root to a leaf has the
8 * same number of black nodes as every other path.
9 * 4. The root is always black.
11 * We get some corollaries:
12 * 1. The longest path from the root to a leaf is
13 * at most twice as long as the shortest path.
14 * 2. Both children of a red node are either leaves,
15 * or they are both not.
17 * This code is meant to be fast, so all the cases have
18 * been expanded, and the insert and delete functions are
19 * long (12 cases for insert, 18 for delete in lift_black).
21 * ----------------------------------------------------------------
23 * This file is part of MetaPRL, a modular, higher order
24 * logical framework that provides a logical programming
25 * environment for OCaml and other languages.
27 * See the file doc/htmlman/default.html or visit http://metaprl.org/
28 * for more information.
30 * Copyright (C) 1998-2005 PRL Group, Cornell University and Caltech
32 * This library is free software; you can redistribute it and/or
33 * modify it under the terms of the GNU Lesser General Public
34 * License as published by the Free Software Foundation,
35 * version 2.1 of the License.
37 * This library is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
40 * Lesser General Public License for more details.
42 * You should have received a copy of the GNU Lesser General Public
43 * License along with this library; if not, write to the Free Software
44 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
46 * Additional permission is given to link this library with the
47 * OpenSSL project's "OpenSSL" library, and with the OCaml runtime,
48 * and you may distribute the linked executables. See the file
49 * LICENSE.libmojave for more details.
51 * Author: Jason Hickey
60 module LmMake
(Ord
: OrderedType
) =
62 (************************************************************************
64 ************************************************************************)
69 * Table is a binary tree.
70 * Color is kept in the label to save space.
75 | Red
of elt
* tree
* tree
* int
76 | Black
of elt
* tree
* tree
* int
80 * The tree is always balanced, so we don't need
81 * extra mutable fields.
94 * Exception for unchanged tree during insertion.
98 (************************************************************************
100 ************************************************************************)
105 let cardinality = function
107 | Black
(_
, _
, _
, size
) ->
115 let new_black key left right
=
116 Black
(key
, left
, right
, cardinality left
+ cardinality right
+ 1)
118 let new_red key left right
=
119 Red
(key
, left
, right
, cardinality left
+ cardinality right
+ 1)
121 (************************************************************************
123 ************************************************************************)
128 let rec pp_print_tree out tree
=
130 Black
(_
, left
, right
, size
) ->
131 fprintf out
"@[<v 3>Black(%d):@ %a@ %a@]" size
pp_print_tree left
pp_print_tree right
132 | Red
(_
, left
, right
, size
) ->
133 fprintf out
"@[<v 3>Red(%d):@ %a@ %a@]" size
pp_print_tree left
pp_print_tree right
137 let print_tree = pp_print_tree stdout
140 * Check the size of the set.
142 let check_size tree
=
144 printf
"%a@\n%a@\n" pp_print_tree tree
pp_print_tree tree'
;
145 raise
(Invalid_argument
"check_size")
149 Black
(_
, left
, right
, size
) ->
150 if size
<> check left
+ check right
+ 1 then
154 | Red
(_
, left
, right
, size
) ->
155 if size
<> check left
+ check right
+ 1 then
165 * Check the red-invariant.
167 let rec check_red = function
169 | Red
(_
, _
, Red _
, _
) ->
170 raise
(Failure
"Lm_set.check_red")
171 | Red
(_
, left
, right
, _
)
172 | Black
(_
, left
, right
, _
) ->
179 * Check the black invariant.
181 let rec black_depth i
= function
182 Black
(_
, left
, _
, _
) ->
183 black_depth (succ i
) left
184 | Red
(_
, left
, _
, _
) ->
189 let rec check_black_aux i j
= function
190 Black
(_
, left
, right
, _
) ->
191 check_black_aux i
(succ j
) left
;
192 check_black_aux i
(succ j
) right
193 | Red
(_
, left
, right
, _
) ->
194 check_black_aux i j left
;
195 check_black_aux i j right
198 raise
(Failure
"Lm_set.check_black")
200 let check_black tree
=
201 check_black_aux (black_depth 0 tree
) 0 tree
204 * Check that all the nodes are sorted.
206 let rec check_sort_lt key
= function
207 Black
(key'
, left
, right
, _
)
208 | Red
(key'
, left
, right
, _
) ->
209 if Ord.compare key' key
>= 0 then
210 raise
(Failure
"Lm_set.check_sort");
211 check_sort_lt key' left
;
212 check_sort_gt_lt key' key right
217 and check_sort_gt key
= function
218 Black
(key'
, left
, right
, _
)
219 | Red
(key'
, left
, right
, _
) ->
220 if Ord.compare key' key
<= 0 then
221 raise
(Failure
"Lm_set.check_sort");
222 check_sort_gt_lt key key' left
;
223 check_sort_gt key right
228 and check_sort_gt_lt key key'
= function
229 Black
(key''
, left
, right
, _
)
230 | Red
(key''
, left
, right
, _
) ->
231 if Ord.compare key'' key
<= 0 || Ord.compare key'' key'
>= 0 then
232 raise
(Failure
"Lm_set.check_sort");
233 check_sort_gt_lt key key'' left
;
234 check_sort_gt_lt key'' key' right
239 let check_sort = function
240 Black
(key
, left
, right
, _
) ->
241 check_sort_lt key left
;
242 check_sort_gt key right
244 raise
(Failure
"Lm_set.check_sort: root is red")
249 * Perform all the checks.
260 (************************************************************************
262 ************************************************************************)
265 * Insert an entry into the tree.
267 let rec insert key
= function
268 Black
(key0
, left0
, right0
, size0
) ->
270 let comp = Ord.compare key key0
in
273 else if comp < 0 then
278 * Ok even if child becomes red.
280 Black
(key0
, insert key left0
, right0
, succ size0
)
282 | Red
(key1
, left1
, right1
, size1
) ->
283 let comp = Ord.compare key key1
in
286 else if comp < 0 then
287 match insert key left1
, right0
with
288 Red
_ as node
, Red
(key2
, left2
, right2
, size2
) ->
294 * key1:r key2:r key1:b key2:b
296 * key2:r right1 key2:r right1
299 Black
(key1
, node
, right1
, succ size1
),
300 Black
(key2
, left2
, right2
, size2
),
302 | Red
_ as node
, _ ->
308 * key1:r key2:b key3:r key0:b
310 * key3:r right1 right1 key2:r
314 new_red key0 right1 right0
,
322 * key1:r key2 key1:r key2
324 * key3:b right1 key3:b right1
327 new_red key1 node right1
,
331 match insert key right1
, right0
with
332 Red
_ as node
, Red
(key2
, left2
, right2
, size2
) ->
338 * key1:r key2:r key1:b key2:b
340 * left1 node:r left1 node:r
343 Black
(key1
, left1
, node
, succ size1
),
344 Black
(key2
, left2
, right2
, size2
),
346 | Red
(key3
, left3
, right3
, _), _ ->
352 * key1:r right0 key1:r key0:r
354 * left1 key3:r left1 left3 right3 right0
359 new_red key1 left1 left3
,
360 new_red key0 right3 right0
,
373 new_red key1 left1 node3
,
382 * Node can be replaced even if it becomes red.
384 Black
(key0
, left0
, insert key right0
, succ size0
)
386 | Red
(key2
, left2
, right2
, size2
) ->
387 let comp = Ord.compare key key2
in
390 else if comp < 0 then
391 match left0
, insert key left2
with
392 Red
(key1
, left1
, right1
, size1
), (Red
_ as node
) ->
398 * key1:r key2:r key1:b key2:b
400 * node:r right2 node:r right2
403 Black
(key1
, left1
, right1
, size1
),
404 Black
(key2
, node
, right2
, succ size2
),
406 | _, Red
(key3
, left3
, right3
, _) ->
412 * key1:b key2:r key0:r key2:r
414 * key3:r right2 left0 left3 right3 right2
419 new_red key0 left0 left3
,
420 new_red key2 right3 right2
,
434 new_red key2 node3 right2
,
437 match left0
, insert key right2
with
438 Red
(key1
, left1
, right1
, size1
), (Red
_ as node
) ->
444 * key1:r key2:r key1:b key2:b
446 * left2 node:r left2 node:r
449 Black
(key1
, left1
, right1
, size1
),
450 Black
(key2
, left2
, node
, succ size2
),
452 | _, (Red
_ as node
) ->
458 * left0:b key2:r key0:r node:r
460 * left2 node:r left0:b left2
463 new_red key0 left0 left2
,
478 new_red key2 left2 node3
,
482 (* Leaf is colored red *)
483 Red
(key
, Leaf
, Leaf
, 1)
486 (* Red nodes will not come up *)
487 raise
(Invalid_argument
"Lm_set.insert")
490 let insert key tree =
491 try insert key tree with
492 (Invalid_argument _) as exn ->
499 * Add an element to the set.
501 let add t key
= match t
with
503 Black
(key
, Leaf
, Leaf
, 1)
506 match insert key node
with
507 Red
(key
, left
, right
, size
) ->
508 Black
(key
, left
, right
, size
)
515 let add_list set keys
=
516 List.fold_left
add set keys
518 (************************************************************************
520 ************************************************************************)
523 * Construct a path during the removal.
525 let rec delete key path node
=
527 Black
(key'
, left
, right
, _) ->
528 let comp = Ord.compare key key'
in
530 match left
, right
with
532 lift_black key path Leaf
533 | Red
(key
, left
, right
, size
), Leaf
->
534 lift key path
(Black
(key
, left
, right
, size
))
536 delete_min
(Delete node
:: path
) right
537 else if comp < 0 then
538 delete key
(Left node
:: path
) left
540 delete key
(Right node
:: path
) right
541 | Red
(key'
, left
, right
, _) ->
542 let comp = Ord.compare key key'
in
548 delete_min
(Delete node
:: path
) right
549 else if comp < 0 then
550 delete key
(Left node
:: path
) left
552 delete key
(Right node
:: path
) right
556 and delete_min path node
=
558 Black
(key
, Leaf
, Leaf
, _) ->
559 lift_black key path Leaf
560 | Black
(key
, Leaf
, Red
(key'
, left
, right
, size
), _) ->
561 lift key path
(Black
(key'
, left
, right
, size
))
562 | Red
(key
, Leaf
, Leaf
, _) ->
564 | Black
(_, left
, _, _) ->
565 delete_min
(Left node
:: path
) left
566 | Red
(_, left
, _, _) ->
567 delete_min
(Left node
:: path
) left
572 * Copy the tree with no need to propagate black.
574 and lift key path node
=
575 match path
, node
with
576 Left
(Black
(key0
, _, right0
, size0
)) :: path
, left
->
577 lift key path
(Black
(key0
, left
, right0
, pred size0
))
578 | Left
(Red
(key0
, _, right0
, size0
)) :: path
, left
->
579 lift key path
(Red
(key0
, left
, right0
, pred size0
))
580 | Right
(Black
(key0
, left0
, _, size0
)) :: path
, right
->
581 lift key path
(Black
(key0
, left0
, right
, pred size0
))
582 | Right
(Red
(key0
, left0
, _, size0
)) :: path
, right
->
583 lift key path
(Red
(key0
, left0
, right
, pred size0
))
584 | Delete
(Black
(_, left0
, _, size0
)) :: path
, right
->
585 lift key path
(Black
(key
, left0
, right
, pred size0
))
586 | Delete
(Red
(_, left0
, _, size0
)) :: path
, right
->
587 lift key path
(Red
(key
, left0
, right
, pred size0
))
592 | Delete Leaf
:: _, _ ->
593 raise
(Invalid_argument
"lift")
596 * Propagate the extra black up the tree.
598 and lift_black key path node
=
599 match path
, node
with
600 Left
(Black
(key0
, _, right0
, size0
)) :: path
, left
->
603 Black
(key2
, left2
, right2
, size2
) ->
605 match left2
, right2
with
606 _, Red
(key3
, left3
, right3
, size3
) ->
610 * left:bb key2:b key0:b right2:b
612 * left2 right2:r left:b left2
616 new_black key0 left left2
,
617 Black
(key3
, left3
, right3
, size3
),
620 | Red
(key3
, left3
, right3
, _), _ ->
624 * left:bb key2:b key0:b key2:b
626 * key3:r right2:b left:b left3 right3 right2:b
632 new_black key0 left left3
,
633 new_black key2 right3 right2
,
640 * left:bb key2:b left:b key2:r
642 * left2:b right2:b left2:b right2:b
644 lift_black key path
(**)
647 Red
(key2
, left2
, right2
, size2
),
651 | Red
(key2
, left2
, right2
, _) ->
654 Black
(key3
, Red
(key4
, left4
, right4
, _), d
, _) ->
658 * left:bb key2:r key4:r right2:b
660 * key3:b right2:b key0:b key3:b
662 * key4:r d left:b left4 right4 d
669 (new_black key0 left left4
)
670 (new_black key3 right4 d
),
674 | Black
(key3
, c
, Red
(key4
, left4
, right4
, size4
), _) ->
678 * left:bb key2:r key3:r right2
680 * key3:b right2 key0:b key4:b
687 (new_black key0 left c
)
688 (Black
(key4
, left4
, right4
, size4
)),
692 | Black
(key3
, c
, d
, _) ->
696 * left:bb key2:r key0:b right2:b
698 * key3:b right2:b left:b key3:r
704 new_black key0 left
(new_red key3 c d
),
710 raise
(Invalid_argument
"lift_black1")
714 raise
(Invalid_argument
"lift_black2")
717 | Right
(Black
(key0
, left0
, _, size0
)) :: path
, right
->
720 Black
(key1
, left1
, right1
, size1
) ->
722 match left1
, right1
with
723 Red
(key3
, left3
, right3
, size3
), _ ->
727 * key1:b right:bb left1:b key0:b
729 * left1:r right1 right1 right:b
733 Black
(key3
, left3
, right3
, size3
),
734 new_black key0 right1 right
,
737 | _, Red
(key3
, left3
, right3
, _) ->
741 * key1:b right:bb key1:b key0:b
743 * left1:b key3:r left1:b left3 right3 right
749 new_black key1 left1 left3
,
750 new_black key0 right3 right
,
757 * key1:b right:bb key1:r right:bb
759 * left1:b right1:b left1:b right1:b
761 lift_black key path
(**)
763 Red
(key1
, left1
, right1
, size1
),
769 | Red
(key1
, left1
, right1
, _) ->
772 Black
(key3
, d
, Red
(key4
, left4
, right4
, _), _) ->
776 * key1:r right:bb left1:b key4:r
778 * left1:b key3:b key3:b key0:b
780 * d key4:r d left4 right4 right:b
788 (new_black key3 d left4
)
789 (new_black key0 right4 right
),
792 | Black
(key3
, Red
(key4
, left4
, right4
, size4
), c
, _) ->
796 * key1:r right:bb left1 key3:r
798 * left1 key3:b key4:b key0:b
806 (Black
(key4
, left4
, right4
, size4
))
807 (new_black key0 c right
),
810 | Black
(key3
, c
, d
, size3
) ->
814 * key1:r right:bb left1 key0:b
816 * left1 key3:b key3:r right:b
823 new_black key0
(Red
(key3
, c
, d
, size3
)) right
,
828 raise
(Invalid_argument
"lift_black3")
832 raise
(Invalid_argument
"lift_black4")
835 | Left
(Red
(key0
, _, right0
, size0
)) :: path
, left
->
838 Black
(key2
, left2
, right2
, size2
) ->
840 match left2
, right2
with
841 _, Red
(key3
, left3
, right3
, size3
) ->
845 * left:bb key2:b key0:b right2:b
847 * left2:b right2:r left:b left2:b
851 new_black key0 left left2
,
852 Black
(key3
, left3
, right3
, size3
),
855 | Red
(key3
, left3
, right3
, _), _ ->
859 * left:bb key2:b key0:r key2:r
861 * key3:r right2 left:b left3 right3 right2
867 new_red key0 left left3
,
868 new_red key2 right3 right2
,
875 * left:bb key2:b left:b key2:r
877 * left2:b right2:b left2:b right2:b
882 Red
(key2
, left2
, right2
, size2
),
887 raise
(Invalid_argument
"lift_black5")
890 | Right
(Red
(key0
, left0
, _, size0
)) :: path
, right
->
893 Black
(key1
, left1
, right1
, size1
) ->
895 match left1
, right1
with
896 Red
(key3
, left3
, right3
, size3
), _ ->
900 * key1:b right:bb left1:b key0:b
902 * left1:r right1 right1 right:b
906 Black
(key3
, left3
, right3
, size3
),
907 new_black key0 right1 right
,
910 | _, Red
(key3
, left3
, right3
, _) ->
914 * key1:b right:bb key1:r key0:r
916 * left1 key3:r left1 left3 right3 right:b
922 new_red key1 left1 left3
,
923 new_red key0 right3 right
,
930 * key1:b right:bb key1:r right:b
932 * left1:b right1:b left1:b right1:b
936 Red
(key1
, left1
, right1
, size1
),
943 raise
(Invalid_argument
"lift_black6")
946 | Delete
(Black
(_, left0
, right0
, size0
)) :: path
, node
->
947 lift_black key
(Right
(Black
(key
, left0
, right0
, size0
)) :: path
) node
949 | Delete
(Red
(_, left0
, right0
, size0
)) :: path
, node
->
950 lift_black key
(Right
(Red
(key
, left0
, right0
, size0
)) :: path
) node
957 | Delete Leaf
:: _, _ ->
958 raise
(Invalid_argument
"lift_black7")
963 let remove tree key
=
964 try delete key
[] tree
with
968 let subtract_list tree keys
=
969 List.fold_left
remove tree keys
971 (************************************************************************
972 * UNION & INTERSECTION *
973 ************************************************************************)
976 * Get the elements of the list.
978 let rec to_list_aux elements
= function
979 Black
(key
, left
, right
, _)
980 | Red
(key
, left
, right
, _) ->
981 to_list_aux (key
:: to_list_aux elements right
) left
985 let to_list = to_list_aux []
987 let elements = to_list
989 let rec reverse elements = function
991 reverse (h
:: elements) t
995 let rec merge elements elements1 elements2
=
996 match elements1
, elements2
with
997 key1
:: tl1
, key2
:: tl2
->
998 let comp = Ord.compare key1 key2
in
1000 merge (key1
:: elements) tl1 tl2
1001 else if comp < 0 then
1002 merge (key1
:: elements) tl1 elements2
1004 merge (key2
:: elements) elements1 tl2
1006 reverse elements1
elements
1008 reverse elements2
elements
1014 if 1 lsl i
>= x
then
1020 * Build a set from a list.
1023 if 1 lsl i
>= j
then
1028 let rec of_sorted_array depth max_depth
elements off len
=
1030 if depth
= max_depth
then
1031 Red
(elements.(off
), Leaf
, Leaf
, 1)
1033 Black
(elements.(off
), Leaf
, Leaf
, 1)
1034 else if len
= 2 then
1035 Black
(elements.(off
+ 1), Red
(elements.(off
), Leaf
, Leaf
, 1), Leaf
, 2)
1037 let len2 = len
lsr 1 in
1038 Black
(elements.(off
+ len2),
1039 of_sorted_array (succ depth
) max_depth
elements off
len2,
1040 of_sorted_array (succ depth
) max_depth
elements (off
+ len2 + 1) (len
- len2 - 1),
1043 let of_sorted_list = function
1047 Black
(key
, Leaf
, Leaf
, 1)
1049 let elements = Array.of_list
elements in
1050 let length = Lm_array_util.distinct compare
elements in
1051 let max_depth = pred
(log2 1 (succ
length)) in
1052 of_sorted_array 0 max_depth elements 0 length
1055 * Convert to a list.
1057 let rec to_list_aux l
= function
1058 Black
(key
, left
, right
, _)
1059 | Red
(key
, left
, right
, _) ->
1060 to_list_aux (key
:: to_list_aux l right
) left
1068 * Union flattens the two trees,
1069 * merges them, then creates a new tree.
1071 let rec union_aux s1
= function
1072 Black
(key
, left
, right
, _)
1073 | Red
(key
, left
, right
, _) ->
1074 union_aux (add (union_aux s1 left
) key
) right
1079 let size1 = cardinality s1
in
1080 let size2 = cardinality s2
in
1081 if size1 < size2 then
1087 * See if two sets intersect.
1089 let rec intersect_aux elems1 elems2
=
1090 match elems1
, elems2
with
1091 elem1
:: elems1'
, elem2
:: elems2'
->
1092 let comp = Ord.compare elem1 elem2
in
1095 else if comp < 0 then
1096 intersect_aux elems1' elems2
1098 intersect_aux elems1 elems2'
1103 let intersectp s1 s2
=
1104 intersect_aux (to_list s1
) (to_list s2
)
1106 (************************************************************************
1108 ************************************************************************)
1111 * Search without reorganizing the tree.
1113 let rec mem t key
= match t
with
1114 Black
(key'
, left
, right
, _)
1115 | Red
(key'
, left
, right
, _) ->
1116 let comp = Ord.compare key key'
in
1119 else if comp < 0 then
1128 * An empty tree is just a leaf.
1132 let is_empty = function
1139 Black
(key
, Leaf
, Leaf
, 1)
1142 List.fold_left
(fun set item
-> add set item
) empty l
1145 * Iterate a function over the hashtable.
1147 let rec iter f
= function
1148 Black
(key
, left
, right
, _)
1149 | Red
(key
, left
, right
, _) ->
1157 * Fold a function over the subrange of the set
1159 let rec range_fold range f arg
= function
1160 Black
(key
, left
, right
, _)
1161 | Red
(key
, left
, right
, _) ->
1162 let c = range key
in
1164 range_fold range f arg right
1166 range_fold range f arg left
1168 let arg = range_fold range f
arg left
in
1169 let arg = f
arg key
in
1170 range_fold range f
arg right
1175 * Fold a function over the set.
1177 let rec fold f
arg = function
1178 Black
(key
, left
, right
, _)
1179 | Red
(key
, left
, right
, _) ->
1180 let arg = fold f
arg left
in
1181 let arg = f
arg key
in
1189 let rec equal set1 set2
=
1190 if cardinality set1
= cardinality set2
then
1191 let list1 = to_list set1
in
1192 let list2 = to_list set2
in
1193 List.for_all2
(fun x y
-> Ord.compare x y
= 0) list1 list2
1198 * BUG: these functions are too slow!
1199 * Could be much more optimized.
1209 let size1 = cardinality s1
in
1210 let size2 = cardinality s2
in
1212 if size1 < size2 then
1223 let partition pred s
=
1224 fold (fun (s1, s2
) x
->
1228 s1, add s2 x
) (empty, empty) s
1230 let rec diff s
= function
1231 Black
(key
, left
, right
, _)
1232 | Red
(key
, left
, right
, _) ->
1233 let s = remove s key
in
1234 let s = diff s left
in
1239 let rec subset s1 s2
=
1241 Black
(key
, left
, right
, _)
1242 | Red
(key
, left
, right
, _) ->
1243 mem s2 key
&& subset left s2
&& subset right s2
1247 let is_subset = subset
1250 let rec compare s1 s2
=
1252 x1
:: s1, x2
:: s2
->
1253 let cmp = Ord.compare x1 x2
in
1265 compare (to_list s1) (to_list s2
)
1270 let rec min_elt = function
1271 Black
(key
, Leaf
, _, _)
1272 | Red
(key
, Leaf
, _, _) ->
1274 | Black
(_, left
, _, _)
1275 | Red
(_, left
, _, _) ->
1280 let rec max_elt = function
1281 Black
(key
, _, Leaf
, _)
1282 | Red
(key
, _, Leaf
, _) ->
1284 | Black
(_, _, right
, _)
1285 | Red
(_, _, right
, _) ->
1290 let choose = min_elt
1295 let rec for_all pred
= function
1296 Black
(key
, left
, right
, _)
1297 | Red
(key
, left
, right
, _) ->
1298 pred key
&& for_all pred left
&& for_all pred right
1302 let rec exists pred
= function
1303 Black
(key
, left
, right
, _)
1304 | Red
(key
, left
, right
, _) ->
1305 pred key
|| exists pred left
|| exists pred right
1312 let cardinal = cardinality
1315 * Filtering operations.
1317 let rec mem_filt s = function
1322 let rem = mem_filt s t
in
1330 let rec not_mem_filt s = function
1337 let rem = not_mem_filt s t
in
1343 let rec fst_mem_filt s = function
1346 | (((v
, _) as h
) :: t
) as l
->
1348 let rem = fst_mem_filt s t
in
1357 module LmMakeDebug
(Ord
: OrderedTypeDebug
) =
1359 module XSet
= LmMake
(Ord
)
1366 let rec pp_print out tree
=
1369 Black
(key
, left
, right
, size
) ->
1370 fprintf out
"(@[<hv 0>Black@ %a:%d %a %a)@]" (**)
1376 | Red
(key
, left
, right
, size
) ->
1377 fprintf out
"(@[<hv 0>Red@ %a:%d %a %a)@]" (**)
1384 output_string out
"Leaf"
1386 let print = pp_print
1389 module Make
(Ord
: OrderedType
) : S
with type elt
= Ord.t
=
1391 module XSet
= LmMake
(Ord
)
1405 XSet.fold (fun x y
-> f y x
) x
s
1408 fst
(XSet.partition f
s)
1414 * Caml-master: "compile"