在Dafny中,一个对象的方法如何修改另一个对象?

时间:2018-07-16 15:18:21

标签: dafny

此Dafny代码无法编译:

class Inner {
  method m1() modifies this {}
}

class Outer {
  var inner: Inner
  constructor(rvec: Inner) { inner := rvec; }

  method m2()
    modifies this, this.inner
  {
    var i := 0;
    while i < 3
    {
      inner.m1();
      i := i + 1;
    }
  }
}

错误是:

Dafny 2.1.1.10209
stdin.dfy(15,18): Error: call may violate context's modifies clause
Dafny program verifier finished with 1 verified, 1 error

这是怎么回事?如果我删除了循环,效果很好。

1 个答案:

答案 0 :(得分:0)

method m2() modifies this.inner或等效的modifies inner显然是指this.inner上的m2 在输入中的值。也就是说,old(this.inner)是允许m2修改的特定对象。

如果Dafny丢失了线程并且不确定inner是否已更改,则会收到此错误。

要修复它:

  • 最简单的解决方法是将modifies this, this.inner更改为modifies this.inner。这样,Dafny知道该方法中的任何内容都无法分配给this的字段。因此,inner必须始终引用相同的对象。

  • 但是在实际代码中,也许您还需要修改this的某些字段。在这种情况下,您可以证明this.inner的更改方式与您证明其他任何方式都不相同;如果您有while循环,请使用不变式:

    while i < 3
      invariant inner == old(inner)
    {
      ...
    }