From de1f112320ba021c5f4dea1af9e5f90b1e5afe34 Mon Sep 17 00:00:00 2001 From: public-release Date: Thu, 21 Nov 2024 20:31:32 +0000 Subject: [PATCH] v0.18~preview.130.05+548 --- composition_infix/README.md | 2 + composition_infix/src/composition_infix.ml | 2 + composition_infix/src/composition_infix.mli | 7 + composition_infix/src/dune | 5 + lint/ppx_base_lint.ml | 7 +- ppx/src/ppx_base_internal.ml | 2 +- src/comparable_intf.ml | 4 +- src/comparisons.ml | 4 +- src/dictionary_immutable_intf.ml | 11 + src/hash_set.ml | 1 + src/hash_set_intf.ml | 1 + src/int.ml | 8 + src/int32.ml | 8 + src/int63_emul.ml | 8 + src/int64.ml | 141 +- src/int_conversions.ml | 22 +- src/int_intf.ml | 8 + src/map.ml | 1436 ++++++------- src/map_intf.ml | 8 + src/nativeint.ml | 8 + src/option.ml | 27 +- src/option.mli | 8 +- src/ppx_compare_lib.ml | 117 +- src/ppx_compare_lib.mli | 183 +- src/ppx_compare_lib_intf.ml | 190 ++ src/set.ml | 462 ++-- src/source_code_position.ml | 19 +- src/source_code_position0.ml | 13 + test/allocation/test_option_allocation.ml | 5 +- test/coverage/map/constructor.ml | 724 ++++--- test/coverage/map/functor.ml | 16 + test/coverage/set/constructor.ml | 2 +- test/dune | 2 +- test/test_map.ml | 88 +- test/test_map_and_set_internals.ml | 2152 ++++--------------- test/test_option.ml | 11 + test/test_set.ml | 30 +- 37 files changed, 2286 insertions(+), 3456 deletions(-) create mode 100644 composition_infix/README.md create mode 100644 composition_infix/src/composition_infix.ml create mode 100644 composition_infix/src/composition_infix.mli create mode 100644 composition_infix/src/dune create mode 100644 src/ppx_compare_lib_intf.ml diff --git a/composition_infix/README.md b/composition_infix/README.md new file mode 100644 index 0000000..a21571f --- /dev/null +++ b/composition_infix/README.md @@ -0,0 +1,2 @@ +A single-module library for defining infix composition operators `<<` +and `>>`. diff --git a/composition_infix/src/composition_infix.ml b/composition_infix/src/composition_infix.ml new file mode 100644 index 0000000..72a401c --- /dev/null +++ b/composition_infix/src/composition_infix.ml @@ -0,0 +1,2 @@ +let ( >> ) f g x = g (f x) +let ( << ) f g x = f (g x) diff --git a/composition_infix/src/composition_infix.mli b/composition_infix/src/composition_infix.mli new file mode 100644 index 0000000..ff2da80 --- /dev/null +++ b/composition_infix/src/composition_infix.mli @@ -0,0 +1,7 @@ +(** Infix composition operators. + + - [ a |> (f >> g) = a |> f |> g ] + - [ (f << g) a = f (g a) ] *) + +val ( >> ) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c +val ( << ) : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c diff --git a/composition_infix/src/dune b/composition_infix/src/dune new file mode 100644 index 0000000..2759885 --- /dev/null +++ b/composition_infix/src/dune @@ -0,0 +1,5 @@ +(library + (name composition_infix) + (public_name base.composition_infix) + (preprocess no_preprocessing) + (libraries)) diff --git a/lint/ppx_base_lint.ml b/lint/ppx_base_lint.ml index ab2e1c0..153bf5c 100644 --- a/lint/ppx_base_lint.ml +++ b/lint/ppx_base_lint.ml @@ -181,9 +181,10 @@ let () = | { pstr_loc = loc; _ } :: _ as st -> (check (module_of_loc loc))#structure st; st) - ~intf:(function - | [] -> [] - | { psig_loc = loc; _ } :: _ as sg -> + ~intf:(fun sg -> + match sg.psg_items with + | [] -> sg + | { psig_loc = loc; _ } :: _ -> (check (module_of_loc loc))#signature sg; sg) ;; diff --git a/ppx/src/ppx_base_internal.ml b/ppx/src/ppx_base_internal.ml index 5afa906..bd2c4ae 100644 --- a/ppx/src/ppx_base_internal.ml +++ b/ppx/src/ppx_base_internal.ml @@ -3,7 +3,7 @@ open Ppxlib module Specialize_polymorphic_compare = struct let signature ~loc = - [%sig: + [%sigil: [@@@ocaml.ppwarning "ppx_base_internal: intended only for use inside Base"] external ( = ) : (t[@local_opt]) -> (t[@local_opt]) -> bool = "%equal" diff --git a/src/comparable_intf.ml b/src/comparable_intf.ml index 9f76507..c661162 100644 --- a/src/comparable_intf.ml +++ b/src/comparable_intf.ml @@ -75,7 +75,9 @@ module type With_zero = sig end module type S = sig - include Comparisons + type t + + include Comparisons with type t := t (** [ascending] is identical to [compare]. [descending x y = ascending y x]. These are intended to be mnemonic when used like [List.sort ~compare:ascending] and [List.sort diff --git a/src/comparisons.ml b/src/comparisons.ml index 63d1d90..2260a10 100644 --- a/src/comparisons.ml +++ b/src/comparisons.ml @@ -2,8 +2,8 @@ open! Import -(** [Infix] lists the typical infix comparison operators. These functions are provided by - [.O] modules, i.e., modules that expose monomorphic infix comparisons over some +(** [Infix] lists the typical infix comparison operators. These functions are provided + by [.O] modules, i.e., modules that expose monomorphic infix comparisons over some [.t]. *) module type Infix = sig type t diff --git a/src/dictionary_immutable_intf.ml b/src/dictionary_immutable_intf.ml index 21a148a..1075362 100644 --- a/src/dictionary_immutable_intf.ml +++ b/src/dictionary_immutable_intf.ml @@ -284,6 +284,17 @@ module Definitions = struct , 'phantom ) transformer + (** Like [update]. Returns the new value. *) + val update_and_return + : ( ('key, 'data, 'phantom) t + -> 'key key + -> f:('data option -> 'data) + -> 'data * ('key, 'data, 'phantom) t + , 'key + , 'data + , 'phantom ) + transformer + (** Adds [data] to the existing key/value pair for [key]. Interprets a missing key as having an empty list. *) val add_multi diff --git a/src/hash_set.ml b/src/hash_set.ml index 1c56252..bc04bd2 100644 --- a/src/hash_set.ml +++ b/src/hash_set.ml @@ -14,6 +14,7 @@ module Accessors = struct let hashable = hashable let clear = Hashtbl.clear let length = Hashtbl.length + let capacity = Hashtbl.capacity let mem = Hashtbl.mem let is_empty t = Hashtbl.is_empty t diff --git a/src/hash_set_intf.ml b/src/hash_set_intf.ml index 9d7e36c..1065e19 100644 --- a/src/hash_set_intf.ml +++ b/src/hash_set_intf.ml @@ -40,6 +40,7 @@ module type Accessors = sig val diff : 'a t -> 'a t -> 'a t val of_hashtbl_keys : ('a, _) Hashtbl.t -> 'a t val to_hashtbl : 'key t -> f:('key -> 'data) -> ('key, 'data) Hashtbl.t + val capacity : _ t -> int end type ('key, 'z) create_options = ('key, unit, 'z) Hashtbl_intf.create_options diff --git a/src/int.ml b/src/int.ml index 3347a79..cb9d110 100644 --- a/src/int.ml +++ b/src/int.ml @@ -346,6 +346,14 @@ include O (* [Int] and [Int.O] agree value-wise *) +module Summable = struct + type nonrec t = t + + let zero = zero + let[@inline] ( + ) x y = x + y + let[@inline] ( - ) x y = x - y +end + module Private = struct module O_F = O.F end diff --git a/src/int32.ml b/src/int32.ml index dde2b41..78ec7b2 100644 --- a/src/int32.ml +++ b/src/int32.ml @@ -332,3 +332,11 @@ end include O (* [Int32] and [Int32.O] agree value-wise *) + +module Summable = struct + type nonrec t = t + + let zero = zero + let[@inline] ( + ) x y = x + y + let[@inline] ( - ) x y = x - y +end diff --git a/src/int63_emul.ml b/src/int63_emul.ml index 0b49c55..027080e 100644 --- a/src/int63_emul.ml +++ b/src/int63_emul.ml @@ -483,6 +483,14 @@ include Int_string_conversions.Make_binary (struct (* [Int63] and [Int63.O] agree value-wise *) +module Summable = struct + type nonrec t = t + + let zero = zero + let[@inline] ( + ) x y = x + y + let[@inline] ( - ) x y = x - y +end + module Repr = struct type emulated = t diff --git a/src/int64.ml b/src/int64.ml index a628bdd..424f460 100644 --- a/src/int64.ml +++ b/src/int64.ml @@ -60,7 +60,6 @@ let pred = pred let succ = succ let pow = Int_math.Private.int64_pow let rem = rem -let neg = neg let minus_one = minus_one let one = one let zero = zero @@ -168,19 +167,82 @@ let of_nativeint_exn = of_nativeint let to_nativeint = Conv.int64_to_nativeint let to_nativeint_exn = Conv.int64_to_nativeint_exn +module Pre_O = struct + external ( + ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_add" + external ( - ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_sub" + external ( * ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_mul" + external ( / ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_div" + external ( ~- ) : (t[@local_opt]) -> (t[@local_opt]) = "%int64_neg" + + let ( ** ) = ( ** ) + + include Int64_replace_polymorphic_compare + + let abs = abs + + external neg : (t[@local_opt]) -> (t[@local_opt]) = "%int64_neg" + + let zero = zero + let of_int_exn = of_int_exn +end + +module O = struct + include Pre_O + + include Int_math.Make (struct + type nonrec t = t + + include Pre_O + + let rem = rem + let to_float = to_float + let of_float = of_float + let of_string = T.of_string + let to_string = T.to_string + end) + + external ( land ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_and" + external ( lor ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_or" + external ( lxor ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_xor" + + let lnot = bit_not + + external ( lsl ) + : (t[@local_opt]) + -> (int[@local_opt]) + -> (t[@local_opt]) + = "%int64_lsl" + + external ( asr ) + : (t[@local_opt]) + -> (int[@local_opt]) + -> (t[@local_opt]) + = "%int64_asr" + + external ( lsr ) + : (t[@local_opt]) + -> (int[@local_opt]) + -> (t[@local_opt]) + = "%int64_lsr" +end + +include O + module Pow2 = struct open! Import open Int64_replace_polymorphic_compare - let raise_s = Error.raise_s + open struct + let raise_s = Error.raise_s - let non_positive_argument () = - Printf.invalid_argf "argument must be strictly positive" () - ;; + let non_positive_argument () = + Printf.invalid_argf "argument must be strictly positive" () + ;; - let ( lor ) = Stdlib.Int64.logor - let ( lsr ) = Stdlib.Int64.shift_right_logical - let ( land ) = Stdlib.Int64.logand + let ( lor ) = Stdlib.Int64.logor + let ( lsr ) = Stdlib.Int64.shift_right_logical + let ( land ) = Stdlib.Int64.logand + end (** "ceiling power of 2" - Least power of 2 greater than or equal to x. *) let ceil_pow2 x = @@ -296,69 +358,16 @@ include Pretty_printer.Register (struct let module_name = "Base.Int64" end) -module Pre_O = struct - external ( + ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_add" - external ( - ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_sub" - external ( * ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_mul" - external ( / ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_div" - external ( ~- ) : (t[@local_opt]) -> (t[@local_opt]) = "%int64_neg" - - let ( ** ) = ( ** ) - - include Int64_replace_polymorphic_compare - - let abs = abs +(* [Int64] and [Int64.O] agree value-wise *) - external neg : (t[@local_opt]) -> (t[@local_opt]) = "%int64_neg" +module Summable = struct + type nonrec t = t let zero = zero - let of_int_exn = of_int_exn + let[@inline] ( + ) x y = x + y + let[@inline] ( - ) x y = x - y end -module O = struct - include Pre_O - - include Int_math.Make (struct - type nonrec t = t - - include Pre_O - - let rem = rem - let to_float = to_float - let of_float = of_float - let of_string = T.of_string - let to_string = T.to_string - end) - - external ( land ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_and" - external ( lor ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_or" - external ( lxor ) : (t[@local_opt]) -> (t[@local_opt]) -> (t[@local_opt]) = "%int64_xor" - - let lnot = bit_not - - external ( lsl ) - : (t[@local_opt]) - -> (int[@local_opt]) - -> (t[@local_opt]) - = "%int64_lsl" - - external ( asr ) - : (t[@local_opt]) - -> (int[@local_opt]) - -> (t[@local_opt]) - = "%int64_asr" - - external ( lsr ) - : (t[@local_opt]) - -> (int[@local_opt]) - -> (t[@local_opt]) - = "%int64_lsr" -end - -include O - -(* [Int64] and [Int64.O] agree value-wise *) - (* Include type-specific [Replace_polymorphic_compare] at the end, after including functor application that could shadow its definitions. This is here so that efficient versions of the comparison functions are exported by diff --git a/src/int_conversions.ml b/src/int_conversions.ml index 97ecf2f..debb2e4 100644 --- a/src/int_conversions.ml +++ b/src/int_conversions.ml @@ -71,14 +71,10 @@ let int32_to_int_exn x = (* int <-> int64 *) -let[@cold] [@inline never] [@local never] [@specialise never] int64_to_int_failure x = - convert_failure - (Stdlib.Int64.add - (globalize_int64 x) - 0L (* force int64 boxing to be here under flambda2 *)) - "int64" - "int" - int64_to_string +let[@cold] [@inline never] [@local never] [@specialise never] [@zero_alloc] int64_to_int_failure + x + = + convert_failure x "int64" "int" int64_to_string ;; let () = assert (num_bits_int < num_bits_int64) @@ -96,7 +92,15 @@ let int64_to_int x = ;; let int64_to_int_exn x = - if int64_is_representable_as_int x then int64_to_int_trunc x else int64_to_int_failure x + if int64_is_representable_as_int x + then int64_to_int_trunc x + else ( + let x = + Stdlib.Int64.add + (globalize_int64 x) + 0L (* force int64 boxing to be here under flambda2 *) + in + int64_to_int_failure x) ;; (* int <-> nativeint *) diff --git a/src/int_intf.ml b/src/int_intf.ml index a3a0f29..f0b6adb 100644 --- a/src/int_intf.ml +++ b/src/int_intf.ml @@ -249,6 +249,14 @@ module type S_common = sig The result is unspecified if the argument is nan or falls outside the range of representable integers. *) val of_float_unchecked : float -> t + + module Summable : sig + type nonrec t = t + + val zero : t + val ( + ) : t -> t -> t + val ( - ) : t -> t -> t + end end module type Operators_unbounded = sig diff --git a/src/map.ml b/src/map.ml index 9ac3cd6..8e3887c 100644 --- a/src/map.ml +++ b/src/map.ml @@ -69,31 +69,32 @@ let () = [@@@end] -(* [With_length.t] allows us to store length information on the stack while - keeping the tree global. This saves up to O(log n) blocks of heap allocation. *) -module With_length : sig - type 'a t = private - { tree : 'a - ; length : int - } +module Tree0 = struct + (* Weight-balanced trees, where the weight of each tree is [length t + 1]. We store + [weight] at each node to make balance operations cheap, and computing length just + requires subtracting 1. Conveniently, for the node N=(L,k,R), wt(N)=wt(L)+wt(R). - val with_length : 'a -> int -> 'a t - val with_length_global : 'a -> int -> 'a t - val globalize : 'a t -> 'a t -end = struct - type 'a t = - { tree : 'a - ; length : int - } + Weight-balanced trees of this form are originally defined in [1]. The balancing + algorithm depends on two parameters: delta and gamma. Delta controls the balance + invariant: for sibling subtrees A and B, [wt(A) <= wt(B) * delta] and vice versa. + Gamma is used during rotation to decide whether to use a single or double rotation. A + single left-rotation suffices for (_, (A, B)) if [wt(A) < wt(B) * gamma]. The valid + bounds for these parameters and their performance impact are analyzed in [2]. - let with_length tree length = { tree; length } - let with_length_global tree length = { tree; length } - let globalize { tree; length } = { tree; length } -end + Of the options presented in [2], we choose (delta, gamma) = (5/2, 3/2). This choice + is good by three criteria. One, it has the best performance in the paper's + benchmarks. Two, it yields average tree heights in our own tests comparable to our + previous implementation based on AVL trees. Three, we can implement these comparisons + efficiently with just two bit shifts and one addition each. -open With_length + We define the weight comparisons below as [is_too_heavy] and [may_rotate_just_once]. + + [1] Binary search trees of bounded balance, Nievergelt and Reingold, SIAM Journal on + Computing Vol. 2, Iss. 1 (1973). https://dl.acm.org/doi/pdf/10.1145/800152.804906 + + [2] Balancing weight-balanced trees, Hirai and Yamamoto, JFP 21 (3): 287–307, 2011. + https://yoichihirai.com/bst.pdf *) -module Tree0 = struct type ('k, 'v) t = | Empty | Leaf of @@ -105,15 +106,67 @@ module Tree0 = struct ; key : 'k ; data : 'v ; right : ('k, 'v) t - ; height : int + ; weight : int } type ('k, 'v) tree = ('k, 'v) t - let height = function - | Empty -> 0 - | Leaf _ -> 1 - | Node { left = _; key = _; data = _; right = _; height = h } -> h + (* Checks for failure of the balance invariant in one direction: + + {[ not (wt(A) <= wt(B) * 5/2) ]} + + We negate it by changing [<=] to [>]. + + {[ wt(A) > wt(B) * 5/2 ]} + + We avoid division by multiplying both sides by two. + + {[ wt(A) * 2 > wt(B) * 5 ]} + + We stick to powers of two by changing [x * 5] to [x * 4 + x]. + + {[ wt(A) * 2 > wt(B) * 4 + wt(B) ]} + + And we avoid multiplication by using shifts for multiplication by 2 and by 4. + + {[ wt(A) << 1 > wt(B) << 2 + wt(B) ]} + *) + let is_too_heavy ~weight:wtA ~for_weight:wtB = + (* See? Just like above! *) + wtA lsl 1 > (wtB lsl 2) + wtB + [@@inline always] + ;; + + (* Checks if we can use a single rotation for the currently-lower siblings: + + {[ wt(A) < wt(B) * 3/2 ]} + + We avoid division by multiplying both sides by two. + + {[ wt(A) * 2 < wt(B) * 3 ]} + + We stick to powers of two by changing [x * 3] to [x * 2 + x]. + + {[ wt(A) * 2 < wt(B) * 2 + wt(B) ]} + + We incur one fewer multiplication by moving [wt(B) * 2] to the left. + + {[ (wt(A) - wt(B)) * 2 < wt(B) ]} + + And we avoid multiplication by using shift for multiplication by 2. + + {[ (wt(A) - wt(B)) << 1 < wt(B) ]} + *) + let may_rotate_just_once ~inner_sibling_weight:wtA ~outer_sibling_weight:wtB = + (* See? Just like above! *) + (wtA - wtB) lsl 1 < wtB + [@@inline always] + ;; + + let weight = function + | Empty -> 1 + | Leaf _ -> 2 + | Node { left = _; key = _; data = _; right = _; weight = w } -> w ;; let order_invariants = @@ -130,7 +183,7 @@ module Tree0 = struct match t with | Empty -> true | Leaf { key = k; data = _ } -> in_range ~lower ~upper compare_key k - | Node { left = l; key = k; data = _; right = r; height = _ } -> + | Node { left = l; key = k; data = _; right = r; weight = _ } -> in_range ~lower ~upper compare_key k && loop ~lower ~upper:(Some k) compare_key l && loop ~lower:(Some k) ~upper compare_key r @@ -141,34 +194,28 @@ module Tree0 = struct let rec balance_invariants t = match t with | Empty | Leaf _ -> true - | Node { left = l; key = _; data = _; right = r; height = h } -> - let hl = height l - and hr = height r in - abs (hl - hr) <= 2 - && h = max hl hr + 1 - && h > 1 + | Node { left = l; key = _; data = _; right = r; weight = w } -> + let wl = weight l + and wr = weight r in + w = wl + wr + && w > 2 + && (not (is_too_heavy ~weight:wl ~for_weight:wr)) + && (not (is_too_heavy ~weight:wr ~for_weight:wl)) && balance_invariants l && balance_invariants r ;; let invariants t ~compare_key = order_invariants t ~compare_key && balance_invariants t - (* preconditions: |height(l) - height(r)| <= 2, hl = height(l), hr = height(r) *) - let[@inline] create_with_heights ~hl ~hr l x d r = - if hl = 0 && hr = 0 + (* preconditions: wl = weight(l), wr = weight(r), and neither [is_too_heavy] *) + let[@inline] create_with_weights ~wl ~wr l x d r = + if wl = 1 && wr = 1 then Leaf { key = x; data = d } - else - Node - { left = l - ; key = x - ; data = d - ; right = r - ; height = (if hl >= hr then hl + 1 else hr + 1) - } + else Node { left = l; key = x; data = d; right = r; weight = wl + wr } ;; - (* precondition: |height(l) - height(r)| <= 2 *) - let create l x d r = create_with_heights ~hl:(height l) ~hr:(height r) l x d r + (* precondition: neither weight(l) nor weight(r) [is_too_heavy]. *) + let create l x d r = create_with_weights ~wl:(weight l) ~wr:(weight r) l x d r let singleton key data = Leaf { key; data } (* We must call [f] with increasing indexes, because the bin_prot reader in @@ -188,7 +235,7 @@ module Tree0 = struct ; key = k ; data = v ; right = Empty - ; height = 2 + ; weight = 3 } | 3 -> let kl, vl = f i in @@ -199,7 +246,7 @@ module Tree0 = struct ; key = k ; data = v ; right = Leaf { key = kr; data = vr } - ; height = 2 + ; weight = 4 } | n -> let left_length = n lsr 1 in @@ -223,13 +270,12 @@ module Tree0 = struct then fun i -> array.(i) else fun i -> array.(array_length - 1 - i) in - with_length (of_increasing_iterator_unchecked ~len:array_length ~f:next) array_length + of_increasing_iterator_unchecked ~len:array_length ~f:next ;; let of_sorted_array array ~compare_key = match array with - | [||] | [| _ |] -> - Result.Ok (of_sorted_array_unchecked array ~compare_key |> globalize) + | [||] | [| _ |] -> Result.Ok (of_sorted_array_unchecked array ~compare_key) | _ -> with_return (fun r -> let increasing = @@ -245,44 +291,48 @@ module Tree0 = struct then r.return (Or_error.error_string "of_sorted_array: elements are not ordered") done; - Result.Ok (of_sorted_array_unchecked array ~compare_key |> globalize)) + Result.Ok (of_sorted_array_unchecked array ~compare_key)) ;; - (* precondition: |height(l) - height(r)| <= 3 *) + (* precondition: balanced, or one side [is_too_heavy] by at most 1 *) let[@inline] bal l x d r = - let hl = height l in - let hr = height r in - if hl > hr + 2 + let wl = weight l in + let wr = weight r in + if is_too_heavy ~weight:wl ~for_weight:wr then ( match l with | Empty -> invalid_arg "Map.bal" - | Leaf _ -> assert false (* height(Leaf) = 1 && 1 is not larger than hr + 2 *) - | Node { left = ll; key = lv; data = ld; right = lr; height = _ } -> - if height ll >= height lr + | Leaf _ -> assert false (* a leaf never [is_too_heavy] *) + | Node { left = ll; key = lv; data = ld; right = lr; weight = _ } -> + if may_rotate_just_once + ~inner_sibling_weight:(weight lr) + ~outer_sibling_weight:(weight ll) then create ll lv ld (create lr x d r) else ( match lr with | Empty -> invalid_arg "Map.bal" | Leaf { key = lrv; data = lrd } -> create (create ll lv ld Empty) lrv lrd (create Empty x d r) - | Node { left = lrl; key = lrv; data = lrd; right = lrr; height = _ } -> + | Node { left = lrl; key = lrv; data = lrd; right = lrr; weight = _ } -> create (create ll lv ld lrl) lrv lrd (create lrr x d r))) - else if hr > hl + 2 + else if is_too_heavy ~weight:wr ~for_weight:wl then ( match r with | Empty -> invalid_arg "Map.bal" - | Leaf _ -> assert false (* height(Leaf) = 1 && 1 is not larger than hl + 2 *) - | Node { left = rl; key = rv; data = rd; right = rr; height = _ } -> - if height rr >= height rl + | Leaf _ -> assert false (* a leaf never [is_too_heavy] *) + | Node { left = rl; key = rv; data = rd; right = rr; weight = _ } -> + if may_rotate_just_once + ~inner_sibling_weight:(weight rl) + ~outer_sibling_weight:(weight rr) then create (create l x d rl) rv rd rr else ( match rl with | Empty -> invalid_arg "Map.bal" | Leaf { key = rlv; data = rld } -> create (create l x d Empty) rlv rld (create Empty rv rd rr) - | Node { left = rll; key = rlv; data = rld; right = rlr; height = _ } -> + | Node { left = rll; key = rlv; data = rld; right = rlr; weight = _ } -> create (create l x d rll) rlv rld (create rlr rv rd rr))) - else create_with_heights ~hl ~hr l x d r + else create_with_weights ~wl ~wr l x d r ;; let empty = Empty @@ -306,7 +356,6 @@ module Tree0 = struct let rec find_and_add_or_set t - ~length ~key:x ~data ~compare_key @@ -314,7 +363,7 @@ module Tree0 = struct ~(add_or_set : Add_or_set.t) = match t with - | Empty -> with_length (Leaf { key = x; data }) (length + 1) + | Empty -> Leaf { key = x; data } | Leaf { key = v; data = d } -> let c = compare_key x v in if c = 0 @@ -322,66 +371,37 @@ module Tree0 = struct match add_or_set with | Add_exn_internal -> Exn.raise_without_backtrace Duplicate | Add_exn -> raise_key_already_present ~key:x ~sexp_of_key - | Set -> with_length (Leaf { key = x; data }) length) + | Set -> Leaf { key = x; data }) else if c < 0 then - with_length - (Node - { left = Leaf { key = x; data } - ; key = v - ; data = d - ; right = Empty - ; height = 2 - }) - (length + 1) + Node + { left = Leaf { key = x; data }; key = v; data = d; right = Empty; weight = 3 } else - with_length - (Node - { left = Empty - ; key = v - ; data = d - ; right = Leaf { key = x; data } - ; height = 2 - }) - (length + 1) - | Node { left = l; key = v; data = d; right = r; height = h } -> + Node + { left = Empty; key = v; data = d; right = Leaf { key = x; data }; weight = 3 } + | Node { left = l; key = v; data = d; right = r; weight = w } -> let c = compare_key x v in if c = 0 then ( match add_or_set with | Add_exn_internal -> Exn.raise_without_backtrace Duplicate | Add_exn -> raise_key_already_present ~key:x ~sexp_of_key - | Set -> - with_length (Node { left = l; key = x; data; right = r; height = h }) length) + | Set -> Node { left = l; key = x; data; right = r; weight = w }) else ( - let l, r, length = + let l, r = if c < 0 then ( - let { tree = l; length } = - find_and_add_or_set - ~length - ~key:x - ~data - l - ~compare_key - ~sexp_of_key - ~add_or_set + let l = + find_and_add_or_set ~key:x ~data l ~compare_key ~sexp_of_key ~add_or_set in - l, r, length) + l, r) else ( - let { tree = r; length } = - find_and_add_or_set - ~length - ~key:x - ~data - r - ~compare_key - ~sexp_of_key - ~add_or_set + let r = + find_and_add_or_set ~key:x ~data r ~compare_key ~sexp_of_key ~add_or_set in - l, r, length) + l, r) in - with_length (bal l v d r) length) + bal l v d r) ;; (* specialization of [set'] for the case when [key] is less than all the existing keys *) @@ -389,8 +409,8 @@ module Tree0 = struct match t with | Empty -> Leaf { key; data } | Leaf { key = v; data = d } -> - Node { left = Leaf { key; data }; key = v; data = d; right = Empty; height = 2 } - | Node { left = l; key = v; data = d; right = r; height = _ } -> + Node { left = Leaf { key; data }; key = v; data = d; right = Empty; weight = 3 } + | Node { left = l; key = v; data = d; right = r; weight = _ } -> let l = set_min key data l in bal l v d r ;; @@ -401,20 +421,19 @@ module Tree0 = struct match t with | Empty -> Leaf { key; data } | Leaf { key = v; data = d } -> - Node { left = Empty; key = v; data = d; right = Leaf { key; data }; height = 2 } - | Node { left = l; key = v; data = d; right = r; height = _ } -> + Node { left = Empty; key = v; data = d; right = Leaf { key; data }; weight = 3 } + | Node { left = l; key = v; data = d; right = r; weight = _ } -> let r = set_max r key data in bal l v d r ;; - let add_exn t ~length ~key ~data ~compare_key ~sexp_of_key = - find_and_add_or_set t ~length ~key ~data ~compare_key ~sexp_of_key ~add_or_set:Add_exn + let add_exn t ~key ~data ~compare_key ~sexp_of_key = + find_and_add_or_set t ~key ~data ~compare_key ~sexp_of_key ~add_or_set:Add_exn ;; - let add_exn_internal t ~length ~key ~data ~compare_key ~sexp_of_key = + let add_exn_internal t ~key ~data ~compare_key ~sexp_of_key = find_and_add_or_set t - ~length ~key ~data ~compare_key @@ -422,10 +441,9 @@ module Tree0 = struct ~add_or_set:Add_exn_internal ;; - let set t ~length ~key ~data ~compare_key = + let set t ~key ~data ~compare_key = find_and_add_or_set t - ~length ~key ~data ~compare_key @@ -433,8 +451,6 @@ module Tree0 = struct ~add_or_set:Set ;; - let set' t key data ~compare_key = (set t ~length:0 ~key ~data ~compare_key).tree - module Build_increasing : sig type ('k, 'd) t @@ -472,7 +488,7 @@ module Tree0 = struct ; key = k1 ; data = d1 ; right = Leaf { key = k2; data = d2 } - ; height = 2 + ; weight = 3 } | 3, (k3, d3) :: (k2, d2) :: (k1, d1) :: tail -> list := tail; @@ -481,7 +497,7 @@ module Tree0 = struct ; key = k2 ; data = d2 ; right = Leaf { key = k3; data = d3 } - ; height = 2 + ; weight = 4 } | _, _ -> let nr = len / 2 in @@ -500,46 +516,133 @@ module Tree0 = struct let of_increasing_sequence seq ~compare_key = with_return (fun { return } -> - let { tree = builder; length } = - Sequence.fold - seq - ~init:(with_length_global Build_increasing.empty 0) - ~f:(fun { tree = builder; length } (key, data) -> - match Build_increasing.max_key builder with - | Some prev_key when compare_key prev_key key >= 0 -> - return (Or_error.error_string "of_increasing_sequence: non-increasing key") - | _ -> - with_length_global - (Build_increasing.add_unchecked builder ~key ~data) - (length + 1)) + let builder = + Sequence.fold seq ~init:Build_increasing.empty ~f:(fun builder (key, data) -> + match Build_increasing.max_key builder with + | Some prev_key when compare_key prev_key key >= 0 -> + return (Or_error.error_string "of_increasing_sequence: non-increasing key") + | _ -> Build_increasing.add_unchecked builder ~key ~data) in - Ok (with_length_global (Build_increasing.to_tree_unchecked builder) length)) - ;; - - (* Like [bal] but allows any difference in height between [l] and [r]. - - O(|height l - height r|) *) - let rec join l k d r = - match l, r with - | Empty, _ -> set_min k d r - | _, Empty -> set_max l k d - | Leaf { key = lk; data = ld }, _ -> set_min lk ld (set_min k d r) - | _, Leaf { key = rk; data = rd } -> set_max (set_max l k d) rk rd - | ( Node { left = ll; key = lk; data = ld; right = lr; height = lh } - , Node { left = rl; key = rk; data = rd; right = rr; height = rh } ) -> - let l, k, d, r = - (* [bal] requires height difference <= 3. *) - if lh > rh + 3 - (* [height lr >= height r], - therefore [height (join lr k d r ...)] is [height rl + 1] or [height rl] - therefore the height difference with [ll] will be <= 3 *) - then ll, lk, ld, join lr k d r - else if rh > lh + 3 - then join l k d rl, rk, rd, rr - else l, k, d, r - in - bal l k d r - ;; + Ok (Build_increasing.to_tree_unchecked builder)) + ;; + + (* The [join] algorithm is taken from the github implementation[3] of [4]. It is like + [create] and [bal], and works on trees of arbitrary weight. + + We adapt our functions from [include/pam/balance_utils.h]. We use the name [join] for + [node_join], [join_rotating_right] for [right_join], and [join_rotating_left] for + [left_join]. We use our [may_rotate_just_once] where they use [is_single_rotation]. + + In the two recursive helpers, we've moved the initial balance check to just outside + the recursive call instead of just inside the function definition, since the + condition is known the first time we call it. + + [3] https://github.com/cmuparlay/PAM/tree/2a30a856a55698c7aa7e7ebf86ee826864bbcf86 + + [4] Just Join for Parallel Ordered Sets; Blelloch, Ferizovic, and Sun; SPAA ’16, July + 11-13, 20. https://www.cs.cmu.edu/~guyb/papers/BFS16.pdf *) + include struct + open struct + (* These helpers are intended only to be called from [join]. *) + + (* For [join_rotating_right l lk ld m rk rd r], the arguments correspond to an + unbalanced tree with the shape: + {v + (rk,rd) + / \ + (lk,ld) r + / \ + l m + v} + + Precondition: [create l lk ld m] [is_too_heavy] for [r], and [r = Node _]. *) + let rec join_rotating_right l lk ld m rk rd r = + let mr = + (* Recur down [m]'s right side until [create m rk rd r] is balanced. *) + match m with + | Node { left = ml; key = mk; data = md; right = mr; weight = mw } + when is_too_heavy ~weight:mw ~for_weight:(weight r) -> + join_rotating_right ml mk md mr rk rd r + | _ -> create m rk rd r + in + (* Since [r] is a [Node], [mr] must be a [Node]. *) + match mr with + | Empty -> assert false + | Leaf _ -> assert false + | Node { left = m; key = rk; data = rd; right = r; weight = mrw } -> + (* Now re-add [l] with 0-2 rotations. Proven sufficient in literature above. *) + let lw = weight l in + (match m with + | Node { left = ml; key = mk; data = md; right = mr; weight = mw } + when is_too_heavy ~weight:mrw ~for_weight:lw -> + if may_rotate_just_once + ~inner_sibling_weight:mw + ~outer_sibling_weight:(weight r) + then create (create l lk ld m) rk rd r + else create (create l lk ld ml) mk md (create mr rk rd r) + | _ -> create l lk ld mr) + ;; + + (* Rotating left proceeds symmetrically to rotating right. *) + + (* For [join_rotating_left l lk ld m rk rd r], the arguments correspond to an + unbalanced tree with the shape: + {v + (lk,ld) + / \ + l (rk,rd) + / \ + m r + v} + + Precondition: [create m rk rd r] [is_too_heavy] for [l], and [l = Node _]. *) + let rec join_rotating_left l lk ld m rk rd r = + let lm = + (* Recur down [m]'s left side until [create l lk ld m] is balanced. *) + match m with + | Node { left = ml; key = mk; data = md; right = mr; weight = mw } + when is_too_heavy ~weight:mw ~for_weight:(weight l) -> + join_rotating_left l lk ld ml mk md mr + | _ -> create l lk ld m + in + (* Since [l] is a [Node], [lm] must be a [Node]. *) + match lm with + | Empty -> assert false + | Leaf _ -> assert false + | Node { left = l; key = lk; data = ld; right = m; weight = lmw } -> + (* Now re-add [r] with 0-2 rotations. Proven sufficient in literature above. *) + let rw = weight r in + (match m with + | Node { left = ml; key = mk; data = md; right = mr; weight = mw } + when is_too_heavy ~weight:lmw ~for_weight:rw -> + if may_rotate_just_once + ~inner_sibling_weight:mw + ~outer_sibling_weight:(weight l) + then create l lk ld (create m rk rd r) + else create (create l lk ld ml) mk md (create mr rk rd r) + | _ -> create lm rk rd r) + ;; + end + + (* Like [create] and [bal], for arbitrary height differences. See more detailed + comment at start of [include struct ...] above. *) + let join l k d r = + (* Cases adding just one or two keys are straightforward. *) + match l, r with + | Empty, _ -> set_min k d r + | _, Empty -> set_max l k d + | Leaf { key = lk; data = ld }, _ -> set_min lk ld (set_min k d r) + | _, Leaf { key = rk; data = rd } -> set_max (set_max l k d) rk rd + | ( Node { left = ll; key = lk; data = ld; right = lr; weight = lw } + , Node { left = rl; key = rk; data = rd; right = rr; weight = rw } ) -> + (* Otherwise, recur down the heavier side and rotate toward the lighter side. *) + if is_too_heavy ~weight:lw ~for_weight:rw + then join_rotating_right ll lk ld lr k d r + else if is_too_heavy ~weight:rw ~for_weight:lw + then join_rotating_left l k d rl rk rd rr + else create l k d r + ;; + end let[@inline] rec split_gen t x ~compare_key = match t with @@ -551,7 +654,7 @@ module Tree0 = struct else if cmp < 0 then Empty, None, t else t, None, Empty - | Node { left = l; key = k; data = d; right = r; height = _ } -> + | Node { left = l; key = k; data = d; right = r; weight = _ } -> let cmp = compare_key k in if cmp = 0 then l, Some (k, d), r @@ -622,14 +725,14 @@ module Tree0 = struct match t with | Empty -> None | Leaf { key = v; data = d } -> if compare_key x v = 0 then Some d else None - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> let c = compare_key x v in if c = 0 then Some d else find (if c < 0 then l else r) x ~compare_key ;; - let add_multi t ~length ~key ~data ~compare_key = + let add_multi t ~key ~data ~compare_key = let data = data :: Option.value (find t key ~compare_key) ~default:[] in - set ~length ~key ~data t ~compare_key + set ~key ~data t ~compare_key ;; let find_multi t x ~compare_key = @@ -647,7 +750,7 @@ module Tree0 = struct | Empty -> if_not_found x ~sexp_of_key | Leaf { key = v; data = d } -> if compare_key x v = 0 then d else if_not_found x ~sexp_of_key - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> let c = compare_key x v in if c = 0 then d else find_exn (if c < 0 then l else r) x ~compare_key ~sexp_of_key in @@ -660,8 +763,8 @@ module Tree0 = struct let rec min_elt = function | Empty -> None | Leaf { key = k; data = d } -> Some (k, d) - | Node { left = Empty; key = k; data = d; right = _; height = _ } -> Some (k, d) - | Node { left = l; key = _; data = _; right = _; height = _ } -> min_elt l + | Node { left = Empty; key = k; data = d; right = _; weight = _ } -> Some (k, d) + | Node { left = l; key = _; data = _; right = _; weight = _ } -> min_elt l ;; exception Map_min_elt_exn_of_empty_map [@@deriving_inline sexp] @@ -699,8 +802,8 @@ module Tree0 = struct let rec max_elt = function | Empty -> None | Leaf { key = k; data = d } -> Some (k, d) - | Node { left = _; key = k; data = d; right = Empty; height = _ } -> Some (k, d) - | Node { left = _; key = _; data = _; right = r; height = _ } -> max_elt r + | Node { left = _; key = k; data = d; right = Empty; weight = _ } -> Some (k, d) + | Node { left = _; key = _; data = _; right = r; weight = _ } -> max_elt r ;; let max_elt_exn t = @@ -713,8 +816,8 @@ module Tree0 = struct match t with | Empty -> invalid_arg "Map.remove_min_elt" | Leaf _ -> Empty - | Node { left = Empty; key = _; data = _; right = r; height = _ } -> r - | Node { left = l; key = x; data = d; right = r; height = _ } -> + | Node { left = Empty; key = _; data = _; right = r; weight = _ } -> r + | Node { left = l; key = x; data = d; right = r; weight = _ } -> bal (remove_min_elt l) x d r ;; @@ -738,7 +841,7 @@ module Tree0 = struct then (* k < min || k > max *) init else f ~key:k ~data:d init - | Node { left = l; key = k; data = d; right = r; height = _ } -> + | Node { left = l; key = k; data = d; right = r; weight = _ } -> let c_min = compare_key k min in if c_min < 0 then @@ -777,7 +880,7 @@ module Tree0 = struct (* preconditions: - all elements in t1 are less than elements in t2 - - |height(t1) - height(t2)| <= 2 *) + - neither [is_too_heavy] for the other *) let concat_unchecked t1 t2 = match t1, t2 with | Empty, t -> t @@ -787,7 +890,7 @@ module Tree0 = struct bal t1 x d (remove_min_elt t2) ;; - (* similar to [concat_unchecked], and balances trees of arbitrary height differences *) + (* similar to [concat_unchecked], and balances trees of arbitrary weight differences *) let concat_and_balance_unchecked t1 t2 = match t1, t2 with | Empty, t -> t @@ -797,110 +900,111 @@ module Tree0 = struct join t1 x d (remove_min_elt t2) ;; - let rec remove t x ~length ~compare_key = + let rec remove t x ~compare_key = match t with - | Empty -> with_length t length - | Leaf { key = v; data = _ } -> - if compare_key x v = 0 then with_length Empty (length - 1) else with_length t length - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Empty -> t + | Leaf { key = v; data = _ } -> if compare_key x v = 0 then Empty else t + | Node { left = l; key = v; data = d; right = r; weight = w } -> let c = compare_key x v in if c = 0 - then with_length (concat_unchecked l r) (length - 1) + then concat_unchecked l r else ( - let l, r, length' = + let l, r = if c < 0 then ( - let { tree = l; length = length' } = remove l x ~length ~compare_key in - l, r, length') + let l = remove l x ~compare_key in + l, r) else ( - let { tree = r; length = length' } = remove r x ~length ~compare_key in - l, r, length') + let r = remove r x ~compare_key in + l, r) in - if length = length' - then with_length t length - else with_length (bal l v d r) length') + if w = weight l + weight r then t else bal l v d r) ;; - let rec change t key ~f ~length ~compare_key = + let rec change t key ~f ~compare_key = match t with | Empty -> (match f None with - | None -> with_length Empty length - | Some data -> with_length (Leaf { key; data }) (length + 1)) + | None -> Empty + | Some data -> Leaf { key; data }) | Leaf { key = v; data = d } -> let c = compare_key key v in if c = 0 then ( match f (Some d) with - | None -> with_length Empty (length - 1) - | Some d' -> with_length (Leaf { key = v; data = d' }) length) + | None -> Empty + | Some d' -> Leaf { key = v; data = d' }) else if c < 0 then ( - let { tree = l'; length } = change Empty key ~f ~length ~compare_key in - if phys_equal l' t - then with_length t length - else with_length (bal l' v d Empty) length) + let l' = change Empty key ~f ~compare_key in + if phys_equal l' t then t else bal l' v d Empty) else ( - let { tree = r'; length } = change Empty key ~f ~length ~compare_key in - if phys_equal r' t - then with_length t length - else with_length (bal Empty v d r') length) - | Node { left = l; key = v; data = d; right = r; height = h } -> + let r' = change Empty key ~f ~compare_key in + if phys_equal r' t then t else bal Empty v d r') + | Node { left = l; key = v; data = d; right = r; weight = w } -> let c = compare_key key v in if c = 0 then ( match f (Some d) with - | None -> with_length (concat_unchecked l r) (length - 1) - | Some data -> - with_length (Node { left = l; key; data; right = r; height = h }) length) + | None -> concat_unchecked l r + | Some data -> Node { left = l; key; data; right = r; weight = w }) else if c < 0 then ( - let { tree = l'; length } = change l key ~f ~length ~compare_key in - if phys_equal l' l - then with_length t length - else with_length (bal l' v d r) length) + let l' = change l key ~f ~compare_key in + if phys_equal l' l then t else bal l' v d r) else ( - let { tree = r'; length } = change r key ~f ~length ~compare_key in - if phys_equal r' r - then with_length t length - else with_length (bal l v d r') length) + let r' = change r key ~f ~compare_key in + if phys_equal r' r then t else bal l v d r') ;; - let rec update t key ~f ~length ~compare_key = + let rec update t key ~f ~compare_key = match t with | Empty -> let data = f None in - with_length (Leaf { key; data }) (length + 1) + Leaf { key; data } | Leaf { key = v; data = d } -> let c = compare_key key v in if c = 0 then ( let d' = f (Some d) in - with_length (Leaf { key = v; data = d' }) length) + Leaf { key = v; data = d' }) else if c < 0 then ( - let { tree = l; length } = update Empty key ~f ~length ~compare_key in - with_length (bal l v d Empty) length) + let l = update Empty key ~f ~compare_key in + bal l v d Empty) else ( - let { tree = r; length } = update Empty key ~f ~length ~compare_key in - with_length (bal Empty v d r) length) - | Node { left = l; key = v; data = d; right = r; height = h } -> + let r = update Empty key ~f ~compare_key in + bal Empty v d r) + | Node { left = l; key = v; data = d; right = r; weight = w } -> let c = compare_key key v in if c = 0 then ( let data = f (Some d) in - with_length (Node { left = l; key; data; right = r; height = h }) length) + Node { left = l; key; data; right = r; weight = w }) else if c < 0 then ( - let { tree = l; length } = update l key ~f ~length ~compare_key in - with_length (bal l v d r) length) + let l = update l key ~f ~compare_key in + bal l v d r) else ( - let { tree = r; length } = update r key ~f ~length ~compare_key in - with_length (bal l v d r) length) + let r = update r key ~f ~compare_key in + bal l v d r) + ;; + + let update_and_return t key ~f ~compare_key = + let result_ref = ref None in + let new_t = + update t key ~compare_key ~f:(fun elt -> + let res = f elt in + result_ref := Some res; + res) + in + (* This [Option.value_exn] is safe because it is guaranteed by [update] that [f] will + be called exactly once. *) + !result_ref |> Option.value_exn |> Modes.Global.wrap, new_t ;; - let remove_multi t key ~length ~compare_key = - change t key ~length ~compare_key ~f:(function + let remove_multi t key ~compare_key = + change t key ~compare_key ~f:(function | None | Some ([] | [ _ ]) -> None | Some (_ :: (_ :: _ as non_empty_tail)) -> Some non_empty_tail) ;; @@ -909,7 +1013,7 @@ module Tree0 = struct match t with | Empty -> () | Leaf { key = v; data = _ } -> f v - | Node { left = l; key = v; data = _; right = r; height = _ } -> + | Node { left = l; key = v; data = _; right = r; weight = _ } -> iter_keys ~f l; f v; iter_keys ~f r @@ -919,7 +1023,7 @@ module Tree0 = struct match t with | Empty -> () | Leaf { key = _; data = d } -> f d - | Node { left = l; key = _; data = d; right = r; height = _ } -> + | Node { left = l; key = _; data = d; right = r; weight = _ } -> iter ~f l; f d; iter ~f r @@ -929,7 +1033,7 @@ module Tree0 = struct match t with | Empty -> () | Leaf { key = v; data = d } -> f ~key:v ~data:d - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> iteri ~f l; f ~key:v ~data:d; iteri ~f r @@ -940,7 +1044,7 @@ module Tree0 = struct match t with | Empty -> Continue | Leaf { key = v; data = d } -> f ~key:v ~data:d - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> (match iteri_until_loop ~f l with | Stop -> Stop | Continue -> @@ -955,29 +1059,29 @@ module Tree0 = struct match t with | Empty -> Empty | Leaf { key = v; data = d } -> Leaf { key = v; data = f d } - | Node { left = l; key = v; data = d; right = r; height = h } -> + | Node { left = l; key = v; data = d; right = r; weight = w } -> let l' = map ~f l in let d' = f d in let r' = map ~f r in - Node { left = l'; key = v; data = d'; right = r'; height = h } + Node { left = l'; key = v; data = d'; right = r'; weight = w } ;; let rec mapi t ~f = match t with | Empty -> Empty | Leaf { key = v; data = d } -> Leaf { key = v; data = f ~key:v ~data:d } - | Node { left = l; key = v; data = d; right = r; height = h } -> + | Node { left = l; key = v; data = d; right = r; weight = w } -> let l' = mapi ~f l in let d' = f ~key:v ~data:d in let r' = mapi ~f r in - Node { left = l'; key = v; data = d'; right = r'; height = h } + Node { left = l'; key = v; data = d'; right = r'; weight = w } ;; let rec fold t ~init:accu ~f = match t with | Empty -> accu | Leaf { key = v; data = d } -> f ~key:v ~data:d accu - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> fold ~f r ~init:(f ~key:v ~data:d (fold ~f l ~init:accu)) ;; @@ -986,7 +1090,7 @@ module Tree0 = struct match t with | Empty -> Continue acc | Leaf { key = v; data = d } -> f ~key:v ~data:d acc - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> (match fold_until_loop l ~acc ~f with | Stop final -> Stop final | Continue acc -> @@ -1003,56 +1107,48 @@ module Tree0 = struct match t with | Empty -> accu | Leaf { key = v; data = d } -> f ~key:v ~data:d accu - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> fold_right ~f l ~init:(f ~key:v ~data:d (fold_right ~f r ~init:accu)) ;; - let rec filter_mapi t ~f ~len = + let rec filter_mapi t ~f = match t with | Empty -> Empty | Leaf { key = v; data = d } -> (match f ~key:v ~data:d with | Some new_data -> Leaf { key = v; data = new_data } - | None -> - decr len; - Empty) - | Node { left = l; key = v; data = d; right = r; height = _ } -> - let l' = filter_mapi l ~f ~len in + | None -> Empty) + | Node { left = l; key = v; data = d; right = r; weight = _ } -> + let l' = filter_mapi l ~f in let new_data = f ~key:v ~data:d in - let r' = filter_mapi r ~f ~len in + let r' = filter_mapi r ~f in (match new_data with | Some new_data -> join l' v new_data r' - | None -> - decr len; - concat_and_balance_unchecked l' r') + | None -> concat_and_balance_unchecked l' r') ;; - let rec filteri t ~f ~len = + let rec filteri t ~f = match t with | Empty -> Empty | Leaf { key = v; data = d } -> (match f ~key:v ~data:d with | true -> t - | false -> - decr len; - Empty) - | Node { left = l; key = v; data = d; right = r; height = _ } -> - let l' = filteri l ~f ~len in + | false -> Empty) + | Node { left = l; key = v; data = d; right = r; weight = _ } -> + let l' = filteri l ~f in let keep_data = f ~key:v ~data:d in - let r' = filteri r ~f ~len in + let r' = filteri r ~f in if phys_equal l l' && keep_data && phys_equal r r' then t else ( match keep_data with | true -> join l' v d r' - | false -> - decr len; - concat_and_balance_unchecked l' r') + | false -> concat_and_balance_unchecked l' r') ;; - let filter t ~f ~len = filteri t ~len ~f:(fun ~key:_ ~data -> f data) [@nontail] - let filter_keys t ~f ~len = filteri t ~len ~f:(fun ~key ~data:_ -> f key) [@nontail] - let filter_map t ~f ~len = filter_mapi t ~len ~f:(fun ~key:_ ~data -> f data) [@nontail] + let filter t ~f = filteri t ~f:(fun ~key:_ ~data -> f data) [@nontail] + let filter_keys t ~f = filteri t ~f:(fun ~key ~data:_ -> f key) [@nontail] + let filter_map t ~f = filter_mapi t ~f:(fun ~key:_ ~data -> f data) [@nontail] let partition_mapi t ~f = let t1, t2 = @@ -1077,7 +1173,7 @@ module Tree0 = struct (match f ~key:v ~data:d with | true -> t, Empty | false -> Empty, t) - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> let l't, l'f = loop l ~f in let keep_data_t = f ~key:v ~data:d in let r't, r'f = loop r ~f in @@ -1108,7 +1204,7 @@ module Tree0 = struct match t with | Empty -> e | Leaf { key = v; data = d } -> More (v, d, Empty, e) - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> cons l (More (v, d, r, e)) ;; @@ -1116,7 +1212,7 @@ module Tree0 = struct match t with | Empty -> e | Leaf { key = v; data = d } -> More (v, d, Empty, e) - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> cons_right r (More (v, d, l, e)) ;; @@ -1128,10 +1224,10 @@ module Tree0 = struct match t with | Empty -> e | Leaf { key = v; data = d } -> - loop (Node { left = Empty; key = v; data = d; right = Empty; height = 1 }) e - | Node { left = _; key = v; data = _; right = r; height = _ } + loop (Node { left = Empty; key = v; data = d; right = Empty; weight = 2 }) e + | Node { left = _; key = v; data = _; right = r; weight = _ } when compare v key < 0 -> loop r e - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> loop l (More (v, d, r, e)) in loop t End @@ -1142,10 +1238,10 @@ module Tree0 = struct match t with | Empty -> e | Leaf { key = v; data = d } -> - loop (Node { left = Empty; key = v; data = d; right = Empty; height = 1 }) e - | Node { left = l; key = v; data = _; right = _; height = _ } + loop (Node { left = Empty; key = v; data = d; right = Empty; weight = 2 }) e + | Node { left = l; key = v; data = _; right = _; weight = _ } when compare v key > 0 -> loop l e - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Node { left = l; key = v; data = d; right = r; weight = _ } -> loop r (More (v, d, l, e)) in loop t End @@ -1155,7 +1251,7 @@ module Tree0 = struct match tree with | Empty -> assert false | Leaf { key = v; data = d } -> Empty, More (v, d, Empty, e) - | Node { left = l; key = v; data = d; right = r; height = _ } -> l, More (v, d, r, e) + | Node { left = l; key = v; data = d; right = r; weight = _ } -> l, More (v, d, r, e) ;; (* [drop_phys_equal_prefix tree1 acc1 tree2 acc2] drops the largest physically-equal @@ -1167,20 +1263,24 @@ module Tree0 = struct is skipped. *) let rec drop_phys_equal_prefix tree1 acc1 tree2 acc2 = if phys_equal tree1 tree2 - then acc1, acc2 + then (* Trees are equal, drop them *) + acc1, acc2 else ( - let h2 = height tree2 in - let h1 = height tree1 in - if h2 = h1 + let w2 = weight tree2 in + let w1 = weight tree1 in + if w2 = w1 then ( + (* Neither tree can be a subtree of the other, descend into both *) let tree1, acc1 = step_deeper_exn tree1 acc1 in let tree2, acc2 = step_deeper_exn tree2 acc2 in drop_phys_equal_prefix tree1 acc1 tree2 acc2) - else if h2 > h1 + else if w2 > w1 then ( + (* [tree1] could be a subtree of [tree2], step into [tree2] only *) let tree2, acc2 = step_deeper_exn tree2 acc2 in drop_phys_equal_prefix tree1 acc1 tree2 acc2) else ( + (* [tree2] could be a subtree of [tree1], step into [tree1] only *) let tree1, acc1 = step_deeper_exn tree1 acc1 in drop_phys_equal_prefix tree1 acc1 tree2 acc2)) ;; @@ -1352,7 +1452,7 @@ module Tree0 = struct let t = side (l, r) in match maybe with | None -> t - | Some (key, data) -> set' t key data ~compare_key + | Some (key, data) -> set t ~key ~data ~compare_key in match order with | `Increasing_key -> @@ -1417,8 +1517,8 @@ module Tree0 = struct | _ (* when x > 0 *) -> let acc = add acc k' v' in remove acc k v) - | ( Node { left = l; key = k; data = v; right = r; height = _ } - , Node { left = l'; key = k'; data = v'; right = r'; height = _ } ) + | ( Node { left = l; key = k; data = v; right = r; weight = _ } + , Node { left = l'; key = k'; data = v'; right = r'; weight = _ } ) when compare_key k k' = 0 -> let acc = loop l l' acc in let acc = delta acc k v v' in @@ -1431,11 +1531,10 @@ module Tree0 = struct loop t1 t2 init [@nontail] ;; - let rec length = function + let length = function | Empty -> 0 | Leaf _ -> 1 - | Node { left = l; key = _; data = _; right = r; height = _ } -> - length l + length r + 1 + | Node { left = _; key = _; data = _; right = _; weight = w } -> w - 1 ;; let hash_fold_t_ignoring_structure hash_fold_key hash_fold_data state t = @@ -1457,17 +1556,14 @@ module Tree0 = struct end let[@inline always] of_foldable' ~fold foldable ~init ~f ~compare_key = - (fold [@inlined hint]) - foldable - ~init:(with_length_global empty 0) - ~f:(fun { tree = accum; length } (key, data) -> - let prev_data = - match find accum key ~compare_key with - | None -> init - | Some prev -> prev - in - let data = f prev_data data in - (set accum ~length ~key ~data ~compare_key |> globalize) [@nontail]) [@nontail] + (fold [@inlined hint]) foldable ~init:empty ~f:(fun accum (key, data) -> + let prev_data = + match find accum key ~compare_key with + | None -> init + | Some prev -> prev + in + let data = f prev_data data in + set accum ~key ~data ~compare_key [@nontail]) [@nontail] ;; module Of_foldable (M : Foldable) = struct @@ -1476,32 +1572,21 @@ module Tree0 = struct ;; let of_foldable_reduce foldable ~f ~compare_key = - M.fold - foldable - ~init:(with_length_global empty 0) - ~f:(fun { tree = accum; length } (key, data) -> - let new_data = - match find accum key ~compare_key with - | None -> data - | Some prev -> f prev data - in - (set accum ~length ~key ~data:new_data ~compare_key |> globalize) [@nontail]) [@nontail - ] + M.fold foldable ~init:empty ~f:(fun accum (key, data) -> + let new_data = + match find accum key ~compare_key with + | None -> data + | Some prev -> f prev data + in + set accum ~key ~data:new_data ~compare_key [@nontail]) [@nontail] ;; let of_foldable foldable ~compare_key = with_return (fun r -> let map = - M.fold - foldable - ~init:(with_length_global empty 0) - ~f:(fun { tree = t; length } (key, data) -> - let ({ tree = _; length = length' } as acc) = - set ~length ~key ~data t ~compare_key - in - if length = length' - then r.return (`Duplicate_key key) - else globalize acc [@nontail]) + M.fold foldable ~init:empty ~f:(fun t (key, data) -> + let acc = set ~key ~data t ~compare_key in + if length t = length acc then r.return (`Duplicate_key key) else acc) in `Ok map) ;; @@ -1566,17 +1651,10 @@ module Tree0 = struct let of_list_with_key list ~get_key ~compare_key = with_return (fun r -> let map = - List.fold - list - ~init:(with_length_global empty 0) - ~f:(fun { tree = t; length } data -> - let key = get_key data in - let ({ tree = _; length = new_length } as acc) = - set ~length ~key ~data t ~compare_key - in - if length = new_length - then r.return (`Duplicate_key key) - else globalize acc [@nontail]) + List.fold list ~init:empty ~f:(fun t data -> + let key = get_key data in + let acc = set ~key ~data t ~compare_key in + if length t = length acc then r.return (`Duplicate_key key) else acc) in `Ok map) [@nontail] ;; @@ -1601,30 +1679,27 @@ module Tree0 = struct let of_list_with_key_multi list ~get_key ~compare_key = let list = List.rev list in - List.fold list ~init:(with_length_global empty 0) ~f:(fun { tree = t; length } data -> + List.fold list ~init:empty ~f:(fun t data -> let key = get_key data in - (update t key ~length ~compare_key ~f:(fun option -> - let list = Option.value option ~default:[] in - data :: list) - |> globalize) [@nontail]) [@nontail] + update t key ~compare_key ~f:(fun option -> + let list = Option.value option ~default:[] in + data :: list) [@nontail]) [@nontail] ;; let of_list_with_key_fold list ~get_key ~init ~f ~compare_key = - List.fold list ~init:(with_length_global empty 0) ~f:(fun { tree = t; length } data -> + List.fold list ~init:empty ~f:(fun t data -> let key = get_key data in - (update t key ~length ~compare_key ~f:(function - | None -> f init data - | Some prev -> f prev data) - |> globalize) [@nontail]) [@nontail] + update t key ~compare_key ~f:(function + | None -> f init data + | Some prev -> f prev data) [@nontail]) [@nontail] ;; let of_list_with_key_reduce list ~get_key ~f ~compare_key = - List.fold list ~init:(with_length_global empty 0) ~f:(fun { tree = t; length } data -> + List.fold list ~init:empty ~f:(fun t data -> let key = get_key data in - (update t key ~length ~compare_key ~f:(function - | None -> data - | Some prev -> f prev data) - |> globalize) [@nontail]) [@nontail] + update t key ~compare_key ~f:(function + | None -> data + | Some prev -> f prev data) [@nontail]) [@nontail] ;; let for_all t ~f = @@ -1685,39 +1760,28 @@ module Tree0 = struct | None -> ()); let len = !i in let get i = Uniform_array.get elts i in - let tree = of_increasing_iterator_unchecked ~len ~f:get in - with_length tree len + of_increasing_iterator_unchecked ~len ~f:get ;; let merge_skewed = - let merge_large_first length_large t_large t_small ~call ~combine ~compare_key = - fold - t_small - ~init:(with_length_global t_large length_large) - ~f:(fun ~key ~data:data' { tree = t; length } -> - (update t key ~length ~compare_key ~f:(function - | None -> data' - | Some data -> call combine ~key data data') - |> globalize) [@nontail]) [@nontail] + let merge_large_first t_large t_small ~call ~combine ~compare_key = + fold t_small ~init:t_large ~f:(fun ~key ~data:data' t -> + update t key ~compare_key ~f:(function + | None -> data' + | Some data -> call combine ~key data data') [@nontail]) [@nontail] in let call f ~key x y = f ~key x y in let swap f ~key x y = f ~key y x in - fun t1 t2 ~length1 ~length2 ~combine ~compare_key -> - if length2 <= length1 - then merge_large_first length1 t1 t2 ~call ~combine ~compare_key - else merge_large_first length2 t2 t1 ~call:swap ~combine ~compare_key + fun t1 t2 ~combine ~compare_key -> + if length t2 <= length t1 + then merge_large_first t1 t2 ~call ~combine ~compare_key + else merge_large_first t2 t1 ~call:swap ~combine ~compare_key ;; - let merge_disjoint_exn t1 t2 ~length1 ~length2 ~(comparator : _ Comparator.t) = - merge_skewed - t1 - t2 - ~length1 - ~length2 - ~compare_key:comparator.compare - ~combine:(fun ~key _ _ -> - Error.create "Map.merge_disjoint_exn: duplicate key" key comparator.sexp_of_t - |> Error.raise) + let merge_disjoint_exn t1 t2 ~(comparator : _ Comparator.t) = + merge_skewed t1 t2 ~compare_key:comparator.compare ~combine:(fun ~key _ _ -> + Error.create "Map.merge_disjoint_exn: duplicate key" key comparator.sexp_of_t + |> Error.raise) ;; module Closest_key_impl = struct @@ -1765,7 +1829,7 @@ module Tree0 = struct | `Less_than -> c < 0 then Some (k', v') else repackage found_marker found_key found_value - | Node { left = l; key = k'; data = v'; right = r; height = _ } -> + | Node { left = l; key = k'; data = v'; right = r; weight = _ } -> let c = compare_key k' k in if c = 0 then ( @@ -1795,47 +1859,39 @@ module Tree0 = struct let closest_key = Closest_key_impl.closest_key - let rec rank t k ~compare_key = - match t with - | Empty -> None - | Leaf { key = k'; data = _ } -> if compare_key k' k = 0 then Some 0 else None - | Node { left = l; key = k'; data = _; right = r; height = _ } -> - let c = compare_key k' k in - if c = 0 - then Some (length l) - else if c > 0 - then rank l k ~compare_key - else Option.map (rank r k ~compare_key) ~f:(fun rank -> rank + 1 + length l) + let rank t k ~compare_key = + let rec loop t acc = + match t with + | Empty -> None + | Leaf { key = k'; data = _ } -> if compare_key k' k = 0 then Some acc else None + | Node { left = l; key = k'; data = _; right = r; weight = _ } -> + let c = compare_key k' k in + if c = 0 + then Some (acc + length l) + else if c > 0 + then loop l acc + else loop r (acc + length l + 1) + in + loop t 0 [@nontail] ;; - (* this could be implemented using [Sequence] interface but the following implementation - allocates only 2 words and doesn't require write-barrier *) - let rec nth' num_to_search = function - | Empty -> None - | Leaf { key = k; data = v } -> - if !num_to_search = 0 - then Some (k, v) - else ( - decr num_to_search; - None) - | Node { left = l; key = k; data = v; right = r; height = _ } -> - (match nth' num_to_search l with - | Some _ as some -> some - | None -> - if !num_to_search = 0 - then Some (k, v) - else ( - decr num_to_search; - nth' num_to_search r)) + let nth t n = + let rec loop t n = + match t with + | Empty -> assert false + | Leaf { key; data } -> key, data + | Node { left; key; data; right; weight = _ } -> + let l = length left in + if n < l then loop left n else if n = l then key, data else loop right (n - l - 1) + in + if n < 0 || n >= length t then None else Some (loop t n) ;; - let nth t n = nth' (ref n) t - let rec find_first_satisfying t ~f = match t with | Empty -> None | Leaf { key = k; data = v } -> if f ~key:k ~data:v then Some (k, v) else None - | Node { left = l; key = k; data = v; right = r; height = _ } -> + | Node { left = l; key = k; data = v; right = r; weight = _ } -> if f ~key:k ~data:v then ( match find_first_satisfying l ~f with @@ -1848,7 +1904,7 @@ module Tree0 = struct match t with | Empty -> None | Leaf { key = k; data = v } -> if f ~key:k ~data:v then Some (k, v) else None - | Node { left = l; key = k; data = v; right = r; height = _ } -> + | Node { left = l; key = k; data = v; right = r; weight = _ } -> if f ~key:k ~data:v then ( match find_last_satisfying r ~f with @@ -1933,21 +1989,18 @@ module Tree0 = struct type ('k, 'v) acc = { mutable bad_key : 'k option - ; mutable map_length : ('k, 'v) t With_length.t + ; mutable map : ('k, 'v) t } let of_iteri ~iteri ~compare_key = - let acc = { bad_key = None; map_length = with_length_global empty 0 } in + let acc = { bad_key = None; map = empty } in iteri ~f:(fun ~key ~data -> - let { tree = map; length } = acc.map_length in - let ({ tree = _; length = length' } as pair) = - set ~length ~key ~data map ~compare_key - in - if length = length' && Option.is_none acc.bad_key + let new_map = set ~key ~data acc.map ~compare_key in + if length acc.map = length new_map && Option.is_none acc.bad_key then acc.bad_key <- Some key - else acc.map_length <- globalize pair); + else acc.map <- new_map); match acc.bad_key with - | None -> `Ok acc.map_length + | None -> `Ok acc.map | Some key -> `Duplicate_key key ;; @@ -1999,16 +2052,10 @@ module Tree0 = struct = with_return (fun { return } -> `Ok - (fold - t1 - ~init:(with_length_global empty 0) - ~f:(fun ~key ~data { tree = t2; length } -> - let key = f key in - try - add_exn_internal t2 ~length ~key ~data ~compare_key ~sexp_of_key - |> globalize - with - | Duplicate -> return (`Duplicate_key key)))) [@nontail] + (fold t1 ~init:empty ~f:(fun ~key ~data t2 -> + let key = f key in + try add_exn_internal t2 ~key ~data ~compare_key ~sexp_of_key with + | Duplicate -> return (`Duplicate_key key)))) [@nontail] ;; let map_keys_exn t ~f ~comparator = @@ -2021,30 +2068,16 @@ module Tree0 = struct ;; let transpose_keys ~outer_comparator ~inner_comparator outer_t = - fold - outer_t - ~init:(with_length_global empty 0) - ~f:(fun ~key:outer_key ~data:inner_t acc -> - fold - inner_t - ~init:acc - ~f:(fun ~key:inner_key ~data { tree = acc; length = acc_len } -> - (update - acc - inner_key - ~length:acc_len - ~compare_key:inner_comparator.Comparator.compare - ~f:(function - | None -> with_length_global (singleton outer_key data) 1 - | Some { tree = elt; length = elt_len } -> - (set - elt - ~key:outer_key - ~data - ~length:elt_len - ~compare_key:outer_comparator.Comparator.compare - |> globalize) [@nontail]) - |> globalize) [@nontail])) + fold outer_t ~init:empty ~f:(fun ~key:outer_key ~data:inner_t acc -> + fold inner_t ~init:acc ~f:(fun ~key:inner_key ~data acc -> + update acc inner_key ~compare_key:inner_comparator.Comparator.compare ~f:(function + | None -> singleton outer_key data + | Some elt -> + set + elt + ~key:outer_key + ~data + ~compare_key:outer_comparator.Comparator.compare [@nontail]) [@nontail])) ;; module Make_applicative_traversals (A : Applicative.Lazy_applicative) = struct @@ -2053,12 +2086,12 @@ module Tree0 = struct | Empty -> A.return Empty | Leaf { key = v; data = d } -> A.map (f ~key:v ~data:d) ~f:(fun new_data -> Leaf { key = v; data = new_data }) - | Node { left = l; key = v; data = d; right = r; height = h } -> + | Node { left = l; key = v; data = d; right = r; weight = w } -> let l' = A.of_thunk (fun () -> mapi ~f l) in let d' = f ~key:v ~data:d in let r' = A.of_thunk (fun () -> mapi ~f r) in A.map3 l' d' r' ~f:(fun l' d' r' -> - Node { left = l'; key = v; data = d'; right = r'; height = h }) + Node { left = l'; key = v; data = d'; right = r'; weight = w }) ;; (* In theory the computation of length on-the-fly is not necessary here because it can @@ -2068,24 +2101,20 @@ module Tree0 = struct let filter_mapi t ~f = let rec tree_filter_mapi t ~f = match t with - | Empty -> A.return (with_length_global Empty 0) + | Empty -> A.return Empty | Leaf { key = v; data = d } -> A.map (f ~key:v ~data:d) ~f:(function - | Some new_data -> with_length_global (Leaf { key = v; data = new_data }) 1 - | None -> with_length_global Empty 0) - | Node { left = l; key = v; data = d; right = r; height = _ } -> + | Some new_data -> Leaf { key = v; data = new_data } + | None -> Empty) + | Node { left = l; key = v; data = d; right = r; weight = _ } -> A.map3 (A.of_thunk (fun () -> tree_filter_mapi l ~f)) (f ~key:v ~data:d) (A.of_thunk (fun () -> tree_filter_mapi r ~f)) - ~f: - (fun - { tree = l'; length = l_len } new_data { tree = r'; length = r_len } -> + ~f:(fun l' new_data r' -> match new_data with - | Some new_data -> - with_length_global (join l' v new_data r') (l_len + r_len + 1) - | None -> - with_length_global (concat_and_balance_unchecked l' r') (l_len + r_len)) + | Some new_data -> join l' v new_data r' + | None -> concat_and_balance_unchecked l' r') in tree_filter_mapi t ~f ;; @@ -2099,55 +2128,29 @@ type ('k, 'v, 'comparator) t = nonsense. *) comparator : ('k, 'comparator) Comparator.t ; tree : ('k, 'v) Tree0.t - ; length : int } type ('k, 'v, 'comparator) tree = ('k, 'v) Tree0.t let compare_key t = t.comparator.Comparator.compare +let like { tree = _; comparator } tree = { tree; comparator } -let like { tree = _; length = _; comparator } ({ tree; length } : _ With_length.t) = - { tree; length; comparator } +let like_maybe_no_op ({ tree = old_tree; comparator } as old_t) tree = + if phys_equal old_tree tree then old_t else { tree; comparator } ;; -let like_maybe_no_op - ({ tree = old_tree; length = _; comparator } as old_t) - ({ tree; length } : _ With_length.t) - = - if phys_equal old_tree tree then old_t else { tree; length; comparator } -;; - -let with_same_length { tree = _; comparator; length } tree = { tree; comparator; length } -let of_like_tree t tree = { tree; comparator = t.comparator; length = Tree0.length tree } - -let of_like_tree_maybe_no_op t tree = - if phys_equal t.tree tree - then t - else { tree; comparator = t.comparator; length = Tree0.length tree } -;; - -let of_tree ~comparator tree = { tree; comparator; length = Tree0.length tree } - -(* Exposing this function would make it very easy for the invariants - of this module to be broken. *) -let of_tree_unsafe ~comparator ~length tree = { tree; comparator; length } +let with_same_length { tree = _; comparator } tree = { tree; comparator } +let of_tree ~comparator tree = { tree; comparator } module Accessors = struct let comparator t = t.comparator let to_tree t = t.tree - - let invariants t = - Tree0.invariants t.tree ~compare_key:(compare_key t) && Tree0.length t.tree = t.length - ;; - + let invariants t = Tree0.invariants t.tree ~compare_key:(compare_key t) let is_empty t = Tree0.is_empty t.tree - let length t = t.length + let length t = Tree0.length t.tree let set t ~key ~data = - like - t - (Tree0.set t.tree ~length:t.length ~key ~data ~compare_key:(compare_key t)) - [@nontail] + like t (Tree0.set t.tree ~key ~data ~compare_key:(compare_key t)) [@nontail] ;; let add_exn t ~key ~data = @@ -2155,7 +2158,6 @@ module Accessors = struct t (Tree0.add_exn t.tree - ~length:t.length ~key ~data ~compare_key:(compare_key t) @@ -2167,7 +2169,6 @@ module Accessors = struct t (Tree0.add_exn_internal t.tree - ~length:t.length ~key ~data ~compare_key:(compare_key t) @@ -2181,33 +2182,28 @@ module Accessors = struct ;; let add_multi t ~key ~data = - like - t - (Tree0.add_multi t.tree ~length:t.length ~key ~data ~compare_key:(compare_key t)) - [@nontail] + like t (Tree0.add_multi t.tree ~key ~data ~compare_key:(compare_key t)) [@nontail] ;; let remove_multi t key = - like - t - (Tree0.remove_multi t.tree ~length:t.length key ~compare_key:(compare_key t)) - [@nontail] + like t (Tree0.remove_multi t.tree key ~compare_key:(compare_key t)) [@nontail] ;; let find_multi t key = Tree0.find_multi t.tree key ~compare_key:(compare_key t) let change t key ~f = - like - t - (Tree0.change t.tree key ~f ~length:t.length ~compare_key:(compare_key t)) - [@nontail] + like t (Tree0.change t.tree key ~f ~compare_key:(compare_key t)) [@nontail] ;; let update t key ~f = - like - t - (Tree0.update t.tree key ~f ~length:t.length ~compare_key:(compare_key t)) - [@nontail] + like t (Tree0.update t.tree key ~f ~compare_key:(compare_key t)) [@nontail] + ;; + + let update_and_return t key ~f = + let result, new_t = + Tree0.update_and_return t.tree key ~f ~compare_key:(compare_key t) + in + Modes.Global.unwrap result, like t new_t ;; let find_exn t key = @@ -2221,9 +2217,7 @@ module Accessors = struct let find t key = Tree0.find t.tree key ~compare_key:(compare_key t) let remove t key = - like_maybe_no_op - t - (Tree0.remove t.tree key ~length:t.length ~compare_key:(compare_key t)) [@nontail] + like_maybe_no_op t (Tree0.remove t.tree key ~compare_key:(compare_key t)) [@nontail] ;; let mem t key = Tree0.mem t.tree key ~compare_key:(compare_key t) @@ -2243,53 +2237,44 @@ module Accessors = struct ;; let filter_keys t ~f = - let len = ref t.length in - let tree = Tree0.filter_keys t.tree ~f ~len in - like_maybe_no_op t (with_length tree !len) [@nontail] + let tree = Tree0.filter_keys t.tree ~f in + like_maybe_no_op t tree [@nontail] ;; let filter t ~f = - let len = ref t.length in - let tree = Tree0.filter t.tree ~f ~len in - like_maybe_no_op t (with_length tree !len) [@nontail] + let tree = Tree0.filter t.tree ~f in + like_maybe_no_op t tree [@nontail] ;; let filteri t ~f = - let len = ref t.length in - let tree = Tree0.filteri t.tree ~f ~len in - like_maybe_no_op t (with_length tree !len) [@nontail] + let tree = Tree0.filteri t.tree ~f in + like_maybe_no_op t tree [@nontail] ;; let filter_map t ~f = - let len = ref t.length in - let tree = Tree0.filter_map t.tree ~f ~len in - like t (with_length tree !len) [@nontail] + let tree = Tree0.filter_map t.tree ~f in + like t tree [@nontail] ;; let filter_mapi t ~f = - let len = ref t.length in - let tree = Tree0.filter_mapi t.tree ~f ~len in - like t (with_length tree !len) [@nontail] - ;; - - let of_like_tree2 t (t1, t2) = of_like_tree t t1, of_like_tree t t2 - - let of_like_tree2_maybe_no_op t (t1, t2) = - of_like_tree_maybe_no_op t t1, of_like_tree_maybe_no_op t t2 + let tree = Tree0.filter_mapi t.tree ~f in + like t tree [@nontail] ;; - let partition_mapi t ~f = of_like_tree2 t (Tree0.partition_mapi t.tree ~f) - let partition_map t ~f = of_like_tree2 t (Tree0.partition_map t.tree ~f) - let partitioni_tf t ~f = of_like_tree2_maybe_no_op t (Tree0.partitioni_tf t.tree ~f) - let partition_tf t ~f = of_like_tree2_maybe_no_op t (Tree0.partition_tf t.tree ~f) + let like2 t (t1, t2) = like t t1, like t t2 + let like2_maybe_no_op t (t1, t2) = like_maybe_no_op t t1, like_maybe_no_op t t2 + let partition_mapi t ~f = like2 t (Tree0.partition_mapi t.tree ~f) + let partition_map t ~f = like2 t (Tree0.partition_map t.tree ~f) + let partitioni_tf t ~f = like2_maybe_no_op t (Tree0.partitioni_tf t.tree ~f) + let partition_tf t ~f = like2_maybe_no_op t (Tree0.partition_tf t.tree ~f) let combine_errors t = Or_error.map - ~f:(of_like_tree t) + ~f:(like t) (Tree0.combine_errors t.tree ~sexp_of_key:t.comparator.sexp_of_t) ;; - let unzip t = of_like_tree2 t (Tree0.unzip t.tree) + let unzip t = like2 t (Tree0.unzip t.tree) let compare_direct compare_data t1 t2 = Tree0.compare (compare_key t1) compare_data t1.tree t2.tree @@ -2321,25 +2306,14 @@ module Accessors = struct let merge_disjoint_exn t1 t2 = like t1 - (Tree0.merge_disjoint_exn - t1.tree - t2.tree - ~length1:t1.length - ~length2:t2.length - ~comparator:t1.comparator) [@nontail] + (Tree0.merge_disjoint_exn t1.tree t2.tree ~comparator:t1.comparator) [@nontail] ;; let merge_skewed t1 t2 ~combine = (* This is only a no-op in the case where at least one of the maps is empty. *) like_maybe_no_op - (if t2.length <= t1.length then t1 else t2) - (Tree0.merge_skewed - t1.tree - t2.tree - ~length1:t1.length - ~length2:t2.length - ~combine - ~compare_key:(compare_key t1)) + (if length t2 <= length t1 then t1 else t2) + (Tree0.merge_skewed t1.tree t2.tree ~combine ~compare_key:(compare_key t1)) ;; let min_elt t = Tree0.min_elt t.tree @@ -2357,54 +2331,22 @@ module Accessors = struct let split t k = let l, maybe, r = Tree0.split t.tree k ~compare_key:(compare_key t) in - let comparator = comparator t in - (* Try to traverse the least amount possible to calculate the length, - using height as a heuristic. *) - let both_len = if Option.is_some maybe then t.length - 1 else t.length in - if Tree0.height l < Tree0.height r - then ( - let l = of_tree l ~comparator in - l, maybe, of_tree_unsafe r ~comparator ~length:(both_len - length l)) - else ( - let r = of_tree r ~comparator in - of_tree_unsafe l ~comparator ~length:(both_len - length r), maybe, r) + like t l, maybe, like t r ;; let split_and_reinsert_boundary t ~into k = - let l, r = - Tree0.split_and_reinsert_boundary t.tree ~into k ~compare_key:(compare_key t) - in - let comparator = comparator t in - (* Try to traverse the least amount possible to calculate the length, - using height as a heuristic. *) - if Tree0.height l < Tree0.height r - then ( - let l = of_tree l ~comparator in - l, of_tree_unsafe r ~comparator ~length:(t.length - length l)) - else ( - let r = of_tree r ~comparator in - of_tree_unsafe l ~comparator ~length:(t.length - length r), r) + Tree0.split_and_reinsert_boundary t.tree ~into k ~compare_key:(compare_key t) + |> like2 t ;; let split_le_gt t k = split_and_reinsert_boundary t ~into:`Left k let split_lt_ge t k = split_and_reinsert_boundary t ~into:`Right k let subrange t ~lower_bound ~upper_bound = - let left, mid, right = + let _, mid, _ = Tree0.split_range t.tree ~lower_bound ~upper_bound ~compare_key:(compare_key t) in - (* Try to traverse the least amount possible to calculate the length, - using height as a heuristic. *) - let outer_joined_height = - let h_l = Tree0.height left - and h_r = Tree0.height right in - if h_l = h_r then h_l + 1 else max h_l h_r - in - if outer_joined_height < Tree0.height mid - then ( - let mid_length = t.length - (Tree0.length left + Tree0.length right) in - of_tree_unsafe mid ~comparator:(comparator t) ~length:mid_length) - else of_tree mid ~comparator:(comparator t) + like t mid ;; let append ~lower_part ~upper_part = @@ -2414,12 +2356,7 @@ module Accessors = struct ~lower_part:lower_part.tree ~upper_part:upper_part.tree with - | `Ok tree -> - `Ok - (of_tree_unsafe - tree - ~comparator:(comparator lower_part) - ~length:(lower_part.length + upper_part.length)) + | `Ok tree -> `Ok (of_tree tree ~comparator:(comparator lower_part)) | `Overlapping_key_ranges -> `Overlapping_key_ranges ;; @@ -2464,7 +2401,7 @@ module Accessors = struct Tree0.binary_search_two_sided_bounds t.tree ~compare ~lower_bound ~upper_bound with | Some (lower_bound, upper_bound) -> subrange t ~lower_bound ~upper_bound - | None -> like_maybe_no_op t (with_length Tree0.Empty 0) [@nontail] + | None -> like_maybe_no_op t Tree0.Empty [@nontail] ;; module Make_applicative_traversals (A : Applicative.Lazy_applicative) = struct @@ -2493,125 +2430,96 @@ module Tree = struct let singleton ~comparator:_ k v = Tree0.singleton k v let of_sorted_array_unchecked ~comparator array = - (Tree0.of_sorted_array_unchecked array ~compare_key:comparator.Comparator.compare) - .tree + Tree0.of_sorted_array_unchecked array ~compare_key:comparator.Comparator.compare ;; let of_sorted_array ~comparator array = Tree0.of_sorted_array array ~compare_key:comparator.Comparator.compare - |> Or_error.map ~f:(fun (x : ('k, 'v) Tree0.t With_length.t) -> x.tree) ;; let of_alist ~comparator alist = - match Tree0.of_alist alist ~compare_key:comparator.Comparator.compare with - | `Duplicate_key _ as d -> d - | `Ok { tree; length = _ } -> `Ok tree + Tree0.of_alist alist ~compare_key:comparator.Comparator.compare ;; - let of_alist_or_error ~comparator alist = - Tree0.of_alist_or_error alist ~comparator - |> Or_error.map ~f:(fun (x : ('k, 'v) Tree0.t With_length.t) -> x.tree) - ;; - - let of_alist_exn ~comparator alist = (Tree0.of_alist_exn alist ~comparator).tree + let of_alist_or_error ~comparator alist = Tree0.of_alist_or_error alist ~comparator + let of_alist_exn ~comparator alist = Tree0.of_alist_exn alist ~comparator let of_alist_multi ~comparator alist = - (Tree0.of_alist_multi alist ~compare_key:comparator.Comparator.compare).tree + Tree0.of_alist_multi alist ~compare_key:comparator.Comparator.compare ;; let of_alist_fold ~comparator alist ~init ~f = - (Tree0.of_alist_fold alist ~init ~f ~compare_key:comparator.Comparator.compare).tree + Tree0.of_alist_fold alist ~init ~f ~compare_key:comparator.Comparator.compare ;; let of_alist_reduce ~comparator alist ~f = - (Tree0.of_alist_reduce alist ~f ~compare_key:comparator.Comparator.compare).tree + Tree0.of_alist_reduce alist ~f ~compare_key:comparator.Comparator.compare ;; let of_iteri ~comparator ~iteri = - match Tree0.of_iteri ~iteri ~compare_key:comparator.Comparator.compare with - | `Ok { tree; length = _ } -> `Ok tree - | `Duplicate_key _ as d -> d + Tree0.of_iteri ~iteri ~compare_key:comparator.Comparator.compare ;; - let of_iteri_exn ~comparator ~iteri = (Tree0.of_iteri_exn ~iteri ~comparator).tree + let of_iteri_exn ~comparator ~iteri = Tree0.of_iteri_exn ~iteri ~comparator let of_increasing_iterator_unchecked ~comparator:_required_by_intf ~len ~f = Tree0.of_increasing_iterator_unchecked ~len ~f ;; let of_increasing_sequence ~comparator seq = - Or_error.map - ~f:(fun (x : ('k, 'v) Tree0.t With_length.t) -> x.tree) - (Tree0.of_increasing_sequence seq ~compare_key:comparator.Comparator.compare) + Tree0.of_increasing_sequence seq ~compare_key:comparator.Comparator.compare ;; let of_sequence ~comparator seq = - match Tree0.of_sequence seq ~compare_key:comparator.Comparator.compare with - | `Duplicate_key _ as d -> d - | `Ok { tree; length = _ } -> `Ok tree + Tree0.of_sequence seq ~compare_key:comparator.Comparator.compare ;; - let of_sequence_or_error ~comparator seq = - Tree0.of_sequence_or_error seq ~comparator - |> Or_error.map ~f:(fun (x : ('k, 'v) Tree0.t With_length.t) -> x.tree) - ;; - - let of_sequence_exn ~comparator seq = (Tree0.of_sequence_exn seq ~comparator).tree + let of_sequence_or_error ~comparator seq = Tree0.of_sequence_or_error seq ~comparator + let of_sequence_exn ~comparator seq = Tree0.of_sequence_exn seq ~comparator let of_sequence_multi ~comparator seq = - (Tree0.of_sequence_multi seq ~compare_key:comparator.Comparator.compare).tree + Tree0.of_sequence_multi seq ~compare_key:comparator.Comparator.compare ;; let of_sequence_fold ~comparator seq ~init ~f = - (Tree0.of_sequence_fold seq ~init ~f ~compare_key:comparator.Comparator.compare).tree + Tree0.of_sequence_fold seq ~init ~f ~compare_key:comparator.Comparator.compare ;; let of_sequence_reduce ~comparator seq ~f = - (Tree0.of_sequence_reduce seq ~f ~compare_key:comparator.Comparator.compare).tree + Tree0.of_sequence_reduce seq ~f ~compare_key:comparator.Comparator.compare ;; let of_list_with_key ~comparator list ~get_key = - match - Tree0.of_list_with_key list ~get_key ~compare_key:comparator.Comparator.compare - with - | `Duplicate_key _ as d -> d - | `Ok { tree; length = _ } -> `Ok tree + Tree0.of_list_with_key list ~get_key ~compare_key:comparator.Comparator.compare ;; let of_list_with_key_or_error ~comparator list ~get_key = Tree0.of_list_with_key_or_error list ~get_key ~comparator - |> Or_error.map ~f:(fun (x : ('k, 'v) Tree0.t With_length.t) -> x.tree) ;; let of_list_with_key_exn ~comparator list ~get_key = - (Tree0.of_list_with_key_exn list ~get_key ~comparator).tree + Tree0.of_list_with_key_exn list ~get_key ~comparator ;; let of_list_with_key_multi ~comparator list ~get_key = - (Tree0.of_list_with_key_multi - list - ~get_key - ~compare_key:comparator.Comparator.compare) - .tree + Tree0.of_list_with_key_multi list ~get_key ~compare_key:comparator.Comparator.compare ;; let of_list_with_key_fold ~comparator list ~get_key ~init ~f = - (Tree0.of_list_with_key_fold - list - ~get_key - ~init - ~f - ~compare_key:comparator.Comparator.compare) - .tree + Tree0.of_list_with_key_fold + list + ~get_key + ~init + ~f + ~compare_key:comparator.Comparator.compare ;; let of_list_with_key_reduce ~comparator list ~get_key ~f = - (Tree0.of_list_with_key_reduce - list - ~get_key - ~f - ~compare_key:comparator.Comparator.compare) - .tree + Tree0.of_list_with_key_reduce + list + ~get_key + ~f + ~compare_key:comparator.Comparator.compare ;; let to_tree t = t @@ -2624,29 +2532,25 @@ module Tree = struct let length t = Tree0.length t let set ~comparator t ~key ~data = - (Tree0.set t ~key ~data ~length:0 ~compare_key:comparator.Comparator.compare).tree + Tree0.set t ~key ~data ~compare_key:comparator.Comparator.compare ;; let add_exn ~comparator t ~key ~data = - (Tree0.add_exn - t - ~key - ~data - ~length:0 - ~compare_key:comparator.Comparator.compare - ~sexp_of_key:comparator.sexp_of_t) - .tree + Tree0.add_exn + t + ~key + ~data + ~compare_key:comparator.Comparator.compare + ~sexp_of_key:comparator.sexp_of_t ;; let add_exn_internal ~comparator t ~key ~data = - (Tree0.add_exn_internal - t - ~key - ~data - ~length:0 - ~compare_key:comparator.Comparator.compare - ~sexp_of_key:comparator.sexp_of_t) - .tree + Tree0.add_exn_internal + t + ~key + ~data + ~compare_key:comparator.Comparator.compare + ~sexp_of_key:comparator.sexp_of_t ;; let add ~comparator t ~key ~data = @@ -2655,12 +2559,11 @@ module Tree = struct ;; let add_multi ~comparator t ~key ~data = - (Tree0.add_multi t ~key ~data ~length:0 ~compare_key:comparator.Comparator.compare) - .tree + Tree0.add_multi t ~key ~data ~compare_key:comparator.Comparator.compare ;; let remove_multi ~comparator t key = - (Tree0.remove_multi t key ~length:0 ~compare_key:comparator.Comparator.compare).tree + Tree0.remove_multi t key ~compare_key:comparator.Comparator.compare ;; let find_multi ~comparator t key = @@ -2668,11 +2571,18 @@ module Tree = struct ;; let change ~comparator t key ~f = - (Tree0.change t key ~f ~length:0 ~compare_key:comparator.Comparator.compare).tree + Tree0.change t key ~f ~compare_key:comparator.Comparator.compare ;; let update ~comparator t key ~f = - change ~comparator t key ~f:(fun data -> Some (f data)) [@nontail] + Tree0.update t key ~f ~compare_key:comparator.Comparator.compare + ;; + + let update_and_return ~comparator t key ~f = + let result, tree = + Tree0.update_and_return t key ~f ~compare_key:comparator.Comparator.compare + in + Modes.Global.unwrap result, tree ;; let find_exn ~comparator t key = @@ -2686,7 +2596,7 @@ module Tree = struct let find ~comparator t key = Tree0.find t key ~compare_key:comparator.Comparator.compare let remove ~comparator t key = - (Tree0.remove t key ~length:0 ~compare_key:comparator.Comparator.compare).tree + Tree0.remove t key ~compare_key:comparator.Comparator.compare ;; let mem ~comparator t key = Tree0.mem t key ~compare_key:comparator.Comparator.compare @@ -2709,11 +2619,11 @@ module Tree = struct Tree0.fold2 t1 t2 ~init ~f ~compare_key:comparator.Comparator.compare ;; - let filter_keys t ~f = Tree0.filter_keys t ~f ~len:(ref 0) [@nontail] - let filter t ~f = Tree0.filter t ~f ~len:(ref 0) [@nontail] - let filteri t ~f = Tree0.filteri t ~f ~len:(ref 0) [@nontail] - let filter_map t ~f = Tree0.filter_map t ~f ~len:(ref 0) [@nontail] - let filter_mapi t ~f = Tree0.filter_mapi t ~f ~len:(ref 0) [@nontail] + let filter_keys t ~f = Tree0.filter_keys t ~f + let filter t ~f = Tree0.filter t ~f + let filteri t ~f = Tree0.filteri t ~f + let filter_map t ~f = Tree0.filter_map t ~f + let filter_mapi t ~f = Tree0.filter_mapi t ~f let partition_mapi t ~f = Tree0.partition_mapi t ~f let partition_map t ~f = Tree0.partition_map t ~f let partitioni_tf t ~f = Tree0.partitioni_tf t ~f @@ -2752,25 +2662,13 @@ module Tree = struct ;; let merge ~comparator t1 t2 ~f = - (Tree0.merge t1 t2 ~f ~compare_key:comparator.Comparator.compare).tree + Tree0.merge t1 t2 ~f ~compare_key:comparator.Comparator.compare ;; - let merge_disjoint_exn ~comparator t1 t2 = - (Tree0.merge_disjoint_exn t1 t2 ~length1:(length t1) ~length2:(length t2) ~comparator) - .tree - ;; + let merge_disjoint_exn ~comparator t1 t2 = Tree0.merge_disjoint_exn t1 t2 ~comparator let merge_skewed ~comparator t1 t2 ~combine = - (* Length computation makes this significantly slower than [merge_skewed] on a map - with a [length] field, but does preserve amount of allocation. *) - (Tree0.merge_skewed - t1 - t2 - ~length1:(length t1) - ~length2:(length t2) - ~combine - ~compare_key:comparator.Comparator.compare) - .tree + Tree0.merge_skewed t1 t2 ~combine ~compare_key:comparator.Comparator.compare ;; let min_elt t = Tree0.min_elt t @@ -2842,7 +2740,7 @@ module Tree = struct let sexp_of_t sexp_of_k sexp_of_v _ t = Tree0.sexp_of_t sexp_of_k sexp_of_v t let t_of_sexp_direct ~comparator k_of_sexp v_of_sexp sexp = - (Tree0.t_of_sexp_direct k_of_sexp v_of_sexp sexp ~comparator).tree + Tree0.t_of_sexp_direct k_of_sexp v_of_sexp sexp ~comparator ;; let to_sequence ~comparator ?order ?keys_greater_or_equal_to ?keys_less_or_equal_to t = @@ -2861,25 +2759,10 @@ module Tree = struct | None -> Empty ;; - module Make_applicative_traversals (A : Applicative.Lazy_applicative) = struct - module Tree0_traversals = Tree0.Make_applicative_traversals (A) - - let mapi t ~f = Tree0_traversals.mapi t ~f - - let filter_mapi t ~f = - A.map - (Tree0_traversals.filter_mapi t ~f) - ~f:(fun (x : ('k, 'v) Tree0.t With_length.t) -> x.tree) - ;; - end - - let map_keys ~comparator t ~f = - match Tree0.map_keys ~comparator t ~f with - | `Ok { tree = t; length = _ } -> `Ok t - | `Duplicate_key _ as dup -> dup - ;; + module Make_applicative_traversals = Tree0.Make_applicative_traversals - let map_keys_exn ~comparator t ~f = (Tree0.map_keys_exn ~comparator t ~f).tree + let map_keys ~comparator t ~f = Tree0.map_keys ~comparator t ~f + let map_keys_exn ~comparator t ~f = Tree0.map_keys_exn ~comparator t ~f (* This calling convention of [~comparator ~comparator] is confusing. It is required because [access_options] and [create_options] both demand a [~comparator] argument in @@ -2889,8 +2772,7 @@ module Tree = struct Better to just live with an undesirable interface in a function that will probably never be called directly. *) let transpose_keys ~comparator:outer_comparator ~comparator:inner_comparator t = - (Tree0.transpose_keys ~outer_comparator ~inner_comparator t).tree - |> map ~f:(fun (x : ('k, 'v) Tree0.t With_length.t) -> x.tree) + Tree0.transpose_keys ~outer_comparator ~inner_comparator t ;; module Build_increasing = struct @@ -2914,21 +2796,13 @@ module Using_comparator = struct include Accessors - let empty ~comparator = { tree = Tree0.empty; comparator; length = 0 } - let singleton ~comparator k v = { comparator; tree = Tree0.singleton k v; length = 1 } - - let of_tree0 ~comparator ({ tree; length } : _ With_length.t) = - { comparator; tree; length } - ;; - - let of_tree ~comparator tree = - of_tree0 ~comparator (with_length tree (Tree0.length tree)) [@nontail] - ;; - + let empty ~comparator = { tree = Tree0.empty; comparator } + let singleton ~comparator k v = { comparator; tree = Tree0.singleton k v } + let of_tree ~comparator tree = { comparator; tree } let to_tree = to_tree let of_sorted_array_unchecked ~comparator array = - of_tree0 + of_tree ~comparator (Tree0.of_sorted_array_unchecked array ~compare_key:comparator.Comparator.compare) [@nontail] @@ -2937,93 +2811,91 @@ module Using_comparator = struct let of_sorted_array ~comparator array = Or_error.map (Tree0.of_sorted_array array ~compare_key:comparator.Comparator.compare) - ~f:(fun tree -> of_tree0 ~comparator tree) + ~f:(fun tree -> of_tree ~comparator tree) ;; let of_alist ~comparator alist = match Tree0.of_alist alist ~compare_key:comparator.Comparator.compare with - | `Ok { tree; length } -> `Ok { comparator; tree; length } + | `Ok tree -> `Ok (of_tree ~comparator tree) | `Duplicate_key _ as z -> z ;; let of_alist_or_error ~comparator alist = Result.map (Tree0.of_alist_or_error alist ~comparator) ~f:(fun tree -> - of_tree0 ~comparator tree) + of_tree ~comparator tree) ;; let of_alist_exn ~comparator alist = - of_tree0 ~comparator (Tree0.of_alist_exn alist ~comparator) + of_tree ~comparator (Tree0.of_alist_exn alist ~comparator) ;; let of_alist_multi ~comparator alist = - of_tree0 + of_tree ~comparator (Tree0.of_alist_multi alist ~compare_key:comparator.Comparator.compare) ;; let of_alist_fold ~comparator alist ~init ~f = - of_tree0 + of_tree ~comparator (Tree0.of_alist_fold alist ~init ~f ~compare_key:comparator.Comparator.compare) ;; let of_alist_reduce ~comparator alist ~f = - of_tree0 + of_tree ~comparator (Tree0.of_alist_reduce alist ~f ~compare_key:comparator.Comparator.compare) ;; let of_iteri ~comparator ~iteri = match Tree0.of_iteri ~compare_key:comparator.Comparator.compare ~iteri with - | `Ok tree_length -> `Ok (of_tree0 ~comparator tree_length) + | `Ok tree_length -> `Ok (of_tree ~comparator tree_length) | `Duplicate_key _ as z -> z ;; let of_iteri_exn ~comparator ~iteri = - of_tree0 ~comparator (Tree0.of_iteri_exn ~comparator ~iteri) + of_tree ~comparator (Tree0.of_iteri_exn ~comparator ~iteri) ;; let of_increasing_iterator_unchecked ~comparator ~len ~f = - of_tree0 - ~comparator - (with_length (Tree0.of_increasing_iterator_unchecked ~len ~f) len) [@nontail] + of_tree ~comparator (Tree0.of_increasing_iterator_unchecked ~len ~f) [@nontail] ;; let of_increasing_sequence ~comparator seq = Or_error.map - ~f:(fun x -> of_tree0 ~comparator x) + ~f:(fun x -> of_tree ~comparator x) (Tree0.of_increasing_sequence seq ~compare_key:comparator.Comparator.compare) ;; let of_sequence ~comparator seq = match Tree0.of_sequence seq ~compare_key:comparator.Comparator.compare with - | `Ok { tree; length } -> `Ok { comparator; tree; length } + | `Ok tree -> `Ok (of_tree ~comparator tree) | `Duplicate_key _ as z -> z ;; let of_sequence_or_error ~comparator seq = Result.map (Tree0.of_sequence_or_error seq ~comparator) ~f:(fun tree -> - of_tree0 ~comparator tree) + of_tree ~comparator tree) ;; let of_sequence_exn ~comparator seq = - of_tree0 ~comparator (Tree0.of_sequence_exn seq ~comparator) + of_tree ~comparator (Tree0.of_sequence_exn seq ~comparator) ;; let of_sequence_multi ~comparator seq = - of_tree0 + of_tree ~comparator (Tree0.of_sequence_multi seq ~compare_key:comparator.Comparator.compare) ;; let of_sequence_fold ~comparator seq ~init ~f = - of_tree0 + of_tree ~comparator (Tree0.of_sequence_fold seq ~init ~f ~compare_key:comparator.Comparator.compare) ;; let of_sequence_reduce ~comparator seq ~f = - of_tree0 + of_tree ~comparator (Tree0.of_sequence_reduce seq ~f ~compare_key:comparator.Comparator.compare) ;; @@ -3032,22 +2904,22 @@ module Using_comparator = struct match Tree0.of_list_with_key list ~get_key ~compare_key:comparator.Comparator.compare with - | `Ok { tree; length } -> `Ok { comparator; tree; length } + | `Ok tree -> `Ok (of_tree ~comparator tree) | `Duplicate_key _ as z -> z ;; let of_list_with_key_or_error ~comparator list ~get_key = Result.map (Tree0.of_list_with_key_or_error list ~get_key ~comparator) ~f:(fun tree -> - of_tree0 ~comparator tree) + of_tree ~comparator tree) ;; let of_list_with_key_exn ~comparator list ~get_key = - of_tree0 ~comparator (Tree0.of_list_with_key_exn list ~get_key ~comparator) + of_tree ~comparator (Tree0.of_list_with_key_exn list ~get_key ~comparator) ;; let of_list_with_key_multi ~comparator list ~get_key = Tree0.of_list_with_key_multi list ~get_key ~compare_key:comparator.Comparator.compare - |> of_tree0 ~comparator + |> of_tree ~comparator ;; let of_list_with_key_fold ~comparator list ~get_key ~init ~f = @@ -3057,7 +2929,7 @@ module Using_comparator = struct ~init ~f ~compare_key:comparator.Comparator.compare - |> of_tree0 ~comparator + |> of_tree ~comparator ;; let of_list_with_key_reduce ~comparator list ~get_key ~f = @@ -3066,32 +2938,32 @@ module Using_comparator = struct ~get_key ~f ~compare_key:comparator.Comparator.compare - |> of_tree0 ~comparator + |> of_tree ~comparator ;; let t_of_sexp_direct ~comparator k_of_sexp v_of_sexp sexp = - of_tree0 ~comparator (Tree0.t_of_sexp_direct k_of_sexp v_of_sexp sexp ~comparator) + of_tree ~comparator (Tree0.t_of_sexp_direct k_of_sexp v_of_sexp sexp ~comparator) ;; let map_keys ~comparator t ~f = match Tree0.map_keys t.tree ~f ~comparator with - | `Ok pair -> `Ok (of_tree0 ~comparator pair) + | `Ok pair -> `Ok (of_tree ~comparator pair) | `Duplicate_key _ as dup -> dup ;; let map_keys_exn ~comparator t ~f = - of_tree0 ~comparator (Tree0.map_keys_exn t.tree ~f ~comparator) + of_tree ~comparator (Tree0.map_keys_exn t.tree ~f ~comparator) ;; let transpose_keys ~comparator:inner_comparator t = let outer_comparator = t.comparator in Tree0.transpose_keys ~outer_comparator ~inner_comparator (Tree0.map t.tree ~f:to_tree) - |> of_tree0 ~comparator:inner_comparator - |> map ~f:(fun x -> of_tree0 ~comparator:outer_comparator x) + |> of_tree ~comparator:inner_comparator + |> map ~f:(fun x -> of_tree ~comparator:outer_comparator x) ;; module Empty_without_value_restriction (K : Comparator.S1) = struct - let empty = { tree = Tree0.empty; comparator = K.comparator; length = 0 } + let empty = { tree = Tree0.empty; comparator = K.comparator } end module Tree = Tree @@ -3285,7 +3157,7 @@ module Poly = struct include Accessors let comparator = Comparator.Poly.comparator - let of_tree tree = { tree; comparator; length = Tree0.length tree } + let of_tree tree = { tree; comparator } include Using_comparator.Empty_without_value_restriction (Comparator.Poly) @@ -3355,8 +3227,30 @@ module Private = struct type ('k, 'v) t = ('k, 'v) Tree0.t let balance_invariants t = Tree0.balance_invariants t - let are_balanced t1 t2 = abs (Tree0.height t1 - Tree0.height t2) <= 2 - let are_almost_balanced t1 t2 = abs (Tree0.height t1 - Tree0.height t2) <= 3 + + let are_balanced t1 t2 = + let w1 = Tree0.weight t1 + and w2 = Tree0.weight t2 in + (not (Tree0.is_too_heavy ~weight:w1 ~for_weight:w2)) + && not (Tree0.is_too_heavy ~weight:w2 ~for_weight:w1) + ;; + + let are_almost_balanced t1 t2 = + let w1 = Tree0.weight t1 + and w2 = Tree0.weight t2 in + match t1, t2 with + | Node node, _ when Tree0.is_too_heavy ~weight:w1 ~for_weight:w2 -> + (not (Tree0.is_too_heavy ~weight:(w1 - 1) ~for_weight:w2)) + && Tree0.may_rotate_just_once + ~inner_sibling_weight:(Tree0.weight node.right) + ~outer_sibling_weight:(Tree0.weight node.left) + | _, Node node when Tree0.is_too_heavy ~weight:w2 ~for_weight:w1 -> + (not (Tree0.is_too_heavy ~weight:(w2 - 1) ~for_weight:w1)) + && Tree0.may_rotate_just_once + ~inner_sibling_weight:(Tree0.weight node.left) + ~outer_sibling_weight:(Tree0.weight node.right) + | _ -> true + ;; let expose t = match (t : (_, _) Tree0.t) with diff --git a/src/map_intf.ml b/src/map_intf.ml index 1281c83..3ff535f 100644 --- a/src/map_intf.ml +++ b/src/map_intf.ml @@ -1115,6 +1115,14 @@ module type Map = sig (** [update t key ~f] is [change t key ~f:(fun o -> Some (f o))]. *) val update : ('k, 'v, 'cmp) t -> 'k -> f:('v option -> 'v) -> ('k, 'v, 'cmp) t + (** [update_and_return t key ~f] is like [update t key ~f], but also returns the new + value. *) + val update_and_return + : ('k, 'v, 'cmp) t + -> 'k + -> f:('v option -> 'v) + -> 'v * ('k, 'v, 'cmp) t + (** Returns [Some value] bound to the given key, or [None] if none exists. *) val find : ('k, 'v, 'cmp) t -> 'k -> 'v option diff --git a/src/nativeint.ml b/src/nativeint.ml index e221494..f2ca97f 100644 --- a/src/nativeint.ml +++ b/src/nativeint.ml @@ -322,6 +322,14 @@ include O (* [Nativeint] and [Nativeint.O] agree value-wise *) +module Summable = struct + type nonrec t = t + + let zero = zero + let[@inline] ( + ) x y = x + y + let[@inline] ( - ) x y = x - y +end + (* Include type-specific [Replace_polymorphic_compare] at the end, after including functor application that could shadow its definitions. This is here so that efficient versions of the comparison functions are exported by diff --git a/src/option.ml b/src/option.ml index dbb5ed3..3190630 100644 --- a/src/option.ml +++ b/src/option.ml @@ -109,30 +109,25 @@ let[@inline] value t ~default = (value_local (Modes.Global.wrap_option t) ~default:{ global = default }).global ;; -let value_local_exn ?here ?error ?message t = +let value_local_exn ?(here = Stdlib.Lexing.dummy_pos) ?error ?message t = match t with | Some x -> x | None -> let error = - match here, error, message with - | None, None, None -> Error.of_string "Option.value_exn None" - | None, None, Some m -> Error.of_string m - | None, Some e, None -> e - | None, Some e, Some m -> Error.tag e ~tag:m - | Some p, None, None -> - Error.create "Option.value_exn" p Source_code_position0.sexp_of_t - | Some p, None, Some m -> Error.create m p Source_code_position0.sexp_of_t - | Some p, Some e, _ -> - Error.create - (value message ~default:"") - (e, p) - (sexp_of_pair Error.sexp_of_t Source_code_position0.sexp_of_t) + match error, message with + | None, None -> + if Source_code_position.is_dummy here + then Error.of_string "Option.value_exn None" + else Error.create "Option.value_exn None" here Source_code_position0.sexp_of_t + | Some e, None -> e + | None, Some m -> Error.of_string m + | Some e, Some m -> Error.tag e ~tag:m in Error.raise error ;; -let[@inline] value_exn ?here ?error ?message t = - (value_local_exn ?here ?error ?message (Modes.Global.wrap_option t)).global +let[@inline] value_exn ?(here = Stdlib.Lexing.dummy_pos) ?error ?message t = + (value_local_exn ~here ?error ?message (Modes.Global.wrap_option t)).global ;; let value_or_thunk_local o ~default = diff --git a/src/option.mli b/src/option.mli index a6e1111..dd11095 100644 --- a/src/option.mli +++ b/src/option.mli @@ -74,10 +74,10 @@ val value : 'a t -> default:'a -> 'a val value_local : 'a t -> default:'a -> 'a (** Extracts the underlying value, or raises if there is no value present. The - error raised can be augmented using the [~here], [~error], and [~message] - optional arguments. *) + raised error can be augmented using the [~error] and [~message] optional arguments. + If neither is provided, the raised error will include the provided location. *) val value_exn - : ?here:Source_code_position0.t + : ?here:Stdlib.Lexing.position -> ?error:Error.t -> ?message:string -> 'a t @@ -85,7 +85,7 @@ val value_exn (** Like [value_exn], but over a local [t]. *) val value_local_exn - : ?here:Source_code_position0.t + : ?here:Stdlib.Lexing.position -> ?error:Error.t -> ?message:string -> 'a t diff --git a/src/ppx_compare_lib.ml b/src/ppx_compare_lib.ml index 64fc280..6ebef8d 100644 --- a/src/ppx_compare_lib.ml +++ b/src/ppx_compare_lib.ml @@ -1,4 +1,5 @@ open Import0 +include Ppx_compare_lib_intf.Definitions let compare_abstract ~type_name _ _ = Printf.ksprintf @@ -14,122 +15,6 @@ let equal_abstract ~type_name _ _ = type_name ;; -type 'a compare = 'a -> 'a -> int -type 'a compare__local = 'a -> 'a -> int -type 'a equal = 'a -> 'a -> bool -type 'a equal__local = 'a -> 'a -> bool - -module Comparable = struct - module type S = sig - type t - - val compare : t compare - end - - module type S1 = sig - type 'a t - - val compare : 'a compare -> 'a t compare - end - - module type S2 = sig - type ('a, 'b) t - - val compare : 'a compare -> 'b compare -> ('a, 'b) t compare - end - - module type S3 = sig - type ('a, 'b, 'c) t - - val compare : 'a compare -> 'b compare -> 'c compare -> ('a, 'b, 'c) t compare - end - - module type S_local = sig - type t - - val compare__local : t compare__local - end - - module type S_local1 = sig - type 'a t - - val compare__local : 'a compare__local -> 'a t compare__local - end - - module type S_local2 = sig - type ('a, 'b) t - - val compare__local - : 'a compare__local - -> 'b compare__local - -> ('a, 'b) t compare__local - end - - module type S_local3 = sig - type ('a, 'b, 'c) t - - val compare__local - : 'a compare__local - -> 'b compare__local - -> 'c compare__local - -> ('a, 'b, 'c) t compare__local - end -end - -module Equal = struct - module type S = sig - type t - - val equal : t equal - end - - module type S1 = sig - type 'a t - - val equal : 'a equal -> 'a t equal - end - - module type S2 = sig - type ('a, 'b) t - - val equal : 'a equal -> 'b equal -> ('a, 'b) t equal - end - - module type S3 = sig - type ('a, 'b, 'c) t - - val equal : 'a equal -> 'b equal -> 'c equal -> ('a, 'b, 'c) t equal - end - - module type S_local = sig - type t - - val equal__local : t equal__local - end - - module type S_local1 = sig - type 'a t - - val equal__local : 'a equal__local -> 'a t equal__local - end - - module type S_local2 = sig - type ('a, 'b) t - - val equal__local : 'a equal__local -> 'b equal__local -> ('a, 'b) t equal__local - end - - module type S_local3 = sig - type ('a, 'b, 'c) t - - val equal__local - : 'a equal__local - -> 'b equal__local - -> 'c equal__local - -> ('a, 'b, 'c) t equal__local - end -end - module Builtin = struct let compare_bool : bool compare = Poly.compare let compare_bool__local : bool compare__local = Poly.compare diff --git a/src/ppx_compare_lib.mli b/src/ppx_compare_lib.mli index f3cb657..f0d538a 100644 --- a/src/ppx_compare_lib.mli +++ b/src/ppx_compare_lib.mli @@ -1,182 +1 @@ -(** Runtime support for auto-generated comparators. Users are not intended to use this - module directly. *) - -type 'a compare = 'a -> 'a -> int -type 'a compare__local = 'a -> 'a -> int -type 'a equal = 'a -> 'a -> bool -type 'a equal__local = 'a -> 'a -> bool - -(** Raise when fully applied *) -val compare_abstract : type_name:string -> _ compare__local - -val equal_abstract : type_name:string -> _ equal__local - -module Comparable : sig - module type S = sig - type t - - val compare : t compare - end - - module type S1 = sig - type 'a t - - val compare : 'a compare -> 'a t compare - end - - module type S2 = sig - type ('a, 'b) t - - val compare : 'a compare -> 'b compare -> ('a, 'b) t compare - end - - module type S3 = sig - type ('a, 'b, 'c) t - - val compare : 'a compare -> 'b compare -> 'c compare -> ('a, 'b, 'c) t compare - end - - module type S_local = sig - type t - - val compare__local : t compare__local - end - - module type S_local1 = sig - type 'a t - - val compare__local : 'a compare__local -> 'a t compare__local - end - - module type S_local2 = sig - type ('a, 'b) t - - val compare__local - : 'a compare__local - -> 'b compare__local - -> ('a, 'b) t compare__local - end - - module type S_local3 = sig - type ('a, 'b, 'c) t - - val compare__local - : 'a compare__local - -> 'b compare__local - -> 'c compare__local - -> ('a, 'b, 'c) t compare__local - end -end - -module Equal : sig - module type S = sig - type t - - val equal : t equal - end - - module type S1 = sig - type 'a t - - val equal : 'a equal -> 'a t equal - end - - module type S2 = sig - type ('a, 'b) t - - val equal : 'a equal -> 'b equal -> ('a, 'b) t equal - end - - module type S3 = sig - type ('a, 'b, 'c) t - - val equal : 'a equal -> 'b equal -> 'c equal -> ('a, 'b, 'c) t equal - end - - module type S_local = sig - type t - - val equal__local : t equal__local - end - - module type S_local1 = sig - type 'a t - - val equal__local : 'a equal__local -> 'a t equal__local - end - - module type S_local2 = sig - type ('a, 'b) t - - val equal__local : 'a equal__local -> 'b equal__local -> ('a, 'b) t equal__local - end - - module type S_local3 = sig - type ('a, 'b, 'c) t - - val equal__local - : 'a equal__local - -> 'b equal__local - -> 'c equal__local - -> ('a, 'b, 'c) t equal__local - end -end - -module Builtin : sig - val compare_bool : bool compare - val compare_char : char compare - val compare_float : float compare - val compare_int : int compare - val compare_int32 : int32 compare - val compare_int64 : int64 compare - val compare_nativeint : nativeint compare - val compare_string : string compare - val compare_bytes : bytes compare - val compare_unit : unit compare - val compare_array : 'a compare -> 'a array compare - val compare_list : 'a compare -> 'a list compare - val compare_option : 'a compare -> 'a option compare - val compare_ref : 'a compare -> 'a ref compare - val equal_bool : bool equal - val equal_char : char equal - val equal_float : float equal - val equal_int : int equal - val equal_int32 : int32 equal - val equal_int64 : int64 equal - val equal_nativeint : nativeint equal - val equal_string : string equal - val equal_bytes : bytes equal - val equal_unit : unit equal - val equal_array : 'a equal -> 'a array equal - val equal_list : 'a equal -> 'a list equal - val equal_option : 'a equal -> 'a option equal - val equal_ref : 'a equal -> 'a ref equal - val compare_bool__local : bool compare__local - val compare_char__local : char compare__local - val compare_float__local : float compare__local - val compare_int__local : int compare__local - val compare_int32__local : int32 compare__local - val compare_int64__local : int64 compare__local - val compare_nativeint__local : nativeint compare__local - val compare_string__local : string compare__local - val compare_bytes__local : bytes compare__local - val compare_unit__local : unit compare__local - val compare_array__local : 'a compare__local -> 'a array compare__local - val compare_list__local : 'a compare__local -> 'a list compare__local - val compare_option__local : 'a compare__local -> 'a option compare__local - val compare_ref__local : 'a compare__local -> 'a ref compare__local - val equal_bool__local : bool equal__local - val equal_char__local : char equal__local - val equal_float__local : float equal__local - val equal_int__local : int equal__local - val equal_int32__local : int32 equal__local - val equal_int64__local : int64 equal__local - val equal_nativeint__local : nativeint equal__local - val equal_string__local : string equal__local - val equal_bytes__local : bytes equal__local - val equal_unit__local : unit equal__local - val equal_array__local : 'a equal__local -> 'a array equal__local - val equal_list__local : 'a equal__local -> 'a list equal__local - val equal_option__local : 'a equal__local -> 'a option equal__local - val equal_ref__local : 'a equal__local -> 'a ref equal__local -end +include Ppx_compare_lib_intf.Ppx_compare_lib (** @inline *) diff --git a/src/ppx_compare_lib_intf.ml b/src/ppx_compare_lib_intf.ml new file mode 100644 index 0000000..a410ae9 --- /dev/null +++ b/src/ppx_compare_lib_intf.ml @@ -0,0 +1,190 @@ +(** Runtime support for auto-generated comparators. Users are not intended to use this + module directly. *) + +module Definitions = struct + type 'a compare = 'a -> 'a -> int + type 'a compare__local = 'a -> 'a -> int + type 'a equal = 'a -> 'a -> bool + type 'a equal__local = 'a -> 'a -> bool + + module Comparable = struct + module type S = sig + type t + + val compare : t compare + end + + module type S1 = sig + type 'a t + + val compare : 'a compare -> 'a t compare + end + + module type S2 = sig + type ('a, 'b) t + + val compare : 'a compare -> 'b compare -> ('a, 'b) t compare + end + + module type S3 = sig + type ('a, 'b, 'c) t + + val compare : 'a compare -> 'b compare -> 'c compare -> ('a, 'b, 'c) t compare + end + + module type S_local = sig + type t + + val compare__local : t compare__local + end + + module type S_local1 = sig + type 'a t + + val compare__local : 'a compare__local -> 'a t compare__local + end + + module type S_local2 = sig + type ('a, 'b) t + + val compare__local + : 'a compare__local + -> 'b compare__local + -> ('a, 'b) t compare__local + end + + module type S_local3 = sig + type ('a, 'b, 'c) t + + val compare__local + : 'a compare__local + -> 'b compare__local + -> 'c compare__local + -> ('a, 'b, 'c) t compare__local + end + end + + module Equal = struct + module type S = sig + type t + + val equal : t equal + end + + module type S1 = sig + type 'a t + + val equal : 'a equal -> 'a t equal + end + + module type S2 = sig + type ('a, 'b) t + + val equal : 'a equal -> 'b equal -> ('a, 'b) t equal + end + + module type S3 = sig + type ('a, 'b, 'c) t + + val equal : 'a equal -> 'b equal -> 'c equal -> ('a, 'b, 'c) t equal + end + + module type S_local = sig + type t + + val equal__local : t equal__local + end + + module type S_local1 = sig + type 'a t + + val equal__local : 'a equal__local -> 'a t equal__local + end + + module type S_local2 = sig + type ('a, 'b) t + + val equal__local : 'a equal__local -> 'b equal__local -> ('a, 'b) t equal__local + end + + module type S_local3 = sig + type ('a, 'b, 'c) t + + val equal__local + : 'a equal__local + -> 'b equal__local + -> 'c equal__local + -> ('a, 'b, 'c) t equal__local + end + end +end + +module type Ppx_compare_lib = sig + include module type of struct + include Definitions + end + + (** Raise when fully applied *) + val compare_abstract : type_name:string -> _ compare__local + + val equal_abstract : type_name:string -> _ equal__local + + module Builtin : sig + val compare_bool : bool compare + val compare_char : char compare + val compare_float : float compare + val compare_int : int compare + val compare_int32 : int32 compare + val compare_int64 : int64 compare + val compare_nativeint : nativeint compare + val compare_string : string compare + val compare_bytes : bytes compare + val compare_unit : unit compare + val compare_array : 'a compare -> 'a array compare + val compare_list : 'a compare -> 'a list compare + val compare_option : 'a compare -> 'a option compare + val compare_ref : 'a compare -> 'a ref compare + val equal_bool : bool equal + val equal_char : char equal + val equal_float : float equal + val equal_int : int equal + val equal_int32 : int32 equal + val equal_int64 : int64 equal + val equal_nativeint : nativeint equal + val equal_string : string equal + val equal_bytes : bytes equal + val equal_unit : unit equal + val equal_array : 'a equal -> 'a array equal + val equal_list : 'a equal -> 'a list equal + val equal_option : 'a equal -> 'a option equal + val equal_ref : 'a equal -> 'a ref equal + val compare_bool__local : bool compare__local + val compare_char__local : char compare__local + val compare_float__local : float compare__local + val compare_int__local : int compare__local + val compare_int32__local : int32 compare__local + val compare_int64__local : int64 compare__local + val compare_nativeint__local : nativeint compare__local + val compare_string__local : string compare__local + val compare_bytes__local : bytes compare__local + val compare_unit__local : unit compare__local + val compare_array__local : 'a compare__local -> 'a array compare__local + val compare_list__local : 'a compare__local -> 'a list compare__local + val compare_option__local : 'a compare__local -> 'a option compare__local + val compare_ref__local : 'a compare__local -> 'a ref compare__local + val equal_bool__local : bool equal__local + val equal_char__local : char equal__local + val equal_float__local : float equal__local + val equal_int__local : int equal__local + val equal_int32__local : int32 equal__local + val equal_int64__local : int64 equal__local + val equal_nativeint__local : nativeint equal__local + val equal_string__local : string equal__local + val equal_bytes__local : bytes equal__local + val equal_unit__local : unit equal__local + val equal_array__local : 'a equal__local -> 'a array equal__local + val equal_list__local : 'a equal__local -> 'a list equal__local + val equal_option__local : 'a equal__local -> 'a option equal__local + val equal_ref__local : 'a equal__local -> 'a ref equal__local + end +end diff --git a/src/set.ml b/src/set.ml index e2f5a57..88cb0b8 100644 --- a/src/set.ml +++ b/src/set.ml @@ -19,6 +19,31 @@ include Set_intf let with_return = With_return.with_return module Tree0 = struct + (* Weight-balanced trees, where the weight of each tree is [length t + 1]. We store + [weight] at each node to make balance operations cheap, and computing length just + requires subtracting 1. Conveniently, for the node N=(L,k,R), wt(N)=wt(L)+wt(R). + + Weight-balanced trees of this form are originally defined in [1]. The balancing + algorithm depends on two parameters: delta and gamma. Delta controls the balance + invariant: for sibling subtrees A and B, [wt(A) <= wt(B) * delta] and vice versa. + Gamma is used during rotation to decide whether to use a single or double rotation. A + single left-rotation suffices for (_, (A, B)) if [wt(A) < wt(B) * gamma]. The valid + bounds for these parameters and their performance impact are analyzed in [2]. + + Of the options presented in [2], we choose (delta, gamma) = (5/2, 3/2). This choice + is good by three criteria. One, it has the best performance in the paper's + benchmarks. Two, it yields average tree heights in our own tests comparable to our + previous implementation based on AVL trees. Three, we can implement these comparisons + efficiently with just two bit shifts and one addition each. + + We define the weight comparisons below as [is_too_heavy] and [may_rotate_just_once]. + + [1] Binary search trees of bounded balance, Nievergelt and Reingold, SIAM Journal on + Computing Vol. 2, Iss. 1 (1973). https://dl.acm.org/doi/pdf/10.1145/800152.804906 + + [2] Balancing weight-balanced trees, Hirai and Yamamoto, JFP 21 (3): 287–307, 2011. + https://yoichihirai.com/bst.pdf *) + type 'a t = | Empty (* Leaf is the same as Node with empty children but uses less space. *) @@ -27,24 +52,73 @@ module Tree0 = struct { left : 'a t ; elt : 'a ; right : 'a t - ; height : int - ; size : int + ; weight : int } type 'a tree = 'a t - (* Sets are represented by balanced binary trees (the heights of the children differ by - at most 2. *) - let[@inline always] height = function - | Empty -> 0 - | Leaf { elt = _ } -> 1 - | Node { left = _; elt = _; right = _; height = h; size = _ } -> h + (* Checks for failure of the balance invariant in one direction: + + {[ not (wt(A) <= wt(B) * 5/2) ]} + + We negate it by changing [<=] to [>]. + + {[ wt(A) > wt(B) * 5/2 ]} + + We avoid division by multiplying both sides by two. + + {[ wt(A) * 2 > wt(B) * 5 ]} + + We stick to powers of two by changing [x * 5] to [x * 4 + x]. + + {[ wt(A) * 2 > wt(B) * 4 + wt(B) ]} + + And we avoid multiplication by using shifts for multiplication by 2 and by 4. + + {[ wt(A) << 1 > wt(B) << 2 + wt(B) ]} + *) + let is_too_heavy ~weight:wtA ~for_weight:wtB = + (* See? Just like above! *) + wtA lsl 1 > (wtB lsl 2) + wtB + [@@inline always] + ;; + + (* Checks if we can use a single rotation for the currently-lower siblings: + + {[ wt(A) < wt(B) * 3/2 ]} + + We avoid division by multiplying both sides by two. + + {[ wt(A) * 2 < wt(B) * 3 ]} + + We stick to powers of two by changing [x * 3] to [x * 2 + x]. + + {[ wt(A) * 2 < wt(B) * 2 + wt(B) ]} + + We incur one fewer multiplication by moving [wt(B) * 2] to the left. + + {[ (wt(A) - wt(B)) * 2 < wt(B) ]} + + And we avoid multiplication by using shift for multiplication by 2. + + {[ (wt(A) - wt(B)) << 1 < wt(B) ]} + *) + let may_rotate_just_once ~inner_sibling_weight:wtA ~outer_sibling_weight:wtB = + (* See? Just like above! *) + (wtA - wtB) lsl 1 < wtB + [@@inline always] + ;; + + let[@inline always] weight = function + | Empty -> 1 + | Leaf { elt = _ } -> 2 + | Node { left = _; elt = _; right = _; weight = w } -> w ;; let[@inline always] length = function | Empty -> 0 | Leaf { elt = _ } -> 1 - | Node { left = _; elt = _; right = _; height = _; size = s } -> s + | Node { left = _; elt = _; right = _; weight = w } -> w - 1 ;; let order_invariants = @@ -61,7 +135,7 @@ module Tree0 = struct match t with | Empty -> true | Leaf { elt = v } -> in_range ~lower ~upper compare_elt v - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> in_range ~lower ~upper compare_elt v && loop ~lower ~upper:(Some v) compare_elt l && loop ~lower:(Some v) ~upper compare_elt r @@ -72,13 +146,13 @@ module Tree0 = struct let rec balance_invariants t = match t with | Empty | Leaf _ -> true - | Node { left = l; elt = _; right = r; height = h; size = n } -> - let hl = height l - and hr = height r in - abs (hl - hr) <= 2 - && h = max hl hr + 1 - && n = length l + length r + 1 - && h > 1 + | Node { left = l; elt = _; right = r; weight = w } -> + let wl = weight l + and wr = weight r in + w = wl + wr + && w > 2 + && (not (is_too_heavy ~weight:wl ~for_weight:wr)) + && (not (is_too_heavy ~weight:wr ~for_weight:wl)) && balance_invariants l && balance_invariants r ;; @@ -92,18 +166,13 @@ module Tree0 = struct (* Creates a new node with left son l, value v and right son r. We must have all elements of l < v < all elements of r. - l and r must be balanced and | height l - height r | <= 2. *) + l and r must be balanced and neither [is_too_heavy] for the other. *) let[@inline always] create l v r = - let hl = (height [@inlined]) l in - let hr = (height [@inlined]) r in - let h = if hl >= hr then hl + 1 else hr + 1 in - if h = 1 - then Leaf { elt = v } - else ( - let sl = (length [@inlined]) l in - let sr = (length [@inlined]) r in - Node { left = l; elt = v; right = r; height = h; size = sl + sr + 1 }) + let wl = (weight [@inlined]) l in + let wr = (weight [@inlined]) r in + let w = wl + wr in + if w = 2 then Leaf { elt = v } else Node { left = l; elt = v; right = r; weight = w } ;; (* We must call [f] with increasing indexes, because the bin_prot reader in @@ -169,42 +238,42 @@ module Tree0 = struct ;; (* Same as create, but performs one step of rebalancing if necessary. - Assumes l and r balanced and | height l - height r | <= 3. *) + Assumes l and r balanced and either [is_too_heavy] by at most 1. *) let bal l v r = - let hl = (height [@inlined]) l in - let hr = (height [@inlined]) r in - if hl > hr + 2 + let wl = (weight [@inlined]) l in + let wr = (weight [@inlined]) r in + if is_too_heavy ~weight:wl ~for_weight:wr then ( match l with | Empty -> assert false - | Leaf { elt = _ } -> assert false (* because h(l)>h(r)+2 and h(leaf)=1 *) - | Node { left = ll; elt = lv; right = lr; height = _; size = _ } -> - if height ll >= height lr + | Leaf { elt = _ } -> assert false (* a leaf never [is_too_heavy] *) + | Node { left = ll; elt = lv; right = lr; weight = _ } -> + if may_rotate_just_once + ~inner_sibling_weight:(weight lr) + ~outer_sibling_weight:(weight ll) then create ll lv (create lr v r) else ( match lr with | Empty -> assert false - | Leaf { elt = lrv } -> - assert (is_empty ll); - create (create ll lv Empty) lrv (create Empty v r) - | Node { left = lrl; elt = lrv; right = lrr; height = _; size = _ } -> + | Leaf { elt = lrv } -> create (create ll lv Empty) lrv (create Empty v r) + | Node { left = lrl; elt = lrv; right = lrr; weight = _ } -> create (create ll lv lrl) lrv (create lrr v r))) - else if hr > hl + 2 + else if is_too_heavy ~weight:wr ~for_weight:wl then ( match r with | Empty -> assert false - | Leaf { elt = _ } -> assert false (* because h(r)>h(l)+2 and h(leaf)=1 *) - | Node { left = rl; elt = rv; right = rr; height = _; size = _ } -> - if height rr >= height rl + | Leaf { elt = _ } -> assert false (* a leaf never [is_too_heavy] *) + | Node { left = rl; elt = rv; right = rr; weight = _ } -> + if may_rotate_just_once + ~inner_sibling_weight:(weight rl) + ~outer_sibling_weight:(weight rr) then create (create l v rl) rv rr else ( match rl with | Empty -> assert false - | Leaf { elt = rlv } -> - assert (is_empty rr); - create (create l v Empty) rlv (create Empty rv rr) - | Node { left = rll; elt = rlv; right = rlr; height = _; size = _ } -> + | Leaf { elt = rlv } -> create (create l v Empty) rlv (create Empty rv rr) + | Node { left = rll; elt = rlv; right = rlr; weight = _ } -> create (create l v rll) rlv (create rlr rv rr))) else (create [@inlined]) l v r ;; @@ -223,7 +292,7 @@ module Tree0 = struct else if c < 0 then create (Leaf { elt = x }) v Empty else create Empty v (Leaf { elt = x }) - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> let c = compare_elt x v in if c = 0 then Exn.raise_without_backtrace Same @@ -239,44 +308,143 @@ module Tree0 = struct let rec add_min x t = match t with | Empty -> Leaf { elt = x } - | Leaf { elt = _ } -> Node { left = Empty; elt = x; right = t; height = 2; size = 2 } - | Node { left = l; elt = v; right = r; height = _; size = _ } -> bal (add_min x l) v r + | Leaf { elt = _ } -> Node { left = Empty; elt = x; right = t; weight = 3 } + | Node { left = l; elt = v; right = r; weight = _ } -> bal (add_min x l) v r ;; (* specialization of [add] that assumes that [x] is greater than all existing elements *) let rec add_max t x = match t with | Empty -> Leaf { elt = x } - | Leaf { elt = _ } -> Node { left = t; elt = x; right = Empty; height = 2; size = 2 } - | Node { left = l; elt = v; right = r; height = _; size = _ } -> bal l v (add_max r x) - ;; - - (* Same as create and bal, but no assumptions are made on the relative heights of l and - r. *) - let rec join l v r = - match l, r with - | Empty, _ -> add_min v r - | _, Empty -> add_max l v - | Leaf { elt = lv }, _ -> add_min lv (add_min v r) - | _, Leaf { elt = rv } -> add_max (add_max l v) rv - | ( Node { left = ll; elt = lv; right = lr; height = lh; size = _ } - , Node { left = rl; elt = rv; right = rr; height = rh; size = _ } ) -> - if lh > rh + 2 - then bal ll lv (join lr v r) - else if rh > lh + 2 - then bal (join l v rl) rv rr - else create l v r - ;; + | Leaf { elt = _ } -> Node { left = t; elt = x; right = Empty; weight = 3 } + | Node { left = l; elt = v; right = r; weight = _ } -> bal l v (add_max r x) + ;; + + (* The [join] algorithm is taken from the github implementation[3] of [4]. It is like + [create] and [bal], and works on trees of arbitrary weight. + + We adapt our functions from [include/pam/balance_utils.h]. We use the name [join] for + [node_join], [join_rotating_right] for [right_join], and [join_rotating_left] for + [left_join]. We use our [may_rotate_just_once] where they use [is_single_rotation]. + + In the two recursive helpers, we've moved the initial balance check to just outside + the recursive call instead of just inside the function definition, since the + condition is known the first time we call it. + + [3] https://github.com/cmuparlay/PAM/tree/2a30a856a55698c7aa7e7ebf86ee826864bbcf86 + + [4] Just Join for Parallel Ordered Sets; Blelloch, Ferizovic, and Sun; SPAA ’16, July + 11-13, 20. https://www.cs.cmu.edu/~guyb/papers/BFS16.pdf *) + include struct + open struct + (* These helpers are intended only to be called from [join]. *) + + (* For [join_rotating_right l lv m rv r], the arguments correspond to an + unbalanced tree with the shape: + {v + rv + / \ + lv r + / \ + l m + v} + + Precondition: [create l lv m] [is_too_heavy] for [r], and [r = Node _]. *) + let rec join_rotating_right l lv m rv r = + let mr = + (* Recur down [m]'s right side until [create m rv r] is balanced. *) + match m with + | Node { left = ml; elt = mv; right = mr; weight = mw } + when is_too_heavy ~weight:mw ~for_weight:(weight r) -> + join_rotating_right ml mv mr rv r + | _ -> create m rv r + in + (* Since [r] is a [Node], [mr] must be a [Node]. *) + match mr with + | Empty -> assert false + | Leaf _ -> assert false + | Node { left = m; elt = rv; right = r; weight = mrw } -> + (* Now re-add [l] with 0-2 rotations. Proven sufficient in literature above. *) + let lw = weight l in + (match m with + | Node { left = ml; elt = mv; right = mr; weight = mw } + when is_too_heavy ~weight:mrw ~for_weight:lw -> + if may_rotate_just_once + ~inner_sibling_weight:mw + ~outer_sibling_weight:(weight r) + then create (create l lv m) rv r + else create (create l lv ml) mv (create mr rv r) + | _ -> create l lv mr) + ;; + + (* Rotating left proceeds symmetrically to rotating right. *) + + (* For [join_rotating_left l lv m rv r], the arguments correspond to an + unbalanced tree with the shape: + {v + lv + / \ + l rv + / \ + m r + v} + + Precondition: [create m rv r] [is_too_heavy] for [l], and [l = Node _]. *) + let rec join_rotating_left l lv m rv r = + let lm = + (* Recur down [m]'s left side until [create l lv m] is balanced. *) + match m with + | Node { left = ml; elt = mv; right = mr; weight = mw } + when is_too_heavy ~weight:mw ~for_weight:(weight l) -> + join_rotating_left l lv ml mv mr + | _ -> create l lv m + in + (* Since [l] is a [Node], [lm] must be a [Node]. *) + match lm with + | Empty -> assert false + | Leaf _ -> assert false + | Node { left = l; elt = lv; right = m; weight = lmw } -> + (* Now re-add [r] with 0-2 rotations. Proven sufficient in literature above. *) + let rw = weight r in + (match m with + | Node { left = ml; elt = mv; right = mr; weight = mw } + when is_too_heavy ~weight:lmw ~for_weight:rw -> + if may_rotate_just_once + ~inner_sibling_weight:mw + ~outer_sibling_weight:(weight l) + then create l lv (create m rv r) + else create (create l lv ml) mv (create mr rv r) + | _ -> create lm rv r) + ;; + end + + (* Like [create] and [bal], for arbitrary height differences. See more detailed + comment at start of [include struct ...] above. *) + let join l v r = + (* Cases adding just one or two values are straightforward. *) + match l, r with + | Empty, _ -> add_min v r + | _, Empty -> add_max l v + | Leaf { elt = lv }, _ -> add_min lv (add_min v r) + | _, Leaf { elt = rv } -> add_max (add_max l v) rv + | ( Node { left = ll; elt = lv; right = lr; weight = lw } + , Node { left = rl; elt = rv; right = rr; weight = rw } ) -> + (* Otherwise, recur down the heavier side and rotate toward the lighter side. *) + if is_too_heavy ~weight:lw ~for_weight:rw + then join_rotating_right ll lv lr v r + else if is_too_heavy ~weight:rw ~for_weight:lw + then join_rotating_left l v rl rv rr + else create l v r + ;; + end let return_none () = None (* Smallest and greatest element of a set *) let rec call_with_min_elt ~none ~some = function | Empty -> none () - | Leaf { elt = v } | Node { left = Empty; elt = v; right = _; height = _; size = _ } - -> some v - | Node { left = l; elt = _; right = _; height = _; size = _ } -> - call_with_min_elt l ~none ~some + | Leaf { elt = v } | Node { left = Empty; elt = v; right = _; weight = _ } -> some v + | Node { left = l; elt = _; right = _; weight = _ } -> call_with_min_elt l ~none ~some ;; let raise_min_elt_exn () = Error.raise_s (Atom "Set.min_elt_exn: empty set") @@ -288,7 +456,7 @@ module Tree0 = struct match t with | Empty -> Container.Continue_or_stop.Continue acc | Leaf { elt = value } -> f acc value [@nontail] - | Node { left; elt = value; right; height = _; size = _ } -> + | Node { left; elt = value; right; weight = _ } -> (match fold_until_helper ~f left acc with | Stop _a as x -> x | Continue acc -> @@ -303,10 +471,8 @@ module Tree0 = struct let rec call_with_max_elt ~none ~some = function | Empty -> none () - | Leaf { elt = v } | Node { left = _; elt = v; right = Empty; height = _; size = _ } - -> some v - | Node { left = _; elt = _; right = r; height = _; size = _ } -> - call_with_max_elt r ~none ~some + | Leaf { elt = v } | Node { left = _; elt = v; right = Empty; weight = _ } -> some v + | Node { left = _; elt = _; right = r; weight = _ } -> call_with_max_elt r ~none ~some ;; let raise_max_elt_exn () = Error.raise_s (Atom "Set.max_elt_exn: empty set") @@ -318,13 +484,12 @@ module Tree0 = struct let rec remove_min_elt = function | Empty -> invalid_arg "Set.remove_min_elt" | Leaf { elt = _ } -> Empty - | Node { left = Empty; elt = _; right = r; height = _; size = _ } -> r - | Node { left = l; elt = v; right = r; height = _; size = _ } -> - bal (remove_min_elt l) v r + | Node { left = Empty; elt = _; right = r; weight = _ } -> r + | Node { left = l; elt = v; right = r; weight = _ } -> bal (remove_min_elt l) v r ;; (* Merge two trees l and r into one. All elements of l must precede the elements of r. - Assume | height l - height r | <= 2. *) + Assume either l or r [is_too_heavy] by at most 1. *) let merge t1 t2 = match t1, t2 with | Empty, t -> t @@ -333,7 +498,7 @@ module Tree0 = struct ;; (* Merge two trees l and r into one. All elements of l must precede the elements of r. - No assumption on the heights of l and r. *) + No assumption on the weights of l and r. *) let concat t1 t2 = match t1, t2 with | Empty, t | t, Empty -> t @@ -351,7 +516,7 @@ module Tree0 = struct else if c < 0 then Empty, None, Leaf { elt = v } else Leaf { elt = v }, None, Empty - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> let c = compare_elt x v in if c = 0 then l, Some v, r @@ -371,7 +536,7 @@ module Tree0 = struct | Empty -> Empty, Empty | Leaf { elt = v } -> if compare_elt x v >= 0 then Leaf { elt = v }, Empty else Empty, Leaf { elt = v } - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> let c = compare_elt x v in if c = 0 then add_max l v, r @@ -389,7 +554,7 @@ module Tree0 = struct | Empty -> Empty, Empty | Leaf { elt = v } -> if compare_elt x v > 0 then Leaf { elt = v }, Empty else Empty, Leaf { elt = v } - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> let c = compare_elt x v in if c = 0 then l, add_min v r @@ -412,7 +577,7 @@ module Tree0 = struct | Leaf { elt = v } -> let c = compare_elt x v in c = 0 - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> let c = compare_elt x v in c = 0 || mem (if c < 0 then l else r) x ~compare_elt ;; @@ -425,7 +590,7 @@ module Tree0 = struct | Empty -> Exn.raise_without_backtrace Same | Leaf { elt = v } -> if compare_elt x v = 0 then Empty else Exn.raise_without_backtrace Same - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> let c = compare_elt x v in if c = 0 then merge l r else if c < 0 then bal (aux l) v r else bal l v (aux r) in @@ -438,7 +603,7 @@ module Tree0 = struct match t with | Empty -> Exn.raise_without_backtrace Same | Leaf { elt = _ } -> if i = 0 then Empty else Exn.raise_without_backtrace Same - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> let l_size = length l in let c = Poly.compare i l_size in if c = 0 @@ -460,9 +625,9 @@ module Tree0 = struct | Empty, t | t, Empty -> t | Leaf { elt = v1 }, _ -> add s2 v1 ~compare_elt | _, Leaf { elt = v2 } -> add s1 v2 ~compare_elt - | ( Node { left = l1; elt = v1; right = r1; height = h1; size = _ } - , Node { left = l2; elt = v2; right = r2; height = h2; size = _ } ) -> - if h1 >= h2 + | ( Node { left = l1; elt = v1; right = r1; weight = w1 } + , Node { left = l2; elt = v2; right = r2; weight = w2 } ) -> + if w1 >= w2 then ( let l2, _, r2 = split s2 v1 ~compare_elt in join (union l1 l2) v1 (union r1 r2)) @@ -487,7 +652,7 @@ module Tree0 = struct | Empty, _ | _, Empty -> Empty | (Leaf { elt } as singleton), other_set | other_set, (Leaf { elt } as singleton) -> if mem other_set elt ~compare_elt then singleton else Empty - | Node { left = l1; elt = v1; right = r1; height = _; size = _ }, t2 -> + | Node { left = l1; elt = v1; right = r1; weight = _ }, t2 -> (match split t2 v1 ~compare_elt with | l2, None, r2 -> concat (inter l1 l2) (inter r1 r2) | l2, Some v1, r2 -> join (inter l1 l2) v1 (inter r1 r2))) @@ -504,8 +669,8 @@ module Tree0 = struct | Empty, _ -> Empty | t1, Empty -> t1 | Leaf { elt = v1 }, t2 -> - diff (Node { left = Empty; elt = v1; right = Empty; height = 1; size = 1 }) t2 - | Node { left = l1; elt = v1; right = r1; height = _; size = _ }, t2 -> + diff (Node { left = Empty; elt = v1; right = Empty; weight = 2 }) t2 + | Node { left = l1; elt = v1; right = r1; weight = _ }, t2 -> (match split t2 v1 ~compare_elt with | l2, None, r2 -> join (diff l1 l2) v1 (diff r1 r2) | l2, Some _, r2 -> concat (diff l1 l2) (diff r1 r2))) @@ -525,16 +690,14 @@ module Tree0 = struct match s with | Empty -> e | Leaf { elt = v } -> More (v, Empty, e) - | Node { left = l; elt = v; right = r; height = _; size = _ } -> - cons l (More (v, r, e)) + | Node { left = l; elt = v; right = r; weight = _ } -> cons l (More (v, r, e)) ;; let rec cons_right s (e : (_, decreasing) t) : (_, decreasing) t = match s with | Empty -> e | Leaf { elt = v } -> More (v, Empty, e) - | Node { left = l; elt = v; right = r; height = _; size = _ } -> - cons_right r (More (v, l, e)) + | Node { left = l; elt = v; right = r; weight = _ } -> cons_right r (More (v, l, e)) ;; let of_set s : (_, increasing) t = cons s End @@ -545,11 +708,10 @@ module Tree0 = struct match t with | Empty -> e | Leaf { elt = v } -> - loop (Node { left = Empty; elt = v; right = Empty; height = 1; size = 1 }) e - | Node { left = _; elt = v; right = r; height = _; size = _ } - when compare v key < 0 -> loop r e - | Node { left = l; elt = v; right = r; height = _; size = _ } -> - loop l (More (v, r, e)) + loop (Node { left = Empty; elt = v; right = Empty; weight = 2 }) e + | Node { left = _; elt = v; right = r; weight = _ } when compare v key < 0 -> + loop r e + | Node { left = l; elt = v; right = r; weight = _ } -> loop l (More (v, r, e)) in loop t End ;; @@ -559,11 +721,10 @@ module Tree0 = struct match t with | Empty -> e | Leaf { elt = v } -> - loop (Node { left = Empty; elt = v; right = Empty; height = 1; size = 1 }) e - | Node { left = l; elt = v; right = _; height = _; size = _ } - when compare v key > 0 -> loop l e - | Node { left = l; elt = v; right = r; height = _; size = _ } -> - loop r (More (v, l, e)) + loop (Node { left = Empty; elt = v; right = Empty; weight = 2 }) e + | Node { left = l; elt = v; right = _; weight = _ } when compare v key > 0 -> + loop l e + | Node { left = l; elt = v; right = r; weight = _ } -> loop r (More (v, l, e)) in loop t End ;; @@ -698,7 +859,7 @@ module Tree0 = struct match t with | Empty -> None | Leaf { elt = v } -> if f v then Some v else None - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> if f v then ( match find_first_satisfying l ~f with @@ -711,7 +872,7 @@ module Tree0 = struct match t with | Empty -> None | Leaf { elt = v } -> if f v then Some v else None - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> if f v then ( match find_last_satisfying r ~f with @@ -785,31 +946,26 @@ module Tree0 = struct | Empty, _ -> true | _, Empty -> false | Leaf { elt = v1 }, t2 -> mem t2 v1 ~compare_elt - | Node { left = l1; elt = v1; right = r1; height = _; size = _ }, Leaf { elt = v2 } - -> + | Node { left = l1; elt = v1; right = r1; weight = _ }, Leaf { elt = v2 } -> (match l1, r1 with | Empty, Empty -> (* This case shouldn't occur in practice because we should have constructed a Leaf {elt=rather} than a Node with two Empty subtrees *) compare_elt v1 v2 = 0 | _, _ -> false) - | ( Node { left = l1; elt = v1; right = r1; height = _; size = _ } - , (Node { left = l2; elt = v2; right = r2; height = _; size = _ } as t2) ) -> + | ( Node { left = l1; elt = v1; right = r1; weight = _ } + , (Node { left = l2; elt = v2; right = r2; weight = _ } as t2) ) -> let c = compare_elt v1 v2 in if c = 0 then phys_equal s1 s2 || (is_subset l1 ~of_:l2 && is_subset r1 ~of_:r2) - (* Note that height and size don't matter here. *) + (* Note that weight doesn't matter here. *) else if c < 0 then - is_subset - (Node { left = l1; elt = v1; right = Empty; height = 0; size = 0 }) - ~of_:l2 + is_subset (Node { left = l1; elt = v1; right = Empty; weight = 0 }) ~of_:l2 && is_subset r1 ~of_:t2 else - is_subset - (Node { left = Empty; elt = v1; right = r1; height = 0; size = 0 }) - ~of_:r2 + is_subset (Node { left = Empty; elt = v1; right = r1; weight = 0 }) ~of_:r2 && is_subset l1 ~of_:t2 in is_subset s1 ~of_:s2 @@ -820,7 +976,7 @@ module Tree0 = struct | Empty, _ | _, Empty -> true | Leaf { elt }, other_set | other_set, Leaf { elt } -> not (mem other_set elt ~compare_elt) - | Node { left = l1; elt = v1; right = r1; height = _; size = _ }, t2 -> + | Node { left = l1; elt = v1; right = r1; weight = _ }, t2 -> if phys_equal s1 s2 then false else ( @@ -834,7 +990,7 @@ module Tree0 = struct let rec iter = function | Empty -> () | Leaf { elt = v } -> f v - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> iter l; f v; iter r @@ -848,7 +1004,7 @@ module Tree0 = struct match s with | Empty -> accu | Leaf { elt = v } -> f accu v - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> fold ~f r ~init:(f (fold ~f l ~init:accu) v) ;; @@ -863,7 +1019,7 @@ module Tree0 = struct match s with | Empty -> accu | Leaf { elt = v } -> f v accu - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> fold_right ~f l ~init:(f v (fold_right ~f r ~init:accu)) ;; @@ -871,7 +1027,7 @@ module Tree0 = struct match t with | Empty -> true | Leaf { elt = v } -> p v - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> p v && for_all ~f:p l && for_all ~f:p r ;; @@ -879,7 +1035,7 @@ module Tree0 = struct match t with | Empty -> false | Leaf { elt = v } -> p v - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> p v || exists ~f:p l || exists ~f:p r ;; @@ -887,7 +1043,7 @@ module Tree0 = struct let rec filt = function | Empty -> Empty | Leaf { elt = v } as t -> if p v then t else Empty - | Node { left = l; elt = v; right = r; height = _; size = _ } as t -> + | Node { left = l; elt = v; right = r; weight = _ } as t -> let l' = filt l in let keep_v = p v in let r' = filt r in @@ -907,7 +1063,7 @@ module Tree0 = struct (match p v with | None -> accu | Some v -> add accu v ~compare_elt) - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> filt (filt (match p v with @@ -923,7 +1079,7 @@ module Tree0 = struct let rec loop = function | Empty -> Empty, Empty | Leaf { elt = v } as t -> if p v then t, Empty else Empty, t - | Node { left = l; elt = v; right = r; height = _; size = _ } as t -> + | Node { left = l; elt = v; right = r; weight = _ } as t -> let l't, l'f = loop l in let keep_v_t = p v in let r't, r'f = loop r in @@ -942,7 +1098,7 @@ module Tree0 = struct let rec elements_aux accu = function | Empty -> accu | Leaf { elt = v } -> v :: accu - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> elements_aux (v :: elements_aux accu r) l ;; @@ -951,7 +1107,7 @@ module Tree0 = struct let call_with_choose ~none ~some = function | Empty -> none () | Leaf { elt = v } -> some v - | Node { left = _; elt = v; right = _; height = _; size = _ } -> some v + | Node { left = _; elt = v; right = _; weight = _ } -> some v ;; let raise_choose_exn () = Error.raise_s (Atom "Set.choose_exn: empty set") @@ -976,8 +1132,8 @@ module Tree0 = struct let to_array = function | Empty -> [||] | Leaf { elt = v } -> [| v |] - | Node { left = l; elt = v; right = r; height = _; size = s } -> - let res = Array.create ~len:s v in + | Node { left = l; elt = v; right = r; weight = w } -> + let res = Array.create ~len:(w - 1) v in let pos_ref = ref 0 in let rec loop = function (* Invariant: on entry and on exit to [loop], !pos_ref is the next @@ -986,7 +1142,7 @@ module Tree0 = struct | Leaf { elt = v } -> res.(!pos_ref) <- v; incr pos_ref - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> loop l; res.(!pos_ref) <- v; incr pos_ref; @@ -1021,7 +1177,7 @@ module Tree0 = struct match t with | Empty -> None | Leaf { elt = v } -> if f v then Some v else None - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> if f v then Some v else ( @@ -1034,7 +1190,7 @@ module Tree0 = struct match t with | Empty -> None | Leaf { elt = v } -> f v - | Node { left = l; elt = v; right = r; height = _; size = _ } -> + | Node { left = l; elt = v; right = r; weight = _ } -> (match f v with | Some _ as r -> r | None -> @@ -1053,8 +1209,8 @@ module Tree0 = struct match t with | Empty -> None | Leaf { elt = v } -> if i = 0 then Some v else None - | Node { left = l; elt = v; right = r; height = _; size = s } -> - if i >= s + | Node { left = l; elt = v; right = r; weight = w } -> + if i >= w - 1 then None else ( let l_size = length l in @@ -1563,8 +1719,30 @@ module Private = struct type 'a t = 'a Tree0.t let balance_invariants t = Tree0.balance_invariants t - let are_balanced t1 t2 = abs (Tree0.height t1 - Tree0.height t2) <= 2 - let are_almost_balanced t1 t2 = abs (Tree0.height t1 - Tree0.height t2) <= 3 + + let are_balanced t1 t2 = + let w1 = Tree0.weight t1 + and w2 = Tree0.weight t2 in + (not (Tree0.is_too_heavy ~weight:w1 ~for_weight:w2)) + && not (Tree0.is_too_heavy ~weight:w2 ~for_weight:w1) + ;; + + let are_almost_balanced t1 t2 = + let w1 = Tree0.weight t1 + and w2 = Tree0.weight t2 in + match t1, t2 with + | Node node, _ when Tree0.is_too_heavy ~weight:w1 ~for_weight:w2 -> + (not (Tree0.is_too_heavy ~weight:(w1 - 1) ~for_weight:w2)) + && Tree0.may_rotate_just_once + ~inner_sibling_weight:(Tree0.weight node.right) + ~outer_sibling_weight:(Tree0.weight node.left) + | _, Node node when Tree0.is_too_heavy ~weight:w2 ~for_weight:w1 -> + (not (Tree0.is_too_heavy ~weight:(w2 - 1) ~for_weight:w1)) + && Tree0.may_rotate_just_once + ~inner_sibling_weight:(Tree0.weight node.left) + ~outer_sibling_weight:(Tree0.weight node.right) + | _ -> true + ;; let expose t = match (t : _ Tree0.t) with diff --git a/src/source_code_position.ml b/src/source_code_position.ml index bd2e7d2..c9e8408 100644 --- a/src/source_code_position.ml +++ b/src/source_code_position.ml @@ -1,18 +1,3 @@ open! Import -module M = Source_code_position0 -include M -include Comparable.Make_using_comparator (M) - -let equal__local a b = equal_int (compare__local a b) 0 - -let of_pos (pos_fname, pos_lnum, pos_cnum, _) = - { pos_fname; pos_lnum; pos_cnum; pos_bol = 0 } -;; - -let here_or_there ?(here = Stdlib.Lexing.dummy_pos) there = - match there with - | None -> here - | Some there -> there -;; - -let is_dummy t = equal__local Stdlib.Lexing.dummy_pos t +include Source_code_position0 +include Comparable.Make_using_comparator (Source_code_position0) diff --git a/src/source_code_position0.ml b/src/source_code_position0.ml index 5f3465f..8f387d3 100644 --- a/src/source_code_position0.ml +++ b/src/source_code_position0.ml @@ -102,3 +102,16 @@ let to_string { Stdlib.Lexing.pos_fname; pos_lnum; pos_cnum; pos_bol } = ;; let sexp_of_t t = Sexp.Atom (to_string t) +let equal__local a b = equal_int (compare__local a b) 0 + +let of_pos (pos_fname, pos_lnum, pos_cnum, _) = + { pos_fname; pos_lnum; pos_cnum; pos_bol = 0 } +;; + +let here_or_there ?(here = Stdlib.Lexing.dummy_pos) there = + match there with + | None -> here + | Some there -> there +;; + +let is_dummy t = equal__local Stdlib.Lexing.dummy_pos t diff --git a/test/allocation/test_option_allocation.ml b/test/allocation/test_option_allocation.ml index 12f2141..7451612 100644 --- a/test/allocation/test_option_allocation.ml +++ b/test/allocation/test_option_allocation.ml @@ -44,9 +44,10 @@ module%test [@name "local mode vs global mode"] _ = struct ;; let%expect_test "value_local_exn" = + let here = [%here] in test - ~local:Option.value_local_exn - ~global:Option.value_exn + ~local:(Option.value_local_exn ~here) + ~global:(Option.value_exn ~here) (module struct type t = int option [@@deriving quickcheck, sexp_of] end) diff --git a/test/coverage/map/constructor.ml b/test/coverage/map/constructor.ml index 82b8b78..be8b0d7 100644 --- a/test/coverage/map/constructor.ml +++ b/test/coverage/map/constructor.ml @@ -71,6 +71,8 @@ module Constructor = struct | Change of 'key * ('data option, 'data option) Func.t * ('key, 'data) t [@weight rec_weight] | Update of 'key * ('data option, 'data) Func.t * ('key, 'data) t [@weight rec_weight] + | Update_and_return of 'key * ('data option, 'data) Func.t * ('key, 'data) t + [@weight rec_weight] | Remove of 'key * ('key, 'data) t [@weight rec_weight] | Map of ('data, 'data) Func.t * ('key, 'data) t [@weight rec_weight] | Mapi of ('key, ('data, 'data) Func.t) Func.t * ('key, 'data) t [@weight rec_weight] @@ -143,6 +145,7 @@ module Constructor = struct | Set (_, _, t) -> [ t ] | Change (_, _, t) -> [ t ] | Update (_, _, t) -> [ t ] + | Update_and_return (_, _, t) -> [ t ] | Remove (_, t) -> [ t ] | Map (_, t) -> [ t ] | Mapi (_, t) -> [ t ] @@ -210,6 +213,7 @@ module Constructor = struct | Set (key, _, t) -> key :: keys t | Change (key, _, t) -> key :: keys t | Update (key, _, t) -> key :: keys t + | Update_and_return (key, _, t) -> key :: keys t | Remove (key, t) -> key :: keys t | Map (_, t) -> keys t | Mapi (fn, t) -> Func.inputs fn @ keys t @@ -313,6 +317,8 @@ module Constructor = struct Change (k key, Func.map ~i:(Option.map ~f:d) ~o:(Option.map ~f:d) fn, map ~k ~d t) | Update (key, fn, t) -> Update (k key, Func.map ~i:(Option.map ~f:d) ~o:d fn, map ~k ~d t) + | Update_and_return (key, fn, t) -> + Update_and_return (k key, Func.map ~i:(Option.map ~f:d) ~o:d fn, map ~k ~d t) | Remove (key, t) -> Remove (k key, map ~k ~d t) | Map (fn, t) -> Map (Func.map ~i:d ~o:d fn, map ~k ~d t) | Mapi (fn, t) -> Mapi (Func.map ~i:k ~o:(Func.map ~i:d ~o:d) fn, map ~k ~d t) @@ -484,6 +490,7 @@ module Constructor = struct | Set (key, data, t) -> Set (key, data, normalize t) | Change (key, fn, t) -> Change (key, fn, normalize t) | Update (key, fn, t) -> Update (key, fn, normalize t) + | Update_and_return (key, fn, t) -> Update_and_return (key, fn, normalize t) | Remove (key, t) -> Remove (key, normalize t) | Map (fn, t) -> Map (fn, normalize t) | Mapi (fn, t) -> Mapi (fn, normalize t) @@ -667,6 +674,12 @@ module Constructor = struct (access Impl.change) (value t) key ~f:(Func.apply fn (module Data_option)) | Update (key, fn, t) -> (access Impl.update) (value t) key ~f:(Func.apply fn (module Data_option)) + | Update_and_return (key, fn, t) -> + (access Impl.update_and_return) + (value t) + key + ~f:(Func.apply fn (module Data_option)) + |> snd | Remove (key, t) -> (access Impl.remove) (value t) key | Map (fn, t) -> Impl.map (value t) ~f:(Func.apply fn (module Data)) | Mapi (fn, t) -> @@ -832,12 +845,12 @@ module%test [@tags "64-bits-only"] _ : Impl = struct % | size | count ----+------+------ 0 | 1 | 10000 - 50 | 4 | 5747 - 75 | 11 | 2687 - 90 | 25 | 1057 - 95 | 40 | 523 - 99 | 77 | 101 - 100 | 293 | 1 + 50 | 5 | 5038 + 75 | 11 | 2604 + 90 | 25 | 1038 + 95 | 39 | 503 + 99 | 78 | 100 + 100 | 273 | 1 |}] ;; @@ -880,7 +893,7 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 86 + - | 0 | 85 |}] ;; @@ -894,7 +907,7 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - 100 | 1 | 79 + 100 | 1 | 85 |}] ;; @@ -908,15 +921,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 117 + - | 0 | 95 ----+------+------ - 0 | 1 | 170 - 50 | 3 | 94 - 75 | 8 | 44 - 90 | 14 | 21 - 95 | 19 | 10 + 0 | 1 | 190 + 50 | 3 | 100 + 75 | 7 | 49 + 90 | 18 | 19 + 95 | 23 | 11 99 | 27 | 2 - 100 | 28 | 1 + 100 | 33 | 1 |}] ;; @@ -930,15 +943,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 91 + - | 0 | 81 ----+------+------ - 0 | 1 | 192 - 50 | 3 | 100 - 75 | 8 | 50 - 90 | 16 | 20 + 0 | 1 | 213 + 50 | 3 | 115 + 75 | 9 | 54 + 90 | 20 | 23 95 | 23 | 11 - 99 | 28 | 2 - 100 | 48 | 1 + 99 | 29 | 4 + 100 | 38 | 1 |}] ;; @@ -952,14 +965,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 16 + - | 0 | 10 ----+------+------ - 0 | 1 | 56 - 50 | 11 | 28 - 75 | 21 | 15 - 90 | 25 | 8 - 95 | 28 | 3 - 100 | 31 | 1 + 0 | 1 | 69 + 50 | 12 | 37 + 75 | 18 | 19 + 90 | 25 | 7 + 95 | 27 | 4 + 100 | 30 | 1 |}] ;; @@ -973,13 +986,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 9 + - | 0 | 16 ----+------+------ - 0 | 1 | 74 - 50 | 8 | 41 - 75 | 18 | 20 - 90 | 25 | 9 - 100 | 28 | 4 + 0 | 1 | 58 + 50 | 10 | 31 + 75 | 16 | 15 + 90 | 22 | 6 + 95 | 27 | 3 + 100 | 29 | 2 |}] ;; @@ -993,14 +1007,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 9 + - | 0 | 14 ----+------+------ - 0 | 1 | 82 - 50 | 10 | 41 - 75 | 18 | 21 - 90 | 26 | 9 - 95 | 27 | 7 - 100 | 30 | 2 + 0 | 1 | 58 + 50 | 10 | 29 + 75 | 20 | 15 + 90 | 27 | 6 + 95 | 29 | 3 + 100 | 31 | 1 |}] ;; @@ -1014,13 +1028,13 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 18 + - | 0 | 15 ----+------+------ - 0 | 1 | 64 - 50 | 13 | 32 - 75 | 22 | 16 - 90 | 26 | 8 - 95 | 29 | 4 + 0 | 1 | 68 + 50 | 11 | 36 + 75 | 17 | 18 + 90 | 23 | 7 + 95 | 25 | 4 100 | 31 | 1 |}] ;; @@ -1035,14 +1049,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 18 + - | 0 | 9 ----+------+------ - 0 | 1 | 74 - 50 | 11 | 37 - 75 | 20 | 20 - 90 | 26 | 8 - 95 | 29 | 4 - 100 | 31 | 2 + 0 | 1 | 65 + 50 | 8 | 35 + 75 | 17 | 18 + 90 | 24 | 7 + 95 | 26 | 5 + 100 | 30 | 1 |}] ;; @@ -1056,14 +1070,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 9 + - | 0 | 8 ----+------+------ - 0 | 1 | 59 - 50 | 9 | 30 - 75 | 16 | 15 - 90 | 25 | 6 - 95 | 28 | 3 - 100 | 30 | 1 + 0 | 1 | 80 + 50 | 8 | 43 + 75 | 18 | 20 + 90 | 26 | 8 + 95 | 29 | 4 + 100 | 30 | 3 |}] ;; @@ -1077,12 +1091,12 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 8 + - | 0 | 18 ----+------+------ - 0 | 1 | 76 - 50 | 3 | 55 - 75 | 4 | 32 - 100 | 5 | 8 + 0 | 1 | 57 + 50 | 3 | 37 + 90 | 4 | 20 + 100 | 5 | 4 |}] ;; @@ -1096,13 +1110,12 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 11 + - | 0 | 12 ----+------+------ - 0 | 1 | 72 - 50 | 3 | 41 - 90 | 4 | 29 - 95 | 5 | 7 - 100 | 6 | 1 + 0 | 1 | 66 + 50 | 3 | 37 + 75 | 4 | 25 + 100 | 5 | 10 |}] ;; @@ -1116,14 +1129,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 9 + - | 0 | 13 ----+------+------ - 0 | 1 | 77 - 50 | 9 | 39 - 75 | 17 | 20 - 90 | 20 | 12 - 95 | 24 | 5 - 100 | 28 | 1 + 0 | 1 | 63 + 50 | 9 | 34 + 75 | 19 | 18 + 90 | 26 | 7 + 95 | 28 | 4 + 100 | 31 | 1 |}] ;; @@ -1137,14 +1150,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 9 + - | 0 | 10 ----+------+------ - 0 | 1 | 79 - 50 | 9 | 44 - 75 | 15 | 20 - 90 | 22 | 9 - 95 | 23 | 7 - 100 | 29 | 1 + 0 | 1 | 59 + 50 | 10 | 31 + 75 | 19 | 16 + 90 | 27 | 6 + 95 | 28 | 5 + 100 | 30 | 2 |}] ;; @@ -1158,13 +1171,13 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 15 + - | 0 | 14 ----+------+------ - 0 | 1 | 77 - 50 | 9 | 41 - 75 | 18 | 22 - 90 | 24 | 9 - 95 | 26 | 6 + 0 | 1 | 79 + 50 | 10 | 40 + 75 | 21 | 20 + 90 | 27 | 8 + 95 | 28 | 5 100 | 31 | 1 |}] ;; @@ -1179,14 +1192,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 11 + - | 0 | 8 ----+------+------ - 0 | 1 | 71 - 50 | 14 | 36 - 75 | 21 | 19 - 90 | 25 | 8 - 95 | 27 | 4 - 100 | 28 | 2 + 0 | 1 | 85 + 50 | 9 | 43 + 75 | 16 | 27 + 90 | 23 | 10 + 95 | 27 | 6 + 100 | 31 | 2 |}] ;; @@ -1200,12 +1213,13 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 13 + - | 0 | 11 ----+------+------ - 0 | 1 | 71 + 0 | 1 | 74 50 | 3 | 48 - 90 | 4 | 32 - 100 | 5 | 7 + 75 | 4 | 25 + 95 | 5 | 10 + 100 | 6 | 2 |}] ;; @@ -1221,10 +1235,10 @@ module%test [@tags "64-bits-only"] _ : Impl = struct ----+------+------ - | 0 | 11 ----+------+------ - 0 | 1 | 68 - 75 | 3 | 45 - 95 | 4 | 14 - 100 | 5 | 3 + 0 | 1 | 58 + 50 | 3 | 47 + 75 | 4 | 25 + 100 | 5 | 7 |}] ;; @@ -1238,13 +1252,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 10 + - | 0 | 4 ----+------+------ - 0 | 1 | 68 - 50 | 12 | 35 - 75 | 19 | 17 - 95 | 25 | 7 - 100 | 27 | 1 + 0 | 1 | 71 + 50 | 12 | 37 + 75 | 17 | 20 + 90 | 26 | 8 + 95 | 28 | 4 + 100 | 30 | 1 |}] ;; @@ -1260,12 +1275,12 @@ module%test [@tags "64-bits-only"] _ : Impl = struct ----+------+------ - | 0 | 14 ----+------+------ - 0 | 1 | 86 - 50 | 11 | 44 - 75 | 18 | 23 - 90 | 25 | 10 - 95 | 27 | 6 - 100 | 30 | 1 + 0 | 1 | 76 + 50 | 10 | 38 + 75 | 16 | 21 + 90 | 21 | 8 + 95 | 24 | 6 + 100 | 31 | 1 |}] ;; @@ -1281,12 +1296,12 @@ module%test [@tags "64-bits-only"] _ : Impl = struct ----+------+------ - | 0 | 10 ----+------+------ - 0 | 1 | 68 - 50 | 10 | 34 - 75 | 17 | 18 - 90 | 24 | 7 - 95 | 25 | 6 - 100 | 28 | 2 + 0 | 1 | 100 + 50 | 9 | 51 + 75 | 21 | 25 + 90 | 28 | 11 + 95 | 30 | 5 + 100 | 31 | 2 |}] ;; @@ -1300,11 +1315,11 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 13 + - | 0 | 7 ----+------+------ 0 | 1 | 68 - 50 | 2 | 41 - 100 | 3 | 17 + 75 | 2 | 37 + 100 | 3 | 10 |}] ;; @@ -1318,12 +1333,12 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 12 + - | 0 | 11 ----+------+------ - 0 | 1 | 69 - 50 | 2 | 48 - 95 | 3 | 18 - 100 | 4 | 1 + 0 | 1 | 67 + 50 | 2 | 45 + 95 | 3 | 17 + 100 | 4 | 3 |}] ;; @@ -1337,13 +1352,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 11 + - | 0 | 9 ----+------+------ - 0 | 1 | 78 - 50 | 11 | 39 - 75 | 20 | 20 - 90 | 27 | 8 - 100 | 30 | 5 + 0 | 1 | 77 + 50 | 13 | 42 + 75 | 18 | 21 + 90 | 24 | 8 + 95 | 27 | 4 + 100 | 31 | 1 |}] ;; @@ -1359,12 +1375,12 @@ module%test [@tags "64-bits-only"] _ : Impl = struct ----+------+------ - | 0 | 17 ----+------+------ - 0 | 1 | 67 - 50 | 10 | 36 - 75 | 18 | 17 - 90 | 26 | 7 - 95 | 29 | 5 - 100 | 31 | 1 + 0 | 1 | 68 + 50 | 11 | 35 + 75 | 16 | 19 + 90 | 22 | 7 + 95 | 25 | 4 + 100 | 30 | 1 |}] ;; @@ -1379,12 +1395,12 @@ module%test [@tags "64-bits-only"] _ : Impl = struct % | size | count ----+------+------ 0 | 1 | 265 - 50 | 3 | 143 - 75 | 7 | 69 - 90 | 17 | 27 - 95 | 21 | 16 - 99 | 27 | 4 - 100 | 38 | 1 + 50 | 2 | 170 + 75 | 5 | 68 + 90 | 12 | 27 + 95 | 19 | 14 + 99 | 29 | 3 + 100 | 39 | 1 |}] ;; @@ -1398,13 +1414,13 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - 0 | 1 | 271 - 50 | 2 | 183 - 75 | 4 | 85 - 90 | 13 | 33 - 95 | 21 | 14 - 99 | 28 | 4 - 100 | 51 | 1 + 0 | 1 | 307 + 50 | 2 | 213 + 75 | 5 | 81 + 90 | 12 | 31 + 95 | 18 | 16 + 99 | 27 | 4 + 100 | 52 | 1 |}] ;; @@ -1418,13 +1434,13 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - 0 | 1 | 263 - 50 | 2 | 151 - 75 | 5 | 66 - 90 | 12 | 29 - 95 | 20 | 14 - 99 | 26 | 3 - 100 | 29 | 1 + 0 | 1 | 258 + 50 | 2 | 172 + 75 | 5 | 72 + 90 | 14 | 27 + 95 | 22 | 13 + 99 | 28 | 3 + 100 | 43 | 1 |}] ;; @@ -1438,15 +1454,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 62 + - | 0 | 51 ----+------+------ - 0 | 1 | 202 - 50 | 3 | 101 - 75 | 8 | 53 - 90 | 16 | 22 - 95 | 21 | 11 - 99 | 28 | 3 - 100 | 41 | 1 + 0 | 1 | 206 + 50 | 3 | 109 + 75 | 8 | 55 + 90 | 17 | 22 + 95 | 22 | 11 + 99 | 28 | 4 + 100 | 38 | 1 |}] ;; @@ -1460,13 +1476,33 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - 0 | 1 | 277 - 50 | 2 | 178 - 75 | 7 | 71 - 90 | 18 | 29 - 95 | 23 | 18 - 99 | 30 | 3 - 100 | 48 | 1 + 0 | 1 | 302 + 50 | 2 | 200 + 75 | 6 | 77 + 90 | 17 | 32 + 95 | 21 | 19 + 99 | 26 | 5 + 100 | 29 | 1 + |}] + ;; + + let update_and_return = Map.update_and_return + + let%expect_test _ = + test (function + | Update_and_return _ -> true + | _ -> false); + [%expect + {| + % | size | count + ----+------+------ + 0 | 1 | 242 + 50 | 2 | 149 + 75 | 4 | 82 + 90 | 16 | 26 + 95 | 20 | 13 + 99 | 28 | 3 + 100 | 33 | 1 |}] ;; @@ -1480,15 +1516,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 100 + - | 0 | 92 ----+------+------ - 0 | 1 | 190 - 50 | 3 | 113 - 75 | 11 | 48 - 90 | 20 | 20 - 95 | 24 | 10 - 99 | 39 | 2 - 100 | 42 | 1 + 0 | 1 | 174 + 50 | 3 | 103 + 75 | 9 | 48 + 90 | 18 | 18 + 95 | 20 | 9 + 99 | 27 | 2 + 100 | 28 | 1 |}] ;; @@ -1502,15 +1538,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 110 + - | 0 | 82 ----+------+------ - 0 | 1 | 194 - 50 | 3 | 106 - 75 | 8 | 53 - 90 | 18 | 22 - 95 | 23 | 10 - 99 | 43 | 2 - 100 | 49 | 1 + 0 | 1 | 188 + 50 | 3 | 95 + 75 | 6 | 52 + 90 | 16 | 19 + 95 | 22 | 10 + 99 | 28 | 2 + 100 | 42 | 1 |}] ;; @@ -1524,14 +1560,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 100 + - | 0 | 87 ----+------+------ - 0 | 1 | 169 - 50 | 2 | 114 - 75 | 8 | 45 - 90 | 18 | 18 - 95 | 21 | 9 - 99 | 29 | 2 + 0 | 1 | 150 + 50 | 3 | 84 + 75 | 9 | 38 + 90 | 19 | 15 + 95 | 23 | 8 + 99 | 28 | 3 100 | 30 | 1 |}] ;; @@ -1546,15 +1582,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 168 + - | 0 | 139 ----+------+------ - 0 | 1 | 133 - 50 | 2 | 76 - 75 | 7 | 34 - 90 | 16 | 18 - 95 | 22 | 7 - 99 | 29 | 2 - 100 | 38 | 1 + 0 | 1 | 128 + 50 | 2 | 73 + 75 | 5 | 32 + 90 | 13 | 13 + 95 | 17 | 7 + 99 | 26 | 3 + 100 | 27 | 1 |}] ;; @@ -1568,14 +1604,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 163 + - | 0 | 149 ----+------+------ - 0 | 1 | 140 - 50 | 2 | 97 - 75 | 6 | 37 + 0 | 1 | 137 + 50 | 2 | 92 + 75 | 5 | 43 90 | 12 | 14 - 95 | 20 | 7 - 100 | 24 | 2 + 95 | 17 | 8 + 99 | 24 | 2 + 100 | 25 | 1 |}] ;; @@ -1589,15 +1626,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 157 + - | 0 | 135 ----+------+------ 0 | 1 | 134 - 50 | 2 | 81 + 50 | 2 | 80 75 | 4 | 39 - 90 | 10 | 16 - 95 | 14 | 8 - 99 | 23 | 2 - 100 | 24 | 1 + 90 | 12 | 15 + 95 | 18 | 7 + 99 | 27 | 2 + 100 | 29 | 1 |}] ;; @@ -1611,14 +1648,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 154 + - | 0 | 153 ----+------+------ - 0 | 1 | 109 - 50 | 3 | 64 - 75 | 6 | 30 - 90 | 16 | 11 + 0 | 1 | 122 + 50 | 2 | 78 + 75 | 8 | 33 + 90 | 18 | 13 95 | 20 | 8 - 99 | 24 | 2 + 99 | 23 | 2 100 | 26 | 1 |}] ;; @@ -1633,15 +1670,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 184 + - | 0 | 136 ----+------+------ - 0 | 1 | 119 - 50 | 2 | 78 - 75 | 5 | 32 - 90 | 14 | 12 - 95 | 19 | 6 - 99 | 24 | 3 - 100 | 25 | 1 + 0 | 1 | 149 + 50 | 2 | 95 + 75 | 5 | 42 + 90 | 12 | 17 + 95 | 16 | 8 + 99 | 23 | 2 + 100 | 24 | 1 |}] ;; @@ -1655,15 +1692,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 145 + - | 0 | 160 ----+------+------ - 0 | 1 | 105 - 50 | 3 | 53 - 75 | 7 | 27 - 90 | 15 | 11 - 95 | 22 | 6 - 99 | 26 | 3 - 100 | 28 | 1 + 0 | 1 | 124 + 50 | 2 | 76 + 75 | 5 | 32 + 90 | 17 | 13 + 95 | 22 | 7 + 100 | 27 | 2 |}] ;; @@ -1677,14 +1713,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 142 + - | 0 | 151 ----+------+------ - 0 | 1 | 128 - 50 | 3 | 64 - 75 | 8 | 32 - 90 | 15 | 13 - 95 | 18 | 8 - 100 | 24 | 2 + 0 | 1 | 130 + 50 | 2 | 87 + 75 | 5 | 40 + 90 | 11 | 13 + 95 | 18 | 7 + 99 | 23 | 2 + 100 | 24 | 1 |}] ;; @@ -1698,14 +1735,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 158 + - | 0 | 145 ----+------+------ - 0 | 1 | 132 - 50 | 2 | 77 - 75 | 5 | 33 - 90 | 10 | 15 - 95 | 14 | 7 - 100 | 27 | 2 + 0 | 1 | 125 + 50 | 2 | 69 + 75 | 5 | 32 + 90 | 11 | 13 + 95 | 16 | 7 + 99 | 22 | 3 + 100 | 28 | 1 |}] ;; @@ -1719,15 +1757,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 142 + - | 0 | 149 ----+------+------ - 0 | 1 | 121 - 50 | 2 | 75 - 75 | 6 | 33 - 90 | 12 | 14 - 95 | 21 | 7 - 99 | 29 | 2 - 100 | 41 | 1 + 0 | 1 | 97 + 50 | 2 | 64 + 75 | 5 | 25 + 90 | 15 | 10 + 95 | 18 | 5 + 100 | 39 | 1 |}] ;; @@ -1741,15 +1778,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 83 + - | 0 | 79 ----+------+------ - 0 | 1 | 179 - 50 | 2 | 120 - 75 | 5 | 55 - 90 | 9 | 20 - 95 | 11 | 10 - 99 | 24 | 2 - 100 | 53 | 1 + 0 | 1 | 205 + 50 | 2 | 132 + 75 | 6 | 52 + 90 | 14 | 22 + 95 | 19 | 11 + 99 | 28 | 4 + 100 | 41 | 1 |}] ;; @@ -1763,15 +1800,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 33 + - | 0 | 27 ----+------+------ - 0 | 1 | 249 - 50 | 5 | 126 - 75 | 13 | 67 - 90 | 23 | 31 - 95 | 29 | 13 - 99 | 42 | 3 - 100 | 69 | 1 + 0 | 1 | 240 + 50 | 6 | 121 + 75 | 15 | 60 + 90 | 23 | 26 + 95 | 28 | 12 + 99 | 49 | 3 + 100 | 54 | 1 |}] ;; @@ -1785,15 +1822,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 37 + - | 0 | 28 ----+------+------ - 0 | 1 | 237 - 50 | 5 | 122 - 75 | 13 | 65 - 90 | 22 | 25 - 95 | 27 | 15 - 99 | 34 | 3 - 100 | 40 | 1 + 0 | 1 | 248 + 50 | 5 | 138 + 75 | 14 | 63 + 90 | 24 | 27 + 95 | 28 | 14 + 99 | 36 | 3 + 100 | 47 | 2 |}] ;; @@ -1807,15 +1844,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 176 + - | 0 | 155 ----+------+------ - 0 | 1 | 115 - 50 | 2 | 72 - 75 | 6 | 33 - 90 | 10 | 15 - 95 | 14 | 8 - 99 | 18 | 2 - 100 | 27 | 1 + 0 | 1 | 104 + 50 | 2 | 62 + 75 | 5 | 27 + 90 | 10 | 11 + 95 | 16 | 7 + 99 | 19 | 2 + 100 | 21 | 1 |}] ;; @@ -1829,14 +1866,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 164 + - | 0 | 149 ----+------+------ - 0 | 1 | 115 - 50 | 2 | 67 + 0 | 1 | 110 + 50 | 2 | 68 75 | 5 | 30 - 90 | 12 | 13 - 95 | 19 | 7 - 99 | 23 | 4 + 90 | 14 | 11 + 95 | 19 | 6 + 99 | 22 | 2 100 | 25 | 1 |}] ;; @@ -1851,15 +1888,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 132 + - | 0 | 147 ----+------+------ - 0 | 1 | 123 - 50 | 2 | 69 - 75 | 5 | 32 - 90 | 13 | 13 - 95 | 15 | 7 - 99 | 27 | 2 - 100 | 63 | 1 + 0 | 1 | 127 + 50 | 2 | 70 + 75 | 5 | 38 + 90 | 14 | 13 + 95 | 16 | 8 + 100 | 20 | 2 |}] ;; @@ -1873,15 +1909,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 23 + - | 0 | 24 ----+------+------ - 0 | 1 | 260 - 50 | 5 | 140 - 75 | 12 | 66 + 0 | 1 | 239 + 50 | 6 | 123 + 75 | 13 | 62 90 | 22 | 26 - 95 | 28 | 13 - 99 | 41 | 3 - 100 | 43 | 2 + 95 | 27 | 13 + 99 | 37 | 3 + 100 | 48 | 1 |}] ;; @@ -1895,14 +1931,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 191 + - | 0 | 170 ----+------+------ - 0 | 1 | 84 - 50 | 2 | 51 - 75 | 6 | 23 - 90 | 16 | 9 - 95 | 19 | 5 - 100 | 25 | 1 + 0 | 1 | 101 + 50 | 3 | 56 + 75 | 6 | 29 + 90 | 13 | 12 + 95 | 20 | 6 + 99 | 26 | 2 + 100 | 28 | 1 |}] ;; @@ -1921,15 +1958,15 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 94 + - | 0 | 87 ----+------+------ - 0 | 1 | 179 - 50 | 3 | 95 - 75 | 6 | 53 - 90 | 16 | 20 - 95 | 21 | 9 - 99 | 25 | 2 - 100 | 27 | 1 + 0 | 1 | 176 + 50 | 4 | 91 + 75 | 10 | 46 + 90 | 18 | 21 + 95 | 24 | 10 + 99 | 29 | 2 + 100 | 30 | 1 |}] ;; @@ -1941,15 +1978,14 @@ module%test [@tags "64-bits-only"] _ : Impl = struct {| % | size | count ----+------+------ - - | 0 | 159 + - | 0 | 141 ----+------+------ - 0 | 1 | 138 - 50 | 3 | 70 - 75 | 7 | 35 - 90 | 12 | 17 - 95 | 16 | 8 - 99 | 22 | 2 - 100 | 27 | 1 + 0 | 1 | 120 + 50 | 2 | 72 + 75 | 7 | 31 + 90 | 16 | 12 + 95 | 22 | 7 + 100 | 23 | 3 |}] ;; end diff --git a/test/coverage/map/functor.ml b/test/coverage/map/functor.ml index 0d9b344..47a697c 100644 --- a/test/coverage/map/functor.ml +++ b/test/coverage/map/functor.ml @@ -1118,6 +1118,22 @@ module Test_transformers let expect = access set t ~key ~data in require_equal (module Inst.Value) actual expect) + and update_and_return = update_and_return + + and () = + quickcheck_m + (module Inst_and_key_and_data) + ~f:(fun (t, key, data) -> + let t = Inst.value t in + let new_data, actual = + access update_and_return t key ~f:(fun previous -> + require_equal (module Data.Option (Int)) previous (access find t key); + data) + in + let expect = access set t ~key ~data in + require_equal (module Inst.Value) actual expect; + require_equal (module Int) new_data data) + and add_multi = add_multi and remove_multi = remove_multi diff --git a/test/coverage/set/constructor.ml b/test/coverage/set/constructor.ml index da02f83..70c1441 100644 --- a/test/coverage/set/constructor.ml +++ b/test/coverage/set/constructor.ml @@ -958,7 +958,7 @@ module%test [@tags "64-bits-only"] _ : Impl = struct - | 0 | 559 ----+------+------ 0 | 1 | 9 - 50 | 2 | 5 + 50 | 2 | 6 75 | 4 | 3 100 | 14 | 1 |}] diff --git a/test/dune b/test/dune index 55bc4cd..e813326 100644 --- a/test/dune +++ b/test/dune @@ -4,4 +4,4 @@ bignum.bigint expect_test_helpers_core.expect_test_helpers_base expectable sexp_grammar_validation sexplib stdio) (preprocess - (pps ppx_jane -dont-apply=pipebang -no-check-on-extensions ppx_template))) + (pps ppx_jane -dont-apply=pipebang -no-check-on-extensions))) diff --git a/test/test_map.ml b/test/test_map.ml index ce01ccb..8df3972 100644 --- a/test/test_map.ml +++ b/test/test_map.ml @@ -284,33 +284,41 @@ module%test [@name "[symmetric_diff]"] _ = struct [%expect {| ((size 1_048_576) - (add_comparisons 20_971_521) - (diff_comparisons 22_020_076) - (mean_diff_comparisons 20.999980926513672) - (median_diff_comparisons 21) + (add_comparisons 24_379_415) + (diff_comparisons 25_165_828) + (mean_diff_comparisons 24.000003814697266) + (median_diff_comparisons 24) (diff_comparison_buckets ( ((comparisons 1) (times 1)) ((comparisons 2) (times 1)) - ((comparisons 3) (times 1)) - ((comparisons 4) (times 2)) - ((comparisons 5) (times 4)) - ((comparisons 6) (times 8)) - ((comparisons 7) (times 16)) - ((comparisons 8) (times 32)) - ((comparisons 9) (times 64)) - ((comparisons 10) (times 128)) - ((comparisons 11) (times 256)) - ((comparisons 12) (times 512)) - ((comparisons 13) (times 1_024)) - ((comparisons 14) (times 2_048)) - ((comparisons 15) (times 4_096)) - ((comparisons 16) (times 8_192)) - ((comparisons 17) (times 16_384)) - ((comparisons 18) (times 32_768)) - ((comparisons 19) (times 65_536)) - ((comparisons 20) (times 131_072)) - ((comparisons 21) (times 262_144)) - ((comparisons 22) (times 524_287))))) + ((comparisons 3) (times 3)) + ((comparisons 4) (times 4)) + ((comparisons 5) (times 6)) + ((comparisons 6) (times 11)) + ((comparisons 7) (times 20)) + ((comparisons 8) (times 35)) + ((comparisons 9) (times 61)) + ((comparisons 10) (times 107)) + ((comparisons 11) (times 188)) + ((comparisons 12) (times 330)) + ((comparisons 13) (times 579)) + ((comparisons 14) (times 1_016)) + ((comparisons 15) (times 1_783)) + ((comparisons 16) (times 3_129)) + ((comparisons 17) (times 5_491)) + ((comparisons 18) (times 9_636)) + ((comparisons 19) (times 16_910)) + ((comparisons 20) (times 29_675)) + ((comparisons 21) (times 52_056)) + ((comparisons 22) (times 90_397)) + ((comparisons 23) (times 147_221)) + ((comparisons 24) (times 205_068)) + ((comparisons 25) (times 224_909)) + ((comparisons 26) (times 170_393)) + ((comparisons 27) (times 73_527)) + ((comparisons 28) (times 14_876)) + ((comparisons 29) (times 1_123)) + ((comparisons 30) (times 20))))) |}] ;; @@ -512,22 +520,22 @@ let%expect_test ("space" [@tags "no-js"]) = ┌───────────┬──────────────┬───────────┐ │ length │ construction │ words │ ├───────────┼──────────────┼───────────┤ - │ 1 │ l_to_r │ 17 │ - │ 1 │ r_to_l │ 17 │ - │ 1 │ balanced │ 17 │ - │ 1 │ random │ 17 │ - │ 100 │ l_to_r │ 464 │ - │ 100 │ r_to_l │ 464 │ - │ 100 │ balanced │ 503 │ - │ 100 │ random │ 509 │ - │ 10_000 │ l_to_r │ 45_014 │ - │ 10_000 │ r_to_l │ 45_014 │ - │ 10_000 │ balanced │ 47_726 │ - │ 10_000 │ random │ 48_887 │ - │ 1_000_000 │ l_to_r │ 4_500_014 │ - │ 1_000_000 │ r_to_l │ 4_500_014 │ - │ 1_000_000 │ balanced │ 4_572_875 │ - │ 1_000_000 │ random │ 4_884_050 │ + │ 1 │ l_to_r │ 16 │ + │ 1 │ r_to_l │ 16 │ + │ 1 │ balanced │ 16 │ + │ 1 │ random │ 16 │ + │ 100 │ l_to_r │ 463 │ + │ 100 │ r_to_l │ 463 │ + │ 100 │ balanced │ 502 │ + │ 100 │ random │ 487 │ + │ 10_000 │ l_to_r │ 45_013 │ + │ 10_000 │ r_to_l │ 45_013 │ + │ 10_000 │ balanced │ 47_725 │ + │ 10_000 │ random │ 47_083 │ + │ 1_000_000 │ l_to_r │ 4_500_013 │ + │ 1_000_000 │ r_to_l │ 4_500_013 │ + │ 1_000_000 │ balanced │ 4_572_874 │ + │ 1_000_000 │ random │ 4_714_564 │ └───────────┴──────────────┴───────────┘ |}] ;; diff --git a/test/test_map_and_set_internals.ml b/test/test_map_and_set_internals.ml index be3359c..c6db17f 100644 --- a/test/test_map_and_set_internals.ml +++ b/test/test_map_and_set_internals.ml @@ -124,15 +124,15 @@ let test (module Tree : S) = ;; end - (* Testing up to size 18 takes ~5 seconds, at least on the box where this was - originally tested in 2023-12. Testing more takes ~15 seconds. *) - let max_total_size_to_test = 18 + (* Testing up to size 24 takes ~5 seconds, at least on the box where this was + originally tested in 2024-05. Testing more takes ~15 seconds. *) + let max_total_size_to_test = 24 (* Reduce output by skipping cases where either side is an empty tree. *) let min_size_to_show = 1 (* The smallest size where we see completely-unbalanced pairs and neither side is - empty is 9 (8 on one side, 1 on the other). *) + empty is 6 (5 on one side, 1 on the other). We show a few sizes beyond that. *) let max_total_size_to_show = 9 (* Cache of pre-computed trees. *) @@ -169,7 +169,7 @@ let test (module Tree : S) = in if should_show then ( - print_s [%sexp (lsize : int), (rsize : int), (l : t), (r : t)]; + print_s [%sexp ((lsize : int), (rsize : int)), (l : t), (r : t)]; shown := !shown + 1))); print_s [%sexp { shown = (!shown : int); total = (!total : int) }] ;; @@ -184,1281 +184,227 @@ let test (module Tree : S) = ~have_been_shown:(fun _ _ -> false); [%expect {| - (1 1 (. .) (. .)) - (1 2 (. .) (. (. .))) - (1 2 (. .) ((. .) .)) - (2 1 (. (. .)) (. .)) - (2 1 ((. .) .) (. .)) - (1 3 (. .) (. (. (. .)))) - (1 3 (. .) (. ((. .) .))) - (1 3 (. .) ((. .) (. .))) - (1 3 (. .) ((. (. .)) .)) - (1 3 (. .) (((. .) .) .)) - (2 2 (. (. .)) (. (. .))) - (2 2 (. (. .)) ((. .) .)) - (2 2 ((. .) .) (. (. .))) - (2 2 ((. .) .) ((. .) .)) - (3 1 (. (. (. .))) (. .)) - (3 1 (. ((. .) .)) (. .)) - (3 1 ((. .) (. .)) (. .)) - (3 1 ((. (. .)) .) (. .)) - (3 1 (((. .) .) .) (. .)) - (1 4 (. .) (. ((. .) (. .)))) - (1 4 (. .) ((. .) (. (. .)))) - (1 4 (. .) ((. .) ((. .) .))) - (1 4 (. .) ((. (. .)) (. .))) - (1 4 (. .) (((. .) .) (. .))) - (1 4 (. .) (((. .) (. .)) .)) - (2 3 (. (. .)) (. (. (. .)))) - (2 3 (. (. .)) (. ((. .) .))) - (2 3 (. (. .)) ((. .) (. .))) - (2 3 (. (. .)) ((. (. .)) .)) - (2 3 (. (. .)) (((. .) .) .)) - (2 3 ((. .) .) (. (. (. .)))) - (2 3 ((. .) .) (. ((. .) .))) - (2 3 ((. .) .) ((. .) (. .))) - (2 3 ((. .) .) ((. (. .)) .)) - (2 3 ((. .) .) (((. .) .) .)) - (3 2 (. (. (. .))) (. (. .))) - (3 2 (. (. (. .))) ((. .) .)) - (3 2 (. ((. .) .)) (. (. .))) - (3 2 (. ((. .) .)) ((. .) .)) - (3 2 ((. .) (. .)) (. (. .))) - (3 2 ((. .) (. .)) ((. .) .)) - (3 2 ((. (. .)) .) (. (. .))) - (3 2 ((. (. .)) .) ((. .) .)) - (3 2 (((. .) .) .) (. (. .))) - (3 2 (((. .) .) .) ((. .) .)) - (4 1 (. ((. .) (. .))) (. .)) - (4 1 ((. .) (. (. .))) (. .)) - (4 1 ((. .) ((. .) .)) (. .)) - (4 1 ((. (. .)) (. .)) (. .)) - (4 1 (((. .) .) (. .)) (. .)) - (4 1 (((. .) (. .)) .) (. .)) - (1 5 (. .) ((. .) ((. .) (. .)))) - (1 5 (. .) ((. (. .)) (. (. .)))) - (1 5 (. .) ((. (. .)) ((. .) .))) - (1 5 (. .) (((. .) .) (. (. .)))) - (1 5 (. .) (((. .) .) ((. .) .))) - (1 5 (. .) (((. .) (. .)) (. .))) - (2 4 (. (. .)) (. ((. .) (. .)))) - (2 4 (. (. .)) ((. .) (. (. .)))) - (2 4 (. (. .)) ((. .) ((. .) .))) - (2 4 (. (. .)) ((. (. .)) (. .))) - (2 4 (. (. .)) (((. .) .) (. .))) - (2 4 (. (. .)) (((. .) (. .)) .)) - (2 4 ((. .) .) (. ((. .) (. .)))) - (2 4 ((. .) .) ((. .) (. (. .)))) - (2 4 ((. .) .) ((. .) ((. .) .))) - (2 4 ((. .) .) ((. (. .)) (. .))) - (2 4 ((. .) .) (((. .) .) (. .))) - (2 4 ((. .) .) (((. .) (. .)) .)) - (3 3 (. (. (. .))) (. (. (. .)))) - (3 3 (. (. (. .))) (. ((. .) .))) - (3 3 (. (. (. .))) ((. .) (. .))) - (3 3 (. (. (. .))) ((. (. .)) .)) - (3 3 (. (. (. .))) (((. .) .) .)) - (3 3 (. ((. .) .)) (. (. (. .)))) - (3 3 (. ((. .) .)) (. ((. .) .))) - (3 3 (. ((. .) .)) ((. .) (. .))) - (3 3 (. ((. .) .)) ((. (. .)) .)) - (3 3 (. ((. .) .)) (((. .) .) .)) - (3 3 ((. .) (. .)) (. (. (. .)))) - (3 3 ((. .) (. .)) (. ((. .) .))) - (3 3 ((. .) (. .)) ((. .) (. .))) - (3 3 ((. .) (. .)) ((. (. .)) .)) - (3 3 ((. .) (. .)) (((. .) .) .)) - (3 3 ((. (. .)) .) (. (. (. .)))) - (3 3 ((. (. .)) .) (. ((. .) .))) - (3 3 ((. (. .)) .) ((. .) (. .))) - (3 3 ((. (. .)) .) ((. (. .)) .)) - (3 3 ((. (. .)) .) (((. .) .) .)) - (3 3 (((. .) .) .) (. (. (. .)))) - (3 3 (((. .) .) .) (. ((. .) .))) - (3 3 (((. .) .) .) ((. .) (. .))) - (3 3 (((. .) .) .) ((. (. .)) .)) - (3 3 (((. .) .) .) (((. .) .) .)) - (4 2 (. ((. .) (. .))) (. (. .))) - (4 2 (. ((. .) (. .))) ((. .) .)) - (4 2 ((. .) (. (. .))) (. (. .))) - (4 2 ((. .) (. (. .))) ((. .) .)) - (4 2 ((. .) ((. .) .)) (. (. .))) - (4 2 ((. .) ((. .) .)) ((. .) .)) - (4 2 ((. (. .)) (. .)) (. (. .))) - (4 2 ((. (. .)) (. .)) ((. .) .)) - (4 2 (((. .) .) (. .)) (. (. .))) - (4 2 (((. .) .) (. .)) ((. .) .)) - (4 2 (((. .) (. .)) .) (. (. .))) - (4 2 (((. .) (. .)) .) ((. .) .)) - (5 1 ((. .) ((. .) (. .))) (. .)) - (5 1 ((. (. .)) (. (. .))) (. .)) - (5 1 ((. (. .)) ((. .) .)) (. .)) - (5 1 (((. .) .) (. (. .))) (. .)) - (5 1 (((. .) .) ((. .) .)) (. .)) - (5 1 (((. .) (. .)) (. .)) (. .)) - (1 6 (. .) ((. (. .)) ((. .) (. .)))) - (1 6 (. .) (((. .) .) ((. .) (. .)))) - (1 6 (. .) (((. .) (. .)) (. (. .)))) - (1 6 (. .) (((. .) (. .)) ((. .) .))) - (2 5 (. (. .)) ((. .) (. (. (. .))))) - (2 5 (. (. .)) ((. .) (. ((. .) .)))) - (2 5 (. (. .)) ((. .) ((. .) (. .)))) - (2 5 (. (. .)) ((. .) ((. (. .)) .))) - (2 5 (. (. .)) ((. .) (((. .) .) .))) - (2 5 (. (. .)) ((. (. .)) (. (. .)))) - (2 5 (. (. .)) ((. (. .)) ((. .) .))) - (2 5 (. (. .)) (((. .) .) (. (. .)))) - (2 5 (. (. .)) (((. .) .) ((. .) .))) - (2 5 (. (. .)) ((. (. (. .))) (. .))) - (2 5 (. (. .)) ((. ((. .) .)) (. .))) - (2 5 (. (. .)) (((. .) (. .)) (. .))) - (2 5 (. (. .)) (((. (. .)) .) (. .))) - (2 5 (. (. .)) ((((. .) .) .) (. .))) - (2 5 ((. .) .) ((. .) (. (. (. .))))) - (2 5 ((. .) .) ((. .) (. ((. .) .)))) - (2 5 ((. .) .) ((. .) ((. .) (. .)))) - (2 5 ((. .) .) ((. .) ((. (. .)) .))) - (2 5 ((. .) .) ((. .) (((. .) .) .))) - (2 5 ((. .) .) ((. (. .)) (. (. .)))) - (2 5 ((. .) .) ((. (. .)) ((. .) .))) - (2 5 ((. .) .) (((. .) .) (. (. .)))) - (2 5 ((. .) .) (((. .) .) ((. .) .))) - (2 5 ((. .) .) ((. (. (. .))) (. .))) - (2 5 ((. .) .) ((. ((. .) .)) (. .))) - (2 5 ((. .) .) (((. .) (. .)) (. .))) - (2 5 ((. .) .) (((. (. .)) .) (. .))) - (2 5 ((. .) .) ((((. .) .) .) (. .))) - (3 4 (. (. (. .))) (. ((. .) (. .)))) - (3 4 (. (. (. .))) ((. .) (. (. .)))) - (3 4 (. (. (. .))) ((. .) ((. .) .))) - (3 4 (. (. (. .))) ((. (. .)) (. .))) - (3 4 (. (. (. .))) (((. .) .) (. .))) - (3 4 (. (. (. .))) (((. .) (. .)) .)) - (3 4 (. ((. .) .)) (. ((. .) (. .)))) - (3 4 (. ((. .) .)) ((. .) (. (. .)))) - (3 4 (. ((. .) .)) ((. .) ((. .) .))) - (3 4 (. ((. .) .)) ((. (. .)) (. .))) - (3 4 (. ((. .) .)) (((. .) .) (. .))) - (3 4 (. ((. .) .)) (((. .) (. .)) .)) - (3 4 ((. .) (. .)) (. ((. .) (. .)))) - (3 4 ((. .) (. .)) ((. .) (. (. .)))) - (3 4 ((. .) (. .)) ((. .) ((. .) .))) - (3 4 ((. .) (. .)) ((. (. .)) (. .))) - (3 4 ((. .) (. .)) (((. .) .) (. .))) - (3 4 ((. .) (. .)) (((. .) (. .)) .)) - (3 4 ((. (. .)) .) (. ((. .) (. .)))) - (3 4 ((. (. .)) .) ((. .) (. (. .)))) - (3 4 ((. (. .)) .) ((. .) ((. .) .))) - (3 4 ((. (. .)) .) ((. (. .)) (. .))) - (3 4 ((. (. .)) .) (((. .) .) (. .))) - (3 4 ((. (. .)) .) (((. .) (. .)) .)) - (3 4 (((. .) .) .) (. ((. .) (. .)))) - (3 4 (((. .) .) .) ((. .) (. (. .)))) - (3 4 (((. .) .) .) ((. .) ((. .) .))) - (3 4 (((. .) .) .) ((. (. .)) (. .))) - (3 4 (((. .) .) .) (((. .) .) (. .))) - (3 4 (((. .) .) .) (((. .) (. .)) .)) - (4 3 (. ((. .) (. .))) (. (. (. .)))) - (4 3 (. ((. .) (. .))) (. ((. .) .))) - (4 3 (. ((. .) (. .))) ((. .) (. .))) - (4 3 (. ((. .) (. .))) ((. (. .)) .)) - (4 3 (. ((. .) (. .))) (((. .) .) .)) - (4 3 ((. .) (. (. .))) (. (. (. .)))) - (4 3 ((. .) (. (. .))) (. ((. .) .))) - (4 3 ((. .) (. (. .))) ((. .) (. .))) - (4 3 ((. .) (. (. .))) ((. (. .)) .)) - (4 3 ((. .) (. (. .))) (((. .) .) .)) - (4 3 ((. .) ((. .) .)) (. (. (. .)))) - (4 3 ((. .) ((. .) .)) (. ((. .) .))) - (4 3 ((. .) ((. .) .)) ((. .) (. .))) - (4 3 ((. .) ((. .) .)) ((. (. .)) .)) - (4 3 ((. .) ((. .) .)) (((. .) .) .)) - (4 3 ((. (. .)) (. .)) (. (. (. .)))) - (4 3 ((. (. .)) (. .)) (. ((. .) .))) - (4 3 ((. (. .)) (. .)) ((. .) (. .))) - (4 3 ((. (. .)) (. .)) ((. (. .)) .)) - (4 3 ((. (. .)) (. .)) (((. .) .) .)) - (4 3 (((. .) .) (. .)) (. (. (. .)))) - (4 3 (((. .) .) (. .)) (. ((. .) .))) - (4 3 (((. .) .) (. .)) ((. .) (. .))) - (4 3 (((. .) .) (. .)) ((. (. .)) .)) - (4 3 (((. .) .) (. .)) (((. .) .) .)) - (4 3 (((. .) (. .)) .) (. (. (. .)))) - (4 3 (((. .) (. .)) .) (. ((. .) .))) - (4 3 (((. .) (. .)) .) ((. .) (. .))) - (4 3 (((. .) (. .)) .) ((. (. .)) .)) - (4 3 (((. .) (. .)) .) (((. .) .) .)) - (5 2 ((. .) (. (. (. .)))) (. (. .))) - (5 2 ((. .) (. (. (. .)))) ((. .) .)) - (5 2 ((. .) (. ((. .) .))) (. (. .))) - (5 2 ((. .) (. ((. .) .))) ((. .) .)) - (5 2 ((. .) ((. .) (. .))) (. (. .))) - (5 2 ((. .) ((. .) (. .))) ((. .) .)) - (5 2 ((. .) ((. (. .)) .)) (. (. .))) - (5 2 ((. .) ((. (. .)) .)) ((. .) .)) - (5 2 ((. .) (((. .) .) .)) (. (. .))) - (5 2 ((. .) (((. .) .) .)) ((. .) .)) - (5 2 ((. (. .)) (. (. .))) (. (. .))) - (5 2 ((. (. .)) (. (. .))) ((. .) .)) - (5 2 ((. (. .)) ((. .) .)) (. (. .))) - (5 2 ((. (. .)) ((. .) .)) ((. .) .)) - (5 2 (((. .) .) (. (. .))) (. (. .))) - (5 2 (((. .) .) (. (. .))) ((. .) .)) - (5 2 (((. .) .) ((. .) .)) (. (. .))) - (5 2 (((. .) .) ((. .) .)) ((. .) .)) - (5 2 ((. (. (. .))) (. .)) (. (. .))) - (5 2 ((. (. (. .))) (. .)) ((. .) .)) - (5 2 ((. ((. .) .)) (. .)) (. (. .))) - (5 2 ((. ((. .) .)) (. .)) ((. .) .)) - (5 2 (((. .) (. .)) (. .)) (. (. .))) - (5 2 (((. .) (. .)) (. .)) ((. .) .)) - (5 2 (((. (. .)) .) (. .)) (. (. .))) - (5 2 (((. (. .)) .) (. .)) ((. .) .)) - (5 2 ((((. .) .) .) (. .)) (. (. .))) - (5 2 ((((. .) .) .) (. .)) ((. .) .)) - (6 1 ((. (. .)) ((. .) (. .))) (. .)) - (6 1 (((. .) .) ((. .) (. .))) (. .)) - (6 1 (((. .) (. .)) (. (. .))) (. .)) - (6 1 (((. .) (. .)) ((. .) .)) (. .)) - (1 7 (. .) (((. .) (. .)) ((. .) (. .)))) - (2 6 (. (. .)) ((. .) (. ((. .) (. .))))) - (2 6 (. (. .)) ((. .) ((. .) (. (. .))))) - (2 6 (. (. .)) ((. .) ((. .) ((. .) .)))) - (2 6 (. (. .)) ((. .) ((. (. .)) (. .)))) - (2 6 (. (. .)) ((. .) (((. .) .) (. .)))) - (2 6 (. (. .)) ((. .) (((. .) (. .)) .))) - (2 6 (. (. .)) ((. (. .)) (. (. (. .))))) - (2 6 (. (. .)) ((. (. .)) (. ((. .) .)))) - (2 6 (. (. .)) ((. (. .)) ((. .) (. .)))) - (2 6 (. (. .)) ((. (. .)) ((. (. .)) .))) - (2 6 (. (. .)) ((. (. .)) (((. .) .) .))) - (2 6 (. (. .)) (((. .) .) (. (. (. .))))) - (2 6 (. (. .)) (((. .) .) (. ((. .) .)))) - (2 6 (. (. .)) (((. .) .) ((. .) (. .)))) - (2 6 (. (. .)) (((. .) .) ((. (. .)) .))) - (2 6 (. (. .)) (((. .) .) (((. .) .) .))) - (2 6 (. (. .)) ((. (. (. .))) (. (. .)))) - (2 6 (. (. .)) ((. (. (. .))) ((. .) .))) - (2 6 (. (. .)) ((. ((. .) .)) (. (. .)))) - (2 6 (. (. .)) ((. ((. .) .)) ((. .) .))) - (2 6 (. (. .)) (((. .) (. .)) (. (. .)))) - (2 6 (. (. .)) (((. .) (. .)) ((. .) .))) - (2 6 (. (. .)) (((. (. .)) .) (. (. .)))) - (2 6 (. (. .)) (((. (. .)) .) ((. .) .))) - (2 6 (. (. .)) ((((. .) .) .) (. (. .)))) - (2 6 (. (. .)) ((((. .) .) .) ((. .) .))) - (2 6 (. (. .)) ((. ((. .) (. .))) (. .))) - (2 6 (. (. .)) (((. .) (. (. .))) (. .))) - (2 6 (. (. .)) (((. .) ((. .) .)) (. .))) - (2 6 (. (. .)) (((. (. .)) (. .)) (. .))) - (2 6 (. (. .)) ((((. .) .) (. .)) (. .))) - (2 6 (. (. .)) ((((. .) (. .)) .) (. .))) - (2 6 ((. .) .) ((. .) (. ((. .) (. .))))) - (2 6 ((. .) .) ((. .) ((. .) (. (. .))))) - (2 6 ((. .) .) ((. .) ((. .) ((. .) .)))) - (2 6 ((. .) .) ((. .) ((. (. .)) (. .)))) - (2 6 ((. .) .) ((. .) (((. .) .) (. .)))) - (2 6 ((. .) .) ((. .) (((. .) (. .)) .))) - (2 6 ((. .) .) ((. (. .)) (. (. (. .))))) - (2 6 ((. .) .) ((. (. .)) (. ((. .) .)))) - (2 6 ((. .) .) ((. (. .)) ((. .) (. .)))) - (2 6 ((. .) .) ((. (. .)) ((. (. .)) .))) - (2 6 ((. .) .) ((. (. .)) (((. .) .) .))) - (2 6 ((. .) .) (((. .) .) (. (. (. .))))) - (2 6 ((. .) .) (((. .) .) (. ((. .) .)))) - (2 6 ((. .) .) (((. .) .) ((. .) (. .)))) - (2 6 ((. .) .) (((. .) .) ((. (. .)) .))) - (2 6 ((. .) .) (((. .) .) (((. .) .) .))) - (2 6 ((. .) .) ((. (. (. .))) (. (. .)))) - (2 6 ((. .) .) ((. (. (. .))) ((. .) .))) - (2 6 ((. .) .) ((. ((. .) .)) (. (. .)))) - (2 6 ((. .) .) ((. ((. .) .)) ((. .) .))) - (2 6 ((. .) .) (((. .) (. .)) (. (. .)))) - (2 6 ((. .) .) (((. .) (. .)) ((. .) .))) - (2 6 ((. .) .) (((. (. .)) .) (. (. .)))) - (2 6 ((. .) .) (((. (. .)) .) ((. .) .))) - (2 6 ((. .) .) ((((. .) .) .) (. (. .)))) - (2 6 ((. .) .) ((((. .) .) .) ((. .) .))) - (2 6 ((. .) .) ((. ((. .) (. .))) (. .))) - (2 6 ((. .) .) (((. .) (. (. .))) (. .))) - (2 6 ((. .) .) (((. .) ((. .) .)) (. .))) - (2 6 ((. .) .) (((. (. .)) (. .)) (. .))) - (2 6 ((. .) .) ((((. .) .) (. .)) (. .))) - (2 6 ((. .) .) ((((. .) (. .)) .) (. .))) - (3 5 (. (. (. .))) ((. .) (. (. (. .))))) - (3 5 (. (. (. .))) ((. .) (. ((. .) .)))) - (3 5 (. (. (. .))) ((. .) ((. .) (. .)))) - (3 5 (. (. (. .))) ((. .) ((. (. .)) .))) - (3 5 (. (. (. .))) ((. .) (((. .) .) .))) - (3 5 (. (. (. .))) ((. (. .)) (. (. .)))) - (3 5 (. (. (. .))) ((. (. .)) ((. .) .))) - (3 5 (. (. (. .))) (((. .) .) (. (. .)))) - (3 5 (. (. (. .))) (((. .) .) ((. .) .))) - (3 5 (. (. (. .))) ((. (. (. .))) (. .))) - (3 5 (. (. (. .))) ((. ((. .) .)) (. .))) - (3 5 (. (. (. .))) (((. .) (. .)) (. .))) - (3 5 (. (. (. .))) (((. (. .)) .) (. .))) - (3 5 (. (. (. .))) ((((. .) .) .) (. .))) - (3 5 (. ((. .) .)) ((. .) (. (. (. .))))) - (3 5 (. ((. .) .)) ((. .) (. ((. .) .)))) - (3 5 (. ((. .) .)) ((. .) ((. .) (. .)))) - (3 5 (. ((. .) .)) ((. .) ((. (. .)) .))) - (3 5 (. ((. .) .)) ((. .) (((. .) .) .))) - (3 5 (. ((. .) .)) ((. (. .)) (. (. .)))) - (3 5 (. ((. .) .)) ((. (. .)) ((. .) .))) - (3 5 (. ((. .) .)) (((. .) .) (. (. .)))) - (3 5 (. ((. .) .)) (((. .) .) ((. .) .))) - (3 5 (. ((. .) .)) ((. (. (. .))) (. .))) - (3 5 (. ((. .) .)) ((. ((. .) .)) (. .))) - (3 5 (. ((. .) .)) (((. .) (. .)) (. .))) - (3 5 (. ((. .) .)) (((. (. .)) .) (. .))) - (3 5 (. ((. .) .)) ((((. .) .) .) (. .))) - (3 5 ((. .) (. .)) ((. .) (. (. (. .))))) - (3 5 ((. .) (. .)) ((. .) (. ((. .) .)))) - (3 5 ((. .) (. .)) ((. .) ((. .) (. .)))) - (3 5 ((. .) (. .)) ((. .) ((. (. .)) .))) - (3 5 ((. .) (. .)) ((. .) (((. .) .) .))) - (3 5 ((. .) (. .)) ((. (. .)) (. (. .)))) - (3 5 ((. .) (. .)) ((. (. .)) ((. .) .))) - (3 5 ((. .) (. .)) (((. .) .) (. (. .)))) - (3 5 ((. .) (. .)) (((. .) .) ((. .) .))) - (3 5 ((. .) (. .)) ((. (. (. .))) (. .))) - (3 5 ((. .) (. .)) ((. ((. .) .)) (. .))) - (3 5 ((. .) (. .)) (((. .) (. .)) (. .))) - (3 5 ((. .) (. .)) (((. (. .)) .) (. .))) - (3 5 ((. .) (. .)) ((((. .) .) .) (. .))) - (3 5 ((. (. .)) .) ((. .) (. (. (. .))))) - (3 5 ((. (. .)) .) ((. .) (. ((. .) .)))) - (3 5 ((. (. .)) .) ((. .) ((. .) (. .)))) - (3 5 ((. (. .)) .) ((. .) ((. (. .)) .))) - (3 5 ((. (. .)) .) ((. .) (((. .) .) .))) - (3 5 ((. (. .)) .) ((. (. .)) (. (. .)))) - (3 5 ((. (. .)) .) ((. (. .)) ((. .) .))) - (3 5 ((. (. .)) .) (((. .) .) (. (. .)))) - (3 5 ((. (. .)) .) (((. .) .) ((. .) .))) - (3 5 ((. (. .)) .) ((. (. (. .))) (. .))) - (3 5 ((. (. .)) .) ((. ((. .) .)) (. .))) - (3 5 ((. (. .)) .) (((. .) (. .)) (. .))) - (3 5 ((. (. .)) .) (((. (. .)) .) (. .))) - (3 5 ((. (. .)) .) ((((. .) .) .) (. .))) - (3 5 (((. .) .) .) ((. .) (. (. (. .))))) - (3 5 (((. .) .) .) ((. .) (. ((. .) .)))) - (3 5 (((. .) .) .) ((. .) ((. .) (. .)))) - (3 5 (((. .) .) .) ((. .) ((. (. .)) .))) - (3 5 (((. .) .) .) ((. .) (((. .) .) .))) - (3 5 (((. .) .) .) ((. (. .)) (. (. .)))) - (3 5 (((. .) .) .) ((. (. .)) ((. .) .))) - (3 5 (((. .) .) .) (((. .) .) (. (. .)))) - (3 5 (((. .) .) .) (((. .) .) ((. .) .))) - (3 5 (((. .) .) .) ((. (. (. .))) (. .))) - (3 5 (((. .) .) .) ((. ((. .) .)) (. .))) - (3 5 (((. .) .) .) (((. .) (. .)) (. .))) - (3 5 (((. .) .) .) (((. (. .)) .) (. .))) - (3 5 (((. .) .) .) ((((. .) .) .) (. .))) - (4 4 (. ((. .) (. .))) (. ((. .) (. .)))) - (4 4 (. ((. .) (. .))) ((. .) (. (. .)))) - (4 4 (. ((. .) (. .))) ((. .) ((. .) .))) - (4 4 (. ((. .) (. .))) ((. (. .)) (. .))) - (4 4 (. ((. .) (. .))) (((. .) .) (. .))) - (4 4 (. ((. .) (. .))) (((. .) (. .)) .)) - (4 4 ((. .) (. (. .))) (. ((. .) (. .)))) - (4 4 ((. .) (. (. .))) ((. .) (. (. .)))) - (4 4 ((. .) (. (. .))) ((. .) ((. .) .))) - (4 4 ((. .) (. (. .))) ((. (. .)) (. .))) - (4 4 ((. .) (. (. .))) (((. .) .) (. .))) - (4 4 ((. .) (. (. .))) (((. .) (. .)) .)) - (4 4 ((. .) ((. .) .)) (. ((. .) (. .)))) - (4 4 ((. .) ((. .) .)) ((. .) (. (. .)))) - (4 4 ((. .) ((. .) .)) ((. .) ((. .) .))) - (4 4 ((. .) ((. .) .)) ((. (. .)) (. .))) - (4 4 ((. .) ((. .) .)) (((. .) .) (. .))) - (4 4 ((. .) ((. .) .)) (((. .) (. .)) .)) - (4 4 ((. (. .)) (. .)) (. ((. .) (. .)))) - (4 4 ((. (. .)) (. .)) ((. .) (. (. .)))) - (4 4 ((. (. .)) (. .)) ((. .) ((. .) .))) - (4 4 ((. (. .)) (. .)) ((. (. .)) (. .))) - (4 4 ((. (. .)) (. .)) (((. .) .) (. .))) - (4 4 ((. (. .)) (. .)) (((. .) (. .)) .)) - (4 4 (((. .) .) (. .)) (. ((. .) (. .)))) - (4 4 (((. .) .) (. .)) ((. .) (. (. .)))) - (4 4 (((. .) .) (. .)) ((. .) ((. .) .))) - (4 4 (((. .) .) (. .)) ((. (. .)) (. .))) - (4 4 (((. .) .) (. .)) (((. .) .) (. .))) - (4 4 (((. .) .) (. .)) (((. .) (. .)) .)) - (4 4 (((. .) (. .)) .) (. ((. .) (. .)))) - (4 4 (((. .) (. .)) .) ((. .) (. (. .)))) - (4 4 (((. .) (. .)) .) ((. .) ((. .) .))) - (4 4 (((. .) (. .)) .) ((. (. .)) (. .))) - (4 4 (((. .) (. .)) .) (((. .) .) (. .))) - (4 4 (((. .) (. .)) .) (((. .) (. .)) .)) - (5 3 ((. .) (. (. (. .)))) (. (. (. .)))) - (5 3 ((. .) (. (. (. .)))) (. ((. .) .))) - (5 3 ((. .) (. (. (. .)))) ((. .) (. .))) - (5 3 ((. .) (. (. (. .)))) ((. (. .)) .)) - (5 3 ((. .) (. (. (. .)))) (((. .) .) .)) - (5 3 ((. .) (. ((. .) .))) (. (. (. .)))) - (5 3 ((. .) (. ((. .) .))) (. ((. .) .))) - (5 3 ((. .) (. ((. .) .))) ((. .) (. .))) - (5 3 ((. .) (. ((. .) .))) ((. (. .)) .)) - (5 3 ((. .) (. ((. .) .))) (((. .) .) .)) - (5 3 ((. .) ((. .) (. .))) (. (. (. .)))) - (5 3 ((. .) ((. .) (. .))) (. ((. .) .))) - (5 3 ((. .) ((. .) (. .))) ((. .) (. .))) - (5 3 ((. .) ((. .) (. .))) ((. (. .)) .)) - (5 3 ((. .) ((. .) (. .))) (((. .) .) .)) - (5 3 ((. .) ((. (. .)) .)) (. (. (. .)))) - (5 3 ((. .) ((. (. .)) .)) (. ((. .) .))) - (5 3 ((. .) ((. (. .)) .)) ((. .) (. .))) - (5 3 ((. .) ((. (. .)) .)) ((. (. .)) .)) - (5 3 ((. .) ((. (. .)) .)) (((. .) .) .)) - (5 3 ((. .) (((. .) .) .)) (. (. (. .)))) - (5 3 ((. .) (((. .) .) .)) (. ((. .) .))) - (5 3 ((. .) (((. .) .) .)) ((. .) (. .))) - (5 3 ((. .) (((. .) .) .)) ((. (. .)) .)) - (5 3 ((. .) (((. .) .) .)) (((. .) .) .)) - (5 3 ((. (. .)) (. (. .))) (. (. (. .)))) - (5 3 ((. (. .)) (. (. .))) (. ((. .) .))) - (5 3 ((. (. .)) (. (. .))) ((. .) (. .))) - (5 3 ((. (. .)) (. (. .))) ((. (. .)) .)) - (5 3 ((. (. .)) (. (. .))) (((. .) .) .)) - (5 3 ((. (. .)) ((. .) .)) (. (. (. .)))) - (5 3 ((. (. .)) ((. .) .)) (. ((. .) .))) - (5 3 ((. (. .)) ((. .) .)) ((. .) (. .))) - (5 3 ((. (. .)) ((. .) .)) ((. (. .)) .)) - (5 3 ((. (. .)) ((. .) .)) (((. .) .) .)) - (5 3 (((. .) .) (. (. .))) (. (. (. .)))) - (5 3 (((. .) .) (. (. .))) (. ((. .) .))) - (5 3 (((. .) .) (. (. .))) ((. .) (. .))) - (5 3 (((. .) .) (. (. .))) ((. (. .)) .)) - (5 3 (((. .) .) (. (. .))) (((. .) .) .)) - (5 3 (((. .) .) ((. .) .)) (. (. (. .)))) - (5 3 (((. .) .) ((. .) .)) (. ((. .) .))) - (5 3 (((. .) .) ((. .) .)) ((. .) (. .))) - (5 3 (((. .) .) ((. .) .)) ((. (. .)) .)) - (5 3 (((. .) .) ((. .) .)) (((. .) .) .)) - (5 3 ((. (. (. .))) (. .)) (. (. (. .)))) - (5 3 ((. (. (. .))) (. .)) (. ((. .) .))) - (5 3 ((. (. (. .))) (. .)) ((. .) (. .))) - (5 3 ((. (. (. .))) (. .)) ((. (. .)) .)) - (5 3 ((. (. (. .))) (. .)) (((. .) .) .)) - (5 3 ((. ((. .) .)) (. .)) (. (. (. .)))) - (5 3 ((. ((. .) .)) (. .)) (. ((. .) .))) - (5 3 ((. ((. .) .)) (. .)) ((. .) (. .))) - (5 3 ((. ((. .) .)) (. .)) ((. (. .)) .)) - (5 3 ((. ((. .) .)) (. .)) (((. .) .) .)) - (5 3 (((. .) (. .)) (. .)) (. (. (. .)))) - (5 3 (((. .) (. .)) (. .)) (. ((. .) .))) - (5 3 (((. .) (. .)) (. .)) ((. .) (. .))) - (5 3 (((. .) (. .)) (. .)) ((. (. .)) .)) - (5 3 (((. .) (. .)) (. .)) (((. .) .) .)) - (5 3 (((. (. .)) .) (. .)) (. (. (. .)))) - (5 3 (((. (. .)) .) (. .)) (. ((. .) .))) - (5 3 (((. (. .)) .) (. .)) ((. .) (. .))) - (5 3 (((. (. .)) .) (. .)) ((. (. .)) .)) - (5 3 (((. (. .)) .) (. .)) (((. .) .) .)) - (5 3 ((((. .) .) .) (. .)) (. (. (. .)))) - (5 3 ((((. .) .) .) (. .)) (. ((. .) .))) - (5 3 ((((. .) .) .) (. .)) ((. .) (. .))) - (5 3 ((((. .) .) .) (. .)) ((. (. .)) .)) - (5 3 ((((. .) .) .) (. .)) (((. .) .) .)) - (6 2 ((. .) (. ((. .) (. .)))) (. (. .))) - (6 2 ((. .) (. ((. .) (. .)))) ((. .) .)) - (6 2 ((. .) ((. .) (. (. .)))) (. (. .))) - (6 2 ((. .) ((. .) (. (. .)))) ((. .) .)) - (6 2 ((. .) ((. .) ((. .) .))) (. (. .))) - (6 2 ((. .) ((. .) ((. .) .))) ((. .) .)) - (6 2 ((. .) ((. (. .)) (. .))) (. (. .))) - (6 2 ((. .) ((. (. .)) (. .))) ((. .) .)) - (6 2 ((. .) (((. .) .) (. .))) (. (. .))) - (6 2 ((. .) (((. .) .) (. .))) ((. .) .)) - (6 2 ((. .) (((. .) (. .)) .)) (. (. .))) - (6 2 ((. .) (((. .) (. .)) .)) ((. .) .)) - (6 2 ((. (. .)) (. (. (. .)))) (. (. .))) - (6 2 ((. (. .)) (. (. (. .)))) ((. .) .)) - (6 2 ((. (. .)) (. ((. .) .))) (. (. .))) - (6 2 ((. (. .)) (. ((. .) .))) ((. .) .)) - (6 2 ((. (. .)) ((. .) (. .))) (. (. .))) - (6 2 ((. (. .)) ((. .) (. .))) ((. .) .)) - (6 2 ((. (. .)) ((. (. .)) .)) (. (. .))) - (6 2 ((. (. .)) ((. (. .)) .)) ((. .) .)) - (6 2 ((. (. .)) (((. .) .) .)) (. (. .))) - (6 2 ((. (. .)) (((. .) .) .)) ((. .) .)) - (6 2 (((. .) .) (. (. (. .)))) (. (. .))) - (6 2 (((. .) .) (. (. (. .)))) ((. .) .)) - (6 2 (((. .) .) (. ((. .) .))) (. (. .))) - (6 2 (((. .) .) (. ((. .) .))) ((. .) .)) - (6 2 (((. .) .) ((. .) (. .))) (. (. .))) - (6 2 (((. .) .) ((. .) (. .))) ((. .) .)) - (6 2 (((. .) .) ((. (. .)) .)) (. (. .))) - (6 2 (((. .) .) ((. (. .)) .)) ((. .) .)) - (6 2 (((. .) .) (((. .) .) .)) (. (. .))) - (6 2 (((. .) .) (((. .) .) .)) ((. .) .)) - (6 2 ((. (. (. .))) (. (. .))) (. (. .))) - (6 2 ((. (. (. .))) (. (. .))) ((. .) .)) - (6 2 ((. (. (. .))) ((. .) .)) (. (. .))) - (6 2 ((. (. (. .))) ((. .) .)) ((. .) .)) - (6 2 ((. ((. .) .)) (. (. .))) (. (. .))) - (6 2 ((. ((. .) .)) (. (. .))) ((. .) .)) - (6 2 ((. ((. .) .)) ((. .) .)) (. (. .))) - (6 2 ((. ((. .) .)) ((. .) .)) ((. .) .)) - (6 2 (((. .) (. .)) (. (. .))) (. (. .))) - (6 2 (((. .) (. .)) (. (. .))) ((. .) .)) - (6 2 (((. .) (. .)) ((. .) .)) (. (. .))) - (6 2 (((. .) (. .)) ((. .) .)) ((. .) .)) - (6 2 (((. (. .)) .) (. (. .))) (. (. .))) - (6 2 (((. (. .)) .) (. (. .))) ((. .) .)) - (6 2 (((. (. .)) .) ((. .) .)) (. (. .))) - (6 2 (((. (. .)) .) ((. .) .)) ((. .) .)) - (6 2 ((((. .) .) .) (. (. .))) (. (. .))) - (6 2 ((((. .) .) .) (. (. .))) ((. .) .)) - (6 2 ((((. .) .) .) ((. .) .)) (. (. .))) - (6 2 ((((. .) .) .) ((. .) .)) ((. .) .)) - (6 2 ((. ((. .) (. .))) (. .)) (. (. .))) - (6 2 ((. ((. .) (. .))) (. .)) ((. .) .)) - (6 2 (((. .) (. (. .))) (. .)) (. (. .))) - (6 2 (((. .) (. (. .))) (. .)) ((. .) .)) - (6 2 (((. .) ((. .) .)) (. .)) (. (. .))) - (6 2 (((. .) ((. .) .)) (. .)) ((. .) .)) - (6 2 (((. (. .)) (. .)) (. .)) (. (. .))) - (6 2 (((. (. .)) (. .)) (. .)) ((. .) .)) - (6 2 ((((. .) .) (. .)) (. .)) (. (. .))) - (6 2 ((((. .) .) (. .)) (. .)) ((. .) .)) - (6 2 ((((. .) (. .)) .) (. .)) (. (. .))) - (6 2 ((((. .) (. .)) .) (. .)) ((. .) .)) - (7 1 (((. .) (. .)) ((. .) (. .))) (. .)) - (2 7 (. (. .)) ((. .) ((. .) ((. .) (. .))))) - (2 7 (. (. .)) ((. .) ((. (. .)) (. (. .))))) - (2 7 (. (. .)) ((. .) ((. (. .)) ((. .) .)))) - (2 7 (. (. .)) ((. .) (((. .) .) (. (. .))))) - (2 7 (. (. .)) ((. .) (((. .) .) ((. .) .)))) - (2 7 (. (. .)) ((. .) (((. .) (. .)) (. .)))) - (2 7 (. (. .)) ((. (. .)) (. ((. .) (. .))))) - (2 7 (. (. .)) ((. (. .)) ((. .) (. (. .))))) - (2 7 (. (. .)) ((. (. .)) ((. .) ((. .) .)))) - (2 7 (. (. .)) ((. (. .)) ((. (. .)) (. .)))) - (2 7 (. (. .)) ((. (. .)) (((. .) .) (. .)))) - (2 7 (. (. .)) ((. (. .)) (((. .) (. .)) .))) - (2 7 (. (. .)) (((. .) .) (. ((. .) (. .))))) - (2 7 (. (. .)) (((. .) .) ((. .) (. (. .))))) - (2 7 (. (. .)) (((. .) .) ((. .) ((. .) .)))) - (2 7 (. (. .)) (((. .) .) ((. (. .)) (. .)))) - (2 7 (. (. .)) (((. .) .) (((. .) .) (. .)))) - (2 7 (. (. .)) (((. .) .) (((. .) (. .)) .))) - (2 7 (. (. .)) ((. (. (. .))) (. (. (. .))))) - (2 7 (. (. .)) ((. (. (. .))) (. ((. .) .)))) - (2 7 (. (. .)) ((. (. (. .))) ((. .) (. .)))) - (2 7 (. (. .)) ((. (. (. .))) ((. (. .)) .))) - (2 7 (. (. .)) ((. (. (. .))) (((. .) .) .))) - (2 7 (. (. .)) ((. ((. .) .)) (. (. (. .))))) - (2 7 (. (. .)) ((. ((. .) .)) (. ((. .) .)))) - (2 7 (. (. .)) ((. ((. .) .)) ((. .) (. .)))) - (2 7 (. (. .)) ((. ((. .) .)) ((. (. .)) .))) - (2 7 (. (. .)) ((. ((. .) .)) (((. .) .) .))) - (2 7 (. (. .)) (((. .) (. .)) (. (. (. .))))) - (2 7 (. (. .)) (((. .) (. .)) (. ((. .) .)))) - (2 7 (. (. .)) (((. .) (. .)) ((. .) (. .)))) - (2 7 (. (. .)) (((. .) (. .)) ((. (. .)) .))) - (2 7 (. (. .)) (((. .) (. .)) (((. .) .) .))) - (2 7 (. (. .)) (((. (. .)) .) (. (. (. .))))) - (2 7 (. (. .)) (((. (. .)) .) (. ((. .) .)))) - (2 7 (. (. .)) (((. (. .)) .) ((. .) (. .)))) - (2 7 (. (. .)) (((. (. .)) .) ((. (. .)) .))) - (2 7 (. (. .)) (((. (. .)) .) (((. .) .) .))) - (2 7 (. (. .)) ((((. .) .) .) (. (. (. .))))) - (2 7 (. (. .)) ((((. .) .) .) (. ((. .) .)))) - (2 7 (. (. .)) ((((. .) .) .) ((. .) (. .)))) - (2 7 (. (. .)) ((((. .) .) .) ((. (. .)) .))) - (2 7 (. (. .)) ((((. .) .) .) (((. .) .) .))) - (2 7 (. (. .)) ((. ((. .) (. .))) (. (. .)))) - (2 7 (. (. .)) ((. ((. .) (. .))) ((. .) .))) - (2 7 (. (. .)) (((. .) (. (. .))) (. (. .)))) - (2 7 (. (. .)) (((. .) (. (. .))) ((. .) .))) - (2 7 (. (. .)) (((. .) ((. .) .)) (. (. .)))) - (2 7 (. (. .)) (((. .) ((. .) .)) ((. .) .))) - (2 7 (. (. .)) (((. (. .)) (. .)) (. (. .)))) - (2 7 (. (. .)) (((. (. .)) (. .)) ((. .) .))) - (2 7 (. (. .)) ((((. .) .) (. .)) (. (. .)))) - (2 7 (. (. .)) ((((. .) .) (. .)) ((. .) .))) - (2 7 (. (. .)) ((((. .) (. .)) .) (. (. .)))) - (2 7 (. (. .)) ((((. .) (. .)) .) ((. .) .))) - (2 7 (. (. .)) (((. .) ((. .) (. .))) (. .))) - (2 7 (. (. .)) (((. (. .)) (. (. .))) (. .))) - (2 7 (. (. .)) (((. (. .)) ((. .) .)) (. .))) - (2 7 (. (. .)) ((((. .) .) (. (. .))) (. .))) - (2 7 (. (. .)) ((((. .) .) ((. .) .)) (. .))) - (2 7 (. (. .)) ((((. .) (. .)) (. .)) (. .))) - (2 7 ((. .) .) ((. .) ((. .) ((. .) (. .))))) - (2 7 ((. .) .) ((. .) ((. (. .)) (. (. .))))) - (2 7 ((. .) .) ((. .) ((. (. .)) ((. .) .)))) - (2 7 ((. .) .) ((. .) (((. .) .) (. (. .))))) - (2 7 ((. .) .) ((. .) (((. .) .) ((. .) .)))) - (2 7 ((. .) .) ((. .) (((. .) (. .)) (. .)))) - (2 7 ((. .) .) ((. (. .)) (. ((. .) (. .))))) - (2 7 ((. .) .) ((. (. .)) ((. .) (. (. .))))) - (2 7 ((. .) .) ((. (. .)) ((. .) ((. .) .)))) - (2 7 ((. .) .) ((. (. .)) ((. (. .)) (. .)))) - (2 7 ((. .) .) ((. (. .)) (((. .) .) (. .)))) - (2 7 ((. .) .) ((. (. .)) (((. .) (. .)) .))) - (2 7 ((. .) .) (((. .) .) (. ((. .) (. .))))) - (2 7 ((. .) .) (((. .) .) ((. .) (. (. .))))) - (2 7 ((. .) .) (((. .) .) ((. .) ((. .) .)))) - (2 7 ((. .) .) (((. .) .) ((. (. .)) (. .)))) - (2 7 ((. .) .) (((. .) .) (((. .) .) (. .)))) - (2 7 ((. .) .) (((. .) .) (((. .) (. .)) .))) - (2 7 ((. .) .) ((. (. (. .))) (. (. (. .))))) - (2 7 ((. .) .) ((. (. (. .))) (. ((. .) .)))) - (2 7 ((. .) .) ((. (. (. .))) ((. .) (. .)))) - (2 7 ((. .) .) ((. (. (. .))) ((. (. .)) .))) - (2 7 ((. .) .) ((. (. (. .))) (((. .) .) .))) - (2 7 ((. .) .) ((. ((. .) .)) (. (. (. .))))) - (2 7 ((. .) .) ((. ((. .) .)) (. ((. .) .)))) - (2 7 ((. .) .) ((. ((. .) .)) ((. .) (. .)))) - (2 7 ((. .) .) ((. ((. .) .)) ((. (. .)) .))) - (2 7 ((. .) .) ((. ((. .) .)) (((. .) .) .))) - (2 7 ((. .) .) (((. .) (. .)) (. (. (. .))))) - (2 7 ((. .) .) (((. .) (. .)) (. ((. .) .)))) - (2 7 ((. .) .) (((. .) (. .)) ((. .) (. .)))) - (2 7 ((. .) .) (((. .) (. .)) ((. (. .)) .))) - (2 7 ((. .) .) (((. .) (. .)) (((. .) .) .))) - (2 7 ((. .) .) (((. (. .)) .) (. (. (. .))))) - (2 7 ((. .) .) (((. (. .)) .) (. ((. .) .)))) - (2 7 ((. .) .) (((. (. .)) .) ((. .) (. .)))) - (2 7 ((. .) .) (((. (. .)) .) ((. (. .)) .))) - (2 7 ((. .) .) (((. (. .)) .) (((. .) .) .))) - (2 7 ((. .) .) ((((. .) .) .) (. (. (. .))))) - (2 7 ((. .) .) ((((. .) .) .) (. ((. .) .)))) - (2 7 ((. .) .) ((((. .) .) .) ((. .) (. .)))) - (2 7 ((. .) .) ((((. .) .) .) ((. (. .)) .))) - (2 7 ((. .) .) ((((. .) .) .) (((. .) .) .))) - (2 7 ((. .) .) ((. ((. .) (. .))) (. (. .)))) - (2 7 ((. .) .) ((. ((. .) (. .))) ((. .) .))) - (2 7 ((. .) .) (((. .) (. (. .))) (. (. .)))) - (2 7 ((. .) .) (((. .) (. (. .))) ((. .) .))) - (2 7 ((. .) .) (((. .) ((. .) .)) (. (. .)))) - (2 7 ((. .) .) (((. .) ((. .) .)) ((. .) .))) - (2 7 ((. .) .) (((. (. .)) (. .)) (. (. .)))) - (2 7 ((. .) .) (((. (. .)) (. .)) ((. .) .))) - (2 7 ((. .) .) ((((. .) .) (. .)) (. (. .)))) - (2 7 ((. .) .) ((((. .) .) (. .)) ((. .) .))) - (2 7 ((. .) .) ((((. .) (. .)) .) (. (. .)))) - (2 7 ((. .) .) ((((. .) (. .)) .) ((. .) .))) - (2 7 ((. .) .) (((. .) ((. .) (. .))) (. .))) - (2 7 ((. .) .) (((. (. .)) (. (. .))) (. .))) - (2 7 ((. .) .) (((. (. .)) ((. .) .)) (. .))) - (2 7 ((. .) .) ((((. .) .) (. (. .))) (. .))) - (2 7 ((. .) .) ((((. .) .) ((. .) .)) (. .))) - (2 7 ((. .) .) ((((. .) (. .)) (. .)) (. .))) - (3 6 (. (. (. .))) ((. .) (. ((. .) (. .))))) - (3 6 (. (. (. .))) ((. .) ((. .) (. (. .))))) - (3 6 (. (. (. .))) ((. .) ((. .) ((. .) .)))) - (3 6 (. (. (. .))) ((. .) ((. (. .)) (. .)))) - (3 6 (. (. (. .))) ((. .) (((. .) .) (. .)))) - (3 6 (. (. (. .))) ((. .) (((. .) (. .)) .))) - (3 6 (. (. (. .))) ((. (. .)) (. (. (. .))))) - (3 6 (. (. (. .))) ((. (. .)) (. ((. .) .)))) - (3 6 (. (. (. .))) ((. (. .)) ((. .) (. .)))) - (3 6 (. (. (. .))) ((. (. .)) ((. (. .)) .))) - (3 6 (. (. (. .))) ((. (. .)) (((. .) .) .))) - (3 6 (. (. (. .))) (((. .) .) (. (. (. .))))) - (3 6 (. (. (. .))) (((. .) .) (. ((. .) .)))) - (3 6 (. (. (. .))) (((. .) .) ((. .) (. .)))) - (3 6 (. (. (. .))) (((. .) .) ((. (. .)) .))) - (3 6 (. (. (. .))) (((. .) .) (((. .) .) .))) - (3 6 (. (. (. .))) ((. (. (. .))) (. (. .)))) - (3 6 (. (. (. .))) ((. (. (. .))) ((. .) .))) - (3 6 (. (. (. .))) ((. ((. .) .)) (. (. .)))) - (3 6 (. (. (. .))) ((. ((. .) .)) ((. .) .))) - (3 6 (. (. (. .))) (((. .) (. .)) (. (. .)))) - (3 6 (. (. (. .))) (((. .) (. .)) ((. .) .))) - (3 6 (. (. (. .))) (((. (. .)) .) (. (. .)))) - (3 6 (. (. (. .))) (((. (. .)) .) ((. .) .))) - (3 6 (. (. (. .))) ((((. .) .) .) (. (. .)))) - (3 6 (. (. (. .))) ((((. .) .) .) ((. .) .))) - (3 6 (. (. (. .))) ((. ((. .) (. .))) (. .))) - (3 6 (. (. (. .))) (((. .) (. (. .))) (. .))) - (3 6 (. (. (. .))) (((. .) ((. .) .)) (. .))) - (3 6 (. (. (. .))) (((. (. .)) (. .)) (. .))) - (3 6 (. (. (. .))) ((((. .) .) (. .)) (. .))) - (3 6 (. (. (. .))) ((((. .) (. .)) .) (. .))) - (3 6 (. ((. .) .)) ((. .) (. ((. .) (. .))))) - (3 6 (. ((. .) .)) ((. .) ((. .) (. (. .))))) - (3 6 (. ((. .) .)) ((. .) ((. .) ((. .) .)))) - (3 6 (. ((. .) .)) ((. .) ((. (. .)) (. .)))) - (3 6 (. ((. .) .)) ((. .) (((. .) .) (. .)))) - (3 6 (. ((. .) .)) ((. .) (((. .) (. .)) .))) - (3 6 (. ((. .) .)) ((. (. .)) (. (. (. .))))) - (3 6 (. ((. .) .)) ((. (. .)) (. ((. .) .)))) - (3 6 (. ((. .) .)) ((. (. .)) ((. .) (. .)))) - (3 6 (. ((. .) .)) ((. (. .)) ((. (. .)) .))) - (3 6 (. ((. .) .)) ((. (. .)) (((. .) .) .))) - (3 6 (. ((. .) .)) (((. .) .) (. (. (. .))))) - (3 6 (. ((. .) .)) (((. .) .) (. ((. .) .)))) - (3 6 (. ((. .) .)) (((. .) .) ((. .) (. .)))) - (3 6 (. ((. .) .)) (((. .) .) ((. (. .)) .))) - (3 6 (. ((. .) .)) (((. .) .) (((. .) .) .))) - (3 6 (. ((. .) .)) ((. (. (. .))) (. (. .)))) - (3 6 (. ((. .) .)) ((. (. (. .))) ((. .) .))) - (3 6 (. ((. .) .)) ((. ((. .) .)) (. (. .)))) - (3 6 (. ((. .) .)) ((. ((. .) .)) ((. .) .))) - (3 6 (. ((. .) .)) (((. .) (. .)) (. (. .)))) - (3 6 (. ((. .) .)) (((. .) (. .)) ((. .) .))) - (3 6 (. ((. .) .)) (((. (. .)) .) (. (. .)))) - (3 6 (. ((. .) .)) (((. (. .)) .) ((. .) .))) - (3 6 (. ((. .) .)) ((((. .) .) .) (. (. .)))) - (3 6 (. ((. .) .)) ((((. .) .) .) ((. .) .))) - (3 6 (. ((. .) .)) ((. ((. .) (. .))) (. .))) - (3 6 (. ((. .) .)) (((. .) (. (. .))) (. .))) - (3 6 (. ((. .) .)) (((. .) ((. .) .)) (. .))) - (3 6 (. ((. .) .)) (((. (. .)) (. .)) (. .))) - (3 6 (. ((. .) .)) ((((. .) .) (. .)) (. .))) - (3 6 (. ((. .) .)) ((((. .) (. .)) .) (. .))) - (3 6 ((. .) (. .)) ((. .) (. ((. .) (. .))))) - (3 6 ((. .) (. .)) ((. .) ((. .) (. (. .))))) - (3 6 ((. .) (. .)) ((. .) ((. .) ((. .) .)))) - (3 6 ((. .) (. .)) ((. .) ((. (. .)) (. .)))) - (3 6 ((. .) (. .)) ((. .) (((. .) .) (. .)))) - (3 6 ((. .) (. .)) ((. .) (((. .) (. .)) .))) - (3 6 ((. .) (. .)) ((. (. .)) (. (. (. .))))) - (3 6 ((. .) (. .)) ((. (. .)) (. ((. .) .)))) - (3 6 ((. .) (. .)) ((. (. .)) ((. .) (. .)))) - (3 6 ((. .) (. .)) ((. (. .)) ((. (. .)) .))) - (3 6 ((. .) (. .)) ((. (. .)) (((. .) .) .))) - (3 6 ((. .) (. .)) (((. .) .) (. (. (. .))))) - (3 6 ((. .) (. .)) (((. .) .) (. ((. .) .)))) - (3 6 ((. .) (. .)) (((. .) .) ((. .) (. .)))) - (3 6 ((. .) (. .)) (((. .) .) ((. (. .)) .))) - (3 6 ((. .) (. .)) (((. .) .) (((. .) .) .))) - (3 6 ((. .) (. .)) ((. (. (. .))) (. (. .)))) - (3 6 ((. .) (. .)) ((. (. (. .))) ((. .) .))) - (3 6 ((. .) (. .)) ((. ((. .) .)) (. (. .)))) - (3 6 ((. .) (. .)) ((. ((. .) .)) ((. .) .))) - (3 6 ((. .) (. .)) (((. .) (. .)) (. (. .)))) - (3 6 ((. .) (. .)) (((. .) (. .)) ((. .) .))) - (3 6 ((. .) (. .)) (((. (. .)) .) (. (. .)))) - (3 6 ((. .) (. .)) (((. (. .)) .) ((. .) .))) - (3 6 ((. .) (. .)) ((((. .) .) .) (. (. .)))) - (3 6 ((. .) (. .)) ((((. .) .) .) ((. .) .))) - (3 6 ((. .) (. .)) ((. ((. .) (. .))) (. .))) - (3 6 ((. .) (. .)) (((. .) (. (. .))) (. .))) - (3 6 ((. .) (. .)) (((. .) ((. .) .)) (. .))) - (3 6 ((. .) (. .)) (((. (. .)) (. .)) (. .))) - (3 6 ((. .) (. .)) ((((. .) .) (. .)) (. .))) - (3 6 ((. .) (. .)) ((((. .) (. .)) .) (. .))) - (3 6 ((. (. .)) .) ((. .) (. ((. .) (. .))))) - (3 6 ((. (. .)) .) ((. .) ((. .) (. (. .))))) - (3 6 ((. (. .)) .) ((. .) ((. .) ((. .) .)))) - (3 6 ((. (. .)) .) ((. .) ((. (. .)) (. .)))) - (3 6 ((. (. .)) .) ((. .) (((. .) .) (. .)))) - (3 6 ((. (. .)) .) ((. .) (((. .) (. .)) .))) - (3 6 ((. (. .)) .) ((. (. .)) (. (. (. .))))) - (3 6 ((. (. .)) .) ((. (. .)) (. ((. .) .)))) - (3 6 ((. (. .)) .) ((. (. .)) ((. .) (. .)))) - (3 6 ((. (. .)) .) ((. (. .)) ((. (. .)) .))) - (3 6 ((. (. .)) .) ((. (. .)) (((. .) .) .))) - (3 6 ((. (. .)) .) (((. .) .) (. (. (. .))))) - (3 6 ((. (. .)) .) (((. .) .) (. ((. .) .)))) - (3 6 ((. (. .)) .) (((. .) .) ((. .) (. .)))) - (3 6 ((. (. .)) .) (((. .) .) ((. (. .)) .))) - (3 6 ((. (. .)) .) (((. .) .) (((. .) .) .))) - (3 6 ((. (. .)) .) ((. (. (. .))) (. (. .)))) - (3 6 ((. (. .)) .) ((. (. (. .))) ((. .) .))) - (3 6 ((. (. .)) .) ((. ((. .) .)) (. (. .)))) - (3 6 ((. (. .)) .) ((. ((. .) .)) ((. .) .))) - (3 6 ((. (. .)) .) (((. .) (. .)) (. (. .)))) - (3 6 ((. (. .)) .) (((. .) (. .)) ((. .) .))) - (3 6 ((. (. .)) .) (((. (. .)) .) (. (. .)))) - (3 6 ((. (. .)) .) (((. (. .)) .) ((. .) .))) - (3 6 ((. (. .)) .) ((((. .) .) .) (. (. .)))) - (3 6 ((. (. .)) .) ((((. .) .) .) ((. .) .))) - (3 6 ((. (. .)) .) ((. ((. .) (. .))) (. .))) - (3 6 ((. (. .)) .) (((. .) (. (. .))) (. .))) - (3 6 ((. (. .)) .) (((. .) ((. .) .)) (. .))) - (3 6 ((. (. .)) .) (((. (. .)) (. .)) (. .))) - (3 6 ((. (. .)) .) ((((. .) .) (. .)) (. .))) - (3 6 ((. (. .)) .) ((((. .) (. .)) .) (. .))) - (3 6 (((. .) .) .) ((. .) (. ((. .) (. .))))) - (3 6 (((. .) .) .) ((. .) ((. .) (. (. .))))) - (3 6 (((. .) .) .) ((. .) ((. .) ((. .) .)))) - (3 6 (((. .) .) .) ((. .) ((. (. .)) (. .)))) - (3 6 (((. .) .) .) ((. .) (((. .) .) (. .)))) - (3 6 (((. .) .) .) ((. .) (((. .) (. .)) .))) - (3 6 (((. .) .) .) ((. (. .)) (. (. (. .))))) - (3 6 (((. .) .) .) ((. (. .)) (. ((. .) .)))) - (3 6 (((. .) .) .) ((. (. .)) ((. .) (. .)))) - (3 6 (((. .) .) .) ((. (. .)) ((. (. .)) .))) - (3 6 (((. .) .) .) ((. (. .)) (((. .) .) .))) - (3 6 (((. .) .) .) (((. .) .) (. (. (. .))))) - (3 6 (((. .) .) .) (((. .) .) (. ((. .) .)))) - (3 6 (((. .) .) .) (((. .) .) ((. .) (. .)))) - (3 6 (((. .) .) .) (((. .) .) ((. (. .)) .))) - (3 6 (((. .) .) .) (((. .) .) (((. .) .) .))) - (3 6 (((. .) .) .) ((. (. (. .))) (. (. .)))) - (3 6 (((. .) .) .) ((. (. (. .))) ((. .) .))) - (3 6 (((. .) .) .) ((. ((. .) .)) (. (. .)))) - (3 6 (((. .) .) .) ((. ((. .) .)) ((. .) .))) - (3 6 (((. .) .) .) (((. .) (. .)) (. (. .)))) - (3 6 (((. .) .) .) (((. .) (. .)) ((. .) .))) - (3 6 (((. .) .) .) (((. (. .)) .) (. (. .)))) - (3 6 (((. .) .) .) (((. (. .)) .) ((. .) .))) - (3 6 (((. .) .) .) ((((. .) .) .) (. (. .)))) - (3 6 (((. .) .) .) ((((. .) .) .) ((. .) .))) - (3 6 (((. .) .) .) ((. ((. .) (. .))) (. .))) - (3 6 (((. .) .) .) (((. .) (. (. .))) (. .))) - (3 6 (((. .) .) .) (((. .) ((. .) .)) (. .))) - (3 6 (((. .) .) .) (((. (. .)) (. .)) (. .))) - (3 6 (((. .) .) .) ((((. .) .) (. .)) (. .))) - (3 6 (((. .) .) .) ((((. .) (. .)) .) (. .))) - (4 5 (. ((. .) (. .))) ((. .) (. (. (. .))))) - (4 5 (. ((. .) (. .))) ((. .) (. ((. .) .)))) - (4 5 (. ((. .) (. .))) ((. .) ((. .) (. .)))) - (4 5 (. ((. .) (. .))) ((. .) ((. (. .)) .))) - (4 5 (. ((. .) (. .))) ((. .) (((. .) .) .))) - (4 5 (. ((. .) (. .))) ((. (. .)) (. (. .)))) - (4 5 (. ((. .) (. .))) ((. (. .)) ((. .) .))) - (4 5 (. ((. .) (. .))) (((. .) .) (. (. .)))) - (4 5 (. ((. .) (. .))) (((. .) .) ((. .) .))) - (4 5 (. ((. .) (. .))) ((. (. (. .))) (. .))) - (4 5 (. ((. .) (. .))) ((. ((. .) .)) (. .))) - (4 5 (. ((. .) (. .))) (((. .) (. .)) (. .))) - (4 5 (. ((. .) (. .))) (((. (. .)) .) (. .))) - (4 5 (. ((. .) (. .))) ((((. .) .) .) (. .))) - (4 5 ((. .) (. (. .))) ((. .) (. (. (. .))))) - (4 5 ((. .) (. (. .))) ((. .) (. ((. .) .)))) - (4 5 ((. .) (. (. .))) ((. .) ((. .) (. .)))) - (4 5 ((. .) (. (. .))) ((. .) ((. (. .)) .))) - (4 5 ((. .) (. (. .))) ((. .) (((. .) .) .))) - (4 5 ((. .) (. (. .))) ((. (. .)) (. (. .)))) - (4 5 ((. .) (. (. .))) ((. (. .)) ((. .) .))) - (4 5 ((. .) (. (. .))) (((. .) .) (. (. .)))) - (4 5 ((. .) (. (. .))) (((. .) .) ((. .) .))) - (4 5 ((. .) (. (. .))) ((. (. (. .))) (. .))) - (4 5 ((. .) (. (. .))) ((. ((. .) .)) (. .))) - (4 5 ((. .) (. (. .))) (((. .) (. .)) (. .))) - (4 5 ((. .) (. (. .))) (((. (. .)) .) (. .))) - (4 5 ((. .) (. (. .))) ((((. .) .) .) (. .))) - (4 5 ((. .) ((. .) .)) ((. .) (. (. (. .))))) - (4 5 ((. .) ((. .) .)) ((. .) (. ((. .) .)))) - (4 5 ((. .) ((. .) .)) ((. .) ((. .) (. .)))) - (4 5 ((. .) ((. .) .)) ((. .) ((. (. .)) .))) - (4 5 ((. .) ((. .) .)) ((. .) (((. .) .) .))) - (4 5 ((. .) ((. .) .)) ((. (. .)) (. (. .)))) - (4 5 ((. .) ((. .) .)) ((. (. .)) ((. .) .))) - (4 5 ((. .) ((. .) .)) (((. .) .) (. (. .)))) - (4 5 ((. .) ((. .) .)) (((. .) .) ((. .) .))) - (4 5 ((. .) ((. .) .)) ((. (. (. .))) (. .))) - (4 5 ((. .) ((. .) .)) ((. ((. .) .)) (. .))) - (4 5 ((. .) ((. .) .)) (((. .) (. .)) (. .))) - (4 5 ((. .) ((. .) .)) (((. (. .)) .) (. .))) - (4 5 ((. .) ((. .) .)) ((((. .) .) .) (. .))) - (4 5 ((. (. .)) (. .)) ((. .) (. (. (. .))))) - (4 5 ((. (. .)) (. .)) ((. .) (. ((. .) .)))) - (4 5 ((. (. .)) (. .)) ((. .) ((. .) (. .)))) - (4 5 ((. (. .)) (. .)) ((. .) ((. (. .)) .))) - (4 5 ((. (. .)) (. .)) ((. .) (((. .) .) .))) - (4 5 ((. (. .)) (. .)) ((. (. .)) (. (. .)))) - (4 5 ((. (. .)) (. .)) ((. (. .)) ((. .) .))) - (4 5 ((. (. .)) (. .)) (((. .) .) (. (. .)))) - (4 5 ((. (. .)) (. .)) (((. .) .) ((. .) .))) - (4 5 ((. (. .)) (. .)) ((. (. (. .))) (. .))) - (4 5 ((. (. .)) (. .)) ((. ((. .) .)) (. .))) - (4 5 ((. (. .)) (. .)) (((. .) (. .)) (. .))) - (4 5 ((. (. .)) (. .)) (((. (. .)) .) (. .))) - (4 5 ((. (. .)) (. .)) ((((. .) .) .) (. .))) - (4 5 (((. .) .) (. .)) ((. .) (. (. (. .))))) - (4 5 (((. .) .) (. .)) ((. .) (. ((. .) .)))) - (4 5 (((. .) .) (. .)) ((. .) ((. .) (. .)))) - (4 5 (((. .) .) (. .)) ((. .) ((. (. .)) .))) - (4 5 (((. .) .) (. .)) ((. .) (((. .) .) .))) - (4 5 (((. .) .) (. .)) ((. (. .)) (. (. .)))) - (4 5 (((. .) .) (. .)) ((. (. .)) ((. .) .))) - (4 5 (((. .) .) (. .)) (((. .) .) (. (. .)))) - (4 5 (((. .) .) (. .)) (((. .) .) ((. .) .))) - (4 5 (((. .) .) (. .)) ((. (. (. .))) (. .))) - (4 5 (((. .) .) (. .)) ((. ((. .) .)) (. .))) - (4 5 (((. .) .) (. .)) (((. .) (. .)) (. .))) - (4 5 (((. .) .) (. .)) (((. (. .)) .) (. .))) - (4 5 (((. .) .) (. .)) ((((. .) .) .) (. .))) - (4 5 (((. .) (. .)) .) ((. .) (. (. (. .))))) - (4 5 (((. .) (. .)) .) ((. .) (. ((. .) .)))) - (4 5 (((. .) (. .)) .) ((. .) ((. .) (. .)))) - (4 5 (((. .) (. .)) .) ((. .) ((. (. .)) .))) - (4 5 (((. .) (. .)) .) ((. .) (((. .) .) .))) - (4 5 (((. .) (. .)) .) ((. (. .)) (. (. .)))) - (4 5 (((. .) (. .)) .) ((. (. .)) ((. .) .))) - (4 5 (((. .) (. .)) .) (((. .) .) (. (. .)))) - (4 5 (((. .) (. .)) .) (((. .) .) ((. .) .))) - (4 5 (((. .) (. .)) .) ((. (. (. .))) (. .))) - (4 5 (((. .) (. .)) .) ((. ((. .) .)) (. .))) - (4 5 (((. .) (. .)) .) (((. .) (. .)) (. .))) - (4 5 (((. .) (. .)) .) (((. (. .)) .) (. .))) - (4 5 (((. .) (. .)) .) ((((. .) .) .) (. .))) - (5 4 ((. .) (. (. (. .)))) (. ((. .) (. .)))) - (5 4 ((. .) (. (. (. .)))) ((. .) (. (. .)))) - (5 4 ((. .) (. (. (. .)))) ((. .) ((. .) .))) - (5 4 ((. .) (. (. (. .)))) ((. (. .)) (. .))) - (5 4 ((. .) (. (. (. .)))) (((. .) .) (. .))) - (5 4 ((. .) (. (. (. .)))) (((. .) (. .)) .)) - (5 4 ((. .) (. ((. .) .))) (. ((. .) (. .)))) - (5 4 ((. .) (. ((. .) .))) ((. .) (. (. .)))) - (5 4 ((. .) (. ((. .) .))) ((. .) ((. .) .))) - (5 4 ((. .) (. ((. .) .))) ((. (. .)) (. .))) - (5 4 ((. .) (. ((. .) .))) (((. .) .) (. .))) - (5 4 ((. .) (. ((. .) .))) (((. .) (. .)) .)) - (5 4 ((. .) ((. .) (. .))) (. ((. .) (. .)))) - (5 4 ((. .) ((. .) (. .))) ((. .) (. (. .)))) - (5 4 ((. .) ((. .) (. .))) ((. .) ((. .) .))) - (5 4 ((. .) ((. .) (. .))) ((. (. .)) (. .))) - (5 4 ((. .) ((. .) (. .))) (((. .) .) (. .))) - (5 4 ((. .) ((. .) (. .))) (((. .) (. .)) .)) - (5 4 ((. .) ((. (. .)) .)) (. ((. .) (. .)))) - (5 4 ((. .) ((. (. .)) .)) ((. .) (. (. .)))) - (5 4 ((. .) ((. (. .)) .)) ((. .) ((. .) .))) - (5 4 ((. .) ((. (. .)) .)) ((. (. .)) (. .))) - (5 4 ((. .) ((. (. .)) .)) (((. .) .) (. .))) - (5 4 ((. .) ((. (. .)) .)) (((. .) (. .)) .)) - (5 4 ((. .) (((. .) .) .)) (. ((. .) (. .)))) - (5 4 ((. .) (((. .) .) .)) ((. .) (. (. .)))) - (5 4 ((. .) (((. .) .) .)) ((. .) ((. .) .))) - (5 4 ((. .) (((. .) .) .)) ((. (. .)) (. .))) - (5 4 ((. .) (((. .) .) .)) (((. .) .) (. .))) - (5 4 ((. .) (((. .) .) .)) (((. .) (. .)) .)) - (5 4 ((. (. .)) (. (. .))) (. ((. .) (. .)))) - (5 4 ((. (. .)) (. (. .))) ((. .) (. (. .)))) - (5 4 ((. (. .)) (. (. .))) ((. .) ((. .) .))) - (5 4 ((. (. .)) (. (. .))) ((. (. .)) (. .))) - (5 4 ((. (. .)) (. (. .))) (((. .) .) (. .))) - (5 4 ((. (. .)) (. (. .))) (((. .) (. .)) .)) - (5 4 ((. (. .)) ((. .) .)) (. ((. .) (. .)))) - (5 4 ((. (. .)) ((. .) .)) ((. .) (. (. .)))) - (5 4 ((. (. .)) ((. .) .)) ((. .) ((. .) .))) - (5 4 ((. (. .)) ((. .) .)) ((. (. .)) (. .))) - (5 4 ((. (. .)) ((. .) .)) (((. .) .) (. .))) - (5 4 ((. (. .)) ((. .) .)) (((. .) (. .)) .)) - (5 4 (((. .) .) (. (. .))) (. ((. .) (. .)))) - (5 4 (((. .) .) (. (. .))) ((. .) (. (. .)))) - (5 4 (((. .) .) (. (. .))) ((. .) ((. .) .))) - (5 4 (((. .) .) (. (. .))) ((. (. .)) (. .))) - (5 4 (((. .) .) (. (. .))) (((. .) .) (. .))) - (5 4 (((. .) .) (. (. .))) (((. .) (. .)) .)) - (5 4 (((. .) .) ((. .) .)) (. ((. .) (. .)))) - (5 4 (((. .) .) ((. .) .)) ((. .) (. (. .)))) - (5 4 (((. .) .) ((. .) .)) ((. .) ((. .) .))) - (5 4 (((. .) .) ((. .) .)) ((. (. .)) (. .))) - (5 4 (((. .) .) ((. .) .)) (((. .) .) (. .))) - (5 4 (((. .) .) ((. .) .)) (((. .) (. .)) .)) - (5 4 ((. (. (. .))) (. .)) (. ((. .) (. .)))) - (5 4 ((. (. (. .))) (. .)) ((. .) (. (. .)))) - (5 4 ((. (. (. .))) (. .)) ((. .) ((. .) .))) - (5 4 ((. (. (. .))) (. .)) ((. (. .)) (. .))) - (5 4 ((. (. (. .))) (. .)) (((. .) .) (. .))) - (5 4 ((. (. (. .))) (. .)) (((. .) (. .)) .)) - (5 4 ((. ((. .) .)) (. .)) (. ((. .) (. .)))) - (5 4 ((. ((. .) .)) (. .)) ((. .) (. (. .)))) - (5 4 ((. ((. .) .)) (. .)) ((. .) ((. .) .))) - (5 4 ((. ((. .) .)) (. .)) ((. (. .)) (. .))) - (5 4 ((. ((. .) .)) (. .)) (((. .) .) (. .))) - (5 4 ((. ((. .) .)) (. .)) (((. .) (. .)) .)) - (5 4 (((. .) (. .)) (. .)) (. ((. .) (. .)))) - (5 4 (((. .) (. .)) (. .)) ((. .) (. (. .)))) - (5 4 (((. .) (. .)) (. .)) ((. .) ((. .) .))) - (5 4 (((. .) (. .)) (. .)) ((. (. .)) (. .))) - (5 4 (((. .) (. .)) (. .)) (((. .) .) (. .))) - (5 4 (((. .) (. .)) (. .)) (((. .) (. .)) .)) - (5 4 (((. (. .)) .) (. .)) (. ((. .) (. .)))) - (5 4 (((. (. .)) .) (. .)) ((. .) (. (. .)))) - (5 4 (((. (. .)) .) (. .)) ((. .) ((. .) .))) - (5 4 (((. (. .)) .) (. .)) ((. (. .)) (. .))) - (5 4 (((. (. .)) .) (. .)) (((. .) .) (. .))) - (5 4 (((. (. .)) .) (. .)) (((. .) (. .)) .)) - (5 4 ((((. .) .) .) (. .)) (. ((. .) (. .)))) - (5 4 ((((. .) .) .) (. .)) ((. .) (. (. .)))) - (5 4 ((((. .) .) .) (. .)) ((. .) ((. .) .))) - (5 4 ((((. .) .) .) (. .)) ((. (. .)) (. .))) - (5 4 ((((. .) .) .) (. .)) (((. .) .) (. .))) - (5 4 ((((. .) .) .) (. .)) (((. .) (. .)) .)) - (6 3 ((. .) (. ((. .) (. .)))) (. (. (. .)))) - (6 3 ((. .) (. ((. .) (. .)))) (. ((. .) .))) - (6 3 ((. .) (. ((. .) (. .)))) ((. .) (. .))) - (6 3 ((. .) (. ((. .) (. .)))) ((. (. .)) .)) - (6 3 ((. .) (. ((. .) (. .)))) (((. .) .) .)) - (6 3 ((. .) ((. .) (. (. .)))) (. (. (. .)))) - (6 3 ((. .) ((. .) (. (. .)))) (. ((. .) .))) - (6 3 ((. .) ((. .) (. (. .)))) ((. .) (. .))) - (6 3 ((. .) ((. .) (. (. .)))) ((. (. .)) .)) - (6 3 ((. .) ((. .) (. (. .)))) (((. .) .) .)) - (6 3 ((. .) ((. .) ((. .) .))) (. (. (. .)))) - (6 3 ((. .) ((. .) ((. .) .))) (. ((. .) .))) - (6 3 ((. .) ((. .) ((. .) .))) ((. .) (. .))) - (6 3 ((. .) ((. .) ((. .) .))) ((. (. .)) .)) - (6 3 ((. .) ((. .) ((. .) .))) (((. .) .) .)) - (6 3 ((. .) ((. (. .)) (. .))) (. (. (. .)))) - (6 3 ((. .) ((. (. .)) (. .))) (. ((. .) .))) - (6 3 ((. .) ((. (. .)) (. .))) ((. .) (. .))) - (6 3 ((. .) ((. (. .)) (. .))) ((. (. .)) .)) - (6 3 ((. .) ((. (. .)) (. .))) (((. .) .) .)) - (6 3 ((. .) (((. .) .) (. .))) (. (. (. .)))) - (6 3 ((. .) (((. .) .) (. .))) (. ((. .) .))) - (6 3 ((. .) (((. .) .) (. .))) ((. .) (. .))) - (6 3 ((. .) (((. .) .) (. .))) ((. (. .)) .)) - (6 3 ((. .) (((. .) .) (. .))) (((. .) .) .)) - (6 3 ((. .) (((. .) (. .)) .)) (. (. (. .)))) - (6 3 ((. .) (((. .) (. .)) .)) (. ((. .) .))) - (6 3 ((. .) (((. .) (. .)) .)) ((. .) (. .))) - (6 3 ((. .) (((. .) (. .)) .)) ((. (. .)) .)) - (6 3 ((. .) (((. .) (. .)) .)) (((. .) .) .)) - (6 3 ((. (. .)) (. (. (. .)))) (. (. (. .)))) - (6 3 ((. (. .)) (. (. (. .)))) (. ((. .) .))) - (6 3 ((. (. .)) (. (. (. .)))) ((. .) (. .))) - (6 3 ((. (. .)) (. (. (. .)))) ((. (. .)) .)) - (6 3 ((. (. .)) (. (. (. .)))) (((. .) .) .)) - (6 3 ((. (. .)) (. ((. .) .))) (. (. (. .)))) - (6 3 ((. (. .)) (. ((. .) .))) (. ((. .) .))) - (6 3 ((. (. .)) (. ((. .) .))) ((. .) (. .))) - (6 3 ((. (. .)) (. ((. .) .))) ((. (. .)) .)) - (6 3 ((. (. .)) (. ((. .) .))) (((. .) .) .)) - (6 3 ((. (. .)) ((. .) (. .))) (. (. (. .)))) - (6 3 ((. (. .)) ((. .) (. .))) (. ((. .) .))) - (6 3 ((. (. .)) ((. .) (. .))) ((. .) (. .))) - (6 3 ((. (. .)) ((. .) (. .))) ((. (. .)) .)) - (6 3 ((. (. .)) ((. .) (. .))) (((. .) .) .)) - (6 3 ((. (. .)) ((. (. .)) .)) (. (. (. .)))) - (6 3 ((. (. .)) ((. (. .)) .)) (. ((. .) .))) - (6 3 ((. (. .)) ((. (. .)) .)) ((. .) (. .))) - (6 3 ((. (. .)) ((. (. .)) .)) ((. (. .)) .)) - (6 3 ((. (. .)) ((. (. .)) .)) (((. .) .) .)) - (6 3 ((. (. .)) (((. .) .) .)) (. (. (. .)))) - (6 3 ((. (. .)) (((. .) .) .)) (. ((. .) .))) - (6 3 ((. (. .)) (((. .) .) .)) ((. .) (. .))) - (6 3 ((. (. .)) (((. .) .) .)) ((. (. .)) .)) - (6 3 ((. (. .)) (((. .) .) .)) (((. .) .) .)) - (6 3 (((. .) .) (. (. (. .)))) (. (. (. .)))) - (6 3 (((. .) .) (. (. (. .)))) (. ((. .) .))) - (6 3 (((. .) .) (. (. (. .)))) ((. .) (. .))) - (6 3 (((. .) .) (. (. (. .)))) ((. (. .)) .)) - (6 3 (((. .) .) (. (. (. .)))) (((. .) .) .)) - (6 3 (((. .) .) (. ((. .) .))) (. (. (. .)))) - (6 3 (((. .) .) (. ((. .) .))) (. ((. .) .))) - (6 3 (((. .) .) (. ((. .) .))) ((. .) (. .))) - (6 3 (((. .) .) (. ((. .) .))) ((. (. .)) .)) - (6 3 (((. .) .) (. ((. .) .))) (((. .) .) .)) - (6 3 (((. .) .) ((. .) (. .))) (. (. (. .)))) - (6 3 (((. .) .) ((. .) (. .))) (. ((. .) .))) - (6 3 (((. .) .) ((. .) (. .))) ((. .) (. .))) - (6 3 (((. .) .) ((. .) (. .))) ((. (. .)) .)) - (6 3 (((. .) .) ((. .) (. .))) (((. .) .) .)) - (6 3 (((. .) .) ((. (. .)) .)) (. (. (. .)))) - (6 3 (((. .) .) ((. (. .)) .)) (. ((. .) .))) - (6 3 (((. .) .) ((. (. .)) .)) ((. .) (. .))) - (6 3 (((. .) .) ((. (. .)) .)) ((. (. .)) .)) - (6 3 (((. .) .) ((. (. .)) .)) (((. .) .) .)) - (6 3 (((. .) .) (((. .) .) .)) (. (. (. .)))) - (6 3 (((. .) .) (((. .) .) .)) (. ((. .) .))) - (6 3 (((. .) .) (((. .) .) .)) ((. .) (. .))) - (6 3 (((. .) .) (((. .) .) .)) ((. (. .)) .)) - (6 3 (((. .) .) (((. .) .) .)) (((. .) .) .)) - (6 3 ((. (. (. .))) (. (. .))) (. (. (. .)))) - (6 3 ((. (. (. .))) (. (. .))) (. ((. .) .))) - (6 3 ((. (. (. .))) (. (. .))) ((. .) (. .))) - (6 3 ((. (. (. .))) (. (. .))) ((. (. .)) .)) - (6 3 ((. (. (. .))) (. (. .))) (((. .) .) .)) - (6 3 ((. (. (. .))) ((. .) .)) (. (. (. .)))) - (6 3 ((. (. (. .))) ((. .) .)) (. ((. .) .))) - (6 3 ((. (. (. .))) ((. .) .)) ((. .) (. .))) - (6 3 ((. (. (. .))) ((. .) .)) ((. (. .)) .)) - (6 3 ((. (. (. .))) ((. .) .)) (((. .) .) .)) - (6 3 ((. ((. .) .)) (. (. .))) (. (. (. .)))) - (6 3 ((. ((. .) .)) (. (. .))) (. ((. .) .))) - (6 3 ((. ((. .) .)) (. (. .))) ((. .) (. .))) - (6 3 ((. ((. .) .)) (. (. .))) ((. (. .)) .)) - (6 3 ((. ((. .) .)) (. (. .))) (((. .) .) .)) - (6 3 ((. ((. .) .)) ((. .) .)) (. (. (. .)))) - (6 3 ((. ((. .) .)) ((. .) .)) (. ((. .) .))) - (6 3 ((. ((. .) .)) ((. .) .)) ((. .) (. .))) - (6 3 ((. ((. .) .)) ((. .) .)) ((. (. .)) .)) - (6 3 ((. ((. .) .)) ((. .) .)) (((. .) .) .)) - (6 3 (((. .) (. .)) (. (. .))) (. (. (. .)))) - (6 3 (((. .) (. .)) (. (. .))) (. ((. .) .))) - (6 3 (((. .) (. .)) (. (. .))) ((. .) (. .))) - (6 3 (((. .) (. .)) (. (. .))) ((. (. .)) .)) - (6 3 (((. .) (. .)) (. (. .))) (((. .) .) .)) - (6 3 (((. .) (. .)) ((. .) .)) (. (. (. .)))) - (6 3 (((. .) (. .)) ((. .) .)) (. ((. .) .))) - (6 3 (((. .) (. .)) ((. .) .)) ((. .) (. .))) - (6 3 (((. .) (. .)) ((. .) .)) ((. (. .)) .)) - (6 3 (((. .) (. .)) ((. .) .)) (((. .) .) .)) - (6 3 (((. (. .)) .) (. (. .))) (. (. (. .)))) - (6 3 (((. (. .)) .) (. (. .))) (. ((. .) .))) - (6 3 (((. (. .)) .) (. (. .))) ((. .) (. .))) - (6 3 (((. (. .)) .) (. (. .))) ((. (. .)) .)) - (6 3 (((. (. .)) .) (. (. .))) (((. .) .) .)) - (6 3 (((. (. .)) .) ((. .) .)) (. (. (. .)))) - (6 3 (((. (. .)) .) ((. .) .)) (. ((. .) .))) - (6 3 (((. (. .)) .) ((. .) .)) ((. .) (. .))) - (6 3 (((. (. .)) .) ((. .) .)) ((. (. .)) .)) - (6 3 (((. (. .)) .) ((. .) .)) (((. .) .) .)) - (6 3 ((((. .) .) .) (. (. .))) (. (. (. .)))) - (6 3 ((((. .) .) .) (. (. .))) (. ((. .) .))) - (6 3 ((((. .) .) .) (. (. .))) ((. .) (. .))) - (6 3 ((((. .) .) .) (. (. .))) ((. (. .)) .)) - (6 3 ((((. .) .) .) (. (. .))) (((. .) .) .)) - (6 3 ((((. .) .) .) ((. .) .)) (. (. (. .)))) - (6 3 ((((. .) .) .) ((. .) .)) (. ((. .) .))) - (6 3 ((((. .) .) .) ((. .) .)) ((. .) (. .))) - (6 3 ((((. .) .) .) ((. .) .)) ((. (. .)) .)) - (6 3 ((((. .) .) .) ((. .) .)) (((. .) .) .)) - (6 3 ((. ((. .) (. .))) (. .)) (. (. (. .)))) - (6 3 ((. ((. .) (. .))) (. .)) (. ((. .) .))) - (6 3 ((. ((. .) (. .))) (. .)) ((. .) (. .))) - (6 3 ((. ((. .) (. .))) (. .)) ((. (. .)) .)) - (6 3 ((. ((. .) (. .))) (. .)) (((. .) .) .)) - (6 3 (((. .) (. (. .))) (. .)) (. (. (. .)))) - (6 3 (((. .) (. (. .))) (. .)) (. ((. .) .))) - (6 3 (((. .) (. (. .))) (. .)) ((. .) (. .))) - (6 3 (((. .) (. (. .))) (. .)) ((. (. .)) .)) - (6 3 (((. .) (. (. .))) (. .)) (((. .) .) .)) - (6 3 (((. .) ((. .) .)) (. .)) (. (. (. .)))) - (6 3 (((. .) ((. .) .)) (. .)) (. ((. .) .))) - (6 3 (((. .) ((. .) .)) (. .)) ((. .) (. .))) - (6 3 (((. .) ((. .) .)) (. .)) ((. (. .)) .)) - (6 3 (((. .) ((. .) .)) (. .)) (((. .) .) .)) - (6 3 (((. (. .)) (. .)) (. .)) (. (. (. .)))) - (6 3 (((. (. .)) (. .)) (. .)) (. ((. .) .))) - (6 3 (((. (. .)) (. .)) (. .)) ((. .) (. .))) - (6 3 (((. (. .)) (. .)) (. .)) ((. (. .)) .)) - (6 3 (((. (. .)) (. .)) (. .)) (((. .) .) .)) - (6 3 ((((. .) .) (. .)) (. .)) (. (. (. .)))) - (6 3 ((((. .) .) (. .)) (. .)) (. ((. .) .))) - (6 3 ((((. .) .) (. .)) (. .)) ((. .) (. .))) - (6 3 ((((. .) .) (. .)) (. .)) ((. (. .)) .)) - (6 3 ((((. .) .) (. .)) (. .)) (((. .) .) .)) - (6 3 ((((. .) (. .)) .) (. .)) (. (. (. .)))) - (6 3 ((((. .) (. .)) .) (. .)) (. ((. .) .))) - (6 3 ((((. .) (. .)) .) (. .)) ((. .) (. .))) - (6 3 ((((. .) (. .)) .) (. .)) ((. (. .)) .)) - (6 3 ((((. .) (. .)) .) (. .)) (((. .) .) .)) - (7 2 ((. .) ((. .) ((. .) (. .)))) (. (. .))) - (7 2 ((. .) ((. .) ((. .) (. .)))) ((. .) .)) - (7 2 ((. .) ((. (. .)) (. (. .)))) (. (. .))) - (7 2 ((. .) ((. (. .)) (. (. .)))) ((. .) .)) - (7 2 ((. .) ((. (. .)) ((. .) .))) (. (. .))) - (7 2 ((. .) ((. (. .)) ((. .) .))) ((. .) .)) - (7 2 ((. .) (((. .) .) (. (. .)))) (. (. .))) - (7 2 ((. .) (((. .) .) (. (. .)))) ((. .) .)) - (7 2 ((. .) (((. .) .) ((. .) .))) (. (. .))) - (7 2 ((. .) (((. .) .) ((. .) .))) ((. .) .)) - (7 2 ((. .) (((. .) (. .)) (. .))) (. (. .))) - (7 2 ((. .) (((. .) (. .)) (. .))) ((. .) .)) - (7 2 ((. (. .)) (. ((. .) (. .)))) (. (. .))) - (7 2 ((. (. .)) (. ((. .) (. .)))) ((. .) .)) - (7 2 ((. (. .)) ((. .) (. (. .)))) (. (. .))) - (7 2 ((. (. .)) ((. .) (. (. .)))) ((. .) .)) - (7 2 ((. (. .)) ((. .) ((. .) .))) (. (. .))) - (7 2 ((. (. .)) ((. .) ((. .) .))) ((. .) .)) - (7 2 ((. (. .)) ((. (. .)) (. .))) (. (. .))) - (7 2 ((. (. .)) ((. (. .)) (. .))) ((. .) .)) - (7 2 ((. (. .)) (((. .) .) (. .))) (. (. .))) - (7 2 ((. (. .)) (((. .) .) (. .))) ((. .) .)) - (7 2 ((. (. .)) (((. .) (. .)) .)) (. (. .))) - (7 2 ((. (. .)) (((. .) (. .)) .)) ((. .) .)) - (7 2 (((. .) .) (. ((. .) (. .)))) (. (. .))) - (7 2 (((. .) .) (. ((. .) (. .)))) ((. .) .)) - (7 2 (((. .) .) ((. .) (. (. .)))) (. (. .))) - (7 2 (((. .) .) ((. .) (. (. .)))) ((. .) .)) - (7 2 (((. .) .) ((. .) ((. .) .))) (. (. .))) - (7 2 (((. .) .) ((. .) ((. .) .))) ((. .) .)) - (7 2 (((. .) .) ((. (. .)) (. .))) (. (. .))) - (7 2 (((. .) .) ((. (. .)) (. .))) ((. .) .)) - (7 2 (((. .) .) (((. .) .) (. .))) (. (. .))) - (7 2 (((. .) .) (((. .) .) (. .))) ((. .) .)) - (7 2 (((. .) .) (((. .) (. .)) .)) (. (. .))) - (7 2 (((. .) .) (((. .) (. .)) .)) ((. .) .)) - (7 2 ((. (. (. .))) (. (. (. .)))) (. (. .))) - (7 2 ((. (. (. .))) (. (. (. .)))) ((. .) .)) - (7 2 ((. (. (. .))) (. ((. .) .))) (. (. .))) - (7 2 ((. (. (. .))) (. ((. .) .))) ((. .) .)) - (7 2 ((. (. (. .))) ((. .) (. .))) (. (. .))) - (7 2 ((. (. (. .))) ((. .) (. .))) ((. .) .)) - (7 2 ((. (. (. .))) ((. (. .)) .)) (. (. .))) - (7 2 ((. (. (. .))) ((. (. .)) .)) ((. .) .)) - (7 2 ((. (. (. .))) (((. .) .) .)) (. (. .))) - (7 2 ((. (. (. .))) (((. .) .) .)) ((. .) .)) - (7 2 ((. ((. .) .)) (. (. (. .)))) (. (. .))) - (7 2 ((. ((. .) .)) (. (. (. .)))) ((. .) .)) - (7 2 ((. ((. .) .)) (. ((. .) .))) (. (. .))) - (7 2 ((. ((. .) .)) (. ((. .) .))) ((. .) .)) - (7 2 ((. ((. .) .)) ((. .) (. .))) (. (. .))) - (7 2 ((. ((. .) .)) ((. .) (. .))) ((. .) .)) - (7 2 ((. ((. .) .)) ((. (. .)) .)) (. (. .))) - (7 2 ((. ((. .) .)) ((. (. .)) .)) ((. .) .)) - (7 2 ((. ((. .) .)) (((. .) .) .)) (. (. .))) - (7 2 ((. ((. .) .)) (((. .) .) .)) ((. .) .)) - (7 2 (((. .) (. .)) (. (. (. .)))) (. (. .))) - (7 2 (((. .) (. .)) (. (. (. .)))) ((. .) .)) - (7 2 (((. .) (. .)) (. ((. .) .))) (. (. .))) - (7 2 (((. .) (. .)) (. ((. .) .))) ((. .) .)) - (7 2 (((. .) (. .)) ((. .) (. .))) (. (. .))) - (7 2 (((. .) (. .)) ((. .) (. .))) ((. .) .)) - (7 2 (((. .) (. .)) ((. (. .)) .)) (. (. .))) - (7 2 (((. .) (. .)) ((. (. .)) .)) ((. .) .)) - (7 2 (((. .) (. .)) (((. .) .) .)) (. (. .))) - (7 2 (((. .) (. .)) (((. .) .) .)) ((. .) .)) - (7 2 (((. (. .)) .) (. (. (. .)))) (. (. .))) - (7 2 (((. (. .)) .) (. (. (. .)))) ((. .) .)) - (7 2 (((. (. .)) .) (. ((. .) .))) (. (. .))) - (7 2 (((. (. .)) .) (. ((. .) .))) ((. .) .)) - (7 2 (((. (. .)) .) ((. .) (. .))) (. (. .))) - (7 2 (((. (. .)) .) ((. .) (. .))) ((. .) .)) - (7 2 (((. (. .)) .) ((. (. .)) .)) (. (. .))) - (7 2 (((. (. .)) .) ((. (. .)) .)) ((. .) .)) - (7 2 (((. (. .)) .) (((. .) .) .)) (. (. .))) - (7 2 (((. (. .)) .) (((. .) .) .)) ((. .) .)) - (7 2 ((((. .) .) .) (. (. (. .)))) (. (. .))) - (7 2 ((((. .) .) .) (. (. (. .)))) ((. .) .)) - (7 2 ((((. .) .) .) (. ((. .) .))) (. (. .))) - (7 2 ((((. .) .) .) (. ((. .) .))) ((. .) .)) - (7 2 ((((. .) .) .) ((. .) (. .))) (. (. .))) - (7 2 ((((. .) .) .) ((. .) (. .))) ((. .) .)) - (7 2 ((((. .) .) .) ((. (. .)) .)) (. (. .))) - (7 2 ((((. .) .) .) ((. (. .)) .)) ((. .) .)) - (7 2 ((((. .) .) .) (((. .) .) .)) (. (. .))) - (7 2 ((((. .) .) .) (((. .) .) .)) ((. .) .)) - (7 2 ((. ((. .) (. .))) (. (. .))) (. (. .))) - (7 2 ((. ((. .) (. .))) (. (. .))) ((. .) .)) - (7 2 ((. ((. .) (. .))) ((. .) .)) (. (. .))) - (7 2 ((. ((. .) (. .))) ((. .) .)) ((. .) .)) - (7 2 (((. .) (. (. .))) (. (. .))) (. (. .))) - (7 2 (((. .) (. (. .))) (. (. .))) ((. .) .)) - (7 2 (((. .) (. (. .))) ((. .) .)) (. (. .))) - (7 2 (((. .) (. (. .))) ((. .) .)) ((. .) .)) - (7 2 (((. .) ((. .) .)) (. (. .))) (. (. .))) - (7 2 (((. .) ((. .) .)) (. (. .))) ((. .) .)) - (7 2 (((. .) ((. .) .)) ((. .) .)) (. (. .))) - (7 2 (((. .) ((. .) .)) ((. .) .)) ((. .) .)) - (7 2 (((. (. .)) (. .)) (. (. .))) (. (. .))) - (7 2 (((. (. .)) (. .)) (. (. .))) ((. .) .)) - (7 2 (((. (. .)) (. .)) ((. .) .)) (. (. .))) - (7 2 (((. (. .)) (. .)) ((. .) .)) ((. .) .)) - (7 2 ((((. .) .) (. .)) (. (. .))) (. (. .))) - (7 2 ((((. .) .) (. .)) (. (. .))) ((. .) .)) - (7 2 ((((. .) .) (. .)) ((. .) .)) (. (. .))) - (7 2 ((((. .) .) (. .)) ((. .) .)) ((. .) .)) - (7 2 ((((. .) (. .)) .) (. (. .))) (. (. .))) - (7 2 ((((. .) (. .)) .) (. (. .))) ((. .) .)) - (7 2 ((((. .) (. .)) .) ((. .) .)) (. (. .))) - (7 2 ((((. .) (. .)) .) ((. .) .)) ((. .) .)) - (7 2 (((. .) ((. .) (. .))) (. .)) (. (. .))) - (7 2 (((. .) ((. .) (. .))) (. .)) ((. .) .)) - (7 2 (((. (. .)) (. (. .))) (. .)) (. (. .))) - (7 2 (((. (. .)) (. (. .))) (. .)) ((. .) .)) - (7 2 (((. (. .)) ((. .) .)) (. .)) (. (. .))) - (7 2 (((. (. .)) ((. .) .)) (. .)) ((. .) .)) - (7 2 ((((. .) .) (. (. .))) (. .)) (. (. .))) - (7 2 ((((. .) .) (. (. .))) (. .)) ((. .) .)) - (7 2 ((((. .) .) ((. .) .)) (. .)) (. (. .))) - (7 2 ((((. .) .) ((. .) .)) (. .)) ((. .) .)) - (7 2 ((((. .) (. .)) (. .)) (. .)) (. (. .))) - (7 2 ((((. .) (. .)) (. .)) (. .)) ((. .) .)) - ((shown 1_274) (total 1_977_836)) + ((1 1) (. .) (. .)) + ((1 2) (. .) (. (. .))) + ((1 2) (. .) ((. .) .)) + ((2 1) (. (. .)) (. .)) + ((2 1) ((. .) .) (. .)) + ((1 3) (. .) ((. .) (. .))) + ((2 2) (. (. .)) (. (. .))) + ((2 2) (. (. .)) ((. .) .)) + ((2 2) ((. .) .) (. (. .))) + ((2 2) ((. .) .) ((. .) .)) + ((3 1) ((. .) (. .)) (. .)) + ((1 4) (. .) ((. .) (. (. .)))) + ((1 4) (. .) ((. .) ((. .) .))) + ((1 4) (. .) ((. (. .)) (. .))) + ((1 4) (. .) (((. .) .) (. .))) + ((2 3) (. (. .)) ((. .) (. .))) + ((2 3) ((. .) .) ((. .) (. .))) + ((3 2) ((. .) (. .)) (. (. .))) + ((3 2) ((. .) (. .)) ((. .) .)) + ((4 1) ((. .) (. (. .))) (. .)) + ((4 1) ((. .) ((. .) .)) (. .)) + ((4 1) ((. (. .)) (. .)) (. .)) + ((4 1) (((. .) .) (. .)) (. .)) + ((2 4) (. (. .)) ((. .) (. (. .)))) + ((2 4) (. (. .)) ((. .) ((. .) .))) + ((2 4) (. (. .)) ((. (. .)) (. .))) + ((2 4) (. (. .)) (((. .) .) (. .))) + ((2 4) ((. .) .) ((. .) (. (. .)))) + ((2 4) ((. .) .) ((. .) ((. .) .))) + ((2 4) ((. .) .) ((. (. .)) (. .))) + ((2 4) ((. .) .) (((. .) .) (. .))) + ((3 3) ((. .) (. .)) ((. .) (. .))) + ((4 2) ((. .) (. (. .))) (. (. .))) + ((4 2) ((. .) (. (. .))) ((. .) .)) + ((4 2) ((. .) ((. .) .)) (. (. .))) + ((4 2) ((. .) ((. .) .)) ((. .) .)) + ((4 2) ((. (. .)) (. .)) (. (. .))) + ((4 2) ((. (. .)) (. .)) ((. .) .)) + ((4 2) (((. .) .) (. .)) (. (. .))) + ((4 2) (((. .) .) (. .)) ((. .) .)) + ((2 5) (. (. .)) ((. .) ((. .) (. .)))) + ((2 5) (. (. .)) ((. (. .)) (. (. .)))) + ((2 5) (. (. .)) ((. (. .)) ((. .) .))) + ((2 5) (. (. .)) (((. .) .) (. (. .)))) + ((2 5) (. (. .)) (((. .) .) ((. .) .))) + ((2 5) (. (. .)) (((. .) (. .)) (. .))) + ((2 5) ((. .) .) ((. .) ((. .) (. .)))) + ((2 5) ((. .) .) ((. (. .)) (. (. .)))) + ((2 5) ((. .) .) ((. (. .)) ((. .) .))) + ((2 5) ((. .) .) (((. .) .) (. (. .)))) + ((2 5) ((. .) .) (((. .) .) ((. .) .))) + ((2 5) ((. .) .) (((. .) (. .)) (. .))) + ((3 4) ((. .) (. .)) ((. .) (. (. .)))) + ((3 4) ((. .) (. .)) ((. .) ((. .) .))) + ((3 4) ((. .) (. .)) ((. (. .)) (. .))) + ((3 4) ((. .) (. .)) (((. .) .) (. .))) + ((4 3) ((. .) (. (. .))) ((. .) (. .))) + ((4 3) ((. .) ((. .) .)) ((. .) (. .))) + ((4 3) ((. (. .)) (. .)) ((. .) (. .))) + ((4 3) (((. .) .) (. .)) ((. .) (. .))) + ((5 2) ((. .) ((. .) (. .))) (. (. .))) + ((5 2) ((. .) ((. .) (. .))) ((. .) .)) + ((5 2) ((. (. .)) (. (. .))) (. (. .))) + ((5 2) ((. (. .)) (. (. .))) ((. .) .)) + ((5 2) ((. (. .)) ((. .) .)) (. (. .))) + ((5 2) ((. (. .)) ((. .) .)) ((. .) .)) + ((5 2) (((. .) .) (. (. .))) (. (. .))) + ((5 2) (((. .) .) (. (. .))) ((. .) .)) + ((5 2) (((. .) .) ((. .) .)) (. (. .))) + ((5 2) (((. .) .) ((. .) .)) ((. .) .)) + ((5 2) (((. .) (. .)) (. .)) (. (. .))) + ((5 2) (((. .) (. .)) (. .)) ((. .) .)) + ((2 6) (. (. .)) ((. .) ((. .) (. (. .))))) + ((2 6) (. (. .)) ((. .) ((. .) ((. .) .)))) + ((2 6) (. (. .)) ((. .) ((. (. .)) (. .)))) + ((2 6) (. (. .)) ((. .) (((. .) .) (. .)))) + ((2 6) (. (. .)) ((. (. .)) ((. .) (. .)))) + ((2 6) (. (. .)) (((. .) .) ((. .) (. .)))) + ((2 6) (. (. .)) (((. .) (. .)) (. (. .)))) + ((2 6) (. (. .)) (((. .) (. .)) ((. .) .))) + ((2 6) (. (. .)) (((. .) (. (. .))) (. .))) + ((2 6) (. (. .)) (((. .) ((. .) .)) (. .))) + ((2 6) (. (. .)) (((. (. .)) (. .)) (. .))) + ((2 6) (. (. .)) ((((. .) .) (. .)) (. .))) + ((2 6) ((. .) .) ((. .) ((. .) (. (. .))))) + ((2 6) ((. .) .) ((. .) ((. .) ((. .) .)))) + ((2 6) ((. .) .) ((. .) ((. (. .)) (. .)))) + ((2 6) ((. .) .) ((. .) (((. .) .) (. .)))) + ((2 6) ((. .) .) ((. (. .)) ((. .) (. .)))) + ((2 6) ((. .) .) (((. .) .) ((. .) (. .)))) + ((2 6) ((. .) .) (((. .) (. .)) (. (. .)))) + ((2 6) ((. .) .) (((. .) (. .)) ((. .) .))) + ((2 6) ((. .) .) (((. .) (. (. .))) (. .))) + ((2 6) ((. .) .) (((. .) ((. .) .)) (. .))) + ((2 6) ((. .) .) (((. (. .)) (. .)) (. .))) + ((2 6) ((. .) .) ((((. .) .) (. .)) (. .))) + ((3 5) ((. .) (. .)) ((. .) ((. .) (. .)))) + ((3 5) ((. .) (. .)) ((. (. .)) (. (. .)))) + ((3 5) ((. .) (. .)) ((. (. .)) ((. .) .))) + ((3 5) ((. .) (. .)) (((. .) .) (. (. .)))) + ((3 5) ((. .) (. .)) (((. .) .) ((. .) .))) + ((3 5) ((. .) (. .)) (((. .) (. .)) (. .))) + ((4 4) ((. .) (. (. .))) ((. .) (. (. .)))) + ((4 4) ((. .) (. (. .))) ((. .) ((. .) .))) + ((4 4) ((. .) (. (. .))) ((. (. .)) (. .))) + ((4 4) ((. .) (. (. .))) (((. .) .) (. .))) + ((4 4) ((. .) ((. .) .)) ((. .) (. (. .)))) + ((4 4) ((. .) ((. .) .)) ((. .) ((. .) .))) + ((4 4) ((. .) ((. .) .)) ((. (. .)) (. .))) + ((4 4) ((. .) ((. .) .)) (((. .) .) (. .))) + ((4 4) ((. (. .)) (. .)) ((. .) (. (. .)))) + ((4 4) ((. (. .)) (. .)) ((. .) ((. .) .))) + ((4 4) ((. (. .)) (. .)) ((. (. .)) (. .))) + ((4 4) ((. (. .)) (. .)) (((. .) .) (. .))) + ((4 4) (((. .) .) (. .)) ((. .) (. (. .)))) + ((4 4) (((. .) .) (. .)) ((. .) ((. .) .))) + ((4 4) (((. .) .) (. .)) ((. (. .)) (. .))) + ((4 4) (((. .) .) (. .)) (((. .) .) (. .))) + ((5 3) ((. .) ((. .) (. .))) ((. .) (. .))) + ((5 3) ((. (. .)) (. (. .))) ((. .) (. .))) + ((5 3) ((. (. .)) ((. .) .)) ((. .) (. .))) + ((5 3) (((. .) .) (. (. .))) ((. .) (. .))) + ((5 3) (((. .) .) ((. .) .)) ((. .) (. .))) + ((5 3) (((. .) (. .)) (. .)) ((. .) (. .))) + ((6 2) ((. .) ((. .) (. (. .)))) (. (. .))) + ((6 2) ((. .) ((. .) (. (. .)))) ((. .) .)) + ((6 2) ((. .) ((. .) ((. .) .))) (. (. .))) + ((6 2) ((. .) ((. .) ((. .) .))) ((. .) .)) + ((6 2) ((. .) ((. (. .)) (. .))) (. (. .))) + ((6 2) ((. .) ((. (. .)) (. .))) ((. .) .)) + ((6 2) ((. .) (((. .) .) (. .))) (. (. .))) + ((6 2) ((. .) (((. .) .) (. .))) ((. .) .)) + ((6 2) ((. (. .)) ((. .) (. .))) (. (. .))) + ((6 2) ((. (. .)) ((. .) (. .))) ((. .) .)) + ((6 2) (((. .) .) ((. .) (. .))) (. (. .))) + ((6 2) (((. .) .) ((. .) (. .))) ((. .) .)) + ((6 2) (((. .) (. .)) (. (. .))) (. (. .))) + ((6 2) (((. .) (. .)) (. (. .))) ((. .) .)) + ((6 2) (((. .) (. .)) ((. .) .)) (. (. .))) + ((6 2) (((. .) (. .)) ((. .) .)) ((. .) .)) + ((6 2) (((. .) (. (. .))) (. .)) (. (. .))) + ((6 2) (((. .) (. (. .))) (. .)) ((. .) .)) + ((6 2) (((. .) ((. .) .)) (. .)) (. (. .))) + ((6 2) (((. .) ((. .) .)) (. .)) ((. .) .)) + ((6 2) (((. (. .)) (. .)) (. .)) (. (. .))) + ((6 2) (((. (. .)) (. .)) (. .)) ((. .) .)) + ((6 2) ((((. .) .) (. .)) (. .)) (. (. .))) + ((6 2) ((((. .) .) (. .)) (. .)) ((. .) .)) + ((3 6) ((. .) (. .)) ((. .) ((. .) (. (. .))))) + ((3 6) ((. .) (. .)) ((. .) ((. .) ((. .) .)))) + ((3 6) ((. .) (. .)) ((. .) ((. (. .)) (. .)))) + ((3 6) ((. .) (. .)) ((. .) (((. .) .) (. .)))) + ((3 6) ((. .) (. .)) ((. (. .)) ((. .) (. .)))) + ((3 6) ((. .) (. .)) (((. .) .) ((. .) (. .)))) + ((3 6) ((. .) (. .)) (((. .) (. .)) (. (. .)))) + ((3 6) ((. .) (. .)) (((. .) (. .)) ((. .) .))) + ((3 6) ((. .) (. .)) (((. .) (. (. .))) (. .))) + ((3 6) ((. .) (. .)) (((. .) ((. .) .)) (. .))) + ((3 6) ((. .) (. .)) (((. (. .)) (. .)) (. .))) + ((3 6) ((. .) (. .)) ((((. .) .) (. .)) (. .))) + ((4 5) ((. .) (. (. .))) ((. .) ((. .) (. .)))) + ((4 5) ((. .) (. (. .))) ((. (. .)) (. (. .)))) + ((4 5) ((. .) (. (. .))) ((. (. .)) ((. .) .))) + ((4 5) ((. .) (. (. .))) (((. .) .) (. (. .)))) + ((4 5) ((. .) (. (. .))) (((. .) .) ((. .) .))) + ((4 5) ((. .) (. (. .))) (((. .) (. .)) (. .))) + ((4 5) ((. .) ((. .) .)) ((. .) ((. .) (. .)))) + ((4 5) ((. .) ((. .) .)) ((. (. .)) (. (. .)))) + ((4 5) ((. .) ((. .) .)) ((. (. .)) ((. .) .))) + ((4 5) ((. .) ((. .) .)) (((. .) .) (. (. .)))) + ((4 5) ((. .) ((. .) .)) (((. .) .) ((. .) .))) + ((4 5) ((. .) ((. .) .)) (((. .) (. .)) (. .))) + ((4 5) ((. (. .)) (. .)) ((. .) ((. .) (. .)))) + ((4 5) ((. (. .)) (. .)) ((. (. .)) (. (. .)))) + ((4 5) ((. (. .)) (. .)) ((. (. .)) ((. .) .))) + ((4 5) ((. (. .)) (. .)) (((. .) .) (. (. .)))) + ((4 5) ((. (. .)) (. .)) (((. .) .) ((. .) .))) + ((4 5) ((. (. .)) (. .)) (((. .) (. .)) (. .))) + ((4 5) (((. .) .) (. .)) ((. .) ((. .) (. .)))) + ((4 5) (((. .) .) (. .)) ((. (. .)) (. (. .)))) + ((4 5) (((. .) .) (. .)) ((. (. .)) ((. .) .))) + ((4 5) (((. .) .) (. .)) (((. .) .) (. (. .)))) + ((4 5) (((. .) .) (. .)) (((. .) .) ((. .) .))) + ((4 5) (((. .) .) (. .)) (((. .) (. .)) (. .))) + ((5 4) ((. .) ((. .) (. .))) ((. .) (. (. .)))) + ((5 4) ((. .) ((. .) (. .))) ((. .) ((. .) .))) + ((5 4) ((. .) ((. .) (. .))) ((. (. .)) (. .))) + ((5 4) ((. .) ((. .) (. .))) (((. .) .) (. .))) + ((5 4) ((. (. .)) (. (. .))) ((. .) (. (. .)))) + ((5 4) ((. (. .)) (. (. .))) ((. .) ((. .) .))) + ((5 4) ((. (. .)) (. (. .))) ((. (. .)) (. .))) + ((5 4) ((. (. .)) (. (. .))) (((. .) .) (. .))) + ((5 4) ((. (. .)) ((. .) .)) ((. .) (. (. .)))) + ((5 4) ((. (. .)) ((. .) .)) ((. .) ((. .) .))) + ((5 4) ((. (. .)) ((. .) .)) ((. (. .)) (. .))) + ((5 4) ((. (. .)) ((. .) .)) (((. .) .) (. .))) + ((5 4) (((. .) .) (. (. .))) ((. .) (. (. .)))) + ((5 4) (((. .) .) (. (. .))) ((. .) ((. .) .))) + ((5 4) (((. .) .) (. (. .))) ((. (. .)) (. .))) + ((5 4) (((. .) .) (. (. .))) (((. .) .) (. .))) + ((5 4) (((. .) .) ((. .) .)) ((. .) (. (. .)))) + ((5 4) (((. .) .) ((. .) .)) ((. .) ((. .) .))) + ((5 4) (((. .) .) ((. .) .)) ((. (. .)) (. .))) + ((5 4) (((. .) .) ((. .) .)) (((. .) .) (. .))) + ((5 4) (((. .) (. .)) (. .)) ((. .) (. (. .)))) + ((5 4) (((. .) (. .)) (. .)) ((. .) ((. .) .))) + ((5 4) (((. .) (. .)) (. .)) ((. (. .)) (. .))) + ((5 4) (((. .) (. .)) (. .)) (((. .) .) (. .))) + ((6 3) ((. .) ((. .) (. (. .)))) ((. .) (. .))) + ((6 3) ((. .) ((. .) ((. .) .))) ((. .) (. .))) + ((6 3) ((. .) ((. (. .)) (. .))) ((. .) (. .))) + ((6 3) ((. .) (((. .) .) (. .))) ((. .) (. .))) + ((6 3) ((. (. .)) ((. .) (. .))) ((. .) (. .))) + ((6 3) (((. .) .) ((. .) (. .))) ((. .) (. .))) + ((6 3) (((. .) (. .)) (. (. .))) ((. .) (. .))) + ((6 3) (((. .) (. .)) ((. .) .)) ((. .) (. .))) + ((6 3) (((. .) (. (. .))) (. .)) ((. .) (. .))) + ((6 3) (((. .) ((. .) .)) (. .)) ((. .) (. .))) + ((6 3) (((. (. .)) (. .)) (. .)) ((. .) (. .))) + ((6 3) ((((. .) .) (. .)) (. .)) ((. .) (. .))) + ((shown 220) (total 3_276_340)) |}] ;; @@ -1471,383 +417,53 @@ let test (module Tree : S) = ~have_been_shown:are_balanced; [%expect {| - (1 5 (. .) ((. .) (. (. (. .))))) - (1 5 (. .) ((. .) (. ((. .) .)))) - (1 5 (. .) ((. .) ((. (. .)) .))) - (1 5 (. .) ((. .) (((. .) .) .))) - (1 5 (. .) ((. (. (. .))) (. .))) - (1 5 (. .) ((. ((. .) .)) (. .))) - (1 5 (. .) (((. (. .)) .) (. .))) - (1 5 (. .) ((((. .) .) .) (. .))) - (5 1 ((. .) (. (. (. .)))) (. .)) - (5 1 ((. .) (. ((. .) .))) (. .)) - (5 1 ((. .) ((. (. .)) .)) (. .)) - (5 1 ((. .) (((. .) .) .)) (. .)) - (5 1 ((. (. (. .))) (. .)) (. .)) - (5 1 ((. ((. .) .)) (. .)) (. .)) - (5 1 (((. (. .)) .) (. .)) (. .)) - (5 1 ((((. .) .) .) (. .)) (. .)) - (1 6 (. .) ((. .) (. ((. .) (. .))))) - (1 6 (. .) ((. .) ((. .) (. (. .))))) - (1 6 (. .) ((. .) ((. .) ((. .) .)))) - (1 6 (. .) ((. .) ((. (. .)) (. .)))) - (1 6 (. .) ((. .) (((. .) .) (. .)))) - (1 6 (. .) ((. .) (((. .) (. .)) .))) - (1 6 (. .) ((. (. .)) (. (. (. .))))) - (1 6 (. .) ((. (. .)) (. ((. .) .)))) - (1 6 (. .) ((. (. .)) ((. (. .)) .))) - (1 6 (. .) ((. (. .)) (((. .) .) .))) - (1 6 (. .) (((. .) .) (. (. (. .))))) - (1 6 (. .) (((. .) .) (. ((. .) .)))) - (1 6 (. .) (((. .) .) ((. (. .)) .))) - (1 6 (. .) (((. .) .) (((. .) .) .))) - (1 6 (. .) ((. (. (. .))) (. (. .)))) - (1 6 (. .) ((. (. (. .))) ((. .) .))) - (1 6 (. .) ((. ((. .) .)) (. (. .)))) - (1 6 (. .) ((. ((. .) .)) ((. .) .))) - (1 6 (. .) (((. (. .)) .) (. (. .)))) - (1 6 (. .) (((. (. .)) .) ((. .) .))) - (1 6 (. .) ((((. .) .) .) (. (. .)))) - (1 6 (. .) ((((. .) .) .) ((. .) .))) - (1 6 (. .) ((. ((. .) (. .))) (. .))) - (1 6 (. .) (((. .) (. (. .))) (. .))) - (1 6 (. .) (((. .) ((. .) .)) (. .))) - (1 6 (. .) (((. (. .)) (. .)) (. .))) - (1 6 (. .) ((((. .) .) (. .)) (. .))) - (1 6 (. .) ((((. .) (. .)) .) (. .))) - (6 1 ((. .) (. ((. .) (. .)))) (. .)) - (6 1 ((. .) ((. .) (. (. .)))) (. .)) - (6 1 ((. .) ((. .) ((. .) .))) (. .)) - (6 1 ((. .) ((. (. .)) (. .))) (. .)) - (6 1 ((. .) (((. .) .) (. .))) (. .)) - (6 1 ((. .) (((. .) (. .)) .)) (. .)) - (6 1 ((. (. .)) (. (. (. .)))) (. .)) - (6 1 ((. (. .)) (. ((. .) .))) (. .)) - (6 1 ((. (. .)) ((. (. .)) .)) (. .)) - (6 1 ((. (. .)) (((. .) .) .)) (. .)) - (6 1 (((. .) .) (. (. (. .)))) (. .)) - (6 1 (((. .) .) (. ((. .) .))) (. .)) - (6 1 (((. .) .) ((. (. .)) .)) (. .)) - (6 1 (((. .) .) (((. .) .) .)) (. .)) - (6 1 ((. (. (. .))) (. (. .))) (. .)) - (6 1 ((. (. (. .))) ((. .) .)) (. .)) - (6 1 ((. ((. .) .)) (. (. .))) (. .)) - (6 1 ((. ((. .) .)) ((. .) .)) (. .)) - (6 1 (((. (. .)) .) (. (. .))) (. .)) - (6 1 (((. (. .)) .) ((. .) .)) (. .)) - (6 1 ((((. .) .) .) (. (. .))) (. .)) - (6 1 ((((. .) .) .) ((. .) .)) (. .)) - (6 1 ((. ((. .) (. .))) (. .)) (. .)) - (6 1 (((. .) (. (. .))) (. .)) (. .)) - (6 1 (((. .) ((. .) .)) (. .)) (. .)) - (6 1 (((. (. .)) (. .)) (. .)) (. .)) - (6 1 ((((. .) .) (. .)) (. .)) (. .)) - (6 1 ((((. .) (. .)) .) (. .)) (. .)) - (1 7 (. .) ((. .) ((. .) ((. .) (. .))))) - (1 7 (. .) ((. .) ((. (. .)) (. (. .))))) - (1 7 (. .) ((. .) ((. (. .)) ((. .) .)))) - (1 7 (. .) ((. .) (((. .) .) (. (. .))))) - (1 7 (. .) ((. .) (((. .) .) ((. .) .)))) - (1 7 (. .) ((. .) (((. .) (. .)) (. .)))) - (1 7 (. .) ((. (. .)) (. ((. .) (. .))))) - (1 7 (. .) ((. (. .)) ((. .) (. (. .))))) - (1 7 (. .) ((. (. .)) ((. .) ((. .) .)))) - (1 7 (. .) ((. (. .)) ((. (. .)) (. .)))) - (1 7 (. .) ((. (. .)) (((. .) .) (. .)))) - (1 7 (. .) ((. (. .)) (((. .) (. .)) .))) - (1 7 (. .) (((. .) .) (. ((. .) (. .))))) - (1 7 (. .) (((. .) .) ((. .) (. (. .))))) - (1 7 (. .) (((. .) .) ((. .) ((. .) .)))) - (1 7 (. .) (((. .) .) ((. (. .)) (. .)))) - (1 7 (. .) (((. .) .) (((. .) .) (. .)))) - (1 7 (. .) (((. .) .) (((. .) (. .)) .))) - (1 7 (. .) ((. (. (. .))) (. (. (. .))))) - (1 7 (. .) ((. (. (. .))) (. ((. .) .)))) - (1 7 (. .) ((. (. (. .))) ((. .) (. .)))) - (1 7 (. .) ((. (. (. .))) ((. (. .)) .))) - (1 7 (. .) ((. (. (. .))) (((. .) .) .))) - (1 7 (. .) ((. ((. .) .)) (. (. (. .))))) - (1 7 (. .) ((. ((. .) .)) (. ((. .) .)))) - (1 7 (. .) ((. ((. .) .)) ((. .) (. .)))) - (1 7 (. .) ((. ((. .) .)) ((. (. .)) .))) - (1 7 (. .) ((. ((. .) .)) (((. .) .) .))) - (1 7 (. .) (((. .) (. .)) (. (. (. .))))) - (1 7 (. .) (((. .) (. .)) (. ((. .) .)))) - (1 7 (. .) (((. .) (. .)) ((. (. .)) .))) - (1 7 (. .) (((. .) (. .)) (((. .) .) .))) - (1 7 (. .) (((. (. .)) .) (. (. (. .))))) - (1 7 (. .) (((. (. .)) .) (. ((. .) .)))) - (1 7 (. .) (((. (. .)) .) ((. .) (. .)))) - (1 7 (. .) (((. (. .)) .) ((. (. .)) .))) - (1 7 (. .) (((. (. .)) .) (((. .) .) .))) - (1 7 (. .) ((((. .) .) .) (. (. (. .))))) - (1 7 (. .) ((((. .) .) .) (. ((. .) .)))) - (1 7 (. .) ((((. .) .) .) ((. .) (. .)))) - (1 7 (. .) ((((. .) .) .) ((. (. .)) .))) - (1 7 (. .) ((((. .) .) .) (((. .) .) .))) - (1 7 (. .) ((. ((. .) (. .))) (. (. .)))) - (1 7 (. .) ((. ((. .) (. .))) ((. .) .))) - (1 7 (. .) (((. .) (. (. .))) (. (. .)))) - (1 7 (. .) (((. .) (. (. .))) ((. .) .))) - (1 7 (. .) (((. .) ((. .) .)) (. (. .)))) - (1 7 (. .) (((. .) ((. .) .)) ((. .) .))) - (1 7 (. .) (((. (. .)) (. .)) (. (. .)))) - (1 7 (. .) (((. (. .)) (. .)) ((. .) .))) - (1 7 (. .) ((((. .) .) (. .)) (. (. .)))) - (1 7 (. .) ((((. .) .) (. .)) ((. .) .))) - (1 7 (. .) ((((. .) (. .)) .) (. (. .)))) - (1 7 (. .) ((((. .) (. .)) .) ((. .) .))) - (1 7 (. .) (((. .) ((. .) (. .))) (. .))) - (1 7 (. .) (((. (. .)) (. (. .))) (. .))) - (1 7 (. .) (((. (. .)) ((. .) .)) (. .))) - (1 7 (. .) ((((. .) .) (. (. .))) (. .))) - (1 7 (. .) ((((. .) .) ((. .) .)) (. .))) - (1 7 (. .) ((((. .) (. .)) (. .)) (. .))) - (7 1 ((. .) ((. .) ((. .) (. .)))) (. .)) - (7 1 ((. .) ((. (. .)) (. (. .)))) (. .)) - (7 1 ((. .) ((. (. .)) ((. .) .))) (. .)) - (7 1 ((. .) (((. .) .) (. (. .)))) (. .)) - (7 1 ((. .) (((. .) .) ((. .) .))) (. .)) - (7 1 ((. .) (((. .) (. .)) (. .))) (. .)) - (7 1 ((. (. .)) (. ((. .) (. .)))) (. .)) - (7 1 ((. (. .)) ((. .) (. (. .)))) (. .)) - (7 1 ((. (. .)) ((. .) ((. .) .))) (. .)) - (7 1 ((. (. .)) ((. (. .)) (. .))) (. .)) - (7 1 ((. (. .)) (((. .) .) (. .))) (. .)) - (7 1 ((. (. .)) (((. .) (. .)) .)) (. .)) - (7 1 (((. .) .) (. ((. .) (. .)))) (. .)) - (7 1 (((. .) .) ((. .) (. (. .)))) (. .)) - (7 1 (((. .) .) ((. .) ((. .) .))) (. .)) - (7 1 (((. .) .) ((. (. .)) (. .))) (. .)) - (7 1 (((. .) .) (((. .) .) (. .))) (. .)) - (7 1 (((. .) .) (((. .) (. .)) .)) (. .)) - (7 1 ((. (. (. .))) (. (. (. .)))) (. .)) - (7 1 ((. (. (. .))) (. ((. .) .))) (. .)) - (7 1 ((. (. (. .))) ((. .) (. .))) (. .)) - (7 1 ((. (. (. .))) ((. (. .)) .)) (. .)) - (7 1 ((. (. (. .))) (((. .) .) .)) (. .)) - (7 1 ((. ((. .) .)) (. (. (. .)))) (. .)) - (7 1 ((. ((. .) .)) (. ((. .) .))) (. .)) - (7 1 ((. ((. .) .)) ((. .) (. .))) (. .)) - (7 1 ((. ((. .) .)) ((. (. .)) .)) (. .)) - (7 1 ((. ((. .) .)) (((. .) .) .)) (. .)) - (7 1 (((. .) (. .)) (. (. (. .)))) (. .)) - (7 1 (((. .) (. .)) (. ((. .) .))) (. .)) - (7 1 (((. .) (. .)) ((. (. .)) .)) (. .)) - (7 1 (((. .) (. .)) (((. .) .) .)) (. .)) - (7 1 (((. (. .)) .) (. (. (. .)))) (. .)) - (7 1 (((. (. .)) .) (. ((. .) .))) (. .)) - (7 1 (((. (. .)) .) ((. .) (. .))) (. .)) - (7 1 (((. (. .)) .) ((. (. .)) .)) (. .)) - (7 1 (((. (. .)) .) (((. .) .) .)) (. .)) - (7 1 ((((. .) .) .) (. (. (. .)))) (. .)) - (7 1 ((((. .) .) .) (. ((. .) .))) (. .)) - (7 1 ((((. .) .) .) ((. .) (. .))) (. .)) - (7 1 ((((. .) .) .) ((. (. .)) .)) (. .)) - (7 1 ((((. .) .) .) (((. .) .) .)) (. .)) - (7 1 ((. ((. .) (. .))) (. (. .))) (. .)) - (7 1 ((. ((. .) (. .))) ((. .) .)) (. .)) - (7 1 (((. .) (. (. .))) (. (. .))) (. .)) - (7 1 (((. .) (. (. .))) ((. .) .)) (. .)) - (7 1 (((. .) ((. .) .)) (. (. .))) (. .)) - (7 1 (((. .) ((. .) .)) ((. .) .)) (. .)) - (7 1 (((. (. .)) (. .)) (. (. .))) (. .)) - (7 1 (((. (. .)) (. .)) ((. .) .)) (. .)) - (7 1 ((((. .) .) (. .)) (. (. .))) (. .)) - (7 1 ((((. .) .) (. .)) ((. .) .)) (. .)) - (7 1 ((((. .) (. .)) .) (. (. .))) (. .)) - (7 1 ((((. .) (. .)) .) ((. .) .)) (. .)) - (7 1 (((. .) ((. .) (. .))) (. .)) (. .)) - (7 1 (((. (. .)) (. (. .))) (. .)) (. .)) - (7 1 (((. (. .)) ((. .) .)) (. .)) (. .)) - (7 1 ((((. .) .) (. (. .))) (. .)) (. .)) - (7 1 ((((. .) .) ((. .) .)) (. .)) (. .)) - (7 1 ((((. .) (. .)) (. .)) (. .)) (. .)) - (1 8 (. .) ((. .) ((. (. .)) ((. .) (. .))))) - (1 8 (. .) ((. .) (((. .) .) ((. .) (. .))))) - (1 8 (. .) ((. .) (((. .) (. .)) (. (. .))))) - (1 8 (. .) ((. .) (((. .) (. .)) ((. .) .)))) - (1 8 (. .) ((. (. .)) ((. .) ((. .) (. .))))) - (1 8 (. .) ((. (. .)) ((. (. .)) (. (. .))))) - (1 8 (. .) ((. (. .)) ((. (. .)) ((. .) .)))) - (1 8 (. .) ((. (. .)) (((. .) .) (. (. .))))) - (1 8 (. .) ((. (. .)) (((. .) .) ((. .) .)))) - (1 8 (. .) ((. (. .)) (((. .) (. .)) (. .)))) - (1 8 (. .) (((. .) .) ((. .) ((. .) (. .))))) - (1 8 (. .) (((. .) .) ((. (. .)) (. (. .))))) - (1 8 (. .) (((. .) .) ((. (. .)) ((. .) .)))) - (1 8 (. .) (((. .) .) (((. .) .) (. (. .))))) - (1 8 (. .) (((. .) .) (((. .) .) ((. .) .)))) - (1 8 (. .) (((. .) .) (((. .) (. .)) (. .)))) - (1 8 (. .) ((. (. (. .))) (. ((. .) (. .))))) - (1 8 (. .) ((. (. (. .))) ((. .) (. (. .))))) - (1 8 (. .) ((. (. (. .))) ((. .) ((. .) .)))) - (1 8 (. .) ((. (. (. .))) ((. (. .)) (. .)))) - (1 8 (. .) ((. (. (. .))) (((. .) .) (. .)))) - (1 8 (. .) ((. (. (. .))) (((. .) (. .)) .))) - (1 8 (. .) ((. ((. .) .)) (. ((. .) (. .))))) - (1 8 (. .) ((. ((. .) .)) ((. .) (. (. .))))) - (1 8 (. .) ((. ((. .) .)) ((. .) ((. .) .)))) - (1 8 (. .) ((. ((. .) .)) ((. (. .)) (. .)))) - (1 8 (. .) ((. ((. .) .)) (((. .) .) (. .)))) - (1 8 (. .) ((. ((. .) .)) (((. .) (. .)) .))) - (1 8 (. .) (((. .) (. .)) (. ((. .) (. .))))) - (1 8 (. .) (((. .) (. .)) ((. .) (. (. .))))) - (1 8 (. .) (((. .) (. .)) ((. .) ((. .) .)))) - (1 8 (. .) (((. .) (. .)) ((. (. .)) (. .)))) - (1 8 (. .) (((. .) (. .)) (((. .) .) (. .)))) - (1 8 (. .) (((. .) (. .)) (((. .) (. .)) .))) - (1 8 (. .) (((. (. .)) .) (. ((. .) (. .))))) - (1 8 (. .) (((. (. .)) .) ((. .) (. (. .))))) - (1 8 (. .) (((. (. .)) .) ((. .) ((. .) .)))) - (1 8 (. .) (((. (. .)) .) ((. (. .)) (. .)))) - (1 8 (. .) (((. (. .)) .) (((. .) .) (. .)))) - (1 8 (. .) (((. (. .)) .) (((. .) (. .)) .))) - (1 8 (. .) ((((. .) .) .) (. ((. .) (. .))))) - (1 8 (. .) ((((. .) .) .) ((. .) (. (. .))))) - (1 8 (. .) ((((. .) .) .) ((. .) ((. .) .)))) - (1 8 (. .) ((((. .) .) .) ((. (. .)) (. .)))) - (1 8 (. .) ((((. .) .) .) (((. .) .) (. .)))) - (1 8 (. .) ((((. .) .) .) (((. .) (. .)) .))) - (1 8 (. .) ((. ((. .) (. .))) (. (. (. .))))) - (1 8 (. .) ((. ((. .) (. .))) (. ((. .) .)))) - (1 8 (. .) ((. ((. .) (. .))) ((. .) (. .)))) - (1 8 (. .) ((. ((. .) (. .))) ((. (. .)) .))) - (1 8 (. .) ((. ((. .) (. .))) (((. .) .) .))) - (1 8 (. .) (((. .) (. (. .))) (. (. (. .))))) - (1 8 (. .) (((. .) (. (. .))) (. ((. .) .)))) - (1 8 (. .) (((. .) (. (. .))) ((. .) (. .)))) - (1 8 (. .) (((. .) (. (. .))) ((. (. .)) .))) - (1 8 (. .) (((. .) (. (. .))) (((. .) .) .))) - (1 8 (. .) (((. .) ((. .) .)) (. (. (. .))))) - (1 8 (. .) (((. .) ((. .) .)) (. ((. .) .)))) - (1 8 (. .) (((. .) ((. .) .)) ((. .) (. .)))) - (1 8 (. .) (((. .) ((. .) .)) ((. (. .)) .))) - (1 8 (. .) (((. .) ((. .) .)) (((. .) .) .))) - (1 8 (. .) (((. (. .)) (. .)) (. (. (. .))))) - (1 8 (. .) (((. (. .)) (. .)) (. ((. .) .)))) - (1 8 (. .) (((. (. .)) (. .)) ((. .) (. .)))) - (1 8 (. .) (((. (. .)) (. .)) ((. (. .)) .))) - (1 8 (. .) (((. (. .)) (. .)) (((. .) .) .))) - (1 8 (. .) ((((. .) .) (. .)) (. (. (. .))))) - (1 8 (. .) ((((. .) .) (. .)) (. ((. .) .)))) - (1 8 (. .) ((((. .) .) (. .)) ((. .) (. .)))) - (1 8 (. .) ((((. .) .) (. .)) ((. (. .)) .))) - (1 8 (. .) ((((. .) .) (. .)) (((. .) .) .))) - (1 8 (. .) ((((. .) (. .)) .) (. (. (. .))))) - (1 8 (. .) ((((. .) (. .)) .) (. ((. .) .)))) - (1 8 (. .) ((((. .) (. .)) .) ((. .) (. .)))) - (1 8 (. .) ((((. .) (. .)) .) ((. (. .)) .))) - (1 8 (. .) ((((. .) (. .)) .) (((. .) .) .))) - (1 8 (. .) (((. .) ((. .) (. .))) (. (. .)))) - (1 8 (. .) (((. .) ((. .) (. .))) ((. .) .))) - (1 8 (. .) (((. (. .)) (. (. .))) (. (. .)))) - (1 8 (. .) (((. (. .)) (. (. .))) ((. .) .))) - (1 8 (. .) (((. (. .)) ((. .) .)) (. (. .)))) - (1 8 (. .) (((. (. .)) ((. .) .)) ((. .) .))) - (1 8 (. .) ((((. .) .) (. (. .))) (. (. .)))) - (1 8 (. .) ((((. .) .) (. (. .))) ((. .) .))) - (1 8 (. .) ((((. .) .) ((. .) .)) (. (. .)))) - (1 8 (. .) ((((. .) .) ((. .) .)) ((. .) .))) - (1 8 (. .) ((((. .) (. .)) (. .)) (. (. .)))) - (1 8 (. .) ((((. .) (. .)) (. .)) ((. .) .))) - (1 8 (. .) (((. (. .)) ((. .) (. .))) (. .))) - (1 8 (. .) ((((. .) .) ((. .) (. .))) (. .))) - (1 8 (. .) ((((. .) (. .)) (. (. .))) (. .))) - (1 8 (. .) ((((. .) (. .)) ((. .) .)) (. .))) - (8 1 ((. .) ((. (. .)) ((. .) (. .)))) (. .)) - (8 1 ((. .) (((. .) .) ((. .) (. .)))) (. .)) - (8 1 ((. .) (((. .) (. .)) (. (. .)))) (. .)) - (8 1 ((. .) (((. .) (. .)) ((. .) .))) (. .)) - (8 1 ((. (. .)) ((. .) ((. .) (. .)))) (. .)) - (8 1 ((. (. .)) ((. (. .)) (. (. .)))) (. .)) - (8 1 ((. (. .)) ((. (. .)) ((. .) .))) (. .)) - (8 1 ((. (. .)) (((. .) .) (. (. .)))) (. .)) - (8 1 ((. (. .)) (((. .) .) ((. .) .))) (. .)) - (8 1 ((. (. .)) (((. .) (. .)) (. .))) (. .)) - (8 1 (((. .) .) ((. .) ((. .) (. .)))) (. .)) - (8 1 (((. .) .) ((. (. .)) (. (. .)))) (. .)) - (8 1 (((. .) .) ((. (. .)) ((. .) .))) (. .)) - (8 1 (((. .) .) (((. .) .) (. (. .)))) (. .)) - (8 1 (((. .) .) (((. .) .) ((. .) .))) (. .)) - (8 1 (((. .) .) (((. .) (. .)) (. .))) (. .)) - (8 1 ((. (. (. .))) (. ((. .) (. .)))) (. .)) - (8 1 ((. (. (. .))) ((. .) (. (. .)))) (. .)) - (8 1 ((. (. (. .))) ((. .) ((. .) .))) (. .)) - (8 1 ((. (. (. .))) ((. (. .)) (. .))) (. .)) - (8 1 ((. (. (. .))) (((. .) .) (. .))) (. .)) - (8 1 ((. (. (. .))) (((. .) (. .)) .)) (. .)) - (8 1 ((. ((. .) .)) (. ((. .) (. .)))) (. .)) - (8 1 ((. ((. .) .)) ((. .) (. (. .)))) (. .)) - (8 1 ((. ((. .) .)) ((. .) ((. .) .))) (. .)) - (8 1 ((. ((. .) .)) ((. (. .)) (. .))) (. .)) - (8 1 ((. ((. .) .)) (((. .) .) (. .))) (. .)) - (8 1 ((. ((. .) .)) (((. .) (. .)) .)) (. .)) - (8 1 (((. .) (. .)) (. ((. .) (. .)))) (. .)) - (8 1 (((. .) (. .)) ((. .) (. (. .)))) (. .)) - (8 1 (((. .) (. .)) ((. .) ((. .) .))) (. .)) - (8 1 (((. .) (. .)) ((. (. .)) (. .))) (. .)) - (8 1 (((. .) (. .)) (((. .) .) (. .))) (. .)) - (8 1 (((. .) (. .)) (((. .) (. .)) .)) (. .)) - (8 1 (((. (. .)) .) (. ((. .) (. .)))) (. .)) - (8 1 (((. (. .)) .) ((. .) (. (. .)))) (. .)) - (8 1 (((. (. .)) .) ((. .) ((. .) .))) (. .)) - (8 1 (((. (. .)) .) ((. (. .)) (. .))) (. .)) - (8 1 (((. (. .)) .) (((. .) .) (. .))) (. .)) - (8 1 (((. (. .)) .) (((. .) (. .)) .)) (. .)) - (8 1 ((((. .) .) .) (. ((. .) (. .)))) (. .)) - (8 1 ((((. .) .) .) ((. .) (. (. .)))) (. .)) - (8 1 ((((. .) .) .) ((. .) ((. .) .))) (. .)) - (8 1 ((((. .) .) .) ((. (. .)) (. .))) (. .)) - (8 1 ((((. .) .) .) (((. .) .) (. .))) (. .)) - (8 1 ((((. .) .) .) (((. .) (. .)) .)) (. .)) - (8 1 ((. ((. .) (. .))) (. (. (. .)))) (. .)) - (8 1 ((. ((. .) (. .))) (. ((. .) .))) (. .)) - (8 1 ((. ((. .) (. .))) ((. .) (. .))) (. .)) - (8 1 ((. ((. .) (. .))) ((. (. .)) .)) (. .)) - (8 1 ((. ((. .) (. .))) (((. .) .) .)) (. .)) - (8 1 (((. .) (. (. .))) (. (. (. .)))) (. .)) - (8 1 (((. .) (. (. .))) (. ((. .) .))) (. .)) - (8 1 (((. .) (. (. .))) ((. .) (. .))) (. .)) - (8 1 (((. .) (. (. .))) ((. (. .)) .)) (. .)) - (8 1 (((. .) (. (. .))) (((. .) .) .)) (. .)) - (8 1 (((. .) ((. .) .)) (. (. (. .)))) (. .)) - (8 1 (((. .) ((. .) .)) (. ((. .) .))) (. .)) - (8 1 (((. .) ((. .) .)) ((. .) (. .))) (. .)) - (8 1 (((. .) ((. .) .)) ((. (. .)) .)) (. .)) - (8 1 (((. .) ((. .) .)) (((. .) .) .)) (. .)) - (8 1 (((. (. .)) (. .)) (. (. (. .)))) (. .)) - (8 1 (((. (. .)) (. .)) (. ((. .) .))) (. .)) - (8 1 (((. (. .)) (. .)) ((. .) (. .))) (. .)) - (8 1 (((. (. .)) (. .)) ((. (. .)) .)) (. .)) - (8 1 (((. (. .)) (. .)) (((. .) .) .)) (. .)) - (8 1 ((((. .) .) (. .)) (. (. (. .)))) (. .)) - (8 1 ((((. .) .) (. .)) (. ((. .) .))) (. .)) - (8 1 ((((. .) .) (. .)) ((. .) (. .))) (. .)) - (8 1 ((((. .) .) (. .)) ((. (. .)) .)) (. .)) - (8 1 ((((. .) .) (. .)) (((. .) .) .)) (. .)) - (8 1 ((((. .) (. .)) .) (. (. (. .)))) (. .)) - (8 1 ((((. .) (. .)) .) (. ((. .) .))) (. .)) - (8 1 ((((. .) (. .)) .) ((. .) (. .))) (. .)) - (8 1 ((((. .) (. .)) .) ((. (. .)) .)) (. .)) - (8 1 ((((. .) (. .)) .) (((. .) .) .)) (. .)) - (8 1 (((. .) ((. .) (. .))) (. (. .))) (. .)) - (8 1 (((. .) ((. .) (. .))) ((. .) .)) (. .)) - (8 1 (((. (. .)) (. (. .))) (. (. .))) (. .)) - (8 1 (((. (. .)) (. (. .))) ((. .) .)) (. .)) - (8 1 (((. (. .)) ((. .) .)) (. (. .))) (. .)) - (8 1 (((. (. .)) ((. .) .)) ((. .) .)) (. .)) - (8 1 ((((. .) .) (. (. .))) (. (. .))) (. .)) - (8 1 ((((. .) .) (. (. .))) ((. .) .)) (. .)) - (8 1 ((((. .) .) ((. .) .)) (. (. .))) (. .)) - (8 1 ((((. .) .) ((. .) .)) ((. .) .)) (. .)) - (8 1 ((((. .) (. .)) (. .)) (. (. .))) (. .)) - (8 1 ((((. .) (. .)) (. .)) ((. .) .)) (. .)) - (8 1 (((. (. .)) ((. .) (. .))) (. .)) (. .)) - (8 1 ((((. .) .) ((. .) (. .))) (. .)) (. .)) - (8 1 ((((. .) (. .)) (. (. .))) (. .)) (. .)) - (8 1 ((((. .) (. .)) ((. .) .)) (. .)) (. .)) - ((shown 376) (total 2_732_440)) + ((1 5) (. .) ((. .) ((. .) (. .)))) + ((1 5) (. .) ((. (. .)) (. (. .)))) + ((1 5) (. .) ((. (. .)) ((. .) .))) + ((1 5) (. .) (((. .) .) (. (. .)))) + ((1 5) (. .) (((. .) .) ((. .) .))) + ((5 1) ((. (. .)) (. (. .))) (. .)) + ((5 1) ((. (. .)) ((. .) .)) (. .)) + ((5 1) (((. .) .) (. (. .))) (. .)) + ((5 1) (((. .) .) ((. .) .)) (. .)) + ((5 1) (((. .) (. .)) (. .)) (. .)) + ((2 7) (. (. .)) ((. (. .)) ((. .) (. (. .))))) + ((2 7) (. (. .)) ((. (. .)) ((. .) ((. .) .)))) + ((2 7) (. (. .)) ((. (. .)) ((. (. .)) (. .)))) + ((2 7) (. (. .)) ((. (. .)) (((. .) .) (. .)))) + ((2 7) (. (. .)) (((. .) .) ((. .) (. (. .))))) + ((2 7) (. (. .)) (((. .) .) ((. .) ((. .) .)))) + ((2 7) (. (. .)) (((. .) .) ((. (. .)) (. .)))) + ((2 7) (. (. .)) (((. .) .) (((. .) .) (. .)))) + ((2 7) (. (. .)) (((. .) (. .)) ((. .) (. .)))) + ((2 7) ((. .) .) ((. (. .)) ((. .) (. (. .))))) + ((2 7) ((. .) .) ((. (. .)) ((. .) ((. .) .)))) + ((2 7) ((. .) .) ((. (. .)) ((. (. .)) (. .)))) + ((2 7) ((. .) .) ((. (. .)) (((. .) .) (. .)))) + ((2 7) ((. .) .) (((. .) .) ((. .) (. (. .))))) + ((2 7) ((. .) .) (((. .) .) ((. .) ((. .) .)))) + ((2 7) ((. .) .) (((. .) .) ((. (. .)) (. .)))) + ((2 7) ((. .) .) (((. .) .) (((. .) .) (. .)))) + ((2 7) ((. .) .) (((. .) (. .)) ((. .) (. .)))) + ((7 2) (((. .) (. .)) ((. .) (. .))) (. (. .))) + ((7 2) (((. .) (. .)) ((. .) (. .))) ((. .) .)) + ((7 2) (((. .) (. (. .))) (. (. .))) (. (. .))) + ((7 2) (((. .) (. (. .))) (. (. .))) ((. .) .)) + ((7 2) (((. .) (. (. .))) ((. .) .)) (. (. .))) + ((7 2) (((. .) (. (. .))) ((. .) .)) ((. .) .)) + ((7 2) (((. .) ((. .) .)) (. (. .))) (. (. .))) + ((7 2) (((. .) ((. .) .)) (. (. .))) ((. .) .)) + ((7 2) (((. .) ((. .) .)) ((. .) .)) (. (. .))) + ((7 2) (((. .) ((. .) .)) ((. .) .)) ((. .) .)) + ((7 2) (((. (. .)) (. .)) (. (. .))) (. (. .))) + ((7 2) (((. (. .)) (. .)) (. (. .))) ((. .) .)) + ((7 2) (((. (. .)) (. .)) ((. .) .)) (. (. .))) + ((7 2) (((. (. .)) (. .)) ((. .) .)) ((. .) .)) + ((7 2) ((((. .) .) (. .)) (. (. .))) (. (. .))) + ((7 2) ((((. .) .) (. .)) (. (. .))) ((. .) .)) + ((7 2) ((((. .) .) (. .)) ((. .) .)) (. (. .))) + ((7 2) ((((. .) .) (. .)) ((. .) .)) ((. .) .)) + ((shown 46) (total 3_431_304)) |}] ;; @@ -1860,71 +476,163 @@ let test (module Tree : S) = ~have_been_shown:are_almost_balanced; [%expect {| - (1 8 (. .) ((. (. .)) ((. .) (. (. (. .)))))) - (1 8 (. .) ((. (. .)) ((. .) (. ((. .) .))))) - (1 8 (. .) ((. (. .)) ((. .) ((. (. .)) .)))) - (1 8 (. .) ((. (. .)) ((. .) (((. .) .) .)))) - (1 8 (. .) ((. (. .)) ((. (. (. .))) (. .)))) - (1 8 (. .) ((. (. .)) ((. ((. .) .)) (. .)))) - (1 8 (. .) ((. (. .)) (((. (. .)) .) (. .)))) - (1 8 (. .) ((. (. .)) ((((. .) .) .) (. .)))) - (1 8 (. .) (((. .) .) ((. .) (. (. (. .)))))) - (1 8 (. .) (((. .) .) ((. .) (. ((. .) .))))) - (1 8 (. .) (((. .) .) ((. .) ((. (. .)) .)))) - (1 8 (. .) (((. .) .) ((. .) (((. .) .) .)))) - (1 8 (. .) (((. .) .) ((. (. (. .))) (. .)))) - (1 8 (. .) (((. .) .) ((. ((. .) .)) (. .)))) - (1 8 (. .) (((. .) .) (((. (. .)) .) (. .)))) - (1 8 (. .) (((. .) .) ((((. .) .) .) (. .)))) - (1 8 (. .) (((. .) (. (. (. .)))) (. (. .)))) - (1 8 (. .) (((. .) (. (. (. .)))) ((. .) .))) - (1 8 (. .) (((. .) (. ((. .) .))) (. (. .)))) - (1 8 (. .) (((. .) (. ((. .) .))) ((. .) .))) - (1 8 (. .) (((. .) ((. (. .)) .)) (. (. .)))) - (1 8 (. .) (((. .) ((. (. .)) .)) ((. .) .))) - (1 8 (. .) (((. .) (((. .) .) .)) (. (. .)))) - (1 8 (. .) (((. .) (((. .) .) .)) ((. .) .))) - (1 8 (. .) (((. (. (. .))) (. .)) (. (. .)))) - (1 8 (. .) (((. (. (. .))) (. .)) ((. .) .))) - (1 8 (. .) (((. ((. .) .)) (. .)) (. (. .)))) - (1 8 (. .) (((. ((. .) .)) (. .)) ((. .) .))) - (1 8 (. .) ((((. (. .)) .) (. .)) (. (. .)))) - (1 8 (. .) ((((. (. .)) .) (. .)) ((. .) .))) - (1 8 (. .) (((((. .) .) .) (. .)) (. (. .)))) - (1 8 (. .) (((((. .) .) .) (. .)) ((. .) .))) - (8 1 ((. (. .)) ((. .) (. (. (. .))))) (. .)) - (8 1 ((. (. .)) ((. .) (. ((. .) .)))) (. .)) - (8 1 ((. (. .)) ((. .) ((. (. .)) .))) (. .)) - (8 1 ((. (. .)) ((. .) (((. .) .) .))) (. .)) - (8 1 ((. (. .)) ((. (. (. .))) (. .))) (. .)) - (8 1 ((. (. .)) ((. ((. .) .)) (. .))) (. .)) - (8 1 ((. (. .)) (((. (. .)) .) (. .))) (. .)) - (8 1 ((. (. .)) ((((. .) .) .) (. .))) (. .)) - (8 1 (((. .) .) ((. .) (. (. (. .))))) (. .)) - (8 1 (((. .) .) ((. .) (. ((. .) .)))) (. .)) - (8 1 (((. .) .) ((. .) ((. (. .)) .))) (. .)) - (8 1 (((. .) .) ((. .) (((. .) .) .))) (. .)) - (8 1 (((. .) .) ((. (. (. .))) (. .))) (. .)) - (8 1 (((. .) .) ((. ((. .) .)) (. .))) (. .)) - (8 1 (((. .) .) (((. (. .)) .) (. .))) (. .)) - (8 1 (((. .) .) ((((. .) .) .) (. .))) (. .)) - (8 1 (((. .) (. (. (. .)))) (. (. .))) (. .)) - (8 1 (((. .) (. (. (. .)))) ((. .) .)) (. .)) - (8 1 (((. .) (. ((. .) .))) (. (. .))) (. .)) - (8 1 (((. .) (. ((. .) .))) ((. .) .)) (. .)) - (8 1 (((. .) ((. (. .)) .)) (. (. .))) (. .)) - (8 1 (((. .) ((. (. .)) .)) ((. .) .)) (. .)) - (8 1 (((. .) (((. .) .) .)) (. (. .))) (. .)) - (8 1 (((. .) (((. .) .) .)) ((. .) .)) (. .)) - (8 1 (((. (. (. .))) (. .)) (. (. .))) (. .)) - (8 1 (((. (. (. .))) (. .)) ((. .) .)) (. .)) - (8 1 (((. ((. .) .)) (. .)) (. (. .))) (. .)) - (8 1 (((. ((. .) .)) (. .)) ((. .) .)) (. .)) - (8 1 ((((. (. .)) .) (. .)) (. (. .))) (. .)) - (8 1 ((((. (. .)) .) (. .)) ((. .) .)) (. .)) - (8 1 (((((. .) .) .) (. .)) (. (. .))) (. .)) - (8 1 (((((. .) .) .) (. .)) ((. .) .)) (. .)) - ((shown 64) (total 5_812_834)) + ((1 5) (. .) (((. .) (. .)) (. .))) + ((5 1) ((. .) ((. .) (. .))) (. .)) + ((1 6) (. .) ((. .) ((. .) (. (. .))))) + ((1 6) (. .) ((. .) ((. .) ((. .) .)))) + ((1 6) (. .) ((. .) ((. (. .)) (. .)))) + ((1 6) (. .) ((. .) (((. .) .) (. .)))) + ((1 6) (. .) ((. (. .)) ((. .) (. .)))) + ((1 6) (. .) (((. .) .) ((. .) (. .)))) + ((1 6) (. .) (((. .) (. .)) (. (. .)))) + ((1 6) (. .) (((. .) (. .)) ((. .) .))) + ((1 6) (. .) (((. .) (. (. .))) (. .))) + ((1 6) (. .) (((. .) ((. .) .)) (. .))) + ((1 6) (. .) (((. (. .)) (. .)) (. .))) + ((1 6) (. .) ((((. .) .) (. .)) (. .))) + ((6 1) ((. .) ((. .) (. (. .)))) (. .)) + ((6 1) ((. .) ((. .) ((. .) .))) (. .)) + ((6 1) ((. .) ((. (. .)) (. .))) (. .)) + ((6 1) ((. .) (((. .) .) (. .))) (. .)) + ((6 1) ((. (. .)) ((. .) (. .))) (. .)) + ((6 1) (((. .) .) ((. .) (. .))) (. .)) + ((6 1) (((. .) (. .)) (. (. .))) (. .)) + ((6 1) (((. .) (. .)) ((. .) .)) (. .)) + ((6 1) (((. .) (. (. .))) (. .)) (. .)) + ((6 1) (((. .) ((. .) .)) (. .)) (. .)) + ((6 1) (((. (. .)) (. .)) (. .)) (. .)) + ((6 1) ((((. .) .) (. .)) (. .)) (. .)) + ((1 7) (. .) ((. (. .)) ((. .) (. (. .))))) + ((1 7) (. .) ((. (. .)) ((. .) ((. .) .)))) + ((1 7) (. .) ((. (. .)) ((. (. .)) (. .)))) + ((1 7) (. .) ((. (. .)) (((. .) .) (. .)))) + ((1 7) (. .) (((. .) .) ((. .) (. (. .))))) + ((1 7) (. .) (((. .) .) ((. .) ((. .) .)))) + ((1 7) (. .) (((. .) .) ((. (. .)) (. .)))) + ((1 7) (. .) (((. .) .) (((. .) .) (. .)))) + ((1 7) (. .) (((. .) (. .)) ((. .) (. .)))) + ((1 7) (. .) (((. .) (. (. .))) (. (. .)))) + ((1 7) (. .) (((. .) (. (. .))) ((. .) .))) + ((1 7) (. .) (((. .) ((. .) .)) (. (. .)))) + ((1 7) (. .) (((. .) ((. .) .)) ((. .) .))) + ((1 7) (. .) (((. (. .)) (. .)) (. (. .)))) + ((1 7) (. .) (((. (. .)) (. .)) ((. .) .))) + ((1 7) (. .) ((((. .) .) (. .)) (. (. .)))) + ((1 7) (. .) ((((. .) .) (. .)) ((. .) .))) + ((7 1) ((. (. .)) ((. .) (. (. .)))) (. .)) + ((7 1) ((. (. .)) ((. .) ((. .) .))) (. .)) + ((7 1) ((. (. .)) ((. (. .)) (. .))) (. .)) + ((7 1) ((. (. .)) (((. .) .) (. .))) (. .)) + ((7 1) (((. .) .) ((. .) (. (. .)))) (. .)) + ((7 1) (((. .) .) ((. .) ((. .) .))) (. .)) + ((7 1) (((. .) .) ((. (. .)) (. .))) (. .)) + ((7 1) (((. .) .) (((. .) .) (. .))) (. .)) + ((7 1) (((. .) (. .)) ((. .) (. .))) (. .)) + ((7 1) (((. .) (. (. .))) (. (. .))) (. .)) + ((7 1) (((. .) (. (. .))) ((. .) .)) (. .)) + ((7 1) (((. .) ((. .) .)) (. (. .))) (. .)) + ((7 1) (((. .) ((. .) .)) ((. .) .)) (. .)) + ((7 1) (((. (. .)) (. .)) (. (. .))) (. .)) + ((7 1) (((. (. .)) (. .)) ((. .) .)) (. .)) + ((7 1) ((((. .) .) (. .)) (. (. .))) (. .)) + ((7 1) ((((. .) .) (. .)) ((. .) .)) (. .)) + ((1 8) (. .) ((. (. .)) ((. .) ((. .) (. .))))) + ((1 8) (. .) ((. (. .)) ((. (. .)) (. (. .))))) + ((1 8) (. .) ((. (. .)) ((. (. .)) ((. .) .)))) + ((1 8) (. .) ((. (. .)) (((. .) .) (. (. .))))) + ((1 8) (. .) ((. (. .)) (((. .) .) ((. .) .)))) + ((1 8) (. .) ((. (. .)) (((. .) (. .)) (. .)))) + ((1 8) (. .) (((. .) .) ((. .) ((. .) (. .))))) + ((1 8) (. .) (((. .) .) ((. (. .)) (. (. .))))) + ((1 8) (. .) (((. .) .) ((. (. .)) ((. .) .)))) + ((1 8) (. .) (((. .) .) (((. .) .) (. (. .))))) + ((1 8) (. .) (((. .) .) (((. .) .) ((. .) .)))) + ((1 8) (. .) (((. .) .) (((. .) (. .)) (. .)))) + ((1 8) (. .) (((. .) (. .)) ((. .) (. (. .))))) + ((1 8) (. .) (((. .) (. .)) ((. .) ((. .) .)))) + ((1 8) (. .) (((. .) (. .)) ((. (. .)) (. .)))) + ((1 8) (. .) (((. .) (. .)) (((. .) .) (. .)))) + ((1 8) (. .) (((. .) (. (. .))) ((. .) (. .)))) + ((1 8) (. .) (((. .) ((. .) .)) ((. .) (. .)))) + ((1 8) (. .) (((. (. .)) (. .)) ((. .) (. .)))) + ((1 8) (. .) ((((. .) .) (. .)) ((. .) (. .)))) + ((1 8) (. .) (((. .) ((. .) (. .))) (. (. .)))) + ((1 8) (. .) (((. .) ((. .) (. .))) ((. .) .))) + ((1 8) (. .) (((. (. .)) (. (. .))) (. (. .)))) + ((1 8) (. .) (((. (. .)) (. (. .))) ((. .) .))) + ((1 8) (. .) (((. (. .)) ((. .) .)) (. (. .)))) + ((1 8) (. .) (((. (. .)) ((. .) .)) ((. .) .))) + ((1 8) (. .) ((((. .) .) (. (. .))) (. (. .)))) + ((1 8) (. .) ((((. .) .) (. (. .))) ((. .) .))) + ((1 8) (. .) ((((. .) .) ((. .) .)) (. (. .)))) + ((1 8) (. .) ((((. .) .) ((. .) .)) ((. .) .))) + ((1 8) (. .) ((((. .) (. .)) (. .)) (. (. .)))) + ((1 8) (. .) ((((. .) (. .)) (. .)) ((. .) .))) + ((2 7) (. (. .)) (((. .) (. (. .))) (. (. .)))) + ((2 7) (. (. .)) (((. .) (. (. .))) ((. .) .))) + ((2 7) (. (. .)) (((. .) ((. .) .)) (. (. .)))) + ((2 7) (. (. .)) (((. .) ((. .) .)) ((. .) .))) + ((2 7) (. (. .)) (((. (. .)) (. .)) (. (. .)))) + ((2 7) (. (. .)) (((. (. .)) (. .)) ((. .) .))) + ((2 7) (. (. .)) ((((. .) .) (. .)) (. (. .)))) + ((2 7) (. (. .)) ((((. .) .) (. .)) ((. .) .))) + ((2 7) ((. .) .) (((. .) (. (. .))) (. (. .)))) + ((2 7) ((. .) .) (((. .) (. (. .))) ((. .) .))) + ((2 7) ((. .) .) (((. .) ((. .) .)) (. (. .)))) + ((2 7) ((. .) .) (((. .) ((. .) .)) ((. .) .))) + ((2 7) ((. .) .) (((. (. .)) (. .)) (. (. .)))) + ((2 7) ((. .) .) (((. (. .)) (. .)) ((. .) .))) + ((2 7) ((. .) .) ((((. .) .) (. .)) (. (. .)))) + ((2 7) ((. .) .) ((((. .) .) (. .)) ((. .) .))) + ((7 2) ((. (. .)) ((. .) (. (. .)))) (. (. .))) + ((7 2) ((. (. .)) ((. .) (. (. .)))) ((. .) .)) + ((7 2) ((. (. .)) ((. .) ((. .) .))) (. (. .))) + ((7 2) ((. (. .)) ((. .) ((. .) .))) ((. .) .)) + ((7 2) ((. (. .)) ((. (. .)) (. .))) (. (. .))) + ((7 2) ((. (. .)) ((. (. .)) (. .))) ((. .) .)) + ((7 2) ((. (. .)) (((. .) .) (. .))) (. (. .))) + ((7 2) ((. (. .)) (((. .) .) (. .))) ((. .) .)) + ((7 2) (((. .) .) ((. .) (. (. .)))) (. (. .))) + ((7 2) (((. .) .) ((. .) (. (. .)))) ((. .) .)) + ((7 2) (((. .) .) ((. .) ((. .) .))) (. (. .))) + ((7 2) (((. .) .) ((. .) ((. .) .))) ((. .) .)) + ((7 2) (((. .) .) ((. (. .)) (. .))) (. (. .))) + ((7 2) (((. .) .) ((. (. .)) (. .))) ((. .) .)) + ((7 2) (((. .) .) (((. .) .) (. .))) (. (. .))) + ((7 2) (((. .) .) (((. .) .) (. .))) ((. .) .)) + ((8 1) ((. (. .)) ((. .) ((. .) (. .)))) (. .)) + ((8 1) ((. (. .)) ((. (. .)) (. (. .)))) (. .)) + ((8 1) ((. (. .)) ((. (. .)) ((. .) .))) (. .)) + ((8 1) ((. (. .)) (((. .) .) (. (. .)))) (. .)) + ((8 1) ((. (. .)) (((. .) .) ((. .) .))) (. .)) + ((8 1) ((. (. .)) (((. .) (. .)) (. .))) (. .)) + ((8 1) (((. .) .) ((. .) ((. .) (. .)))) (. .)) + ((8 1) (((. .) .) ((. (. .)) (. (. .)))) (. .)) + ((8 1) (((. .) .) ((. (. .)) ((. .) .))) (. .)) + ((8 1) (((. .) .) (((. .) .) (. (. .)))) (. .)) + ((8 1) (((. .) .) (((. .) .) ((. .) .))) (. .)) + ((8 1) (((. .) .) (((. .) (. .)) (. .))) (. .)) + ((8 1) (((. .) (. .)) ((. .) (. (. .)))) (. .)) + ((8 1) (((. .) (. .)) ((. .) ((. .) .))) (. .)) + ((8 1) (((. .) (. .)) ((. (. .)) (. .))) (. .)) + ((8 1) (((. .) (. .)) (((. .) .) (. .))) (. .)) + ((8 1) (((. .) (. (. .))) ((. .) (. .))) (. .)) + ((8 1) (((. .) ((. .) .)) ((. .) (. .))) (. .)) + ((8 1) (((. (. .)) (. .)) ((. .) (. .))) (. .)) + ((8 1) ((((. .) .) (. .)) ((. .) (. .))) (. .)) + ((8 1) (((. .) ((. .) (. .))) (. (. .))) (. .)) + ((8 1) (((. .) ((. .) (. .))) ((. .) .)) (. .)) + ((8 1) (((. (. .)) (. (. .))) (. (. .))) (. .)) + ((8 1) (((. (. .)) (. (. .))) ((. .) .)) (. .)) + ((8 1) (((. (. .)) ((. .) .)) (. (. .))) (. .)) + ((8 1) (((. (. .)) ((. .) .)) ((. .) .)) (. .)) + ((8 1) ((((. .) .) (. (. .))) (. (. .))) (. .)) + ((8 1) ((((. .) .) (. (. .))) ((. .) .)) (. .)) + ((8 1) ((((. .) .) ((. .) .)) (. (. .))) (. .)) + ((8 1) ((((. .) .) ((. .) .)) ((. .) .)) (. .)) + ((8 1) ((((. .) (. .)) (. .)) (. (. .))) (. .)) + ((8 1) ((((. .) (. .)) (. .)) ((. .) .)) (. .)) + ((shown 156) (total 13_501_812)) |}] ;; end diff --git a/test/test_option.ml b/test/test_option.ml index c9c790f..4349168 100644 --- a/test/test_option.ml +++ b/test/test_option.ml @@ -7,6 +7,17 @@ let%test _ = [%compare.equal: int t] (merge (Some 3) None ~f) (Some 3) let%test _ = [%compare.equal: int t] (merge None (Some 3) ~f) (Some 3) let%test _ = [%compare.equal: int t] (merge (Some 1) (Some 3) ~f) (Some 4) +let%expect_test "[value_exn]" = + (* Location information should be excluded when [here] is [Lexing.dummy_pos], which is + the default value of [here] in the external version of Base *) + Expect_test_helpers_base.require_does_raise ~hide_positions:true (fun () -> + value_exn None); + [%expect {| ("Option.value_exn None" lib/base/test/test_option.ml:LINE:COL) |}]; + Expect_test_helpers_base.require_does_raise (fun () -> + value_exn None ~here:Lexing.dummy_pos); + [%expect {| "Option.value_exn None" |}] +;; + let%expect_test "[value_or_thunk]" = let default () = print_endline "THUNK!"; diff --git a/test/test_set.ml b/test/test_set.ml index f7236ab..4323534 100644 --- a/test/test_set.ml +++ b/test/test_set.ml @@ -190,7 +190,7 @@ module%test [@name "element selection"] _ = struct (0 (Error "Set.choose_exn: empty set")) (1 (Ok 1)) (2 multiple (((Ok 2) balanced) ((Ok 1) left-heavy) ((Ok 2) right-heavy))) - (3 multiple (((Ok 2) balanced) ((Ok 1) left-heavy) ((Ok 3) right-heavy))) + (3 (Ok 2)) (4 multiple (((Ok 3) balanced) ((Ok 2) left-heavy) ((Ok 3) right-heavy))) (5 multiple (((Ok 3) balanced) ((Ok 2) left-heavy) ((Ok 4) right-heavy))) (6 multiple (((Ok 4) balanced) ((Ok 2) left-heavy) ((Ok 5) right-heavy))) @@ -249,9 +249,7 @@ module%test [@name "element selection"] _ = struct (0 ()) (1 ((1))) (2 ((1 2))) - (3 - multiple - ((((3) (1 2)) balanced) (((3) (1 2)) left-heavy) (((1 2) (3)) right-heavy))) + (3 ((3) (1 2))) (4 multiple ((((1 2 4) (3)) balanced) @@ -307,18 +305,18 @@ let%expect_test ("space" [@tags "no-js"]) = │ 1 │ r_to_l │ 15 │ │ 1 │ balanced │ 15 │ │ 1 │ random │ 15 │ - │ 100 │ l_to_r │ 413 │ - │ 100 │ r_to_l │ 413 │ - │ 100 │ balanced │ 465 │ - │ 100 │ random │ 473 │ - │ 10_000 │ l_to_r │ 40_013 │ - │ 10_000 │ r_to_l │ 40_013 │ - │ 10_000 │ balanced │ 43_629 │ - │ 10_000 │ random │ 45_177 │ - │ 1_000_000 │ l_to_r │ 4_000_013 │ - │ 1_000_000 │ r_to_l │ 4_000_013 │ - │ 1_000_000 │ balanced │ 4_097_161 │ - │ 1_000_000 │ random │ 4_512_061 │ + │ 100 │ l_to_r │ 363 │ + │ 100 │ r_to_l │ 363 │ + │ 100 │ balanced │ 402 │ + │ 100 │ random │ 387 │ + │ 10_000 │ l_to_r │ 35_013 │ + │ 10_000 │ r_to_l │ 35_013 │ + │ 10_000 │ balanced │ 37_725 │ + │ 10_000 │ random │ 37_083 │ + │ 1_000_000 │ l_to_r │ 3_500_013 │ + │ 1_000_000 │ r_to_l │ 3_500_013 │ + │ 1_000_000 │ balanced │ 3_572_874 │ + │ 1_000_000 │ random │ 3_714_564 │ └───────────┴──────────────┴───────────┘ |}] ;;