(* TEST include config; include testing; binary_modules = "config build_path_prefix_map format_doc misc"; bytecode; *) let check_and_count_calls n = let calls = ref 0 in let res = Misc.find_first_mono (fun i -> incr calls; i >= n) in assert (res = n); !calls let report i = let calls = check_and_count_calls i in Printf.printf "%d: %d calls\n%!" i calls let () = print_endline "Testing small values"; let small_tests = List.init 20 (fun i -> i) in List.iter report small_tests; print_newline () let () = print_endline "Testing around max_int/2"; (* we do not use [report] to show the test output, as the output depends on the value of [max_int], so it is not portable across integer sizes. *) let median_tests = List.map (fun i -> max_int / 2 + i) [-2; -1; 0; 1; 2] in List.map check_and_count_calls median_tests |> ignore; print_newline () let () = print_endline "Testing around max_int"; (* see above for why we do not use [report] *) let max_int_tests = List.map (fun i -> max_int + i) [-4; -3; -2; -1; 0] in List.map check_and_count_calls max_int_tests |> ignore; print_newline () let () = let n = 100 in Printf.printf "Showing predicate calls for find_first_mono to find n=%d\n%!" n; let res = Misc.find_first_mono (fun i -> Printf.printf "call on %d\n%!" i; i >= n) in Printf.printf "result: %d\n%!" res; print_newline () let () = print_endline "Test constantly-false predicates"; print_endline "Constantly-false predicates are outside the spec,\n\ but we ask them to return [max_int] rather than loop or crash."; let res = Misc.find_first_mono (fun _ -> false) in assert (res = max_int); print_newline () let () = print_endline "Test non-monotonous predicates"; print_endline "Non-monotonous predicates are outside the spec,\n\ but we ask them to find a satisfying value rather than loop or crash\n\ as long as they are asymptotically true."; (* We generate predicates that are true above 1000 but are sometimes-true before that. *) for n = 1 to 499 do let pred i = i >= 1000 || (i > n && i mod n = 0) in let res = Misc.find_first_mono pred in assert (pred res) done; print_newline ()