I have just realised that CryptoMiniSat, having won a number of medals, does one of the most basic things, failed literal probing, all wrong. Let me tell you why it’s all wrong. In essence, failed literal probing is trivial. We enqueue a fact, such as
a, and then propagate it. If this fails, i.e. if two opposing facts such as
-g are derived, we know that
a cannot be true, so we set
-a. Easy. Or maybe not so easy.
The devil is in the details, so let’s see how we derived both
a. Let’s assume that we have the following set of binary clauses:
-a V b
-b V c
-b V d
-d V e
-d V f
-e V g
-f V -g
which, from the point of view of
a is best described as the graph:
Propagating "a", deriving both "g" and "-g"
The problem is, that if we only derive
-a from this graph, we end up with only that one literal set, because
-a doesn’t propagate anything on the clauses. This is quite sad, because, in fact, we could derive something stronger. From the graph it is evident that setting
d would have failed: the graph would simply have its upper part cut away completely, but the lower part, including the derivation of both
-g would still stand:
Deriving both "g" and "-g" from "d"
What is special about node
d? Well, it’s where the 1st UIP, the first unique implication point, lies. And it is quite simple to see that
-d is in fact the strongest thing we can derive from this graph. It’s much stronger than simply
-a, because setting
-d propagates on the clauses, giving
-b,-a, setting three variables instead of one, including
-a. An interesting observation is the following: deriving
-b is the 2nd UIP, and deriving
-a is the last UIP. In other words, at least in this most simple case, 1st UIP is in fact the strongest, and 2nd, 3rd.. last UIP are less strong in strict order.
Let me remark on one more thing about failed literal probing. Once failed literal probing has been done on literal
x and it visited the node set
N, there is no need to try to do failed literal probing on any nodes in
N, since they cannot possibly fail. Although the failing of a literal can have consequences on the failing of other literals, if we ignore this side-effect, we could speed up failed literal probing by marking literals already visited, and only carrying out failed literal probing on ones that haven’t been marked. This is really trivial, but I haven’t been using it :S
I am quite sure that some advanced SAT solvers (such as lingeling) do all of the above things right. It’s probably only CryptoMiniSat that fails miserably :)
Note: there is a subtle bug with marking literals visited as “OK”. If two different subgraphs could fail, but we abort on the first one, then we might mark a literal OK when in fact it isn’t. It is therefore easiest not to mark any literals if the probe failed (which is very rare).