我正在尝试使用SAT Solver来解决组合问题。
这涉及以下步骤:
- 将问题编码为一组布尔表达式。
- 将表达式的连词翻译成CNF/DIMACS
(使用自制工具bc2cnf、bool2cnf或Limboole) - 求解CNF
(使用 SAT 求解器,如Cryptominisat、Plingeling、Clasp或Z3) - 将解决方案(假设为“SAT”结果)转换回问题域
这适用于我的小样本。但对于更具挑战性的问题,SAT 求解器需要数小时甚至数天才能得出 SAT/UNSAT 结论。我尝试调整我的编码以获得解决方案。但是我在编码上投入的精力越多,我就越不能确定我的编码实际上是正确的(即“可满足性等效”)。
从布尔表达式到 CNF 的步骤相当复杂,在可管理数量的子句和变量方面是有效的。等待 SAT 求解器的时间很长并且不确定时间是否花在正确的轨道上是很痛苦的。
布尔表达式可能是错误的。因此,我想验证 CNF 实际上代表了原始问题,而不仅仅是布尔表达式。
我的问题:
我如何验证给定的编码是原始布尔表达式的有效表示?
从文献中,我知道了一些问题的解决方案,我可以将其转化为变量分配,以获得对我的编码过程的信任。但是由于Tseitin encoding,我的 CNF 中的大多数变量都是辅助(切换)变量。如果没有Tseitin encoding,我的 CNF 将太大而无法解决。因此,我不能简单地检查已知解决方案是否满足每个 CNF 子句。
我曾尝试使用cnf2aig将 CNF 转换回布尔表达式,但该工具仍处于起步阶段。在不切换变量的情况下,可以直接根据主要问题变量的布尔表达式检查分配。
有一些关于“CNF 到电路”方法的出版物,但没有一个提供可用的工具。
是否有任何最佳实践来完成这样的检查?