无法了解unsat-core的Z3行为

时间:2018-07-17 11:24:40

标签: z3

我知道Z3不能保证最小的非核心响应,但是我在下一个脚本的输出中看到的内容对我来说很奇怪。

在脚本中,我尝试检查这样的简单表达式(以某种伪语言):

(n_number == 22) AND (n_text == "abcd") AND (n_number == 44)

很明显,结果是由第一和第三子句引起的。

(对我而言)奇怪的是,非核心响应会根据我(命名)的断言顺序而变化。

我认为第二个子句永远不会出现在unsat响应中,但是 在案例4中,我看到了。

结果

RESULT for script "little3pieces"

---------- CASE 1: assert only on piece1 and piece3
unsat
(as22val as22noMiss as22noErr as44val namedP1t namedP3t)

---------- CASE 2: assert on all pieces (order: 2,1,3)
unsat
(as22val as22noMiss as22noErr as44val namedP1t namedP3t)

---------- CASE 3: assert on all pieces (order: 1,2,3)
unsat
(as22val as22noMiss as22noErr as44val namedP1t namedP3t)

---------- CASE 4: assert on all pieces (order: 1,3,2)
unsat
(as22val as44val as44noErr namedP1t **namedP2t** namedP3t)

有人可以给我一个解释吗?

(在我的脚本中,每种类型都有2个标志,所以我有:

  • TValue Int->一个带有ERRor布尔值和MISSing布尔值的整数

  • TValue布尔->布尔型,其中布尔用于ERRor,布尔用于MISSing

依此类推...)

(set-option :produce-unsat-cores true)
; REMEMBER: set name on assert 

(set-option :interactive-mode true)  ;;; <<< TO USE (get-assertions)


;#######################
;RECORD DATATYPE with BOTTOM and ERROR
;#######################
(declare-datatypes (U) ((TValue (mk-val (val U)(miss Bool)(err Bool)))))

;#######################
;Set of elements of type T with attached an integer index
;#######################
(define-sort Set (T) (Array Int T)) 

;################### MyString DECLARATIONs #######################
 (declare-datatypes () ((MyString s_abcd  s_AdditionalStringValue )))

;################### FACPL FUNCTION DECLARATIONs #######################
(define-fun isFalse ((x (TValue Bool))) Bool
    (ite (= x (mk-val false false false)) true false)
)

(define-fun isTrue ((x (TValue Bool))) Bool
    (ite (= x (mk-val true false false)) true false)
)


(define-fun equalInt ((x (TValue Int)) (y (TValue Int))) (TValue Bool)
    (ite (or (err x) (err y))
        (mk-val false false true)
        (ite (or (miss x) (miss y))
            (mk-val false true false)
            (ite (= (val x) (val y))
                (mk-val true false false)
                (mk-val false false false)
            )
        )
    )
)

;; SIMILAR VERSION
(define-fun equalString ((x (TValue MyString)) (y (TValue MyString))) (TValue Bool)
    (ite (or (err x) (err y))
        (mk-val false false true)
        (ite (or (miss x) (miss y))
            (mk-val false true false)
            (ite (= (val x) (val y))
                (mk-val true false false)
                (mk-val false false false)
            )
        )
    )
)

;########### END DATATYPEs AND FUNCTIONs DECLARATION #######



;############# ATTRIBUTE DECLARATIONs ###################
(declare-const n_number (TValue Int))
;; ORIG without name... (assert (not (and (miss n_number) (err n_number))))
(assert (! (not (and (miss n_number) (err n_number))) :named asNumberConstraint ))


(declare-const n_text (TValue MyString))
;; ORIG without name... (assert (not (and (miss n_text) (err n_text))))
(assert (! (not (and (miss n_text) (err n_text))) :named asTextConstraint ))


;########### CONSTANTs DECLARATIONs ##################

;;; ------------------------------------- CONSTANT INT = 22
(declare-const const_22 (TValue Int))

; ORIG without name
;(assert (= (val const_22) 22))
;(assert (not (miss const_22))) 
;(assert (not (err const_22)))

; same with name 
(assert (! (= (val const_22) 22) :named as22val) )
(assert (! (not (miss const_22)) :named as22noMiss) )
(assert (! (not (err const_22))  :named as22noErr) )



