Algorithm 1 (Brute force SAT solver). Given a partial truth assignment J, determine whether we can expand it into a total one which satisfies ϕ.
BF(J):
- if J is a total assignment and [[ϕ]]J=T, return SAT
- if J is a total assignment and [[ϕ]]J=F, return UNSAT
- if J is not a total assignment
- pick a propositional variable p which is not assigned a value by J
- execute BF(J∪[p↦T]) and BF(J∪[p↦F])
- return SAT if one of the above answers SAT, return UNSAT otherwise
Optimization: A conflict may be detected on a partial assignment!
这种方法就相当于用递归的方式遍历所有可能的 J。
Example:
(p1∨¬p4)∧(¬p2∨p3)∧(p2∨p4)∧(¬p2∨¬p3∨p4)∧(¬p1∨¬p4)
J=[p1↦T,p4↦T]
Algorithm 2. BF+(J):
- if J causes a conflict on ϕ, return UNSAT
- otherwise, if J is a total assignment, return SAT
- otherwise,
- pick a propositional variable p which is not assigned a value by J
- execute BF+(J∪[p↦T]) and BF+(J∪[p↦F])
- return SAT if one of the above answers SAT, return UNSAT otherwise
和上一种方法相比,这种方法能够在 partial truth assignment J UNSAT 的时候退出,减少了枚举数量。
Unit Propagation (赋值推导): In one clause, if all literals except one are false, the last one must be true.
Example:
⇒⇒⇒(p1∨¬p4)∧(¬p2∨p3)∧(p2∨p4)∧(¬p2∨¬p3∨p4)∧(¬p1∨¬p4)J=[p2↦T]J(p3) should be T(p1∨¬p4)∧(¬p2∨p3)∧(p2∨p4)∧(¬p2∨¬p3∨p4)∧(¬p1∨¬p4)J=[p2↦T,p3↦T]J(p4) should be T
Algorithm 3 (DPLL(J)).
- let J′ be UnitPro(J)
- if J′ causes a conflict on ϕ, return UNSAT
- otherwise, if J′ is a total assignment, return SAT
- otherwise,
- pick a propositional variable p which is not assigned a value by J′
- execute DPLL(J′∪[p↦T]) and DPLL(J′∪[p↦F])
- return SAT if one of the above answers SAT, return UNSAT otherwise
利用了赋值推导的算法,进一步减少了需要枚举的情况。
Algorithm 4 (CDCL, Conflict Driven Clause Learning).
矛盾驱动的子句学习方法。
- let J be the empty assignment at the beginning
- set J to UnitPro(J)
- if J causes a conflict on ϕ
- let D be the result of ConflictClauseGen()
- if D is an empty clause, return UNSAT
- add D to the CNF
- remove assignments after the second last “Pick” in D from J
- go back to step 2 (the unit propagation step)
- otherwise, if J is a total assignment, return SAT
- otherwise,
- pick a propositional variable p which is not assigned a value by J
- pick a truth value t∈{T,F}
- set J to (J∪[p↦t])
- go back to step 2 (the unit propagation step)
这种方法会不断增加子句的数量。例如:
p1∨p5¬p1∨p7p2∨p4∨¬p9¬p2∨p9∨¬p10¬p3∨¬p8p4∨¬p5∨¬p7¬p6∨p9p6∨p10¬p7∨p8∨¬p9∨p10¬p9∨¬p10
可以发现 J(p1) 决定 J(p7);J(p3) 决定 J(p8);J(p6) 决定 J(p9) 决定 J(p10)。当 J(p1)=J(p3)=J(p6)=T,会导致 [[¬p7∨p8∨¬p9∨p10]]J=F,矛盾。因此引入了子句 ¬p1∨¬p3∨¬p6。