Can dafny assert cope with "! false" - dafny

The final commented out assert will not validate but when run the if statement above will prints.
OUTPUT
ohb= true
ohx= false
palin(xe) == false
ohx ==false
function method palin(a:seq<int>) :bool {
forall i:int :: (0<=i && i<(|a|/2)) ==> a[i]==a[|a|-i -1]
}
method Main() {
var xe:seq<int> := [0,1,2,3,0];
var se:seq<int> := [0,1,2,1,0];
var ohb := palin(se);
var ohx :bool := palin(xe);
print "ohb= ",ohb,"\n";
print "ohx= ",ohx,"\n";
assert palin(se);
if (palin(xe) == false) {print "palin(xe) == false\n";}
if (!ohx) {print "ohx ==false\n";}
//assert !ohx;
}

A failing assert means the verifier cannot automatically find a proof. If you think the property holds, you need to write the proof (or part of the proof).
For your program, proving that something is not a palindrome comes down to showing a position that violates the palindrome property. In terms of logic, you're trying to prove the negation of a forall, which is an exists, and to prove an exists you'll need to supply the witness for the bound variable i.
In your example, the following suffices:
predicate method palin(a: seq<int>) {
forall i :: 0 <= i < |a| / 2 ==> a[i] == a[|a| - i - 1]
}
method Main() {
var xe := [0,1,2,3,0];
var se := [0,1,2,1,0];
var ohb := palin(se);
var ohx := palin(xe);
print "ohb= ", ohb, "\n";
print "ohx= ", ohx, "\n";
assert palin(se);
if palin(xe) == false { print "palin(xe) == false\n"; }
if !ohx { print "ohx == false\n"; }
assert !ohx by {
assert xe[1] != xe[3];
}
}

Related

How to check this sequence element is equal to that sequence element in Dafny

I have 2 sequences a:seq and b:seq, I wonder if we use the function, how we can determine that the element at this index in seq a is equal to element at this index in seq b
function test(s:seq<nat>, u:seq<nat>): nat
ensures |s|>0
ensures |u|>0
ensures |s| == |u|
{
// Code
}
method Testing()
{
var sys:seq<nat> := [4,2,9,3,1];
var usr:seq<nat> := [1,2,3,4,5];
assert test(sys, usr) == 1
// The element at the index 2 of sys and usr are equal, so it have 1 element that match in both 2 sequence
}
Because of the function I could not create a while loop, so I can not do the basic logic on that, so I wonder if there's something that fit the requirement.
After researching and working by Python to find the recursion in Python, finally I found the answer for this:
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..])
)
}
This is a wonderful problem to solve with Dafny.
Let me state the problem in clear:
Given two sequences of the same length, find the first index at which these sequences are equal. Otherwise return the length of the sequences.
That formulation makes it possible to not require that sequences are non-empty.
Thus, we can start with the following definition
function bullspec(s:seq<nat>, u:seq<nat>): (r: nat)
requires |s| == |u|
// Ensures r is either a sequence index or the sequence length
ensures r <= |s|
// All the elements before r are different
ensures forall i: nat | i < r :: s[i] != u[i]
// Either r is the sequence length or the elements at index r are equal
ensures r == |s| || s[r] == u[r]
{
Now, if you manage to prove this function, you will have prove that this function does what you want it to do.
To obtain the body of the function, you usually have to check whether the sequence if empty. In our case, we can return 0, which is the length of the sequence.
if |s| == 0 then 0 else
If the sequence is not empty, then we can compare the first elements. If they are equal, then we return the index 0
if s[0] == u[0] then 0 else
Otherwise, what happens if we recurse into bullspec(s[1..],u[1..])? We will obtain an index that is offset by 1 ! So we only need to add 1 to it.
1 + bullspec(s[1..],u[1..])
}
With this, you can verify that your function does exactly what you intended it to do.

Is there a data type in Dafny like List<T> in java?

