我试图在Dafny中证明简单的gcd
算法,因此我写了以下内容,但似乎无法在循环不变量内使用方法divides
:
method divides(d: int, x: int) returns (result: bool)
requires d > 0
requires x > 0
ensures (result == true ) ==> (exists q : int :: (d * q == x))
ensures (result == false) ==> (forall q : int :: (d * q != x))
{
// code omitted
}
method gcd(a: int, b: int) returns (result: int)
requires a > 0
requires b > 0
ensures (forall d : int :: ((exists q1 : int :: q1 * d == a) && (exists q2 :: (q2 * d == b))) ==>
(exists q3 : int :: (q3 * d == result)))
{
var x := a;
var y := b;
var fuel := a+b;
while ((x != y) && (fuel > 0))
decreases fuel
invariant x > 0
invariant y > 0
invariant (forall d : int :: (divides(d,x) && divides(d,y)) ==> (divides(d,a) && divides(d,b)))
{
// code omitted
}
return x;
}
反正内部是否使用divides
方法/函数/宏?
答案 0 :(得分:1)
与方法不同,函数可以出现在表达式中。您可以创建一个函数:
function div(d: int, x: int): bool
{
if (d != 0 && x % d == 0) then true else false
}
然后在您的方法divides
中,您可以拥有
ensures result == div(d,x)
,并且在方法gcd
中,您可以在变量中使用函数div
。
请注意,来自Dafny指南:函数的一个警告是,它们不仅可以出现在注释中,而且只能出现在注释中。函数绝不是最终编译程序的一部分,它们只是帮助我们验证代码的工具。