如何从Z3中的Seq类型中提取元素作为基类型?

时间:2017-10-11 20:28:07

标签: z3

如何将序列中的元素提取到基本类型,以便以下方法有效?

(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)))

3 个答案:

答案 0 :(得分:3)

在实现合适的功能之前(或者向我们揭示它的存在),您可以使用以下解决方法:

(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)

答案 1 :(得分:1)

请参阅Z3问题跟踪器中的相关讨论:https://github.com/Z3Prover/z3/issues/1302

看起来确实可行,但由于量词,它不太可能给你一个有效的方法。像Malte这样的明确编码可能是最实用的方法。

答案 2 :(得分:0)

您正在寻找nth。这是一个简单的例子:

(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))

z3会立即给出正确答案(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)))))