Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Skolemization in Z3

I am trying to remove existential quantifiers in my theory using Skolemization. This means that I replace existential quantifiers with functions that are parameterized by the universally quantified variables in the scope of the existential quantifiers.

Here I found an explanation how to do this in Z3, but I am still having troubles doing it. Suppose the following two functions:

(define-fun f1 ((t Int)) Bool (= t 3))
(define-fun f2 () Bool (exists ((t Int)) (f1 t)))

I believe that f2 should be true, because there exists an integer t such that (f1 t) is true, namely t=3. I apply Skolemization by introducing a constant for the existentially quantified formula:

(define-const c Int)

Then the formula with the existential quantifier is rewritten to:

(define-fun f2 () Bool (f1 c))

This does not work, that is, the constant c does not have the value 3. I suspect it is because we have not given an interpretation to the constant c, because if we add (assert (= c 3)) it works fine, but this takes away the whole idea of the existential quantifier. Is there a way in which I give a less explicit interpretation to c so that this will work?

like image 987
marczoid Avatar asked Oct 17 '25 01:10

marczoid


1 Answers

So, I think you have it about right actually, here's the script I used with automatic (via Z3's SNF tactic) and manual (via adding the constant c) skolemization, which gave the value 3 in the model for the skolem constant as expected (smt-lib script: http://rise4fun.com/Z3/YJy2 ):

(define-fun f1 ((t Int)) Bool (= t 3))
(define-fun f2 () Bool (exists ((t Int)) (f1 t)))
(declare-const c Int)
(define-fun f2a () Bool (f1 c))

(push)
(assert f2)
(check-sat) ; sat
(get-model) ; model gives t!0 = 3 (automatic skolemization in Z3)
(pop)

(push)
(assert f2a)
(check-sat) ; sat
(get-model) ; model gives c = 3 after manual skolemization
(pop)

Also, note that Z3 has a Skolem normal form (SNF) conversion tactic built in, and here's an example in z3py (link to script: http://rise4fun.com/Z3Py/ZY2D ):

s = Solver()

f1 = Function('f1', IntSort(), BoolSort())
t = Int('t')
f2 = Exists(t, f1(t))
f1p = ForAll(t, f1(t) == (t == 3)) # expanded define-fun macro (define-fun f1 ((t Int)) Bool (= t 3))

s.add(f1p)
s.add(f2)

print f1p
print f2

print s.check()
print s.model() # model has skolem constant = 3

g = Goal()
g.add(f1p)
g.add(f2)
t = Tactic('snf') # use tactic to convert to SNF
res = t(g)
print res.as_expr()
s = Solver()
s.add( res.as_expr() )
print s.check()
print s.model() # model has skolem constant = 3
like image 169
Taylor T. Johnson Avatar answered Oct 19 '25 12:10

Taylor T. Johnson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!