Is there a built-in data type in Dafny like List in Java (or any type for dynamic list)?
I've looked for it in Dafny Reference Manual, but nothing found.
It seems that a self-defined class must be defined for it.
If it is the fact, then how can the performance be assured for the generated java program and how can the gernerality of Dafny as a programming language be assured?
Not criticism, just curious.
Dafny's first collection is undoubtedly seq, which is an immutable list.
function sum(s: seq<int>): int {
if |s| == 0 then 0 else s[0] + sum(s[1..])
}
For anything else, the Dafny team is working on a standard library, but you might be interestest by the first example given in the Dafny documentation that also explain why lists are non trivial objects to verify:
https://dafny.org/dafny/DafnyRef/DafnyRef#sec-example
In short, to define a list, you want to write a class and store a ghost model of all the elements to ensure there is no cycle, and possibly write this node into another data structure. But the proofs are not obvious. Here is what I got so far.
class ListNode<T> {
var head: T
var tail: ListNode?<T>
ghost var Repr: seq<ListNode<T>>
constructor(h: T, t: ListNode?<T>) requires t != null ==> t.Valid() ensures Valid()
{
head:= h;
tail := t;
Repr := [this] + (if t == null then [] else t.Repr);
}
predicate Valid() reads this, Repr decreases |Repr|
{
&& |Repr| > 0
&& Repr[0] == this
&& (if tail == null then |Repr| == 1 else
&& |Repr| > 1
&& tail == Repr[1]
&& tail.Repr == Repr[1..]
&& tail.Valid())
}
lemma ReprAreDecreasing(i: int)
requires Valid()
requires 0 <= i < |Repr|
ensures Repr[i].Repr == Repr[i..]
ensures Repr[i].Valid()
{
if i == 0 {
} else {
tail.ReprAreDecreasing(i-1);
}
}
}
class List<T> {
var head: ListNode?<T>
var last: ListNode?<T>
ghost var Repr: seq<ListNode<T>>
constructor() ensures Valid() {
head := null;
last := null;
Repr := [];
}
lemma ValidImpliesAllNodesValid(n: ListNode<T>)
requires Valid()
requires n in Repr
ensures n.Valid() {
if n == head {
assert n.Valid();
} else {
var i :| 0 <= i < |Repr| && Repr[i] == n;
head.ReprAreDecreasing(i);
}
}
method Append(node: ListNode<T>)
{
...
}
predicate Valid() reads this, Repr
{
(if head != null then
&& last != null
&& head in Repr
&& head.Repr == Repr
&& head.Valid()
&& last == head.Repr[|head.Repr|-1]
&& assert last.Repr == head.Repr[|head.Repr|-1..] by {
head.ReprAreDecreasing(|head.Repr|-1);
} last.Valid()
else
&& last == null
&& |Repr| == 0)
}
}
References:
https://dafny.org/dafny/DafnyRef/DafnyRef#sec-seq-comprehension

LHS of assignment must denote a mutable variable

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_SendGntEinv__5_0(Cache_State:array<CACHE_STATE>, Chan2_Cmd:array<MSG_CMD>, Chan2_Data:array<DATA>, CurCmd:MSG_CMD, CurPtr:NODE, ExGntd:boolean, MemData:DATA, ShrSet:array<boolean>,
i:nat,N0:nat,p__Inv0:nat,p__Inv2:nat)
requires 0<= i < N0
requires Chan2_Cmd.Length==N0
requires Chan2_Data.Length==N0
requires ShrSet.Length==N0
requires p__Inv0!=p__Inv2&&p__Inv2<N0&& p__Inv0<N0
requires i==p__Inv2
//1
//guard condition
requires ((Chan2_Cmd[i] == Empty) && (CurCmd == ReqE) && (CurPtr == i) && (ExGntd == false) && (forall j |0<= j<N0 :: (ShrSet[j] == false) ))
ensures (!((Cache_State[p__Inv0] == E) && (Chan2_Cmd[p__Inv2] == GntS)))
modifies Chan2_Cmd
modifies Chan2_Data
modifies ShrSet
{
Chan2_Cmd[i] := GntE;
Chan2_Data[i] := MemData;
ShrSet[i] := true;
ExGntd := true;
CurCmd := Empty;
}
I try to compile this code, however tip mentions me
LHS of assignment must denote a mutable variable
and I don't know how to solve the problem. Does the CurCMD and the EXGntd need to be array value, or there has other solution to this problem?
In-parameters are immutable. The error message points out that you're trying to assign to them.
You can introduce (mutable) local variables, if you want. In your example, that would look like:
var ExGntd', CurCmd' := ExGntd, CurCmd;
...
ExGntd' := true;
CurCmd' := Empty;

strange index out of range In Dafny

