Z3 Smt2 lib:declare const和#x2B;断言`和`定义乐趣'?
我有一个用smt2 lib格式编写的z3模型。我注意到当我使用:Z3 Smt2 lib:declare const和#x2B;断言`和`定义乐趣'?,z3,smt,model-checking,Z3,Smt,Model Checking,我有一个用smt2 lib格式编写的z3模型。我注意到当我使用: (declare-const flat1 (Seq Dummy)) (assert (= flat1 (unroll dummyFormula1))) (define-fun flat1 () (Seq Dummy) (unroll dummyFormula1)) 模型为sat,而我使用时: (declare-const flat1 (Seq Dummy)) (assert (= flat1 (unroll dummyForm
(declare-const flat1 (Seq Dummy))
(assert (= flat1 (unroll dummyFormula1)))
(define-fun flat1 () (Seq Dummy) (unroll dummyFormula1))
模型为sat,而我使用时:
(declare-const flat1 (Seq Dummy))
(assert (= flat1 (unroll dummyFormula1)))
(define-fun flat1 () (Seq Dummy) (unroll dummyFormula1))
该模型被报告为未知。
为什么差异很重要?如果有帮助,我可以制作我的模型的最小版本
编辑#1-一个简单的例子
请确保使用github master中的z3运行它,因为。您可以在下面我用A)
和B)
指示的两个版本之间切换
(set-option :produce-models true)
; --------------- Basic Definitions -------------------
(declare-datatype Dummy (A B))
(declare-datatype Formula
((Base (forB Dummy))
(And (andB1 Formula) (andB2 Formula))
(Or (orB1 Formula) (orB2 Formula))
(Not (notB Formula))))
(declare-const dummyFormula1 Formula)
(assert (= dummyFormula1 (Base A)))
(declare-const dummyFormula2 Formula)
(assert (= dummyFormula2 (And (Base A) (Base A))))
; --------------- Some functions -----------------------
(define-fun
in_list ((o Dummy) (l (Seq Dummy))) Bool
(seq.contains l (seq.unit o)))
(define-fun
permutation ((l1 (Seq Dummy)) (l2 (Seq Dummy))) Bool
(forall ((o Dummy)) (= (in_list o l1) (in_list o l2))))
(define-fun-rec unroll ((f Formula)) (Seq Dummy)
(match f
(((Base j) (seq.unit j))
((And f1 f2) (seq.++ (unroll f1) (unroll f2)))
((Or f1 f2) (seq.++ (unroll f1) (unroll f2)))
((Not f1) (unroll f1)))))
; -------------- The question -------------------------
;; Here are two versions that should express the same idea, but try commenting
;; the first one and uncommenting the second one!
;; A)
(declare-const flat1 (Seq Dummy))
(assert (= flat1 (unroll dummyFormula1)))
;; B)
; (define-fun flat1 () (Seq Dummy) (unroll dummyFormula1))
; -----------------------------------------------------
(declare-const flat2 (Seq Dummy))
(assert (= flat2 (unroll dummyFormula2)))
(assert (permutation flat1 flat2))
; --------------- Verify -------------------
(check-sat)
(get-model)
很难说不看z3的内部结构。但我想指出的是,虽然这两种结构非常相似,但有一个微妙的区别 如果您查看标准()的第62页,它会说:
(define-fun f ((x1 σ1) · · · (xn σn)) σ t)
with n ≥ 0 and t not containing f is semantically equivalent to the command sequence
(declare-fun f (σ1 · · · σn) σ)
(assert (forall ((x1 σ1) · · · (xn σn)) (= ( f x1 · · · xn) t)).
因此,当您使用define fun
表单时,您明确地输入了一个量化公式。当您像手动那样使用declare const
/assert
时,此量化不存在
现在你可以说在你的案例中没有参数,所以应该没有区别,我同意你的观点。但是你也在使用一些新的特性,比如match
,define fun rec
等等,所以很明显z3在这里遇到了一些问题。既然您已经有了一个最小的示例,为什么不将其发布到Z3Github问题站点并在那里获得一些反馈呢。我怀疑宏查找器可能遗漏了一个案例,无法实例化这个特定案例,但确实很难说,而且可能还有一个很好的理由
如果你在那里发帖并得到一个好的答案,请更新这个问题,让我们知道发生了什么 一个最简单的版本确实会有帮助。@PatrickTrentin添加了一个最简单的例子,请告诉我你是否可以重现这种行为。非常好的建议,谢谢@Levent Erkok。如果我得到解释,我会更新这个帖子!