Skip to content
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 support for type invariants #197

Merged
merged 6 commits into from
Mar 13, 2024

Conversation

n-osborne
Copy link
Collaborator

This PR proposes to add checks for type invariants (for sut) in:

  • postcond in order to guarantee preservation of invariants
  • init_state in order to check that the user-provided value respects the invariants.

The second one is done in init_state and not init_sut as Gospel invariants are supposed to be talking about the model, not the actual value.

@n-osborne n-osborne added this to the 0.2 milestone Feb 7, 2024
@n-osborne
Copy link
Collaborator Author

This PR is still a draft as the type invariants are placed in an assert in the init_state function. This will cause a crash. We should find a better way to communicate with the user, via QCheck for example.

@n-osborne
Copy link
Collaborator Author

This should close #186

@n-osborne n-osborne force-pushed the qcheck-stm-with-invariants branch 2 times, most recently from e9490b9 to d718ed2 Compare February 8, 2024 21:24
@n-osborne n-osborne marked this pull request as ready for review February 8, 2024 22:00
@n-osborne
Copy link
Collaborator Author

Checking for type invariant regaring init_state is now done with QCheck.Test.fail_report
This allow to have a nice test failure message from QCheck.

@n-osborne n-osborne requested a review from shym February 9, 2024 08:39
@n-osborne n-osborne force-pushed the qcheck-stm-with-invariants branch 3 times, most recently from 11c3244 to 5bf542e Compare February 13, 2024 09:19
@n-osborne n-osborne force-pushed the qcheck-stm-with-invariants branch from 5bf542e to cda7ce7 Compare February 23, 2024 09:27
Copy link
Contributor

@shym shym left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very good, well done!

Still, I managed to find a couple of suggestions 😄

  • Is the fact that the function is named wrapped_init_state part of a bigger plan, because, as this PR stands, it is used only to check the initial state and its result is always discarded. In the present state, I would then suggest renaming it as check_init_state and giving it the type unit -> unit. agree_prop could then use a simple sequence check_init_state (); ....
  • I noticed that invariants_errors.expected appears before the invariants.mli is created. I would suggest squashing the “Check type invariants in init_state” and “Add some tests” commits.

I also put smaller comments on some lines, they were harder to describe without context.

@@ -383,8 +377,8 @@ let ghost_functions =
let run sigs config =
let open Reserr in
let open Ir in
let* state = state config sigs in
let* state, invariants = state config sigs in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line reads a bit funny. I suggest renaming the state function as state_and_invariants.

@@ -159,7 +159,15 @@ module Spec =
match cmd__010_ with | Get -> Res (int, (get sut__011_))
end
module STMTests = (STM_sequential.Make)(Spec)
let wrapped_init_state () =
let __state__012_ = Spec.init_state in
if true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me wonder: should the test deciding to generate a non-trivial wrapped_init_state rather be whether we have some invariants to test after translation, rather than Option.is_some at the beginning?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

@@ -843,11 +895,16 @@ let stm include_ config ir =
let descr = estring (module_name ^ " STM tests") in
[%stri
let _ =
let open QCheck in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is QCheck necessary for more than just Test.make? If not, I would rather go with QCheck.Test.make.

Mostly add `list_or` and `enot` that will soon be needed, but take the
opportunity to move `qualify` and redefine some functions that where
worngfully using `evar` on qualified names.
This will guarantee preservation of type invariants for `sut`
@n-osborne n-osborne force-pushed the qcheck-stm-with-invariants branch from cda7ce7 to 15bfd2c Compare March 12, 2024 15:43
@n-osborne
Copy link
Collaborator Author

Thanks for your suggestions @shym
Reworking check_init_state led to some more refactoring, but I believe it is nicer now.

Copy link
Contributor

@shym shym left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it is nicer now, thanks!

@n-osborne n-osborne merged commit 3e211fc into ocaml-gospel:main Mar 13, 2024
3 checks passed
@n-osborne n-osborne deleted the qcheck-stm-with-invariants branch March 13, 2024 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants