从z3py获取证据

时间:2015-04-11 12:15:15

标签: python z3 z3py

我一直在浏览Z3Py的文档,因为我这样的人都无法弄清楚如何从解算器中获取证据(例如,如果我从De Morgan定律的实例开始,我该如何提取来自实例的Z3Py的证明,一步一步)。我看到的唯一参考是proof(self)类中的Solver,如果启用了证明构造,它应该得到最后一次检查的证据,但我一直收到非常模糊的错误:

Traceback (most recent call last):
  File "example.py", line 36, in <module>
    prove(prop)
  File "example.py", line 15, in prove
    print(s.proof())
  File "src/api/python/z3.py", line 5851, in proof
  File "src/api/python/z3core.py", line 3770, in Z3_solver_get_proof
z3types.Z3Exception: 'invalid usage'`

因此我默认禁用了数据证明构造(可能是因为开销问题)。我该如何启用它?或者这甚至没有达到我认为应该达到的目的,通过像Idempotency这样简单的公理来逐步推导证明?

更新 :实际上,经过尝试,(相信我,我确保我的版本是微软研究网站的最新版本,甚至重建了它)set_param未定义:

>>> from z3 import *
>>> print [s for s in dir(z3) if 'set_param' in s]
['Z3_fixedpoint_set_params', 'Z3_set_param_value', 'Z3_solver_set_params']
>>> set_param
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'set_param' is not defined

我随后尝试使用Z3_set_param_valueZ3_solver_set_params,然后set_option(proof=True)(因为它在参考中被列为set_param`的别名)无济于事:

>>> set_option(proof=True)
Error setting 'PROOF', reason: unknown option.
terminate called after throwing an instance of 'z3_error'
Aborted (core dumped)

1 个答案:

答案 0 :(得分:1)

是的,您必须设置proof = True才能启用校样。此外,必须在启用证明的模式下创建所有表达式。一种方法如下:

>>> set_param(proof=True)
>>> ctx = Context()
>>> s = Solver(ctx=ctx)
>>> x = Int('x', ctx=ctx)
>>> s.add(x > 0)
>>> s.add(x == 0)
>>> s.check()
unsat
>>> s.proof()
mp(mp(asserted(x > 0),
      rewrite((x > 0) == Not(x <= 0)),
      Not(x <= 0)),
   trans(monotonicity(trans(monotonicity(asserted(x == 0),
                                        (x <= 0) == (0 <= 0)),
                            rewrite((0 <= 0) == True),
                            (x <= 0) == True),
                      Not(x <= 0) == Not(True)),
         rewrite(Not(True) == False),
         Not(x <= 0) == False),
   False)

在此示例中,我将校样模式设置为全局true。然后创建一个在任何地方传递表达式或求解器的引用上下文。

如果您确保在对Z3进行任何其他调用之前将校样模式设置为True,那么您不必携带自己的上下文。换句话说,以下也有效:

python.exe
>>> from z3 import *
>>> set_param(proof=True)
>>> x = Int('x')
>>> s = Solver()
>>> s.add(x > 0)
>>> s.add(x == 0)
>>> s.check()
unsat
>>> s.proof() 
mp(mp(asserted(x > 0),
      rewrite((x > 0) == Not(x <= 0)),
      Not(x <= 0)),
   trans(monotonicity(trans(monotonicity(asserted(x == 0),
                                        (x <= 0) == (0 <= 0)),
                          rewrite((0 <= 0) == True),
                        (x <= 0) == True),
                  Not(x <= 0) == Not(True)),
     rewrite(Not(True) == False),
     Not(x <= 0) == False),
  False)