我如何告诉 Dafny 一个方法总是 returns 一个“新”对象?
How can I tell Dafny that a method always returns a `new` object?
In this example,我有一个 return 新数组的方法:
method Zeroes(len: nat) returns (h: array<nat>)
ensures h.Length == len && all_zeroes(h)
{
h := new nat[len];
...
}
和另一种尝试使用它的方法:
method Histogram(a: array<nat>, limit: nat) returns (h: array<nat>)
requires greater_than_all(limit, a)
ensures h.Length == limit && histogram_of(h, a)
{
h := Zeroes(limit);
assert histogram_of_prefix(h, a, 0);
var i := 0;
while i < a.Length
invariant 0 <= i <= a.Length
invariant histogram_of_prefix(h, a, i)
{
var n := a[i];
h[n] := h[n] + 1;
i := i + 1;
}
}
Dafny 抱怨是因为它无法证明 Zeroes(limit)
不会 return a
。 (如果它真的发生了,我的代码将被完全破坏,Dafny 正确地指出。)
看来,通过将 Zeroes
分解为一个函数,我已经带走了一些信息。如果我将 Zeroes
的主体移回 Histogram
,那么 Dafny 会看到 h := new nat[limit];
它知道这与 a
不是同一个数组,并且验证成功。
如何更改 Zeroes
的签名以告诉 Dafny 它始终 return 是一个新数组?
您可以使用 fresh
。如
ensures fresh(h)
另见 。
In this example,我有一个 return 新数组的方法:
method Zeroes(len: nat) returns (h: array<nat>)
ensures h.Length == len && all_zeroes(h)
{
h := new nat[len];
...
}
和另一种尝试使用它的方法:
method Histogram(a: array<nat>, limit: nat) returns (h: array<nat>)
requires greater_than_all(limit, a)
ensures h.Length == limit && histogram_of(h, a)
{
h := Zeroes(limit);
assert histogram_of_prefix(h, a, 0);
var i := 0;
while i < a.Length
invariant 0 <= i <= a.Length
invariant histogram_of_prefix(h, a, i)
{
var n := a[i];
h[n] := h[n] + 1;
i := i + 1;
}
}
Dafny 抱怨是因为它无法证明 Zeroes(limit)
不会 return a
。 (如果它真的发生了,我的代码将被完全破坏,Dafny 正确地指出。)
看来,通过将 Zeroes
分解为一个函数,我已经带走了一些信息。如果我将 Zeroes
的主体移回 Histogram
,那么 Dafny 会看到 h := new nat[limit];
它知道这与 a
不是同一个数组,并且验证成功。
如何更改 Zeroes
的签名以告诉 Dafny 它始终 return 是一个新数组?
您可以使用 fresh
。如
ensures fresh(h)
另见