所以我尝试在 Dafny 中为一个简化的荷兰国旗问题实施一个程序,其中所有索引 0 <= n < k 是红色,所有索引 k <= n < arr.Length 是蓝色,除了它一直说 k可能会越界,即使它最多应该是 arr.Length 根据我的编码方式。我在这里做错了什么?
method dutch(arr: array?<char>) returns (k: int)
requires arr != null && forall x :: 0 <= x < arr.Length ==> arr[x] == 'r' || arr[x] == 'b'
ensures k <= arr.Length //postcondition might not hold
ensures forall n :: 0 <= n < k ==> arr[n] == 'r' //out of range
ensures forall n :: k <= n < arr.Length ==> arr[n] == 'b' //out of range
modifies arr
{
var x := 0;
k := 0;
while(x < arr.Length)
invariant k <= x
invariant forall n :: 0 <= n < k ==> arr[n] == 'r' //out of range
invariant forall n :: k <= n < x ==> arr[n] == 'b' //invariant might not be maintained by loop
{
if(arr[x] == 'r')
{
arr[x] := arr[k];
arr[k] := 'r';
k := k + 1;
}
x := x + 1;
}
}
答案 0 :(得分:1)
在循环之后,所有已知的是循环守卫的不变量和否定。所以,arr.Length <= x
成立,k <= x
也成立。因此,根据您的循环规范,x
可能是 arr.Length + 10
,k
可能是 arr.Length + 2
。
要验证程序,您需要将 k
“根据我的编码方式最多应该是 arr.Length
”的信念转变为循环规范。所以,添加
invariant k <= arr.Length