You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The reason for this comes from how Carbon handles exhale. When something (anything) is exhaled, Carbon creates a new heap, and assumes that the heap values of both heaps (the old and the new) are the same, for the heap locations where some permission is held.
When a predicate is unfolded (even in a dummy assertion), the permissions inside will be known to be folded. Thus the memory locations referred by these permissions will conserve their values after an exhale.
The following program doesn't verify with Carbon:
field f: Int
field g: Bool
predicate p(x: Ref) { acc(x.f) }
method test(x: Ref, y: Ref)
requires p(x) && acc(y.g)
{
label pre
// assert unfolding p(x) in true // Verifies if uncommented
exhale acc(y.g) // Fails if uncommented, verifies if commented
assert (unfolding p(x) in x.f) == old[pre]((unfolding p(x) in x.f))
}
However, it verifies if either:
The exhale is commented.
The dummy assertion is uncommented.
Regarding this program, whether it should verify or not depends on the semantics of predicates. It should verify if predicates are equirecursive, but it shouldn't if predicates are isorecursive.
In the following example, the last assert fails:
It seems that it is sufficient to exhale something that is not known to be disjoint to cause a problem:
The text was updated successfully, but these errors were encountered: