Я пытаюсь решить комбинаторную проблему с помощью SAT Solver.
Это включает в себя следующие шаги:
- Закодируйте проблему как набор логических выражений.
- Переведите сочетание выражений в CNF / DIMACS
(используя собственные инструменты, bc2cnf, bool2cnf или Limboole) - Решите CNF
(используя SAT Solvers, например Cryptominisat, Plingeling, застежка или Z3) - Переведите решение (при условии, что результат «SAT») обратно в проблемную область.
В моем случае это работает для небольших образцов. Но для более сложных задач решателю SAT требуются часы или даже дни, чтобы не прийти к выводу SAT / UNSAT. Я пытаюсь настроить кодировку, чтобы найти решение. Но чем больше усилий я прилагаю к кодированию, тем менее уверен, что моя кодировка действительно правильная (т.е. «эквивалент выполнимости»).
Шаг от логического выражения к CNF довольно запутан, чтобы быть эффективным с точки зрения управляемого количества предложений и переменных. Мучительно долго ждать SAT-решателя и не быть уверенным, что время потрачено на верный путь.
Логическое выражение может быть неправильным. Поэтому я хотел бы подтвердить, что CNF действительно представляет исходную проблему, а не только логическое выражение.
Мой вопрос:
Как я могу убедиться, что данная кодировка является допустимым представлением исходного логического выражения?
Из литературы мне известны решения некоторых проблем, которые я мог бы преобразовать в присвоения переменных, чтобы получить доверие к моему процессу кодирования. Но из-за кодировки Цейтина большинство переменных в моем CNF являются вспомогательными (переключение) переменные. Без кодирования Цейтина моя CNF была бы слишком большой, чтобы ее можно было решить. Поэтому я не могу просто проверить, выполняется ли каждое предложение CNF известным решением.
Я попытался преобразовать CNF обратно в логические выражения, используя cnf2aig, но инструмент все еще в своем младенчество. Без переключения переменных легко проверить соответствие логическим выражениям основных проблемных переменных.
Есть несколько публикаций о подходах "CNF-to-circuit", но ни одна из них не дает полезного инструмента.
Есть ли какая-нибудь передовая практика для выполнения такой проверки?