我可以使用declare-const来消除forall通用量词吗?

时间:2012-11-05 23:14:57

标签: z3 theorem-proving

我对使用通用量词和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量词吗?

2 个答案:

答案 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体现的经典逻辑。