18 size_t max_occurrence = 0;
23 const unsigned other_idx =
IDX (other);
26 watches *other_watches = all_watches + other;
28 if (other_occurrence <= max_occurrence)
30 max_occurrence = other_occurrence;
31 max_occurring = other;
34 bool subsumed =
false;
35 const size_t fasteloccs =
GET_OPTION (fasteloccs);
37 if (other == max_occurring)
39 const unsigned other_idx =
IDX (other);
42 watches *other_watches = all_watches + other;
43 const size_t size_other_watches =
SIZE_WATCHES (*other_watches);
44 if (size_other_watches > fasteloccs)
66 if (values[other2] < 0)
92 const size_t fasteloccs =
GET_OPTION (fasteloccs);
93 const size_t fastelclslim =
GET_OPTION (fastelclslim);
94 const size_t fastelsub =
GET_OPTION (fastelsub);
106 if (values[other] > 0)
108 const unsigned other_idx =
IDX (other);
109 const flags *other_flags = all_flags + other_idx;
121 if (c->
size > fastelclslim) {
122 res = fasteloccs + 1;
126 value other_value = values[other];
127 if (other_value > 0) {
134 if (fastelsub && fast_forward_subsumed (
solver, c)) {
139 if (++res > fasteloccs)
150static void do_fast_resolve_binary_binary (
kissat *
solver,
unsigned pivot,
151 unsigned clit,
unsigned dlit) {
154 if (clit ==
NOT (dlit)) {
155 LOG (
"resolvent tautological");
159 value cval = values[clit];
161 LOG (
"1st antecedent satisfied");
164 value dval = values[dlit];
166 LOG (
"2nd antecedent satisfied");
169 if (cval < 0 && dval < 0) {
171 solver->inconsistent =
true;
172 LOG (
"resolved empty clause");
178 LOG (
"resolved unit clause %s",
LOGLIT (dlit));
179 INC (eliminate_units);
184 LOG (
"resolved unit clause %s",
LOGLIT (clit));
185 INC (eliminate_units);
190 LOG (
"resolved unit clause %s",
LOGLIT (clit));
191 INC (eliminate_units);
201 LOGTMP (
"%s resolvent", LOGVAR (pivot));
209static void do_fast_resolve_binary_large (
kissat *
solver,
unsigned pivot,
218 LOG (
"binary clause antecedent satisfied");
225 bool satisfied =
false, tautological =
false;
226 const unsigned not_lit =
NOT (
lit);
228 const unsigned idx_other =
IDX (other);
229 if (idx_other == pivot)
233 if (other == not_lit) {
234 LOG (
"resolvent tautological");
238 value other_val = values[other];
242 LOG (
"large clause antecedent satisfied");
249 if (satisfied || tautological) {
256 solver->inconsistent =
true;
257 LOG (
"resolved empty clause");
265 LOG (
"resolved unit clause %s",
LOGLIT (unit));
266 INC (eliminate_units);
270 LOGTMP (
"%s resolvent", LOGVAR (pivot));
275static void do_fast_resolve_large_large (
kissat *
solver,
unsigned pivot,
287 bool satisfied =
false, tautological =
false;
289 const unsigned idx_other =
IDX (other);
290 if (idx_other == pivot)
292 value other_val = values[other];
296 LOG (
"1st antecedent satisfied");
303 if (satisfied || tautological) {
311 const unsigned idx_other =
IDX (other);
312 if (idx_other == pivot)
314 value other_val = values[other];
318 LOG (
"2nd antecedent satisfied");
322 mark mark_other = marks[other];
325 const unsigned not_other =
NOT (other);
326 mark mark_not_other = marks[not_other];
327 if (mark_not_other) {
328 LOG (
"tautological resolvent");
334 if (satisfied || tautological) {
343 solver->inconsistent =
true;
344 LOG (
"resolved empty clause");
353 LOG (
"resolved unit clause %s",
LOGLIT (unit));
354 INC (eliminate_units);
358 LOGTMP (
"%s resolvent", LOGVAR (pivot));
369 LOGWATCH (
LIT (pivot), cwatch,
"1st fast %s elimination antecedent",
371 LOGWATCH (
NOT (
LIT (pivot)), dwatch,
"1st fast %s elimination antecedent",
379 clause *c = cbin ? 0 : kissat_dereference_clause (
solver, cref);
380 clause *d = dbin ? 0 : kissat_dereference_clause (
solver, dref);
382 do_fast_resolve_binary_binary (
solver, pivot, clit, dlit);
383 else if (cbin && !dbin)
384 do_fast_resolve_binary_large (
solver, pivot, clit, d);
385 else if (!cbin && dbin)
386 do_fast_resolve_binary_large (
solver, pivot, dlit, c);
389 do_fast_resolve_large_large (
solver, pivot, c, d);
393static void fast_delete_and_weaken_clauses (
kissat *
solver,
unsigned lit) {
408 bool satisfied =
false;
410 if (values[other] > 0) {
423static void do_fast_eliminate (
kissat *
solver,
unsigned pivot) {
424 LOG (
"fast variable elimination of %s", LOGVAR (pivot));
425 const unsigned lit =
LIT (pivot);
426 const unsigned not_lit =
NOT (
lit);
429 watches *not_lit_watches = all_watches + not_lit;
436 for (
watch *
p = begin_lit_watches;
p < end_lit_watches;
p++)
437 for (
watch *q = begin_not_lit_watches; q < end_not_lit_watches; q++) {
438 do_fast_resolve (
solver, pivot, *
p, *q);
442 const size_t i =
p - begin_lit_watches;
443 const size_t j = q - begin_not_lit_watches;
444 all_watches = new_all_watches;
445 lit_watches = all_watches +
lit;
446 not_lit_watches = all_watches + not_lit;
450 end_not_lit_watches =
END_WATCHES (*not_lit_watches);
451 p = begin_lit_watches + i;
452 q = begin_not_lit_watches + j;
456 INC (fast_eliminated);
458 fast_delete_and_weaken_clauses (
solver,
lit);
459 fast_delete_and_weaken_clauses (
solver, not_lit);
462static bool can_fast_resolve_binary_binary (
kissat *
solver,
unsigned clit,
466 if (clit ==
NOT (dlit))
469 value cval = values[clit];
472 value dval = values[dlit];
475 if (cval < 0 && dval < 0) {
477 solver->inconsistent =
true;
478 LOG (
"resolved empty clause");
484 LOG (
"resolved unit clause %s",
LOGLIT (dlit));
485 INC (eliminate_units);
490 LOG (
"resolved unit clause %s",
LOGLIT (clit));
491 INC (eliminate_units);
496 LOG (
"resolved unit clause %s",
LOGLIT (clit));
497 INC (eliminate_units);
506static bool can_fast_resolve_binary_large (
kissat *
solver,
unsigned pivot,
516 const unsigned not_lit =
NOT (
lit);
517 bool found_lit =
false;
521 if (other == not_lit)
523 value other_val = values[other];
525 LOG (
"large clause antecedent satisfied");
534 const unsigned idx =
IDX (other);
543 LOGTMP (
"self-subsuming resolvent");
545 INC (fast_strengthened);
550 solver->inconsistent =
true;
551 LOG (
"resolved empty clause");
554 }
else if (size == 1) {
556 LOG (
"resolved %s unit clause",
LOGLIT (unit));
557 INC (eliminate_units);
562 c = kissat_dereference_clause (
solver, ref);
563 LOGCLS (c,
"self-subsuming antecedent");
570static bool can_fast_resolve_large_large (
kissat *
solver,
unsigned pivot,
580 bool satisfied =
false;
584 const unsigned idx_other =
IDX (other);
585 if (idx_other == pivot)
587 value other_val = values[other];
600 bool tautological =
false;
603 const unsigned idx_other =
IDX (other);
604 if (idx_other == pivot)
606 value other_val = values[other];
615 const unsigned not_other =
NOT (other);
616 const mark mark_not_other = marks[not_other];
617 if (mark_not_other) {
621 const mark other_mark = marks[other];
629 bool strengthened =
false;
630 if (!satisfied && !tautological) {
634 solver->inconsistent =
true;
635 LOG (
"resolved empty clause");
639 }
else if (size == 1) {
641 LOG (
"resolved %s unit clause",
LOGLIT (unit));
642 INC (eliminate_units);
646 bool c_subsumed =
false, d_subsumed =
false;
648 if (size < c->size) {
656 c_subsumed = (count >=
size);
658 if (size < d->size) {
668 d_subsumed = (count >=
size);
674 if (c_subsumed || d_subsumed) {
675 LOGTMP (
"self-subsuming resolvent");
677 INC (fast_strengthened);
683 c = kissat_dereference_clause (
solver, c_ref);
684 LOGCLS (c,
"self-subsuming antecedent");
688 d = kissat_dereference_clause (
solver, d_ref);
689 LOGCLS (d,
"self-subsuming antecedent");
692 if (c_subsumed && d_subsumed)
698 return !satisfied && !tautological && !strengthened;
710 clause *c = cbin ? 0 : kissat_dereference_clause (
solver, cref);
711 clause *d = dbin ? 0 : kissat_dereference_clause (
solver, dref);
713 return can_fast_resolve_binary_binary (
solver, clit, dlit);
715 return can_fast_resolve_binary_large (
solver, pivot, clit, d);
717 return can_fast_resolve_binary_large (
solver, pivot, dlit, c);
719 return can_fast_resolve_large_large (
solver, pivot, c, d);
722static bool resolvents_limited (
kissat *
solver,
unsigned pivot,
724 const unsigned lit =
LIT (pivot);
725 const unsigned not_lit =
NOT (
lit);
728 watches *not_lit_watches = all_watches + not_lit;
734 for (
watch *
p = begin_lit_watches;
p < end_lit_watches;
p++)
735 for (
watch *q = begin_not_lit_watches; q < end_not_lit_watches; q++) {
736 if (can_fast_resolve (
solver, pivot, *
p, *q) && ++resolved > limit)
741 const size_t i =
p - begin_lit_watches;
742 const size_t j = q - begin_not_lit_watches;
743 all_watches = new_all_watches;
744 lit_watches = all_watches +
lit;
745 not_lit_watches = all_watches + not_lit;
749 end_not_lit_watches =
END_WATCHES (*not_lit_watches);
750 p = begin_lit_watches + i;
751 q = begin_not_lit_watches + j;
756static bool try_to_fast_eliminate (
kissat *
solver,
unsigned pivot) {
760 const unsigned lit =
LIT (pivot);
761 const unsigned not_lit =
NOT (
lit);
762 const size_t fasteloccs =
GET_OPTION (fasteloccs);
764 if (
pos > fasteloccs)
766 const size_t neg = flush_occurrences (
solver, not_lit);
767 if (neg > fasteloccs)
769 const size_t sum =
pos + neg;
770 const size_t product =
pos * neg;
771 if (sum > fasteloccs)
773 const size_t fastelim =
GET_OPTION (fastelim);
774 if (product <= fastelim) {
775 do_fast_eliminate (
solver, pivot);
778 if (resolvents_limited (
solver, pivot, fastelim)) {
779 do_fast_eliminate (
solver, pivot);
785static void flush_eliminated_binary_clauses_of_literal (
kissat *
solver,
797 const unsigned other_idx =
IDX (other);
798 flags *other_flags = all_flags + other_idx;
805static void flush_eliminated_binary_clauses (
kissat *
solver) {
807 const unsigned lit =
LIT (idx);
808 const unsigned not_lit =
NOT (
lit);
809 flush_eliminated_binary_clauses_of_literal (
solver,
lit);
810 flush_eliminated_binary_clauses_of_literal (
solver, not_lit);
822#define RANK_CANDIDATE(CANDIDATE) ((CANDIDATE).score)
830 const unsigned variables_before =
solver->active;
836 const unsigned fastelrounds =
GET_OPTION (fastelrounds);
837 const size_t fasteloccs =
GET_OPTION (fasteloccs);
839 unsigned eliminated = 0;
842 candidates candidates;
846 if (round++ >= fastelrounds)
849 solver,
"gathering candidates for fast elimination round %u",
861 if (
pos > fasteloccs)
863 const unsigned not_lit =
LIT (
pivot);
864 const size_t neg = flush_occurrences (
solver, not_lit);
865 if (neg > fasteloccs)
868 if (
score > fasteloccs)
874 const size_t size_candidates =
SIZE_STACK (candidates);
875 const size_t active_variables =
solver->active;
877 solver,
"gathered %zu candidates %.0f%% in elimination round %u",
878 size_candidates, kissat_percent (size_candidates, active_variables),
882 unsigned eliminated_this_round = 0;
895 eliminated_this_round++;
896 if (
solver->inconsistent) {
902 if (
solver->inconsistent) {
909 eliminated += eliminated_this_round;
911 solver,
"fast eliminated %u of %zu candidates %.0f%% in round %u",
912 eliminated_this_round, size_candidates,
913 kissat_percent (eliminated_this_round, size_candidates), round);
915 if (!eliminated_this_round)
920 FLAGS (idx)->eliminate =
true;
921 flush_eliminated_binary_clauses (
solver);
924 const unsigned original_variables =
solver->statistics.variables_original;
925 const unsigned variables_after =
solver->active;
929 "fast elimination of %u variables %.0f%% (%u remain %.0f%%)",
930 eliminated, kissat_percent (eliminated, variables_before),
932 kissat_percent (variables_after, original_variables));
935 REPORT (!eliminated,
'e');
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void kissat_learned_unit(kissat *solver, unsigned lit)
#define RESIZE_STACK(S, NEW_SIZE)
#define all_stack(T, E, S)
ABC_NAMESPACE_IMPL_START typedef signed char value
#define CHECK_AND_ADD_EMPTY(...)
reference kissat_new_irredundant_clause(kissat *solver)
void kissat_mark_clause_as_garbage(kissat *solver, clause *c)
void kissat_delete_binary(kissat *solver, unsigned a, unsigned b)
void kissat_enter_dense_mode(kissat *solver, litpairs *irredundant)
void kissat_resume_sparse_mode(kissat *solver, bool flush_eliminated, litpairs *irredundant)
void kissat_flush_units_while_connected(kissat *solver)
#define RANK_CANDIDATE(CANDIDATE)
void kissat_fast_variable_elimination(struct kissat *)
void kissat_mark_eliminated_variable(kissat *solver, unsigned idx)
#define all_variables(IDX)
#define all_literals_in_clause(LIT, C)
#define KISSAT_assert(ignore)
#define kissat_verbose(...)
#define kissat_extremely_verbose(...)
#define kissat_very_verbose(...)
#define ADD_EMPTY_TO_PROOF(...)
#define RADIX_STACK(VTYPE, RTYPE, S, RANK)
ABC_NAMESPACE_HEADER_START typedef unsigned reference
#define fastel_terminated_1
void kissat_connect_irredundant_large_clauses(kissat *solver)
#define BEGIN_WATCHES(WS)
#define RELEASE_WATCHES(WS)
#define SET_END_OF_WATCHES(WS, P)
#define all_binary_large_watches(WATCH, WATCHES)
void kissat_weaken_binary(kissat *solver, unsigned lit, unsigned other)
void kissat_weaken_clause(kissat *solver, unsigned lit, clause *c)