Skip to content

Commit 4012d24

Browse files
committed
persistent bit vectors, wip
1 parent 1516aaa commit 4012d24

File tree

5 files changed

+66
-57
lines changed

5 files changed

+66
-57
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ sieve.opt
2222

2323
bench.exe
2424
perf.data
25+
bench_pbv.exe

bench_pbv.ml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
(* sandbox to test performance *)
3+
4+
open Format
5+
6+
let time f x =
7+
let open Unix in
8+
let u = (times()).tms_utime in
9+
let y = f x in
10+
let ut = (times()).tms_utime -. u in
11+
printf "%2.2f@." ut;
12+
y
13+
14+
open Bitv__Pbv
15+
16+
let () = Random.init 42
17+
let n = int_of_string Sys.argv.(1)
18+
19+
module M = Small(struct let size = Sys.int_size end)
20+
open M
21+
let v = init 63 (fun i -> i < n)
22+
let () = printf "v = %a@." print v
23+
let f v =
24+
let s = ref 0 in
25+
iter_subsets (fun v -> s := !s + pop v) v;
26+
printf "sum = %d@." !s
27+
let () = time f v

dune

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,9 @@
3030
(modules bench)
3131
(promote (until-clean))
3232
(libraries unix bitv))
33+
34+
(executable
35+
(name bench_pbv)
36+
(modules bench_pbv)
37+
(promote (until-clean))
38+
(libraries unix bitv))

pbv.ml

Lines changed: 21 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ module type S = sig
6262
val disjoint: t -> t -> bool
6363
val iteri_true: (elt -> unit) -> t -> unit
6464
val foldi_true: (elt -> 'a -> 'a) -> t -> 'a -> 'a
65+
val iter_subsets: (t -> unit) -> t -> unit
6566
val for_all: (elt -> bool) -> t -> bool
6667
val exists: (elt -> bool) -> t -> bool
6768
val filter: (elt -> bool) -> t -> t
@@ -273,7 +274,9 @@ let compute_nlz size x =
273274
let rec loop i = if x land i != 0 then size - 1 - tib i else loop (i lsr 1) in
274275
loop (1 lsl (size - 1))
275276

276-
module Native = struct
277+
module Small(X: sig val size: int end) = struct
278+
279+
let () = if X.size < 0 || X.size > Sys.int_size then invalid_arg "Small"
277280

278281
type t = int (* including the sign bit *)
279282

@@ -285,18 +288,18 @@ module Native = struct
285288
type elt = int
286289

287290
let max_length =
288-
Sys.int_size
291+
X.size
289292

290293
let length _v =
291-
Sys.int_size
294+
X.size
292295

293296
let make _n b =
294-
if b then -1 else 0
297+
if b then 1 lsl X.size - 1 else 0
295298

296299
let init _n f =
297300
let rec build v i = if i < 0 then v else
298301
let v = if f i then (v lsl 1) lor 1 else v lsl 1 in build v (i-1) in
299-
build 0 (Sys.int_size - 1)
302+
build 0 (X.size - 1)
300303

301304
let unsafe_get v i =
302305
(v lsr i) land 1 <> 0
@@ -333,7 +336,7 @@ module Native = struct
333336
let bw_or = (lor)
334337
let bw_and = (land)
335338
let bw_xor = (lxor)
336-
let bw_not = (lnot)
339+
let bw_not v = (lnot v) land (1 lsl X.size - 1)
337340

338341
let ntz v = compute_ntz max_length v
339342
let nlz v = compute_nlz max_length v
@@ -401,6 +404,12 @@ module Native = struct
401404
if v == 0 then acc else
402405
let i = v land (-v) in foldi_true_ofs f ofs (v - i) (f (ofs + tib i) acc)
403406

407+
let iter_subsets f v =
408+
let rec iter s v =
409+
if v = 0 then f s else (
410+
let b = v land (-v) in let v = v - b in iter (s + b) v; iter s v) in
411+
iter 0 v
412+
404413
let rec for_all p v =
405414
v == 0 || let i = v land (-v) in p (tib i) && for_all p (v - i)
406415

