我知道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 ----------