### Example bitstring representation Source: https://github.com/stedolan/crowbar/wiki/Design-notes Shows the binary representation of a tree structure. ```text 01 01 00 00 00 00 01 00 00 00 00 05 00 00 00 00 00 ``` -------------------------------- ### Testing Map Implementation Consistency Source: https://context7.com/stedolan/crowbar/llms.txt A comprehensive example for testing a map implementation using Crowbar. It generates and verifies states involving lists and maps to ensure consistency. ```ocaml open Crowbar module IntMap = Map.Make(Int) (* Build map and list in parallel to verify consistency *) type test_state = (int * int) list * int IntMap.t let state_gen : test_state gen = fix (fun self -> choose [ (* Empty state *) const ([], IntMap.empty); (* Add an element *) map [uint8; uint8; self] (fun k v (lst, map) -> ((k, v) :: lst, IntMap.add k v map)); (* Remove an element *) map [uint8; self] (fun k (lst, map) -> let rec remove_all key = function | [] -> [] | (k', _) :: rest when k' = key -> remove_all key rest | x :: rest -> x :: remove_all key rest in (remove_all k lst, IntMap.remove k map)); (* Merge two states *) map [self; self] (fun (lst1, map1) (lst2, map2) -> (lst1 @ lst2, IntMap.union (fun _ a _ -> Some a) map1 map2)) ]) let verify_state ((lst, map) : test_state) = (* Deduplicate list keeping last occurrence *) let dedup lst = let tbl = Hashtbl.create 16 in List.iter (fun (k, v) -> Hashtbl.replace tbl k v) lst; Hashtbl.fold (fun k v acc -> (k, v) :: acc) tbl [] |> List.sort (fun (a, _) (b, _) -> compare a b) in let expected = dedup lst in let actual = IntMap.bindings map in expected = actual let () = add_test ~name:"map consistency" [state_gen] (fun state -> check (verify_state state)) ``` -------------------------------- ### Generate Strings with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Generates strings of arbitrary length, including empty strings. The example verifies that the length of a generated string is non-negative. ```ocaml open Crowbar let () = add_test ~name:"string length" [bytes] (fun s -> check (String.length s >= 0)) ``` -------------------------------- ### Generate Random Integers with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Demonstrates generating a random integer and testing an identity property. Use this for general integer generation. The example also shows how to run tests in QuickCheck-like random mode or AFL fuzzing mode. ```ocaml open Crowbar (* Generate a random integer and test properties *) let () = add_test ~name:"integer identity" [int] (fun i -> check_eq i i) (* Run from command line: $ ./test.exe # Quick random testing mode $ afl-fuzz -i input -o output ./test.exe @@ # AFL mode *) ``` -------------------------------- ### Generate Floating-Point Numbers with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Generates double-precision floating-point numbers. The example tests for finite results of addition, allowing for NaN. ```ocaml open Crowbar let () = add_test ~name:"float arithmetic" [float; float] (fun a b -> guard (Float.is_finite a && Float.is_finite b); check (Float.is_finite (a +. b) || Float.is_nan (a +. b))) ``` -------------------------------- ### Generate 32-bit and 64-bit Integers with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Generates signed 32-bit integers using `int32` and signed 64-bit integers using `int64`. The example demonstrates arithmetic properties for `int32`. ```ocaml open Crowbar let () = add_test ~name:"int32 arithmetic" [int32; int32] (fun a b -> let sum = Int32.add a b in check_eq ~pp:pp_int32 (Int32.sub sum b) a) ``` -------------------------------- ### Generate Fixed-Length Strings with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Generates strings of a specified fixed length. The example tests that a string generated with `bytes_fixed 10` has a length of exactly 10. ```ocaml open Crowbar let () = add_test ~name:"fixed length string" [bytes_fixed 10] (fun s -> check_eq ~pp:pp_int (String.length s) 10) ``` -------------------------------- ### Generate Boolean Values with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Generates `true` or `false` values. The example tests the commutativity of logical AND and OR operations. ```ocaml open Crowbar let () = add_test ~name:"boolean logic" [bool; bool] (fun a b -> check_eq (a && b) (b && a); (* commutativity *) check_eq (a || b) (b || a)) ``` -------------------------------- ### Generate 8-bit Integers with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Generates unsigned bytes (0-255) using `uint8` and signed bytes (-128 to 127) using `int8`. The examples test the bounds of these generators. ```ocaml open Crowbar (* Test byte range operations *) let () = add_test ~name:"byte bounds" [uint8] (fun b -> check (b >= 0 && b <= 255)) let () = add_test ~name:"signed byte bounds" [int8] (fun b -> check (b >= -128 && b <= 127)) ``` -------------------------------- ### Generate 16-bit Integers with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Generates unsigned 16-bit integers (0-65535) with `uint16` and signed 16-bit integers (-32768 to 32767) with `int16`. The example verifies the range of `uint16`. ```ocaml open Crowbar let () = add_test ~name:"uint16 range" [uint16] (fun n -> check (n >= 0 && n <= 65535)) ``` -------------------------------- ### Generate Integers in a Range with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Generates integers within a specified range. `range ~min:1 6` generates numbers from 1 up to (but not including) 1 + 6, effectively producing values from 1 to 6. The second example shows generating array indices within the bounds of an array. ```ocaml open Crowbar (* Generate numbers from 1 to 100 *) let dice = range ~min:1 6 (* 1, 2, 3, 4, 5, or 6 *) let () = add_test ~name:"dice roll" [dice] (fun d -> check (d >= 1 && d <= 6)) (* Generate array indices *) let () = add_test ~name:"array access" [list1 int] (fun lst -> let arr = Array.of_list lst in let idx_gen = range (Array.length arr) in add_test ~name:"safe access" [idx_gen] (fun i -> check (arr.(i) = arr.(i)))) ``` -------------------------------- ### Generate Characters with Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Generates ASCII characters using `char` and Unicode scalar values using `uchar`. The example checks that the generated ASCII character's code is within the valid byte range. ```ocaml open Crowbar let () = add_test ~name:"char codes" [char] (fun c -> let code = Char.code c in check (code >= 0 && code <= 255)) ``` -------------------------------- ### Generate Constant Values with `const` in Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Always generates the same constant value. Examples include generating a constant integer `0` or an empty list `[]`. The test verifies that a constant value of 42 is generated. ```ocaml open Crowbar let zero = const 0 let empty_list = const [] let () = add_test ~name:"constant value" [const 42] (fun n -> check_eq n 42) ``` -------------------------------- ### Running Crowbar Tests Source: https://context7.com/stedolan/crowbar/llms.txt Demonstrates how to run Crowbar tests in quickcheck mode (random testing) and AFL mode (coverage-guided fuzzing). Includes options for seeding, iterations, and reproducing failures. ```shell # Quickcheck mode (random testing) ./my_test.exe # With specific seed for reproducibility ./my_test.exe -s 12345 # More iterations ./my_test.exe -r 10000 # AFL fuzzing mode mkdir -p input output echo "seed" > input/seed afl-fuzz -i input -o output ./my_test.exe @@ # Reproduce a failing case ./my_test.exe output/crashes/id:000000 # Verbose output ./my_test.exe -v ``` -------------------------------- ### Naive QuickCheck Algorithm Source: https://github.com/stedolan/crowbar/wiki/Design-notes A basic testing loop that generates random test cases and checks for failures. 'N' represents the number of iterations. ```pseudocode N times { let t = generate a random testcase if t fails { print t } } ``` -------------------------------- ### Configure AFL environment Source: https://github.com/stedolan/crowbar/blob/master/README.md Commands to switch to an AFL-instrumented OCaml compiler environment. ```shell $ opam switch 4.06.0+afl $ eval `opam config env` $ ./build_my_rad_test.sh # or your relevant build runes ``` -------------------------------- ### Crowbar Syntax Module: Binding Operators Source: https://context7.com/stedolan/crowbar/llms.txt Demonstrates modern OCaml syntax for generators using binding operators like let+, let*, and+. Useful for mapping, combining, and dynamically binding generators. ```ocaml open Crowbar open Crowbar.Syntax (* let+ for mapping *) let uppercase_char : char gen = let+ c = char in Char.uppercase_ascii c (* and+ for combining generators (like pair) *) let point_gen : (int * int) gen = let+ x = int and+ y = int in (x, y) (* let* for dynamic binding *) let sized_list : int list gen = let* size = range ~min:1 10 in let rec gen_list n = if n <= 0 then const [] else let+ hd = int and+ tl = gen_list (n - 1) in hd :: tl in gen_list size let () = add_test ~name:"sized list length" [sized_list] (fun lst -> check (List.length lst >= 1 && List.length lst <= 10)) ``` -------------------------------- ### Random Walk Algorithm for Test Case Generation Source: https://github.com/stedolan/crowbar/wiki/Design-notes This pseudocode outlines a random walk strategy for generating test cases. It uses a queue to manage test cases and mutates existing ones to create new ones, with a focus on identifying failing test cases. ```pseudocode q := a queue with a single small test case N times { let t = remove item from q M times { let t' = mutate t add t' to q if t' fails { print t } } } ``` -------------------------------- ### Run random test mode Source: https://github.com/stedolan/crowbar/blob/master/README.md Executing the test binary without arguments triggers the simple random testing mode. ```shell $ ./my_rad_test.exe | head -5 the first test: PASS the second test: PASS ``` -------------------------------- ### Use Built-in Pretty Printers Source: https://context7.com/stedolan/crowbar/llms.txt Crowbar provides standard printers for common types to ensure clear output during test failures. ```ocaml open Crowbar (* Available printers *) let _ = pp_int (* int printer *) let _ = pp_int32 (* Int32.t printer *) let _ = pp_int64 (* Int64.t printer *) let _ = pp_float (* float printer *) let _ = pp_bool (* bool printer *) let _ = pp_string (* string printer *) let _ = pp_list (* list printer - takes element printer *) let _ = pp_option (* option printer - takes element printer *) (* Usage in check_eq *) let () = add_test ~name:"list concat" [list int; list int] (fun a b -> let ab = a @ b in check_eq ~pp:(pp_list pp_int) (List.length ab) (List.length a + List.length b)) ``` -------------------------------- ### Register a test case Source: https://github.com/stedolan/crowbar/blob/master/README.md Use Crowbar.add_test to register a test function with a name and a generator for input types. ```ocaml let () = Crowbar.(add_test ~name:"identity function" [int] (fun i -> identity i)) ``` -------------------------------- ### Define a property test Source: https://github.com/stedolan/crowbar/blob/master/README.md Use Crowbar.check_eq to define a property that should hold true for the given input. ```ocaml let identity x = Crowbar.check_eq x x ``` -------------------------------- ### Generate Lists Source: https://context7.com/stedolan/crowbar/llms.txt `list` generates lists of any length (including empty), `list1` generates non-empty lists. Use for testing list-processing functions. ```ocaml open Crowbar let () = add_test ~name:"list reverse" [list int] (fun lst -> check_eq (List.rev (List.rev lst)) lst) let () = add_test ~name:"non-empty list" [list1 int] (fun lst -> check (List.length lst >= 1)) ``` -------------------------------- ### Attach Custom Printers with with_printer Source: https://context7.com/stedolan/crowbar/llms.txt Attaches a pretty-printer to a generator to improve error messages during test failures. ```ocaml open Crowbar type color = Red | Green | Blue let pp_color ppf = function | Red -> pp ppf "Red" | Green -> pp ppf "Green" | Blue -> pp ppf "Blue" let color_gen = with_printer pp_color @@ choose [const Red; const Green; const Blue] let () = add_test ~name:"color identity" [color_gen; color_gen] (fun c1 c2 -> guard (c1 = c2); check_eq ~pp:pp_color c1 c2) ``` -------------------------------- ### Unwrap Options or Skip with nonetheless Source: https://context7.com/stedolan/crowbar/llms.txt Unwraps an option value, or skips the test case if the value is None. ```ocaml open Crowbar let () = add_test ~name:"find and use" [list (pair int bytes); int] (fun assoc key -> let value = nonetheless (List.assoc_opt key assoc) in check (String.length value >= 0)) ``` -------------------------------- ### Run AFL fuzzing mode Source: https://github.com/stedolan/crowbar/blob/master/README.md Invoke the test binary using afl-fuzz to perform coverage-guided property testing. ```shell afl-fuzz -i test/input -o output ./my_rad_test.exe @@ ``` -------------------------------- ### Custom Printer for Person Type Source: https://context7.com/stedolan/crowbar/llms.txt Defines a custom printer for the 'person' type using Format.fprintf for structured output. Requires the 'person' type definition and the 'pp_person' function. ```ocaml open Crowbar type person = { name: string; age: int } let pp_person ppf p = pp ppf "{ name = %S; age = %d }" p.name p.age let person_gen = with_printer pp_person @@ map [bytes; range 120] (fun name age -> { name; age }) let () = add_test ~name:"person age" [person_gen] (fun p -> check (p.age >= 0 && p.age < 120)) ``` -------------------------------- ### Assert Equality with check_eq Source: https://context7.com/stedolan/crowbar/llms.txt Verifies that two values are equal, supporting optional custom equality functions and pretty-printers. ```ocaml open Crowbar (* Basic equality check *) let () = add_test ~name:"reverse twice" [list int] (fun lst -> check_eq (List.rev (List.rev lst)) lst) (* With custom printer for better error messages *) let () = add_test ~name:"sort idempotent" [list int] (fun lst -> let sorted = List.sort compare lst in check_eq ~pp:(pp_list pp_int) (List.sort compare sorted) sorted) (* With custom comparison *) let () = add_test ~name:"float equality" [float; float] (fun a b -> guard (Float.is_finite a && Float.is_finite b); let sum = a +. b in check_eq ~cmp:Float.compare ~pp:pp_float sum (b +. a)) (* With custom equality function *) let () = add_test ~name:"set equality" [list int; list int] (fun a b -> let set_eq xs ys = let xs = List.sort_uniq compare xs in let ys = List.sort_uniq compare ys in xs = ys in guard (set_eq a b); check_eq ~eq:set_eq a b) ``` -------------------------------- ### Crowbar Fuzzing Algorithm Pseudocode Source: https://github.com/stedolan/crowbar/wiki/Design-notes This pseudocode outlines the core fuzzing loop used by Crowbar, involving a queue of test cases, mutation, and checking for new coverage or failures. ```pseudocode * q := a queue with a single small test case * N times { * let t = remove item from q * M times { * let t' = mutate t if t' fails { print t } * if t' did something new { * add t' to q * } * } * } ``` -------------------------------- ### Parsed bitstring structure Source: https://github.com/stedolan/crowbar/wiki/Design-notes Visualizes how the bitstring maps to the tree structure. ```text 01 01 00 00 00 00 01 00 00 00 00 05 00 00 00 00 00 B [B [L -- int32: 1 --] [L -- int32: 5 --][ L -- int32: 0 --]] ``` -------------------------------- ### with_printer Source: https://context7.com/stedolan/crowbar/llms.txt Attaches a custom pretty-printer to a generator to improve error messages during test failures. ```APIDOC ## with_printer ### Description Attaches a pretty-printer to a generator for better error messages on test failures. ### Parameters - **pp** (function) - Required - The pretty-printing function (ppf -> 'a -> unit). - **gen** (generator) - Required - The generator to attach the printer to. ``` -------------------------------- ### Generate Arrays Source: https://context7.com/stedolan/crowbar/llms.txt `array` generates arrays of any length (including empty), `array1` generates non-empty arrays. Use for testing array-manipulating code. ```ocaml open Crowbar let () = add_test ~name:"array to list roundtrip" [array int] (fun arr -> check_eq (Array.of_list (Array.to_list arr)) arr) ``` -------------------------------- ### Register Property Tests with add_test Source: https://context7.com/stedolan/crowbar/llms.txt Registers test functions with generators. Tests are executed automatically when the program runs. ```ocaml open Crowbar (* Basic test registration *) let () = add_test ~name:"addition commutes" [int; int] (fun a b -> check_eq (a + b) (b + a)) (* Test with multiple generators *) let () = add_test ~name:"list operations" [list int; int] (fun lst elem -> let extended = elem :: lst in check_eq (List.hd extended) elem; check_eq (List.tl extended) lst) (* Anonymous test (auto-generated name) *) let () = add_test [bool] (fun b -> check (b || not b)) ``` -------------------------------- ### check_eq Source: https://context7.com/stedolan/crowbar/llms.txt Asserts that two values are equal, supporting custom equality and printing. ```APIDOC ## check_eq ### Description Checks that two values are equal, with optional custom equality function and pretty-printer. ### Parameters - **pp** (function) - Optional - Custom pretty-printer. - **cmp** (function) - Optional - Custom comparison function. - **eq** (function) - Optional - Custom equality function. - **val1** (any) - Required - First value to compare. - **val2** (any) - Required - Second value to compare. ``` -------------------------------- ### Fail with Message using fail / failf Source: https://context7.com/stedolan/crowbar/llms.txt Explicitly triggers a test failure with a custom message or formatted string. ```ocaml open Crowbar let () = add_test ~name:"invariant check" [list int] (fun lst -> let sorted = List.sort compare lst in let rec is_sorted = function | [] | [_] -> true | a :: b :: rest -> a <= b && is_sorted (b :: rest) in if not (is_sorted sorted) then fail "List.sort produced unsorted output" else check true) (* With formatted message *) let () = add_test ~name:"bounds check" [int] (fun n -> if n < -1000 || n > 1000 then failf "Value %d out of expected range [-1000, 1000]" n else check true) ``` -------------------------------- ### Generate Random Permutations Source: https://context7.com/stedolan/crowbar/llms.txt Generates random permutations of a given list. Useful for testing algorithms that rely on order independence. ```ocaml open Crowbar let shuffled_cards = shuffle [1; 2; 3; 4; 5] let () = add_test ~name:"shuffle preserves elements" [shuffled_cards] (fun deck -> check_eq (List.sort compare deck) [1; 2; 3; 4; 5]) ``` -------------------------------- ### add_test Source: https://context7.com/stedolan/crowbar/llms.txt Registers a property test function with a list of generators. ```APIDOC ## add_test ### Description Registers a test function with generators. Tests are run when the program executes. ### Parameters - **name** (string) - Optional - The name of the test. - **generators** (list) - Required - A list of generators for the test inputs. - **f** (function) - Required - The test function to execute. ``` -------------------------------- ### Choose Between Generators Source: https://context7.com/stedolan/crowbar/llms.txt Randomly selects one generator from a list to produce a value. Useful for generating data that can take on multiple distinct forms. ```ocaml open Crowbar (* Generate either small or large numbers *) let bimodal_int = choose [ range 10; (* small numbers: 0-9 *) range ~min:1000 100 (* large numbers: 1000-1099 *) ] (* Generate a binary tree *) type tree = Leaf | Node of tree * int * tree let tree_gen = fix (fun tree_gen -> choose [ const Leaf; map [tree_gen; int; tree_gen] (fun l v r -> Node (l, v, r)) ]) let () = add_test ~name:"tree size" [tree_gen] (fun t -> let rec size = function | Leaf -> 0 | Node (l, _, r) -> 1 + size l + size r in check (size t >= 0)) ``` -------------------------------- ### Generator Termination Algorithm Source: https://github.com/stedolan/crowbar/wiki/Design-notes An improved testing algorithm that generates random 'smallish' test cases to ensure generator termination. 'N' represents the number of iterations. ```pseudocode N times { let t = generate a random smallish testcase if t fails { print t } } ``` -------------------------------- ### Generate Optional Values Source: https://context7.com/stedolan/crowbar/llms.txt Wraps a generator to produce `Some value` or `None`. Use when a value may or may not be present. ```ocaml open Crowbar let optional_int = option int let () = add_test ~name:"option handling" [optional_int] (fun opt -> match opt with | None -> check true | Some n -> check (n = n)) ``` -------------------------------- ### Generate Result Values Source: https://context7.com/stedolan/crowbar/llms.txt Generates either `Ok value` or `Error value`. Useful for testing functions that return `result` types. ```ocaml open Crowbar let int_or_string = result int bytes let () = add_test ~name:"result handling" [int_or_string] (fun r -> match r with | Ok n -> check (n = n) | Error s -> check (String.length s >= 0)) ``` -------------------------------- ### guard Source: https://context7.com/stedolan/crowbar/llms.txt Aborts the current test case without failure if the condition is false. ```APIDOC ## guard ### Description Aborts the current test case without recording a failure. Use to filter out invalid inputs. ### Parameters - **condition** (bool) - Required - The condition that must be true to proceed. ``` -------------------------------- ### Generate Pairs Source: https://context7.com/stedolan/crowbar/llms.txt Combines two generators to produce tuples. Suitable for generating structured data with multiple components. ```ocaml open Crowbar let coord = pair int int let () = add_test ~name:"pair swap" [coord] (fun (a, b) -> let (b', a') = (b, a) in check_eq a a'; check_eq b b') ``` -------------------------------- ### check Source: https://context7.com/stedolan/crowbar/llms.txt Asserts a boolean condition, failing the test if the condition is false. ```APIDOC ## check ### Description Fails the test if the boolean condition is false. ### Parameters - **condition** (bool) - Required - The boolean expression to verify. ``` -------------------------------- ### fail / failf Source: https://context7.com/stedolan/crowbar/llms.txt Explicitly fails a test with a custom message. ```APIDOC ## fail / failf ### Description Explicitly fails the test with a custom message. failf supports formatted strings. ### Parameters - **message** (string) - Required - The failure message. ``` -------------------------------- ### Skip Invalid Test Cases with guard Source: https://context7.com/stedolan/crowbar/llms.txt Aborts the current test case without recording a failure, useful for filtering out invalid inputs. ```ocaml open Crowbar let () = add_test ~name:"division" [int; int] (fun a b -> guard (b <> 0); (* Skip division by zero *) check_eq ((a / b) * b + (a mod b)) a) let () = add_test ~name:"positive only" [int] (fun n -> guard (n > 0); check (n * 2 > n)) ``` -------------------------------- ### Define a recursive generator Source: https://github.com/stedolan/crowbar/wiki/Design-notes Defines a recursive generator for a tree structure using Crowbar's combinators. ```OCaml type t = L of Int32.t | B of t * t let gen = rec (fun g -> choose [ map [int32] (fun n -> L n); map [g; g] (fun x y -> B (x, y))] ``` -------------------------------- ### Transform Generated Values with `map` in Crowbar Source: https://context7.com/stedolan/crowbar/llms.txt Transforms the output of generators using a mapping function. This allows for creating custom data types like `point` or specialized character generators, such as `safe_char_gen` for printable ASCII. ```ocaml open Crowbar (* Create a custom type generator *) type point = { x: int; y: int } let point_gen : point gen = map [int; int] (fun x y -> { x; y }) (* Character generator from uint8 *) let safe_char_gen : char gen = map [range ~min:32 95] Char.chr (* printable ASCII *) let () = add_test ~name:"point creation" [point_gen] (fun p -> check (p.x = p.x && p.y = p.y)) ``` -------------------------------- ### Explicitly Skip Test Case with bad_test Source: https://context7.com/stedolan/crowbar/llms.txt Marks the current test case as invalid and skips it explicitly. ```ocaml open Crowbar let () = add_test ~name:"parse valid only" [bytes] (fun s -> match int_of_string s with | n -> check (n = n) | exception Failure _ -> bad_test ()) ``` -------------------------------- ### Assert Boolean Conditions with check Source: https://context7.com/stedolan/crowbar/llms.txt Fails the test if the provided boolean condition evaluates to false. ```ocaml open Crowbar let () = add_test ~name:"positive squares" [int] (fun n -> guard (n <> 0); check (n * n > 0)) ``` -------------------------------- ### Concatenate String Generators Source: https://context7.com/stedolan/crowbar/llms.txt Concatenates a list of string generators with a separator. Ideal for generating structured string data like CSV or delimited records. ```ocaml open Crowbar let csv_row = concat_gen_list (const ",") [bytes; bytes; bytes] let () = add_test ~name:"csv format" [csv_row] (fun row -> let parts = String.split_on_char ',' row in check (List.length parts >= 1)) ``` -------------------------------- ### Force Lazy Generators Source: https://context7.com/stedolan/crowbar/llms.txt Forces evaluation of a lazy generator, useful for defining recursive generators that might otherwise cause infinite loops. Use when a generator's definition depends on itself. ```ocaml open Crowbar type expr = Num of int | Add of expr * expr let rec expr_gen = lazy ( choose [ map [int] (fun n -> Num n); map [unlazy expr_gen; unlazy expr_gen] (fun a b -> Add (a, b)) ]) let lazy expr_gen = expr_gen let () = add_test ~name:"expr evaluation" [expr_gen] (fun e -> let rec eval = function | Num n -> n | Add (a, b) -> eval a + eval b in check (eval e = eval e)) ``` -------------------------------- ### Define Recursive Generators Source: https://context7.com/stedolan/crowbar/llms.txt Defines generators for recursive data types using a fixed-point combinator. Essential for generating complex, self-referential structures. ```ocaml open Crowbar (* Binary tree with fix *) type 'a tree = Leaf of 'a | Branch of 'a tree * 'a tree let tree_gen (elem_gen : 'a gen) : 'a tree gen = fix (fun self -> choose [ map [elem_gen] (fun x -> Leaf x); map [self; self] (fun l r -> Branch (l, r)) ]) let () = add_test ~name:"tree leaves" [tree_gen int] (fun t -> let rec count_leaves = function | Leaf _ -> 1 | Branch (l, r) -> count_leaves l + count_leaves r in check (count_leaves t >= 1)) ``` -------------------------------- ### Dependent Generation Source: https://context7.com/stedolan/crowbar/llms.txt Creates generators where the structure depends on previously generated values. Use sparingly as it limits fuzzing optimizations. Suitable for scenarios where subsequent data must relate to prior data. ```ocaml open Crowbar (* Generate a list and then an index into that list *) let list_with_index : (int list * int) gen = dynamic_bind (list1 int) (fun lst -> map [range (List.length lst)] (fun i -> (lst, i))) let () = add_test ~name:"safe list access" [list_with_index] (fun (lst, i) -> let elem = List.nth lst i in check (List.mem elem lst)) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.