How do you extract an element as the base type from a Seq type in Z3?

瘦欲@ 提交于 2020-06-25 21:42:28

问题


How do I extract an element in a Sequence to the base type, so that the following will work?

(define-sort ISeq () (Seq Int))
(define-const x ISeq (seq.unit 5))
(define-const y ISeq (seq.unit 6))
(assert (>= (seq.at x 0) (seq.at y 0)))

回答1:


Until a suitable function is implemented (or its existence is revealed to us), you could use the following work-around:

(define-sort ISeq () (Seq Int))
(define-const x ISeq (seq.unit 5))
(define-const y ISeq (seq.unit 6))

(declare-const e1 Int)
(declare-const e2 Int)

(push)
  (assert (= (seq.unit e1) (seq.at x 0)))
  (assert (= (seq.unit e2) (seq.at y 0)))

  (assert (not (>= e2 e1)))
  (check-sat)
(pop)

(push) ;; or alternatively
  (assert (not
    (implies
      (and
        (= (seq.unit e1) (seq.at x 0))
        (= (seq.unit e2) (seq.at y 0)))
      (>= e2 e1))))
  (check-sat)
(pop)



回答2:


See the relevant discussion at the Z3 issue tracker: https://github.com/Z3Prover/z3/issues/1302

It seems a workaround is indeed possible, but due to quantifiers it's unlikely to give you an effective method. An explicit encoding like Malte suggests might be the most practical approach here in the meantime.




回答3:


You're looking for nth. Here is a simple example of it:

(define-sort ISeq () (Seq Int))
(declare-const x ISeq)
(declare-const y ISeq)
(assert (= (seq.len x) 4))
(assert (= (seq.len y) 3))
(assert (< (seq.nth x 3) (seq.nth y 1)))
(check-sat)
(get-value (x y))

And z3 answers immediately with a correct answer (1237 > 1236):

sat
((x (seq.++ (seq.unit 6)
        (seq.++ (seq.unit 7) (seq.++ (seq.unit 8) (seq.unit 1236)))))
 (y (seq.++ (seq.unit 9) (seq.++ (seq.unit 1237) (seq.unit 12)))))


来源:https://stackoverflow.com/questions/46696982/how-do-you-extract-an-element-as-the-base-type-from-a-seq-type-in-z3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!