package ortac-runtime-qcheck-stm
Runtime support library for Ortac/QCheck-STM-generated code
Install
Dune Dependency
Authors
Maintainers
Sources
0.7.0.tar.gz
md5=1429cb7ec517060772f97504d84ff789
sha512=498e1b40dd29f5feef3df5fa54f924c7b53f24726b1613a5d8dd7ef8ca16b8cf97a76b9fd2951f32143b59a67b8d80fe13b081890fca07787a5a5fda30102a97
doc/src/ortac-runtime-qcheck-stm/ortac_runtime_qcheck_stm.ml.html
Source file ortac_runtime_qcheck_stm.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
open STM include Ortac_runtime type expected_result = | Value of res | Protected_value of res | Exception of string | Out_of_domain type report = { mod_name : string; init_sut : string; ret : expected_result; cmd : string; terms : (string * location) list; } let report mod_name init_sut ret cmd terms = { mod_name; init_sut; ret; cmd; terms } let append a b = match (a, b) with | None, None -> None | Some _, None -> a | None, Some _ -> b | Some r0, Some r1 -> assert (r0.cmd = r1.cmd); Some { r0 with terms = r0.terms @ r1.terms } type _ ty += Dummy : _ ty let dummy = (Dummy, fun _ -> Printf.sprintf "unknown value") let is_dummy = function Res ((Dummy, _), _) -> true | _ -> false module Model = struct module Make (M : sig type elt val init : elt end) = struct type elt = M.elt type t = elt list let create n () : t = List.init n (fun _ -> M.init) let size = List.length let rec drop_n t n = if n = 0 then t else drop_n (List.tl t) (n - 1) let push t e = e :: t let get t n = try List.nth t n with _ -> failwith ("nth: " ^ string_of_int n) end end module SUT = struct module Make (M : sig type sut val init : unit -> sut end) = struct type elt = M.sut type t = elt list ref let create n () = ref @@ List.init n (fun _ -> M.init ()) let size t = List.length !t let get t = List.nth !t let push t e = t := e :: !t let get_name t n = Format.asprintf "sut%d" (size t - n - 1) end end module Make (Spec : Spec) = struct open QCheck module Internal = Internal.Make (Spec) [@alert "-internal"] let pp_trace max_suts ppf (trace, mod_name, init_sut, ret) = let open Fmt in let pp_expected ppf = function | Value ret when not @@ is_dummy ret -> pf ppf "assert (r = %s)@\n" (show_res ret) | Protected_value ret when not @@ is_dummy ret -> pf ppf "assert (r = Ok %s)@\n" (show_res ret) | Exception exn -> pf ppf "assert (@[match r with@\n\ \ @[| Error (%s _) -> true@\n\ | _ -> false@]@])@\n" exn | Out_of_domain -> pf ppf "(* @[Partial function called out of domain@\n\ in the computation of the expected value.@] *)@\n" | _ -> () in let rec aux ppf = function | [ (c, r) ] -> pf ppf "%s@\n%a(* returned %s *)@\n" c pp_expected ret (show_res r) | (c, r) :: xs -> pf ppf "%s@\n(* returned %s *)@\n" c (show_res r); aux ppf xs | _ -> assert false in let inits = List.init max_suts (fun i -> Format.asprintf "let sut%d = %s" i init_sut) in pf ppf "@[%s@\n\ open %s@\n\ let protect f = try Ok (f ()) with e -> Error e@\n\ %a@\n\ %a@]" "[@@@ocaml.warning \"-8\"]" mod_name Format.( pp_print_list ~pp_sep:(fun pf _ -> fprintf pf "@\n") pp_print_string) inits aux trace let pp_terms ppf err = let open Fmt in let pp_aux ppf (term, l) = pf ppf "@[%a@\n @[%s@]@]@\n" pp_loc l term in pf ppf "%a" (list ~sep:(any "@\n") pp_aux) err let message max_suts trace report = Test.fail_reportf "Gospel specification violation in function %s\n\ @;\ \ @[%a@]@\n\ when executing the following sequence of operations:@\n\ @;\ \ @[%a@]@." report.cmd pp_terms report.terms (pp_trace max_suts) (trace, report.mod_name, report.init_sut, report.ret) let rec check_disagree postcond ortac_show_cmd s sut cs = match cs with | [] -> None | c :: cs -> ( let res = Spec.run c sut in let call = ortac_show_cmd c sut (cs = []) res in (* This functor will be called after a modified postcond has been defined, returning a list of 3-plets containing the command, the term and the location *) match postcond c s res with | None -> ( let s' = Spec.next_state c s in match check_disagree postcond ortac_show_cmd s' sut cs with | None -> None | Some (rest, report) -> Some ((call, res) :: rest, report)) | Some report -> Some ([ (call, res) ], report)) let agree_prop max_suts check_init_state ortac_show_cmd postcond cs = check_init_state (); assume (Internal.cmds_ok Spec.init_state cs); let sut = Spec.init_sut () in (* reset system's state *) let res = try Ok (check_disagree postcond ortac_show_cmd Spec.init_state sut cs) with exn -> Error exn in let () = Spec.cleanup sut in let res = match res with Ok res -> res | Error exn -> raise exn in match res with | None -> true | Some (trace, report) -> message max_suts trace report let agree_test ~count ~name max_suts wrapped_init_state ortac_show_cmd postcond = let test_prop = agree_prop max_suts wrapped_init_state ortac_show_cmd postcond in let env_var_fail () = let msg = "ORTAC_QCHECK_STM_TIMEOUT must be set to a positive integer" in Printf.eprintf "%s" msg; exit 1 in let wrapped_prop = match Sys.getenv_opt "ORTAC_QCHECK_STM_TIMEOUT" with | None -> test_prop | Some time -> let timeout = try int_of_string time with _ -> env_var_fail () in if timeout <= 0 then env_var_fail (); Util.fork_prop_with_timeout timeout test_prop in Test.make ~name ~count (Internal.arb_cmds Spec.init_state) wrapped_prop end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>