Смешивание вещественных чисел и бит-векторов

У меня есть два скрипта SMT2-Lib, использующие реалы, которые морально эквивалентны. Разница лишь в том, что один использует битовые векторы, а другой - нет.

Вот версия, которая использует как реалы, так и битовые векторы:

; uses both reals and bit-vectors
(set-option :produce-models true)
(define-fun s2 () Real (root-obj (+ (^ x 2) (- 2)) 2))
(define-fun s3 () Real 0.0)
(define-fun s6 () Real (/ 1.0 1.0))
(declare-fun s0 () (_ BitVec 1))
(declare-fun s1 () (_ BitVec 1))
(assert
   (let ((s4 (- s3 s2)))
   (let ((s5 (ite (= #b1 s1) s2 s4)))
   (let ((s7 (+ s5 s6)))
   (let ((s8 (- s5 s6)))
   (let ((s9 (ite (= #b1 s0) s7 s8)))
   (let ((s10 (ite (>= s9 s3) #b1 #b0)))
   (= s10 #b1))))))))

(check-sat)
(get-model)

Вот морально эквивалентный сценарий, используя Bool вместо битового вектора размера 1, в остальном он по сути тот же:

; uses reals only
(set-option :produce-models true)
(define-fun s2 () Real (root-obj (+ (^ x 2) (- 2)) 2))
(define-fun s3 () Real 0.0)
(define-fun s6 () Real (/ 1.0 1.0))
(declare-fun s0 () (Bool))
(declare-fun s1 () (Bool))
(assert
   (let ((s4 (- s3 s2)))
   (let ((s5 (ite s1 s2 s4)))
   (let ((s7 (+ s5 s6)))
   (let ((s8 (- s5 s6)))
   (let ((s9 (ite s0 s7 s8)))
   (let ((s10 (ite (>= s9 s3) #b1 #b0)))
   (= s10 #b1))))))))

(check-sat)
(get-model)

Для первого я получаю unknown от z3 (v4.1 на Mac), в то время как последний приятно производит sat и модель.

Хотя SMT-Lib2 не позволяет смешивать реалы и битовые векторы, я думал, что Z3 отлично справляется с этими комбинациями. Я ошибаюсь? Есть ли обходной путь?

(Обратите внимание, что это сгенерированные скрипты, поэтому просто Bool вместо (_ BitVec 1) является довольно дорогостоящим, так как требует совсем немного изменений в другом месте.)

1 ответ

Решение

Новый нелинейный решатель еще не интегрирован с другими теориями. Он поддерживает только реальные переменные и логические значения. На самом деле, он также допускает целочисленные переменные, но их поддержка очень ограничена. Он фактически решает нелинейные целочисленные задачи как реальные проблемы и просто проверяет в конце концов, присваивается ли каждой целочисленной переменной целочисленное значение. Более того, этот решатель является единственной полной процедурой для нелинейной (действительной) арифметики, доступной в Z3.

Поскольку ваша первая задача содержит бит-векторы, нелинейный решатель не используется Z3. Вместо этого Z3 использует универсальный решатель, который объединяет многие теории, но он не является полным для нелинейной арифметики.

При этом я понимаю, что это ограничение, и я работаю над этим. В ближайшем будущем Z3 будет иметь новый решатель, который объединяет нелинейную арифметику, массивы, битовые векторы и т. Д.

Наконец, теория битовых векторов является очень частным случаем, так как мы можем легко свести ее к логике высказываний в Z3. Z3 имеет тактику bit-blast это относится это сокращение. Эта тактика может превратить любую нелинейную проблему + бит-вектор в проблему, которая содержит только вещественные и логические значения. Вот пример ( http://rise4fun.com/Z3/0xl).

; uses both reals and bit-vectors
(set-option :produce-models true)
(define-fun s2 () Real (root-obj (+ (^ x 2) (- 2)) 2))
(define-fun s3 () Real 0.0)
(define-fun s6 () Real (/ 1.0 1.0))
(declare-fun s0 () (_ BitVec 1))
(declare-fun s1 () (_ BitVec 1))
(declare-fun v2 () (_ BitVec 8))
(assert
   (let ((s4 (- s3 s2)))
   (let ((s5 (ite (= #b1 s1) s2 s4)))
   (let ((s7 (+ s5 s6)))
   (let ((s8 (- s5 s6)))
   (let ((s9 (ite (= #b1 s0) s7 s8)))
   (let ((s10 (ite (>= s9 s3) #b1 #b0)))
   (= s10 #b1))))))))

(assert (or (and (not (= v2 #x00)) (not (= v2 #x01))) (bvslt v2 #x00)))
(assert (distinct (bvnot v2) #x00))
(check-sat-using (then simplify bit-blast qfnra))
(get-model)
Другие вопросы по тегам