平等列表是彼此的排列。为什么Z3回答'未知'?

时间:2016-03-10 15:45:45

标签: arrays z3

我正在尝试验证排序算法并决定将编程语言中的列表建模为元组(大小为Int,内容为Array Int - > Obj)并将其称为MyList。

然后我遇到了以下问题:

l0和l1是这样的MyLists。

当被问及(assert (not (permutation l0 l0)))时,Z3会快速回答unsat

当被问及(assert (not (permutation l1 l1)))时,Z3会快速回答unsat

但是当我要求

(assert (= l1 l0))
(assert (not (permutation l1 l0)))

几秒后答案unknown。怎么可能?这个查询难度更大吗? AFAIK数组在Z3中是扩展的,因此将两个列表等同起来应该归结为反身案例,不是吗?

以下是完整代码(SMT-LIB2):

(set-option :produce-unsat-cores true)
(set-option :produce-models true)

; --------------- Basic Definitions -------------------

(declare-sort Obj 0)

; --------------- Predicates -------------------------------

(declare-datatypes () ((MyList (mk-pair (size Int) (contents (Array Int Obj))))))

(define-fun size_list ((l MyList) (size Int)) Bool
                      (and
                        (<= 0 size)
                        (= (size l) size)
                      )
)

(define-fun select_list ((l MyList) (index Int) (result Obj)) Bool
                        (and
                          (exists ((sl Int))
                            (and
                              (size_list l sl)
                              (>= index 0)
                              (< index sl)
                            )
                          )
                          (= (select (contents l) index) result)
                        )
)

(define-fun in_list ((o Obj) (l MyList)) Bool
                    (exists ((i Int)) (select_list l i o)))


(define-fun permutation ((l1 MyList) (l2 MyList)) Bool
                        (forall ((o Obj)) (= (in_list o l1) (in_list o l2))))

(declare-const l0 MyList)
(declare-const l1 MyList)

;(assert (not (permutation l0 l0)))  ; unsat
;(assert (not (permutation l1 l1)))  ; unsat

(assert (= l1 l0))
(assert (not (permutation l1 l0)))   ; unknown

; --------------- Verify -------------------
(check-sat)

另外:当解算器回答unknown时,如何继续?在这种情况下,型号和Unsat-cores不可用......

提前致谢。

1 个答案:

答案 0 :(得分:1)

是的,这是对预处理过程中量词处理方式的限制,而Z3无法检索简单的同余。

也许您可以从对序列的新支持中受益。然后这个问题,可能还有相关问题,变得更加容易:

(set-option :produce-unsat-cores true)
(set-option :produce-models true)

; --------------- Basic Definitions -------------------

(declare-sort Obj 0)

; --------------- Predicates -------------------------------

(define-sort MyList () (Seq Obj))

(define-fun in_list ((o Obj) (l MyList)) Bool (seq.contains l (seq.unit o)))


(define-fun permutation ((l1 MyList) (l2 MyList)) Bool
                    (forall ((o Obj)) (= (in_list o l1) (in_list o l2))))

(declare-const l0 MyList)
(declare-const l1 MyList)

;(assert (not (permutation l0 l0)))  ; unsat
;(assert (not (permutation l1 l1)))  ; unsat

(assert (= l1 l0))
(assert (not (permutation l1 l0)))   ; unknown

; --------------- Verify -------------------
(check-sat)

有关详细信息,请参阅http://rise4fun.com/z3/tutorial/sequences