continue removal of CCGen/CCsequence

This commit is contained in:
Simon Cruanes 2014-12-13 03:11:16 +01:00
parent d1c00657b2
commit d0c3af5492
48 changed files with 415 additions and 417 deletions

12
_oasis
View file

@ -86,12 +86,12 @@ Library "containers_advanced"
Modules: CCLinq, CCBatch, CCCat, CCMonadIO Modules: CCLinq, CCBatch, CCCat, CCMonadIO
FindlibName: advanced FindlibName: advanced
FindlibParent: containers FindlibParent: containers
BuildDepends: containers BuildDepends: containers, sequence
Library "containers_pervasives" Library "containers_pervasives"
Path: pervasives Path: pervasives
Modules: CCPervasives Modules: CCPervasives
BuildDepends: containers, BuildDepends: containers
FindlibName: pervasives FindlibName: pervasives
FindlibParent: containers FindlibParent: containers
@ -185,7 +185,7 @@ Executable run_benchs
Build$: flag(bench) && flag(misc) Build$: flag(bench) && flag(misc)
MainIs: run_benchs.ml MainIs: run_benchs.ml
BuildDepends: containers, containers.misc, containers.advanced, BuildDepends: containers, containers.misc, containers.advanced,
containers.string, benchmark containers.string, sequence, gen, benchmark
Executable bench_hash Executable bench_hash
Path: benchs/ Path: benchs/
@ -201,7 +201,7 @@ Executable bench_conv
CompiledObject: native CompiledObject: native
Build$: flag(bench) Build$: flag(bench)
MainIs: bench_conv.ml MainIs: bench_conv.ml
BuildDepends: containers,benchmark BuildDepends: containers,benchmark,gen
Executable test_levenshtein Executable test_levenshtein
Path: tests/ Path: tests/
@ -236,7 +236,7 @@ Executable run_qtest
MainIs: run_qtest.ml MainIs: run_qtest.ml
Build$: flag(tests) Build$: flag(tests)
BuildDepends: containers, containers.misc, containers.string, BuildDepends: containers, containers.misc, containers.string,
oUnit, QTest2Lib sequence, gen, oUnit, QTest2Lib
Executable run_tests Executable run_tests
Path: tests/ Path: tests/
@ -244,7 +244,7 @@ Executable run_tests
CompiledObject: native CompiledObject: native
MainIs: run_tests.ml MainIs: run_tests.ml
Build$: flag(tests) && flag(misc) Build$: flag(tests) && flag(misc)
BuildDepends: containers, oUnit, qcheck, containers.misc BuildDepends: containers, oUnit, sequence, gen, qcheck, containers.misc
Test all Test all
Command: make test-all Command: make test-all

View file

