21#define LD_MAX_WALK_REF 31
22#define MAX_WALK_REF ((1u << LD_MAX_WALK_REF) - 1)
29static inline tagged make_tagged (
bool binary,
unsigned ref) {
31 tagged res = {.ref = ref, .binary = binary};
44#define INVALID_BEST_TRAIL_POS UINT_MAX
49 unsigned best_trail_pos;
64 value *original_values;
97 clause *c = kissat_dereference_clause (
solver, clause_ref);
105 unsigned counter_ref) {
113 const unsigned *
const lits =
114 dereference_literals (
solver,
walker, counter_ref, &size);
120 unsigned counter_ref,
unsigned pos) {
128 if (counter_ref != other_counter_ref) {
130 counter *other_counter = counters + other_counter_ref;
139 const unsigned *
const lits =
140 dereference_literals (
solver,
walker, counter_ref, &size);
141 LOGLITS (size, lits,
"popped unsatisfied[%u]",
pos);
148static double cbvals[][2] = {{0.0, 2.00}, {3.0, 2.50}, {4.0, 2.85},
149 {5.0, 3.70}, {6.0, 5.10}, {7.0, 7.40}};
151static double fit_cbval (
double size) {
152 const size_t num_cbvals =
sizeof cbvals /
sizeof *cbvals;
154 while (i + 2 < num_cbvals &&
155 (cbvals[i][0] > size || cbvals[i + 1][0] < size))
157 const double x2 = cbvals[i + 1][0], x1 = cbvals[i][0];
158 const double y2 = cbvals[i + 1][1], y1 = cbvals[i][1];
159 const double dx = x2 - x1, dy = y2 - y1;
161 const double res = dy * (
size - x1) / dx + y1;
169 const double cb = (
GET (walks) & 1) ? fit_cbval (
walker->size) : 2.0;
170 const double base = 1 / cb;
173 unsigned exponents = 0;
174 for (next = 1; next; next *= base)
181 for (epsilon = next = 1; next; next = epsilon * base)
182 walker->table[i++] = epsilon = next;
185 walker->exponents = exponents;
186 walker->epsilon = epsilon;
189 "CB %.2f with inverse %.2f as base", cb, base);
200 INC (walk_decisions);
206 unsigned imported = 0;
209 if (!
flags[idx].active)
213 best_values[idx] =
value;
214 const unsigned lit =
LIT (idx);
215 const unsigned not_lit =
NOT (
lit);
217 values[not_lit] = -
value;
221 LOG (
"copied %s decision phase %d", LOGVAR (idx), (
int)
value);
224 "imported %u decision phases %.0f%%", imported,
225 kissat_percent (imported,
solver->active));
228static unsigned connect_binary_counters (
walker *
walker) {
238 unsigned unsat = 0, counter_ref = 0;
240 for (
unsigned binary_ref = 0; binary_ref <
size; binary_ref++) {
245 const value first_value = values[first];
246 const value second_value = values[second];
247 if (!first_value || !second_value)
250 refs[counter_ref] = make_tagged (
true, binary_ref);
251 watches *first_watches = all_watches + first;
252 watches *second_watches = all_watches + second;
253 kissat_push_large_watch (
solver, first_watches, counter_ref);
254 kissat_push_large_watch (
solver, second_watches, counter_ref);
255 const unsigned count = (first_value > 0) + (second_value > 0);
265 "initially %u unsatisfied binary clauses %.0f%% out of %u",
266 unsat, kissat_percent (unsat, counter_ref), counter_ref);
270 walker->size += 2.0 * counter_ref;
274static void connect_large_counters (
walker *
walker,
unsigned counter_ref) {
277 const value *
const original_values =
walker->original_values;
278 const value *
const local_search_values =
solver->values;
286 clause *last_irredundant = kissat_last_irredundant_clause (
solver);
289 if (last_irredundant && c > last_irredundant)
295 bool continue_with_next_clause =
false;
303 continue_with_next_clause =
true;
306 if (continue_with_next_clause)
313 refs[counter_ref] = make_tagged (
false, clause_ref);
314 unsigned count = 0,
size = 0;
338 "initially %u unsatisfied large clauses %.0f%% out of %u",
339 unsat, kissat_percent (unsat, large), large);
358 "%s minimum of %u unsatisfied clauses after %" PRIu64
364#define report_initial_minimum(...) \
367#define report_minimum(...) \
373 litpairs *binaries) {
380 walker->clauses = clauses;
381 walker->binaries = binaries;
387 import_decision_phases (
walker);
393 const unsigned counter_ref = connect_binary_counters (
walker);
394 connect_large_counters (
walker, counter_ref);
399 "initially %u unsatisfied irredundant clauses %.0f%% "
401 walker->initial, kissat_percent (
walker->initial, clauses),
409 init_score_table (
walker);
420 walker->report.minimum = UINT_MAX;
421 walker->report.flipped = 0;
429 unsigned clauses =
walker->clauses;
444 const unsigned not_lit =
NOT (
lit);
456 ADD (walk_steps, steps);
463static double scale_score (
walker *
walker,
unsigned breaks) {
464 if (breaks < walker->exponents)
465 return walker->table[breaks];
475 const unsigned *
const lits =
476 dereference_literals (
solver,
walker, counter_ref, &size);
478 LOGLITS (size, lits,
"picked unsatisfied[%u]",
pos);
486 const unsigned *
const end_of_lits = lits +
size;
487 for (
const unsigned *
p = lits;
p != end_of_lits;
p++) {
488 const unsigned lit = *
p;
493 const double score = scale_score (
walker, breaks);
495 LOG (
"literal %s breaks %u score %g",
LOGLIT (
lit), breaks, score);
502 const double random = kissat_pick_double (&
walker->random);
505 const double threshold = sum *
random;
506 LOG (
"score sum %g and random threshold %g", sum, threshold);
512 double picked_score = 0;
517 for (
const unsigned *
p = lits;
p != end_of_lits;
p++) {
518 const unsigned lit = *
p;
521 const double score = *
scores++;
523 if (threshold < sum) {
526 picked_score = score;
532 LOG (
"picked literal %s with score %g",
LOGLIT (picked_lit),
541 const value *
const values,
unsigned flipped) {
545 const unsigned not_flipped =
NOT (flipped);
547 LOG (
"breaking one-satisfied clauses containing negated flipped literal "
567 LOG (
"broken %u one-satisfied clauses containing "
568 "negated flipped literal %s",
569 broken,
LOGLIT (not_flipped));
570 ADD (walk_steps, steps);
577 const value *
const values,
unsigned flipped) {
579 LOG (
"making unsatisfied clauses containing flipped literal %s",
602 LOG (
"made %u unsatisfied clauses containing flipped literal %s", made,
604 ADD (walk_steps, steps);
613 LOG (
"copying all values as best phases since trail is invalid");
614 const value *
const current_values =
solver->values;
617 const unsigned lit =
LIT (idx);
620 best_values[idx] =
value;
622 LOG (
"reset best trail position to 0");
623 walker->best_trail_pos = 0;
627#if defined(LOGGING) || !defined(KISSAT_NDEBUG)
632 const unsigned kept = size_trail -
walker->best_trail_pos;
633 LOG (
"saving %u values of flipped literals on trail of size %u",
634 walker->best_trail_pos, size_trail);
640 const unsigned *
const best = begin +
walker->best_trail_pos;
641 for (
const unsigned *
p = begin;
p != best;
p++) {
642 const unsigned lit = *
p;
644 const unsigned idx =
IDX (
lit);
645 best_values[idx] =
value;
648 LOG (
"no need to shift and keep remaining %u literals", kept);
651 LOG (
"flushed %u literals %.0f%% from trail",
walker->best_trail_pos,
652 kissat_percent (
walker->best_trail_pos, size_trail));
655 for (
const unsigned *
p = best;
p != end;
p++)
660 LOG (
"keeping %u literals %.0f%% on trail", kept,
661 kissat_percent (kept, size_trail));
662 LOG (
"reset best trail position to 0");
663 walker->best_trail_pos = 0;
669 LOG (
"not pushing flipped %s to already invalid trail",
676 const unsigned limit =
VARS / 4 + 1;
678 if (size_trail < limit) {
680 LOG (
"pushed flipped %s to trail which now has size %u",
681 LOGLIT (flipped), size_trail + 1);
682 }
else if (
walker->best_trail_pos) {
683 LOG (
"trail reached limit %u but has best position %u", limit,
688 LOG (
"pushed flipped %s to trail which now has size %zu",
691 LOG (
"trail reached limit %u without best position", limit);
693 LOG (
"not pushing %s to invalidated trail",
LOGLIT (flipped));
695 LOG (
"best trail position becomes invalid");
701 LOG (
"flipping literal %s",
LOGLIT (flip));
705 values[flip] = -
value;
716 int verbosity = kissat_verbosity (
solver);
717 bool report = (verbosity > 2);
718 if (verbosity == 2) {
721 else if (
walker->minimum < 5 ||
walker->report.minimum == UINT_MAX ||
737 LOG (
"new best trail position %u",
walker->best_trail_pos);
746 LOG (
"starting local search flip %" PRIu64
" with %u unsatisfied clauses",
753 LOG (
"ending local search step %" PRIu64
" with %u unsatisfied clauses",
760 const unsigned before =
walker->minimum;
774 "walking ends with %u unsatisfied clauses",
walker->current);
776 "flipping %" PRIu64
" literals took %" PRIu64
" steps (%.2f per flipped)",
777 walker->flipped, steps, kissat_average (steps,
walker->flipped));
779 const unsigned after =
walker->minimum;
781 solver,
"walk",
GET (walks),
"%s minimum %u after %" PRIu64
" flips",
782 after < before ? "new" : "unchanged", after, walker->flipped);
801 "no improvement thus keeping saved phases");
806 "saving improved assignment of %u unsatisfied clauses",
809 if (!
walker->best_trail_pos ||
811 LOG (
"minimum already saved");
815 export_best_values (
walker);
823static void check_walk (
kissat *
solver,
unsigned expected) {
824 unsigned unsatisfied = 0;
830 if (kissat_empty_vector (
watches))
864 bool satisfied =
false;
878 LOGCLS (c,
"unsatisfied");
881 LOG (
"expected %u unsatisfied", expected);
882 LOG (
"actually %u unsatisfied", unsatisfied);
896 local_search_round (&
walker);
900 save_final_minimum (&
walker);
902 unsigned expected =
walker.minimum;
909 check_walk (
solver, expected);
920 "can not walk since last "
921 "irredundant clause reference %u too large",
929 "can not walk due to "
930 "way too many irredundant clauses %" PRIu64,
950 "last irredundant clause reference %u too large",
958 "way too many irredundant clauses %" PRIu64, clauses);
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void * kissat_malloc(kissat *solver, size_t bytes)
void * kissat_calloc(kissat *solver, size_t n, size_t size)
void kissat_free(kissat *solver, void *ptr, size_t bytes)
void kissat_dealloc(kissat *solver, void *ptr, size_t n, size_t size)
ABC_NAMESPACE_HEADER_START typedef word ward
ABC_NAMESPACE_HEADER_START typedef uint64_t generator
#define POKE_STACK(S, N, E)
#define SET_END_OF_STACK(S, P)
ABC_NAMESPACE_IMPL_START typedef signed char value
void kissat_mark_clause_as_garbage(kissat *solver, clause *c)
int kissat_decide_phase(kissat *solver, unsigned idx)
void kissat_enter_dense_mode(kissat *solver, litpairs *irredundant)
void kissat_resume_sparse_mode(kissat *solver, bool flush_eliminated, litpairs *irredundant)
type
CUBE COVER and CUBE typedefs ///.
#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 STOP_SEARCH_AND_START_SIMPLIFIER(...)
#define STOP_SIMPLIFIER_AND_RESUME_SEARCH(...)
ABC_NAMESPACE_HEADER_START typedef unsigned reference
#define walk_terminated_1
#define report_minimum(...)
void kissat_walk(kissat *solver)
#define INVALID_BEST_TRAIL_POS
#define report_initial_minimum(...)
bool kissat_walking(kissat *solver)
ABC_NAMESPACE_IMPL_START void kissat_warmup(kissat *solver)
#define all_binary_blocking_watches(WATCH, WATCHES)
#define all_binary_large_watches(WATCH, WATCHES)