堆上的Dafny迭代器无法确保Valid()

时间:2019-09-06 00:50:24

标签: dafny

我有一个在堆上分配迭代器并在该迭代器上调用MoveNext()的类。我想证明如果MoveNext()返回true,则Valid()对于迭代器成立。

iterator Iter()
{}

class MyClass
{
    var iter : Iter;

    constructor ()
    {
        iter := new Iter();
    }
    method next() returns (more : bool)
    requires iter.Valid();
    modifies iter, iter._new, iter._modifies;
    {
        more := iter.MoveNext();
        // This assertion fails:
        assert more ==> iter.Valid();
    }
}

我看了/rprint的输出,方法MoveNext()包含ensures more ==> this.Valid(),这似乎暗示了我想要的断言。如果我将iter更改为在方法next()中本地分配,则Dafny将验证断言。

1 个答案:

答案 0 :(得分:1)

问题在于iter._modifiesthis中的内容一无所知。如果this.iter在这些集合之一中,则MoveNext()在呼叫next()的过程中可能已更改。

var i := iter; more := iter.MoveNext(); assert i == iter; // this assertion fails assert more ==> iter.Valid(); 的正文确认了我刚才说的话:

more

因此,在Valid()的假设下,iter仍保留迭代器,但是more := iter.MoveNext(); assert more ==> old(iter).Valid(); // this holds 可能不再引用该迭代器:

next()

解决此问题的方法可能是向method next() returns (more : bool) requires iter.Valid() requires this !in iter._new + iter._modifies // add this precondition modifies iter, iter._new, iter._modifies { more := iter.MoveNext(); assert more ==> iter.Valid(); // this now verifies } 添加一个前提条件:

My Host Provider disconnects me every 15 minutes.

Rustan