79 for (
unsigned i = 0; i !=
hops; i++) {
99 unsigned factor = q->factor;
108 for (
unsigned i = 0; i !=
hops; i++) {
138 for (
unsigned i = 0; i !=
hops; i++) {
141 DEALLOC (score, allocated_score);
159 if (!kissat_heap_contains (cands,
lit))
161 }
else if (kissat_heap_contains (cands,
lit))
171 const unsigned lit =
LIT (idx);
172 const unsigned not_lit =
NOT (
lit);
181 size_t size_cands = kissat_size_heap (cands);
183 solver,
"scheduled %zu factorization candidate literals %.0f %%",
184 size_cands, kissat_percent (size_cands,
LITS));
194 memset (res, 0,
sizeof *res);
201 res->
id = last->
id + 1;
226 clause *
const c = kissat_dereference_clause (
solver, ref);
234 ADD (factor_ticks, ticks);
238static void clear_nounted (
kissat *
solver, unsigneds *nounted) {
247static void clear_qlauses (
kissat *
solver, references *qlauses) {
258 unsigned dst_idx,
unsigned hops) {
260 const unsigned src_idx =
IDX (src_lit);
261 bool matched = (src_idx == dst_idx);
264 const unsigned next_hops = hops - 1;
267 double res = score[src_idx];
271 for (
unsigned sign = 0;
sign != 2;
sign++) {
272 const unsigned signed_src_lit = src_lit ^
sign;
279 res += distinct_paths (
factoring, other, dst_idx, next_hops);
285 if (other != signed_src_lit)
286 res += distinct_paths (
factoring, other, dst_idx, next_hops);
289 ADD (factor_ticks, ticks);
292 score[src_idx] = res;
295 LOG (
"caching %g distinct paths from %s to %s in %u hops", res,
296 LOGVAR (src_idx), LOGVAR (dst_idx), hops);
303 const unsigned first_factor = first_quotient->
factor;
307 const unsigned first_factor_idx =
IDX (first_factor);
327 unsigned *next_count_ptr) {
330 statches *last_clauses = &last_quotient->
clauses;
344 if (quotient_watch.type.binary) {
345 const unsigned q = quotient_watch.binary.lit;
346 watches *q_watches = all_watches + q;
347 ticks += 1 + kissat_cache_lines (
SIZE_WATCHES (*q_watches),
350 if (!next_watch.type.binary)
352 const unsigned next = next_watch.binary.lit;
357 const unsigned next_idx =
IDX (next);
365 const reference c_ref = quotient_watch.large.ref;
372 if (marks[other] &
FACTOR) {
378 watches *other_watches = all_watches + other;
379 const size_t other_size =
SIZE_WATCHES (*other_watches);
380 if (min_lit !=
INVALID_LIT && min_size <= other_size)
383 min_size = other_size;
389 watches *min_watches = all_watches + min_lit;
390 unsigned c_size = c->
size;
393 ticks += 1 + kissat_cache_lines (
SIZE_WATCHES (*min_watches),
396 if (min_watch.type.binary)
398 const reference d_ref = min_watch.large.ref;
405 if (d->
size != c_size)
408 int continue_with_next_min_watch = 0;
414 continue_with_next_min_watch = 1;
418 continue_with_next_min_watch = 1;
422 continue_with_next_min_watch = 1;
427 if(continue_with_next_min_watch) {
433 const unsigned next_idx =
IDX (next);
445 clear_nounted (
solver, nounted);
450 ADD (factor_ticks, ticks);
455 clear_qlauses (
solver, qlauses);
460 const unsigned lit_count = count[
lit];
461 if (lit_count < next_count)
463 if (lit_count == next_count) {
468 next_count = lit_count;
473 if (next_count < 2) {
474 LOG (
"next factor count %u smaller than 2", next_count);
476 }
else if (ties > 1) {
477 LOG (
"found %u tied next factor candidate literals with count %u",
479 double next_score = -1;
481 const unsigned lit_count = count[
lit];
482 if (lit_count != next_count)
484 double lit_score = tied_next_factor_score (
factoring,
lit);
486 LOG (
"score %g of next factor candidate %s", lit_score,
488 if (lit_score <= next_score)
490 next_score = lit_score;
495 LOG (
"best score %g of next factor %s", next_score,
LOGLIT (next));
498 LOG (
"single next factor %s with count %u",
LOGLIT (next),
506 *next_count_ptr = next_count;
511 unsigned expected_next_count) {
521 statches *last_clauses = &last_quotient->
clauses;
522 statches *next_clauses = &next_quotient->
clauses;
523 sizes *matches = &next_quotient->
matches;
533 if (last_watch.type.binary) {
534 const unsigned q = last_watch.binary.lit;
535 watches *q_watches = all_watches + q;
536 ticks += 1 + kissat_cache_lines (
SIZE_WATCHES (*q_watches),
539 if (q_watch.type.binary && q_watch.binary.lit == next) {
547 const reference c_ref = last_watch.large.ref;
554 if (marks[other] &
FACTOR) {
560 watches *other_watches = all_watches + other;
561 const size_t other_size =
SIZE_WATCHES (*other_watches);
562 if (min_lit !=
INVALID_LIT && min_size <= other_size)
565 min_size = other_size;
571 watches *min_watches = all_watches + min_lit;
572 unsigned c_size = c->
size;
573 ticks += 1 + kissat_cache_lines (
SIZE_WATCHES (*min_watches),
576 if (min_watch.type.binary)
578 const reference d_ref = min_watch.large.ref;
585 if (d->
size != c_size)
592 goto CONTINUE_WITH_NEXT_MIN_WATCH;
601 CONTINUE_WITH_NEXT_MIN_WATCH:;
610 clear_qlauses (
solver, qlauses);
611 ADD (factor_ticks, ticks);
614 (void) expected_next_count;
618 size_t *best_reduction_ptr) {
619 size_t factors = 1, best_reduction = 0;
624 size_t before_factorization = quotients * factors;
625 size_t after_factorization = quotients + factors;
626 if (before_factorization == after_factorization)
627 LOG (
"quotient[%zu] factors %zu clauses into %zu thus no change",
628 factors - 1, before_factorization, after_factorization);
629 else if (before_factorization < after_factorization)
630 LOG (
"quotient[%zu] factors %zu clauses into %zu thus %zu more",
631 factors - 1, before_factorization, after_factorization,
632 after_factorization - before_factorization);
634 size_t delta = before_factorization - after_factorization;
635 LOG (
"quotient[%zu] factors %zu clauses into %zu thus %zu less",
636 factors - 1, before_factorization, after_factorization, delta);
637 if (!best || best_reduction < delta) {
638 best_reduction = delta;
645 LOG (
"no decreasing quotient found");
648 LOG (
"best decreasing quotient[%zu] with reduction %zu", best->
id,
650 *best_reduction_ptr = best_reduction;
661 size_t new_size =
lit + 1;
662 if (new_size > old_allocated) {
663 size_t new_allocated = 2 * old_allocated;
664 while (new_size > new_allocated)
669 const size_t delta_allocated = new_allocated - old_allocated;
670 const size_t delta_bytes = delta_allocated *
sizeof *count;
671 memset (count + old_size, 0, delta_bytes);
675 const size_t old_allocated_score = old_allocated / 2;
676 const size_t new_allocated_score = new_allocated / 2;
681 new_allocated_score,
sizeof *score);
682 for (
size_t i = old_allocated_score; i != new_allocated_score; i++)
694 statches *q_clauses = &q->
clauses, *prev_clauses = &prev->
clauses;
697 bool prev_is_first = !prev->
id;
702 if (!prev_is_first) {
703 size_t matches =
PEEK_STACK (*prev_matches, j);
710 LOG (
"flushing %zu clauses of quotient[%zu]",
724 INC (clauses_factored);
725 ADD (literals_factored, 2);
729 unsigned not_fresh) {
731 LOG (
"adding factored quotient[%zu] clauses", q->
id);
735 LOGBINARY (not_fresh, other,
"factored quotient");
737 ADD (literals_factored, 2);
740 clause *
const c = kissat_dereference_clause (
solver, c_ref);
758 ADD (literals_factored, c->
size);
762 INC (clauses_factored);
771 watch *last = end - 1;
772 while (
p->raw != needle.
raw)
781 const watch needle = kissat_binary_watch (
lit);
787 LOG (
"deleting unfactored quotient[%zu] clauses", q->
id);
796 ADD (literals_unfactored, 2);
800 LOGCLS (c,
"deleting unfactored");
804 ADD (literals_unfactored, c->
size);
806 INC (clauses_unfactored);
822 LOGCLS (c,
"deleting unfactored");
838 flush_unmatched_clauses (
solver,
p);
841 const unsigned not_fresh =
NOT (fresh);
842 add_factored_quotient (
factoring, q, not_fresh);
858 const unsigned *
p = begin;
860 const unsigned lit = *
p++;
861 const unsigned idx =
IDX (
lit);
862 LOG (
"unbumping fresh[%zu] %s", (
size_t) (
p - begin - 1),
864 const double score = 0;
865 kissat_update_heap (
solver, &
solver->scores, idx, score);
869 const unsigned *
p = end;
873 const unsigned lit = *--
p;
874 const unsigned idx =
IDX (
lit);
881 const unsigned lit = *--
p;
882 const unsigned idx =
IDX (
lit);
907static bool run_factorization (
kissat *
solver, uint64_t limit) {
913 unsigned factored = 0;
915 uint64_t *ticks = &
solver->statistics_.factor_ticks;
917 solver,
"factorization limit of %" PRIu64
" ticks", limit - *ticks);
919 const unsigned first =
921 const unsigned first_idx =
IDX (first);
924 if (*ticks > limit) {
931 const unsigned bit = 1u <<
NEGATED (first);
935 const size_t first_count = first_factor (&
factoring, first);
936 if (first_count > 1) {
939 const unsigned next = next_factor (&
factoring, &next_count);
945 factorize_next (&
factoring, next, next_count);
961 adjust_scores_and_phases_of_fresh_varaibles (&
factoring);
968 const unsigned size_limit =
GET_OPTION (factorsize);
969 if (size_limit < 3) {
975 clause *last_irredundant = kissat_last_irredundant_clause (
solver);
978 unsigned *bincount, *largecount;
993 size_t initial_candidates = 0;
997 if (last_irredundant && last_irredundant < c)
1001 if (c->
size > size_limit)
1005 initial_candidates++;
1008 "initially found %zu large clause candidates",
1009 initial_candidates);
1010 size_t candidates = initial_candidates;
1011 const unsigned rounds =
GET_OPTION (factorcandrounds);
1012 for (
unsigned round = 1; round <= rounds; round++) {
1013 size_t new_candidates = 0;
1014 unsigned *newlargecount;
1019 if (last_irredundant && last_irredundant < c)
1023 if (c->
size > size_limit)
1026 if (bincount[
lit] + largecount[
lit] < 2)
1027 goto CONTINUE_WITH_NEXT_CLAUSE1;
1029 newlargecount[
lit]++;
1031 CONTINUE_WITH_NEXT_CLAUSE1:;
1034 largecount = newlargecount;
1035 if (candidates == new_candidates) {
1037 "no large factorization candidate clauses "
1038 "reduction in round %u",
1042 candidates = new_candidates;
1045 "reduced to %zu large factorization candidate clauses %.0f%% in "
1047 candidates, kissat_percent (candidates, initial_candidates), round);
1050 size_t connected = 0;
1055 if (last_irredundant && last_irredundant < c)
1059 if (c->
size > size_limit)
1061 int continue_with_next_clause2 = 0;
1063 if (bincount[
lit] + largecount[
lit] < 2) {
1064 continue_with_next_clause2 = 1;
1067 if(continue_with_next_clause2) {
1071 kissat_inlined_connect_clause (
solver, all_watches, c, ref);
1079 solver,
"connected %zu large factorization candidate clauses %.0f%%",
1080 connected, kissat_percent (candidates, initial_candidates));
1085 if (
solver->inconsistent)
1090 if (
solver->limits.factor.marked >= s->literals_factor) {
1093 "factorization skipped as no literals have been marked to be added "
1094 "(%" PRIu64
" < %" PRIu64,
1095 solver->limits.factor.marked, s->literals_factor);
1099 INC (factorizations);
1101 "binary clause bounded variable addition");
1102 uint64_t limit =
GET_OPTION (factoriniticks);
1103 if (s->factorizations > 1) {
1108 "initially limiting to %" PRIu64
1109 " million factorization ticks",
1112 limit += s->factor_ticks;
1116 int64_t variables, binary, clauses, ticks;
1117 } before, after, delta;
1118 before.variables = s->variables_extension + s->variables_original;
1121 before.ticks = s->factor_ticks;
1124 connect_clauses_to_factor (
solver);
1125 bool completed = run_factorization (
solver, limit);
1128 after.variables = s->variables_extension + s->variables_original;
1131 after.ticks = s->factor_ticks;
1132 delta.variables = after.variables - before.variables;
1133 delta.binary = before.binary - after.binary;
1134 delta.clauses = before.clauses - after.clauses;
1135 delta.ticks = after.ticks - before.ticks;
1137 delta.ticks * 1e-6);
1139 "introduced %" PRId64
" extension variables %.0f%%",
1141 kissat_percent (delta.variables, before.variables));
1143 "removed %" PRId64
" binary clauses %.0f%%", delta.binary,
1144 kissat_percent (delta.binary, before.binary));
1146 "removed %" PRId64
" large clauses %.0f%%", delta.clauses,
1147 kissat_percent (delta.clauses, before.clauses));
1150 solver->limits.factor.marked = s->literals_factor;
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void * kissat_malloc(kissat *solver, size_t bytes)
void kissat_free(kissat *solver, void *ptr, size_t bytes)
void * kissat_nrealloc(kissat *solver, void *p, size_t o, size_t n, size_t size)
ABC_NAMESPACE_HEADER_START typedef word ward
#define RESIZE_STACK(S, NEW_SIZE)
#define POKE_STACK(S, N, E)
#define all_stack(T, E, S)
reference kissat_new_irredundant_clause(kissat *solver)
void kissat_mark_clause_as_garbage(kissat *solver, clause *c)
void kissat_new_binary_clause(kissat *solver, unsigned first, unsigned second)
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_factor(kissat *solver)
ABC_NAMESPACE_IMPL_START void kissat_release_heap(kissat *solver, heap *heap)
unsigned kissat_fresh_literal(kissat *solver)
#define all_variables(IDX)
#define all_literals(LIT)
#define all_literals_in_clause(LIT, C)
#define KISSAT_assert(ignore)
#define SET_EFFORT_LIMIT(LIMIT, NAME, THRESHHOLD)
#define kissat_extremely_verbose(...)
#define kissat_very_verbose(...)
#define kissat_phase(...)
#define DISCONNECTED(IDX)
ABC_NAMESPACE_HEADER_START typedef unsigned reference
#define IRREDUNDANT_CLAUSES
struct factoring::@160277325255143145147274163211332332056211107037 quotients
#define factor_terminated_1
#define BEGIN_WATCHES(WS)
#define SET_END_OF_WATCHES(WS, P)
#define all_binary_large_watches(WATCH, WATCHES)