3

I'm using Z3 theorem prover (using Z3Py: the Z3 API in Python) to create QBF (Quantified Boolean formula).

Is there any way in Z3 to directly convert your qbf formula into Prenex normal form ?

Pushpa
  • 448
  • 3
  • 10

2 Answers2

2

I don't think there's a tactic to convert to Prenex, but you can surely apply the quantifier-elimination tactic and further process your formulas. Note that the transformed formulas will not really look like the originals, as they are mechanically generated.

Here's an example:

from z3 import *

f = Function('f', IntSort(), IntSort(), IntSort())
x, y = Ints('x y')
p = ForAll(x, Or(x == 2, Exists(y, f (x, y) == 0)))

print Tactic('qe')(p)

Here qe is the quantifier elimination tactic. This produces:

[[Not(Exists(x!0,
             Not(Or(x!0 == 2,
                    Exists(x!1,
                           And(f(x!0, x!1) <= 0,
                               f(x!0, x!1) >= 0))))))]]

For a nice tutorial on tactics, see here: http://ericpony.github.io/z3py-tutorial/strategies-examples.htm

alias
  • 28,120
  • 2
  • 23
  • 40
  • Thanks. My goal is to convert the formula generated by Z3 to give as an input to qbf solvers. I'm, not sure.. but using "qe" will complicate things and make it hard to write a translation to standard input format. – Pushpa Nov 27 '17 at 09:02
2

You could use the skolemize tactic (snf) which will by definition be in prenex form. However it will also eliminate existential quantifiers which is not what you want. Here's an example.

(declare-fun a (Int) Bool)
(declare-fun b (Int) Bool)
(declare-fun c (Int) Bool)
(assert
  (forall ((x Int))
    (or
      (exists ((y Int))
        (a y)
      )
      (exists ((z Int))
        (=>
          (b z)
          (c x)
        )
      )
    )
  )
)
(apply
  (and-then
  ; mode (symbol) NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full (default: skolem)
    (using-params snf :mode skolem)
  )
  :print_benchmark true
  :print false
)

When Z3 is given the above it will responds with something like

(declare-fun c (Int) Bool)
(declare-fun b (Int) Bool)
(declare-fun a (Int) Bool)
(assert (forall ((x Int))
          (or (exists ((y Int)) (a y)) (exists ((z Int)) (=> (b z) (c x))))))
(check-sat)

You can see the available tactics by running

echo "(help-tactic)" | ./z3 -in | less

from a bash shell.

Unfortunately I can't see one that states it does conversion to prenex.

delcypher
  • 751
  • 7
  • 7