Blame test/test_BitSet.ml

rpm-build 0f2925
(*
rpm-build 0f2925
 * ExtLib Testing Suite
rpm-build 0f2925
 * Copyright (C) 2004 Janne Hellsten
rpm-build 0f2925
 *
rpm-build 0f2925
 * This library is free software; you can redistribute it and/or
rpm-build 0f2925
 * modify it under the terms of the GNU Lesser General Public
rpm-build 0f2925
 * License as published by the Free Software Foundation; either
rpm-build 0f2925
 * version 2.1 of the License, or (at your option) any later version,
rpm-build 0f2925
 * with the special exception on linking described in file LICENSE.
rpm-build 0f2925
 *
rpm-build 0f2925
 * This library is distributed in the hope that it will be useful,
rpm-build 0f2925
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rpm-build 0f2925
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
rpm-build 0f2925
 * Lesser General Public License for more details.
rpm-build 0f2925
 *
rpm-build 0f2925
 * You should have received a copy of the GNU Lesser General Public
rpm-build 0f2925
 * License along with this library; if not, write to the Free Software
rpm-build 0f2925
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
rpm-build 0f2925
 *)
rpm-build 0f2925
rpm-build 0f2925
open ExtList
rpm-build 0f2925
rpm-build 0f2925
module B = BitSet
rpm-build 0f2925
rpm-build 0f2925
let biased_rnd_28 () = 
rpm-build 0f2925
  let n_bits = [| 4; 8; 16; 28 |] in
rpm-build 0f2925
  let n = n_bits.(Random.int (Array.length n_bits)) in
rpm-build 0f2925
  Random.int (1 lsl n)
rpm-build 0f2925
rpm-build 0f2925
let popcount n = 
rpm-build 0f2925
  let p = ref 0 in
rpm-build 0f2925
  for i = 0 to 29 do
rpm-build 0f2925
    if n land (1 lsl i) <> 0 then
rpm-build 0f2925
      incr p
rpm-build 0f2925
  done;
rpm-build 0f2925
  !p
rpm-build 0f2925
rpm-build 0f2925
let set_bitset s n = 
rpm-build 0f2925
  for i = 0 to 29 do
rpm-build 0f2925
    if (n land (1 lsl i)) <> 0 then
rpm-build 0f2925
      B.set s i
rpm-build 0f2925
  done;
rpm-build 0f2925
  assert (popcount n = B.count s)
rpm-build 0f2925
rpm-build 0f2925
let bitset_of_int n = 
rpm-build 0f2925
  assert (n <= (1 lsl 29));
rpm-build 0f2925
  let s = B.create 30 in
rpm-build 0f2925
  set_bitset s n;
rpm-build 0f2925
  s
rpm-build 0f2925
rpm-build 0f2925
let int_of_bitset s = 
rpm-build 0f2925
  let n = ref 0 in
rpm-build 0f2925
  for i = 0 to 29 do
rpm-build 0f2925
    if B.is_set s i then
rpm-build 0f2925
      n := !n lor (1 lsl i)
rpm-build 0f2925
  done;
rpm-build 0f2925
  !n
rpm-build 0f2925
rpm-build 0f2925
let bitset_of_int_scale n scl = 
rpm-build 0f2925
  assert (n <= (1 lsl 29));
rpm-build 0f2925
  let s = B.create 30 in
rpm-build 0f2925
  for i = 0 to 29 do
rpm-build 0f2925
    if (n land (1 lsl i)) <> 0 then
rpm-build 0f2925
      B.set s (i*scl)
rpm-build 0f2925
  done;
rpm-build 0f2925
  assert (popcount n = B.count s);
rpm-build 0f2925
  s
rpm-build 0f2925
rpm-build 0f2925
let int_of_bitset_scale s scl = 
rpm-build 0f2925
  let n = ref 0 in
rpm-build 0f2925
  for i = 0 to 29 do
rpm-build 0f2925
    if B.is_set s (i*scl) then
rpm-build 0f2925
      n := !n lor (1 lsl i)
rpm-build 0f2925
  done;
rpm-build 0f2925
  !n
rpm-build 0f2925
rpm-build 0f2925
let test_rnd_creation () =
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let r1 = biased_rnd_28 () in
rpm-build 0f2925
    let s = bitset_of_int r1 in
rpm-build 0f2925
    let c = B.copy s in
rpm-build 0f2925
    assert (int_of_bitset s = r1);
