Open ejconlon opened 2 years ago
Interestingly, it seems to also verify when the triggers are made {r.next}{r.val} - without r.val as a trigger there seems to be a difficulty in finding the permissions to r.val that are needed for establishing the loop invariant.
If I remember correctly, heap-dependent triggers are currently not inferred by Silver's trigger inference code, and thus need to be provided manually.
Hi Malte,
Thanks - that explains why some triggers are needed (although in this example other choices will get made by Viper if we leave triggers out, that unfortunately lead to matching loops); it's less clear to me why both triggers are necessary. I have an idea, but suspect this has to do with the way we desugar quantified permissions internally (which ideally wouldn't be visible to a user..)
The following program verifies under
carbon
but notsilicon
:Loop invariant (forall r: Ref :: { r.next } (r in nodes) ==> acc(r.next, write)) && (forall r: Ref :: { r.next } (r in nodes) ==> acc(r.val, write)) && (forall r: Ref :: { r.next } (r in nodes) ==> r.next != null ==> (r.next in nodes)) might not hold on entry. There might be insufficient permission to access r.val (cyclic.vpr@36.22--36.23) (cached)
It does work with the trigger
r in nodes
or when the triggers are removed.