Proposal: rework the rules for old(self)
in preconditions and postconditions
#532
Replies: 8 comments 3 replies
-
I support removing the I would strongly suggest against As for |
Beta Was this translation helpful? Give feedback.
-
I think whatever approach we take here, it needs to be considered in light of more general |
Beta Was this translation helpful? Give feedback.
-
This was, I believe, my decision, and that's correct. I personally found Dafny's approach of
As demonstrated by the fact that we have different preferences here, I think it's likely people will have different opinions on what feels consistent. I suspect this is because, by the nature of how we specify pre- and post- conditions, there may not be a perfectly consistent approach. Consider that: (a) in the function body, the value of |
Beta Was this translation helpful? Give feedback.
-
I agree with @utaal 's assessment that every choice has some inconsistency. |
Beta Was this translation helpful? Give feedback.
-
FWIW, coming from Dafny, I was initially annoyed by it, but I've grown used to it. I think it helps that (a) when you don't add |
Beta Was this translation helpful? Give feedback.
-
My own personal feeling is:
|
Beta Was this translation helpful? Give feedback.
-
The consensus at the [Verus all-hands] was that we'd want to remove the requirement, but we may want to hold off until the syntax to support the prophecy-based encoding has settled. |
Beta Was this translation helpful? Give feedback.
-
The design principle should be (from a conversation between @jonhnet and @utaal):
|
Beta Was this translation helpful? Give feedback.
-
Edit by @utaal-b: the original title of this by @tchajed is: "Proposal: remove requirement to use old(self) in preconditions". I'm updating it to expand its scope to when
new
(or similar) will come up for the end of a mutable borrow.Currently, for any
&mut
argumenta
, Verus requiresold(a)
to be used in preconditions and disallows plaina
. I don't know the exact rationale for this, but I believe it was so thatold(a)
has the same meaning in a precondition and postcondition.I find that this is unintuitive and mostly results in syntactic overhead when writing preconditions, without adding clarity. In my mind it is consistent for
a
to always mean the "current" value, which is dependent on whether this is a precondition or postcondition, and this is often what is desired. The current setup makes it possible to make copy-paste errors likeold(self).valid()
in both pre and postcondition whenself.valid()
was intended in the postcondition. (I think no matter the design some copy-paste errors are possible.)One proposal is to go back to the way Dafny works and simply use
self
in preconditions, and disallowold
. As far as I can tell this has little impact on the Verus implementation.Another option is to instead have
new(a)
, as mypyvy does. In that casea
would always refer to the current/old value, and obviouslynew
would only be supported in postconditions. Note that mypvy doesn't have a distinct notion of pre/postconditions since the entire transition is expressed as a predicate overa
andnew(a)
, so the design considerations may be different in Verus.Edit by @utaal-b:
@jonhnet and I discussed this offline, and we believe these should be the principles for old/new:
&mut
;&mut
, and the meaning isold
for requires, andnew
for ensures.Beta Was this translation helpful? Give feedback.
All reactions