Temporarily remove satisfied clauses from watchlists
jix opened this issue · comments
This is an idea I have for optimizing unit propagation. It tries to avoid work in the following scenario:
- A clause
C = x, y1, ..., yn
is satisfied by a single literalx
which was assigned on a fairly low decision level - It's other literals
y1, ..., yn
get repeatedly assigned false and unassigned again on deeper decision levels
I need to benchmark how often this happens, but I figure it should be common.
The standard algorithm would repeatedly encounter the clause C
while scanning the watchlists for y1, ..., yn
. Blocking literals (already implemented) make sure that the second time this happens, we don't have to access the clause itself, as the watch will contain x
, which is true, as blocking literal.
I think it's possible to further improve this by temporarily moving the watch to a inactive-watches list associated with x
. During backtracking when x
is unassigned the inactive-watches list is then emptied and the watches are moved back.
I can also imagine this to be especially useful for solving with assumptions, where we essentially never unassign some literals.
This might have synergies with #20.
While this does happen frequently (seems to be 10% to 50% of watches which have a true blocking literal for the instances I looked at) it doesn't happen often enough in a row to outweigh the overhead of moving the watch somewhere else before moving it back.