Z3量化公式中变量个数的计算

Z3量化公式中变量个数的计算,z3,z3py,quantifiers,Z3,Z3py,Quantifiers,我试图收集公式中的所有变量(Z3py中的量化公式)。一个小例子 w, x, y, z = Bools('w x y z') fml = And( ForAll(x, ForAll(y, And(x, y))), ForAll(z, ForAll(w, And(z, w))) ) varSet = traverse( fml ) 我用来遍历的代码是 def traverse(e): r = set() def collect(e): if is_quantifier(e):

我试图收集公式中的所有变量(Z3py中的量化公式)。一个小例子

w, x, y, z = Bools('w x y z')
fml = And( ForAll(x, ForAll(y, And(x, y))), ForAll(z, ForAll(w, And(z, w))) ) 

varSet = traverse( fml )
我用来遍历的代码是

def traverse(e):
  r = set()
  def collect(e):
    if is_quantifier(e):
      # Lets assume there is only one type of quantifier
      if e.is_forall():
          collect(e.body())
    else:
      if ( is_and(e) ):
          n = e.num_args()
          for i in range(n):
              collect( e.arg(i) )
      if ( is_or(e) ):
          n = e.num_args()
          for i in range(n):
              collect( e.arg(i) )
      if ( is_not(e) ):
          collect( e.arg(0) )
      if ( is_var(e) ):
          r.add( e )
  collect(e)
  return r

我得到:集([Var(0),Var(1)])。据我所知,这是由于Z3的使用。是否可以避免这种情况并获得所需的集合:集合([Var(0)、Var(1)、Var(2)、Var(3)])

您的代码是正确的;本例中没有
Var(2)
Var(3)
。有两个顶级量词,每个量词中的de Bruijn指数分别为0和1。这两个量词不会出现在另一个量词的主体中,因此不会出现混淆。

谢谢,困难在于,我正在尝试将QBF公式转换为没有量词的公式,因此,如果Var(2)Var(3)被0和1替换,则非量化版本将丢失信息。例如,在上述公式的情况下,非qbf版本是:和(和(Var(0),Var(1)),和(Var(0),Var(1))。对不起,这就是de Bruijn指数的工作方式。如果修改了公式,则必须调整指数(Z3在许多地方都是这样做的)。想想那些使用相同变量名的子公式,它们也必须重新命名。谢谢,我明白了,我在问有办法吗?你的评论是否定的。有,你只需要重命名/重新编号所有变量。在QBF中,量词前缀是预先声明的,全局用于整个公式,但在Z3中,量词是局部声明的,用于子表达式。创建包含量化表达式的全局量词时,Z3将在必要时对其重新编号。