I'm new to Dafny. I'm getting the error: call might violate context's modifies clause on the line where Seek() calls Step() in the following code:
class Tape {
var val : int;
constructor() {
this.val := 0;
}
method Write(x : int)
modifies this
{
this.val := x;
}
}
class Simulator {
var tape : Tape;
var step_num : nat;
constructor() {
this.tape := new Tape();
this.step_num := 0;
}
method Step()
modifies this, this.tape
ensures this.step_num > old(this.step_num)
{
this.tape.Write(1);
this.step_num := this.step_num + 1;
}
method Seek(target_step_num : int)
modifies this, this.tape
{
while this.step_num < target_step_num {
this.Step();
}
}
}
I don't understand what's going on here because I explicitly annotated Seek() with modifies this, this.tape.
Looking around online I see some talk about "freshness" and I get the impression that this has to do with ensuring that I have permission to access this.tape, but I don't understand how to fix it. Thanks!
You need invariant that this.tape is not reassigned to something else in methods. Adding ensures this.tape == old(this.tape) post condition in Seek and Step and also adding invariant this.tape == old(this.tape) fixes it.
FWIW, in addition to Divyanshu's excellent answer, I also discovered that I could fix this issue by defining tape as a const:
class Simulator {
const tape : Tape;
var step_num : nat;
...
In this case, it appears that const means that the pointer/reference will never be modified (that it will never point to a different Tape object), not that the Tape object itself will be unmodified.
Related
When calling methods which modify fields in a class, I get an error iff the class was created with a factory:
class Counter {
var i: int;
constructor() {
i := 0;
}
method Count()
modifies this
{
i := i + 1;
}
}
method CounterFactory() returns (r: Counter)
{
r := new Counter();
}
method Main() {
var counter := CounterFactory();
counter.Count(); // <~~ Error: call may violate context's modifies clause
}
When I replace the line directly above the error with var counter := new Counter();, the verifier doesn't complain.
CounterFactory() needs a postcondition to show that the returned object is new. The working method looks like this:
method CounterFactory() returns (r: Counter)
ensures fresh(r)
{
r := new Counter();
}
I am using Xtext 2.15 to generate a language that, among other things, processes asynchronous calls in a way they look synchronous.
For instance, the following code in my language:
int a = 1;
int b = 2;
boolean sleepSuccess = doSleep(2000); // sleep two seconds
int c = 3;
int d = 4;
would generate the following Java code:
int a = 1;
int b = 2;
doSleep(2000, new DoSleepCallback() {
public void onTrigger(boolean rc) {
boolean sleepSuccess = rc;
int c = 3;
int d = 4;
}
});
To achieve it, I defined the grammar this way:
grammar org.qedlang.qed.QED with jbase.Jbase // Jbase inherits Xbase
...
FunctionDeclaration return XExpression:
=>({FunctionDeclaration} type=JvmTypeReference name=ValidID '(')
(params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)?
')' block=XBlockExpression
;
The FunctionDeclaration rule is used to define asynchronous calls. In my language library, I would have as system call:
boolean doSleep(int millis) {} // async FunctionDeclaration element stub
The underlying Java implementation would be:
public abstract class DoSleepCallback {
public abstract void onTrigger(boolean rc);
}
public void doSleep(int millis, DoSleepCallback callback) {
<perform sleep and call callback.onTrigger(<success>)>
}
So, using the inferrer, type computer and compiler, how to identify calls to FunctionDeclaration elements, add a callback parameter and process the rest of the body in an inner class?
I could, for instance, override appendFeatureCall in the language compiler, would it work? There is still a part I don't know how to do...
override appendFeatureCall(XAbstractFeatureCall call, ITreeAppendable b) {
...
val feature = call.feature
...
if (feature instanceof JvmExecutable) {
b.append('(')
val arguments = call.actualArguments
if (!arguments.isEmpty) {
...
arguments.appendArguments(b, shouldBreakFirstArgument)
// HERE IS THE PART I DON'T KNOW HOW TO DO
<IF feature IS A FunctionDeclaration>
<argument.appendArgument(NEW GENERATED CALLBACK PARAMETER)>
<INSERT REST OF XBlockExpression body INSIDE CALLBACK INSTANCE>
<ENDIF>
}
b.append(');')
}
}
So basically, how to tell if "feature" points to FunctionDeclaration? The rest, I may be able to do it...
Related to another StackOverflow entry, I had the idea of implementing FunctionDeclaration in the inferrer as a class instead of as a method:
def void inferExpressions(JvmDeclaredType it, FunctionDeclaration function) {
// now let's go over the features
for ( f : (function.block as XBlockExpression).expressions ) {
if (f instanceof FunctionDeclaration) {
members += f.toClass(f.fullyQualifiedName) [
inferVariables(f)
superTypes += typeRef(FunctionDeclarationObject)
// let's add a default constructor
members += f.toConstructor [
for (p : f.params)
parameters += p.toParameter(p.name, p.parameterType)
body = f.block
]
inferExpressions(f)
]
}
}
}
The generated class would extend FunctionDeclarationObject, so I thought there was a way to identify FunctionDeclaration as FunctionDeclarationObject subclasses. But then, I would need to extend the XFeatureCall default scoping to include classes in order to making it work...
I fully realize the question is not obvious, sorry...
Thanks,
Martin
EDIT: modified DoSleepCallback declaration from static to abstract (was erroneous)
I don't think you can generate what you need using the jvm model inferrer.
You should provide your own subclass of the XbaseCompiler (or JBaseCompiler, if any... and don't forget to register with guice in your runtime module), and override doInternalToJavaStatement(XExpression expr, ITreeAppendable it, boolean isReferenced) to manage how your FunctionDeclaration should be generated.
What I'm having issue with is two different methods in two different classes not cooperating, the set-up is as following:
class A{
method b()
ensures statement
{
// Do something
}
}
class C{
method d()
requires statement
{
// Do something
}
}
And a main that calls them as following:
method Main(){
var a: new A;
var c: new C;
a.b();
c.d(); // Error: possible violation of function precondition
}
Why doesn't method d recognize that method b ensures its precondition? If it's a limitation on Dafny's prover how would I go about fixing this issue?
Edit:
Messed up the syntax when I was creating this example, so the test program works. The real one however still got issues. The specific class I'm struggling with is mentioned below:
class TokenController{
var database : map<int, Token>;
// Create a new token if one of the following is true:
// * Token is null
// * Invalid token
//
// Returns true if it was created, false otherwise.
method createToken(key:int, securityLevel:int) returns (res: bool)
modifies this`database;
requires Defines.LOW() <= securityLevel <= Defines.HIGH();
ensures key in database;
ensures database[key] != null;
ensures database[key].isValid;
ensures old(key!in database) || old(database[key] == null) || old(!database[key].isValid) <==> res;
{
if(key !in database || database[key] == null || !database[key].isValid){
var token := new Token.Token;
token.init(key, securityLevel);
// Add it to the map
database := database[key:=token];
res := true;
}
else{
res := false;
}
}
// Returns true if keyt matches the one in the database and the token is valid. Otherwise false.
predicate method validToken(key:int)
requires keyin database;
requires database[key] != null;
reads this`database;
reads this.database[key];
{
database[key].fingerprint == key && database[key].isValid
}
}
In main it's called as following:
var tokenRes : bool;
tokenRes := tokenController.createToken(0, 0);
tokenRes := tokenController.validToken(0); // Error: possible violation of function precondition
Note: I initially posted an over-simplified version of my problem. A more
accurate description follows:
I have the following struct:
struct Thing(T) {
T[3] values;
int opApply(scope int delegate(size_t, ref T) dg) {
int res = 0;
foreach(idx, ref val; values) {
res = dg(idx, val);
if (res) break;
}
return res;
}
}
Foreach can be used like so:
unittest {
Thing!(size_t[]) thing;
foreach(i, ref val ; thing) val ~= i;
}
However, it is not #nogc friendly:
#nogc unittest {
Thing!size_t thing;
foreach(i, ref val ; thing) val = i;
}
If I change the signature to
int opApply(scope int delegate(size_t, ref T) #nogc dg) { ... }
It works for the #nogc case, but fails to compile for non-#nogc cases.
The solutions I have tried are:
Cast the delegate
int opApply(scope int delegate(size_t, ref T) dg) {
auto callme = cast(int delegate(size_t, ref T) #nogc) dg;
// use callme instead of dg to support nogc
This seems wrong as I am willfully casting a #nogc attribute even onto
functions that do may not support it.
Use opSlice instead of opApply:
I'm not sure how to return an (index, ref value) tuple from my range. Even if
I could, I think it would have to contain a pointer to my static array, which
could have a shorter lifetime than the returned range.
Use a templated opApply:
All attempts to work with this have failed to automatically determine the
foreach argument types. For example, I needed to specify:
foreach(size_t idx, ref int value ; thing)
Which I see as a significant hindrance to the API.
Sorry for underspecifying my problem before. For total transparency,
Enumap is the "real-world" example. It
currently uses opSlice, which does not support ref access to values. My
attempts to support 'foreach with ref' while maintaining #nogc support is what
prompted this question.
Instead of overloading the opApplyoperator you can implement an input range for your type. Input ranges work automatically as the agregate argument in foreach statements:
struct Thing(K,V) {
import std.typecons;
#nogc bool empty(){return true;}
#nogc auto front(){return tuple(K.init, V.init);}
#nogc void popFront(){}
}
unittest {
Thing!(int, int) w;
foreach(val ; w) {
int[] i = [1,2,3]; // spurious allocation
}
}
#nogc unittest {
Thing!(int, int) w;
foreach(idx, val ; w) { assert(idx == val); }
}
This solves the problem caused by the allocation of the delegate used in foreach.
Note that the example is shitty (the range doesn't work at all, and usually ranges are provided via opSlice, etc) but you should get the idea.
Consider the following code which prints out the even numbers up to 20:
import std.stdio;
class count_to_ten{
static int opApply()(int delegate(ref int) dg) {
int i = 1;
int ret;
while(i <= 10){
ret = dg(i);
if(ret != 0) {
break;
}
i++;
}
return ret;
}
}
void main() {
int y = 2;
foreach(int x; count_to_ten) {
writeln(x * y);
}
}
The syntax of opApply requires that it take a delegate or function as a normal argument. However, even if we relaxed that and allowed opApply to take a function as a template argument, we still would have no recourse for delegates because D doesn't provide any way to separate the stack-frame pointer from the function pointer. However, this seems like it should be possible since the function-pointer part of the delegate is commonly a compile-time constant. And if we could do that and the body of the loop was short, then it could actually be inlined which might speed this code up quite a bit.
Is there any way to do this? Does the D compiler have some trick by which it happens automagically?