rpm-build 0f2925
    assert (c = s);
rpm-build 0f2925
    assert (B.compare c s = 0);
rpm-build 0f2925
    B.unite c s;
rpm-build 0f2925
    assert (c = s);
rpm-build 0f2925
    B.intersect c (B.empty ());
rpm-build 0f2925
    assert (B.count c = 0);
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_intersect () = 
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let s = bitset_of_int (biased_rnd_28 ()) in
rpm-build 0f2925
    B.intersect s (B.empty ());
rpm-build 0f2925
    assert (B.count s = 0)
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_diff () = 
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let r = biased_rnd_28 () in
rpm-build 0f2925
    let s = bitset_of_int r in
rpm-build 0f2925
    if r <> 0 then
rpm-build 0f2925
      assert (B.count s <> 0);
rpm-build 0f2925
    assert (B.count ((B.diff s s)) = 0);
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_sym_diff () =
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let s = (Random.int 3)+1 in
rpm-build 0f2925
    let r1 = biased_rnd_28 () in
rpm-build 0f2925
    let r2 = biased_rnd_28 () in
rpm-build 0f2925
    let s1 = bitset_of_int_scale r1 s in
rpm-build 0f2925
    let s2 = bitset_of_int_scale r2 s in
rpm-build 0f2925
    assert (int_of_bitset_scale (bitset_of_int_scale r1 s) s = r1);
rpm-build 0f2925
    assert (int_of_bitset_scale (B.sym_diff s1 s2) s = r1 lxor r2);
rpm-build 0f2925
    assert (int_of_bitset_scale (B.sym_diff s2 s1) s = r1 lxor r2);
rpm-build 0f2925
    assert (B.count (B.sym_diff s1 s1) = 0);
rpm-build 0f2925
    assert (B.count (B.sym_diff s2 s2) = 0);
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_compare () =
rpm-build 0f2925
  assert (B.compare (B.empty ()) (B.empty ()) = 0);
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let r1 = biased_rnd_28 () in
rpm-build 0f2925
    let r2 = biased_rnd_28 () in
rpm-build 0f2925
    let s1 = bitset_of_int r1 
rpm-build 0f2925
    and s2 = bitset_of_int r2 in
rpm-build 0f2925
    let sr = B.compare s1 s2
rpm-build 0f2925
    and ir = compare r1 r2 in
rpm-build 0f2925
    assert (sr = ir);
rpm-build 0f2925
    assert (B.compare s1 s1 = 0);
rpm-build 0f2925
    assert (B.compare s2 s2 = 0)
rpm-build 0f2925
  done;
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let scl = (Random.int 15)+1 in
rpm-build 0f2925
    let r1 = biased_rnd_28 () in
rpm-build 0f2925
    let r2 = biased_rnd_28 () in
rpm-build 0f2925
    let s1 = bitset_of_int_scale r1 scl
rpm-build 0f2925
    and s2 = bitset_of_int_scale r2 scl in
rpm-build 0f2925
    let sr = B.compare s1 s2
rpm-build 0f2925
    and ir = compare r1 r2 in
rpm-build 0f2925
    assert (sr = ir)
rpm-build 0f2925
  done;
rpm-build 0f2925
  for i = 1 to 255 do
rpm-build 0f2925
    let s1 = bitset_of_int (i-1) in
rpm-build 0f2925
    let s2 = bitset_of_int i in
rpm-build 0f2925
    assert (B.compare s1 s2 = -1)
rpm-build 0f2925
  done;
rpm-build 0f2925
  for i = 1 to 255 do
rpm-build 0f2925
    let s1 = bitset_of_int (i-1) in
rpm-build 0f2925
    let s2 = bitset_of_int i in
rpm-build 0f2925
    assert (B.compare s1 s2 = -1)
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
module BSSet = Set.Make (struct type t = BitSet.t let compare = B.compare end)
rpm-build 0f2925
rpm-build 0f2925
let test_compare_2 () = 
rpm-build 0f2925
  let nums = List.init 256 Std.identity in
rpm-build 0f2925
  let num_set = 
rpm-build 0f2925
    List.fold_left (fun acc e -> BSSet.add (bitset_of_int e) acc) BSSet.empty nums in
rpm-build 0f2925
  List.iter
rpm-build 0f2925
    (fun e -> 
rpm-build 0f2925
       let bs = bitset_of_int e in
rpm-build 0f2925
       assert (BSSet.mem bs num_set)) nums
