我有一个数字序列,并根据数字的奇数执行操作。它最终沸腾到一个变量中只有奇数个数,这导致不变式失败,因为它坚持认为数字不是奇数。
要检查它,我做了这个。在这里,只要数字为奇数,它就会尝试将其相乘。除非我忽略了某些内容,否则将两个奇数相乘应始终会导致另一个奇数(因为它应为(m+1)*(n+1)
)。 dafny承认数字为奇数时,将乘法视为断言。
if A[i]%2 == 0 {
... // not important skip for now
} else {
assert A[i]%2 == 1;
assert (A[i] * A[i])%2 == 1;
... // do something with it, lets say multiply
}
有解决这个问题的方法吗?
数组本身包含整数(偶数和奇数)。
(这是在while周期内执行的操作)。
答案 0 :(得分:0)
我们想展示以下引理。
lemma odd_mul_odd(a: int, b: int)
requires a % 2 == 1
requires b % 2 == 1
ensures (a * b) % 2 == 1
在Dafny中做了一些数学证明后,我了解到a == (a/b)*b + (a%b)
是它可以轻松证明的一个公理。
因此,我将尝试基于以下逻辑进行证明:
这是在达夫尼,
lemma odd_mul_odd(a: int, b: int)
requires a % 2 == 1
requires b % 2 == 1
ensures (a * b) % 2 == 1
{
var x := a / 2;
var y := b / 2;
calc {
a * b;
{
assert a == 2*x + 1;
assert b == 2*y + 1;
}
(2*x + 1) * (2*y + 1);
4*x*y + 2*x + 2*y + 1;
2*(2*x*y + x + y) + 1;
}
calc {
(a * b) % 2;
(2*(2*x*y + x + y) + 1) % 2;
1;
}
}
不幸的是,在达夫尼,这些数学证明有点令人痛心。我唯一的建议是自由使用calc
语句,一次只做一步。