我对z3py很新。我试图在z3py中编写以下对数表达式。
log(x,y)
我确实搜索了堆栈溢出并遇到了类似的问题,但遗憾的是我无法得到满意的答案。请帮帮我!
答案 0 :(得分:0)
更一般地说,我们如何使用Z3定义日志?
我获得任何牵引力的唯一方法是使用e
的近似值,将exp(x)
定义为(^ e x)
,然后将log
定义为总数函数是exp
的反函数。在SMT-LIB 2中:
(define-fun exp ((x Real)) Real (^ 2.718281828459045 x))
(declare-fun log (Real) Real)
(assert (forall ((x Real)) (= (log (exp x)) x)))
(assert (forall ((x Real)) (= (exp (log x)) x)))
在Z3Py:
from z3 import *
from math import e
# This is an approximation
def Z3_exp(x):
return e ** x
s = Solver()
# We define Z3_log as a total function that is the inverse of Z3_exp
Z3_log = Function('log', RealSort(), RealSort())
x = Real('x')
s.add(ForAll([x], Z3_log(Z3_exp(x)) == x))
s.add(ForAll([x], Z3_exp(Z3_log(x)) == x))
这个问题的一个明显问题是它引入了e
的近似值,这将导致一些不正确的结果,具体取决于您要证明的内容。此外,因为它使用未解释的函数来定义log
,所以不会使用最强大的非线性求解器(nlsat),而且,因为functions are total in SMT-LIB,负参数会出现典型的奇怪域问题。
另一种方法是简单地绑定e
,但这仍然不准确,并且可能会有更糟糕的行为。在Z3中还有一个未记录的内置符号euler
,但目前它基本上没有功能。