Я смущен и стараюсь понять, как связаны два разных входных формата для двигателя с фиксированной точкой Z3. Краткий пример: предположим, что я хочу доказать существование отрицательных чисел. Я объявляю функцию, которая возвращает 1 для неотрицательных чисел и 0 для отрицательных, а затем просит решателя сбой, если есть аргументы, для которых функция возвращает 0. Но есть одно ограничение: я хочу, чтобы решатель ответил sat
, когда существует хотя бы один отрицательное число и unsat
, если все числа неотрицательны.∃-запросы и ∀-запросы с движком с фиксированной точкой Z3
Это тривиально с помощью declare-rel
и query
формата:
(declare-rel f (Int Int))
(declare-rel fail())
(declare-var n Int)
(declare-var m Int)
(rule (=> (< n 0) (f n 0)))
(rule (=> (>= n 0) (f n 1)))
(rule (=> (and (f n m) (= m 0)) fail))
(query fail)
Но это становится сложнее при использовании чистого формата SMT-Lib2 (с forall
). Например, простой
(set-logic HORN)
(declare-fun f (Int Int) Bool)
(declare-fun fail() Bool)
(assert (forall ((n Int))
(=> (< n 0) (f n 0))))
(assert (forall ((n Int))
(=> (>= n 0) (f n 1))))
(assert (forall ((n Int) (m Int))
(=> (and (f n m) (= m 0)) fail)))
(assert (not fail))
(check-sat)
unsat
. Неудивительно, что изменение (= m 0)
до (= m 1)
результаты такие же. Мы можем получить sat
только с учетом fail
от (= m 2)
. Проблема в том, что я не понимаю, , как задать решатель в этом формате.
Как я понять его в данный момент, в то время как с помощью forall
-форма мы можем попросить, чтобы найти только ∀-решения, то есть ответ sat
означает, что решатель удалось найти интерпретацию (или инвариантны) satisfiying все утверждения для всех , а unsat
означает, что таких функций нет. Другими словами, он пытается доказать, положив «доказательство» (инвариант) в модель (очевидно, когда sat
).
Напротив, когда query
ИНГ решения в declare-rel
формате решателе ищет решение для некоторых переменных, так же, как ограничения находятся под ∃-квантор. Другими словами, он дает встречный пример . Он может печатать только инвариант в случае unsat
.
У меня есть несколько вопросов:
- Могу ли я понять это правильно? Я чувствую, что мне не хватает некоторых ключевых идей. Например, общее представление о том, как выразить
(query ...)
в терминах(assert (forall ...))
, будет действительно полезно (и ответ на вопрос 2 будет автоматически). - Есть ли способ решить такие ∃-ограничения (вывод
sat
при обнаружении контрпример) с чистым форматом SMT-LIB2? Если да, то как?
Николай, большое спасибо за четкий и полный ответ. – dvvrd