mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
157 lines
3.6 KiB
OCaml
157 lines
3.6 KiB
OCaml
module Test = (val Containers_testlib.make ~__FILE__ ())
|
|
open Test
|
|
open CCWBTree
|
|
module M = Make (CCInt)
|
|
|
|
type op = Add of int * int | Remove of int | Remove_min
|
|
|
|
let gen_op =
|
|
CCRandom.(
|
|
choose_exn
|
|
[
|
|
return Remove_min;
|
|
map (fun x -> Remove x) small_int;
|
|
pure (fun x y -> Add (x, y)) <*> small_int <*> small_int;
|
|
])
|
|
|
|
and pp_op =
|
|
let open Printf in
|
|
function
|
|
| Add (x, y) -> sprintf "Add %d %d" x y
|
|
| Remove x -> sprintf "Remove %d" x
|
|
| Remove_min -> "Remove_min"
|
|
|
|
let apply_ops l m =
|
|
List.fold_left
|
|
(fun m -> function
|
|
| Add (i, b) -> M.add i b m
|
|
| Remove i -> M.remove i m
|
|
| Remove_min ->
|
|
(try
|
|
let _, _, m' = M.extract_min m in
|
|
m'
|
|
with Not_found -> m))
|
|
m l
|
|
|
|
let op = Q.make ~print:pp_op gen_op
|
|
let _list_uniq = CCList.sort_uniq ~cmp:(CCFun.compose_binop fst Stdlib.compare)
|
|
;;
|
|
|
|
q ~count:200
|
|
Q.(list op)
|
|
(fun l ->
|
|
let m = apply_ops l M.empty in
|
|
M.balanced m)
|
|
;;
|
|
|
|
q
|
|
Q.(list (pair small_int bool))
|
|
(fun l ->
|
|
let m = M.of_list l in
|
|
M.balanced m)
|
|
;;
|
|
|
|
q
|
|
Q.(list (pair small_int small_int))
|
|
(fun l ->
|
|
let l = _list_uniq l in
|
|
let m = M.of_list l in
|
|
List.for_all (fun (k, v) -> M.get_exn k m = v) l)
|
|
;;
|
|
|
|
q
|
|
Q.(list (pair small_int small_int))
|
|
(fun l ->
|
|
let l = _list_uniq l in
|
|
let m = M.of_list l in
|
|
M.cardinal m = List.length l)
|
|
;;
|
|
|
|
q
|
|
Q.(list_of_size Gen.(0 -- 30) (pair small_int small_int))
|
|
(fun l ->
|
|
let m = M.of_list l in
|
|
List.for_all
|
|
(fun (k, _) ->
|
|
M.mem k m
|
|
&&
|
|
let m' = M.remove k m in
|
|
not (M.mem k m'))
|
|
l)
|
|
;;
|
|
|
|
q
|
|
Q.(list_of_size Gen.(0 -- 30) (pair small_int small_int))
|
|
(fun l ->
|
|
let m = M.of_list l in
|
|
List.for_all
|
|
(fun (k, _) ->
|
|
let m' = M.remove k m in
|
|
M.balanced m')
|
|
l)
|
|
;;
|
|
|
|
t @@ fun () ->
|
|
let m = CCList.(0 -- 1000 |> map (fun i -> i, i) |> M.of_list) in
|
|
List.for_all (fun i -> M.nth_exn i m = (i, i)) CCList.(0 -- 1000)
|
|
;;
|
|
|
|
q ~count:1_000
|
|
Q.(list_of_size Gen.(0 -- 30) (pair small_int small_int))
|
|
(fun l ->
|
|
let l = CCList.sort_uniq ~cmp:(CCFun.compose_binop fst compare) l in
|
|
let m = M.of_list l in
|
|
List.for_all
|
|
(fun (k, v) ->
|
|
match M.get_rank k m with
|
|
| `First | `After _ -> true
|
|
| `At n -> (k, v) = M.nth_exn n m)
|
|
l)
|
|
;;
|
|
|
|
q ~count:20
|
|
Q.(list_of_size Gen.(1 -- 100) (pair small_int small_int))
|
|
(fun lst ->
|
|
let lst = _list_uniq lst in
|
|
let m = M.of_list lst in
|
|
List.for_all
|
|
(fun (k, v) ->
|
|
let l, v', r = M.split k m in
|
|
v' = Some v
|
|
&& M.to_iter l |> Iter.for_all (fun (k', _) -> k' < k)
|
|
&& M.to_iter r |> Iter.for_all (fun (k', _) -> k' > k)
|
|
&& M.balanced m
|
|
&& M.cardinal l + M.cardinal r + 1 = List.length lst)
|
|
lst)
|
|
;;
|
|
|
|
t @@ fun () ->
|
|
let m1 = M.of_list [ 1, 1; 2, 2; 4, 4 ] in
|
|
let m2 = M.of_list [ 1, 1; 3, 3; 4, 4; 7, 7 ] in
|
|
let m = M.merge ~f:(fun _ -> CCOption.map2 ( + )) m1 m2 in
|
|
assert_bool "balanced" (M.balanced m);
|
|
assert_equal
|
|
~cmp:(CCList.equal (CCPair.equal CCInt.equal CCInt.equal))
|
|
~printer:CCFormat.(to_string (list (pair int int)))
|
|
[ 1, 2; 4, 8 ]
|
|
(M.to_list m |> List.sort Stdlib.compare);
|
|
true
|
|
;;
|
|
|
|
q
|
|
Q.(
|
|
let p = list (pair small_int small_int) in
|
|
pair p p)
|
|
(fun (l1, l2) ->
|
|
let l1 = _list_uniq l1 and l2 = _list_uniq l2 in
|
|
let m1 = M.of_list l1 and m2 = M.of_list l2 in
|
|
let m =
|
|
M.merge
|
|
~f:(fun _ v1 v2 ->
|
|
match v1 with
|
|
| None -> v2
|
|
| Some _ as r -> r)
|
|
m1 m2
|
|
in
|
|
List.for_all (fun (k, v) -> M.get_exn k m = v) l1
|
|
&& List.for_all (fun (k, v) -> M.mem k m1 || M.get_exn k m = v) l2)
|