Dafny: An Automatic Program Verifier for Functional Correctnesshttp://dafny.codeplex.com/project/feeds/rssDafny is an automatic program verifier for functional correctness.New Post: Comparing strings by (in)equality doesn't workhttps://dafny.codeplex.com/discussions/661047<div style="line-height: normal;">Fixed (GitHub Issue #76). Thanks for the bug report.
<br />
<br />
Rustan<br />
</div>rustanleinoMon, 13 Feb 2017 23:21:12 GMTNew Post: Comparing strings by (in)equality doesn't work 20170213112112PNew Post: inductive predicateshttps://dafny.codeplex.com/discussions/661266<div style="line-height: normal;">I guess that Dafny syntax doesn't allow to declare auxiliary variables in the body of inductive predicates, does it? why?<br />
</div>jiplucapFri, 10 Feb 2017 14:19:56 GMTNew Post: inductive predicates 20170210021956PNew Post: filter_distributes_over_appendhttps://dafny.codeplex.com/discussions/661150<div style="line-height: normal;">Had a flash of insight and came up with the following, but to be honest, it feels a bit like write-only code. Any suggestions for making this proof clearer?<br />
<pre><code> lemma append_associative<T>(xs: seq<T>, ys: seq<T>, zs: seq<T>)
ensures (xs + ys) + zs == xs + (ys + zs)
{}
lemma filter_distributes_over_append<T>(xs1: seq<T>, xs2: seq<T>, pred: T -> bool)
requires forall t :: pred.requires(t)
ensures filter(xs1 + xs2, pred) == filter(xs1, pred) + filter(xs2, pred)
{
if (xs1 == []) {
} else if pred(xs1[0]) {
calc == {
filter(xs1 + xs2, pred); { assert xs1 == [xs1[0]] + xs1[1..]; }
filter(([xs1[0]] + xs1[1..]) + xs2, pred); { append_associative([xs1[0]], xs1[1..], xs2); }
filter([xs1[0]] + (xs1[1..] + xs2), pred);
[xs1[0]] + filter(xs1[1..] + xs2, pred);
[xs1[0]] + filter(xs1[1..], pred) + filter(xs2, pred);
filter([xs1[0]], pred) + filter(xs1[1..], pred) + filter(xs2, pred);
filter([xs1[0]] + xs1[1..], pred) + filter(xs2, pred);
filter(xs1, pred) + filter(xs2, pred);
}
} else {
calc == {
filter(xs1 + xs2, pred); { assert xs1 == [xs1[0]] + xs1[1..]; }
filter(([xs1[0]] + xs1[1..]) + xs2, pred); { append_associative([xs1[0]], xs1[1..], xs2); }
filter([xs1[0]] + (xs1[1..] + xs2), pred);
[] + filter(xs1[1..] + xs2, pred);
filter(xs1[1..] + xs2, pred);
filter(xs1, pred) + filter(xs2, pred);
}
}
}</code></pre>
</div>jonnadalSun, 05 Feb 2017 01:47:45 GMTNew Post: filter_distributes_over_append 20170205014745ANew Post: filter_distributes_over_appendhttps://dafny.codeplex.com/discussions/661150<div style="line-height: normal;">Dafny beginner here, and I'm struggling with what I assume is a simple proof.
<br />
<br />
If I define a sequence filtering function as follows:<br />
<pre><code> function method filter<T>(xs: seq<T>, pred: T -> bool): seq<T>
reads pred.reads
requires forall t :: pred.requires(t)
ensures forall x :: x in xs && pred(x) ==> x in filter(xs, pred)
ensures forall x :: x in filter(xs, pred) ==> x in xs && pred(x)
{
if |xs| == 0 then []
else if pred(xs[0]) then [xs[0]] + filter(xs[1..], pred)
else filter(xs[1..], pred)
}</code></pre>
How might I prove that this function distributes over an append?<br />
<pre><code> lemma filter_distributes_over_append<T>(xs1: seq<T>, xs2: seq<T>, pred: T -> bool)
requires forall t :: pred.requires(t)
ensures filter(xs1 + xs2, pred) == filter(xs1, pred) + filter(xs2, pred)</code></pre>
Any tips and techniques would be much appreciated! Thanks!<br />
</div>jonnadalSun, 05 Feb 2017 01:09:33 GMTNew Post: filter_distributes_over_append 20170205010933ANew Post: assertion violation?https://dafny.codeplex.com/discussions/661047<div style="line-height: normal;"><a href="http://rise4fun.com/Dafny/SNDyT" rel="nofollow">http://rise4fun.com/Dafny/SNDyT</a><br />
</div>jiplucapMon, 30 Jan 2017 19:48:50 GMTNew Post: assertion violation? 20170130074850PNew Post: VS extension crasheshttps://dafny.codeplex.com/discussions/658298<div style="line-height: normal;">I have not heard of this bug before. Can you please file it on <a href="https://github.com/Microsoft/dafny" rel="nofollow">https://github.com/Microsoft/dafny</a>?
<br />
<br />
You asked if there's a better way to create a <code>.dfy</code> file from within VS. I don't know of a simple way to do it. My (possibly mistaken) understanding is that this functionality requires building a project system plug-in. It's embarrassing that the hardest step in writing a simple Dafny program inside VS is the creation of the file. The best way I know to do it is to create a new text file and then do a Save As. In the Save As dialog, be sure to select "All types" as the type of file, since it will let you add the <code>.dfy</code> extension without VS adding yet another <code>.txt</code> after that.
<br />
<br />
Hmm, I was able to recreate your bug (in the most up-to-date version of Dafny). And also find a workaround: don't save the file as an empty file, but instead add an empty comment to the file before saving it:<br />
<pre><code>//</code></pre>
Rustan<br />
</div>rustanleinoTue, 29 Nov 2016 01:28:40 GMTNew Post: VS extension crashes 20161129012840ANew Post: do-while loopshttps://dafny.codeplex.com/discussions/658363<div style="line-height: normal;">Just as in Java, you can use <code>break;</code> (without a label name) if you want to break out of the closest enclosing loop. Unlike in Java, you can also repeat the <code>break</code> keyword in order to break out of some other enclosing loop. For example, if you have an outer loop and an inner loop and want to break out of both loops from inside the inner loop, then you can either label the outer loop and list the label in the <code>break</code> statement:<br />
<pre><code>label Outer:
while ...
{
...
while ...
{
...
break Outer;
...
}
...
}</code></pre>
or you can use a <code>break break;</code> statement, which breaks out of two levels of loops:<br />
<pre><code>while ...
{
...
while ...
{
...
break break;
...
}
...
}</code></pre>
Rustan<br />
</div>rustanleinoTue, 29 Nov 2016 01:18:03 GMTNew Post: do-while loops 20161129011803ANew Post: Dafny's result on VS, Rise4fun and CMD does not matchhttps://dafny.codeplex.com/discussions/659167<div style="line-height: normal;">I have ran into a problem. Some programs get verified when running Dafny version on CMD but then get failed when using Dafny on Rise4fun and Visual Studio (failure reasons are different). Has anyone experinced such a thing? How can I fx it? Thanks<br />
</div>AfsanehRThu, 03 Nov 2016 20:16:27 GMTNew Post: Dafny's result on VS, Rise4fun and CMD does not match 20161103081627PNew Post: Can the verifier find a model even when the method is correct?https://dafny.codeplex.com/discussions/658585<div style="line-height: normal;">Good answers to this question can be found at Stack Exchange <a href="http://stackoverflow.com/questions/39937508/z3-model-for-correct-dafny-method" rel="nofollow">http://stackoverflow.com/questions/39937508/z3-model-for-correct-dafny-method</a> .<br />
<br />
My misundertanding was in thinking that Z3 only produces models when the answer to the query is "sat". In fact Z3 also produces models when the answer to the query is "unknown", which is what is happening in the case above. In fact Boogie's queries to Z3 are only ever answered by "unsat", "unknown", or "time out", so there is no way for Dafny to distinguish between definite counter-examples and possible counter-examples.<br />
</div>TheodoreNorvellSun, 23 Oct 2016 17:42:50 GMTNew Post: Can the verifier find a model even when the method is correct? 20161023054250PClosed Unassigned: Lemmas tutorial: typo and "How Dafny Works" [149]http://dafny.codeplex.com/workitem/149The [Lemmas tutorial](http://rise4fun.com/Dafny/tutorial/Lemmas) states and proves a "distributive lemma" of the `count` function. However, the lemmas statement is not type correct, because `count` expects `seq<bool>` but the lemmas passes `seq<int>`.<br /><br />The tutorial also refers to "How Dafny Works". I didn't find anything useful by googling that phrase. What is this referring to?<br />rustanleinoThu, 20 Oct 2016 00:37:43 GMTClosed Unassigned: Lemmas tutorial: typo and "How Dafny Works" [149] 20161020123743ACommented Unassigned: Lemmas tutorial: typo and "How Dafny Works" [149]http://dafny.codeplex.com/workitem/149The [Lemmas tutorial](http://rise4fun.com/Dafny/tutorial/Lemmas) states and proves a "distributive lemma" of the `count` function. However, the lemmas statement is not type correct, because `count` expects `seq<bool>` but the lemmas passes `seq<int>`.<br /><br />The tutorial also refers to "How Dafny Works". I didn't find anything useful by googling that phrase. What is this referring to?<br />Comments: FixedrustanleinoThu, 20 Oct 2016 00:37:29 GMTCommented Unassigned: Lemmas tutorial: typo and "How Dafny Works" [149] 20161020123729ACommented Unassigned: termination metric [174]http://dafny.codeplex.com/workitem/174<br /><br />http://rise4fun.com/Dafny/yLsls<br /><br />Why the hover text in MVS says only "decreases" for the outermost while?<br />Comments: I'm sorry I realized now that it is not only the decreases expression, but Dafny is not working properly on the partial correctness of the previous program and also on this one http://rise4fun.com/Dafny/v5fA that is obviously incorrect, but Dafny does not detect it. jiplucapTue, 11 Oct 2016 14:30:50 GMTCommented Unassigned: termination metric [174] 20161011023050PCreated Unassigned: termination metric [174]http://dafny.codeplex.com/workitem/174<br /><br />http://rise4fun.com/Dafny/yLsls<br /><br />Why the hover text in MVS says only "decreases" for the outermost while?<br />jiplucapTue, 11 Oct 2016 14:02:25 GMTCreated Unassigned: termination metric [174] 20161011020225PNew Post: Can the verifier find a model even when the method is correct?https://dafny.codeplex.com/discussions/658585<div style="line-height: normal;">I was under the impression that when Z3 finds a model, it's a model that satisfies the negation of a (the?) verification condition, and that means the negation of the VC is satisfiable, and therefore the VC is false, and so the method is not correct.
<br />
<br />
However, for the example below
<br />
<br />
<img src="http://i.stack.imgur.com/YeYM1.png" alt="Image" />
<br />
<br />
the BVD gives a model
<br />
<br />
<img src="http://i.stack.imgur.com/WZnHx.png" alt="Image" />
<br />
<br />
even though the method is correct.
<br />
<br />
Can someone explain where my misunderstanding is?
<br />
<br />
BTW I posted the same question to Stack Exchange, so feel free to answer it there too and reap some points.<br />
</div>TheodoreNorvellSat, 08 Oct 2016 21:44:14 GMTNew Post: Can the verifier find a model even when the method is correct? 20161008094414PCommented Unassigned: Assertion violation - induction hypothesis [173]http://dafny.codeplex.com/workitem/173Please, some help with the following assertion violation<br />http://rise4fun.com/Dafny/cLnNL<br /><br />Comments: Thanks a lot.jiplucapMon, 03 Oct 2016 16:01:36 GMTCommented Unassigned: Assertion violation - induction hypothesis [173] 20161003040136PCommented Unassigned: Assertion violation - induction hypothesis [173]http://dafny.codeplex.com/workitem/173Please, some help with the following assertion violation<br />http://rise4fun.com/Dafny/cLnNL<br /><br />Comments: My guess is that the proof being constructed goes something like this: http://rise4fun.com/Dafny/0FG7 ``` function power(b:int,e:nat):int { if e == 0 then 1 else b*power(b,e-1) } lemma {:induction false} Lemma_SquareAndHalve(b:int, e:nat) 	requires e%2 == 0 && e > 0 	ensures power(b,e) == power(b*b,e/2); { if e == 2 { assert power(b,2) == b*power(b,1) == power(b*b,1); 		 } else { 		calc { 			 power(b*b,e/2); 			 == 			 b*b*power(b*b,(e/2)-1); 			 == 			 b*b*b*b*power(b*b,(e/2)-2); 			 == 			 b*b*b*b*power(b*b,(e-4)/2); 			 == {if(e>4) { Lemma_SquareAndHalve(b,e-4);} else {assert (e-4)/2 == 0;} } 			 b*b*b*b*power(b,e-4); 			 == 			 b*b*power(b,e-2); 			 == 			 power(b,e); 		 } 	 } } ```lexicalscopeMon, 03 Oct 2016 15:29:21 GMTCommented Unassigned: Assertion violation - induction hypothesis [173] 20161003032921PCommented Unassigned: Assertion violation - induction hypothesis [173]http://dafny.codeplex.com/workitem/173Please, some help with the following assertion violation<br />http://rise4fun.com/Dafny/cLnNL<br /><br />Comments: You can disable automatic induction using an anotation ``` lemma {:induction false} Lemma_SquareAndHalve(b:int, e:nat) ```lexicalscopeMon, 03 Oct 2016 15:26:42 GMTCommented Unassigned: Assertion violation - induction hypothesis [173] 20161003032642PCommented Unassigned: Assertion violation - induction hypothesis [173]http://dafny.codeplex.com/workitem/173Please, some help with the following assertion violation<br />http://rise4fun.com/Dafny/cLnNL<br /><br />Comments: http://rise4fun.com/Dafny/jsv2 In this case the induction hypothesis does not should be applied, but apparently it is applied, though one of its preconditions is violated. I know that there is a simpler proof of the lemma, but I would like to know why this exactly works.jiplucapMon, 03 Oct 2016 14:37:06 GMTCommented Unassigned: Assertion violation - induction hypothesis [173] 20161003023706PNew Post: do-while loopshttp://dafny.codeplex.com/discussions/658363<div style="line-height: normal;">Thanks, that works nicely. It also works without the two assert commands.
<br />
<br />
I still prefer the use of break, since it didn't require any new variables or invariants.<br />
</div>TheodoreNorvellSun, 02 Oct 2016 16:19:10 GMTNew Post: do-while loops 20161002041910PNew Post: do-while loopshttp://dafny.codeplex.com/discussions/658363<div style="line-height: normal;">You can use implication in loop invariants as a way to distinguish the behaviour of different loop iterations. In this case we need to distinguish that the first loop iteration is always executed but subsequent ones may or may not be executed. A ghost variable is used to track the initial value of m. Thus one can prove correctness of your original loop.<br />
<pre><code>method divideWithRemainder(x : int, y : int) returns ( p : int, m : int )
requires y > 0
requires x >= 0
ensures p*y + m == x
ensures 0 <= m
ensures m < y
{
p := 0 ;
m := x ;
// Use the first two conjucts of the postcondition as the invariant
while( m >= y )
invariant 0 <= m // From postcondition
invariant p * y + m == x // From postcondition
decreases m
{
ghost var m' := m;
var q := 1 ;
assert m >= q * y ;
while( m >= q * y )
invariant q*y > 0
invariant m == m' ==> m >= q * y
invariant m <= m'
invariant 0 <= m
invariant p * y + m == x
decreases m
{
p := p + q ;
m := m - q * y ;
q := 2*q ;
}
assert m < m';
}
}</code></pre>
</div>lexicalscopeSat, 01 Oct 2016 11:25:41 GMTNew Post: do-while loops 20161001112541A