Z3py使用pow()函数返回方程的未知值

Z3py使用pow()函数返回方程的未知值,z3,z3py,Z3,Z3py,Z3py使用pow()函数返回以下简单问题的未知值 import z3; goal = z3.Goal(); goal = z3.Then('purify-arith','nlsat'); solver = goal.solver(); x = z3.Real('x'); solver.add(x <= 1.8); solver.add(x >= 0); z = 10**x; #z = pow(10,x) returns same result solver.add(z &g

Z3py使用pow()函数返回以下简单问题的未知值

import z3;

goal = z3.Goal();
goal = z3.Then('purify-arith','nlsat');
solver = goal.solver();

x = z3.Real('x');
solver.add(x <= 1.8);
solver.add(x >= 0);

z = 10**x;
#z = pow(10,x) returns same result

solver.add(z >= 0, z <= 1.8);
print solver.check()

显然,
x=0,z=1
是一个令人满意的解决方案。任何关于改变方程式构造方式或修改策略的建议都值得赞赏。

可能存在一些错误,但下面返回的模型是
x=0
z=1
,尽管它给出了未知的结果。假设Python API也显示了这个模型,您可以创建一个简单的hack来提取模型并将其添加到断言中以进行检查,类似于这如何防止未来的模型重用旧的模型值:

以下是示例(rise4fun链接:):

(声明常量x实数)
(声明常数z为实)
(断言(>=x0.0))
(断言(=x0.0)
;(=0,z.py)
4.3.3
[x=0,z=10**x,z>=0,z=0,

z当你写10x时,你指定了一个指数函数。你打算写x10吗?在这种情况下,Z3返回[x=1]@NikolajBjorner感谢你的评论Nikolaj,我确实打算写“10^x”,指数函数。基于一些其他奇怪的行为(例如,平方根)在SMT-LIB文档中找不到
^
,那么
^
是否意味着求幂?pow和**之类的东西似乎还没有定义。非常感谢约翰逊教授的帮助。你的回答解决了我的问题。顺便说一句,在你的SMT代码中,你使用了战术应用(repeat)(then)(repeat purify arith)(重复简化)(重复ctx简化)(重复ctx解算器简化)(重复nlsat)(重复qfnra nlsat)))。您是否建议将其作为解决困难非线性问题的“默认”策略?您的“每天”是什么战术设置?谢谢!很乐意帮忙!我不认为简化的东西有多大帮助:如果
qfnra nlsat
不能解决非线性实数(或强制整数)问题,简化者可能不会帮上忙。我之所以包含更多内容,是因为发现了一个模型有点奇怪,但结果未知(但是Z3有一些用于部分模型构造和返回上次检查的模型的选项,有趣的是,它没有尝试黑客正在做的事情,只是插入找到的模型并进行检查,我希望简化者可以尝试)。
unknown
(declare-const x Real)
(declare-const z Real)

(assert (>= x 0.0))
(assert (<= x 1.8))
(assert (= z (^ 10.0 x)))
(assert (<= z 1.8))
(assert (>= z 0.0))

(apply (repeat (then purify-arith simplify ctx-simplify ctx-solver-simplify nlsat qfnra-nlsat))) ; gives:
; (goals
;(goal
;  (>= x 0.0)
;  (<= x (/ 9.0 5.0))
;  (<= (^ 10.0 x) (/ 9.0 5.0))
;  (>= (^ 10.0 x) 0.0)
;  :precision precise :depth 44)
;)

; (apply (repeat (then (repeat purify-arith) (repeat simplify) (repeat ctx-simplify) (repeat ctx-solver-simplify)  (repeat nlsat)  (repeat qfnra-nlsat))))

(check-sat) ; unknown
;(check-sat-using qfnra-nlsat) ; unknown

(get-model) ; gives x = 0.0 and z = 1.0 even though unknown from check-sat

; could extract 0 and 1 in python API and check whether it's sat:
(assert (= x 0))
(assert (= z 1))

(check-sat) ; sat
import z3;

print z3.get_version_string();

goal = z3.Goal();
goal = z3.Then('purify-arith','nlsat');
#solver = goal.solver();

solver = z3.Solver();

x = z3.Real('x');
z = z3.Real('z');
solver.add(x <= 1.8);
solver.add(x >= 0);
solver.add(z == 10.0 ** x);

# z = 10**x;
#z = pow(10,x) returns same result

solver.add(z >= 0, z <= 1.8);

print solver

print solver.check()
print solver.model()

m = solver.model()

solver.add(x == m[x])
solver.add(z == m[z])

print solver

print solver.check()
D:\>python exponent.py
4.3.3
[x <= 9/5, x >= 0, z == 10**x, z >= 0, z <= 9/5]
unknown
[x = 0, z = 1]
[x <= 9/5,
 x >= 0,
 z == 10**x,
 z >= 0,
 z <= 9/5,
 x == 0,
 z == 1]
sat