Z3中的磺化

Z3中的磺化,z3,smt,theorem-proving,Z3,Smt,Theorem Proving,我正试图在我的理论中删除存在量词。这意味着我用函数替换存在量词,这些函数由存在量词范围内的通用量化变量参数化 我在Z3中找到了一个解释,但是我仍然很难做到这一点。假设以下两个函数: (define-fun f1 ((t Int)) Bool (= t 3)) (define-fun f2 () Bool (exists ((t Int)) (f1 t))) 我相信f2应该是真的,因为存在一个整数t,使得(f1 t)是真的,即t=3。我通过为存在量化公式引入一个常数来应用Skolemizatio

我正试图在我的理论中删除存在量词。这意味着我用函数替换存在量词,这些函数由存在量词范围内的通用量化变量参数化

我在Z3中找到了一个解释,但是我仍然很难做到这一点。假设以下两个函数:

(define-fun f1 ((t Int)) Bool (= t 3))
(define-fun f2 () Bool (exists ((t Int)) (f1 t)))
我相信
f2
应该是真的,因为存在一个整数
t
,使得
(f1 t)
是真的,即
t=3
。我通过为存在量化公式引入一个常数来应用Skolemization:

(define-const c Int)
然后将带有存在量词的公式改写为:

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

这不起作用,即常数
c
没有值3。我怀疑这是因为我们没有解释常量
c
,因为如果我们添加
(assert(=c3))
,它工作得很好,但这带走了存在量词的整个概念。有没有一种方法可以让我对
c
给出一个不太明确的解释,这样就可以工作了?

所以,我想你说得差不多对了,实际上,这是我在自动(通过Z3的SNF策略)和手动(通过添加常数c)skolemization中使用的脚本,它按照预期在模型中为skolem常数提供了值3(smt库脚本:):

另外,请注意,Z3内置了一个Skolem范式(SNF)转换策略,下面是z3py中的一个示例(链接到脚本:):

(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)
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