出现在注解之外的函数
Functions to appear outside of annotations
我正在阅读 Dafny 在线教程 (https://dafny-lang.github.io/dafny/OnlineTutorial/guide)。紧接着Exercise,提到函数只能出现在注解中。因此,不能写:
var v := abs(3);
教程中也提到有时候在真实代码中使用函数会很方便,所以可以定义一个函数方法,可以在真实代码中调用。
所以在练习 5 中,我是这样写的:
function max(a: int, b: int): int
{
if a < b then b else a
}
method Testing() {
var a := 3;
var b := 4;
var c := max(a,b); //seems like Dafny accept this program as oppose what was said in the tutorial
assert a <= c && b <= c;
}
我原以为行会出错
var c := max(a,b);
但是,我没有收到任何错误。
另一方面,在练习 6 中,当我有以下代码时:
function abs(x: int): int
{
if x < 0 then -x else x
}
method Abs(x: int) returns (y: int)
ensures y == abs(x);
{
y := abs(x);
}
我在以下行遇到错误:
y := abs(x);
声明“仅在规范上下文中允许调用函数(考虑将函数声明为 'function method')”。
将 function abs(x: int): int
行更改为 function method abs(x: int): int
后,错误消失了。
我可以检查一下为什么它在练习 5 中有效而在练习 6 中无效吗?
无论如何,我也可以检查一下他们在“在读取代码中使用函数”中使用术语“真实代码”是什么意思吗?
谢谢。
教程有点过时了。感谢您报告。我已提交 an issue on GitHub 更新教程并修复此问题。
这是对正在发生的事情的解释。
正如您在本教程中了解到的,Dafny 对“规范上下文”(例如 requires
/ensures
子句、assert
语句和其他注释)进行了严格区分和“真实代码”(任何未声明的 method
ghost
)。 Dafny 的某些功能仅在规范上下文中可用。
在旧版本的 Dafny 中,用户必须在 method
中明确声明每个变量为 ghost
,如果他们希望该变量能够访问仅规范上下文的功能。
在现代 Dafny 中,如果变量赋值的右侧需要规范上下文,则该变量会自动声明为 ghost。
因此,在练习 5 中,代码工作正常,因为 c
由 Dafny 自动声明 ghost
。由于 c
仅在断言内部使用,所以一切都很好。
在练习 6 中,您正在尝试从 method
return abs
。这不在注释内,而是“真实代码”。 (我们可能想编译并 运行 它!)因为 y
是 Abs
的 return 参数,它是 而不是 ghost 变量,因为它的值必须在 运行 时间存在。所以当你赋值 y := abs(x)
时,赋值的右侧是在“真实代码”上下文中,不允许像 abs
.[=30 那样调用 function
s =]
练习 6 的修正是声明 abs
一个 function method
.
我正在阅读 Dafny 在线教程 (https://dafny-lang.github.io/dafny/OnlineTutorial/guide)。紧接着Exercise,提到函数只能出现在注解中。因此,不能写:
var v := abs(3);
教程中也提到有时候在真实代码中使用函数会很方便,所以可以定义一个函数方法,可以在真实代码中调用。
所以在练习 5 中,我是这样写的:
function max(a: int, b: int): int
{
if a < b then b else a
}
method Testing() {
var a := 3;
var b := 4;
var c := max(a,b); //seems like Dafny accept this program as oppose what was said in the tutorial
assert a <= c && b <= c;
}
我原以为行会出错
var c := max(a,b);
但是,我没有收到任何错误。
另一方面,在练习 6 中,当我有以下代码时:
function abs(x: int): int
{
if x < 0 then -x else x
}
method Abs(x: int) returns (y: int)
ensures y == abs(x);
{
y := abs(x);
}
我在以下行遇到错误:
y := abs(x);
声明“仅在规范上下文中允许调用函数(考虑将函数声明为 'function method')”。
将 function abs(x: int): int
行更改为 function method abs(x: int): int
后,错误消失了。
我可以检查一下为什么它在练习 5 中有效而在练习 6 中无效吗?
无论如何,我也可以检查一下他们在“在读取代码中使用函数”中使用术语“真实代码”是什么意思吗?
谢谢。
教程有点过时了。感谢您报告。我已提交 an issue on GitHub 更新教程并修复此问题。
这是对正在发生的事情的解释。
正如您在本教程中了解到的,Dafny 对“规范上下文”(例如 requires
/ensures
子句、assert
语句和其他注释)进行了严格区分和“真实代码”(任何未声明的 method
ghost
)。 Dafny 的某些功能仅在规范上下文中可用。
在旧版本的 Dafny 中,用户必须在 method
中明确声明每个变量为 ghost
,如果他们希望该变量能够访问仅规范上下文的功能。
在现代 Dafny 中,如果变量赋值的右侧需要规范上下文,则该变量会自动声明为 ghost。
因此,在练习 5 中,代码工作正常,因为 c
由 Dafny 自动声明 ghost
。由于 c
仅在断言内部使用,所以一切都很好。
在练习 6 中,您正在尝试从 method
return abs
。这不在注释内,而是“真实代码”。 (我们可能想编译并 运行 它!)因为 y
是 Abs
的 return 参数,它是 而不是 ghost 变量,因为它的值必须在 运行 时间存在。所以当你赋值 y := abs(x)
时,赋值的右侧是在“真实代码”上下文中,不允许像 abs
.[=30 那样调用 function
s =]
练习 6 的修正是声明 abs
一个 function method
.