Z3 / Z3py中的传递闭包

时间:2019-06-07 14:46:53

标签: z3 z3py

上下文:我正在使用Z3编程指南: https://theory.stanford.edu/~nikolaj/programmingz3.html

看起来Z3现在已经内置了对传递闭包的支持,但目前只能通过Z3py进行访问: https://theory.stanford.edu/~nikolaj/programmingz3.html#sec-transitive-closure

我有两个问题:

(1)是否可以通过其他API或直接通过“ z3 -in”访问可执行文件,还是目前仅针对Z3py?

(2)TransitiveClosure是否应该与push和pop互操作?我们在本周初从master分支构建(提交2788f72bbb6bfd6bdad2da2b4c37ef1bb502469d)并运行以下示例:

from z3 import *
B = BoolSort()
S = DeclareSort('S')
a, b, c = Consts('a b c', S)
R = Function('R', S, S, B)
TCR = TransitiveClosure(R)
s = Solver()

s.add(R(a, b) == True)
s.push()     # If this line is uncommented (or both are) the result is sat, which is wrong.
s.add(TCR(a, b) == False)
s.push()     # But if THIS line is uncommented (or neither are), the result is unsat, which is correct.

print(s)
print(s.check())

正如评论所指出的那样,关于R及其传递闭包的声明之间的push()调用似乎打破了两个关系之间的联系。不知道这是一个错误还是我自己的误解...

2 个答案:

答案 0 :(得分:0)

从外观上看,它也可以通过C / C ++ API获得:

https://github.com/Z3Prover/z3/blob/62de187d02d8d2e7a3667a31753c508f7c73aaa1/src/api/c%2B%2B/z3%2B%2B.h#L637-L639

我认为SMTLib接口(我假设您是z3 -in的意思)不可用,因为它本身正在返回一个关系。并且SMTLib中通常不允许使用此类高阶构造。 (当然,可能会有一个“魔术”开关;众所周知,z3正在试验不属于SMTLib的功能。)

关于是否应该与push / pop一起使用:我认为z3中的定点引擎不允许增量求解;因此,对于它的行为异常,我并不感到惊讶。您绝对应该在他们的问题站点(https://github.com/Z3Prover/z3/issues)报告此行为,这样,如果您尝试做增量工作,他们至少可以发出错误消息,而不是吐出误导性信息。 (或者也许您遇到了错误!所以,这对他们来说也很有帮助。)

答案 1 :(得分:0)

s.pop(),s.push() 不是必需的。

# https://theory.stanford.edu/~nikolaj/programmingz3.html#sec-transitive-closure
from z3 import *
B = BoolSort()
S = DeclareSort('S')

R = Function('R', S, S, B)
TCR = TransitiveClosure(R)
a, b, c = Consts('a b c', S)
s = Solver()

s.add(R(a, b))
s.add(R(b, c))
s.add(Not(TCR(a, c))) # s.add(Not(R(a, c))) will be “sat”,because TCR is transitiveclosure but R is not.
print(s)
print(s.check())  # unsat