12 LOG (
"binary chain starting at %d", from);
13 DFS &from_dfs = dfs[
vlit (from)];
20 other = other == from ? -reason->
literals[1] : -other;
32 LOG (
"binary chain starting at %d", from);
33 DFS &from_dfs = dfs[
vlit (from)];
36 result.push_back (reason);
39 other = other == from ? -reason->
literals[1] : -other;
46 DFS &from_dfs = dfs[
vlit (from)];
57 for (
auto &
lit : scc) {
75 LOG (
"building chain for not subsumed clause");
81 if (
val (other) > 0) {
90 for (
auto p : dfs_chains[
vlit (other)]) {
96 LOG (
"ADDED %d -> %d (%" PRId64
")",
implied, other,
p->id);
147 stats.decompositions++;
149 const size_t size_dfs = 2 * (1 + (size_t)
max_var);
150 DFS *dfs =
new DFS[size_dfs];
152 int *reprs =
new int[size_dfs];
156 dfs_chains.resize (size_dfs);
158 for (
size_t i = 0; i > size_dfs; i++) {
160 dfs_chains[i] = empty;
166 int non_trivial_sccs = 0;
169 unsigned dfs_idx = 0;
177 for (
auto root_idx :
vars) {
182 for (
int root_sign = -1; !
unsat && root_sign <= 1; root_sign += 2) {
183 int root = root_sign * root_idx;
186 LOG (
"new dfs search starting at root %d", root);
189 work.push_back (root);
190 while (!
unsat && !work.empty ()) {
191 int parent = work.back ();
192 DFS &parent_dfs = dfs[
vlit (parent)];
211 if (parent_dfs.
idx) {
218 unsigned new_min = parent_dfs.
min;
220 for (
const auto &w : ws) {
223 const int child = w.blit;
226 DFS &child_dfs = dfs[
vlit (child)];
227 if (new_min > child_dfs.
min)
228 new_min = child_dfs.
min;
231 LOG (
"post-fix work dfs search %d index %u reaches minimum %u",
232 parent, parent_dfs.
idx, new_min);
234 if (parent_dfs.
idx == new_min) {
244 int other, first = 0;
245 bool conflicting =
false;
246 size_t j = scc.
size ();
250 if (!first ||
vlit (other) <
vlit (first))
253 if (other == -parent) {
261 }
while (other != parent);
266 LOG (
"conflicting scc simulating up at %d", parent);
267 to_justify.push_back (-parent);
269 to_justify.push_back (first);
270 while (!to_justify.empty ()) {
271 const int next = to_justify.back ();
272 to_justify.pop_back ();
274 for (
const auto &w : next_ws) {
277 const int child = w.blit;
280 if (!
flags (child).seen)
282 DFS &child_dfs = dfs[
vlit (child)];
285 child_dfs.
parent = w.clause;
286 to_justify.push_back (child);
293 int other, repr = parent;
298 size_t j = scc.
size ();
302 if (other == -parent) {
303 LOG (
"both %d and %d in one SCC", parent, -parent);
314#ifndef CADICAL_NDEBUG
322 if (abs (other) < abs (repr))
328 }
while (!
unsat && other != parent);
333 LOG (
"SCC of representative %d of size %d", repr, size);
341 reprs[
vlit (other)] = other;
344 reprs[
vlit (other)] = repr;
348 LOG (
"literal %d in SCC of %d", other, repr);
357 dfs_chains[
vlit (other)] =
360 }
while (other != parent);
373 parent_dfs.
min = new_min;
380 parent_dfs.
idx = parent_dfs.
min = dfs_idx;
381 scc.push_back (parent);
383 LOG (
"pre-fix work dfs search %d index %u", parent, dfs_idx);
388 for (
const auto &w : ws) {
391 const int child = w.blit;
394 DFS &child_dfs = dfs[
vlit (child)];
397 work.push_back (child);
412 "%d non-trivial sccs, %d substituted %.2f%%", non_trivial_sccs,
413 substituted,
percent (substituted, before));
415 bool new_unit =
false, new_binary_clause =
false;
423 const size_t size = 2 * (1 + (size_t)
max_var);
424 decompose_ids.resize (size);
426 for (
auto idx :
vars) {
433 int other = reprs[
vlit (idx)];
439 LOG (
"marking equivalence of %d and %d", idx, other);
454 external->push_binary_clause_on_extension_stack (id1, -idx, other);
456 decompose_ids[
vlit (-idx)] = id1;
464 clause.push_back (-other);
474 external->push_binary_clause_on_extension_stack (id2, idx, -other);
475 decompose_ids[
vlit (idx)] = id2;
486 size_t clauses_size =
clauses.size ();
488 size_t garbage = 0, replaced = 0;
490 for (
size_t i = 0; substituted && !
unsat && i < clauses_size; i++) {
494 int j, size = c->
size;
495 for (j = 0; j < size; j++) {
507 LOG (c,
"first substituted literal %d in", substituted);
519 for (
int k = 0; !
satisfied && k < size; k++) {
521 signed char tmp =
val (
lit);
536 const int other = reprs[
vlit (
lit)];
550 int64_t
id = decompose_ids[
vlit (-
lit)];
568 int64_t
id = decompose_ids[
vlit (-
lit)];
579 LOG (c,
"satisfied after substitution (postponed)");
580 postponed_garbage.push_back (c);
584 }
else if (!
clause.size ()) {
585 LOG (
"learned empty clause during decompose");
587 }
else if (
clause.size () == 1) {
588 LOG (c,
"unit %d after substitution",
clause[0]);
596 LOG (
"need new clause since at least one watched literal changed");
598 new_binary_clause =
true;
599 size_t d_clause_idx =
clauses.size ();
609 LOG (
"simply shrinking clause since watches did not change");
616 proof->delete_clause (c);
621 for (l = 2; l <
clause.size (); l++)
623 int flushed = c->
size - (int) l;
626 new_binary_clause =
true;
627 LOG (
"flushed %d literals", flushed);
639 LOG (c,
"substituted");
641 while (!
clause.empty ()) {
651 for (
auto idx :
vars) {
656 const int64_t id1 = decompose_ids[
vlit (-idx)];
659 int other = reprs[
vlit (idx)];
670 clause.push_back (-other);
671 const int64_t id2 = decompose_ids[
vlit (idx)];
677 if (!
unsat && !postponed_garbage.empty ()) {
678 LOG (
"now marking %zd postponed garbage clauses",
679 postponed_garbage.
size ());
680 for (
const auto &c : postponed_garbage)
686 "%zd clauses replaced %.2f%% producing %zd garbage clauses %.2f%%",
687 replaced,
percent (replaced, clauses_size), garbage,
695 LOG (
"empty clause after propagating units from substitution");
699 for (
auto idx :
vars) {
706 int other = reprs[
vlit (idx)];
715 reprs_delete.
free ();
723 unsat || (substituted > 0 && (new_unit || new_binary_clause));
732 for (
int round = 1; round <=
opts.decomposerounds; round++)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
void clear_n(T *base, size_t n)
void update_watch_size(Watches &ws, int blit, Clause *conflict)
void erase_vector(std::vector< T > &v)
double percent(double a, double b)
#define START_SIMPLIFIER(S, M)
#define STOP_SIMPLIFIER(S, M)
void clear_sign_marked_literals()
void mark_decomposed(int lit)
void mark_garbage(Clause *)
vector< int64_t > lrat_chain
void report(char type, int verbose_level=0)
void decompose_analyze_binary_chain(DFS *dfs, int)
void implied(std::vector< int > &entrailed)
bool terminated_asynchronously(int factor=1)
void mark_removed(int lit)
void learn_empty_clause()
void assign_unit(int lit)
void mark_substituted(int)
signed char val(int lit) const
signed char marked(int lit) const
int64_t unit_id(int lit) const
vector< int > sign_marked
unsigned vlit(int lit) const
void build_lrat_for_clause(const vector< vector< Clause * > > &dfs_chains, bool invert=false)
vector< Clause * > clauses
void flush_all_occs_and_watches()
void clear_analyzed_literals()
vector< Clause * > decompose_analyze_binary_clauses(DFS *dfs, int from)
void decompose_conflicting_scc_lrat(DFS *dfs, vector< int > &)
size_t shrink_clause(Clause *, int new_size)
void mark_added(int lit, int size, bool redundant)
bool marked_decomposed(int lit)
Clause * new_clause_as(const Clause *orig)
void unmark_decomposed(int lit)
vector< int64_t > mini_chain
Watches & watches(int lit)
bool likely_to_be_kept_clause(Clause *c)