Dafny - 从 Main 调用 class 方法后断言违规
Dafny - Assertion violation after calling class method from Main
我正在为一个 class 编写一些简单的代码,它将棒球运行初始化为 0。它唯一的方法应该将运行次数作为其参数,并且 return bool 基于输入是否大于 class 变量和一个 int,两者中较高者运行如下:
class Baseball_Runs
{
var runs : int;
constructor()
ensures runs == 0;
{
runs := 0;
}
method moreRuns (val: int) returns (hasChanged: bool, newRuns: int)
requires val >= 0;
ensures (val > runs) ==> (hasChanged && newRuns == runs);
ensures (!hasChanged && newRuns == val) ==> (val <= runs);
// ensures if (val > runs) then (hasChanged && newRuns == val) else (!hasChanged && newRuns == runs);
modifies this;
{
if (val > runs)
{
hasChanged := true;
runs := val;
newRuns := val;
} else {
hasChanged := false;
newRuns := runs;
}
}
}
method Main()
{
var r := new Baseball_Runs();
var new_run: int := 0;
var hasChanged: bool := false;
var score: int;
score := 2;
hasChanged, new_run := r.moreRuns(score);
assert (hasChanged && new_run == 2); // I get an assertion error here
}
我注释掉了第 3 个 ensures 块,因为这是我第一次尝试 post-condition 但它 returns 是 postcondition(else 块)执行的错误不成立,所以我选择了前 2 个确保(不确定它是否正确,但整个 class 验证没有错误)。
无论如何,当我从 main 调用 moreRuns() 时,我遇到的问题就出现了。我对 bool 和 int returned 的断言似乎并不成立。有谁知道我哪里出错了?是我的 post-condition 还是我忘记在调用 moreRuns() 之前添加一些断言或者我没有满足 val == 运行的选项?
如有任何提示,我们将不胜感激!
您需要注意在 post 条件下与 runs
的哪个值进行比较。当您修改 runs
时,您想与 old(runs)
.
进行比较
moreRuns
的以下版本有效:
method moreRuns (val: int) returns (hasChanged: bool, newRuns: int)
modifies this
requires val >= 0
ensures
if val > old(runs)
then newRuns == val && hasChanged
else newRuns == old(runs) && !hasChanged
{
if (val > runs) {
hasChanged := true;
runs := val;
newRuns := val;
} else {
hasChanged := false;
newRuns := runs;
}
}
您不需要以分号结束 modifies
/requires
/ensures
子句。
我正在为一个 class 编写一些简单的代码,它将棒球运行初始化为 0。它唯一的方法应该将运行次数作为其参数,并且 return bool 基于输入是否大于 class 变量和一个 int,两者中较高者运行如下:
class Baseball_Runs
{
var runs : int;
constructor()
ensures runs == 0;
{
runs := 0;
}
method moreRuns (val: int) returns (hasChanged: bool, newRuns: int)
requires val >= 0;
ensures (val > runs) ==> (hasChanged && newRuns == runs);
ensures (!hasChanged && newRuns == val) ==> (val <= runs);
// ensures if (val > runs) then (hasChanged && newRuns == val) else (!hasChanged && newRuns == runs);
modifies this;
{
if (val > runs)
{
hasChanged := true;
runs := val;
newRuns := val;
} else {
hasChanged := false;
newRuns := runs;
}
}
}
method Main()
{
var r := new Baseball_Runs();
var new_run: int := 0;
var hasChanged: bool := false;
var score: int;
score := 2;
hasChanged, new_run := r.moreRuns(score);
assert (hasChanged && new_run == 2); // I get an assertion error here
}
我注释掉了第 3 个 ensures 块,因为这是我第一次尝试 post-condition 但它 returns 是 postcondition(else 块)执行的错误不成立,所以我选择了前 2 个确保(不确定它是否正确,但整个 class 验证没有错误)。
无论如何,当我从 main 调用 moreRuns() 时,我遇到的问题就出现了。我对 bool 和 int returned 的断言似乎并不成立。有谁知道我哪里出错了?是我的 post-condition 还是我忘记在调用 moreRuns() 之前添加一些断言或者我没有满足 val == 运行的选项?
如有任何提示,我们将不胜感激!
您需要注意在 post 条件下与 runs
的哪个值进行比较。当您修改 runs
时,您想与 old(runs)
.
moreRuns
的以下版本有效:
method moreRuns (val: int) returns (hasChanged: bool, newRuns: int)
modifies this
requires val >= 0
ensures
if val > old(runs)
then newRuns == val && hasChanged
else newRuns == old(runs) && !hasChanged
{
if (val > runs) {
hasChanged := true;
runs := val;
newRuns := val;
} else {
hasChanged := false;
newRuns := runs;
}
}
您不需要以分号结束 modifies
/requires
/ensures
子句。