@ -43,7 +43,7 @@ let _error_of_exn f = try `Ok (f ()) with ExitWithError s -> `Error
type 'a collection = type 'a collection =
| Seq : 'a sequence -> 'a collection | Seq : 'a sequence -> 'a collection
| List : 'a list -> 'a collection | List : 'a list -> 'a collection
| Set : (module CCSequence.Set.S | Set : (module Sequence.Set.S
with type elt = 'a and type t = 'b) * 'b -> 'a collection with type elt = 'a and type t = 'b) * 'b -> 'a collection
module PMap = struct module PMap = struct
@ -103,7 +103,7 @@ module PMap = struct
} }
let make_cmp (type key) ?(cmp=Pervasives.compare) () = let make_cmp (type key) ?(cmp=Pervasives.compare) () =
let module M = CCSequence.Map.Make(struct let module M = Sequence.Map.Make(struct
type t = key type t = key
let compare = cmp let compare = cmp
end) in end) in
@ -167,26 +167,26 @@ module PMap = struct
| None -> None | None -> None
| Some v -> Some (f v) | Some v -> Some (f v)
); );
to_seq = CCSequence.map (fun (x,y) -> x, f y) m.to_seq; to_seq = Sequence.map (fun (x,y) -> x, f y) m.to_seq;
fold = (fun f' acc -> fold = (fun f' acc ->
m.fold (fun acc x y -> f' acc x (f y)) acc m.fold (fun acc x y -> f' acc x (f y)) acc
); );
} }
let to_list m = CCSequence.to_rev_list m.to_seq let to_list m = Sequence.to_rev_list m.to_seq
let to_coll m = Seq m.to_seq let to_coll m = Seq m.to_seq
let reverse ~build m = let reverse ~build m =
let build = make ~build () in let build = make ~build () in
let seq = CCSequence.map (fun (x,y) -> y,x) (to_seq m) in let seq = Sequence.map (fun (x,y) -> y,x) (to_seq m) in
multimap_of_seq ~build seq multimap_of_seq ~build seq
let reverse_multimap ~build m = let reverse_multimap ~build m =
let build = make ~build () in let build = make ~build () in
let seq = to_seq m in let seq = to_seq m in
let seq = CCSequence.flat_map let seq = Sequence.flat_map
(fun (x,l) -> CCSequence.map (fun y -> y,x) (CCSequence.of_list l) (fun (x,l) -> Sequence.map (fun y -> y,x) (Sequence.of_list l)
) seq ) seq
in in
multimap_of_seq ~build seq multimap_of_seq ~build seq
@ -211,10 +211,10 @@ type ('a,'b) group_join_descr = {
module Coll = struct module Coll = struct
let of_seq s = Seq s let of_seq s = Seq s
let of_list l = List l let of_list l = List l
let of_array a = Seq (CCSequence.of_array a) let of_array a = Seq (Sequence.of_array a)
let set_of_seq (type elt) ?(cmp=Pervasives.compare) seq = let set_of_seq (type elt) ?(cmp=Pervasives.compare) seq =
let module S = CCSequence.Set.Make(struct let module S = Sequence.Set.Make(struct
type t = elt type t = elt
let compare = cmp let compare = cmp
end) in end) in
@ -225,15 +225,15 @@ module Coll = struct
| Seq s -> s | Seq s -> s
| List l -> (fun k -> List.iter k l) | List l -> (fun k -> List.iter k l)
| Set (m, set) -> | Set (m, set) ->
let module S = (val m : CCSequence.Set.S let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in with type elt = elt and type t = 'b) in
S.to_seq set S.to_seq set
let to_list (type elt) = function let to_list (type elt) = function
| Seq s -> CCSequence.to_list s | Seq s -> Sequence.to_list s
| List l -> l | List l -> l
| Set (m, set) -> | Set (m, set) ->
let module S = (val m : CCSequence.Set.S let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in with type elt = elt and type t = 'b) in
S.elements set S.elements set
@ -245,30 +245,30 @@ module Coll = struct
let fold (type elt) f acc c = match c with let fold (type elt) f acc c = match c with
| List l -> List.fold_left f acc l | List l -> List.fold_left f acc l
| Seq s -> CCSequence.fold f acc s | Seq s -> Sequence.fold f acc s
| Set (m, set) -> | Set (m, set) ->
let module S = (val m : CCSequence.Set.S let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in with type elt = elt and type t = 'b) in
S.fold (fun x acc -> f acc x) set acc S.fold (fun x acc -> f acc x) set acc
let map f c = let map f c =
_fmap ~lst:(List.map f) ~seq:(CCSequence.map f) c _fmap ~lst:(List.map f) ~seq:(Sequence.map f) c
let filter p c = let filter p c =
_fmap ~lst:(List.filter p) ~seq:(CCSequence.filter p) c _fmap ~lst:(List.filter p) ~seq:(Sequence.filter p) c
let flat_map f c = let flat_map f c =
let c' = to_seq c in let c' = to_seq c in
Seq (CCSequence.flatMap (fun x -> to_seq (f x)) c') Seq (Sequence.flatMap (fun x -> to_seq (f x)) c')
let filter_map f c = let filter_map f c =
_fmap ~lst:(CCList.filter_map f) ~seq:(CCSequence.fmap f) c _fmap ~lst:(CCList.filter_map f) ~seq:(Sequence.fmap f) c
let size (type elt) = function let size (type elt) = function
| List l -> List.length l | List l -> List.length l
| Seq s -> CCSequence.length s | Seq s -> Sequence.length s
| Set (m, set) -> | Set (m, set) ->
let module S = (val m : CCSequence.Set.S let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in with type elt = elt and type t = 'b) in
S.cardinal set S.cardinal set
@ -278,12 +278,12 @@ module Coll = struct
| List [] -> fail () | List [] -> fail ()
| List (x::_) -> x | List (x::_) -> x
| Seq s -> | Seq s ->
begin match CCSequence.to_list (CCSequence.take 1 s) with begin match Sequence.to_list (Sequence.take 1 s) with
| [x] -> x | [x] -> x
| _ -> fail () | _ -> fail ()
end end
| Set (m, set) -> | Set (m, set) ->
let module S = (val m : CCSequence.Set.S let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in with type elt = elt and type t = 'b) in
try S.choose set with Not_found -> fail () try S.choose set with Not_found -> fail ()
@ -292,7 +292,7 @@ module Coll = struct
with ExitWithError s -> `Error s with ExitWithError s -> `Error s
let take n c = let take n c =
_fmap ~lst:(CCList.take n) ~seq:(CCSequence.take n) c _fmap ~lst:(CCList.take n) ~seq:(Sequence.take n) c
exception MySurpriseExit exception MySurpriseExit
@ -308,7 +308,7 @@ module Coll = struct
let sort cmp c = match c with let sort cmp c = match c with
| List l -> List (List.sort cmp l) | List l -> List (List.sort cmp l)
| Seq s -> List (List.sort cmp (CCSequence.to_rev_list s)) | Seq s -> List (List.sort cmp (Sequence.to_rev_list s))
| _ -> set_of_seq ~cmp (to_seq c) | _ -> set_of_seq ~cmp (to_seq c)
let search obj c = let search obj c =
@ -328,9 +328,9 @@ module Coll = struct
let contains (type elt) ~eq x c = match c with let contains (type elt) ~eq x c = match c with
| List l -> List.exists (eq x) l | List l -> List.exists (eq x) l
| Seq s -> CCSequence.exists (eq x) s | Seq s -> Sequence.exists (eq x) s
| Set (m, set) -> | Set (m, set) ->
let module S = (val m : CCSequence.Set.S let module S = (val m : Sequence.Set.S
with type elt = elt and type t = 'b) in with type elt = elt and type t = 'b) in
(* XXX: here we don't use the equality relation *) (* XXX: here we don't use the equality relation *)
S.mem x set S.mem x set
@ -338,10 +338,10 @@ module Coll = struct
let do_join ~join c1 c2 = let do_join ~join c1 c2 =
let build1 = let build1 =
let seq = to_seq c1 in let seq = to_seq c1 in
let seq = CCSequence.map (fun x -> join.join_key1 x, x) seq in let seq = Sequence.map (fun x -> join.join_key1 x, x) seq in
PMap.multimap_of_seq ~build:(PMap.make ~build:join.join_build ()) seq PMap.multimap_of_seq ~build:(PMap.make ~build:join.join_build ()) seq
in in
let l = CCSequence.fold let l = Sequence.fold
(fun acc y -> (fun acc y ->
let key = join.join_key2 y in let key = join.join_key2 y in
match PMap.get build1 key with match PMap.get build1 key with
@ -373,14 +373,14 @@ module Coll = struct
let do_product c1 c2 = let do_product c1 c2 =
let s1 = to_seq c1 and s2 = to_seq c2 in let s1 = to_seq c1 and s2 = to_seq c2 in
of_seq (CCSequence.product s1 s2) of_seq (Sequence.product s1 s2)
let do_union ~build c1 c2 = let do_union ~build c1 c2 =
let build = PMap.make ~build () in let build = PMap.make ~build () in
to_seq c1 (fun x -> PMap.add build x ()); to_seq c1 (fun x -> PMap.add build x ());
to_seq c2 (fun x -> PMap.add build x ()); to_seq c2 (fun x -> PMap.add build x ());
let seq = PMap.to_seq (PMap.build_get build) in let seq = PMap.to_seq (PMap.build_get build) in
of_seq (CCSequence.map fst seq) of_seq (Sequence.map fst seq)
type inter_status = type inter_status =
| InterLeft | InterLeft
@ -408,7 +408,7 @@ module Coll = struct
let map = PMap.build_get build in let map = PMap.build_get build in
(* output elements of [c1] not in [map] *) (* output elements of [c1] not in [map] *)
let seq = to_seq c1 in let seq = to_seq c1 in
of_seq (CCSequence.filter (fun x -> not (PMap.mem map x)) seq) of_seq (Sequence.filter (fun x -> not (PMap.mem map x)) seq)
end end
(** {2 Query operators} *) (** {2 Query operators} *)
@ -478,22 +478,22 @@ let of_array a =
Start (Coll.of_array a) Start (Coll.of_array a)
let of_array_i a = let of_array_i a =
Start (Coll.of_seq (CCSequence.of_array_i a)) Start (Coll.of_seq (Sequence.of_array_i a))
let of_hashtbl h = let of_hashtbl h =
Start (Coll.of_seq (CCSequence.of_hashtbl h)) Start (Coll.of_seq (Sequence.of_hashtbl h))
let of_seq seq = let of_seq seq =
Start (Coll.of_seq seq) Start (Coll.of_seq seq)
let of_queue q = let of_queue q =
Start (Coll.of_seq (CCSequence.of_queue q)) Start (Coll.of_seq (Sequence.of_queue q))
let of_stack s = let of_stack s =
Start (Coll.of_seq (CCSequence.of_stack s)) Start (Coll.of_seq (Sequence.of_stack s))
let of_string s = let of_string s =
Start (Coll.of_seq (CCSequence.of_str s)) Start (Coll.of_seq (Sequence.of_str s))
(** {6 Execution} *) (** {6 Execution} *)
@ -553,7 +553,7 @@ let _do_unary : type a b. (a,b) unary -> a -> b
| Fold (f, acc) -> Coll.fold f acc c | Fold (f, acc) -> Coll.fold f acc c
| FoldMap (f, acc) -> PMap.fold f acc c | FoldMap (f, acc) -> PMap.fold f acc c
| Reduce (safety, start, mix, stop) -> | Reduce (safety, start, mix, stop) ->
let acc = CCSequence.fold let acc = Sequence.fold
(fun acc x -> match acc with (fun acc x -> match acc with
| None -> Some (start x) | None -> Some (start x)
| Some acc -> Some (mix x acc) | Some acc -> Some (mix x acc)
@ -578,7 +578,7 @@ let _do_unary : type a b. (a,b) unary -> a -> b
| Get (Implicit, k) -> PMap.get_exn c k | Get (Implicit, k) -> PMap.get_exn c k
| Get (Explicit, k) -> PMap.get_err c k | Get (Explicit, k) -> PMap.get_err c k
| GroupBy (build,f) -> | GroupBy (build,f) ->
let seq = CCSequence.map (fun x -> f x, x) (Coll.to_seq c) in let seq = Sequence.map (fun x -> f x, x) (Coll.to_seq c) in
PMap.multimap_of_seq ~build:(PMap.make ~build ()) seq PMap.multimap_of_seq ~build:(PMap.make ~build ()) seq
| Contains (eq, x) -> Coll.contains ~eq x c | Contains (eq, x) -> Coll.contains ~eq x c
| Count build -> | Count build ->
@ -591,7 +591,7 @@ let _do_binary : type a b c. (a, b, c) binary -> a -> b -> c
| GroupJoin gjoin -> Coll.do_group_join ~gjoin c1 c2 | GroupJoin gjoin -> Coll.do_group_join ~gjoin c1 c2
| Product -> Coll.do_product c1 c2 | Product -> Coll.do_product c1 c2
| Append -> | Append ->
Coll.of_seq (CCSequence.append (Coll.to_seq c1) (Coll.to_seq c2)) Coll.of_seq (Sequence.append (Coll.to_seq c1) (Coll.to_seq c2))
| SetOp (Inter,build) -> Coll.do_inter ~build c1 c2 | SetOp (Inter,build) -> Coll.do_inter ~build c1 c2
| SetOp (Union,build) -> Coll.do_union ~build c1 c2 | SetOp (Union,build) -> Coll.do_union ~build c1 c2
| SetOp (Diff,build) -> Coll.do_diff ~build c1 c2 | SetOp (Diff,build) -> Coll.do_diff ~build c1 c2
@ -695,8 +695,8 @@ module M = struct
let flatten q = let flatten q =
let f m = let f m =
let seq = CCSequence.flat_map let seq = Sequence.flat_map
(fun (k,v) -> CCSequence.map (fun v' -> k,v') (Coll.to_seq v)) (fun (k,v) -> Sequence.map (fun v' -> k,v') (Coll.to_seq v))
m.PMap.to_seq m.PMap.to_seq
in Coll.of_seq seq in Coll.of_seq seq
in in
@ -704,8 +704,8 @@ module M = struct
let flatten' q = let flatten' q =
let f m = let f m =
let seq = CCSequence.flatMap let seq = Sequence.flatMap
(fun (k,v) -> CCSequence.map (fun v' -> k,v') (CCSequence.of_list v)) (fun (k,v) -> Sequence.map (fun v' -> k,v') (Sequence.of_list v))
m.PMap.to_seq m.PMap.to_seq
in Coll.of_seq seq in Coll.of_seq seq
in in
@ -885,16 +885,16 @@ let to_array q =
QueryMap ((fun c -> Array.of_list (Coll.to_list c)), q) QueryMap ((fun c -> Array.of_list (Coll.to_list c)), q)
let to_seq q = let to_seq q =
QueryMap ((fun c -> CCSequence.persistent (Coll.to_seq c)), q) QueryMap ((fun c -> Sequence.persistent (Coll.to_seq c)), q)
let to_hashtbl q = let to_hashtbl q =
QueryMap ((fun c -> CCSequence.to_hashtbl (Coll.to_seq c)), q) QueryMap ((fun c -> Sequence.to_hashtbl (Coll.to_seq c)), q)
let to_queue q = let to_queue q =
QueryMap ((fun c q -> CCSequence.to_queue q (Coll.to_seq c)), q) QueryMap ((fun c q -> Sequence.to_queue q (Coll.to_seq c)), q)
let to_stack q = let to_stack q =
QueryMap ((fun c s -> CCSequence.to_stack s (Coll.to_seq c)), q) QueryMap ((fun c s -> Sequence.to_stack s (Coll.to_seq c)), q)
module L = struct module L = struct
let of_list l = Start (Coll.of_list l) let of_list l = Start (Coll.of_list l)
@ -909,7 +909,7 @@ module AdaptSet(S : Set.S) = struct
return (Coll.of_seq (fun k -> S.iter k set)) return (Coll.of_seq (fun k -> S.iter k set))
let to_set q = let to_set q =
let f c = CCSequence.fold (fun set x -> S.add x set) S.empty (Coll.to_seq c) in let f c = Sequence.fold (fun set x -> S.add x set) S.empty (Coll.to_seq c) in
query_map f q query_map f q
let run q = run (to_set q) let run q = run (to_set q)
@ -932,7 +932,7 @@ module AdaptMap(M : Map.S) = struct
let to_map q = let to_map q =
let f c = let f c =
CCSequence.fold (fun m (x,y) -> M.add x y m) M.empty (Coll.to_seq c) Sequence.fold (fun m (x,y) -> M.add x y m) M.empty (Coll.to_seq c)
in in
query_map f q query_map f q
@ -1008,13 +1008,13 @@ module IO = struct
query_map f q query_map f q
let lines' q = let lines' q =
let f s = lazy (CCSequence.to_list (_lines s 0)) in let f s = lazy (Sequence.to_list (_lines s 0)) in
lazy_ (query_map f q) lazy_ (query_map f q)
let _join ~sep ?(stop="") l = let _join ~sep ?(stop="") l =
let buf = Buffer.create 128 in let buf = Buffer.create 128 in
let seq = Coll.to_seq l in let seq = Coll.to_seq l in
CCSequence.iteri Sequence.iteri
(fun i x -> (fun i x ->
if i>0 then Buffer.add_string buf sep; if i>0 then Buffer.add_string buf sep;
Buffer.add_string buf x) Buffer.add_string buf x)
@ -1035,7 +1035,7 @@ module IO = struct
let out_lines oc q = let out_lines oc q =
let x = run_exn q in let x = run_exn q in
CCSequence.iter (fun l -> output_string oc l; output_char oc '\n') (Coll.to_seq x) Sequence.iter (fun l -> output_string oc l; output_char oc '\n') (Coll.to_seq x)
let to_file_exn filename q = let to_file_exn filename q =
_with_file_out filename (fun oc -> out oc q) _with_file_out filename (fun oc -> out oc q)

View file

@ -79,11 +79,11 @@ let () =
bench_list [1,2; 3,4; 5,6; 7,8; 9,10]; bench_list [1,2; 3,4; 5,6; 7,8; 9,10];
let open CCFun in let open CCFun in
let l = CCGen.(1 -- 100 |> map (fun x->x,x) |> to_rev_list) in let l = Gen.(1 -- 100 |> map (fun x->x,x) |> to_rev_list) in
Printf.printf "list of %d elements...\n" (List.length l); Printf.printf "list of %d elements...\n" (List.length l);
bench_list l; bench_list l;
let l = CCGen.(repeat Point.p |> take 10 |> to_rev_list) in let l = Gen.(repeat Point.p |> take 10 |> to_rev_list) in
Printf.printf "list of %d points...\n" (List.length l); Printf.printf "list of %d points...\n" (List.length l);
bench_point_list l; bench_point_list l;

View file

@ -480,8 +480,8 @@ module Iter = struct
(** {2 Sequence/Gen} *) (** {2 Sequence/Gen} *)
let bench_fold n = let bench_fold n =
let seq () = CCSequence.fold (+) 0 CCSequence.(0 --n) in let seq () = Sequence.fold (+) 0 Sequence.(0 --n) in
let gen () = CCGen.fold (+) 0 CCGen.(0 -- n) in let gen () = Gen.fold (+) 0 Gen.(0 -- n) in
let klist () = CCKList.fold (+) 0 CCKList.(0 -- n) in let klist () = CCKList.fold (+) 0 CCKList.(0 -- n) in
CCBench.throughputN 3 CCBench.throughputN 3
[ "sequence.fold", seq, (); [ "sequence.fold", seq, ();
@ -490,10 +490,10 @@ module Iter = struct
] ]
let bench_flat_map n = let bench_flat_map n =
let seq () = CCSequence.( let seq () = Sequence.(
0 -- n |> flat_map (fun x -> x-- (x+10)) |> fold (+) 0 0 -- n |> flat_map (fun x -> x-- (x+10)) |> fold (+) 0
) )
and gen () = CCGen.( and gen () = Gen.(
0 -- n |> flat_map (fun x -> x-- (x+10)) |> fold (+) 0 0 -- n |> flat_map (fun x -> x-- (x+10)) |> fold (+) 0
) )
and klist () = CCKList.( and klist () = CCKList.(
@ -509,12 +509,12 @@ module Iter = struct
let bench_iter n = let bench_iter n =
let seq () = let seq () =
let i = ref 2 in let i = ref 2 in
CCSequence.( Sequence.(
1 -- n |> iter (fun x -> i := !i * x) 1 -- n |> iter (fun x -> i := !i * x)
) )
and gen () = and gen () =
let i = ref 2 in let i = ref 2 in
CCGen.( Gen.(
1 -- n |> iter (fun x -> i := !i * x) 1 -- n |> iter (fun x -> i := !i * x)
) )
and klist () = and klist () =

View file

@ -172,7 +172,7 @@ let iter_true bv f =
done done
(*$T (*$T
of_list [1;5;7] |> iter_true |> CCSequence.to_list |> List.sort CCOrd.compare = [1;5;7] of_list [1;5;7] |> iter_true |> Sequence.to_list |> List.sort CCOrd.compare = [1;5;7]
*) *)
let to_list bv = let to_list bv =

View file

@ -28,6 +28,50 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
type 'a gen = unit -> 'a option (** See {!CCGen} *) type 'a gen = unit -> 'a option (** See {!CCGen} *)
let gen_singleton x =
let done_ = ref false in
fun () -> if !done_ then None else (done_ := true; Some x)
let gen_filter_map f gen =
(* tailrec *)
let rec next () =
match gen() with
| None -> None
| Some x ->
match f x with
| None -> next()
| (Some _) as res -> res
in next
let gen_of_array arr =
let r = ref 0 in
fun () ->
if !r = Array.length arr then None
else (
let x = arr.(!r) in
incr r;
Some x
)
let gen_flat_map f next_elem =
let state = ref `Init in
let rec next() =
match !state with
| `Init -> get_next_gen()
| `Run gen ->
begin match gen () with
| None -> get_next_gen ()
| (Some _) as x -> x
end
| `Stop -> None
and get_next_gen() = match next_elem() with
| None -> state:=`Stop; None
| Some x ->
try state := `Run (f x); next()
with e -> state := `Stop; raise e
in
next
let with_in ?(mode=0o644) ?(flags=[]) filename f = let with_in ?(mode=0o644) ?(flags=[]) filename f =
let ic = open_in_gen flags mode filename in let ic = open_in_gen flags mode filename in
try try
@ -165,8 +209,8 @@ module File = struct
if Sys.is_directory d if Sys.is_directory d
then then
let arr = Sys.readdir d in let arr = Sys.readdir d in
CCGen.of_array arr gen_of_array arr
else CCGen.empty else fun () -> None
let cons_ x tl = let cons_ x tl =
let first=ref true in let first=ref true in
@ -180,19 +224,19 @@ module File = struct
if Sys.is_directory d if Sys.is_directory d
then then
let arr = Sys.readdir d in let arr = Sys.readdir d in
let tail = CCGen.of_array arr in let tail = gen_of_array arr in
let tail = CCGen.flat_map let tail = gen_flat_map
(fun s -> walk (Filename.concat d s)) (fun s -> walk (Filename.concat d s))
tail tail
in cons_ (`Dir,d) tail in cons_ (`Dir,d) tail
else CCGen.singleton (`File, d) else gen_singleton (`File, d)
type walk_item = [`File | `Dir] * t type walk_item = [`File | `Dir] * t
let read_dir ?(recurse=false) d = let read_dir ?(recurse=false) d =
if recurse if recurse
then then
CCGen.filter_map gen_filter_map
(function (function
| `File, f -> Some f | `File, f -> Some f
| `Dir, _ -> None | `Dir, _ -> None

View file

@ -451,7 +451,7 @@ let of_seq ?(init=create ()) seq =
init init
(*$T (*$T
of_seq CCSequence.(1 -- 10) |> to_list = CCList.(1 -- 10) of_seq Sequence.(1 -- 10) |> to_list = CCList.(1 -- 10)
*) *)
let to_seq v k = iter k v let to_seq v k = iter k v
@ -524,7 +524,7 @@ let to_gen v =
) else None ) else None
(*$T (*$T
let v = (1--10) in to_list v = CCGen.to_list (to_gen v) let v = (1--10) in to_list v = Gen.to_list (to_gen v)
*) *)
let of_klist ?(init=create ()) l = let of_klist ?(init=create ()) l =

View file

@ -1,7 +1,7 @@
(** Compute the memory footprint of a value (and its subvalues). Reference is (** Compute the memory footprint of a value (and its subvalues). Reference is
http://rwmj.wordpress.com/2009/08/05/ocaml-internals-part-2-strings-and-other-types/ *) http://rwmj.wordpress.com/2009/08/05/ocaml-internals-part-2-strings-and-other-types/ *)
module Sequence = CCSequence
(** A graph vertex is an Obj.t value *) (** A graph vertex is an Obj.t value *)
let graph = let graph =

View file

@ -25,6 +25,8 @@ for any direct, indirect, incidental, special, exemplary, or consequential
(** {1 Abstract set/relation} *) (** {1 Abstract set/relation} *)
type 'a sequence = ('a -> unit) -> unit
type 'a t = { type 'a t = {
mem : 'a -> bool; mem : 'a -> bool;
iter : ('a -> unit) -> unit; iter : ('a -> unit) -> unit;
@ -102,8 +104,7 @@ let product s1 s2 =
let cardinal () = s1.cardinal () * s2.cardinal () in let cardinal () = s1.cardinal () * s2.cardinal () in
{ mem; iter; cardinal; } { mem; iter; cardinal; }
let to_seq set = let to_seq set k = set.iter k
CCSequence.from_iter (fun k -> set.iter k)
let to_list set = let to_list set =
let l = ref [] in let l = ref [] in
@ -154,7 +155,7 @@ let builder_cmp (type k) ?(cmp=Pervasives.compare) () =
mk_builder ~add ~get mk_builder ~add ~get
let of_seq_builder ~builder seq = let of_seq_builder ~builder seq =
CCSequence.iter builder.add seq; seq builder.add;
builder.get () builder.get ()
let of_seq_hash ?eq ?hash seq = let of_seq_hash ?eq ?hash seq =
@ -165,7 +166,7 @@ let of_seq_cmp ?cmp seq =
let b = builder_cmp ?cmp () in let b = builder_cmp ?cmp () in
of_seq_builder b seq of_seq_builder b seq
let of_list l = of_seq_hash (CCSequence.of_list l) let of_list l = of_seq_hash (fun k -> List.iter k l)
let map ?(builder=builder_hash ()) set ~f = let map ?(builder=builder_hash ()) set ~f =
set.iter set.iter
@ -202,7 +203,7 @@ module MakeHash(X : Hashtbl.HashedType) = struct
let of_seq ?(size=5) seq = let of_seq ?(size=5) seq =
let h = Hashtbl.create size in let h = Hashtbl.create size in
CCSequence.iter (fun x -> Hashtbl.add h x ()) seq; seq (fun x -> Hashtbl.add h x ());
let mem x = Hashtbl.mem h x in let mem x = Hashtbl.mem h x in
let iter k = Hashtbl.iter (fun x () -> k x) h in let iter k = Hashtbl.iter (fun x () -> k x) h in
let cardinal () = Hashtbl.length h in let cardinal () = Hashtbl.length h in
@ -220,8 +221,9 @@ module MakeSet(S : Set.S) = struct
mk_generic ~cardinal ~mem ~iter mk_generic ~cardinal ~mem ~iter
let of_seq ?(init=S.empty) seq = let of_seq ?(init=S.empty) seq =
let set = CCSequence.fold (fun s x -> S.add x s) init seq in let set = ref init in
of_set set seq (fun x -> set := S.add x !set);
of_set !set
let to_set set = let to_set set =
fold set S.empty (fun set x -> S.add x set) fold set S.empty (fun set x -> S.add x set)

View file

@ -25,6 +25,8 @@ for any direct, indirect, incidental, special, exemplary, or consequential
(** {1 Abstract set/relation} *) (** {1 Abstract set/relation} *)
type 'a sequence = ('a -> unit) -> unit
type 'a t type 'a t
val empty : 'a t val empty : 'a t
@ -67,7 +69,7 @@ val intersection : 'a t -> 'a t -> 'a t
val product : 'a t -> 'b t -> ('a * 'b) t val product : 'a t -> 'b t -> ('a * 'b) t
(** Cartesian product *) (** Cartesian product *)
val to_seq : 'a t -> 'a CCSequence.t val to_seq : 'a t -> 'a sequence
val to_list : 'a t -> 'a list val to_list : 'a t -> 'a list
@ -93,13 +95,13 @@ val builder_hash : ?size:int ->
val builder_cmp : ?cmp:('a -> 'a -> int) -> unit -> 'a builder val builder_cmp : ?cmp:('a -> 'a -> int) -> unit -> 'a builder
val of_seq_builder : builder:'a builder -> 'a CCSequence.t -> 'a t val of_seq_builder : builder:'a builder -> 'a sequence -> 'a t
(** Uses the given builder to construct a set from a sequence of elements *) (** Uses the given builder to construct a set from a sequence of elements *)
val of_seq_hash : ?eq:('a -> 'a -> bool) -> ?hash:('a -> int) -> 'a CCSequence.t -> 'a t val of_seq_hash : ?eq:('a -> 'a -> bool) -> ?hash:('a -> int) -> 'a sequence -> 'a t
(** Construction of a set from a sequence of hashable elements *) (** Construction of a set from a sequence of hashable elements *)
val of_seq_cmp : ?cmp:('a -> 'a -> int) -> 'a CCSequence.t -> 'a t val of_seq_cmp : ?cmp:('a -> 'a -> int) -> 'a sequence -> 'a t
(** Construction of a set from a sequence of comparable elements *) (** Construction of a set from a sequence of comparable elements *)
val of_list : 'a list -> 'a t val of_list : 'a list -> 'a t
@ -133,7 +135,7 @@ module MakeHash(X : Hashtbl.HashedType) : sig
type elt = X.t type elt = X.t
(** Elements of the set are hashable *) (** Elements of the set are hashable *)
val of_seq : ?size:int -> elt CCSequence.t -> elt t val of_seq : ?size:int -> elt sequence -> elt t
(** Build a set from a sequence *) (** Build a set from a sequence *)
end end
@ -141,7 +143,7 @@ end
module MakeSet(S : Set.S) : sig module MakeSet(S : Set.S) : sig
type elt = S.elt type elt = S.elt
val of_seq : ?init:S.t -> elt CCSequence.t -> elt t val of_seq : ?init:S.t -> elt sequence -> elt t
(** Build a set from a sequence *) (** Build a set from a sequence *)
val of_set : S.t -> elt t val of_set : S.t -> elt t

View file

@ -124,7 +124,7 @@ let gen l =
(*$Q (*$Q
(Q.list Q.small_int) (fun l -> \ (Q.list Q.small_int) (fun l -> \
l = [] || let q = of_list l in \ l = [] || let q = of_list l in \
gen q |> CCGen.take (List.length l) |> CCGen.to_list = l) gen q |> Gen.take (List.length l) |> Gen.to_list = l)
*) *)
let seq l k = let seq l k =

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Functional (persistent) hashtable} *) (** {1 Functional (persistent) hashtable} *)
type 'a sequence = ('a -> unit) -> unit
(** {2 Signatures} *) (** {2 Signatures} *)
module type HASH = sig module type HASH = sig
@ -64,9 +66,9 @@ module type S = sig
val size : 'a t -> int val size : 'a t -> int
(** Number of bindings *) (** Number of bindings *)
val to_seq : 'a t -> (key * 'a) CCSequence.t val to_seq : 'a t -> (key * 'a) sequence
val of_seq : ?size:int -> (key * 'a) CCSequence.t -> 'a t val of_seq : ?size:int -> (key * 'a) sequence -> 'a t
end end
(** {2 Persistent array} *) (** {2 Persistent array} *)
@ -336,13 +338,13 @@ module Tree(X : HASH) = struct
let size t = let size t =
fold (fun n _ _ -> n + 1) 0 t fold (fun n _ _ -> n + 1) 0 t
let to_seq t = let to_seq t k =
CCSequence.from_iter (fun k -> iter (fun key value -> k (key, value)) t) iter (fun key value -> k (key, value)) t
let of_seq ?(size=32) seq = let of_seq ?(size=32) seq =
CCSequence.fold let cur = ref (empty size) in
(fun t (k,v) -> replace t k v) seq (fun (k,v) -> cur := replace !cur k v);
(empty size) seq !cur
end end
(** {2 Flat hashtable} *) (** {2 Flat hashtable} *)
@ -492,10 +494,10 @@ module Flat(X : HASH) = struct
| _ -> acc) | _ -> acc)
acc t.buckets acc t.buckets
let to_seq t = let to_seq t k = iter (fun key value -> k (key, value)) t
CCSequence.from_iter
(fun k -> iter (fun key value -> k (key, value)) t)
let of_seq ?(size=32) seq = let of_seq ?(size=32) seq =
CCSequence.fold (fun t (k,v) -> replace t k v) (empty size) seq let t = ref (empty size) in
seq (fun (k,v) -> t := replace !t k v);
!t
end end

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Functional (persistent) hashtable} *) (** {1 Functional (persistent) hashtable} *)
type 'a sequence = ('a -> unit) -> unit
(** {2 Signatures} *) (** {2 Signatures} *)
module type HASH = sig module type HASH = sig
@ -64,9 +66,9 @@ module type S = sig
val size : 'a t -> int val size : 'a t -> int
(** Number of bindings *) (** Number of bindings *)
val to_seq : 'a t -> (key * 'a) CCSequence.t val to_seq : 'a t -> (key * 'a) sequence
val of_seq : ?size:int -> (key * 'a) CCSequence.t -> 'a t val of_seq : ?size:int -> (key * 'a) sequence -> 'a t
end end
(** {2 Persistent array} *) (** {2 Persistent array} *)

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** Open addressing hashtable, with linear probing. *) (** Open addressing hashtable, with linear probing. *)
type 'a sequence = ('a -> unit) -> unit
module type S = module type S =
sig sig
type key type key
@ -61,9 +63,9 @@ module type S =
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
(** Fold on bindings *) (** Fold on bindings *)
val to_seq : 'a t -> (key * 'a) CCSequence.t val to_seq : 'a t -> (key * 'a) sequence
val of_seq : 'a t -> (key * 'a) CCSequence.t -> unit val of_seq : 'a t -> (key * 'a) sequence -> unit
val stats : 'a t -> int * int * int * int * int * int val stats : 'a t -> int * int * int * int * int * int
(** Cf Weak.S *) (** Cf Weak.S *)
@ -218,12 +220,11 @@ module Make(H : Hashtbl.HashedType) =
| _ -> fold acc (i+1) | _ -> fold acc (i+1)
in fold acc 0 in fold acc 0
let to_seq t = let to_seq t k =
CCSequence.from_iter iter (fun key value -> k (key, value)) t
(fun k -> iter (fun key value -> k (key, value)) t)
let of_seq t seq = let of_seq t seq =
CCSequence.iter (fun (k,v) -> replace t k v) seq seq (fun (k,v) -> replace t k v)
(** Statistics on the table *) (** Statistics on the table *)
let stats t = (Array.length t.buckets, t.size, t.size, 0, 0, 1) let stats t = (Array.length t.buckets, t.size, t.size, 0, 0, 1)

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** Open addressing hashtable, with linear probing. *) (** Open addressing hashtable, with linear probing. *)
type 'a sequence = ('a -> unit) -> unit
module type S = module type S =
sig sig
type key type key
@ -61,9 +63,9 @@ module type S =
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
(** Fold on bindings *) (** Fold on bindings *)
val to_seq : 'a t -> (key * 'a) CCSequence.t val to_seq : 'a t -> (key * 'a) sequence
val of_seq : 'a t -> (key * 'a) CCSequence.t -> unit val of_seq : 'a t -> (key * 'a) sequence -> unit
val stats : 'a t -> int * int * int * int * int * int val stats : 'a t -> int * int * int * int * int * int
(** Cf Weak.S *) (** Cf Weak.S *)

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Mutable polymorphic hash-set} *) (** {1 Mutable polymorphic hash-set} *)
type 'a sequence = ('a -> unit) -> unit
type 'a t = ('a, unit) PHashtbl.t type 'a t = ('a, unit) PHashtbl.t
(** A set is a hashtable, with trivial values *) (** A set is a hashtable, with trivial values *)
@ -49,11 +51,10 @@ let fold f acc set = PHashtbl.fold (fun acc x () -> f acc x) acc set
let filter p set = PHashtbl.filter (fun x () -> p x) set let filter p set = PHashtbl.filter (fun x () -> p x) set
let to_seq set = let to_seq set k = iter k set
CCSequence.from_iter (fun k -> iter k set)
let of_seq set seq = let of_seq set seq =
CCSequence.iter (fun x -> add set x) seq seq (fun x -> add set x)
let union ?into (s1 : 'a t) (s2 : 'a t) = let union ?into (s1 : 'a t) (s2 : 'a t) =
let into = match into with let into = match into with
@ -62,10 +63,13 @@ let union ?into (s1 : 'a t) (s2 : 'a t) =
of_seq into (to_seq s2); of_seq into (to_seq s2);
into into
let seq_filter p seq k =
seq (fun x -> if p x then k x)
let inter ?into (s1 : 'a t) (s2 : 'a t) = let inter ?into (s1 : 'a t) (s2 : 'a t) =
let into = match into with let into = match into with
| Some s -> s | Some s -> s
| None -> empty ~eq:s1.PHashtbl.eq ~hash:s1.PHashtbl.hash (cardinal s1) in | None -> empty ~eq:s1.PHashtbl.eq ~hash:s1.PHashtbl.hash (cardinal s1) in
(* add to [into] elements of [s1] that also belong to [s2] *) (* add to [into] elements of [s1] that also belong to [s2] *)
of_seq into (CCSequence.filter (fun x -> mem s2 x) (to_seq s1)); of_seq into (seq_filter (fun x -> mem s2 x) (to_seq s1));
into into

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Mutable polymorphic hash-set} *) (** {1 Mutable polymorphic hash-set} *)
type 'a sequence = ('a -> unit) -> unit
type 'a t = ('a, unit) PHashtbl.t type 'a t = ('a, unit) PHashtbl.t
(** A set is a hashtable, with trivial values *) (** A set is a hashtable, with trivial values *)
@ -51,9 +53,9 @@ val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
val filter : ('a -> bool) -> 'a t -> unit val filter : ('a -> bool) -> 'a t -> unit
(** destructive filter (remove elements that do not satisfy the predicate) *) (** destructive filter (remove elements that do not satisfy the predicate) *)
val to_seq : 'a t -> 'a CCSequence.t val to_seq : 'a t -> 'a sequence
val of_seq : 'a t -> 'a CCSequence.t -> unit val of_seq : 'a t -> 'a sequence -> unit
val union : ?into:'a t -> 'a t -> 'a t -> 'a t val union : ?into:'a t -> 'a t -> 'a t -> 'a t
(** Set union. The result is stored in [into] *) (** Set union. The result is stored in [into] *)

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Imperative priority queue} *) (** {1 Imperative priority queue} *)
type 'a sequence = ('a -> unit) -> unit
type 'a t = { type 'a t = {
mutable tree : 'a tree; mutable tree : 'a tree;
cmp : 'a -> 'a -> int; cmp : 'a -> 'a -> int;

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Imperative priority queue} *) (** {1 Imperative priority queue} *)
type 'a sequence = ('a -> unit) -> unit
type 'a t type 'a t
(** A heap containing values of type 'a *) (** A heap containing values of type 'a *)
@ -51,6 +53,6 @@ val iter : 'a t -> ('a -> unit) -> unit
val size : _ t -> int val size : _ t -> int
val to_seq : 'a t -> 'a CCSequence.t val to_seq : 'a t -> 'a sequence
val of_seq : 'a t -> 'a CCSequence.t -> unit val of_seq : 'a t -> 'a sequence -> unit

View file

@ -29,6 +29,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
a graph is always accessed from a given initial node (so only connected a graph is always accessed from a given initial node (so only connected
components can be represented by a single value of type ('v,'e) t). *) components can be represented by a single value of type ('v,'e) t). *)
type 'a sequence = ('a -> unit) -> unit
(** {2 Type definitions} *) (** {2 Type definitions} *)
type ('id, 'v, 'e) t = { type ('id, 'v, 'e) t = {
@ -41,7 +43,7 @@ type ('id, 'v, 'e) t = {
other vertices, or to Empty if the identifier is not part of the graph. *) other vertices, or to Empty if the identifier is not part of the graph. *)
and ('id, 'v, 'e) node = and ('id, 'v, 'e) node =
| Empty | Empty
| Node of 'id * 'v * ('e * 'id) CCSequence.t | Node of 'id * 'v * ('e * 'id) sequence
(** A single node of the graph, with outgoing edges *) (** A single node of the graph, with outgoing edges *)
and ('id, 'e) path = ('id * 'e * 'id) list and ('id, 'e) path = ('id * 'e * 'id) list
(** A reverse path (from the last element of the path to the first). *) (** A reverse path (from the last element of the path to the first). *)
@ -56,7 +58,7 @@ let empty =
let singleton ?(eq=(=)) ?(hash=Hashtbl.hash) v label = let singleton ?(eq=(=)) ?(hash=Hashtbl.hash) v label =
let force v' = let force v' =
if eq v v' then Node (v, label, CCSequence.empty) else Empty in if eq v v' then Node (v, label, fun _ -> ()) else Empty in
{ force; eq; hash; } { force; eq; hash; }
let make ?(eq=(=)) ?(hash=Hashtbl.hash) force = let make ?(eq=(=)) ?(hash=Hashtbl.hash) force =
@ -66,7 +68,7 @@ let from_fun ?(eq=(=)) ?(hash=Hashtbl.hash) f =
let force v = let force v =
match f v with match f v with
| None -> Empty | None -> Empty
| Some (l, edges) -> Node (v, l, CCSequence.of_list edges) in | Some (l, edges) -> Node (v, l, fun k -> List.iter k edges) in
{ eq; hash; force; } { eq; hash; force; }
(** {2 Polymorphic map} *) (** {2 Polymorphic map} *)
@ -110,7 +112,7 @@ module Mutable = struct
let map = mk_map ~eq ~hash in let map = mk_map ~eq ~hash in
let force v = let force v =
try let node = map.map_get v in try let node = map.map_get v in
Node (v, node.mut_v, CCSequence.of_list node.mut_outgoing) Node (v, node.mut_v, fun k -> List.iter k node.mut_outgoing)
with Not_found -> Empty in with Not_found -> Empty in
let graph = { eq; hash; force; } in let graph = { eq; hash; force; } in
map, graph map, graph
@ -129,12 +131,10 @@ end
let from_enum ?(eq=(=)) ?(hash=Hashtbl.hash) ~vertices ~edges = let from_enum ?(eq=(=)) ?(hash=Hashtbl.hash) ~vertices ~edges =
let g, lazy_g = Mutable.create ~eq ~hash () in let g, lazy_g = Mutable.create ~eq ~hash () in
CCSequence.iter vertices
(fun (v,label_v) -> Mutable.add_vertex g v label_v;) (fun (v,label_v) -> Mutable.add_vertex g v label_v;);
vertices; edges
CCSequence.iter (fun (v1, e, v2) -> Mutable.add_edge g v1 e v2);
(fun (v1, e, v2) -> Mutable.add_edge g v1 e v2)
edges;
lazy_g lazy_g
let from_list ?(eq=(=)) ?(hash=Hashtbl.hash) l = let from_list ?(eq=(=)) ?(hash=Hashtbl.hash) l =
@ -174,11 +174,11 @@ module Full = struct
| [] -> false | [] -> false
let bfs_full graph vertices = let bfs_full graph vertices =
CCSequence.from_iter (fun k -> fun k ->
let explored = mk_map ~eq:graph.eq ~hash:graph.hash in let explored = mk_map ~eq:graph.eq ~hash:graph.hash in
let id = ref 0 in let id = ref 0 in
let q = Queue.create () in (* queue of nodes to explore *) let q = Queue.create () in (* queue of nodes to explore *)
CCSequence.iter (fun v -> Queue.push (FullEnter (v,[])) q) vertices; vertices (fun v -> Queue.push (FullEnter (v,[])) q);
while not (Queue.is_empty q) do while not (Queue.is_empty q) do
match Queue.pop q with match Queue.pop q with
| FullEnter (v', path) -> | FullEnter (v', path) ->
@ -188,11 +188,11 @@ module Full = struct
| Node (_, label, edges) -> | Node (_, label, edges) ->
explored.map_add v' (); explored.map_add v' ();
(* explore neighbors *) (* explore neighbors *)
CCSequence.iter edges
(fun (e,v'') -> (fun (e,v'') ->
let path' = (v'',e,v') :: path in let path' = (v'',e,v') :: path in
Queue.push (FullFollowEdge path') q) Queue.push (FullFollowEdge path') q
edges; );
(* exit node afterward *) (* exit node afterward *)
Queue.push (FullExit v') q; Queue.push (FullExit v') q;
(* return this vertex *) (* return this vertex *)
@ -213,17 +213,17 @@ module Full = struct
Queue.push (FullEnter (v'', path')) q; Queue.push (FullEnter (v'', path')) q;
k (MeetEdge (v'', e, v', EdgeForward)) k (MeetEdge (v'', e, v', EdgeForward))
end end
done) done
(* TODO: use a set of nodes currently being explored, rather than (* TODO: use a set of nodes currently being explored, rather than
checking whether the node is in the path (should be faster) *) checking whether the node is in the path (should be faster) *)
let dfs_full graph vertices = let dfs_full graph vertices =
CCSequence.from_iter (fun k -> fun k ->
let explored = mk_map ~eq:graph.eq ~hash:graph.hash in let explored = mk_map ~eq:graph.eq ~hash:graph.hash in
let id = ref 0 in let id = ref 0 in
let s = Stack.create () in (* stack of nodes to explore *) let s = Stack.create () in (* stack of nodes to explore *)
CCSequence.iter (fun v -> Stack.push (FullEnter (v,[])) s) vertices; vertices (fun v -> Stack.push (FullEnter (v,[])) s);
while not (Stack.is_empty s) do while not (Stack.is_empty s) do
match Stack.pop s with match Stack.pop s with
| FullExit v' -> k (ExitVertex v') | FullExit v' -> k (ExitVertex v')
@ -237,10 +237,10 @@ module Full = struct
(* prepare to exit later *) (* prepare to exit later *)
Stack.push (FullExit v') s; Stack.push (FullExit v') s;
(* explore neighbors *) (* explore neighbors *)
CCSequence.iter edges
(fun (e,v'') -> (fun (e,v'') ->
Stack.push (FullFollowEdge ((v'', e, v') :: path)) s) Stack.push (FullFollowEdge ((v'', e, v') :: path)) s
edges; );
(* return this vertex *) (* return this vertex *)
let i = !id in let i = !id in
incr id; incr id;
@ -258,22 +258,28 @@ module Full = struct
Stack.push (FullEnter (v'', path')) s; Stack.push (FullEnter (v'', path')) s;
k (MeetEdge (v'', e, v', EdgeForward)) k (MeetEdge (v'', e, v', EdgeForward))
end end
done) done
end end
let seq_filter_map f seq k =
seq (fun x -> match f x with
| None -> ()
| Some y -> k y
)
let bfs graph v = let bfs graph v =
CCSequence.fmap seq_filter_map
(function (function
| Full.EnterVertex (v, l, i, _) -> Some (v, l, i) | Full.EnterVertex (v, l, i, _) -> Some (v, l, i)
| _ -> None) | _ -> None)
(Full.bfs_full graph (CCSequence.singleton v)) (Full.bfs_full graph (fun k -> k v))
let dfs graph v = let dfs graph v =
CCSequence.fmap seq_filter_map
(function (function
| Full.EnterVertex (v, l, i, _) -> Some (v, l, i) | Full.EnterVertex (v, l, i, _) -> Some (v, l, i)
| _ -> None) | _ -> None)
(Full.dfs_full graph (CCSequence.singleton v)) (Full.dfs_full graph (fun k -> k v))
(** {3 Mutable heap} *) (** {3 Mutable heap} *)
module Heap = struct module Heap = struct
@ -342,7 +348,7 @@ let a_star graph
?(distance=(fun v1 e v2 -> 1.)) ?(distance=(fun v1 e v2 -> 1.))
~goal ~goal
start = start =
CCSequence.from_iter (fun k -> fun k ->
(* map node -> 'came_from' cell *) (* map node -> 'came_from' cell *)
let nodes = mk_map ~eq:graph.eq ~hash:graph.hash in let nodes = mk_map ~eq:graph.eq ~hash:graph.hash in
(* priority queue for nodes to explore *) (* priority queue for nodes to explore *)
@ -376,7 +382,7 @@ let a_star graph
| Empty -> () | Empty -> ()
| Node (_, label, edges) -> | Node (_, label, edges) ->
(* explore neighbors *) (* explore neighbors *)
CCSequence.iter edges
(fun (e,v'') -> (fun (e,v'') ->
let cost = dist +. distance v' e v'' +. heuristic v'' in let cost = dist +. distance v' e v'' +. heuristic v'' in
let cell' = let cell' =
@ -395,14 +401,20 @@ let a_star graph
Heap.insert h (cost, v''); Heap.insert h (cost, v'');
cell'.cf_cost <- cost; (* update best cost/path *) cell'.cf_cost <- cost; (* update best cost/path *)
cell'.cf_prev <- CFEdge (e, cell); cell'.cf_prev <- CFEdge (e, cell);
end) end);
edges;
(* check whether the node we just explored is a goal node *) (* check whether the node we just explored is a goal node *)
if goal v' if goal v'
(* found a goal node! yield it *) (* found a goal node! yield it *)
then k (dist, mk_path nodes [] v') then k (dist, mk_path nodes [] v')
end end
done) done
exception ExitHead
let seq_head seq =
let r = ref None in
try
seq (fun x -> r := Some x; raise ExitHead); None
with ExitHead -> !r
(** Shortest path from the first node to the second one, according (** Shortest path from the first node to the second one, according
to the given (positive!) distance function. The path is reversed, to the given (positive!) distance function. The path is reversed,
@ -413,22 +425,29 @@ let dijkstra graph ?on_explore ?(ignore=fun v -> false)
a_star graph ?on_explore ~ignore ~distance ~heuristic:(fun _ -> 0.) a_star graph ?on_explore ~ignore ~distance ~heuristic:(fun _ -> 0.)
~goal:(fun v -> graph.eq v v2) v1 ~goal:(fun v -> graph.eq v v2) v1
in in
match CCSequence.to_list (CCSequence.take 1 paths) with match seq_head paths with
| [] -> raise Not_found | None -> raise Not_found
| [x] -> x | Some x -> x
| _ -> assert false
exception ExitForall
let seq_for_all p seq =
try
seq (fun x -> if not (p x) then raise ExitForall);
true
with ExitForall -> false
(** Is the subgraph explorable from the given vertex, a Directed (** Is the subgraph explorable from the given vertex, a Directed
Acyclic Graph? *) Acyclic Graph? *)
let is_dag graph v = let is_dag graph v =
CCSequence.for_all seq_for_all
(function (function
| Full.MeetEdge (_, _, _, Full.EdgeBackward) -> false | Full.MeetEdge (_, _, _, Full.EdgeBackward) -> false
| _ -> true) | _ -> true)
(Full.dfs_full graph (CCSequence.singleton v)) (Full.dfs_full graph (fun k -> k v))
let is_dag_full graph vs = let is_dag_full graph vs =
CCSequence.for_all seq_for_all
(function (function
| Full.MeetEdge (_, _, _, Full.EdgeBackward) -> false | Full.MeetEdge (_, _, _, Full.EdgeBackward) -> false
| _ -> true) | _ -> true)
@ -443,9 +462,8 @@ let find_cycle graph v =
let cycle = ref [] in let cycle = ref [] in
try try
let path_stack = Stack.create () in let path_stack = Stack.create () in
let seq = Full.dfs_full graph (CCSequence.singleton v) in let seq = Full.dfs_full graph (fun k -> k v) in
CCSequence.iter seq (function
(function
| Full.EnterVertex (_, _, _, path) -> | Full.EnterVertex (_, _, _, path) ->
Stack.push path path_stack Stack.push path path_stack
| Full.ExitVertex _ -> | Full.ExitVertex _ ->
@ -456,8 +474,8 @@ let find_cycle graph v =
let path = (v1, e, v2) :: path in let path = (v1, e, v2) :: path in
cycle := path; cycle := path;
raise Exit raise Exit
| Full.MeetEdge _ -> ()) | Full.MeetEdge _ -> ()
seq; );
raise Not_found raise Not_found
with Exit -> with Exit ->
!cycle !cycle
@ -471,6 +489,9 @@ let rev_path p =
(** {2 Lazy transformations} *) (** {2 Lazy transformations} *)
let seq_map f seq k = seq (fun x -> k (f x))
let seq_append s1 s2 k = s1 k; s2 k
let union ?(combine=fun x y -> x) g1 g2 = let union ?(combine=fun x y -> x) g1 g2 =
let force v = let force v =
match g1.force v, g2.force v with match g1.force v, g2.force v with
@ -478,7 +499,7 @@ let union ?(combine=fun x y -> x) g1 g2 =
| ((Node _) as n), Empty -> n | ((Node _) as n), Empty -> n
| Empty, ((Node _) as n) -> n | Empty, ((Node _) as n) -> n
| Node (_, l1, e1), Node (_, l2, e2) -> | Node (_, l1, e1), Node (_, l2, e2) ->
Node (v, combine l1 l2, CCSequence.append e1 e2) Node (v, combine l1 l2, seq_append e1 e2)
in { eq=g1.eq; hash=g1.hash; force; } in { eq=g1.eq; hash=g1.hash; force; }
let map ~vertices ~edges g = let map ~vertices ~edges g =
@ -486,10 +507,12 @@ let map ~vertices ~edges g =
match g.force v with match g.force v with
| Empty -> Empty | Empty -> Empty
| Node (_, l, edges_enum) -> | Node (_, l, edges_enum) ->
let edges_enum' = CCSequence.map (fun (e,v') -> (edges e), v') edges_enum in let edges_enum' = seq_map (fun (e,v') -> (edges e), v') edges_enum in
Node (v, vertices l, edges_enum') Node (v, vertices l, edges_enum')
in { eq=g.eq; hash=g.hash; force; } in { eq=g.eq; hash=g.hash; force; }
let seq_flat_map f seq k = seq (fun x -> f x k)
(** Replace each vertex by some vertices. By mapping [v'] to [f v'=v1,...,vn], (** Replace each vertex by some vertices. By mapping [v'] to [f v'=v1,...,vn],
whenever [v] ---e---> [v'], then [v --e--> vi] for i=1,...,n. *) whenever [v] ---e---> [v'], then [v --e--> vi] for i=1,...,n. *)
let flatMap f g = let flatMap f g =
@ -497,24 +520,29 @@ let flatMap f g =
match g.force v with match g.force v with
| Empty -> Empty | Empty -> Empty
| Node (_, l, edges_enum) -> | Node (_, l, edges_enum) ->
let edges_enum' = CCSequence.flatMap let edges_enum' = seq_flat_map
(fun (e, v') -> (fun (e, v') ->
CCSequence.map (fun v'' -> e, v'') (f v')) seq_map (fun v'' -> e, v'') (f v'))
edges_enum in edges_enum in
Node (v, l, edges_enum') Node (v, l, edges_enum')
in { eq=g.eq; hash=g.hash; force; } in { eq=g.eq; hash=g.hash; force; }
let seq_filter p seq k = seq (fun x -> if p x then k x)
let filter ?(vertices=(fun v l -> true)) ?(edges=fun v1 e v2 -> true) g = let filter ?(vertices=(fun v l -> true)) ?(edges=fun v1 e v2 -> true) g =
let force v = let force v =
match g.force v with match g.force v with
| Empty -> Empty | Empty -> Empty
| Node (_, l, edges_enum) when vertices v l -> | Node (_, l, edges_enum) when vertices v l ->
(* filter out edges *) (* filter out edges *)
let edges_enum' = CCSequence.filter (fun (e,v') -> edges v e v') edges_enum in let edges_enum' = seq_filter (fun (e,v') -> edges v e v') edges_enum in
Node (v, l, edges_enum') Node (v, l, edges_enum')
| Node _ -> Empty (* filter out this vertex *) | Node _ -> Empty (* filter out this vertex *)
in { eq=g.eq; hash=g.hash; force; } in { eq=g.eq; hash=g.hash; force; }
let seq_product s1 s2 k =
s1 (fun x -> s2 (fun y -> k(x,y)))
let product g1 g2 = let product g1 g2 =
let force (v1,v2) = let force (v1,v2) =
match g1.force v1, g2.force v2 with match g1.force v1, g2.force v2 with
@ -522,8 +550,8 @@ let product g1 g2 =
| _, Empty -> Empty | _, Empty -> Empty
| Node (_, l1, edges1), Node (_, l2, edges2) -> | Node (_, l1, edges1), Node (_, l2, edges2) ->
(* product of edges *) (* product of edges *)
let edges = CCSequence.product edges1 edges2 in let edges = seq_product edges1 edges2 in
let edges = CCSequence.map (fun ((e1,v1'),(e2,v2')) -> ((e1,e2),(v1',v2'))) edges in let edges = seq_map (fun ((e1,v1'),(e2,v2')) -> ((e1,e2),(v1',v2'))) edges in
Node ((v1,v2), (l1,l2), edges) Node ((v1,v2), (l1,l2), edges)
and eq (v1,v2) (v1',v2') = and eq (v1,v2) (v1',v2') =
g1.eq v1 v1' && g2.eq v2 v2' g1.eq v1 v1' && g2.eq v2 v2'
@ -574,7 +602,7 @@ module Dot = struct
(* print preamble *) (* print preamble *)
Format.fprintf formatter "@[<v2>digraph %s {@;" name; Format.fprintf formatter "@[<v2>digraph %s {@;" name;
(* traverse *) (* traverse *)
CCSequence.iter events
(function (function
| Full.EnterVertex (v, attrs, _, _) -> | Full.EnterVertex (v, attrs, _, _) ->
Format.fprintf formatter " @[<h>%a %a;@]@." pp_vertex v Format.fprintf formatter " @[<h>%a %a;@]@." pp_vertex v
@ -584,8 +612,8 @@ module Dot = struct
Format.fprintf formatter " @[<h>%a -> %a %a;@]@." Format.fprintf formatter " @[<h>%a -> %a %a;@]@."
pp_vertex v1 pp_vertex v2 pp_vertex v1 pp_vertex v2
(CCList.print ~start:"[" ~stop:"]" ~sep:"," print_attribute) (CCList.print ~start:"[" ~stop:"]" ~sep:"," print_attribute)
attrs) attrs
events; );
(* close *) (* close *)
Format.fprintf formatter "}@]@;@?"; Format.fprintf formatter "}@]@;@?";
() ()
@ -608,17 +636,17 @@ let divisors_graph =
if i > 2 if i > 2
then then
let l = divisors [] 2 i in let l = divisors [] 2 i in
let edges = CCSequence.map (fun i -> (), i) (CCSequence.of_list l) in let edges = seq_map (fun i -> (), i) (fun k -> List.iter k l) in
Node (i, i, edges) Node (i, i, edges)
else else
Node (i, i, CCSequence.empty) Node (i, i, fun _ -> ())
in make force in make force
let collatz_graph = let collatz_graph =
let force i = let force i =
if i mod 2 = 0 if i mod 2 = 0
then Node (i, i, CCSequence.singleton ((), i / 2)) then Node (i, i, fun k -> k ((), i / 2))
else Node (i, i, CCSequence.singleton ((), i * 3 + 1)) else Node (i, i, fun k -> k ((), i * 3 + 1))
in make force in make force
let collatz_graph_bis = let collatz_graph_bis =
@ -628,10 +656,10 @@ let collatz_graph_bis =
; false, i * 2 ] @ ; false, i * 2 ] @
if i mod 3 = 1 then [false, (i-1)/3] else [] if i mod 3 = 1 then [false, (i-1)/3] else []
in in
Node (i, i, CCSequence.of_list l) Node (i, i, fun k -> List.iter k l)
in make force in make force
let heap_graph = let heap_graph =
let force i = let force i =
Node (i, i, CCSequence.of_list [(), 2*i; (), 2*i+1]) Node (i, i, fun k -> List.iter k [(), 2*i; (), 2*i+1])
in make force in make force

View file

@ -34,6 +34,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {2 Type definitions} *) (** {2 Type definitions} *)
type 'a sequence = ('a -> unit) -> unit
type ('id, 'v, 'e) t = { type ('id, 'v, 'e) t = {
eq : 'id -> 'id -> bool; eq : 'id -> 'id -> bool;
hash : 'id -> int; hash : 'id -> int;
@ -44,7 +46,7 @@ type ('id, 'v, 'e) t = {
other vertices, or to Empty if the identifier is not part of the graph. *) other vertices, or to Empty if the identifier is not part of the graph. *)
and ('id, 'v, 'e) node = and ('id, 'v, 'e) node =
| Empty | Empty
| Node of 'id * 'v * ('e * 'id) CCSequence.t | Node of 'id * 'v * ('e * 'id) sequence
(** A single node of the graph, with outgoing edges *) (** A single node of the graph, with outgoing edges *)
and ('id, 'e) path = ('id * 'e * 'id) list and ('id, 'e) path = ('id * 'e * 'id) list
(** A reverse path (from the last element of the path to the first). *) (** A reverse path (from the last element of the path to the first). *)
@ -70,8 +72,8 @@ val make : ?eq:('id -> 'id -> bool) -> ?hash:('id -> int) ->
(** Build a graph from the [force] function *) (** Build a graph from the [force] function *)
val from_enum : ?eq:('id -> 'id -> bool) -> ?hash:('id -> int) -> val from_enum : ?eq:('id -> 'id -> bool) -> ?hash:('id -> int) ->
vertices:('id * 'v) CCSequence.t -> vertices:('id * 'v) sequence ->
edges:('id * 'e * 'id) CCSequence.t -> edges:('id * 'e * 'id) sequence ->
('id, 'v, 'e) t ('id, 'v, 'e) t
(** Concrete (eager) representation of a Graph *) (** Concrete (eager) representation of a Graph *)
@ -117,21 +119,21 @@ module Full : sig
| EdgeBackward (* toward the current trail *) | EdgeBackward (* toward the current trail *)
| EdgeTransverse (* toward a totally explored part of the graph *) | EdgeTransverse (* toward a totally explored part of the graph *)
val bfs_full : ('id, 'v, 'e) t -> 'id CCSequence.t -> val bfs_full : ('id, 'v, 'e) t -> 'id sequence ->
('id, 'v, 'e) traverse_event CCSequence.t ('id, 'v, 'e) traverse_event sequence
(** Lazy traversal in breadth first from a finite set of vertices *) (** Lazy traversal in breadth first from a finite set of vertices *)
val dfs_full : ('id, 'v, 'e) t -> 'id CCSequence.t -> val dfs_full : ('id, 'v, 'e) t -> 'id sequence ->
('id, 'v, 'e) traverse_event CCSequence.t ('id, 'v, 'e) traverse_event sequence
(** Lazy traversal in depth first from a finite set of vertices *) (** Lazy traversal in depth first from a finite set of vertices *)
end end
(** The traversal functions assign a unique ID to every traversed node *) (** The traversal functions assign a unique ID to every traversed node *)
val bfs : ('id, 'v, 'e) t -> 'id -> ('id * 'v * int) CCSequence.t val bfs : ('id, 'v, 'e) t -> 'id -> ('id * 'v * int) sequence
(** Lazy traversal in breadth first *) (** Lazy traversal in breadth first *)
val dfs : ('id, 'v, 'e) t -> 'id -> ('id * 'v * int) CCSequence.t val dfs : ('id, 'v, 'e) t -> 'id -> ('id * 'v * int) sequence
(** Lazy traversal in depth first *) (** Lazy traversal in depth first *)
module Heap : sig module Heap : sig
@ -149,7 +151,7 @@ val a_star : ('id, 'v, 'e) t ->
?distance:('id -> 'e -> 'id -> float) -> ?distance:('id -> 'e -> 'id -> float) ->
goal:('id -> bool) -> goal:('id -> bool) ->
'id -> 'id ->
(float * ('id, 'e) path) CCSequence.t (float * ('id, 'e) path) sequence
(** Shortest path from the first node to nodes that satisfy [goal], according (** Shortest path from the first node to nodes that satisfy [goal], according
to the given (positive!) distance function. The distance is also returned. to the given (positive!) distance function. The distance is also returned.
[ignore] allows one to ignore some vertices during exploration. [ignore] allows one to ignore some vertices during exploration.
@ -174,7 +176,7 @@ val is_dag : ('id, _, _) t -> 'id -> bool
(** Is the subgraph explorable from the given vertex, a Directed (** Is the subgraph explorable from the given vertex, a Directed
Acyclic Graph? *) Acyclic Graph? *)
val is_dag_full : ('id, _, _) t -> 'id CCSequence.t -> bool val is_dag_full : ('id, _, _) t -> 'id sequence -> bool
(** Is the Graph reachable from the given vertices, a DAG? See {! is_dag} *) (** Is the Graph reachable from the given vertices, a DAG? See {! is_dag} *)
val find_cycle : ('id, _, 'e) t -> 'id -> ('id, 'e) path val find_cycle : ('id, _, 'e) t -> 'id -> ('id, 'e) path
@ -196,7 +198,7 @@ val map : vertices:('v -> 'v2) -> edges:('e -> 'e2) ->
('id, 'v, 'e) t -> ('id, 'v2, 'e2) t ('id, 'v, 'e) t -> ('id, 'v2, 'e2) t
(** Map vertice and edge labels *) (** Map vertice and edge labels *)
val flatMap : ('id -> 'id CCSequence.t) -> val flatMap : ('id -> 'id sequence) ->
('id, 'v, 'e) t -> ('id, 'v, 'e) t ->
('id, 'v, 'e) t ('id, 'v, 'e) t
(** Replace each vertex by some vertices. By mapping [v'] to [f v'=v1,...,vn], (** Replace each vertex by some vertices. By mapping [v'] to [f v'=v1,...,vn],
@ -231,12 +233,12 @@ module Dot : sig
val pp_enum : ?eq:('id -> 'id -> bool) -> ?hash:('id -> int) -> val pp_enum : ?eq:('id -> 'id -> bool) -> ?hash:('id -> int) ->
name:string -> Format.formatter -> name:string -> Format.formatter ->
('id,attribute list,attribute list) Full.traverse_event CCSequence.t -> ('id,attribute list,attribute list) Full.traverse_event sequence ->
unit unit
val pp : name:string -> ('id, attribute list, attribute list) t -> val pp : name:string -> ('id, attribute list, attribute list) t ->
Format.formatter -> Format.formatter ->
'id CCSequence.t -> unit 'id sequence -> unit
(** Pretty print the given graph (starting from the given set of vertices) (** Pretty print the given graph (starting from the given set of vertices)
to the channel in DOT format *) to the channel in DOT format *)
end end

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Open addressing hashtable (robin hood hashing)} *) (** {1 Open addressing hashtable (robin hood hashing)} *)
type 'a sequence = ('a -> unit) -> unit
type ('a, 'b) t = { type ('a, 'b) t = {
mutable buckets : ('a, 'b) bucket array; mutable buckets : ('a, 'b) bucket array;
mutable size : int; mutable size : int;
@ -77,7 +79,7 @@ let clear t =
(** Index of slot, for i-th probing starting from hash [h] in (** Index of slot, for i-th probing starting from hash [h] in
a table of length [n] *) a table of length [n] *)
let addr h n i = (h + i) mod n let addr h n i = (h + i) mod n
(** Insert (key -> value) in table, starting with the hash. *) (** Insert (key -> value) in table, starting with the hash. *)
let insert t key value = let insert t key value =
let n = Array.length t.buckets in let n = Array.length t.buckets in
@ -217,12 +219,10 @@ let filter pred t =
(** Add the given pairs to the hashtable *) (** Add the given pairs to the hashtable *)
let of_seq t seq = let of_seq t seq =
CCSequence.iter (fun (k,v) -> add t k v) seq seq (fun (k,v) -> add t k v)
(** CCSequence of pairs *) (** CCSequence of pairs *)
let to_seq t = let to_seq t kont = iter (fun k v -> kont (k,v)) t
CCSequence.from_iter
(fun kont -> iter (fun k v -> kont (k,v)) t)
(** Statistics on the table *) (** Statistics on the table *)
let stats t = (Array.length t.buckets, t.size, t.size, 0, 0, 1) let stats t = (Array.length t.buckets, t.size, t.size, 0, 0, 1)

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Open addressing hashtable (robin hood hashing)} *) (** {1 Open addressing hashtable (robin hood hashing)} *)
type 'a sequence = ('a -> unit) -> unit
type ('a, 'b) t = { type ('a, 'b) t = {
mutable buckets : ('a, 'b) bucket array; mutable buckets : ('a, 'b) bucket array;
mutable size : int; mutable size : int;
@ -90,11 +92,11 @@ val filter : ('a -> 'b -> bool) -> ('a, 'b) t -> unit
val fold : ('c -> 'a -> 'b -> 'c) -> 'c -> ('a, 'b) t -> 'c val fold : ('c -> 'a -> 'b -> 'c) -> 'c -> ('a, 'b) t -> 'c
(** Fold on bindings *) (** Fold on bindings *)
val of_seq : ('a, 'b) t -> ('a * 'b) CCSequence.t -> unit val of_seq : ('a, 'b) t -> ('a * 'b) sequence -> unit
(** Add the given pairs to the hashtable *) (** Add the given pairs to the hashtable *)
val to_seq : ('a, 'b) t -> ('a * 'b) CCSequence.t val to_seq : ('a, 'b) t -> ('a * 'b) sequence
(** CCSequence of pairs *) (** Sequence of pairs *)
val stats : (_, _) t -> int * int * int * int * int * int val stats : (_, _) t -> int * int * int * int * int * int
(** Cf Weak.S *) (** Cf Weak.S *)

View file

@ -232,6 +232,6 @@ let run p seq =
<|> (skip_spaces >> exact '(' >> many1 ~sep:(exact ' ') (delay p) >>= fun l -> <|> (skip_spaces >> exact '(' >> many1 ~sep:(exact ' ') (delay p) >>= fun l ->
skip_spaces >> exact ')' >> return (list_ l)) skip_spaces >> exact ')' >> return (list_ l))
in in
let res = run (p ()) (CCSequence.of_str "(a b (c d))") in let res = run (p ()) (Sequence.of_str "(a b (c d))") in
assert_equal res [list_ [atom "a"; atom "b"; list_ [atom "c"; atom "d"]]] assert_equal res [list_ [atom "a"; atom "b"; list_ [atom "c"; atom "d"]]]
*) *)

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 A simple polymorphic directed graph.} *) (** {1 A simple polymorphic directed graph.} *)
type 'a sequence = ('a -> unit) -> unit
type ('v, 'e) t = ('v, ('v, 'e) node) PHashtbl.t type ('v, 'e) t = ('v, ('v, 'e) node) PHashtbl.t
(** Graph parametrized by a type for vertices, and one for edges *) (** Graph parametrized by a type for vertices, and one for edges *)
and ('v, 'e) node = { and ('v, 'e) node = {
@ -83,25 +85,27 @@ let add t v1 e v2 =
() ()
let add_seq t seq = let add_seq t seq =
CCSequence.iter (fun (v1,e,v2) -> add t v1 e v2) seq seq (fun (v1,e,v2) -> add t v1 e v2)
let next t v = let next t v k =
CCSequence.of_list (PHashtbl.find t v).n_next List.iter k (PHashtbl.find t v).n_next
let prev t v = let prev t v k =
CCSequence.of_list (PHashtbl.find t v).n_prev List.iter k (PHashtbl.find t v).n_prev
let seq_map f seq k = seq (fun x -> k (f x))
let seq_filter p seq k = seq (fun x -> if p x then k x)
let between t v1 v2 = let between t v1 v2 =
let edges = CCSequence.of_list (PHashtbl.find t v1).n_next in let edges k = List.iter k (PHashtbl.find t v1).n_next in
let edges = CCSequence.filter (fun (e, v2') -> (PHashtbl.get_eq t) v2 v2') edges in let edges = seq_filter (fun (e, v2') -> (PHashtbl.get_eq t) v2 v2') edges in
CCSequence.map fst edges seq_map fst edges
(** Call [k] on every vertex *) (** Call [k] on every vertex *)
let iter_vertices t k = let iter_vertices t k =
PHashtbl.iter (fun v _ -> k v) t PHashtbl.iter (fun v _ -> k v) t
let vertices t = let vertices t = iter_vertices t
CCSequence.from_iter (iter_vertices t)
(** Call [k] on every edge *) (** Call [k] on every edge *)
let iter t k = let iter t k =
@ -109,27 +113,37 @@ let iter t k =
(fun v1 node -> List.iter (fun (e, v2) -> k (v1, e, v2)) node.n_next) (fun v1 node -> List.iter (fun (e, v2) -> k (v1, e, v2)) node.n_next)
t t
let to_seq t = let to_seq t = iter t
CCSequence.from_iter (iter t)
(** {2 Global operations} *) (** {2 Global operations} *)
exception ExitIsEmpty
let seq_is_empty seq =
try seq (fun _ -> raise ExitIsEmpty); true
with ExitIsEmpty -> false
(** Roots, ie vertices with no incoming edges *) (** Roots, ie vertices with no incoming edges *)
let roots g = let roots g =
let vertices = vertices g in let vertices = vertices g in
CCSequence.filter (fun v -> CCSequence.is_empty (prev g v)) vertices seq_filter (fun v -> seq_is_empty (prev g v)) vertices
(** Leaves, ie vertices with no outgoing edges *) (** Leaves, ie vertices with no outgoing edges *)
let leaves g = let leaves g =
let vertices = vertices g in let vertices = vertices g in
CCSequence.filter (fun v -> CCSequence.is_empty (next g v)) vertices seq_filter (fun v -> seq_is_empty (next g v)) vertices
exception ExitHead
let seq_head seq =
let r = ref None in
try
seq (fun x -> r := Some x; raise ExitHead); None
with ExitHead -> !r
(** Pick a vertex, or raise Not_found *) (** Pick a vertex, or raise Not_found *)
let choose g = let choose g =
match CCSequence.to_list (CCSequence.take 1 (vertices g)) with match seq_head (vertices g) with
| [x] -> x | Some x -> x
| [] -> raise Not_found | None -> raise Not_found
| _ -> assert false
let rev_edge (v,e,v') = (v',e,v) let rev_edge (v,e,v') = (v',e,v)
@ -155,14 +169,12 @@ let bfs graph first k =
(* yield current node *) (* yield current node *)
k v; k v;
(* explore children *) (* explore children *)
CCSequence.iter next graph v
(fun (e, v') -> if not (Hashset.mem explored v') (fun (e, v') -> if not (Hashset.mem explored v')
then (Hashset.add explored v'; Queue.push v' q)) then (Hashset.add explored v'; Queue.push v' q))
(next graph v)
done done
let bfs_seq graph first = let bfs_seq graph first k = bfs graph first k
CCSequence.from_iter (fun k -> bfs graph first k)
(** DFS, with callbacks called on each encountered node and edge *) (** DFS, with callbacks called on each encountered node and edge *)
let dfs_full graph ?(labels=mk_v_table graph) let dfs_full graph ?(labels=mk_v_table graph)
@ -183,7 +195,7 @@ first
(* enter the node *) (* enter the node *)
enter trail'; enter trail';
(* explore edges *) (* explore edges *)
CCSequence.iter next graph v
(fun (e, v') -> (fun (e, v') ->
try let n' = PHashtbl.find labels v' in try let n' = PHashtbl.find labels v' in
if n' < n && List.exists (fun (_,n'') -> n' = n'') trail' if n' < n && List.exists (fun (_,n'') -> n' = n'') trail'
@ -192,8 +204,8 @@ first
fwd_edge (v,e,v') (* forward or cross edge *) fwd_edge (v,e,v') (* forward or cross edge *)
with Not_found -> with Not_found ->
tree_edge (v,e,v'); (* tree edge *) tree_edge (v,e,v'); (* tree edge *)
explore trail' v') (* explore the subnode *) explore trail' v' (* explore the subnode *)
(next graph v); );
(* exit the node *) (* exit the node *)
exit trail' exit trail'
end end
@ -216,10 +228,10 @@ let is_dag g =
else try else try
let labels = mk_v_table g in let labels = mk_v_table g in
(* do a DFS from each root; any back edge indicates a cycle *) (* do a DFS from each root; any back edge indicates a cycle *)
CCSequence.iter vertices g
(fun v -> (fun v ->
dfs_full g ~labels ~back_edge:(fun _ -> raise Exit) v) dfs_full g ~labels ~back_edge:(fun _ -> raise Exit) v
(vertices g); );
true (* complete traversal without back edge *) true (* complete traversal without back edge *)
with Exit -> with Exit ->
false (* back edge detected! *) false (* back edge detected! *)
@ -259,14 +271,13 @@ let min_path_full (type v) (type e) graph
else begin else begin
Hashset.add explored v; Hashset.add explored v;
(* explore successors *) (* explore successors *)
CCSequence.iter next graph v
(fun (e, v') -> (fun (e, v') ->
if Hashset.mem explored v' || ignore v' then () if Hashset.mem explored v' || ignore v' then ()
else else
let cost_v' = (cost v e v') + cost_v in let cost_v' = (cost v e v') + cost_v in
let path' = (v',e,v) :: path in let path' = (v',e,v) :: path in
Heap.insert q (v', cost_v', path')) Heap.insert q (v', cost_v', path'))
(next graph v)
end end
done; done;
(* if a satisfying path was found, Exit would have been raised *) (* if a satisfying path was found, Exit would have been raised *)
@ -307,7 +318,7 @@ type attribute = [
(** Pretty print the graph in DOT, on given formatter. Using a sequence (** Pretty print the graph in DOT, on given formatter. Using a sequence
allows to easily select which edges are important, allows to easily select which edges are important,
or to combine several graphs with [CCSequence.append]. *) or to combine several graphs with [seq_append]. *)
let pp ~name ?vertices let pp ~name ?vertices
~(print_edge : 'v -> 'e -> 'v -> attribute list) ~(print_edge : 'v -> 'e -> 'v -> attribute list)
~(print_vertex : 'v -> attribute list) formatter (graph : ('v, 'e) t) = ~(print_vertex : 'v -> attribute list) formatter (graph : ('v, 'e) t) =
@ -341,14 +352,14 @@ let pp ~name ?vertices
(* print preamble *) (* print preamble *)
Format.fprintf formatter "@[<v2>digraph %s {@;" name; Format.fprintf formatter "@[<v2>digraph %s {@;" name;
(* print edges *) (* print edges *)
CCSequence.iter to_seq graph
(fun (v1, e, v2) -> (fun (v1, e, v2) ->
let attributes = print_edge v1 e v2 in let attributes = print_edge v1 e v2 in
Format.fprintf formatter " @[<h>%a -> %a [%a];@]@." Format.fprintf formatter " @[<h>%a -> %a [%a];@]@."
pp_vertex v1 pp_vertex v2 pp_vertex v1 pp_vertex v2
(CCList.print ~sep:"," print_attribute) (CCList.print ~sep:"," print_attribute)
attributes) attributes
(to_seq graph); );
(* print vertices *) (* print vertices *)
PHashtbl.iter PHashtbl.iter
(fun v _ -> (fun v _ ->

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 A simple polymorphic directed graph.} *) (** {1 A simple polymorphic directed graph.} *)
type 'a sequence = ('a -> unit) -> unit
(** {2 Basics} *) (** {2 Basics} *)
type ('v, 'e) t type ('v, 'e) t
@ -51,31 +53,31 @@ val length : (_, _) t -> int
val add : ('v,'e) t -> 'v -> 'e -> 'v -> unit val add : ('v,'e) t -> 'v -> 'e -> 'v -> unit
(** Add an edge between two vertices *) (** Add an edge between two vertices *)
val add_seq : ('v,'e) t -> ('v * 'e * 'v) CCSequence.t -> unit val add_seq : ('v,'e) t -> ('v * 'e * 'v) sequence -> unit
(** Add the vertices to the graph *) (** Add the vertices to the graph *)
val next : ('v, 'e) t -> 'v -> ('e * 'v) CCSequence.t val next : ('v, 'e) t -> 'v -> ('e * 'v) sequence
(** Outgoing edges *) (** Outgoing edges *)
val prev : ('v, 'e) t -> 'v -> ('e * 'v) CCSequence.t val prev : ('v, 'e) t -> 'v -> ('e * 'v) sequence
(** Incoming edges *) (** Incoming edges *)
val between : ('v, 'e) t -> 'v -> 'v -> 'e CCSequence.t val between : ('v, 'e) t -> 'v -> 'v -> 'e sequence
val iter_vertices : ('v, 'e) t -> ('v -> unit) -> unit val iter_vertices : ('v, 'e) t -> ('v -> unit) -> unit
val vertices : ('v, 'e) t -> 'v CCSequence.t val vertices : ('v, 'e) t -> 'v sequence
(** Iterate on vertices *) (** Iterate on vertices *)
val iter : ('v, 'e) t -> ('v * 'e * 'v -> unit) -> unit val iter : ('v, 'e) t -> ('v * 'e * 'v -> unit) -> unit
val to_seq : ('v, 'e) t -> ('v * 'e * 'v) CCSequence.t val to_seq : ('v, 'e) t -> ('v * 'e * 'v) sequence
(** Dump the graph as a sequence of vertices *) (** Dump the graph as a sequence of vertices *)
(** {2 Global operations} *) (** {2 Global operations} *)
val roots : ('v, 'e) t -> 'v CCSequence.t val roots : ('v, 'e) t -> 'v sequence
(** Roots, ie vertices with no incoming edges *) (** Roots, ie vertices with no incoming edges *)
val leaves : ('v, 'e) t -> 'v CCSequence.t val leaves : ('v, 'e) t -> 'v sequence
(** Leaves, ie vertices with no outgoing edges *) (** Leaves, ie vertices with no outgoing edges *)
val choose : ('v, 'e) t -> 'v val choose : ('v, 'e) t -> 'v
@ -92,8 +94,8 @@ val rev : ('v, 'e) t -> unit
val bfs : ('v, 'e) t -> 'v -> ('v -> unit) -> unit val bfs : ('v, 'e) t -> 'v -> ('v -> unit) -> unit
(** Breadth-first search, from given 'v *) (** Breadth-first search, from given 'v *)
val bfs_seq : ('v, 'e) t -> 'v -> 'v CCSequence.t val bfs_seq : ('v, 'e) t -> 'v -> 'v sequence
(** CCSequence of vertices traversed during breadth-first search *) (** Sequence of vertices traversed during breadth-first search *)
val dfs_full : ('v, 'e) t -> val dfs_full : ('v, 'e) t ->
?labels:('v, int) PHashtbl.t -> ?labels:('v, int) PHashtbl.t ->

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Imperative skip-list} *) (** {1 Imperative skip-list} *)
type 'a gen = unit -> 'a option
(** Most functions are inspired from (** Most functions are inspired from
"A skip list cookbook", William Pugh, 1989. *) "A skip list cookbook", William Pugh, 1989. *)
@ -187,6 +189,10 @@ let gen l =
x := a.(0); x := a.(0);
Some (k, !v) Some (k, !v)
let rec gen_iter f g = match g() with
| None -> ()
| Some x -> f x; gen_iter f g
(** Add content of the iterator to the list *) (** Add content of the iterator to the list *)
let of_gen l gen = let of_gen l gen =
CCGen.iter (fun (k,v) -> add l k v) gen gen_iter (fun (k,v) -> add l k v) gen

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Imperative skip-list} *) (** {1 Imperative skip-list} *)
type 'a gen = unit -> 'a option
type ('a, 'b) t type ('a, 'b) t
(** A skip list that maps elements of type 'a to elements of type 'b *) (** A skip list that maps elements of type 'a to elements of type 'b *)
@ -53,6 +55,6 @@ val remove : ('a, 'b) t -> 'a -> unit
val length : (_, _) t -> int val length : (_, _) t -> int
(** Number of elements *) (** Number of elements *)
val gen : ('a, 'b) t -> ('a * 'b) CCGen.t val gen : ('a, 'b) t -> ('a * 'b) gen
val of_gen : ('a, 'b) t -> ('a * 'b) CCGen.t -> unit val of_gen : ('a, 'b) t -> ('a * 'b) gen -> unit

View file

@ -25,6 +25,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Small set structure} *) (** {1 Small set structure} *)
type 'a sequence = ('a -> unit) -> unit
type 'a t = { type 'a t = {
cmp : 'a -> 'a -> int; cmp : 'a -> 'a -> int;
nodes : 'a node; nodes : 'a node;
@ -123,11 +125,15 @@ let to_seq set =
iter k set iter k set
let of_seq set seq = let of_seq set seq =
CCSequence.fold add set seq let set = ref set in
seq (fun x -> set := add !set x);
!set
let to_list set = let to_list set =
CCSequence.to_rev_list (to_seq set) let l = ref [] in
to_seq set (fun x -> l := x :: !l);
!l
let of_list set l = let of_list set l =
of_seq set (CCSequence.of_list l) List.fold_left add set l

View file

@ -29,6 +29,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function. It is implemented as a sorted list, so most operations function. It is implemented as a sorted list, so most operations
are in linear time. *) are in linear time. *)
type 'a sequence = ('a -> unit) -> unit
type 'a t type 'a t
(** Set of elements of type 'a *) (** Set of elements of type 'a *)
@ -59,9 +62,9 @@ val iter : ('a -> unit) -> 'a t -> unit
val size : _ t -> int val size : _ t -> int
(** Number of elements *) (** Number of elements *)
val to_seq : 'a t -> 'a CCSequence.t val to_seq : 'a t -> 'a sequence
val of_seq : 'a t -> 'a CCSequence.t -> 'a t val of_seq : 'a t -> 'a sequence -> 'a t
val to_list : 'a t -> 'a list val to_list : 'a t -> 'a list

View file

@ -29,6 +29,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://www.cs.cornell.edu/Courses/cs3110/2009fa/recitations/rec-splay.html http://www.cs.cornell.edu/Courses/cs3110/2009fa/recitations/rec-splay.html
*) *)
type 'a sequence = ('a -> unit) -> unit
(** {2 Polymorphic Maps} *) (** {2 Polymorphic Maps} *)
type ('a, 'b) t = { type ('a, 'b) t = {
@ -192,11 +194,12 @@ let choose t =
| Node (k, v, _, _) -> k, v | Node (k, v, _, _) -> k, v
let to_seq t = let to_seq t =
CCSequence.from_iter fun kont -> iter t (fun k v -> kont (k, v))
(fun kont -> iter t (fun k v -> kont (k, v)))
let of_seq t seq = let of_seq t seq =
CCSequence.fold (fun t (k, v) -> add t k v) t seq let t = ref t in
seq (fun (k, v) -> t := add !t k v);
!t
(** {2 Functorial interface} *) (** {2 Functorial interface} *)
@ -238,9 +241,9 @@ module type S = sig
val choose : 'a t -> (key * 'a) val choose : 'a t -> (key * 'a)
(** Some binding, or raises Not_found *) (** Some binding, or raises Not_found *)
val to_seq : 'a t -> (key * 'a) CCSequence.t val to_seq : 'a t -> (key * 'a) sequence
val of_seq : 'a t -> (key * 'a) CCSequence.t -> 'a t val of_seq : 'a t -> (key * 'a) sequence -> 'a t
end end
module type ORDERED = sig module type ORDERED = sig
@ -404,9 +407,10 @@ module Make(X : ORDERED) = struct
| Node (k, v, _, _) -> k, v | Node (k, v, _, _) -> k, v
let to_seq t = let to_seq t =
CCSequence.from_iter fun kont -> iter t (fun k v -> kont (k, v))
(fun kont -> iter t (fun k v -> kont (k, v)))
let of_seq t seq = let of_seq t seq =
CCSequence.fold (fun t (k, v) -> add t k v) t seq let t = ref t in
seq (fun (k, v) -> t := add !t k v);
!t
end end

View file

@ -28,6 +28,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(* TODO: map-wide operations: merge, compare, equal, for_all, exists, (* TODO: map-wide operations: merge, compare, equal, for_all, exists,
batch (sorted) add, partition, split, max_elt, min_elt, map... *) batch (sorted) add, partition, split, max_elt, min_elt, map... *)
type 'a sequence = ('a -> unit) -> unit
(** {2 Polymorphic Maps} *) (** {2 Polymorphic Maps} *)
type ('a, 'b) t type ('a, 'b) t
@ -69,9 +72,9 @@ val size : (_, _) t -> int
val choose : ('a, 'b) t -> ('a * 'b) val choose : ('a, 'b) t -> ('a * 'b)
(** Some binding, or raises Not_found *) (** Some binding, or raises Not_found *)
val to_seq : ('a, 'b) t -> ('a * 'b) CCSequence.t val to_seq : ('a, 'b) t -> ('a * 'b) sequence
val of_seq : ('a, 'b) t -> ('a * 'b) CCSequence.t -> ('a, 'b) t val of_seq : ('a, 'b) t -> ('a * 'b) sequence -> ('a, 'b) t
(** {2 Functorial interface} *) (** {2 Functorial interface} *)
@ -113,9 +116,9 @@ module type S = sig
val choose : 'a t -> (key * 'a) val choose : 'a t -> (key * 'a)
(** Some binding, or raises Not_found *) (** Some binding, or raises Not_found *)
val to_seq : 'a t -> (key * 'a) CCSequence.t val to_seq : 'a t -> (key * 'a) sequence
val of_seq : 'a t -> (key * 'a) CCSequence.t -> 'a t val of_seq : 'a t -> (key * 'a) sequence -> 'a t
end end
module type ORDERED = sig module type ORDERED = sig

View file

@ -13,7 +13,6 @@ let suite =
Test_cc.suite; Test_cc.suite;
Test_puf.suite; Test_puf.suite;
Test_vector.suite; Test_vector.suite;
Test_gen.suite;
Test_deque.suite; Test_deque.suite;
Test_fHashtbl.suite; Test_fHashtbl.suite;
Test_fQueue.suite; Test_fQueue.suite;

View file

@ -3,8 +3,6 @@
open OUnit open OUnit
module Sequence = CCSequence
module H = CCHeap.Make(struct type t = int let leq x y =x<=y end) module H = CCHeap.Make(struct type t = int let leq x y =x<=y end)
let empty = H.empty let empty = H.empty

View file

@ -2,7 +2,6 @@
open OUnit open OUnit
module H = CCPersistentHashtbl.Make(CCInt) module H = CCPersistentHashtbl.Make(CCInt)
module Sequence = CCSequence
let test_add () = let test_add () =
let h = H.create 32 in let h = H.create 32 in

View file

@ -1,6 +1,6 @@
open OUnit open OUnit
module Sequence = CCSequence
let test_cardinal () = let test_cardinal () =
let bv1 = CCBV.create ~size:87 true in let bv1 = CCBV.create ~size:87 true in

View file

@ -2,7 +2,7 @@
open OUnit open OUnit
module Deque = CCDeque module Deque = CCDeque
module Sequence = CCSequence
let plist l = CCPrint.to_string (CCList.pp CCInt.pp) l let plist l = CCPrint.to_string (CCList.pp CCInt.pp) l
let pint i = string_of_int i let pint i = string_of_int i

View file

@ -2,7 +2,7 @@
open OUnit open OUnit
open Containers_misc open Containers_misc
module Sequence = CCSequence
module Test(SomeHashtbl : FHashtbl.S with type key = int) = struct module Test(SomeHashtbl : FHashtbl.S with type key = int) = struct
let test_add () = let test_add () =

View file

@ -2,7 +2,7 @@
open OUnit open OUnit
module FQueue = CCFQueue module FQueue = CCFQueue
module Sequence = CCSequence
let test_empty () = let test_empty () =
let q = FQueue.empty in let q = FQueue.empty in

View file

@ -2,7 +2,7 @@
open OUnit open OUnit
open Containers_misc open Containers_misc
module Sequence = CCSequence
module IHashtbl = FlatHashtbl.Make(struct module IHashtbl = FlatHashtbl.Make(struct
type t = int type t = int

View file

@ -1,132 +0,0 @@
open OUnit
open CCFun
module Gen = CCGen
module GR = Gen.Restart
let pint i = string_of_int i
let plist l =
CCPrint.to_string (CCList.pp CCInt.pp) l
let pstrlist l =
CCPrint.to_string (CCList.pp Buffer.add_string) l
let test_singleton () =
let gen = Gen.singleton 42 in
OUnit.assert_equal (Some 42) (Gen.get gen);
OUnit.assert_equal None (Gen.get gen);
let gen = Gen.singleton 42 in
OUnit.assert_equal 1 (Gen.length gen);
()
let test_iter () =
let e = GR.(1 -- 10) in
OUnit.assert_equal ~printer:pint 10 (GR.length e);
OUnit.assert_equal [1;2] GR.(to_list (1 -- 2));
OUnit.assert_equal [1;2;3;4;5] (GR.to_list (GR.take 5 e));
()
let test_map () =
let e = Gen.(1 -- 10) in
let e' = Gen.map string_of_int e in
OUnit.assert_equal ~printer:pstrlist ["9"; "10"] (Gen.to_list (Gen.drop 8 e'));
()
let test_append () =
let e = Gen.append Gen.(1 -- 5) Gen.(6 -- 10) in
OUnit.assert_equal [10;9;8;7;6;5;4;3;2;1] (Gen.to_rev_list e);
()
let test_flatMap () =
let e = Gen.(1 -- 3) in
let e' = Gen.(e >>= (fun x -> x -- (x+1))) in
OUnit.assert_equal [1;2;2;3;3;4] (Gen.to_list e');
()
let test_zip () =
let e = Gen.zip_with (+) (Gen.repeat 1) Gen.(4--7) in
OUnit.assert_equal [5;6;7;8] (Gen.to_list e);
()
let test_filterMap () =
let f x = if x mod 2 = 0 then Some (string_of_int x) else None in
let e = Gen.filter_map f Gen.(1 -- 10) in
OUnit.assert_equal ["2"; "4"; "6"; "8"; "10"] (Gen.to_list e);
()
let test_merge () =
let e = Gen.of_list [Gen.(1--3); Gen.(4--6); Gen.(7--9)] in
let e' = Gen.merge e in
OUnit.assert_equal [1;2;3;4;5;6;7;8;9] (Gen.to_list e' |> List.sort compare);
()
let test_persistent () =
let i = ref 0 in
let gen () =
let j = !i in
if j > 5 then None else (incr i; Some j)
in
let e = Gen.persistent gen in
OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
()
let test_round_robin () =
let e = GR.round_robin ~n:2 GR.(1--10) in
match e with
| [a;b] ->
OUnit.assert_equal [1;3;5;7;9] (Gen.to_list a);
OUnit.assert_equal [2;4;6;8;10] (Gen.to_list b)
| _ -> OUnit.assert_failure "wrong list lenght"
let test_big_rr () =
let e = GR.round_robin ~n:3 GR.(1 -- 999) in
let l = List.map Gen.length e in
OUnit.assert_equal [333;333;333] l;
()
let test_merge_sorted () =
[Gen.of_list [1;3;5]; Gen.of_list [0;1;1;3;4;6;10]; Gen.of_list [2;2;11]]
|> Gen.sorted_merge_n ?cmp:None
|> Gen.to_list
|> OUnit.assert_equal ~printer:Helpers.print_int_list [0;1;1;1;2;2;3;3;4;5;6;10;11]
let test_interleave () =
let e1 = Gen.of_list [1;3;5;7;9] in
let e2 = Gen.of_list [2;4;6;8;10] in
let e = Gen.interleave e1 e2 in
OUnit.assert_equal [1;2;3;4;5;6;7;8;9;10] (Gen.to_list e);
()
let test_intersperse () =
let e = Gen.(1 -- 5) in
let e' = Gen.intersperse 0 e in
OUnit.assert_equal [1;0;2;0;3;0;4;0;5] (Gen.to_list e');
()
let test_product () =
let printer = Helpers.print_int_int_list in
let e = Gen.product Gen.(1--3) Gen.(4--5) in
OUnit.assert_equal ~printer [1,4; 1,5; 2,4; 2,5; 3,4; 3,5]
(List.sort compare (Gen.to_list e));
()
let suite =
"test_gen" >:::
[ "test_singleton" >:: test_singleton;
"test_iter" >:: test_iter;
"test_map" >:: test_map;
"test_append" >:: test_append;
"test_flatMap" >:: test_flatMap;
"test_zip" >:: test_zip;
"test_filterMap" >:: test_filterMap;
"test_merge" >:: test_merge;
"test_persistent" >:: test_persistent;
"test_round_robin" >:: test_round_robin;
"test_big_rr" >:: test_big_rr;
"test_merge_sorted" >:: test_merge_sorted;
"test_interleave" >:: test_interleave;
"test_intersperse" >:: test_intersperse;
"test_product" >:: test_product;
]

View file

@ -5,7 +5,7 @@ open OUnit
open Helpers open Helpers
open Containers_misc open Containers_misc
module Sequence = CCSequence
module G = PersistentGraph module G = PersistentGraph
(* build a graph from a list of pairs of ints *) (* build a graph from a list of pairs of ints *)

View file

@ -3,7 +3,7 @@
open OUnit open OUnit
open Helpers open Helpers
open Containers_misc open Containers_misc
module Sequence = CCSequence
let test_empty () = let test_empty () =
let h = Heap.empty ~cmp:(fun x y -> x - y) in let h = Heap.empty ~cmp:(fun x y -> x - y) in

View file

@ -66,7 +66,7 @@ let test_keys () =
Mixtbl.set ~inj:inj_int tbl "foo" 1; Mixtbl.set ~inj:inj_int tbl "foo" 1;
Mixtbl.set ~inj:inj_int tbl "bar" 2; Mixtbl.set ~inj:inj_int tbl "bar" 2;
Mixtbl.set ~inj:inj_str tbl "baaz" "hello"; Mixtbl.set ~inj:inj_str tbl "baaz" "hello";
let l = Mixtbl.keys_seq tbl |> CCSequence.to_list in let l = Mixtbl.keys_seq tbl |> Sequence.to_list in
OUnit.assert_equal ["baaz"; "bar"; "foo"] (List.sort compare l); OUnit.assert_equal ["baaz"; "bar"; "foo"] (List.sort compare l);
() ()
@ -78,9 +78,9 @@ let test_bindings () =
Mixtbl.set ~inj:inj_int tbl "bar" 2; Mixtbl.set ~inj:inj_int tbl "bar" 2;
Mixtbl.set ~inj:inj_str tbl "baaz" "hello"; Mixtbl.set ~inj:inj_str tbl "baaz" "hello";
Mixtbl.set ~inj:inj_str tbl "str" "rts"; Mixtbl.set ~inj:inj_str tbl "str" "rts";
let l_int = Mixtbl.bindings_of tbl ~inj:inj_int |> CCSequence.to_list in let l_int = Mixtbl.bindings_of tbl ~inj:inj_int |> Sequence.to_list in
OUnit.assert_equal ["bar", 2; "foo", 1] (List.sort compare l_int); OUnit.assert_equal ["bar", 2; "foo", 1] (List.sort compare l_int);
let l_str = Mixtbl.bindings_of tbl ~inj:inj_str |> CCSequence.to_list in let l_str = Mixtbl.bindings_of tbl ~inj:inj_str |> Sequence.to_list in
OUnit.assert_equal ["baaz", "hello"; "str", "rts"] (List.sort compare l_str); OUnit.assert_equal ["baaz", "hello"; "str", "rts"] (List.sort compare l_str);
() ()

View file

@ -2,7 +2,7 @@
open OUnit open OUnit
open Containers_misc open Containers_misc
module Sequence = CCSequence
let test_add () = let test_add () =
let h = PHashtbl.create 5 in let h = PHashtbl.create 5 in

View file

@ -2,7 +2,7 @@
open OUnit open OUnit
open Containers_misc open Containers_misc
module Sequence = CCSequence
let test1 () = let test1 () =
let empty = SplayMap.empty () in let empty = SplayMap.empty () in

View file

@ -2,7 +2,7 @@
open OUnit open OUnit
module Vector = CCVector module Vector = CCVector
module Sequence = CCSequence
let test_clear () = let test_clear () =
let v = Vector.of_seq Sequence.(1 -- 10) in let v = Vector.of_seq Sequence.(1 -- 10) in

View file

@ -15,9 +15,9 @@ let test_mvar () =
() ()
let test_parallel () = let test_parallel () =
let l = CCSequence.(1 -- 300) in let l = Sequence.(1 -- 300) in
let l = CCSequence.map (fun _ -> Future.spawn (fun () -> Thread.delay 0.1; 1)) l in let l = Sequence.map (fun _ -> Future.spawn (fun () -> Thread.delay 0.1; 1)) l in
let l = CCSequence.to_list l in let l = Sequence.to_list l in
let l' = List.map Future.get l in let l' = List.map Future.get l in
OUnit.assert_equal 300 (List.fold_left (+) 0 l'); OUnit.assert_equal 300 (List.fold_left (+) 0 l');
() ()