Z3中的磺化
我正试图在我的理论中删除存在量词。这意味着我用函数替换存在量词,这些函数由存在量词范围内的通用量化变量参数化 我在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
(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