;;; ------------------------------------- CONSTANT INT = 44
(declare-const const_44 (TValue Int))

; ORIG without name
;(assert (= (val const_44) 44))
;(assert (not (miss const_44))) 
;(assert (not (err const_44)))

(assert (! (= (val const_44) 44) :named as44val) )
(assert (! (not (miss const_44)) :named as44noMiss) )
(assert (! (not (err const_44))  :named as44noErr) )



;;; ------------------------------------- CONSTANT (MY)STRING = s_abcd
(declare-const const_abcd (TValue MyString))

; ORIG without name
;(assert (= (val const_abcd) s_abcd))
;(assert (not (miss const_abcd))) 
;(assert (not (err const_abcd)))

(assert (! (= (val const_abcd) s_abcd) :named asABCDval) )
(assert (! (not (miss const_abcd))     :named asABCDnoMiss) )
(assert (! (not (err const_abcd))      :named asABCDnoErr) )



;######## END ATTRIBUTEs AND CONSTANTs DECLARATION ###############


; --------- BEFORE THIS LINE ALL ASSERTS ARE GIVEN ---------
; --------- but they could be wrong anyway !!!!!!! ---------
; -- so, please, give me hints about all possible defects --



; ===============================================
; START VERIFICATION MADE WITH MY ASSERTS
; ===============================================


; I try to check a simple expression like this (in some pseudo-language):
; (n_number == 22) AND (n_text == "abcd") AND (n_number == 44)



(push)

(define-fun piece1 () (TValue Bool) (equalInt const_22 n_number))    ;;; piece1
(define-fun piece2 () (TValue Bool) (equalString const_abcd n_text)) ;;; piece2
(define-fun piece3 () (TValue Bool) (equalInt n_number const_44))    ;;; piece3


;;; (get-assertions)

; Clearly the result is unsat, caused by piece1 and piece3



; ---------- begin CASE 1 ----------
(push)
(echo "")
(echo "---------- CASE 1: assert only on piece1 and piece3")

(assert (! (isTrue piece1) :named namedP1t))   
(assert (! (isTrue piece3) :named namedP3t))   

(check-sat)
(get-unsat-core)

; I GET:
; (as22val as22noMiss as22noErr as44val namedP1t namedP3t)


(pop)
; ---------- end CASE 1 ----------



; ---------- begin CASE 2 ----------
(push)
(echo "")
(echo "---------- CASE 2: assert on all pieces (order: 2,1,3)")

(assert (! (isTrue piece2) :named namedP2t))  ; <<<< namedP2t on top
(assert (! (isTrue piece1) :named namedP1t))
(assert (! (isTrue piece3) :named namedP3t))

(check-sat)
(get-unsat-core)

; I GET:
; (as22val as22noMiss as22noErr as44val namedP1t namedP3t)

(pop)
; ---------- end CASE 2 ----------



; ---------- begin CASE 3 ----------
(push)
(echo "")
(echo "---------- CASE 3: assert on all pieces (order: 1,2,3)")

(assert (! (isTrue piece1) :named namedP1t))
(assert (! (isTrue piece2) :named namedP2t))  ; <<<< namedP2t in the middle
(assert (! (isTrue piece3) :named namedP3t))

(check-sat)
(get-unsat-core)

; I GET:
; 

(pop)
; ---------- end CASE 3 ----------




; NOW THE STRANGE THING!!!! (FOR ME)



; ---------- begin CASE 4 ----------
(push)
(echo "")
(echo "---------- CASE 4: assert on all pieces (order: 1,3,2)")

(assert (! (isTrue piece1) :named namedP1t))
(assert (! (isTrue piece3) :named namedP3t))
(assert (! (isTrue piece2) :named namedP2t))  ; <<<< namedP2t on bottom

(check-sat)
(get-unsat-core)

; I GET:
; (as22val as44val as44noErr namedP1t namedP2t namedP3t)
; NOW I SEE namedP2t !!!!! WHY?????????????????????????????????
; named2Pt is never the cause of unsat!!!!!!!

(pop)
; ---------- end CASE 4 ----------

0 个答案:

没有答案