z3py:解析小实数时出错

时间:2012-09-07 18:18:22

标签: z3 z3py

我正在尝试将z3py集成到我的应用程序中。有些断言涉及小的实数,例如

solver.add(x <= 1e-6)

然后我收到以下错误:

File "~/src/solver/z3.py", line 2001, in __le__
  a, b = _coerce_exprs(self, other)
File "~/src/solver/z3.py", line 846, in _coerce_exprs
  b = s.cast(b)
File "~/src/solver/z3.py", line 1742, in cast
  return RealVal(val, self.ctx)
File "~/src/solver/z3.py", line 2526, in RealVal
  return RatNumRef(Z3_mk_numeral(ctx.ref(), str(val), RealSort(ctx).ast), ctx)
File "~/src/solver/z3core.py", line 1774, in Z3_mk_numeral
  raise Z3Exception(lib().Z3_get_error_msg_ex(a0, err))
src.solver.z3types.Z3Exception: 'parser error'

虽然断言

solver.add(x <= 1e-4)

似乎很好。

因此,我猜测z3中存在某种精度限制。如果是这样,是否有选项让第一个断言通过?

感谢。

1 个答案:

答案 0 :(得分:4)

Z3没有精度限制。它可以表示任意精度有理数和代数数。这是一个例子:

print RealVal('1/10000000000000000000000000000')
print simplify((RealVal('1/10') ** RealVal('10')) ** RealVal('10'))

您可以在以下网址进行尝试:http://rise4fun.com/Z3Py/ahJQ

函数RealVal(a)将Python值转换为Z3实数值。它使用Z3 C API Z3_mk_numeral来实现这一目标。此代码在Z3发行版中包含的z3.py文件中提供。 API Z3_mk_numeral期望一个字符串,其以十进制格式(例如,“1.3”)或分数格式(例如,“1/3”)编码有理数。请注意,不支持科学记数法。为了使RealVal(a)方便python用户,我们使用方法str(a)a转换为字符串,然后再调用Z3_mk_numeral。 因此,用户还可以编写RealVal(1)RealVal(1.2)

第二点信息是声明solver.add(x <= 1e-4)基本上是solver.add(x <= RealVal(1e-4))的简写。

现在,我们可以问一下,为什么该示例适用于1e-4,但不适用于1e-6。问题是在Python中实现strstr(1e-4)以Z3 "0.0001"支持的十进制表示法返回字符串Z3_mk_numeral,但str(1e-6)以科学计数形式返回字符串"1e-6"Z3_mk_numeral不支持{1}}。

print str(1e-4)
print str(1e-6)

以下是上述示例的链接:http://rise4fun.com/Z3Py/C02q

为了避免这个问题,我们应该在创建Z3表达式时避免科学记数法中的数字。 我将看看是否有时间在Z3_mk_numeral中为下一版Z3添加对科学记数法的支持。