理解Z3中绑定变量的索引

时间:2012-08-05 12:56:59

标签: z3

我试图理解如何在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具有不同的索引。(01)。如果我修改f1并显示Exists,则x具有相同的索引(0)。

原因我想了解索引机制:

我在scala中使用DSL表示的FOL公式,我想发送给z3。现在ScalaZ3有一个mkBound api,用于创建以indexsort为参数的绑定变量。我不确定应该将哪个值传递给index参数。所以,我想知道以下内容:

如果我有两个公式phi1phi2,其最大绑定变量索引n1n2,那么x的索引是ForAll(x, And(phi1, phi2)) 1}}

此外,有没有办法以索引形式显示所有变量? f1.body()只是以索引形式显示x,而不是y。 (我认为原因是y仍然绑定在f1.body()

1 个答案:

答案 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('&#957;<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('&#957;<sub>%s</sub>' % idx, 1)