我正在尝试使用SMT a + b - c - d
对以下表达式建模,所有常量a,b,c,d
都是相同大小的bitvecs,使用以下断言a + b >= c + d
进行约束。我想以不会发生溢出/下溢的方式对其进行建模。
这是我到目前为止所尝试的:
(declare-const a (_ BitVec 4))
(declare-const b (_ BitVec 4))
(declare-const c (_ BitVec 4))
(declare-const d (_ BitVec 4))
(assert (bvuge (bvadd a b) (bvadd c d)))
; this is an inaccurate, only checks the last operation for underflow
; (a+b-c-d) >= d
; (assert (bvuge (bvsub (bvsub (bvadd a b) c) d) d))
;
; this should model that either both sides overflow, neither,
; or only the expression to the left of the inequality
; (
; (a + b <= a and c + d <= c and a + b >= c + d) or
; (a + b >= a and c + d <= c) or
; (a + b >= a and c + d >= c and a + b >= c + d)
; )
;(assert (or
; (and (bvule (bvadd a b) a)
; (bvule (bvadd c d) c)
; (bvuge (bvadd a b) (bvadd c d)))
; (and (bvuge (bvadd a b) a)
; (bvule (bvadd c d) c))
; (and (bvuge (bvadd a b) a)
; (bvuge (bvadd c d) c)
; (bvuge (bvadd a b) (bvadd c d)))))
(assert (bvuge (bvsub (bvsub (bvadd a b) c) d) #x0))
(check-sat)
(get-model)
但我不确定约束是否足够。
答案 0 :(得分:0)
更好的策略是&#34;延伸&#34;更大的位向量并检查结果是否符合您想要的位向量大小。请注意,对位向量进行适当的下溢/溢出检查可能会非常棘手,尤其是在存在乘法的情况下。
幸运的是,有一篇很好的论文描述了如何正确地做到这一点:https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/z3prefix.pdf
(论文有一些小问题:这里和那里有一些拼写错误,签名乘法溢出/下溢公式已经过时了。但它起初是一个很好的资源!)
此外,Z3还提供开箱即用的检查器谓词,用于乘法/过流。
一旦您查看了论文,如果您仍有问题,请随时询问有关其内容的更多问题!