我从 BVD 得到以下结果,我不明白。
令我困惑的是,第二个不变量似乎在生成反例时被忽略了。如果两个不变量是 I0 和 I1 并且保护是 G,那么验证条件肯定是 I0 && I1 && !G ==> qy > x 并且反例应该满足这个否定。我误解了什么?
为了方便任何想要它的人,下面复制了代码。
function TwoToThe( i : int ) : int
decreases i
requires i >= 0
{
if i==0 then 1 else 2*TwoToThe( i-1 )
}
method interestingBVD(x : int, y : int)
requires y > 0
requires x >= 0
{
var q := 1 ;
var qy := y ; // Tracks q*y
ghost var i := 0 ;
// Double q until q*y exceeds x
while( qy < x ) // Off by one error.
invariant qy == q*y
invariant q == TwoToThe(i)
decreases 2*x-qy ;
{
q, qy, i := 2*q, 2*qy, i + 1 ;
}
// In the BVD we get actual numbers!!
assert q*y == qy > x && q == TwoToThe(i) ;
}