I am very new to Dafny. It is complaining here that there is an assertion error:
method Fred () returns (result : int) {
var number : int;
result := number * number;
assert result > 0;
}
I am trying to write an assertion that expresses the following statement: the square of any integer is non-negative
The assertion passes if you change it to result >= 0. Is that what you meant? If number is 0, then result will be 0 too.
Related
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.
On trying to assign values to Nested Object Properties,Dart treats the Nested Object(class OperandRange) as null.
Default values have been assigned to the Nested Object Properties but the issue exists.
In the case below Nested Object Class OperandRange should be assigned minimum and maximum values but dart considers it to the Null.
How to resolve this?
Code
import 'dart:io';
//Nested Object Class
class OperandRange{
double _minValue = 0;
double _maxValue = 10;
OperandRange(this._minValue , this._maxValue);
double get minValue => _minValue;
double get maxValue => _maxValue;
set minValue(double _val){
_minValue = (_val) ;
}
set maxValue(double _val){
_maxValue = (_val) ;
}
}
class OperationData{
List<OperandRange> operandList = [];//Nested Object
List<String> operatorList = [] ;
OperationData({this.operandList, this.operatorList});
}
void main(){
int _operationCount = 2;
OperationData _operation = OperationData();
for(int _index = 0 ; _index < _operationCount ; _index++) {
stdout.write(" Operation $_index - Name(string): ");
_operation.operatorList[_index] = stdin.readLineSync();
//Null Object
stdout.write(" Operand $_index - Minimum Value (double) : ");
_operation.operandList[_index]._minValue =
double.parse(stdin.readLineSync());
stdout.write(" Operand $_index - Maximum Value (double): ");
_operation.operandList[_index]._maxValue =
double.parse(stdin.readLineSync());
}
}
Error
Operation 0 - Name(string): Add
Unhandled exception:
NoSuchMethodError: The method '[]=' was called on null.
Receiver: null
Tried calling: []=(0, "Add")
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 main (1.dart:41:28)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
Process finished with exit code 255
Here is what's happening.
You initialize operandList with a nested list. But this never has any effect because you also initialize it in OperationData constructor. Once you mention it in constructor arguments, it will either be set to a value you pass to constructor, or set to null if you do not pass this argument to constructor.
For your purpose you may remove constructor altogether as you never pass anything to it. Then your [] defaults will stand.
Otherwise, if in some cases you need to initialize it with a custom list, you may do it like this:
class OperationData{
List<OperandRange> operandList;
List<String> operatorList;
OperationData({
List<OperandRange> operandList,
List<String>operatorList,
}) :
this.operandList = operandList ?? <OperandList>[],
this.operatorList = operatorList ?? <String>[]
;
}
The same goes for your OperandRange class. 0 and 10 defaults will never be used as the constructor requires explicit values. By the way, I do not see OperandRange creation at all. The list stays empty. You will catch a next error when trying to access an index out of bounds when you fix the first error.
Also you should upgrade to Dart 2.12 if possible. It introduced null-safety that would show you this error at compile time.
datatype message = Nil | Aenc(aencMsg:message,aencKey:message) | Senc(m1:message,m2:message) | K(r1:role,r2:role) | Pk(r:role) | Sk(r:role) | Str(r:role) | Var(n:role) | Concat(array<message>)
type channel = array<message>
method ReceiveMsgFromChannel(c:channel) returns (m:message)
requires c.Length > 0
requires c[0] != Nil
ensures c[0] == Nil
// requires verify(c)
modifies c
{
m:=c[0];
c[0]:=Nil;
}
method AliceSendMsg_1(c:channel)
requires c.Length > 0
modifies c
{
var aencMsg:=new message[2];
aencMsg[0]:=Var("Na");
aencMsg[1]:=Str("A");
var m :=Aenc(Concat(aencMsg),Pk("B"));
c[0] :=m;
assert m.aencKey == Pk("B");
}
method Test(ch1:channel)
requires ch1.Length>0
requires forall i:int :: 0<=i<ch1.Length ==> ch1[i]==Nil
modifies ch1
{
AliceSendMsg_1(ch1);
var m1:=ReceiveMsgFromChannel(ch1);
}
This is part of my code.I try to define two entities in protocol,One sends message,another receives message.And there AliceSendMsg_1 represent Alice sends the msg of aenc not Nil.Then Bob receives the Msg from Channel.But the message can not be Nil.Why the precondtion fails.Any help in getting this to verify is appreciated. Thank you!
The body of Test first executes,
AliceSendMsg_1(ch1);
Furthermore, AliceSendMsg_1 is marked with modifies ch1 but does not give any postcondition. Therefore, when Dafny reasons about the method Test, it knows absolutely nothing about the contents of ch1 after the call to AliceSendMsg_1. Remember that when Dafny is verifying Test, it does not look into the body of AliceSendMsg_1. All it knows about AliceSendMsg_1 is whatever is in the signature of that method.
You can fix this by simply adding the property you need to the signature of AliceSendMsg_1.
method AliceSendMsg_1(c:channel)
requires c.Length > 0
ensures c[0] != Nil // add this line
modifies c
The following code verifies:
function stepMany(i : int, steps : int) : int
requires steps >= 0;
decreases steps;
{
if steps > 0 then
stepMany(i + 1, steps - 1)
else
i
}
lemma ex2()
{
ghost var ex1 := 10;
ghost var ex1Done := stepMany(ex1, 33);
assert ex1Done == 43; // assertion verifies successfully
}
However, the following code does not verify:
function stepMany(i : int, steps : int) : int
requires steps >= 0;
decreases steps;
{
if steps > 0 then
stepMany(i + 1, steps - 1)
else
i
}
lemma ex2()
{
ghost var ex1 := 10;
ghost var ex1Done := stepMany(ex1, 34); <-- only differences here
assert ex1Done == 44; <-- and here
// assertion DOES NOT verify
}
The only difference is the second parameter of stepMany. The assertion works for all arguments up to 33 and fails for all arguments exceeding 34.
Is there a maximum number of recursive calls Dafny can handle? I have tried searching the documentation and found nothing. There appears to be a command-line argument "/recursionBound", but it does not influence the results.
The limit isn't so much on levels of recursion, but on levels of unfolding. When Dafny has a recursive definition it will unfold it a bit. But not without limit.
What you want is for Dafny to realize that stepMany is just an add function. One way to do that is to write a lemma. Then you need to remind Dafny of what you told it by invoking the lemma. Like this:
// Hey Dafny, the stepMany functions adds its arguments and returns the result.
lemma stepManyAddsItsArguments(i : int, steps : int)
requires steps >= 0
ensures stepMany(i, steps) == i+steps
decreases steps
{} // Hey Dafny, would you mind proving that?
lemma ex2()
{
ghost var ex1 := 10;
ghost var ex1Done := stepMany(ex1, 34);
stepManyAddsItsArguments( ex1, 34) ; // Heh Dafny, remember what I told you about stepMany!
assert ex1Done == 44;
}
This function returns a ctypes.unsigned_char.array() and I do read string on it. It is getting the titles of windows. The problem is sometimes it throws TypeError.
try {
console.error('straight readString on XWindowGetProperty data:', rez_GP.data.readString());
} catch (ex) {
console.error('ex on straight readString:', ex);
}
Please notice the rez_GP.data.readString()
For example this instance: TypeError: malformed UTF-8 character sequence at offset 48. In this situation the window title is Editing js-macosx/bootstrap.js at base-template · Noitidart/js-macosx - Mozilla Firefox The 48th offset is that dot chracter you see, it's chracter code is 183. How to do readString() on this buffer without getting this error?
Thanks
readString expects a utf-8 encoded string. This is true for strings returned by _NET_WM_NAME, but not for WM_NAME.
I found a way to read the string propertly even ifs not utf-8, but im not sure if its he best way or the recommended way. This works though, i have to cast it to unsigned_char (must be this, so not char or jschar) then do fromCharCode:
function readAsChar8ThenAsChar16(stringPtr, known_len, jschar) {
// when reading as jschar it assumes max length of 500
// stringPtr is either char or jschar, if you know its jschar for sure, pass 2nd arg as true
// if known_len is passed, then assumption is not made, at the known_len position in array we will see a null char
// i tried getting known_len from stringPtr but its not possible, it has be known, i tried this:
//"stringPtr.contents.toString()" "95"
//"stringPtr.toString()" "ctypes.unsigned_char.ptr(ctypes.UInt64("0x7f73d5c87650"))"
// so as we see neither of these is 77, this is for the example of "_scratchpad/EnTeHandle.js at master · Noitidart/_scratchpad - Mozilla Firefox"
// tries to do read string on stringPtr, if it fails then it falls to read as jschar
var readJSCharString = function() {
var assumption_max_len = known_len ? known_len : 500;
var ptrAsArr = ctypes.cast(stringPtr, ctypes.unsigned_char.array(assumption_max_len).ptr).contents; // MUST cast to unsigned char (not ctypes.jschar, or ctypes.char) as otherwise i dont get foreign characters, as they are got as negative values, and i should read till i find a 0 which is null terminator which will have unsigned_char code of 0 // can test this by reading a string like this: "_scratchpad/EnTeHandle.js at master · Noitidart/_scratchpad - Mozilla Firefox" at js array position 36 (so 37 if count from 1), we see 183, and at 77 we see char code of 0 IF casted to unsigned_char, if casted to char we see -73 at pos 36 but pos 77 still 0, if casted to jschar we see chineese characters in all spots expect spaces even null terminator is a chineese character
console.info('ptrAsArr.length:', ptrAsArr.length);
//console.log('debug-msg :: dataCasted:', dataCasted, uneval(dataCasted), dataCasted.toString());
var charCode = [];
var fromCharCode = []
for (var i=0; i<ptrAsArr.length; i++) { //if known_len is correct, then will not hit null terminator so like in example of "_scratchpad/EnTeHandle.js at master · Noitidart/_scratchpad - Mozilla Firefox" if you pass length of 77, then null term will not get hit by this loop as null term is at pos 77 and we go till `< known_len`
var thisUnsignedCharCode = ptrAsArr.addressOfElement(i).contents;
if (thisUnsignedCharCode == 0) {
// reached null terminator, break
console.log('reached null terminator, at pos: ', i);
break;
}
charCode.push(thisUnsignedCharCode);
fromCharCode.push(String.fromCharCode(thisUnsignedCharCode));
}
console.info('charCode:', charCode);
console.info('fromCharCode:', fromCharCode);
var char16_val = fromCharCode.join('');
console.info('char16_val:', char16_val);
return char16_val;
}
if (!jschar) {
try {
var char8_val = stringPtr.readString();
console.info('stringPtr.readString():', char8_val);
return char8_val;
} catch (ex if ex.message.indexOf('malformed UTF-8 character sequence at offset ') == 0) {
console.warn('ex of offset utf8 read error when trying to do readString so using alternative method, ex:', ex);
return readJSCharString();
}
} else {
return readJSCharString();
}
}