rpm-build 0f2925
rpm-build 0f2925
let test_compare_3 () = 
rpm-build 0f2925
  for i = 0 to 63 do
rpm-build 0f2925
    for j = 0 to 63 do
rpm-build 0f2925
      let b1 = B.create ((Random.int 128)+32) in
rpm-build 0f2925
      let b2 = B.create ((Random.int 128)+32) in
rpm-build 0f2925
      set_bitset b1 i;
rpm-build 0f2925
      set_bitset b2 j;
rpm-build 0f2925
      assert (B.compare b1 b2 = compare i j)
rpm-build 0f2925
    done
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_empty () = 
rpm-build 0f2925
  for len = 0 to 63 do
rpm-build 0f2925
    let s = B.empty () in
rpm-build 0f2925
    for i = 0 to len do 
rpm-build 0f2925
      assert (not (B.is_set s i));
rpm-build 0f2925
      B.set s i
rpm-build 0f2925
    done;
rpm-build 0f2925
    assert (not (B.is_set s (len+1)));
rpm-build 0f2925
    for i = 0 to len do 
rpm-build 0f2925
      assert (B.is_set s i)
rpm-build 0f2925
    done
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_exceptions () = 
rpm-build 0f2925
  let expect_exn f =
rpm-build 0f2925
    try 
rpm-build 0f2925
      f ();