@@ -465,48 +474,7 @@ module Native = struct
465474

466475
end
467476

468-
module Small(X: sig val size: int end) : S = struct
469-
include Native
470-
471-
let max_length =
472-
X.size
473-
474-
let length _v =
475-
X.size
476-
477-
let make n b =
478-
if n <> X.size then invalid_arg "make";
479-
if b then 1 lsl X.size - 1 else 0
480-
481-
let init _n f =
482-
let rec build v i = if i < 0 then v else
483-
let v = if f i then (v lsl 1) lor 1 else v lsl 1 in build v (i-1) in
484-
build 0 (X.size - 1)
485-
486-
let bw_not v = (lnot v) land (1 lsl X.size - 1)
487-
488-
let ntz v = compute_ntz max_length v
489-
let nlz v = compute_nlz max_length v
490-
491-
include SetOps(struct
492-
type t_ = t type t = t_
493-
let make = make
494-
let length = length
495-
let is_empty = is_empty
496-
let pop = pop
497-
let ntz = ntz
498-
let nlz = nlz
499-
let get = get
500-
let unsafe_get = unsafe_get
501-
let set = set
502-
let unsafe_set = unsafe_set
503-
let bw_or = bw_or
504-
let bw_and = bw_and
505-
let bw_xor = bw_xor
506-
let bw_not = bw_not
507-
let elements = elements
508-
end)
509-
end
477+
module Native = Small(struct let size = Sys.int_size end)
510478

511479
module Large : S = struct
512480

@@ -757,8 +725,13 @@ module Large : S = struct
757725
in
758726
fold 0 acc v
759727

728+
let iter_subsets _f _v =
729+
assert false (*TODO*)
730+
760731
end
761732

733+
(* TODO: module FixedSize for large bit vectors with a fixed size *)
734+
762735
let fixed_size n : (module S) =
763736
if n = Sys.int_size then
764737
(module Native)

pbv.mli

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module type S = sig
3434
val set: t -> int -> bool -> t
3535
val iteri: (int -> bool -> unit) -> t -> unit
3636
val foldi: (int -> bool -> 'a -> 'a) -> t -> 'a -> 'a
37-
(* TODO: fill, blit, sub, append *)
37+
(* TODO: fill, blit, sub, append, random *)
3838

3939
(** Bit vector interface *)
4040

@@ -87,6 +87,7 @@ module type S = sig
8787
val disjoint: t -> t -> bool
8888
val iteri_true: (elt -> unit) -> t -> unit
8989
val foldi_true: (elt -> 'a -> 'a) -> t -> 'a -> 'a
90+
val iter_subsets: (t -> unit) -> t -> unit
9091
val for_all: (elt -> bool) -> t -> bool
9192
val exists: (elt -> bool) -> t -> bool
9293
val filter: (elt -> bool) -> t -> t
@@ -110,17 +111,18 @@ module type S = sig
110111
val of_seq: elt Seq.t -> t
111112
val print_set: Format.formatter -> t -> unit
112113
(** prints a bit vector as a set, using notation [{x1,x2,...,xn}]. *)
113-
(* TODO iter_subsets *)
114114
end
115115

116-
module Native : S
117-
(** Bit vectors of size [Sys.int_size], implemented using a machine integer.
118-
Note: The size parameter of [empty] and [full] is ignored,
119-
and operations [sub] and [append] are not supported. *)
120-
121116
module Small(X: sig val size: int end) : S
122-
(** Bit vectors of size at most [Sys.int_size], implemented using a
123-
machine integer. *)
117+
(** Bit vectors of fixed size not exceeding [Sys.int_size],
118+
implemented using a machine integer.
119+
120+
Note: The size parameter of [empty] and [full] is ignored, and
121+
operations [sub] and [append] are not supported. *)
122+
123+
module Native : S
124+
(** Bit vectors of size [Sys.int_size], implemented using a machine
125+
integer. *)
124126

125127
module Large : S
126128
(** Bit vectors of arbitrary size, up to [2**31 - 1]. *)

0 commit comments

Comments
 (0)