New Pure Function Encoding#163
Open
jaspergeer wants to merge 32 commits into
Open
Conversation
Owner
|
Re: tests, do the tests in the second category mentioned here (the ones which mention "better recursive pure functions") now verify? |
Author
The remaining 3 cause panics but they do on rewrite-2023 as well. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR re-implements the encoding of pure functions. It solves two problems:
Changes
There are changes to existing encoders in this PR:
TyPurenow generates atrigfunction for every type, which takes a snapshot and returns a boolean.TyUsePure's interface exposes some utility functions for callingtrigfunctions.MirLocalDefEncalso generates atrigfunction application. For ADTs, this applies the type'strigfunction to the local's snapshot. For Refs, this applies the referent type'strigfunction to the referent's snapshot.MirImpureemits, when encoding a place, inhales oftrigapplications for that place and any projections whose type is an ADT. When encoding anAggregatervalue, an instance oftrigapplied to the snapshot of the aggregate value is emitted.FunctionEncnow encodes functions using a manual axiomatization, which is described in the next section.This PR adds some tests:
verify/pass/pure-fn/list-enum.rsverify/pass/pure-fn/list-enum-poly.rsverify/pass/pure-fn/pure-spec.rsverify/fail/pure-fn/list-enum-fail.rsverify/fail/pure-fn/pure-spec-fail.rsThe first two tests fail to verify in the current version of Prusti because they rely on function definitions being unfolded alongside the referent of an argument. The second two tests exist as a smoke test for soundness bugs.
In addition, the following were moved to
tests:tests_old/verify/fail/demos/append-sorted-error-{1,2,4}.rstests_old/verify/pass/demos/append-sorted.rs passesDesign
The encoding of a pure function:
is as follows:
where:
[T]refers to the snapshot-based encoding ofT.[<body>](arg0, ..., argn)is the pure encoding of<body>with free variable substitutionsarg0, ..., argn.The free variables of a body are the ordered function arguments followed by the 'return place', if it can be referenced.
Note that the pure encoding will be modified to encode recursive calls to
fas calls tolimited_f.<trig-fns>contains an opaque functionfunction trig_s_T([T]): Boolfor each ADTT.<argi-triggers>is{ limited_f(arg0, ..., argn), trig_s_T(make_concrete_s_T(argi.s_Ref_immutable_1)) }ifTiis an immutable reference type andTis an ADT such that&T = Ti.<argi-triggers>is{ limited_f(arg0, ..., argn), trig_s_Ti(argi) }ifTiis an ADT.<argi-triggers>is empty otherwise.Note: here I take the naive approach of triggering on the unfolding of any ADT parameter - if it turns out that this has too much of a performance impact, we could try analyzing type definitions to restrict triggers to recursive types and try analyzing the body of a pure function to identify which parameters are unfolded around a recursive call
[<pre>](arg0, ..., argn)and[<post>](arg0, ..., argn, ret)and[<post>](arg0, ..., argn, <result>)are the pure encodings of<pre>and<post>with free variable substitutions.Observe that the encoding of the post condition appears inside of an inhale-exhale statement. As a result, Viper will trust that the body of
caller_fsatisfies the spec.Impure Encoding
When a pure function
fis called from impure code, this is encoded as a call tocaller_f.We inhale instances of
trig_s_Tfor instances ofs_Twhich occur in assignment statement rvalues (they may be projections of the root place).We also inhale an instance of
trig_s_Tfor the snapshot encoding ofAggregatervalues, which correspond to ADT constructions.We also inhale an instance of
trig_s_Tfor the PCG operationRepackExpand.