所以,我认为你实际上是正确的,这是我使用自动(通过 Z3 的 SNF 策略)和手动(通过添加常数 c)skolemization 的脚本,它在模型中为 skolem 常数提供了预期的值 3( smt-lib 脚本: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)
另外,请注意 Z3 内置了 Skolem 范式 (SNF) 转换策略,这是 z3py 中的一个示例(脚本链接: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