4

我正在尝试将 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 中存在某种精度限制。如果是这样,是否可以选择让第一个断言通过?

谢谢。

4

1 回答 1

5

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 APIZ3_mk_numeral来实现这一点。此代码可在z3.pyZ3 发行版中包含的文件中找到。APIZ3_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-41e-6. 问题是str在 Python 中的实现。以十进制形式返回 Z3 支持str(1e-4)的字符串,但以科学计数形式返回 Z3 不支持的字符串。"0.0001"Z3_mk_numeralstr(1e-6)"1e-6"Z3_mk_numeral

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

这是上面示例的链接:http ://rise4fun.com/Z3Py/C02q

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

于 2012-09-07T18:55:05.403 回答