比方说,我在Z3中有一个简单的求和类型,其中包含几个不同Arities的构造函数:
(declare-datatypes ()
((Foo bar
(baz (unbaz String))
(quux (unquux1 String) (unquux2 Int)))))
如何断定我知道类型Foo
的值是quux
?我可以在quux1
和quux2
上引入一个存在性,但是我对引入似乎不必要的量词保持谨慎。有没有更好的方法来断言呢?
答案 0 :(得分:0)
假设存在时,存在是相当无害的,因为直接量化存在量化的变量,因此仅需要附加符号。也就是说,摘要的后半部分
(declare-datatypes ()
((Foo bar
(baz (unbaz String))
(quux (unquux1 String) (unquux2 Int)))))
(declare-const f Foo)
(assert (exists ((s String) (i Int)) ;; Let f be a quux
(= f (quux s i))
))
(assert (= f (baz "test"))) ;; Also let f be a baz
(check-sat) ;; UNSAT - as expected
等同于
...
(declare-const _s String)
(declare-const _i Int)
(assert (= f (quux _s _i))) ;; Let f be a quux
(assert (= f (baz "test"))) ;; Also let f be a baz
(check-sat) ;; UNSAT - as expected
如果您对存在性而不是包容所有的事物保持警惕,则可以通过Foo
构造函数到不同标签的映射公理化方法来标记 Foo
值:
(set-option :smt.mbqi false)
(declare-datatypes ()
((Foo bar
(baz (unbaz String))
(quux (unquux1 String) (unquux2 Int)))))
;; Declare a finite sort Foo_tag with three distinct elements
(declare-datatypes () ((Foo_tag Foo_tag.bar Foo_tag.baz Foo_tag.quux)))
;; Alternatively, three distinct elements from an infinite sort such
;; as Int can be used. Either by choosing distinct but unspecified
;; values, as done below, or by directly choosing concrete values,
;; e.g. 1, 2, 3.
; (define-sort Foo_tag () Int)
; (declare-const Foo_tag.bar Foo_tag)
; (declare-const Foo_tag.baz Foo_tag)
; (declare-const Foo_tag.quux Foo_tag)
; (assert (distinct Foo_tag.bar Foo_tag.baz Foo_tag.quux))
;; Tagging function
(declare-fun tag_of (Foo) Foo_tag)
;; Tagging axiom for bar ...
(assert (= (tag_of bar) Foo_tag.bar))
;; ... baz ...
(assert (forall ((s String)) (!
(= (tag_of (baz s)) Foo_tag.baz)
:pattern ((baz s))
)))
;; ... and quux
(assert (forall ((s String) (i Int)) (!
(= (tag_of (quux s i)) Foo_tag.quux)
:pattern ((quux s i))
)))
;; Let's do some testing
(declare-const f Foo)
(assert (= (tag_of f) Foo_tag.quux)) ;; Tag f as a quux
(push)
(assert (= f bar))
(check-sat) ;; UNSAT - as expected
(pop)
(push)
(assert (= f (baz "test")))
(check-sat) ;; UNSAT - as expected
(pop)