How to formulate a connection between pre-execution and post-execution state of a method? - verification

I have the following zaMap (see full code here: http://rise4fun.com/Dafny/LCaM):
class zaMap {
var busybits :array<bool>;
var keys : array<int>;
var values : array<int>;
predicate wellformed ()
reads busybits, keys, values, this
{
busybits != null && keys != null && values != null &&
keys != values &&
busybits.Length == keys.Length &&
keys.Length == values.Length
}
// ... more predicates and methods follow
method put(k : int, v : int) returns (success : bool)
requires wellformed()
modifies busybits, keys, values
ensures !success ==> full()
ensures success ==> mapsto(k, v)
{
var i := findEmpty();
if (i < 0)
{
success := false;
return;
}
assert !busybits[i];
busybits[i] := true;
keys[i] := k;
values[i] := v;
success := true;
}
//...
Now I want to add more specifications to the put method. For example, I want to ensure, that if the return value is success == true, then a map was !full() before the function call, or equivalently if a map not full(), it is guaranteed to put there.
The problem is that, in the precondition "requires" I don't know yet what it will return, and in the postcondition "ensures" I don't have an original map anymore. What people do about that?

You can use the old keyword. Let's take a look at an example. The following method sets to zero all positions of an array containing the element x and leaving the rest as they are. Here's the code:
method setToZero(a: array<int>, x : int )
requires a != null;
modifies a;
ensures forall i :: 0 <= i < a.Length && old(a[i]) == x ==> a[i] == 0;
ensures forall i :: 0 <= i < a.Length && old(a[i]) != x ==> a[i] == old(a[i]);
{
var j := 0;
while (j < a.Length)
invariant 0 <= j <= a.Length;
invariant forall i :: 0 <= i < j && old(a[i]) == x ==> a[i] == 0;
invariant forall i :: 0 <= i < j && old(a[i]) != x ==> a[i] == old(a[i]);
invariant forall i :: j <= i < a.Length ==> a[i] == old(a[i]);
{
if (a[j] == x) {
a[j] := 0;
}
j := j + 1;
}
}

Related

Can not assert the value from Dafny method

This is the code for Bulls and Cows game, simply it just we have 2 array a[] and b[] with the same length, if a[i] == b[i] then Bulls += 1, if a[i] in b && a[i] != b[i] then Cows += 1.
I have written the Bulls and Cows function, but the method BullCows have some problem when calculate it, it make my assert fail.
`
function bullspec(s:seq<nat>, u:seq<nat>): nat
requires |s| > 0
requires |u| > 0
requires |s| == |u|
{
var index:=0;
if |s| == 1 then (
if s[0]==u[0]
then 1 else 0
) else (
if s[index] != u[index]
then bullspec(s[index+1..],u[index+1..])
else 1+bullspec(s[index+1..],u[index+1..])
)
}
function cowspec(s:seq<nat>, u:seq<nat>): nat
requires |s| > 0
requires |u| > 0
requires |s| <= |u|
{
var extra:= |u|-|s|;
var index:=0;
if |s| == 1 then (
if s[0] in u
then 1 else 0
) else(
if s[index] in u && s[index]!=u[extra]
then (1+ cowspec(s[index+1..],u))
else cowspec(s[index+1..],u)
)
}
method BullsCows (s:seq<nat>, u:seq<nat>) returns (b:nat, c:nat)
requires |s|>0 && |u|>0 &&|s|==|u|
// No duplicates in array
requires forall i, j | 0 <= i < |s| && 0 <= j < |s| && i != j :: s[i] != s[j]
requires forall i, j | 0 <= i < |u| && 0 <= j < |u| && i != j :: u[i] != u[j]
ensures forall k :: 0 <= k < |s| && s[k] !in u ==> b == c == 0
ensures forall k :: 0 <= k < |s| && s[k] in u ==> (c + b) > 0
{
var index := 0;
b := 0;
c := 0;
while(index<|s|)
invariant index <= |s|
invariant forall k :: 0 <= k < index && s[k] in u ==> (b + c) > 0
{
if s[index] in u {
if s[index] == u[index]{
b:=b+1;
} else {
c:=c+1;
}
}
index:=index + 1;
}
}
method NotMain()
{
var sys:seq<nat> := [4,2,9,3,1];
var usr:seq<nat> := [1,2,3,4,5];
assert bullspec(sys, usr) == 1; //True
assert cowspec(sys, usr) == 3; //True
var b:nat, c:nat := BullsCows(sys, usr);
assert b == 1; //Not true
assert c == 3; //Not true
}
`
The method NotMain said that assert b == 1; and assert c==3; are not true, this is Dafny language, please could someone help me with this logical, I'm banging my head.
I try put on many ensures in the BullsCows method but there's nothing happen
The problem is that the postcondition on BullsCows() is not strong enough to prove the final two assertions. In particular, there is no connection between the operation of BullsCows() and the specifications bullspec() and cowspec(). You need to connect these things together.
To illustrate I'm going to use a simpler example which is easier to follow. As for your example above, the final assertion fails in the following:
function sumspec(xs: seq<nat>, i: nat) : nat
requires i <= |xs| {
if |xs| == 0 || i == 0 then 0
else sumspec(xs,i-1) + xs[i-1]
}
method sum(s:seq<nat>) returns (r:nat) {
r := 0;
for i := 0 to |s| {
r := r + s[i];
}
return r;
}
method main() {
assert sumspec([1,2,3],3) == 6;
var r := sum([1,2,3]);
assert r == 6;
}
Whilst sumspec() is a valid specification for sum() we have not connected these two things. As such, Dafny assumes that sum() can return any value for r!
To connect the specification (sumspec) with its implementation (sum) we need a stronger postcondition:
method sum(s:seq<nat>) returns (r:nat)
ensures r == sumspec(s,|s|) {
r := 0;
for i := 0 to |s|
invariant r == sumspec(s,i) {
r := r + s[i];
}
return r;
}
Here, r == sumspec(s,|s|) connects the specification with the result of our implementation. We also added a loop invariant to help Dafny show this postcondition holds.

Using promela and Spin to solve algorithmic puzzle about frogs

I study verification at the university using promela. And as an example, i need to solve algorithmic puzzle about frogs. I tried to solve the problem but something doesn't work right
In how many moves will the frogs exchange places? Frogs jump in turn on an empty cage when it is nearby or through one frog of the opposite color.
enter image description here
bool all_frog_done;
active proctype frog_jump()
{
byte i = 0;
byte position[7];
position[0] = 1;
position[1] = 1;
position[2] = 1;
position[3] = 0;
position[4] = 2;
position[5] = 2;
position[6] = 2;
all_frog_done = false;
printf("MSC: position[0] %d position[1] %d position[2] %d position[3] %d position[4] %d position[5] %d position[6] %d \n", position[0], position[1], position[2], position[3], position[4], position[5], position[6]);
do
:: (position[0] == 2) && (position[1] == 2) && (position[2] == 2) && (position[3] == 0) && (position[4] == 1) && (position[5] == 1) && (position[6] == 1) ->
all_frog_done = true; break;
:: else ->
if
:: (position[i] == 1) && (position[i+1] == 0) && (i != 6) ->
position[i] = 0;
position[i+1] = 1;
:: (position[i] == 2) && (position[i-1] == 0) && (i != 0) ->
position[i] = 0;
position[i-1] = 2;
:: (position[i] == 1) && (position[i+1] == 2) && (position[i+2] == 0) && (i <= 4)->
position[i] = 0;
position[i+2] = 1;
:: (position[i] == 2) && (position[i-1] == 1) && (position[i-2] == 0) && (i >= 2)->
position[i] = 0;
position[i-2] = 2;
fi;
printf("MSC: position[0] %d position[1] %d position[2] %d position[3] %d position[4] %d position[5] %d position[6] %d \n", position[0], position[1], position[2], position[3], position[4], position[5], position[6]);
if
:: (i < 7) -> i++;
:: (i > 0) -> i--;
fi;
od;
}

How to write test cases using Equivalence Class, Boundary value, and Basis Path Testing

I have a method isPerfect(x) (with 4<=x<=10000) below, how to write test cases based on Equivalence Class, Boundary Value, and Basis Path Testing:
public boolean checkPerfectNumber(int x) {
if(x >= 4 && x <= 10000) {
int sum = 0;
for(int i = 1; i < x; i++) {
if(x % i == 0) {
sum += i;
}
}
if(sum == x) return true;
}
return false;
}

Needing help on printing mode in java

I am given a task to make a method that takes a parameter of an ArrayList of Integer obj and print out the sum, average, and mode.
I can't seem to figure out how to find the mode. It should print out the number if there is only one mode, and it should print out "no single mode" if there is more than one (or none) mode. My method only prints out "no single mode". How can I fix my code to have the mode printed out?
This is what I have for my code:
public static void printStatistics(ArrayList<Integer> arr){
int sum = 0;
for(int i : arr){
sum += i;
}
System.out.println("Sum: "+sum);
System.out.println("Average: "+(double)sum/arr.size());
int temp = 0, counter = 0, max = 0;
for(int j = 0; j < arr.size() - 1; j++){
for(int k = j+1; k < arr.size(); k++){
if(arr.get(j) == arr.get(k)){
counter++;
if(counter > max){
max = counter;
temp = arr.get(j);
}
if(counter == max){
temp = -1;
}
}
}
}
if(temp > 0){
System.out.println("Mode: "+temp);
}
else if(temp < 0){
System.out.println("Mode: no single mode");
}
}
The problem lies here
if(counter > max){
max = counter;
temp = arr.get(j);
}
if(counter == max){
temp = -1;
}
You are assigning the value of counter to max in the first condition so the second if condition i.e., if(counter == max) will always be true, which results in temp having the value -1 which fulfills else if(temp < 0). This is why you are getting Mode: no single mode as the output every time.
Changing the condition should give you the desired output
if(counter < max){
temp = -1;
}

Getting indexOutOfBoundsException and I don't know why

I have been having this problem for a few hours. I don't know what it is, but I am having a hard time thinking clearly at the moment. This method displays a set of images. The first part of the method is just setting the gridbag constraints, whereas the next part in the if statement is creating jlabels and adding them to an arraylist of jlabels. The exception is being thrown when I try and add mouselisteners to the jlabels after they have been added to the arraylist (this is on line 112, and i have commented this on the code).
public void displayComplexStimulus(BufferedImage[] complexStimulus){
for(int i = 0; i < numberOfElements; i++){
if (i == 0 || i == 1 || i == 2){
c.gridx = i;
c.gridy = 0;
}
else if(i == 3 || i == 4 || i == 5){
c.gridx = i - 3;
c.gridy = 1;
}
else {
c.gridx = i - 6;
c.gridy = 2;
}
if(counter == 1){
if (phase1Trial.getPositionOfCorrectImage()!= i){
phase1IncorrectLabels.add(new JLabel(new ImageIcon(complexStimulus[i])));
phase1IncorrectLabels.get(i).addMouseListener(this); //line 112
add(phase1IncorrectLabels.get(i),c);
}
else if(phase1Trial.getPositionOfCorrectImage() == i){
correctLabel = new JLabel(new ImageIcon(complexStimulus[i]));
add(correctLabel, c);
correctLabel.addMouseListener(this);
}
}
}
}
If i==phase1Trial.getPositionOfCorrectImage() you're not adding an element to phase1IncorrectLabels. So in the next iteration after adding one element to the array it's at position i-1 and not i. You should replace your get(i) by get(phase1IncorrectLabels.size() - 1).