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