2

I'm trying to collect all the variables in a formula (quantified formula in Z3py). A small example

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 )

The code i use to traverse is

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

And I'm getting: set( [Var(0), Var(1)] ). As i understand this is due to Z3 uses De Bruijn index. Is it possible to avoid this and get the desired set: set( [Var(0), Var(1), Var(2), Var(3)] ).

Pushpa
  • 448
  • 3
  • 10

1 Answers1

1

Your code is correct; there is no Var(2) or Var(3) in this example. There are two top-level quantifiers and the de-Bruijn indices in each of them are 0 and 1. Those two quantifiers do not appear within the body of another quantifier, so there can be no confusion.

Christoph Wintersteiger
  • 8,234
  • 1
  • 16
  • 30
  • Thanks, The difficulty is, i'm trying to convert a QBF formula to a formula without quantifiers and hence if Var(2) Var(3) are replaced by 0 and 1 the non-quantified version loses information. For example in the case of the above formula the non-qbf version is : And( And( Var(0), Var(1) ), And ( Var(0), Var(1) ) ). – Pushpa Dec 22 '17 at 14:04
  • Sorry, that's how de-Bruijn indices work. If formulas are modified, the indices have to be adjusted (and Z3 does so in many places). Think of sub-formulas that use the same variable names, those would have to be renamed too. – Christoph Wintersteiger Dec 22 '17 at 14:21
  • Thanks, I understand it, I was asking is there a way out ? And your comment is suggesting No. – Pushpa Dec 22 '17 at 14:24
  • 1
    There is, you'll just have to rename/renumber all the variables. In QBF the quantifier prefix is declared up front, globally for the whole formula, but in Z3 the quantifiers are declared locally for sub-expressions. When you create a global quantifier that contains quantified expressions, Z3 will renumber them if necessary. – Christoph Wintersteiger Dec 22 '17 at 15:24