Има ли начин да се използва Z3 за получаване на модели за ограничения, включващи последователности и карти?

Преди време попитах как мога да използвам Z3, за да получа модели за ограничения, включващи набори (Има ли начин да се използва Z3 за получаване на модели за ограничения, включващи набори?). За това теорията за разширения масив работи добре в моя случай.

Сега имам същия проблем с последователности (с дължина на операциите, членство, (не)равенство, може би нарязване) и карти. т.е. аксиоматизацията води до същия проблем както при множествата. Мислех да кодирам последователности и карти, използвайки и теорията за разширените масиви, но все още не съм успял да измисля добър начин да направя това.

Някой има ли идея как могат да бъдат кодирани поредици и карти, за да се получат точни модели?


person Patrick Spettel    schedule 10.10.2013    source източник


Отговори (1)


В Z3 масивите са по същество карти. Ето пример как да създадете "масив" от списък от цели числа към цели числа.

(declare-const a (Array (List Int) Int))
(declare-const l1 (List Int))
(declare-const l2 (List Int))
(assert (= (select a l1) 0))
(assert (= (select a l2) 0))
(check-sat)
(get-model)

За последователностите можем да ги кодираме с помощта на квантори. Z3 е пълен за много разрешими фрагменти. Повечето от тях са описани в урока за Z3. Ето възможно кодиране.

;; In this example, we are encoding sequences of T.
;; Let us make T == Int
(define-sort T () Int)

;; We represent a sequence as a pair: function + length
(declare-fun S1-data (Int) T)
(declare-const S1-len  Int)

(declare-fun S2-data (Int) T)
(declare-const S2-len  Int)

(declare-fun S3-data (Int) T)
(declare-const S3-len  Int)

;; This encoding has one limitation, we can't have sequences of sequences; nor have sequences as arguments of functions.

;; Here is how we assert that the sequences S1 and S2 are equal.
(push)
(assert (= S1-len S2-len)) 
(assert (forall ((i Int)) (=> (and (<= 0 i) (< i S1-len)) (= (S1-data i) (S2-data i)))))
;; To make the example more interesting, let us assume S1-len > 0
(assert (> S1-len 0))
(check-sat)
(get-model)
(pop)

;; Here is how we say that sequence S3 is the concatenation of sequences S1 and S2.
(push)
(assert (= S3-len (+ S1-len S2-len)))
(assert (forall ((i Int)) (=> (and (<= 0 i) (< i S1-len)) (= (S3-data i) (S1-data i)))))
(assert (forall ((i Int)) (=> (and (<= 0 i) (< i S2-len)) (= (S3-data (+ i S1-len)) (S2-data i)))))
;; let us assert that S1-len and S2-len > 1
(assert (> S1-len 1))
(assert (> S2-len 1))
;; let us also assert that S3(0) != S3(1)
(assert (not (= (S3-data 0) (S3-data 1))))
(check-sat)
(get-model)
(pop)

;; Here is how we encode that sequence S2 is sequence S1 with one extra element a
(push)
(declare-const a T)
(assert (> a 10))
(assert (= S2-len (+ 1 S1-len)))
(assert (= (S2-data S1-len) a))
(assert (forall ((i Int)) (=> (and (<= 0 i) (< i S1-len)) (= (S2-data i) (S1-data i)))))
;; let us also assert that S1-len > 1
(assert (> S1-len 1))
(check-sat)
(get-model)
(pop)
person Leonardo de Moura    schedule 13.10.2013