【问题标题】:Counting number of variables in Z3 quantified formula计算 Z3 量化公式中的变量数
【发布时间】:2018-06-04 16:25:21
【问题描述】:

我正在尝试收集公式中的所有变量(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

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

【问题讨论】:

    标签: z3 z3py quantifiers


    【解决方案1】:

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

    【讨论】:

    • 谢谢,困难在于,我正在尝试将 QBF 公式转换为没有量词的公式,因此如果 Var(2) Var(3) 被 0 和 1 替换为非量化版本丢失信息。例如,在上述公式的情况下,非 qbf 版本为:And( And( Var(0), Var(1) ), And ( Var(0), Var(1) ) )。
    • 抱歉,这就是 de-Bruijn 索引的工作方式。如果修改了公式,则必须调整索引(Z3 在许多地方都这样做)。想想使用相同变量名的子公式,这些也必须重命名。
    • 谢谢,我明白了,我在问有没有出路?而你的评论暗示不。
    • 有,您只需要重命名/重新编号所有变量。在 QBF 中,量词前缀是预先声明的,全局用于整个公式,但在 Z3 中,量词是在本地声明的子表达式。当您创建一个包含量化表达式的全局量词时,Z3 将在必要时对其重新编号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多