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

Encapsulate effects in QuickCheck function arguments #216

Merged
merged 151 commits into from
Sep 30, 2020
Merged

Conversation

MajaRet
Copy link
Contributor

@MajaRet MajaRet commented Sep 29, 2020

Issue

Closes #211

Description of the Change

Effects are now encapsulated in the arguments of QuickCheck functions.
Previously, for example, the following program

prop x = x + x === x + x

would have been transformed by the SharingAnalysisPass as follows.

prop x = let x@0 = x in x@0 + x@0 === x@0 + x@0

However, this led to prop becoming impure when the lets were transformed to shares and call-by-need evaluation was used. An impure property cannot be translated to a Coq Prop by the compiler, so it became unprovable.

Instead, QuickCheck functions now encapsulate generated let bindings (created by the SharingAnalysisPass or the FlattenExprPass). So the function above is transformed to

prop x = (let x@0 = x in x@0 + x@0) === (let x@0 = x in x@0 + x@0)

With this, the property itself remains pure.

Explicit lets in a Haskell module are not modified. Neither are regular predicates, so

p x = x == x

is still unprovable when translated to Coq. One way to mitigate this somewhat would be to write a property prop_p x1 ... xn = p x1 ... xn === True for a predicate p that takes n arguments, or to write a lemma manually in Coq that handles p.

Maja Reichert and others added 30 commits August 26, 2020 10:09
During the conversion of a data declaration, a Normalform instance
will be generated.
This commit implements a part of that generator that generates
most of the nf' function. The resulting code is not yet
valid because the type signature is still missing, but if the
type signature is added manually, the generated code is valid.

We are able to consider types with nested recursion and mutually
recursive types, but I have not considered type synonyms yet.
That will also be added later.
The program to generate typeclass instances for user-defined Haskell
types is now more general.
Instances for different typeclasses can now be generated simply by
passing a few parameters, namely:
- The name of the class
- The name of the function provided by the class
- A function that generates appropriate binders and return types
- A function that builds a concrete value of the return type

Currently, only typeclass instances with a certain structure can be
generated (for example, the class can currently only contain one
function), but it should be quite easy to generate instances for
ShareableArgs in addition to Normalform now.
Before the return type of a data constructor is unified with a type
expression, all variables (underscores) in the type expression are
replaced with fresh variables to prevent unification failures.

Additionally, the naming of the instance and top-level functions is
now done outside of a local environment so that those names are
registered globally and no name clashes can occur.
Local functions and variables are still named inside a local environment.
@MajaRet MajaRet added the pipeline Related to the compiler pipeline (e.g. compiler passes or the command line interface) label Sep 29, 2020
@MajaRet MajaRet self-assigned this Sep 29, 2020
@MajaRet MajaRet marked this pull request as ready for review September 30, 2020 10:16
@MajaRet MajaRet merged commit 83e169c into issue-76 Sep 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pipeline Related to the compiler pipeline (e.g. compiler passes or the command line interface)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants