How to prove Dafny count < size - verification

I'm currently learning Dafny. I'm totally comfused by lemma and I dont know how to use it. The tutorial is not that helpful. What if I want to prove
count(a) <= |a|
how should I do it. Thanks for helping.
function count(a: seq<bool>): nat
ensures count(a) <= |a|;
{
if |a| == 0 then 0 else
(if a[0] then 1 else 0) + count(a[1..])
}

You've already proved it! You wrote the property you wanted as a postcondition of the function and Dafny verifies it without complaints. That's it.
You can also use a lemma to prove the property. Here's an example:
function count(a: seq<bool>): nat
{
if |a| == 0 then 0 else
(if a[0] then 1 else 0) + count(a[1..])
}
lemma CountProperty(a: seq<bool>)
ensures count(a) <= |a|
{
}
Again, Dafny verifies the lemma without issuing any complaints, so you have proved it!
It is not correct to assume that Dafny will always prove things for you automatically. Therefore, it's a good idea to learn how to write proofs manually, too. Here's a manual proof of this property. Just to make sure Dafny doesn't try to do induction automatically, I used a directive to turn it off (thus making our lives harder than Dafny normally would):
lemma {:induction false} CountProperty(a: seq<bool>)
ensures count(a) <= |a|
{
// Let's consider two cases, just like the definition of "count"
// considers two cases.
if |a| == 0 {
// In this case, we have:
assert count(a) == 0 && |a| == 0;
// so the postcondition follows easily.
} else {
// By the definition of "count", we have:
assert count(a) == (if a[0] then 1 else 0) + count(a[1..]);
// We know an upper bound on the first term of the addition:
assert (if a[0] then 1 else 0) <= 1;
// We can also obtain an upper bound on the second term by
// calling the lemma recursively. We do that here:
CountProperty(a[1..]);
// The call we just did gives us the following property:
assert count(a[1..]) <= |a[1..]|;
// Putting these two upper bounds together, we have:
assert count(a) <= 1 + |a[1..]|;
// We're almost done. We just need to relate |a[1..]| to |a|.
// This is easy:
assert |a[1..]| == |a| - 1;
// By the last two assertions, we now have:
assert count(a) <= 1 + |a| - 1;
// which is the postcondition we have to prove.
}
}
A nicer way to write a proof like this is to use a verified calculation, which Dafny calls "the calc statement":
lemma {:induction false} CountProperty(a: seq<bool>)
ensures count(a) <= |a|
{
if |a| == 0 {
// trivial
} else {
calc {
count(a);
== // def. count
(if a[0] then 1 else 0) + count(a[1..]);
<= // left term is bounded by 1
1 + count(a[1..]);
<= { CountProperty(a[1..]); } // induction hypothesis gives a bound for the right term
1 + |a[1..]|;
== { assert |a[1..]| == |a| - 1; }
|a|;
}
}
}
I hope that this gets you started.
Program safely,
Rustan

Related

dafny non aliased memory weird behavior

I have a dafny defined graph ADT (from this SO question) brought here again for completeness:
class Graph
{
var adjList : seq<seq<int>>;
constructor (adjListInput : seq<seq<int>>)
ensures adjList == adjListInput
{
adjList := adjListInput;
}
}
function ValidGraph(G : Graph) : bool
reads G
{
(forall u :: 0 <= u < |G.adjList| ==> forall v :: 0 <= v < |G.adjList[u]| ==> 0 <= G.adjList[u][v] < |G.adjList|) &&
(forall u :: 0 <= u < |G.adjList| ==> forall v,w :: 0 <= v < w < |G.adjList[u]| ==> G.adjList[u][v] != G.adjList[u][w])
}
method main()
{
var G : Graph := new Graph([[1,2],[0,2],[0,1]]);
var nonRelatedArray := new int[8];
var i := 0; while (i < 14)
{
// nonRelatedArray[3] := 55;
i := i + 1;
}
assert (ValidGraph(G));
}
If I remove the write comment to nonRelatedArray at index 3, I get an assertion violation, which is a bit weird because it seems reasonable that the memory model would be able to determine that nonRelatedArray is (well) non related to G.
You can fix this by adding modifies nonRelatedArray to the loop. The key to this modifies clause is that it does not mention G. So then Dafny knows that G will not be modified by the loop, so it will still be a valid graph.
It is a little confusing what happens if you leave off a modifies clause from a loop. If you don't do any writes to the heap (like when you comment out the write above), then Dafny (actually, Boogie) is able to automatically see that nothing is changed at all. But if you do any writes into the heap, Dafny's default modifies clause all of a sudden becomes "anything the surrounding scope is allowed to modify". If you want something other than these two defaults, you need to ask for it explicitly by giving a modifies clause.

how do i correctly use >= and <= in code?

I have tried many thing involving this, >=, >==, =>, ==>.i can not find one that works. hey all return either primary expression needed or expected initializer before '>'. I am creating a IR receiver latch switch and thus have to create parameters for the code because the receiver is not constant in all conditions. Full code below. Any suggestions to fix the code please reply and don't DM me. Thank you.
code:
int LEDState = 0;
int LEDPin = 8;
int dt = 100;
int recieverOld ==> 500 and recieverOld ==< 2000;
int recieverNew;
int recieverPin = 12;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDPin, OUTPUT);
pinMode(recieverPin, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
recieverNew = digitalRead(recieverPin);
if((recieverOld >== 0 && recieverOld <== 10) && (recieverNew >== 500 && recieverNew <== 2000) {
if(LEDState == 0) {
digitalWrite(LEDPin, HIGH);
LEDState = 1;
}
}
recieverOld = recieverNew;
delay(dt);
}
error:
expected initializer before '==' token
if one = used line 4 and related, return error expected primary-expression before '>' token
if > before = line 4 and related, return error expected initializer before '>=' token
Any solutions or suggestions welcome.
TL;DR
Operators that do no exist, and that you should NOT use:
==>, ==<, >==, <==
Operators that works and you can use them:
>= - MORE THAN OR EQUAL, compare operator, for example X >= 5
<= - LESS THAN OR EQUAL, compare operator, for example X <= 5
> - MORE THAN, compare operator, for example X > 5
< - LESS THAN, compare operator, for example X < 5
== - compare operator, when you want to compare values of the variables if they have the same value, for example X == 5, Y == X, 10 == 7
=== - equality operator, similar to compare operator ==, but aditionally checks the type of a variable. for example X === Y, '10' === 10
= - assign operator, when you want to assign something to the variable, for example X = 5
<> OR != - NOT EQUAL, compare operator, for example X != 5, Y <> 10
!== - similar to != or <>, but also checks the type of a value. For example 10 !== '10', and will return opposite result of the equality operator ===

an obvious invariant fails in Dafny

datatype CACHE_STATE = I| S| E
datatype MSG_CMD = Empty| ReqS| ReqE| Inv| InvAck| GntS| GntE
type NODE=nat
type DATA=nat
type boolean=bool
class class_0 {
var
Data : DATA,
Cmd : MSG_CMD
}
class class_1 {
var
Data : DATA,
State : CACHE_STATE
}
method n_RecvGntSinv__1_2(
Chan2 : array<class_0 > ,
Cache : array<class_1 > ,i:nat, N1:nat ,p__Inv0:nat,p__Inv2:nat)
modifies Chan2[i]
modifies Cache[i]
requires 0<= i<N1
requires Cache.Length ==N1
requires N1>0
requires Chan2.Length ==N1
requires p__Inv0!=p__Inv2&&p__Inv2<N1&& p__Inv0<N1
requires Chan2[i] != null
requires Cache[i] !=null
requires i!=p__Inv0&&i!=p__Inv2
requires (!((Cache[p__Inv2].State == E) && (!(Cache[p__Inv0].State == I))))
requires (Chan2[i].Cmd == GntS)
ensures Cache==old(Cache)
ensures Chan2==old(Chan2)
ensures (!((Cache[p__Inv2].State == E) && (!(Cache[p__Inv0].State == I))))
{
Cache[i].State := S;
Cache[i].Data := Chan2[i].Data;
Chan2[i].Cmd := Empty;
}
I have placed the requirement i is different from p__Inv2 and p_Inv0, thus the assignments should not disturb the evaluation of the invariant.
It is obvious that the invariant (!((Cache[p__Inv2].State == E) && (!(Cache[p__Inv0].State == I)))) should hold if it holds before execution.
Dafny shows my assertions fail and gives a counterexample I cann't understand.
Your precondition allows the possibility that Cache[i] references the same object as Cache[p__Inv0] or Cache[p__Inv2]. If that's what you intended, then the method body is indeed incorrect, as reported by the verifier. If that's not what you intended, then a precondition like
requires forall j,k :: 0 <= j < k < Cache.Length ==> Cache[j] != Cache[k]
will make your method verify.

Verifying sum of sequence under a condition in dafny

I am having a problem with getting an invariant to be be maintained in dafny. The invariant is trying to maintain that a total is equal to the a recursive sum of elements in a sequence that match a given condition. What do i need to add/change to get this to verify. Here is my attempt:
datatype MovieTitle = A | B | C
class Movie {
var title: MovieTitle;
var run_time: int;
predicate Valid()
reads this
{
run_time >= 0
}
constructor(mt: MovieTitle, rt: int)
requires rt >= 0;
ensures Valid();
modifies this;
{
title := mt;
run_time := rt;
}
}
function movieSum(s: seq<Movie>, mt: MovieTitle, i: int): int
requires 0 <= i <= |s|;
decreases s, i;
reads s;
reads set x | x in s[..];
{
if |s| == 0 || i == 0 then 0
else if s[0].title == mt then s[0].run_time + movieSum(s[1..], mt, i - 1)
else movieSum(s[1..], mt, i - 1)
}
lemma {:induction s, mt, i} movieSumLemma(s: seq<Movie>, mt: MovieTitle, i: int)
requires 0 <= i < |s|;
ensures s[i].title == mt ==> (movieSum(s, mt, i) + s[i].run_time == movieSum(s, mt, i + 1)) &&
s[i].title != mt ==> (movieSum(s, mt, i) == movieSum(s, mt, i + 1));
decreases s;
{
}
method SumRuntimes(s: seq<Movie>)
{
var total := 0;
var i := 0;
while i < |s|
invariant 0 <= i <= |s|;
invariant total == movieSum(s, A, i);
decreases |s| - i;
{
if s[i].title == A {
total := total + s[i].run_time;
movieSumLemma(s, A, i);
}
i := i + 1;
}
}
Here invariant total == movieSum(s, A, i); won't hold. Any help in getting this to verify is appreciated. Thank you!
The problem is in function movieSum. You're both chopping off the initial element of s in the recursive call and decrementing i. That will not produce the sum of all the mt-movie elements.
You don't need the lemma. But its postcondition doesn't say what you may think it says. It currently has the form
ensures A ==> B && !A ==> C
The 2-character-wide && has higher binding power than the 3-character-wide ==>. So, your postcondition is saying
ensures A ==> ((B && !A) ==> C)
which simplifies to true. Instead, you want
ensures (A ==> B) && (!A ==> C)
which you can also write on two lines (for better readability):
ensures A ==> B
ensures !A ==> C
Your program also has a number of redundant decreases clauses and :induction attributes. I'm guessing you have added these from the blue information squiggles in the IDE. The blue squiggles are just FYI--Dafny is just trying to tell you what its default settings are.
It seems you may be using a very version of Dafny, or I expected you should have got a warning about the deprecated modifies this on the constructor.

Why does `variable++` increment the variable but `variable + 1` does not?

Here's the problem in which I encountered this issue:
The function should compare the value at each index position and score a point if the value for that position is higher. No point if they are the same. Given a = [1, 1, 1] b = [1, 0, 0] output should be [2, 0]
fun compareArrays(a: Array<Int>, b: Array<Int>): Array<Int> {
var aRetVal:Int = 0
var bRetVal:Int = 0
for(i in 0..2){
when {
a[i] > b[i] -> aRetVal + 1 // This does not add 1 to the variable
b[i] > a[i] -> bRetVal++ // This does...
}
}
return arrayOf(aRetVal, bRetVal)
}
The IDE even says that aRetVal is unmodified and should be declared as a val
What others said is true, but in Kotlin there's more. ++ is just syntactic sugar and under the hood it will call inc() on that variable. The same applies to --, which causes dec() to be invoked (see documentation). In other words a++ is equivalent to a.inc() (for Int or other primitive types that gets optimised by the compiler and increment happens without any method call) followed by a reassignment of a to the incremented value.
As a bonus, consider the following code:
fun main() {
var i = 0
val x = when {
i < 5 -> i++
else -> -1
}
println(x) // prints 0
println(i) // prints 1
val y = when {
i < 5 -> ++i
else -> -1
}
println(y) // prints 2
println(i) // prints 2
}
The explanation for that comes from the documentation I linked above:
The compiler performs the following steps for resolution of an operator in the postfix form, e.g. a++:
Store the initial value of a to a temporary storage a0;
Assign the result of a.inc() to a;
Return a0 as a result of the expression.
...
For the prefix forms ++a and --a resolution works the same way, and the effect is:
Assign the result of a.inc() to a;
Return the new value of a as a result of the expression.
Because
variable++ is shortcut for variable = variable + 1 (i.e. with assignment)
and
variable + 1 is "shortcut" for variable + 1 (i.e. without assignment, and actually not a shortcut at all).
That is because what notation a++ does is actually a=a+1, not just a+1. As you can see, a+1 will return a value that is bigger by one than a, but not overwrite a itself.
Hope this helps. Cheers!
The equivalent to a++ is a = a + 1, you have to do a reassignment which the inc operator does as well.
This is not related to Kotlin but a thing you'll find in pretty much any other language