我试图使用Skolemization在我的理论中删除存在量词。这意味着我用存在量词范围内通用量化变量参数化的函数替换存在量词。
Here我在Z3中找到了如何做到这一点的解释,但我仍然遇到麻烦。假设有以下两个函数:
(define-fun f1 ((t Int)) Bool (= t 3))
(define-fun f2 () Bool (exists ((t Int)) (f1 t)))
我认为f2
应该是真的,因为存在t
整数(f1 t)
,即t=3
为真,即(define-const c Int)
。我通过引入存在量化公式的常数来应用Skolemization:
(define-fun f2 () Bool (f1 c))
然后将具有存在量词的公式重写为:
c
这不起作用,也就是说,常量c
没有值3.我怀疑是因为我们没有给常量(assert (= c 3))
解释,因为如果我们添加{ {1}}它工作得很好,但这会夺走存在量词的整个想法。有没有一种方法可以对c
进行不太明确的解释,以便这样做?
答案 0 :(得分:6)
所以,我认为你实际上对它有正确的意义,这里是我用自动(通过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