Z3 / Python从模型中获取python值

时间:2012-09-26 09:17:58

标签: python z3 z3py

如何从Z3模型中获取真正的python值?

E.g。

p = Bool('p')
x = Real('x')
s = Solver()
s.add(Or(x < 5, x > 10), Or(p, x**2 == 2), Not(p))
s.check()
print s.model()[x]
print s.model()[p]

打印

-1.4142135623?
False

但是那些是Z3对象而不是python float / bool对象。

我知道我可以使用is_true / is_false来检查布尔值,但是如何优雅地将ints / reals / ...转换回可用值(无需通过字符串并切除此例如,额外的?符号。

1 个答案:

答案 0 :(得分:19)

对于布尔值,您可以使用函数is_trueis_false。数值可以是整数,有理数或代数。我们可以使用函数is_int_valueis_rational_valueis_algebraic_value来测试每个案例。整数情况最简单,我们可以使用方法as_long()将Z3整数值转换为Python long。对于有理值,我们可以使用方法numerator()denominator()来获得表示分子和分母的Z3整数。方法numerator_as_long()denominator_as_long()self.numerator().as_long()self.denominator().as_long()的快捷方式。最后,代数数字用于表示无理数。 AlgebraicNumRef类有一个名为approx(self, precision)的方法。它返回一个Z3有理数,用精度1/10^precision近似代数数。以下是如何使用此方法的示例。它也可以在线获取:http://rise4fun.com/Z3Py/Mkw

p = Bool('p')
x = Real('x')
s = Solver()
s.add(Or(x < 5, x > 10), Or(p, x**2 == 2), Not(p))
s.check()
m = s.model()
print m[p], m[x]
print "is_true(m[p]):", is_true(m[p])
print "is_false(m[p]):", is_false(m[p])
print "is_int_value(m[x]):", is_int_value(m[x])
print "is_rational_value(m[x]):", is_rational_value(m[x])
print "is_algebraic_value(m[x]):", is_algebraic_value(m[x])
r = m[x].approx(20) # r is an approximation of m[x] with precision 1/10^20
print "is_rational_value(r):", is_rational_value(r)
print r.numerator_as_long()
print r.denominator_as_long()
print float(r.numerator_as_long())/float(r.denominator_as_long())