It'd work like this:

$ cat foo.ml

let double x = if x = 0 then 0 else 2

$ measure_code < foo.ml

(*

val double : int -> int

Estimated time complexity: O(1) (average runtime 0.01us)

Estimated space complexity: O(1) (allocated an average 8 bytes)

Hypothesis:

double 0 -> 0

forall x:int, double x -> 2

*)

(**T double_against_Int_gen

double 0 = 0

double 1 = 2

double (-1) = 2

double 2 = 2

double 3 = 2

double max_int = 2

double min_int = 2

map double (map (fun i -> 1 lsl i) (0--61)) = replicate 62 2

map double (map (fun i -> -1 lsl i) (0--61)) = replicate 62 2

map double [] = []

**)

And a sketch of the value generator:

module Int_gen =

struct

let zero = 0

let one = 1

let minus_one = -1

let even = 2

let odd = 3

let max_val = max_int

let min_val = min_int

let ever_larger = fun i -> 1 lsl i

let ever_smaller = fun i -> -1 lsl i

let larger_limit = 61

let smaller_limit = 61

let extras = []

end

module Float_gen =

struct

let zero = 0.

let one = 1.

let minus_one = -1.

let even = 2.

let odd = 3.

let max_val = max_float

let min_val = -.max_float

let ever_larger = fun i -> 0.1 *. 2. ** (float i)

let ever_smaller = fun i -> -0.1 *. 2. ** (float i)

let larger_limit = 200

let smaller_limit = 200

let extras = [nan, min_float, -.min_float, infinity, neg_infinity, 1e-320, -1e320]

end

module List_gen (G:GENERATOR) =

struct

let zero = []

let one = [G.one]

let minus_one = [G.minus_one]

let even = [G.zero; G.one]

let odd = [G.minus_one; G.zero; G.one]

let max_val = [G.max_val]

let min_val = [G.min_val]

let ever_larger = fun i -> replicate (1 lsl i) G.one

let ever_smaller = fun i -> []

let larger_limit = 8

let smaller_limit = 0

let extras = [[G.one; G.zero]; [G.max_val; G.min_val]; G.extras]

end