Quantcast
Channel: Dafny: An Automatic Program Verifier for Functional Correctness
Viewing all articles
Browse latest Browse all 1106

Commented Unassigned: verifying multiset assertions [165]

$
0
0
I'm having trouble verifying the following program. Can some trigger magic help here?

http://rise4fun.com/Dafny/plIi4

Thanks,
Akash
Comments: Hi Akash, Apparently, auto-triggers (that is, /autoTriggers:1, which is currently used on rise4fun and in Visual Studio, and which will soon also be made the default from the command line) does not recognize ``` multiset(r)[e] ``` as a possible term to be used in the trigger. Instead, `f(e)` is picked (as you had also indicated explicitly in your example), and since there are no `f(e)` terms floating around, the quantifiers are never instantiated. This would be a good bug to fix. In the meantime, here are two possible workarounds: One workaround is to build the proof of the assertion yourself. You would use a `forall` statement for that purpose, in order to write a proof for each `e`. If the body of the `forall` statement mentions `f(e)`, then the quantifiers will be triggered. Unfortunately, since auto-triggers does not pick up on the `multiset(r)[e]` term, you'll get a warning about the `ensures` clause of the `forall` statement. Still, Z3 will pick a trigger and the program will verify: ``` type T function f(a: T) : bool method Select(s1: seq<T>) returns (r: seq<T>) ensures forall e :: f(e) ==> multiset(s1)[e] == multiset(r)[e] ensures forall e :: !f(e) ==> 0 == multiset(r)[e] method Main(s1: seq<T>) { var r1 := Select(s1); var r2 := Select(s1); forall e ensures multiset(r1)[e] == multiset(r2)[e] { if f(e) { } else { } } assert multiset(r1) == multiset(r2); } ``` The other workaround is to write the trigger manually: ``` type T function f(a: T) : bool method Select(s1: seq<T>) returns (r: seq<T>) ensures forall e {:trigger multiset(r)[e]} :: f(e) ==> multiset(s1)[e] == multiset(r)[e] ensures forall e :: !f(e) ==> 0 == multiset(r)[e] method Main(s1: seq<T>) { var r1 := Select(s1); var r2 := Select(s1); assert multiset(r1) == multiset(r2); } ``` This workaround shows the trigger that auto-triggers ought to pick (in addition to also picking `f(e)` and `multiset(s1)[e]`). (In fact, after the fix, I predict that auto-triggers would also pick that trigger for the second quantifier.) I don't know if you were using rise4fun to try this verification out, but in hover text in the Visual Studio and Emacs IDEs for Dafny (and with the `/printTooltips /autoTriggers:1` flags from the command line), you can see what Dafny did for the triggers. Rustan

Viewing all articles
Browse latest Browse all 1106

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>