我试图理解如何在z3
中索引绑定变量。
这里是z3py
中的一个片段和相应的输出。 (http://rise4fun.com/Z3Py/plVw1)
x, y = Ints('x y')
f1 = ForAll(x, And(x == 0, Exists(y, x == y)))
f2 = ForAll(x, Exists(y, And(x == 0, x == y)))
print f1.body()
print f2.body()
输出:
ν0 = 0 ∧ (∃y : ν1 = y)
y : ν1 = 0 ∧ ν1 = y
在f1
中,为什么相同的绑定变量x
具有不同的索引。(0
和1
)。如果我修改f1
并显示Exists
,则x
具有相同的索引(0
)。
原因我想了解索引机制:
我在scala中使用DSL表示的FOL公式,我想发送给z3
。现在ScalaZ3
有一个mkBound
api,用于创建以index
和sort
为参数的绑定变量。我不确定应该将哪个值传递给index
参数。所以,我想知道以下内容:
如果我有两个公式phi1
和phi2
,其最大绑定变量索引n1
和n2
,那么x
的索引是ForAll(x, And(phi1, phi2))
1}}
此外,有没有办法以索引形式显示所有变量? f1.body()
只是以索引形式显示x
,而不是y
。 (我认为原因是y
仍然绑定在f1.body()
)
答案 0 :(得分:5)
Z3使用de Bruijn指数编码绑定变量。 以下维基百科文章详细描述了de Bruijn指数: http://en.wikipedia.org/wiki/De_Bruijn_index 备注:在上面的文章中,索引从1开始,在Z3中,它们从0开始。
关于第二个问题,您可以更改Z3漂亮的打印机。
Z3发行版包含Python API的源代码。漂亮的打印机在文件python\z3printer.py
中实现。
您只需要替换方法:
def pp_var(self, a, d, xs):
idx = z3.get_var_index(a)
sz = len(xs)
if idx >= sz:
return seq1('Var', (to_format(idx),))
else:
return to_format(xs[sz - idx - 1])
与
def pp_var(self, a, d, xs):
idx = z3.get_var_index(a)
return seq1('Var', (to_format(idx),))
如果要重新定义HTML漂亮的打印机,还应该替换。
def pp_var(self, a, d, xs):
idx = z3.get_var_index(a)
sz = len(xs)
if idx >= sz:
# 957 is the greek letter nu
return to_format('ν<sub>%s</sub>' % idx, 1)
else:
return to_format(xs[sz - idx - 1])
与
def pp_var(self, a, d, xs):
idx = z3.get_var_index(a)
return to_format('ν<sub>%s</sub>' % idx, 1)