Unfold, fold, and unfolding must have a strictly positive permission amount #469
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 addresses viperproject/silver#444 on the Carbon side and depends on a change in Silver to introduce a new kind of error and adapt test annotations.
@gauravpartha: I've implemented this now by introducing a completely new check that
perm > none
instead of replacing or modifying the existingperm >= none
checks in the QuantifiedPermModule. Is this a good way of doing things in Carbon?I tried a different version first (it's on branch meilers_unfold_none) where I instead check in QuantifiedPermModule if we're currently folding or unfolding a predicate, and then if that's the case I check the error type and make the comparison strict. That had two drawbacks: a) it felt awkward because exhaleExp and inhaleAux suddenly use some random state in the FuncPredModule, and b) it results in a different order of errors than in Silicon.
I could also imagine a third version where all methods (exhaleExp, exhaleExpBeforeAfter, exhale, exhaleConnective, invokeExhaleOnComponents, inhaleAux, ...) all get an additional boolean parameter to specify whether a value of zero is okay, and then that gets set to false in foldPredicate or unfoldPredicate. That also didn't feel good to me because I pass this one value through fifteen methods, but maybe that's preferable to duplicating the check like in this PR. What do you think?
I should mention: Both other options (where we check that the permission is non-zero when exhaling or inhaling the predicate) also have the issue that they result in a different order of checks for folds than in Silicon: For folds, we would exhale the predicate body before inhaling the predicate and checking that the permission is non-zero. Thus, if some pure constraint in the predicate is not satisfied, we'd get an error about that first, before the error for the zero-permission. In Silicon, the zero-error always comes first, which feels better to me.