dafny Discussions Rss Feedhttps://dafny.codeplex.com/discussionsdafny Discussions Rss DescriptionNew 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? 20161023054250PNew 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? 20161008094414PNew 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 20161001112541ANew Post: do-while loopshttp://dafny.codeplex.com/discussions/658363<div style="line-height: normal;">The answer is embarrassingly simple:<br />
<pre><code> label lp: while( true )
invariant 0 <= m
invariant p*y + m == x
decreases m
{
p := p + q ;
m := m - q*y ;
q := 2*q ;
if( m >= q*y ) break lp ;
}</code></pre>
I still like the goto idea, since it's useful for certain other things. (Even better than "goto lp" is "call lp", with the understanding that tail calls optimize to gotos.)<br />
</div>TheodoreNorvellFri, 30 Sep 2016 02:26:21 GMTNew Post: do-while loops 20160930022621ANew Post: do-while loopshttp://dafny.codeplex.com/discussions/658363<div style="line-height: normal;">Is there a good way to deal with loops that will execute at least once?<br />
<br />
For example, in the following, the verifier complains that m might not decrease in the outer 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
{
var q := 1 ;
assert m >= q * y ;
while( m >= q * y )
invariant 0 <= m
invariant p * y + m == x
decreases m
{
p := p + q ;
m := m - q * y ;
q := 2*q ;
}
}
}</code></pre>
I tried to hint that the inner while loop would be executed at least once by using an assert.<br />
<br />
Of course I can just repeat the loop body before the loop, but this seems inelegant. <br />
<br />
Interestingly, if I delete q := 2*q, it verifies.<br />
<br />
As a feature request, how about this<br />
<pre><code> label lp:
invariant 0 <= m
invariant p*y + m == x
decreases m
{
p := p + q ;
m := m - q*y ;
q := 2*q ;
if( m < q*y ) goto lp ;
}</code></pre>
</div>TheodoreNorvellThu, 29 Sep 2016 17:37:15 GMTNew Post: do-while loops 20160929053715PNew Post: VS extension crasheshttps://dafny.codeplex.com/discussions/658298<div style="line-height: normal;">When I create a text file in Visual Studio and then rename it with a .dfy suffix, the Dafny extension throws an exception and stops working as soon as I edit the file. Shutting down and restarting VS seems to correct the problem.<br />
<ul>
<li>Is this a known bug?</li>
<li>Is there a way to stop this from happening?</li>
<li>
Is there a better way to create Dafny files from within VS?<br />
</li>
</ul>
This is with version 1.9.7 of Dafny and several versions of VS.<br />
<br />
The exception appears to be <br />
<pre><code>System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2.get_Item(TKey key) at Microsoft.VisualStudio.Text.Editor.Implementation.GlyphMarginVisualManager.AddGlyph(IGlyphTag tag, SnapshotSpan span) at Microsoft.VisualStudio.Text.Editor.Implementation.GlyphMargin.RefreshGlyphsOver(ITextViewLine textViewLine) at Microsoft.VisualStudio.Text.Editor.Implementation.GlyphMargin.OnBatchedTagsChanged(Object sender, BatchedTagsChangedEventArgs e) at Microsoft.VisualStudio.Text.Utilities.GuardedOperations.RaiseEvent[TArgs](Object sender, EventHandler`1 eventHandlers, TArgs args)</code></pre>
</div>TheodoreNorvellTue, 27 Sep 2016 23:27:40 GMTNew Post: VS extension crashes 20160927112740PNew Post: Funciton calculating sum of modified arrayhttp://dafny.codeplex.com/discussions/657187<div style="line-height: normal;">Thank you for your quick and helpful answer. It makes sense. I had considered using ghost variables, but I couldn't think of how. I also had written the Sum function for sequences as you did, but that didn't work for me because I wasn't using ghost variables.<br />
<br />
I agree with your second solution. I actually had the multiset postcondition working, but I removed it from my question to put the focus on where my problem was. I do need the multiset condition for correctness. But I also need to know that the sums are correct, because I want to further use them to prove that this algorithm approximates the load balancing solution within a factor of 2, which will require lots of other things to be added.
<br />
<br />
Thanks again for your idea to use ghost variable sequences. That is exactly what I need.<br />
</div>clynchThu, 18 Aug 2016 04:37:46 GMTNew Post: Funciton calculating sum of modified array 20160818043746ANew Post: Funciton calculating sum of modified arrayhttps://dafny.codeplex.com/discussions/657187<div style="line-height: normal;">Given your problem statement though, perhaps you would prefer this specification:
<br />
<br />
<a href="http://rise4fun.com/Dafny/TfXz" rel="nofollow">http://rise4fun.com/Dafny/TfXz</a><br />
<pre><code>function Sum(A: seq<int>): int
{
if A == [] then 0
else A[|A|-1] + Sum(A[..|A|-1])
}
method Stacking(N: array<int>) returns(A: array<int>, B: array<int>, aindex: int, bindex: int)
requires N != null
ensures A != null
ensures B != null
ensures 0 <= aindex <= A.Length
ensures 0 <= bindex <= B.Length
ensures multiset(A[..aindex]) + multiset(B[..bindex]) == multiset(N[..])
{
A := new int[N.Length];
B := new int[N.Length];
bindex := 0;
aindex := 0;
var M1 := 0;
var M2 := 0;
var nindex := 0;
ghost var A' := [];
ghost var B' := [];
ghost var N' := [];
while(nindex < N.Length)
invariant 0 <= nindex <= N.Length
invariant 0 <= aindex <= nindex
invariant 0 <= bindex <= nindex
invariant A' == A[..aindex]
invariant B' == B[..bindex]
invariant N' == N[..nindex]
invariant M1 == Sum(A')
invariant M2 == Sum(B')
invariant multiset(A') + multiset(B') == multiset(N')
{
if(M1 <= M2)
{
M1 := M1 + N[nindex];
A[aindex] := N[nindex];
A' := A' + [N[nindex]];
aindex := aindex + 1;
}
else
{
M2 := M2 + N[nindex];
B[bindex] := N[nindex];
B' := B' + [N[nindex]];
bindex := bindex + 1;
}
N' := N' + [N[nindex]];
nindex := nindex + 1;
}
assert N' == N[..];
}</code></pre>
</div>lexicalscopeWed, 17 Aug 2016 08:53:19 GMTNew Post: Funciton calculating sum of modified array 20160817085319ANew Post: Funciton calculating sum of modified arrayhttps://dafny.codeplex.com/discussions/657187<div style="line-height: normal;">You can use ghost variables. Ghost variables do not appear in the compiler output, but are just used by the verifier.
<br />
<br />
<a href="http://rise4fun.com/Dafny/naKS" rel="nofollow">http://rise4fun.com/Dafny/naKS</a><br />
<pre><code>function Sum(A: seq<int>): int
{
if A == [] then 0
else A[|A|-1] + Sum(A[..|A|-1])
}
method Stacking(N: array<int>) returns(A: array<int>, B: array<int>, aindex: int, bindex: int, M1: int, M2: int)
requires N != null
ensures A != null
ensures B != null
ensures 0 <= aindex <= A.Length
ensures 0 <= bindex <= B.Length
ensures M1 == Sum(A[..aindex])
ensures M2 == Sum(B[..bindex])
ensures M1 + M2 == Sum(N[..])
{
A := new int[N.Length];
B := new int[N.Length];
bindex := 0;
aindex := 0;
M1 := 0;
M2 := 0;
var nindex := 0;
ghost var A' := [];
ghost var B' := [];
ghost var N' := [];
while(nindex < N.Length)
invariant 0 <= nindex <= N.Length
invariant 0 <= aindex <= nindex
invariant 0 <= bindex <= nindex
invariant A' == A[..aindex]
invariant B' == B[..bindex]
invariant N' == N[..nindex]
invariant M1 == Sum(A')
invariant M2 == Sum(B')
invariant M1 + M2 == Sum(N')
{
if(M1 <= M2)
{
M1 := M1 + N[nindex];
A[aindex] := N[nindex];
A' := A' + [N[nindex]];
aindex := aindex + 1;
}
else
{
M2 := M2 + N[nindex];
B[bindex] := N[nindex];
B' := B' + [N[nindex]];
bindex := bindex + 1;
}
N' := N' + [N[nindex]];
nindex := nindex + 1;
}
assert N' == N[..];
}</code></pre>
</div>lexicalscopeWed, 17 Aug 2016 08:44:00 GMTNew Post: Funciton calculating sum of modified array 20160817084400ANew Post: Funciton calculating sum of modified arrayhttp://dafny.codeplex.com/discussions/657187<div style="line-height: normal;">I am trying to implement a greedy algorithm for load balancing. The method Stacking is given an array N of integers and tries to partition its elements into arrays A and B to minimize the maximum sum of the two arrays. To do this, it loops through array N and adds each element to either array A or B, depending on which has the smallest sum so far. It obviously does not always give the optimal solution.
<br />
<br />
The problem I am having is to verify that the sum of A and the sum of B are being computed correctly. I use variable M1 for the sum of A and M2 for the sum of B. A function Sum will calculate the sum of an array. The Sum function works correctly, because I can verify that M1+M2 is the sum of the elements of N.
<br />
<br />
However, it cannot verify that M1 is the sum of the elements of A and M2 is the sum of the elements of B. The problem is that those arrays are being modified. When I add a new element to array A, for example, all the elements before that element in array A are unchanged, so the previous sum that I calculated has not changed. Therefore it is easy to see that the new sum is also correct. But I think Dafny cannot do this, because Dafny knows I modified the array, and Dafny does not realize that the previous sum was not changed.<br />
<br />
The code is below. I include the invariant M1 + M2 == Sum(N,nindex), just to show that the Sum function works correctly. But the invariants M1 == Sum(A,aindex) and M2 == Sum(B,bindex) are not being computed correctly.<br />
<br />
Any ideas on how to make this work?<br />
<pre><code>function Sum(A: array<int>, size: int): int
requires A != null
reads A
requires 0 <= size <= A.Length
{
if size == 0 then 0
else A[size-1] + Sum(A,size-1)
}
method Stacking(N: array<int>) returns(A: array<int>, B: array<int>, aindex: int, bindex: int, M1: int, M2: int)
requires N != null
ensures A != null
ensures B != null
ensures 0 <= aindex <= A.Length
ensures 0 <= bindex <= B.Length
ensures M1 == Sum(A,aindex)
ensures M2 == Sum(B,bindex)
ensures M1 + M2 == Sum(N,N.Length)
{
A := new int[N.Length];
B := new int[N.Length];
bindex := 0;
aindex := 0;
M1 := 0;
M2 := 0;
var nindex := 0;
while(nindex < N.Length)
invariant 0 <= nindex <= N.Length
invariant 0 <= aindex <= nindex
invariant 0 <= bindex <= nindex
invariant M1 == Sum(A,aindex)
invariant M2 == Sum(B,bindex)
invariant M1 + M2 == Sum(N,nindex)
{
if(M1 <= M2)
{
M1 := M1 + N[nindex];
A[aindex] := N[nindex];
aindex := aindex + 1;
}
else
{
M2 := M2 + N[nindex];
B[bindex] := N[nindex];
bindex := bindex + 1;
}
nindex := nindex + 1;
}
}
</code></pre>
Thanks,
<br />
Chris<br />
</div>clynchTue, 16 Aug 2016 19:21:35 GMTNew Post: Funciton calculating sum of modified array 20160816072135PNew Post: Array to Sequence to Multisets and comparisonhttps://dafny.codeplex.com/discussions/656190<div style="line-height: normal;">Hello,
<br />
<br />
I made some changes in my program this morning, I had not realized that the state of the array needed to be asserted before trying to use it, this version is now accepted by the verifier:<br />
<pre><code>class Test {
method Main()
{
var arrInt := new int[5];
arrInt[0] := 4;
arrInt[1] := 3;
arrInt[2] := 2;
arrInt[3] := 1;
arrInt[4] := 0;
assert arrInt[..] == [4,3,2,1,0]; //Assertion of the array's sequence
var m1 := multiset(arrInt[..]);
var m2 := multiset([4,3,2,1,0]);
assert m1 == m2; //The assertion is now valid
}
}</code></pre>
Sorry for the disturbance,
<br />
Alexis Chevalier<br />
</div>AlexisChevalierFri, 08 Jul 2016 12:35:59 GMTNew Post: Array to Sequence to Multisets and comparison 20160708123559P