【发布时间】:2022-08-03 23:33:36
【问题描述】:
我一直试图证明当两个位向量的所有单个位都等效时,它是等效的。换句话说,下面的语句a和b是bv64和BitIsSet是从位向量中提取ith位的函数,WORD_SIZE是64。
(a == b) == (forall i | 0 <= i < WORD_SIZE :: (BitIsSet(a, i) == BitIsSet(b, i)))
第一种情况,a == b 对 Dafny 来说似乎微不足道。所以我要展示的是
if a != b {
assert !(forall i | 0 <= i < WORD_SIZE :: (BitIsSet(a, i) == BitIsSet(b, i)));
}
这基本上表明存在一个i,因此这两个位是不同的:
assert exists i | 0 <= i < WORD_SIZE :: (BitIsSet(a, i) != BitIsSet(b, i))
关于如何最好地解决这个问题的任何提示?
为了完整起见,BitIsSet 基本上掩盖了ith 位置的位并将其与 0 进行比较。
predicate method {:opaque} BitIsSet(x:bv64, i: nat)
requires i < WORD_SIZE
{
(x & ((1 as bv64) << (i as bv7))) != 0
}
同样的事情通过使用布尔序列似乎很简单, 我怀疑使用了某种公理?
lemma SeqBoolEquiv(a: seq<bool>, b: seq<bool>)
requires |a| == WORD_SIZE && |b| == WORD_SIZE
ensures (a == b) <==> (forall i | 0 <= i < WORD_SIZE :: a[i] == b[i])
{
}
编辑:试图了解这里发生了什么:无法显示位向量(与序列相反)的等价性可能是由于 Dafny 级别缺少公理,或者 Boogie 或 Z3 显示位向量等价的一些可能限制那里?
-
我尝试使用 while 循环,但还没有成功。但是,它使我能够找到我提出的一个健全性问题。 github.com/dafny-lang/dafny/issues/2511
-
哦,这很有趣。我很高兴我的问题有助于揭示一个错误。
标签: dafny