Z3不会在手工制作的数据类型上进行分割

时间:2013-03-18 11:52:12

标签: z3 theorem-proving

我已经定义了我自己的布尔值,名为boolean是SMT2,AND函数boolean_and就是它们。 我的猜想是AND是可交换的:

(declare-sort boolean)
(declare-const sk_x boolean)
(declare-const sk_y boolean)
(declare-const boolean_false boolean)
(declare-const boolean_true boolean)
(declare-fun boolean_and (boolean boolean) boolean)

;; axiomatize booleans: false /= true and every bool is true or false
(assert (forall ((x boolean)) (or (= x boolean_false)
                                  (= x boolean_true))))

(assert (not (= boolean_false boolean_true)))

;; definition of AND
(assert (forall ((a boolean)) (= (boolean_and boolean_false a) boolean_false)))
(assert (forall ((a boolean)) (= (boolean_and boolean_true a) a)))

;; try to prove that AND is commutative
(assert (not (= (boolean_and sk_x sk_y)
                (boolean_and sk_y sk_x))))

(check-sat)

然而,一段时间后,z3报告此问题未知,即使我 以为它应该能够在skolemised上使用我的案例拆分断言 变量sk_xsk_y

奇怪的是,如果我删除了我的布尔公理化并将其替换为 declare-datatypes,z3将报告unsat

(declare-datatypes () ((boolean (boolean_true) (boolean_false))))

(declare-const sk_x boolean)
(declare-const sk_y boolean)
(declare-fun boolean_and (boolean boolean) boolean)

(assert (forall ((a boolean)) (= (boolean_and boolean_false a) boolean_false)))
(assert (forall ((a boolean)) (= (boolean_and boolean_true a) a)))

(assert (not (= (boolean_and sk_x sk_y)
                (boolean_and sk_y sk_x))))

(check-sat)

我做错了什么?如何使用公理化将z3转换为案例分割?

1 个答案:

答案 0 :(得分:3)

你没有做错任何事。正式版本(v4.3.1)可能会因包含基数约束的问题而失败,例如

(assert (forall ((x boolean)) (or (= x boolean_false)
                                  (= x boolean_true))))

此约束断言未解释的排序boolean最多包含两个元素。 我解决了这个问题。该修补程序已在unstable分支中提供。 Here是有关如何编译unstable分支的一些说明。 明天,nightly builds也会包含此修复程序。