是否可以将Dafny方法参数注释为可变的,而不将其作为对象?
我的目标是能够验证
method testMethod(a:int, b:int) returns (res :int) {
res :=0;
a := (a - b);
assert a < (a-b);
}
Dafny抱怨这显然是荒谬的说法,他抱怨LHS不是可变变量,而我想避免引入临时变量。
答案 0 :(得分:2)
Dafny中的所有in参数都是不可变的(包括引用类型的in参数,尽管使用适当的modifies
子句,方法可以通过取消引用此类参数来在堆中进行修改)。因此,您需要在示例中使用局部变量来存储表达式a - b
。例如:
method testMethod(a:int, b:int) returns (res:int) {
res := 0;
var myLocalA := a - b;
assert myLocalA < myLocalA - b;
}
如果由于必须为局部变量引入新名称而感到困扰,Dafny实际上允许您为局部变量赋予与参数内相同的名称。如果您发现自己的风格符合您的风格,则可以这样写:
method testMethod(a:int, b:int) returns (res:int) {
res := 0;
var a := a - b;
assert a < a - b;
}
请注意,分配给局部变量a
的右侧提到了参数a
(因为局部变量a
的作用范围还不大时间)。
如果您经常执行此操作,则还可以使用一条语句来开始您的方法
var a := a;
这看起来很荒谬,并且可能使您感到困惑,直到您意识到发生了什么,即该语句引入了局部变量a
并将其初始值分配为参数内a
的值。
不自动允许将内部参数用作局部变量的原因(包括C和Java在内的许多其他语言都允许)是,根据我的经验,某些人对内部参数的含义感到困惑后置条件中的参数。后置条件中提到的参数中值是指调用者传递的参数中值,可以通过使方法体内的参数不可变来明确这一点。
Rustan