问题
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