927 lines
25 KiB
C
Raw Normal View History

2022-08-30 15:42:35 +08:00
#include "allocate.h"
#include "decide.h"
#include "dense.h"
#include "inline.h"
#include "print.h"
#include "report.h"
#include "rephase.h"
#include "terminate.h"
#include "walk.h"
typedef struct tagged tagged;
typedef struct counter counter;
typedef struct walker walker;
#define LD_MAX_WALK_REF 31
#define MAX_WALK_REF ((1u << LD_MAX_WALK_REF) - 1)
struct tagged
{
unsigned ref:LD_MAX_WALK_REF;
bool binary:1;
};
static inline tagged
make_tagged (bool binary, unsigned ref)
{
assert (ref <= MAX_WALK_REF);
tagged res = {.binary = binary,.ref = ref };
return res;
}
struct counter
{
unsigned count;
unsigned pos;
};
// *INDENT-OFF*
typedef STACK (double) doubles;
// *INDENT-ON*
#define INVALID_BEST UINT_MAX
struct walker
{
kissat *solver;
generator random;
counter *counters;
litpairs *binaries;
value *saved;
unsigned clauses;
unsigned offset;
unsigned minimum;
unsigned current;
unsigned initial;
tagged *refs;
double *table;
double epsilon;
unsigned exponents;
doubles scores;
unsigneds unsat;
unsigneds trail;
unsigned best;
uint64_t limit;
#ifndef QUIET
uint64_t start;
uint64_t flipped;
struct
{
uint64_t flipped;
unsigned minimum;
} report;
#endif
};
static const unsigned *
dereference_literals (kissat * solver, walker * walker,
unsigned counter_ref, unsigned *size_ptr)
{
assert (counter_ref < walker->clauses);
tagged tagged = walker->refs[counter_ref];
const unsigned *lits;
if (tagged.binary)
{
const unsigned binary_ref = tagged.ref;
lits = PEEK_STACK (*walker->binaries, binary_ref).lits;
*size_ptr = 2;
}
else
{
const reference clause_ref = tagged.ref;
clause *c = kissat_dereference_clause (solver, clause_ref);
*size_ptr = c->size;
lits = c->lits;
}
return lits;
}
static void
push_unsat (kissat * solver, walker * walker,
counter * counters, unsigned counter_ref)
{
assert (counter_ref < walker->clauses);
counter *counter = counters + counter_ref;
assert (SIZE_STACK (walker->unsat) <= UINT_MAX);
counter->pos = SIZE_STACK (walker->unsat);
PUSH_STACK (walker->unsat, counter_ref);
#ifdef LOGGING
unsigned size;
const unsigned *lits = dereference_literals (solver, walker,
counter_ref, &size);
LOGLITS (size, lits, "pushed unsatisfied[%u]", counter->pos);
#endif
}
static bool
pop_unsat (kissat * solver, walker * walker,
counter * counters, unsigned counter_ref, unsigned pos)
{
assert (walker->current);
assert (counter_ref < walker->clauses);
assert (counters[counter_ref].pos == pos);
assert (walker->current == SIZE_STACK (walker->unsat));
const unsigned other_counter_ref = POP_STACK (walker->unsat);
walker->current--;
bool res = false;
if (counter_ref != other_counter_ref)
{
assert (other_counter_ref < walker->clauses);
counter *other_counter = counters + other_counter_ref;
assert (other_counter->pos == walker->current);
assert (pos < other_counter->pos);
other_counter->pos = pos;
POKE_STACK (walker->unsat, pos, other_counter_ref);
res = true;
}
#ifdef LOGGING
unsigned size;
const unsigned *lits = dereference_literals (solver, walker,
counter_ref, &size);
LOGLITS (size, lits, "popped unsatisfied[%u]", pos);
#else
(void) solver;
#endif
return res;
}
static void
init_score_table (walker * walker)
{
kissat *solver = walker->solver;
const double cb = 2.0;
const double base = 1 / cb;
double next;
unsigned exponents = 0;
for (next = 1; next; next *= base)
exponents++;
walker->table = kissat_malloc (solver, exponents * sizeof (double));
unsigned i = 0;
double epsilon;
for (epsilon = next = 1; next; next = epsilon * base)
walker->table[i++] = epsilon = next;
assert (i == exponents);
walker->exponents = exponents;
walker->epsilon = epsilon;
kissat_phase (solver, "walk", GET (walks),
"CB %.2f with inverse %.2f as base", cb, base);
kissat_phase (solver, "walk", GET (walks),
"table size %u and epsilon %g", exponents, epsilon);
}
static unsigned
currently_unsatified (walker * walker)
{
return SIZE_STACK (walker->unsat);
}
static void
import_decision_phases (walker * walker)
{
kissat *solver = walker->solver;
const phase *phases = solver->phases;
const value initial_phase = INITIAL_PHASE;
const flags *flags = solver->flags;
const bool stable = solver->stable;
value *values = solver->values;
for (all_variables (idx))
{
if (!flags[idx].active)
continue;
const phase *p = phases + idx;
value value = 0;
if (stable)
value = p->target;
if (!value)
value = p->saved;
if (!value)
value = initial_phase;
assert (value);
const unsigned lit = LIT (idx);
const unsigned not_lit = NOT (lit);
values[lit] = value;
values[not_lit] = -value;
LOG ("copied variable %u decision phase %d", idx, (int) value);
}
kissat_phase (solver, "walk", GET (walks), "copied decision phases");
}
static unsigned
connect_binary_counters (walker * walker)
{
kissat *solver = walker->solver;
value *values = solver->values;
tagged *refs = walker->refs;
watches *all_watches = solver->watches;
counter *counters = walker->counters;
assert (SIZE_STACK (*walker->binaries) <= UINT_MAX);
const unsigned size = SIZE_STACK (*walker->binaries);
litpair *binaries = BEGIN_STACK (*walker->binaries);
unsigned unsat = 0, counter_ref = 0;
for (unsigned binary_ref = 0; binary_ref < size; binary_ref++)
{
const litpair *litpair = binaries + binary_ref;
const unsigned first = litpair->lits[0];
const unsigned second = litpair->lits[1];
assert (first < LITS), assert (second < LITS);
const value first_value = values[first];
const value second_value = values[second];
if (!first_value || !second_value)
continue;
assert (counter_ref < walker->clauses);
refs[counter_ref] = make_tagged (true, binary_ref);
watches *first_watches = all_watches + first;
watches *second_watches = all_watches + second;
kissat_push_large_watch (solver, first_watches, counter_ref);
kissat_push_large_watch (solver, second_watches, counter_ref);
const unsigned count = (first_value > 0) + (second_value > 0);
counter *counter = counters + counter_ref;
counter->count = count;
if (!count)
{
push_unsat (solver, walker, counters, counter_ref);
unsat++;
}
counter_ref++;
}
kissat_phase (solver, "walk", GET (walks),
"initially %u unsatisfied binary clauses %.0f%% out of %u",
unsat, kissat_percent (unsat, counter_ref), counter_ref);
#ifdef QUIET
(void) unsat;
#endif
return counter_ref;
}
static void
connect_large_counters (walker * walker, unsigned counter_ref)
{
kissat *solver = walker->solver;
assert (!solver->level);
const value *saved = walker->saved;
const value *values = solver->values;
const word *arena = BEGIN_STACK (solver->arena);
counter *counters = walker->counters;
tagged *refs = walker->refs;
unsigned unsat = 0;
unsigned large = 0;
clause *last_irredundant = kissat_last_irredundant_clause (solver);
for (all_clauses (c))
{
if (last_irredundant && c > last_irredundant)
break;
if (c->garbage)
continue;
if (c->redundant)
continue;
for (all_literals_in_clause (lit, c))
{
const value value = saved[lit];
if (value <= 0)
continue;
LOGCLS (c, "%s satisfied", LOGLIT (lit));
kissat_mark_clause_as_garbage (solver, c);
break;
}
if (c->garbage)
continue;
large++;
assert (kissat_clause_in_arena (solver, c));
reference clause_ref = (word *) c - arena;
assert (clause_ref <= MAX_WALK_REF);
assert (counter_ref < walker->clauses);
refs[counter_ref] = make_tagged (false, clause_ref);
unsigned count = 0;
for (all_literals_in_clause (lit, c))
{
const value value = values[lit];
if (!value)
continue;
watches *watches = &WATCHES (lit);
kissat_push_large_watch (solver, watches, counter_ref);
if (value < 0)
continue;
count++;
}
counter *counter = walker->counters + counter_ref;
counter->count = count;
if (!count)
{
push_unsat (solver, walker, counters, counter_ref);
unsat++;
}
counter_ref++;
}
kissat_phase (solver, "walk", GET (walks),
"initially %u unsatisfied large clauses %.0f%% out of %u",
unsat, kissat_percent (unsat, large), large);
#ifdef QUIET
(void) large;
(void) unsat;
#endif
}
#ifndef QUIET
static void
report_initial_minimum (kissat * solver, walker * walker)
{
walker->report.minimum = walker->minimum;
kissat_very_verbose (solver, "initial minimum of %u unsatisfied clauses",
walker->minimum);
}
static void
report_minimum (const char *type, kissat * solver, walker * walker)
{
assert (walker->minimum <= walker->report.minimum);
kissat_very_verbose (solver,
"%s minimum of %u unsatisfied clauses after %"
PRIu64 " flipped literals", type,
walker->minimum, walker->flipped);
walker->report.minimum = walker->minimum;
}
#else
#define report_initial_minimum(...) do { } while (0)
#define report_minimum(...) do { } while (0)
#endif
static void
init_walker (kissat * solver, walker * walker, litpairs * binaries)
{
assert (IRREDUNDANT_CLAUSES <= MAX_WALK_REF);
const unsigned clauses = IRREDUNDANT_CLAUSES;
memset (walker, 0, sizeof *walker);
walker->solver = solver;
walker->clauses = clauses;
walker->binaries = binaries;
walker->random = solver->random;
walker->saved = solver->values;
solver->values = kissat_calloc (solver, LITS, 1);
import_decision_phases (walker);
walker->counters = kissat_malloc (solver, clauses * sizeof (counter));
walker->refs = kissat_malloc (solver, clauses * sizeof (tagged));
const unsigned counter_ref = connect_binary_counters (walker);
connect_large_counters (walker, counter_ref);
walker->current = walker->initial = currently_unsatified (walker);
kissat_phase (solver, "walk", GET (walks),
"initially %u unsatisfied irredundant clauses %.0f%% "
"out of %" PRIu64, walker->initial,
kissat_percent (walker->initial, IRREDUNDANT_CLAUSES),
IRREDUNDANT_CLAUSES);
walker->minimum = walker->current;
init_score_table (walker);
report_initial_minimum (solver, walker);
}
static void
init_walker_limit (kissat * solver, walker * walker)
{
SET_EFFICIENCY_BOUND (limit, walk, walk_steps, search_ticks, 2 * CLAUSES);
walker->limit = limit;
#ifndef QUIET
walker->start = solver->statistics.walk_steps;
walker->flipped = 0;
walker->report.minimum = UINT_MAX;
walker->report.flipped = 0;;
#endif
}
static void
release_walker (walker * walker)
{
kissat *solver = walker->solver;
kissat_dealloc (solver, walker->table, walker->exponents, sizeof (double));
unsigned clauses = walker->clauses;
kissat_dealloc (solver, walker->refs, clauses, sizeof (tagged));
kissat_dealloc (solver, walker->counters, clauses, sizeof (counter));
RELEASE_STACK (walker->unsat);
RELEASE_STACK (walker->scores);
RELEASE_STACK (walker->trail);
kissat_free (solver, solver->values, LITS);
RELEASE_STACK (walker->unsat);
solver->values = walker->saved;
}
static unsigned
break_value (kissat * solver, walker * walker, value * values, unsigned lit)
{
assert (values[lit] < 0);
const unsigned not_lit = NOT (lit);
watches *watches = &WATCHES (not_lit);
unsigned steps = 0;
unsigned res = 0;
for (all_binary_large_watches (watch, *watches))
{
steps++;
assert (!watch.type.binary);
reference counter_ref = watch.large.ref;
assert (counter_ref < walker->clauses);
counter *counter = walker->counters + counter_ref;
if (counter->count == 1)
res++;
}
ADD (walk_steps, steps);
#ifdef NDEBUG
(void) values;
#endif
return res;
}
static double
scale_score (walker * walker, unsigned breaks)
{
if (breaks < walker->exponents)
return walker->table[breaks];
else
return walker->epsilon;
}
static unsigned
pick_literal (kissat * solver, walker * walker)
{
assert (walker->current == SIZE_STACK (walker->unsat));
const unsigned pos =
kissat_next_random32 (&walker->random) % walker->current;
const unsigned counter_ref = PEEK_STACK (walker->unsat, pos);
unsigned size;
const unsigned *lits =
dereference_literals (solver, walker, counter_ref, &size);
assert (EMPTY_STACK (walker->scores));
value *values = solver->values;
double sum = 0;
unsigned picked_lit = INVALID_LIT;
const unsigned *end_of_lits = lits + size;
for (const unsigned *p = lits; p != end_of_lits; p++)
{
const unsigned lit = *p;
if (!values[lit])
continue;
picked_lit = lit;
const unsigned breaks = break_value (solver, walker, values, lit);
const double score = scale_score (walker, breaks);
assert (score > 0);
LOG ("literal %s breaks %u score %g", LOGLIT (lit), breaks, score);
PUSH_STACK (walker->scores, score);
sum += score;
}
assert (picked_lit != INVALID_LIT);
assert (0 < sum);
const double random = kissat_pick_double (&walker->random);
assert (0 <= random), assert (random < 1);
const double threshold = sum * random;
LOG ("score sum %g and random threshold %g", sum, threshold);
// assert (threshold < sum); // NOT TRUE!!!!
double *scores = BEGIN_STACK (walker->scores);
#ifdef LOGGING
double picked_score = 0;
#endif
sum = 0;
for (const unsigned *p = lits; p != end_of_lits; p++)
{
const unsigned lit = *p;
if (!values[lit])
continue;
const double score = *scores++;
sum += score;
if (threshold < sum)
{
picked_lit = lit;
#ifdef LOGGING
picked_score = score;
#endif
break;
}
}
assert (picked_lit != INVALID_LIT);
LOG ("picked literal %s with score %g", LOGLIT (picked_lit), picked_score);
CLEAR_STACK (walker->scores);
return picked_lit;
}
static void
break_clauses (kissat * solver, walker * walker,
const value * values, unsigned flipped)
{
#ifdef LOGGING
unsigned broken = 0;
#endif
const unsigned not_flipped = NOT (flipped);
assert (values[not_flipped] < 0);
LOG ("breaking one-satisfied clauses containing negated flipped literal %s",
LOGLIT (not_flipped));
watches *watches = &WATCHES (not_flipped);
counter *counters = walker->counters;
unsigned steps = 0;
for (all_binary_large_watches (watch, *watches))
{
steps++;
assert (!watch.type.binary);
const unsigned counter_ref = watch.large.ref;
assert (counter_ref < walker->clauses);
counter *counter = counters + counter_ref;
assert (counter->count);
if (--counter->count)
continue;
push_unsat (solver, walker, counters, counter_ref);
#ifdef LOGGING
broken++;
#endif
}
LOG ("broken %u one-satisfied clauses containing "
"negated flipped literal %s", broken, LOGLIT (not_flipped));
ADD (walk_steps, steps);
#ifdef NDEBUG
(void) values;
#endif
}
static void
make_clauses (kissat * solver, walker * walker,
const value * values, unsigned flipped)
{
assert (values[flipped] > 0);
LOG ("making unsatisfied clauses containing flipped literal %s",
LOGLIT (flipped));
watches *watches = &WATCHES (flipped);
counter *counters = walker->counters;
unsigned steps = 0;
#ifdef LOGGING
unsigned made = 0;
#endif
for (all_binary_large_watches (watch, *watches))
{
steps++;
assert (!watch.type.binary);
const unsigned counter_ref = watch.large.ref;
assert (counter_ref < walker->clauses);
counter *counter = counters + counter_ref;
assert (counter->count < UINT_MAX);
if (counter->count++)
continue;
if (pop_unsat (solver, walker, counters, counter_ref, counter->pos))
steps++;
#ifdef LOGGING
made++;
#endif
}
LOG ("made %u unsatisfied clauses containing flipped literal %s",
made, LOGLIT (flipped));
ADD (walk_steps, steps);
#ifdef NDEBUG
(void) values;
#endif
}
static void
save_all_values (kissat * solver, walker * walker)
{
assert (EMPTY_STACK (walker->trail));
assert (walker->best == INVALID_BEST);
LOG ("copying all values as saved phases since trail is invalid");
const value *values = solver->values;
phase *phases = solver->phases;
for (all_variables (idx))
{
const unsigned lit = LIT (idx);
const value value = values[lit];
if (value)
phases[idx].saved = value;
}
LOG ("reset best trail position to 0");
walker->best = 0;
}
static void
save_walker_trail (kissat * solver, walker * walker, bool keep)
{
#if defined(LOGGING) || !defined(NDEBUG)
assert (walker->best != INVALID_BEST);
assert (SIZE_STACK (walker->trail) <= UINT_MAX);
const unsigned size_trail = SIZE_STACK (walker->trail);
assert (walker->best <= size_trail);
const unsigned kept = size_trail - walker->best;
LOG ("saving %u values of flipped literals on trail of size %u",
walker->best, size_trail);
#endif
unsigned *begin = BEGIN_STACK (walker->trail);
const unsigned *best = begin + walker->best;
const value *values = solver->values;
phase *phases = solver->phases;
for (const unsigned *p = begin; p != best; p++)
{
const unsigned lit = *p;
value value = values[lit];
assert (value);
if (NEGATED (lit))
value = -value;
const unsigned idx = IDX (lit);
phases[idx].saved = value;
}
if (!keep)
{
LOG ("no need to shift and keep remaining %u literals", kept);
return;
}
LOG ("flushed %u literals %.0f%% from trail",
walker->best, kissat_percent (walker->best, size_trail));
const unsigned *end = END_STACK (walker->trail);
unsigned *q = begin;
for (const unsigned *p = best; p != end; p++)
*q++ = *p;
assert ((size_t) (end - q) == walker->best);
assert ((size_t) (q - begin) == kept);
SET_END_OF_STACK (walker->trail, q);
LOG ("keeping %u literals %.0f%% on trail",
kept, kissat_percent (kept, size_trail));
LOG ("reset best trail position to 0");
walker->best = 0;
}
static void
push_flipped (kissat * solver, walker * walker, unsigned flipped)
{
if (walker->best == INVALID_BEST)
{
LOG ("not pushing flipped %s to already invalid trail",
LOGLIT (flipped));
assert (EMPTY_STACK (walker->trail));
}
else
{
assert (SIZE_STACK (walker->trail) <= UINT_MAX);
const unsigned size_trail = SIZE_STACK (walker->trail);
assert (walker->best <= size_trail);
const unsigned limit = VARS / 4 + 1;
assert (limit < INVALID_BEST);
if (size_trail < limit)
{
PUSH_STACK (walker->trail, flipped);
LOG ("pushed flipped %s to trail which now has size %u",
LOGLIT (flipped), size_trail + 1);
}
else if (walker->best)
{
LOG ("trail reached limit %u but has best position %u",
limit, walker->best);
save_walker_trail (solver, walker, true);
PUSH_STACK (walker->trail, flipped);
assert (SIZE_STACK (walker->trail) <= UINT_MAX);
LOG ("pushed flipped %s to trail which now has size %u",
LOGLIT (flipped), SIZE_STACK (walker->trail));
}
else
{
LOG ("trail reached limit %u without best position", limit);
CLEAR_STACK (walker->trail);
LOG ("not pushing %s to invalidated trail", LOGLIT (flipped));
walker->best = INVALID_BEST;
LOG ("best trail position becomes invalid");
}
}
}
static void
flip_literal (kissat * solver, walker * walker, unsigned flip)
{
LOG ("flipping literal %s", LOGLIT (flip));
value *values = solver->values;
const value value = values[flip];
assert (value < 0);
values[flip] = -value;
values[NOT (flip)] = value;
make_clauses (solver, walker, values, flip);
break_clauses (solver, walker, values, flip);
walker->current = currently_unsatified (walker);
}
static void
update_best (kissat * solver, walker * walker)
{
assert (walker->current < walker->minimum);
walker->minimum = walker->current;
#ifndef QUIET
int verbosity = kissat_verbosity (solver);
bool report = (verbosity > 2);
if (verbosity == 2)
{
if (walker->flipped / 2 >= walker->report.flipped)
report = true;
else if (walker->minimum < 5 ||
walker->report.minimum == UINT_MAX ||
walker->minimum <= walker->report.minimum / 2)
report = true;
if (report)
{
walker->report.minimum = walker->minimum;
walker->report.flipped = walker->flipped;
}
}
if (report)
report_minimum ("new", solver, walker);
#endif
if (walker->best == INVALID_BEST)
save_all_values (solver, walker);
else
{
assert (SIZE_STACK (walker->trail) < INVALID_BEST);
walker->best = SIZE_STACK (walker->trail);
LOG ("new best trail position %u", walker->best);
}
}
static void
local_search_step (kissat * solver, walker * walker)
{
assert (walker->current);
INC (flipped);
#ifndef QUIET
assert (walker->flipped < UINT64_MAX);
walker->flipped++;
#endif
LOG ("starting local search flip %" PRIu64 " with %u unsatisfied clauses",
GET (flipped), walker->current);
unsigned lit = pick_literal (solver, walker);
flip_literal (solver, walker, lit);
push_flipped (solver, walker, lit);
if (walker->current < walker->minimum)
update_best (solver, walker);
LOG ("ending local search step %" PRIu64 " with %u unsatisfied clauses",
GET (flipped), walker->current);
}
static void
local_search_round (walker * walker, unsigned round)
{
kissat *solver = walker->solver;
kissat_very_verbose (solver,
"round %u starts with %u unsatisfied clauses",
round, walker->current);
init_walker_limit (solver, walker);
#ifndef QUIET
const unsigned before = walker->minimum;
#endif
statistics *statistics = &solver->statistics;
while (walker->minimum && walker->limit > statistics->walk_steps)
{
if (TERMINATED (23))
break;
local_search_step (solver, walker);
}
#ifndef QUIET
report_minimum ("last", solver, walker);
assert (statistics->walk_steps >= walker->start);
const uint64_t steps = statistics->walk_steps - walker->start;
// *INDENT-OFF*
kissat_very_verbose (solver,
"round %u ends with %u unsatisfied clauses",
round, walker->current);
kissat_very_verbose (solver,
"flipping %" PRIu64 " literals took %" PRIu64 " steps (%.2f per flipped)",
walker->flipped, steps, kissat_average (steps, walker->flipped));
// *INDENT-ON*
const unsigned after = walker->minimum;
kissat_phase (solver, "walk", GET (walks),
"round %u ends with %s minimum %u after %" PRIu64 " flips",
round, after < before ? "new" : "unchanged", after,
walker->flipped);
#else
(void) round;
#endif
}
static char
save_final_minimum (walker * walker)
{
kissat *solver = walker->solver;
assert (walker->minimum <= walker->initial);
if (walker->minimum == walker->initial)
{
kissat_phase (solver, "walk", GET (walks),
"no improvement thus keeping saved phases");
return 0;
}
if (!walker->best || walker->best == INVALID_BEST)
LOG ("minimum already saved");
else
save_walker_trail (solver, walker, false);
INC (walk_improved);
kissat_phase (solver, "walk", GET (walks),
"improved assignment to %u unsatisfied clauses",
walker->minimum);
return 'W';
}
static char
walking_phase (kissat * solver)
{
INC (walks);
litpairs irredundant;
litwatches redundant;
INIT_STACK (irredundant);
INIT_STACK (redundant);
kissat_enter_dense_mode (solver, &irredundant, &redundant);
walker walker;
init_walker (solver, &walker, &irredundant);
const unsigned max_rounds = GET_OPTION (walkrounds);
for (unsigned round = 1; walker.minimum && round <= max_rounds; round++)
{
if (TERMINATED (24))
break;
local_search_round (&walker, round);
}
char res = save_final_minimum (&walker);
release_walker (&walker);
kissat_resume_sparse_mode (solver, false, &irredundant, &redundant);
RELEASE_STACK (irredundant);
RELEASE_STACK (redundant);
return res;
}
char
kissat_walk (kissat * solver)
{
assert (!solver->level);
assert (!solver->inconsistent);
assert (kissat_propagated (solver));
reference last_irredundant = solver->last_irredundant;
if (last_irredundant == INVALID_REF)
last_irredundant = SIZE_STACK (solver->arena);
if (last_irredundant > MAX_WALK_REF)
{
kissat_phase (solver, "walk", GET (walks),
"last irredundant clause reference %u too large",
last_irredundant);
return kissat_rephase_best (solver);
}
if (IRREDUNDANT_CLAUSES > MAX_WALK_REF)
{
kissat_phase (solver, "walk", GET (walks),
"way too many irredundant clauses %" PRIu64,
IRREDUNDANT_CLAUSES);
return kissat_rephase_best (solver);
}
STOP_SEARCH_AND_START_SIMPLIFIER (walking);
char res = walking_phase (solver);
STOP_SIMPLIFIER_AND_RESUME_SEARCH (walking);
return res;
}
int
kissat_walk_initially (kissat * solver)
{
if (solver->inconsistent)
return 20;
if (TERMINATED (25))
return 0;
if (!GET_OPTION (walkinitially))
return 0;
#ifndef QUIET
char type =
#endif
kissat_walk (solver);
REPORT (0, type ? type : 'W');
return 0;
}