2

I have a simple class with autocontracts in Dafny, that creates a new instance of itself.

But Dafny says that "call might violate context's modifies clause" when I call foo.Add() inside Bar method

I can't tell why I'm getting this error since the class does not have any attributes

Am I missing something?

class {:autocontracts} Foo {

    predicate Valid()

    constructor() { }

    method Add() returns (b:bool)

    method Bar() returns (fo:Foo)
        ensures fresh(fo)
    {
        fo := new Foo();
        var i := 0;
        while(i < 3)
            modifies fo
            invariant fo.Valid()
        {
            var ret := fo.Add(); //call might violate context's modifies clause Verifier
            i := 1 + i;
        }
    }
}

Dafny Version at VSCode

the installed Dafny version is the latest known: 3.9.0.41003 = 3.9.0
Ken White
  • 123,280
  • 14
  • 225
  • 444

1 Answers1

2

I think you might have oversimplified your example, because I'm not sure I understand your question.

I think the answer you are looking for is that you should delete the line

modifies fo

from the loop and add the line

invariant fresh(fo.Repr)

This fixes the error about violating the context's modifies clause.

The remaining error in the code you did not mention, but it has to do with the autocontracts postcondition for Bar, which is

this.Valid() && fresh(this.Repr - old(this.Repr))

This is doubly confusing because the Foo class has no fields, and the Bar method never mentions this. So one fix would be to make Bar a static method.

Alternatively, if in your original setting you need Bar to be non-static, then you can add the invariant

invariant this.Valid() && fresh(this.Repr - old(this.Repr))

to the loop to fix this second error.

James Wilcox
  • 5,307
  • 16
  • 25