rpm-build 0f2925
      false (* Should've raised an exception! *)
rpm-build 0f2925
    with B.Negative_index _ -> true in
rpm-build 0f2925
  let s = B.create 100 in
rpm-build 0f2925
  assert (expect_exn (fun () -> B.set s (-15)));
rpm-build 0f2925
  assert (expect_exn (fun () -> B.unset s (-15)));
rpm-build 0f2925
  assert (expect_exn (fun () -> B.toggle s (-15)));
rpm-build 0f2925
  assert (expect_exn 
rpm-build 0f2925
            (fun () ->
rpm-build 0f2925
               let s = B.create 8 in
rpm-build 0f2925
               B.is_set s (-19)))
rpm-build 0f2925
rpm-build 0f2925
module IS = Set.Make (struct type t = int let compare = compare end)
rpm-build 0f2925
rpm-build 0f2925
let set_of_int n = 
rpm-build 0f2925
  let rec loop accu i =
rpm-build 0f2925
    if i < 30 then
rpm-build 0f2925
      if ((1 lsl i) land n) <> 0 then
rpm-build 0f2925
        loop (IS.add i accu) (i+1)
rpm-build 0f2925
      else 
rpm-build 0f2925
        loop accu (i+1)
rpm-build 0f2925
    else accu in
rpm-build 0f2925
  loop IS.empty 0
rpm-build 0f2925
rpm-build 0f2925
let int_of_set s = 
rpm-build 0f2925
  IS.fold (fun i acc -> (1 lsl i) lor acc) s 0
rpm-build 0f2925
rpm-build 0f2925
let test_set_opers () = 
rpm-build 0f2925
  let rnd_oper () = 
rpm-build 0f2925
    match Random.int 3 with
rpm-build 0f2925
      0 -> (IS.inter, B.inter)
rpm-build 0f2925
    | 1 -> (IS.diff, B.diff)
rpm-build 0f2925
    | 2 -> (IS.union, B.union)
rpm-build 0f2925
    | _ -> assert false in
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let r1 = biased_rnd_28 () in
rpm-build 0f2925
    let r2 = biased_rnd_28 () in
rpm-build 0f2925
    let s1 = set_of_int r1
rpm-build 0f2925
    and s2 = set_of_int r2
rpm-build 0f2925
    and bs1 = bitset_of_int r1 
rpm-build 0f2925
    and bs2 = bitset_of_int r2 in
rpm-build 0f2925
    assert (int_of_set s1 = r1);
rpm-build 0f2925
    assert (int_of_set s2 = r2);
rpm-build 0f2925
    assert (int_of_bitset bs1 = r1);
rpm-build 0f2925
    assert (int_of_bitset bs2 = r2);
rpm-build 0f2925
    let (isop,bsop) = rnd_oper () in
rpm-build 0f2925
    let is = isop s1 s2 
rpm-build 0f2925
    and bs = bsop bs1 bs2 in
rpm-build 0f2925
    let is_int = int_of_set is in
rpm-build 0f2925
    let bs_int = int_of_bitset bs in
rpm-build 0f2925
    assert (is_int = bs_int);
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_unite () =
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let r1 = biased_rnd_28 () in
rpm-build 0f2925
    let s = bitset_of_int r1 in
rpm-build 0f2925
    let c = B.copy s in
rpm-build 0f2925
    assert (int_of_bitset s = r1);
rpm-build 0f2925
    let pop = B.count c in
rpm-build 0f2925
    B.unite c (B.empty ());
rpm-build 0f2925
    assert (B.count c = pop);
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_intersect_2 () =
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let r1 = biased_rnd_28 () in
rpm-build 0f2925
    let s = bitset_of_int r1 in
rpm-build 0f2925
    let c = B.copy s in
rpm-build 0f2925
    assert (int_of_bitset s = r1);
rpm-build 0f2925
    B.intersect c (B.empty ());
rpm-build 0f2925
    assert (B.count c = 0);
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_differentiate () = 
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let r1 = biased_rnd_28 () in
rpm-build 0f2925
    let s = bitset_of_int r1 in
rpm-build 0f2925
    let d = B.copy s in
rpm-build 0f2925
    B.differentiate d s;
rpm-build 0f2925
    assert (B.count d = 0);
rpm-build 0f2925
    for j = 0 to 32 do
rpm-build 0f2925
      B.set s (Random.int 256)
rpm-build 0f2925
    done;
rpm-build 0f2925
    let d = B.copy s in
rpm-build 0f2925
    B.differentiate d (B.empty ());
rpm-build 0f2925
    assert (B.count s = B.count d);
rpm-build 0f2925
    assert (B.compare d s = 0);
rpm-build 0f2925
    B.differentiate d s;
rpm-build 0f2925
    assert (B.count d = 0);
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
(* TODO *)
rpm-build 0f2925
let test_differentiate_sym () = 
rpm-build 0f2925
  for i = 0 to 255 do
rpm-build 0f2925
    let r1 = biased_rnd_28 () in
rpm-build 0f2925
    let r2 = biased_rnd_28 () in
rpm-build 0f2925
    let s = bitset_of_int r1 in
rpm-build 0f2925
    let d = B.copy s in
rpm-build 0f2925
    B.differentiate_sym d s;
rpm-build 0f2925
    assert (B.count d = 0);
rpm-build 0f2925
    for j = 0 to 32 do
rpm-build 0f2925
      B.set s (Random.int 256)
rpm-build 0f2925
    done;
rpm-build 0f2925
    let d = B.copy s in
rpm-build 0f2925
    B.differentiate_sym d (B.empty ());
rpm-build 0f2925
    assert (B.count s = B.count d);
rpm-build 0f2925
    assert (B.compare d s = 0);
rpm-build 0f2925
    B.differentiate_sym d s;
rpm-build 0f2925
    assert (B.count d = 0);
rpm-build 0f2925
rpm-build 0f2925
    let s1 = bitset_of_int r1 
rpm-build 0f2925
    and s2 = bitset_of_int r2 in
rpm-build 0f2925
    let d1 = B.copy s1 in
rpm-build 0f2925
    B.differentiate_sym d1 s2;
rpm-build 0f2925
    assert (r1 lxor r2 = int_of_bitset d1);
rpm-build 0f2925
  done
rpm-build 0f2925
rpm-build 0f2925
let test_bs_1 () = 
rpm-build 0f2925
  let b = BitSet.empty () in
rpm-build 0f2925
  BitSet.set b 8;
rpm-build 0f2925
  BitSet.set b 9;
rpm-build 0f2925
  assert (not (BitSet.is_set b 7));
rpm-build 0f2925
  assert (BitSet.is_set b 8);
rpm-build 0f2925
  assert (BitSet.is_set b 9);
rpm-build 0f2925
  assert (not (BitSet.is_set b 10));
rpm-build 0f2925
  ()
rpm-build 0f2925
rpm-build 0f2925
let test_enum_1 () = 
rpm-build 0f2925
  let b = BitSet.empty () in
rpm-build 0f2925
  BitSet.set b 0;
rpm-build 0f2925
  BitSet.set b 1;
rpm-build 0f2925
  let e = BitSet.enum b in
rpm-build 0f2925
  let a = Enum.get e in
rpm-build 0f2925
  let b = Enum.get e in
rpm-build 0f2925
  assert (Option.get a = 0);
rpm-build 0f2925
  assert (Option.get b = 1);
rpm-build 0f2925
  ()
rpm-build 0f2925
rpm-build 0f2925
let test_enum_2 () = 
rpm-build 0f2925
  let n = 13 in
rpm-build 0f2925
  let b = BitSet.empty () in
rpm-build 0f2925
  for i = 0 to n do
rpm-build 0f2925
    BitSet.set b i
rpm-build 0f2925
  done;
rpm-build 0f2925
  let e = BitSet.enum b in
rpm-build 0f2925
  for i = 0 to n do
rpm-build 0f2925
    let a = Enum.get e in
rpm-build 0f2925
    match a with
rpm-build 0f2925
      Some v -> assert (v = i)
rpm-build 0f2925
    | None -> assert false
rpm-build 0f2925
  done;
rpm-build 0f2925
  assert (Enum.get e = None);
rpm-build 0f2925
  ()
rpm-build 0f2925
rpm-build 0f2925
let test_enum_3 () = 
rpm-build 0f2925
  let b = BitSet.empty () in
rpm-build 0f2925
  BitSet.set b 9;
rpm-build 0f2925
  BitSet.set b 10;
rpm-build 0f2925
  let e = BitSet.enum b in
rpm-build 0f2925
  let i = Enum.get e in
rpm-build 0f2925
  let j = Enum.get e in
rpm-build 0f2925
  assert (Option.get i = 9);
rpm-build 0f2925
  begin
rpm-build 0f2925
    match j with
rpm-build 0f2925
      Some v -> 
rpm-build 0f2925
        assert (v = 10);
rpm-build 0f2925
    | None -> 
rpm-build 0f2925
        assert false (* Should NOT come here! *)
rpm-build 0f2925
  end;
rpm-build 0f2925
  assert (Enum.get e = None);
rpm-build 0f2925
  ()
rpm-build 0f2925
rpm-build 0f2925
(* Bug reported by Pascal Zimmer on Feb 27, 2007.  The latter assert
rpm-build 0f2925
   returned None when it should've returned Some 9. *)
rpm-build 0f2925
let test_enum_regr_pz () = 
rpm-build 0f2925
  let b = BitSet.empty () in
rpm-build 0f2925
  BitSet.set b 8;
rpm-build 0f2925
  BitSet.set b 9;
rpm-build 0f2925
  let e = BitSet.enum b in
rpm-build 0f2925
  let i = Enum.get e in
rpm-build 0f2925
  let j = Enum.get e in
rpm-build 0f2925
  assert (Option.get i = 8);
rpm-build 0f2925
  begin
rpm-build 0f2925
    match j with
rpm-build 0f2925
      Some v -> 
rpm-build 0f2925
        assert (v = 9);
rpm-build 0f2925
    | None -> 
rpm-build 0f2925
        assert false (* Should NOT come here! *)
rpm-build 0f2925
  end;
rpm-build 0f2925
  ()
rpm-build 0f2925
rpm-build 0f2925
rpm-build 0f2925
let () =
rpm-build 0f2925
  Util.register "BitSet" [
rpm-build 0f2925
    "basic", test_bs_1;
rpm-build 0f2925
    "enum_1", test_enum_1;
rpm-build 0f2925
    "enum_2", test_enum_2;
rpm-build 0f2925
    "enum_3", test_enum_3;
rpm-build 0f2925
    "enum_regr_pz", test_enum_regr_pz;
rpm-build 0f2925
    "intersect", test_intersect;
rpm-build 0f2925
    "diff", test_diff;
rpm-build 0f2925
    "sym_diff", test_sym_diff;
rpm-build 0f2925
    "rnd_creation", test_rnd_creation;
rpm-build 0f2925
    "empty", test_empty;
rpm-build 0f2925
    "exceptions", test_exceptions;
rpm-build 0f2925
    "compare", test_compare;
rpm-build 0f2925
    "compare_2", test_compare_2;
rpm-build 0f2925
    "compare_3", test_compare_3;
rpm-build 0f2925
    "set_opers", test_set_opers;
rpm-build 0f2925
    "unite",test_unite;
rpm-build 0f2925
    "intersect_2",test_intersect_2;
rpm-build 0f2925
    "differentiate",test_differentiate;
rpm-build 0f2925
    "differentiate_sym", test_differentiate_sym;
rpm-build 0f2925
  ]