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),但会引发“索引超出范围”错误。
答案 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|
之间的参数上调用该函数。