函数初始化数组

时间:2018-11-09 11:50:35

标签: arrays initialization dafny

method arrayFromSeq<T(0)> (s: seq<T>) returns (a:array<T>)
    ensures a[..] == s
    ensures fresh(a)
{
// a := new T[|s|]; 
//forall i | 0 <= i < |s| { a[i] := s[i]; }
a := new T[|s|] (i => (s[i]));
}

我想用第三行替换正文中的前两行,以避免类型T中的限定符(0),但会引发“索引超出范围”错误。

1 个答案:

答案 0 :(得分:0)

您可以改用第三行的修改版本

a := new T[|s|] (i requires 0 <= i < |s| => s[i]);

您的第三行版本不起作用的原因是,Dafny与上下文分开验证了匿名函数。通过单独查看函数i => s[i],Dafny担心i可能会超出范围。

解决方法是为此匿名函数引入一个前提条件,这就是我上面显示的内容。现在,当单独查看函数时,前提条件保证了索引将处于边界。

另外,Dafny必须检查使用该函数是否满足此前提条件。该检查通过了,因为Dafny知道数组初始化new T[|s|]仅会在0到|s|之间的参数上调用该函数。