-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add function generation support #277
Conversation
Oh, I forgot: The PR requires |
As part of the yak-shaving that this PR triggered, I've opened 2 QCheck PRs: c-cube/qcheck#296 and c-cube/qcheck#297 which will help printing nicer counterexample functions involving chars and strings. Feel free to chip in on which QCheck.Print behaviour you prefer... 🙏 🙂 |
Just an quick update: With the following patch, inserting a manual List coercion as we discussed off-line, diff --git a/plugins/qcheck-stm/test/hashtbl.mli b/plugins/qcheck-stm/test/hashtbl.mli
index 8b10a51..45525ae 100644
--- a/plugins/qcheck-stm/test/hashtbl.mli
+++ b/plugins/qcheck-stm/test/hashtbl.mli
@@ -64,11 +64,11 @@ val iter : ('a -> 'b -> unit) -> ('a, 'b) t -> unit
val filter_map_inplace : ('a -> 'b -> 'b option) -> ('a, 'b) t -> unit
(*@ filter_map_inplace f h
modifies h
- ensures h.contents = Sequence.filter_map
+ ensures h.contents = List.of_seq (Sequence.filter_map
(fun (x,y) -> match f x y with
| None -> None
| Some b' -> Some (x, b'))
- (old h.contents) *)
+ (old h.contents)) *)
val fold : ('a -> 'b -> 'c -> 'c) -> ('a, 'b) t -> 'c -> 'c
val length : ('a, 'b) t -> int
|
Excellent! |
93ea93a
to
b33e5a6
Compare
I've just removed Looking more at the first errors described above, e.g., in
I realize now that this is a genuine warning, because it is missing an I've thus updated I've also updated |
In the meantime, I'm ok to pin the right version so that CI has a bit more meaning. As opam files are generated, the pin should be added in a |
e0f07b3
to
c7c0971
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again for this nice PR. This is a really good enhancement of Ortac/QCheck-STM!
Maybe it would be cleaner to run ocamlformat on each of the commits rather than at the end with a separate one?
Regarding the new error constructors in Reserr
:
Type_not_supported_in_function_argument
could be made more specific as it is only used to avoid third-order functions (e.g.Third_order_function_argument
)- At some point in the past we've (lexicographically) ordered the constructors in
Reserr
. Could you add them so that the order is preserved?
Now a more in-depth remark: In Stm_of_ir.subst_core_type
you can get rid of the insert_prefix
extra-argument.
This argument is only set to false in pp_ortac_cmd_case
to build a type that is then fed to pp_of_ty
that will run munge_longident
to get rid of the qualification in the identifier. In the current state, this wouldn't work because you are building the qualified name using lident
directly which build Lident "QCheck.fun_"
, and munge_longident
can't do its job. But if you build Ldot (Lident "QCheck", "fun_")
, then you don't need to rely on insert_prefix
flag.
I've pushed a way to do it on the fun-gen-review
branch on my repo.
Two last small remarks:
There are some leftovers next to Stm_of_ir.prefix_identifier
definition.
I would have written the checks in Ir_of_gospel.no_third_order_arg_or_big_typle
in a more monadic way, but the code is already pretty clear and easy to follow as it is, so no need to change :-)
2219f04
to
4ab0701
Compare
Thanks for the review Nicolas!
Good idea, I've now done so using
Ah, of course. I've restored order to the contructor names in the type declaration in 0b8f9cf.
Ah great. Thanks - I've merged your commit 👍
Oops, sorry. Fixed in 4ab0701
I started writing these in monadic style, but then realized that the check-functions could be pure, and thus ended up with the current version, that calls the pure ones from the monadic-error-merging code 🤷 Let me know how much squashing you want me to do... |
Excellent! Thank you!
I would say if it is not too much hassle, it would be cleaner to have every commit after the Changelog update (54a21d3) squashed at the appropriate place.
I agree, let's do releases in the right order :-) |
Ack!
Things are falling into place: After rolling qcheck.0.23 I've rolled ocaml/opam-repository#27114 |
This requires - building a generator with QCheck.fun1-4 of arbitrary.t type that takes Observables and an arbitrary.t result and finally selecting its .gen field to get a resulting Gen.t - quantifying arbitrary.t generators with QCheck to not pick up Gen.t ones - emitting the special (_ -> _) fun_ type for an arrow type - invoking functions f with QCheck.Fn.apply f in both run_cmd and next_state - validating the fragment of functions we support, i.e., second-order and arity<=4
…ected and hashtbl_stm_tests.expected.ml
4ab0701
to
ddfaf8b
Compare
I've now done so (and learning some nice features of
0.5 is now available fromthe caml.org opam-repo mirror, so I've added an initial commit 104c2e8 bumping the required version, and dropped the pin commit. If the CI is green (tests are green locally), I believe this should be good to go. |
Excellent! Thanks again for this nice PR 😃 |
This (draft) PR add function generation, fixing #270
The core commit is 7a9df34 describing the change as:
- building a generator with
QCheck.fun1-4
ofarbitrary.t
typethat takes
Observable
s and anarbitrary.t
resultand finally selecting its
.gen
field to get a resultingGen.t
- quantifying
arbitrary.t
generators withQCheck
to not pick upGen.t
ones- emitting the special
(_ -> _) fun_
type for an arrow type- invoking functions
f
withQCheck.Fn.apply f
in bothrun_cmd
andnext_state
- validating the fragment of functions we support, i.e., second-order and arity<=4
The PR is good enough shape to share and get feedback on at this point, since I'm starting to hit issues that are getting further from function generation itself.
One remaining issue is warnings about incomplete computations, which shows up in two places, despite both representing a complete model computation, that just happens to involve a function AFAICS:
and
Another issue which took some time to diagnose is a mixture of
List
andSequence
in the hashtbl specification.In
filter_map_inplace
Ortac fails to parse the specification correctly, which results innext_state
modeling a state change, despite themodifies h
specification.The issue is that
h.contents = Sequence.filter_map
is parsed asi.e., with nested applications on the left-hand-side of the equality sign
=
.Commit 2d0ce5a adds a fix attempt for it, which makes Ortac output a
next_state
function honoring themodify h
clause, however the produced code then fails to type-check because of the mixture ofList
andSequence
:As an illustration,the last two commits 63109c8 and 93ea93a adds a quick-and-dirty
List.filter_map
to the runtime andadjusts the
hashtbl
specification to useList
s exclusively, which is sufficient to makedune build @launchtests plugins/qcheck-stm/
pass.These commits only serve as an illustration and should of course be dropped. I seem to recall something about
List
being removed from the Stdlib revision, which may also help solve this problem.