Stateful.PoolA pool of previously generated values. They are populated with the results of rules and may be used as arguments to later rules. A pool lets data flow from one rule to another, so a rule can act on a handle or identifier that an earlier rule produced rather than on a freshly drawn value.
Create one with create and populate it with add. To draw from the pool, use the following generators:
values_reusable: drawing from it returns a value in the pool without removing it.values_consumed: drawing from it removes a value from the pool and returns it.Example: a resource allocator. The alloc rule creates a fresh handle and deposits it in the pool. The free rule draws one of those handles back out and releases it. Without a pool, free would have no way to name a handle that a previous alloc actually created. It could only draw an arbitrary integer, most of which name no live resource.
type state =
{ live : Int.Set.t
; handles : int Stateful.Pool.t
}
let alloc =
Stateful.Rule.create ~name:"alloc" ~step:(fun _tc state ->
let h = fresh_handle () in
Stateful.Pool.add state.handles h;
{ state with live = Set.add state.live h })
let free =
Stateful.Rule.create ~name:"free" ~step:(fun tc state ->
(* draws a handle a prior [alloc] put in the pool *)
let h = draw_silent tc (Stateful.Pool.values_consumed state.handles) in
release h;
{ state with live = Set.remove state.live h })Creates an empty Pool.t. Pools are tied to a test case; do not reuse one across test cases.
val add : 'a t -> 'a -> unitRecords value in variables for later draws.
let n = draw tc (Generators.integers ~min_value:0 ~max_value:100 ()) in
Stateful.Pool.add pool nval size : _ t -> intReturns the number of variables in the pool.
assume tc (Stateful.Pool.size pool > 0)val values_reusable : 'a t -> ('a, Generators.unprintable) Generators.generatorCreate an unprintable generator that returns a variable from the pool without removing it. Calls assume false if the pool is empty.
let existing = draw_silent tc (Stateful.Pool.values_reusable pool)val values_consumed : 'a t -> ('a, Generators.unprintable) Generators.generatorCreate an unprintable generator that removes and returns a variable from the pool. Calls assume false if the pool is empty.
let taken = draw_silent tc (Stateful.Pool.values_consumed pool)