如何在 Z3 的 Python API 中正确使用声明函数的 Solver() 命令
How to correctly use Solver() command in Python API of Z3 with declared function
我使用 Z3 的 Python API 的一些脚本得到了意想不到的结果。我认为我误解了某些过程或只是错误地使用了某些命令。例如,假设我有以下脚本:
from z3 import *
x = Int('x')
def g(x):
if x == 0:
return 1
elif x > 0:
return x**(x+1)
s = Solver()
s.add(g(x) > x)
print s.check()
if s.check()== sat:
m = s.model()
m.evaluate(x, model_completion=True)
print m
这将return以下输出:
sat
[x = 0]
没关系,但是如果我用 s.add(x > 1, g(x) > x)
替换 s.add(g(x) > x)
,这个 returns unsat
。我期待的是:
sat
[x = 2]
任何人都可以帮助我了解发生了什么吗?
我的 Python 技能稍微欠发达,但我认为这个问题背后的关键概念是 Python 函数不会转换为 Z3 函数,例如 if x == 0: ...
不会创建一个检查 x
所有可能值的 Z3 函数。最简单的检查方法是只打印求解器,这样它就会显示约束,只需添加 print s
。在你无法满足的情况下,我得到 [x > 1, x < 1]
,这确实是无法满足的。
Python 的 if-then-else 不会转换为 Z3 的 if-then-else。您必须使用 "If" 函数。看这里:https://github.com/Z3Prover/z3/blob/master/src/api/python/z3.py#L1092
我使用 Z3 的 Python API 的一些脚本得到了意想不到的结果。我认为我误解了某些过程或只是错误地使用了某些命令。例如,假设我有以下脚本:
from z3 import *
x = Int('x')
def g(x):
if x == 0:
return 1
elif x > 0:
return x**(x+1)
s = Solver()
s.add(g(x) > x)
print s.check()
if s.check()== sat:
m = s.model()
m.evaluate(x, model_completion=True)
print m
这将return以下输出:
sat
[x = 0]
没关系,但是如果我用 s.add(x > 1, g(x) > x)
替换 s.add(g(x) > x)
,这个 returns unsat
。我期待的是:
sat
[x = 2]
任何人都可以帮助我了解发生了什么吗?
我的 Python 技能稍微欠发达,但我认为这个问题背后的关键概念是 Python 函数不会转换为 Z3 函数,例如 if x == 0: ...
不会创建一个检查 x
所有可能值的 Z3 函数。最简单的检查方法是只打印求解器,这样它就会显示约束,只需添加 print s
。在你无法满足的情况下,我得到 [x > 1, x < 1]
,这确实是无法满足的。
Python 的 if-then-else 不会转换为 Z3 的 if-then-else。您必须使用 "If" 函数。看这里:https://github.com/Z3Prover/z3/blob/master/src/api/python/z3.py#L1092