GRATgen

Concurrent core-first unit propagation

Concurrent Core-First Unit Propagation

The goal of core-first unit propagation is to keep the number of newly marked clauses small, by preferring already marked clauses when searching for a conflict.

Unit propagation is implemented by a two-watched literals scheme, that is, when processing a literal only the clauses that watch this literal have to be considered.

Standard unit propagation iterates over the unprocessed literals on the trail. For each literal, it iterates over the clauses on the literal's watchlist, tries to acquire a new watched literal, and sets encountered unit-literals or detects a conflict.

For core-first unit propagation, two positions in this iteration (over trail, over watchlist) are maintained. The first position indicates how far unit propagation has proceeded when ignoring unmarked clauses in the watchlists, and the second position indicates how far unit propagation considering all clauses has proceeded.

Initially, unit propagation is done in cf-mode, considering only marked clauses. If this does not yield a conflict, one switches to normal-mode, considering all clauses. If, in normal mode, a new unit clause is found, one immediately switches back to cf-mode: Thus, the new literal is processed preferring marked clauses again.

In DRAT-trim, normal mode only considers unmarked clauses, as the marked clauses have already been processed in cf-mode. In our setting, however, new clauses may be marked concurrently: When processing in normal mode, there may be marked clauses that have been marked after the cf-mode iteration visited this position, and thus have not yet been processed. Currently, we consider all clauses in normal mode. However, a clause that remains in the watchlist after being processed in cf-mode has one of its watched literals set to true (either it was already true, or unit-propagation set it to true). Thus, not much work is spent on those additional clauses.