如何从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 / ...转换回可用值(无需通过字符串并切除此例如,额外的?
符号。
答案 0 :(得分:19)
对于布尔值,您可以使用函数is_true
和is_false
。数值可以是整数,有理数或代数。我们可以使用函数is_int_value
,is_rational_value
和is_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())