我对使用通用量词和declare-const而不使用forall
感到困惑(set-option :mbqi true)
(declare-fun f (Int Int) Int)
(declare-const a Int)
(declare-const b Int)
(assert (forall ((x Int)) (>= (f x x) (+ x a))))
我可以这样写:
(declare-const x Int)
(assert (>= (f x x) (+ x a))))
在这两种情况下,使用Z3 将探索Int类型的所有可能值。那有什么区别? 我真的可以使用declare-const来消除forall量词吗?
答案 0 :(得分:5)
不,这些陈述是不同的。 Z3中的常量是nullary(0 arity)函数,因此(declare-const a Int)
只是(declare-fun a () Int)
的语法糖,所以这两个语句是相同的。你的第二个语句(assert (>= (f x x) (+ x a))))
隐含地断言x的存在,而不是你的第一个语句(assert (forall ((x Int)) (>= (f x x) (+ x a))))
中的所有x。需要注意的是,请注意,在第二个语句中,只有x的单个赋值需要满足断言,而不是所有可能的赋值(也请注意函数f的差异,并参见此Z3 @ rise脚本:http://rise4fun.com/Z3/4cif )。
以下是该脚本的文字:
(set-option :mbqi true)
(declare-fun f (Int Int) Int)
(declare-const a Int)
(declare-fun af () Int)
(declare-const b Int)
(declare-fun bf () Int)
(push)
(declare-const x Int)
(assert (>= (f x x) (+ x a)))
(check-sat) ; note the explicit model value for x: this only checks a single value of x, not all of them
(get-model)
(pop)
(push)
(assert (forall ((x Int)) (>= (f x x) (+ x a))))
(check-sat)
(get-model) ; no model for x since any model must satisfy assertion
(pop)
此外,这是Z3 SMT指南(http://rise4fun.com/z3/tutorial/guide中“未解释的函数和常量”部分下的示例):
(declare-fun f (Int) Int)
(declare-fun a () Int) ; a is a constant
(declare-const b Int) ; syntax sugar for (declare-fun b () Int)
(assert (> a 20))
(assert (> b a))
(assert (= (f 10) 1))
(check-sat)
(get-model)
答案 1 :(得分:4)
您可以使用exists
删除顶级declare-const
。也许这是你困惑的根源?以下两个是等效的:
(assert (exists ((x Int)) (> x 0)))
(check-sat)
和
(declare-fun x () Int)
(assert (> x 0))
(check-sat)
请注意,这仅适用于顶级存在量词。如果您对通用(forall
)和存在(exists
)进行了嵌套量化,那么您可以执行skolemization将存在性浮动到顶层。从逻辑的角度来看,这个过程更为复杂,但相当简单。
通过这种方式,没有将通用量词浮动到顶层的一般方法,至少不是SMT-Lib体现的经典逻辑。