上下文:我正在使用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()调用似乎打破了两个关系之间的联系。不知道这是一个错误还是我自己的误解...
答案 0 :(得分:0)
从外观上看,它也可以通过C / C ++ API获得:
我认为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