我是Z3的新手,我试图了解它是如何工作的,以及它能做什么和不能做什么。我知道Z3通过power(^)运算符至少支持某些对指数的支持(请参阅Z3py returns unknown for equation using pow() function,How to represent logarithmic formula in z3py和Use Z3 and SMT-LIB to define sqrt function with a real number)。我不清楚的是这种支持有多广泛,z3可以对指数进行什么样的推断。
这是一个涉及指数的简单示例,z3 可以分析。我们定义一个指数函数,然后让它验证exp(0)== 1:
(define-fun exp ((x Real)) Real
(^ 2.718281828459045 x))
(declare-fun x1 () Real)
(declare-fun y1 () Real)
(assert (= y1 (exp x1)))
(assert (not (=> (= x1 0.0) (= y1 1.0))))
(check-sat)
(exit)
Z3按预期返回不饱和度。另一方面,这是Z3 无法分析的简单示例:
(define-fun exp ((x Real)) Real
(^ 2.718281828459045 x))
(declare-fun x1 () Real)
(declare-fun y1 () Real)
(assert (= y1 (exp x1)))
(assert (not (< y1 0.0)))
(check-sat)
(exit)
这应该是可以满足的,因为字面上x1的任何值都会给出y1> gt;但是,Z3回归未知。天真的我可能已经预料到Z3能够分析这个,因为它可以分析第一个例子。
我意识到这个问题有点宽泛,但是:任何人都可以让我深入了解Z3如何处理指数,并且(更具体地说)为什么它可以解决我给出的第一个例子而不是第二个例子?
答案 0 :(得分:0)
一般来说很难说,因为非线性解决具有挑战性,但你提出的案例实际上并不那么神秘。你写道:
(assert (= y (exp x)))
(assert (not (=> (= x 0) (= y 1))))
Z3将简化第二个断言,产生:
(assert (= y (exp x)))
(assert (= x 0))
(assert (not (= y 1)))
然后它将传播第一个相等,产生:
(assert (= y (exp 0)))
(assert (not (= y 1)))
现在扩展exp
时,你有一个常量^常量的情况,Z3可以处理(对于整数指数等)。
对于第二种情况,你问它是一个关于变量指数的非常基本的问题,而Z3立即是barfs。这并不是太奇怪,因为关于变量指数的许多问题要么已知不可知,要么未知但很难。