如何在z3py中表示对数公式

时间:2016-07-27 06:48:02

标签: z3 smt z3py

我对z3py很新。我试图在z3py中编写以下对数表达式。

log(x,y)

我确实搜索了堆栈溢出并遇到了类似的问题,但遗憾的是我无法得到满意的答案。请帮帮我!

1 个答案:

答案 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,但目前它基本上没有功能。