Z3 混合实数和位向量

Z3 混合实数和位向量,z3,Z3,我有两个使用reals的SMT2 Lib脚本,它们在道德上是等价的。唯一的区别是,一个也使用位向量,而另一个不使用 以下是同时使用实向量和位向量的版本: ; uses both reals and bit-vectors (set-option :produce-models true) (define-fun s2 () Real (root-obj (+ (^ x 2) (- 2)) 2)) (define-fun s3 () Real 0.0) (define-fun s6 () Real

我有两个使用reals的SMT2 Lib脚本,它们在道德上是等价的。唯一的区别是,一个也使用位向量,而另一个不使用

以下是同时使用实向量和位向量的版本:

; uses both reals and bit-vectors
(set-option :produce-models true)
(define-fun s2 () Real (root-obj (+ (^ x 2) (- 2)) 2))
(define-fun s3 () Real 0.0)
(define-fun s6 () Real (/ 1.0 1.0))
(declare-fun s0 () (_ BitVec 1))
(declare-fun s1 () (_ BitVec 1))
(assert
   (let ((s4 (- s3 s2)))
   (let ((s5 (ite (= #b1 s1) s2 s4)))
   (let ((s7 (+ s5 s6)))
   (let ((s8 (- s5 s6)))
   (let ((s9 (ite (= #b1 s0) s7 s8)))
   (let ((s10 (ite (>= s9 s3) #b1 #b0)))
   (= s10 #b1))))))))

(check-sat)
(get-model)
这是道德上等价的脚本,使用
Bool
而不是大小为1的位向量,否则本质上是相同的:

; uses reals only
(set-option :produce-models true)
(define-fun s2 () Real (root-obj (+ (^ x 2) (- 2)) 2))
(define-fun s3 () Real 0.0)
(define-fun s6 () Real (/ 1.0 1.0))
(declare-fun s0 () (Bool))
(declare-fun s1 () (Bool))
(assert
   (let ((s4 (- s3 s2)))
   (let ((s5 (ite s1 s2 s4)))
   (let ((s7 (+ s5 s6)))
   (let ((s8 (- s5 s6)))
   (let ((s9 (ite s0 s7 s8)))
   (let ((s10 (ite (>= s9 s3) #b1 #b0)))
   (= s10 #b1))))))))

(check-sat)
(get-model)
对于前者,我从z3(Mac上的v4.1)获得了
unknown
,而后者很好地生成了
sat
和一个模型

虽然SMT-Lib2不允许混合实数和位向量,但我认为Z3可以很好地处理这些组合。我弄错了吗?有解决办法吗

(请注意,这些都是生成的脚本,因此仅使用
Bool
而不是
(u-BitVec 1)
)是相当昂贵的,因为它需要在其他地方进行相当多的更改。)

新的理论尚未与其他理论集成。它只支持实变量和布尔值。实际上,它也允许整数变量,但对它们的支持非常有限。它实际上是将非线性整数问题作为实际问题来解决的,最后只需检查每个整数变量是否分配给一个整数值。此外,该解算器是Z3中唯一完整的非线性(实)算法程序

因为第一个问题包含位向量,所以Z3不使用非线性解算器。取而代之的是,Z3使用了一个综合了许多理论的通用解算器,但它对于非线性算法来说是不完整的

也就是说,我明白这是一个限制,我正在努力。在不久的将来,Z3将有一个集成非线性算法、数组、位向量等的新解算器

最后,位向量理论是一个非常特殊的情况,因为我们可以很容易地将它简化为Z3中的命题逻辑。 Z3具有应用此缩减的策略
位爆炸
。这种策略可以将任何非线性+位向量问题简化为只包含实数和布尔数的问题。下面是一个例子()

; uses both reals and bit-vectors
(set-option :produce-models true)
(define-fun s2 () Real (root-obj (+ (^ x 2) (- 2)) 2))
(define-fun s3 () Real 0.0)
(define-fun s6 () Real (/ 1.0 1.0))
(declare-fun s0 () (_ BitVec 1))
(declare-fun s1 () (_ BitVec 1))
(declare-fun v2 () (_ BitVec 8))
(assert
   (let ((s4 (- s3 s2)))
   (let ((s5 (ite (= #b1 s1) s2 s4)))
   (let ((s7 (+ s5 s6)))
   (let ((s8 (- s5 s6)))
   (let ((s9 (ite (= #b1 s0) s7 s8)))
   (let ((s10 (ite (>= s9 s3) #b1 #b0)))
   (= s10 #b1))))))))

(assert (or (and (not (= v2 #x00)) (not (= v2 #x01))) (bvslt v2 #x00)))
(assert (distinct (bvnot v2) #x00))
(check-sat-using (then simplify bit-blast qfnra))
(get-model)