25 double score (
unsigned);
35static double cbvals[][2] = {
36 {0.0, 2.00}, {3.0, 2.50}, {4.0, 2.85}, {5.0, 3.70},
37 {6.0, 5.10}, {7.0, 7.40},
40static const int ncbvals =
sizeof cbvals /
sizeof cbvals[0];
51inline static double fitcbval (
double size) {
53 while (i + 2 < ncbvals &&
54 (cbvals[i][0] > size || cbvals[i + 1][0] < size))
56 const double x2 = cbvals[i + 1][0], x1 = cbvals[i][0];
57 const double y2 = cbvals[i + 1][1], y1 = cbvals[i][1];
58 const double dx = x2 - x1, dy = y2 - y1;
60 const double res = dy * (
size - x1) / dx + y1;
76 const bool use_size_based_cb = (
internal->stats.walk.count & 1);
77 const double cb = use_size_based_cb ? fitcbval (size) : 2.0;
79 const double base = 1 / cb;
86 "CB %.2f with inverse %.2f as base and table size %zd", cb, base,
94 LOG (
"break %u mapped to score %g", i, res);
103 int64_t size =
walker.broken.size ();
106 int pos =
walker.random.pick_int (0, size - 1);
108 LOG (res,
"picking random position %d",
pos);
126 if (
val (w.blit) > 0)
142 auto begin = c->
begin () + 1;
143 const auto end = c->
end ();
147 const int other = *i;
167 const int other = *--i;
192 LOG (
"picking literal by break-count");
195 int64_t propagations = 0;
196 for (
const auto lit : *c) {
199 LOG (
"skipping assumption %d for scoring", -
lit);
206 LOG (
"literal %d break-count %u score %g",
lit, tmp,
score);
210 LOG (
"scored %zd literals",
walker.scores.size ());
212 walker.propagations += propagations;
213 stats.propagations.walk += propagations;
215 const double lim = sum *
walker.random.generate_double ();
216 LOG (
"score sum %g limit %g", sum,
lim);
217 const auto end = c->
end ();
218 auto i = c->
begin ();
219 auto j =
walker.scores.begin ();
226 LOG (
"skipping assumption %d without score", -res);
229 while (sum <=
lim && i != end) {
232 LOG (
"skipping assumption %d without score", -res);
238 LOG (
"picking literal %d by break-count", res);
247 LOG (
"flipping assign %d",
lit);
253 const int idx = abs (
lit);
261 LOG (
"trying to make %zd broken clauses",
walker.broken.size ());
277 const auto eou =
walker.broken.end ();
278 auto j =
walker.broken.begin (), i = j;
288 int *literals = d->
literals, prev = 0;
292 const int size = d->
size;
293 for (
int i = 0; i < size; i++) {
294 const int other = literals[i];
316 for (
int i = size - 1; i >= 0; i--) {
317 int other = literals[i];
333 stats.propagations.walk++;
335 LOG (
"made %" PRId64
" clauses by flipping %d", made,
lit);
342 stats.propagations.walk++;
349 LOG (
"trying to break %zd watched clauses", ws.
size ());
351 for (
const auto &w : ws) {
353 LOG (d,
"unwatch %d in", -
lit);
354 int *literals = d->
literals, replacement = 0, prev = -
lit;
356 const int size = d->
size;
357 for (
int i = 1; i < size; i++) {
358 const int other = literals[i];
362 const signed char tmp =
val (other);
370 literals[0] = replacement;
374 for (
int i = size - 1; i > 0; i--) {
375 const int other = literals[i];
381 walker.broken.push_back (d);
387 LOG (
"broken %" PRId64
" clauses by flipping %d", broken,
lit);
397 int64_t broken =
walker.broken.size ();
398 if (broken >=
stats.walk.minimum)
400 VERBOSE (3,
"new global minimum %" PRId64
"", broken);
401 stats.walk.minimum = broken;
402 for (
auto i :
vars) {
403 const signed char tmp =
vals[i];
415 LOG (
"empty clause after root level propagation");
426 if (
last.collect.fixed <
stats.all.fixed)
434 force_phase_messages =
true;
439 "random walk limit of %" PRId64
" propagations",
limit);
449 if (!
opts.walkredundant)
457 double average_size =
relative (size, n);
460 "%" PRId64
" clauses average size %.2f over %d variables", n,
472 LOG (
"no assumptions so assigning all variables to decision phase");
474 LOG (
"assigning assumptions to their forced phase first");
476 signed char tmp =
val (
lit);
480 LOG (
"inconsistent assumption %d",
lit);
487 const int idx = abs (
lit);
488 LOG (
"initial assign %d to assumption phase", tmp < 0 ? -idx : idx);
494 LOG (
"now assigning remaining variables to their decision phase");
501 for (
auto idx :
vars) {
503 LOG (
"skipping inactive variable %d", idx);
508 LOG (
"skipping assumed variable %d", idx);
520 LOG (
"initial assign %d to decision phase", tmp < 0 ? -idx : idx);
523 LOG (
"watching satisfied and registering broken clauses");
532 if (!
opts.walkredundant)
538 bool satisfiable =
false;
541 int *
lits = c->literals;
542 const int size = c->size;
547 for (
int i = 0;
satisfied < 2 && i < size; i++) {
553 LOG (
"first satisfying literal %d",
lit);
555 LOG (
"non-assumption potentially satisfying literal %d",
lit);
561 LOG (c,
"due to assumptions unsatisfiable");
562 LOG (
"stopping local search since assumptions falsify a clause");
575 walker.broken.push_back (c);
580 int64_t broken =
walker.broken.size ();
581 int64_t total = watched + broken;
582 LOG (
"watching %" PRId64
" clauses %.0f%% "
583 "out of %" PRId64
" (watched and broken)",
584 watched,
percent (watched, total), total);
589 int64_t old_global_minimum =
stats.walk.minimum;
595 int64_t broken =
walker.broken.size ();
598 "starting with %" PRId64
" unsatisfied clauses "
599 "(%.0f%% out of %" PRId64
")",
601 stats.current.irredundant);
605 int64_t minimum = broken;
615 stats.walk.broken += broken;
619 broken =
walker.broken.size ();
620 LOG (
"now have %" PRId64
" broken clauses in total", broken);
621 if (broken >= minimum)
624 VERBOSE (3,
"new phase minimum %" PRId64
" after %" PRId64
" flips",
629 if (minimum < old_global_minimum)
631 "%snew global minimum %" PRId64
"%s in %" PRId64
" flips and "
632 "%" PRId64
" propagations",
633 tout.bright_yellow_code (), minimum,
tout.normal_code (),
634 flips,
walker.propagations);
637 "best phase minimum %" PRId64
" in %" PRId64
" flips and "
638 "%" PRId64
" propagations",
639 minimum, flips,
walker.propagations);
641 if (
opts.profile >= 2) {
643 "%.2f million propagations per second",
645 time () - profiles.walk.started));
647 PHASE (
"walk",
stats.walk.count,
"%.2f thousand flips per second",
648 relative (1e-3 * flips,
time () - profiles.walk.started));
651 PHASE (
"walk",
stats.walk.count,
"%.2f million propagations",
652 1e-6 *
walker.propagations);
654 PHASE (
"walk",
stats.walk.count,
"%.2f thousand flips", 1e-3 * flips);
658 LOG (
"minimum %" PRId64
" non-zero thus potentially continue",
662 LOG (
"minimum is zero thus stop local search");
671 "aborted due to inconsistent assumptions");
676 for (
auto idx :
vars)
689 force_phase_messages =
false;
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
double relative(double a, double b)
double percent(double a, double b)
#define START_INNER_WALK()
#define STOP_INNER_WALK()
double clause_variable_ratio() const
void watch_literal(int lit, int blit, Clause *c)
void garbage_collection()
Clause * walk_pick_clause(Walker &)
bool terminated_asynchronously(int factor=1)
void learn_empty_clause()
int decide_phase(int idx, bool target)
void walk_flip_lit(Walker &, int lit)
signed char val(int lit) const
bool limit(const char *name, int)
void set_val(int lit, signed char val)
int walk_pick_lit(Walker &, Clause *)
vector< int > assumptions
void backtrack(int target_level=0)
vector< Clause * > clauses
void walk_save_minimum(Walker &)
void require_mode(Mode m) const
unsigned walk_break_value(int lit)
void copy_phases(vector< signed char > &)
Watches & watches(int lit)
bool likely_to_be_kept_clause(Clause *c)
int walk_round(int64_t limit, bool prev)
void connect_watches(bool irredundant_only=false)
Walker(Internal *, double size, int64_t limit)
vector< Clause * > broken