When I run my code, I get an index out of range error. The same problem also occurs at the ensures statement.
My code:
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
}
class TopC{
var
AuxData : DATA,
MemData : DATA,
CurPtr : NODE,
CurCmd : MSG_CMD,
ExGntd : boolean,
ShrSet : array<boolean>,
InvSet : array<boolean>,
Chan3 : array<class_0 > ,
Chan2 : array<class_0 > ,
Chan1 : array<class_0 > ,
Cache : array<class_1 > }
method n_RecvInvAck(top:TopC,i:nat, N0:nat,p1:nat,p2:nat )
requires 0<= i<N0
requires top.Chan3.Length ==N0
requires top.ShrSet.Length ==N0
requires N0>0
requires 0<= p1 <top.Chan3.Length
requires 0<= p2 <top.Chan3.Length
requires p1
requires N0>0
requires (i==p2)
requires ((top.Chan3[i].Cmd == InvAck) && (!(top.CurCmd == Empty)))
modifies top.Chan3[i]
modifies top.ShrSet
modifies top
ensures (!((top.ShrSet[p1] == true) && (top.ExGntd == true) &&
(top.ShrSet[p2] == true)))
{
top.Chan3[i].Cmd := Empty;
top.ShrSet[i] := false;
if (top.ExGntd == true) {
top.ExGntd := false;
top.MemData := top.Chan3[i].Data;
}
}
The problem is that the method modifies top, which means it might allocated a totally different array for top.ShrSet, which might have a different length.
You can add the line
ensures top.ShrSet == old(top.ShrSet)
before the other ensures clause to fix this problem.

How to parse result from ovs-vsctl get interface <interface> statistics

Result example:
{collisions=0, rx_bytes=258, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=3, tx_bytes=648, tx_dropped=0, tx_errors=0, tx_packets=8}
This format is like JSON, but not JSON.
Is there an easy way to parse this into map[string]int? Like json.Unmarshal(data, &value).
If that transport format is not recursively defined, i.e. a key cannot start a sub-structure, then its language is regular. As such, you can soundly parse it with Go's standard regexp package:
Playground link.
package main
import (
"fmt"
"regexp"
"strconv"
)
const data = `{collisions=0, rx_bytes=258, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=3, tx_bytes=648, tx_dropped=0, tx_errors=0, tx_packets=8}`
const regex = `([a-z_]+)=([0-9]+)`
func main() {
ms := regexp.MustCompile(regex).FindAllStringSubmatch(data, -1)
vs := make(map[string]int)
for _, m := range ms {
v, _ := strconv.Atoi(m[2])
vs[m[1]] = v
}
fmt.Printf("%#v\n", vs)
}
Regexp by #thwd is an elegant solution.
You can get a more efficient solution by using strings.Split() to split by comma-space (", ") to get the pairs, and then split again by the equal sign ("=") to get the key-value pairs. After that you just need to put these into a map:
func Parse(s string) (m map[string]int, err error) {
if len(s) < 2 || s[0] != '{' || s[len(s)-1] != '}' {
return nil, fmt.Errorf("Invalid input, no wrapping brackets!")
}
m = make(map[string]int)
for _, v := range strings.Split(s[1:len(s)-1], ", ") {
parts := strings.Split(v, "=")
if len(parts) != 2 {
return nil, fmt.Errorf("Equal sign not found in: %s", v)
}
if m[parts[0]], err = strconv.Atoi(parts[1]); err != nil {
return nil, err
}
}
return
}
Using it:
s := "{collisions=0, rx_bytes=258, ...}"
fmt.Println(Parse(s))
Try it on the Go Playground.
Note: If performance is important, this can be improved by not using strings.Split() in the outer loop, but instead searching for the comma "manually" and maintaining indices, and only "take out" substrings that represent actual keys and values (but this solution would be more complex).
Another solution...
...but this option is much slower so it is only viable if performance is not a key requirement: you can turn your input string into a valid JSON format and after that you can use json.Unmarshal(). Error checks omitted:
s := "{collisions=0, rx_bytes=258, ...}"
// Turn into valid JSON:
s = strings.Replace(s, `=`, `":`, -1)
s = strings.Replace(s, `, `, `, "`, -1)
s = strings.Replace(s, `{`, `{"`, -1)
// And now simply unmarshal:
m := make(map[string]int)
json.Unmarshal([]byte(s), &m)
fmt.Println(m)
Advantage of this solution is that this also works if the destination value you unmarhsal into is a struct:
// Unmarshal into a struct (you don't have to care about all fields)
st := struct {
Collisions int `json:"collisions"`
Rx_bytes int `json:"rx_bytes"`
}{}
json.Unmarshal([]byte(s), &st)
fmt.Printf("%+v\n", st)
Try these on the Go Playground.

Resources