我正在尝试验证排序算法并决定将编程语言中的列表建模为元组(大小为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不可用......
提前致谢。
答案 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。