2022-08-30 15:42:35 +08:00

177 lines
4.4 KiB
C

#include "inline.h"
#include "print.h"
#include "reluctant.h"
#include "rephase.h"
#include "report.h"
#include "restart.h"
#include "resources.h"
#include <inttypes.h>
static void
new_mode_limit (kissat * solver)
{
kissat_init_averages (solver, &AVERAGES);
limits *limits = &solver->limits;
statistics *statistics = &solver->statistics;
assert (GET_OPTION (stable) == 1);
if (solver->stable)
{
assert (solver->mode.ticks <= statistics->search_ticks);
uint64_t ticks = statistics->search_ticks - solver->mode.ticks;
const double bias = GET_OPTION (stablebias) * 1e-2;
ticks *= bias;
limits->mode.ticks = statistics->search_ticks + ticks;
kissat_phase (solver, "stable", GET (stable_modes),
"new focused mode switching limit of %s "
"after %s search ticks bias %.0f%%",
FORMAT_COUNT (limits->mode.ticks),
FORMAT_COUNT (ticks), 100 * bias);
}
else
{
const uint64_t interval = GET_OPTION (modeint);
const uint64_t count = statistics->stable_modes;
const uint64_t delta = interval * (kissat_quadratic (count) + 1);
limits->mode.conflicts = CONFLICTS + delta;
kissat_phase (solver, "focus", GET (focused_modes),
"new stable mode switching limit of %s "
"after %s conflicts",
FORMAT_COUNT (limits->mode.conflicts),
FORMAT_COUNT (delta));
}
kissat_reset_rephased (solver);
#ifndef QUIET
solver->mode.conflicts = statistics->conflicts;
#ifndef NMETRICS
solver->mode.propagations = statistics->search_propagations;
#endif
#endif
solver->mode.ticks = statistics->search_ticks;
}
static void
report_switching_from_mode (kissat * solver)
{
#ifndef QUIET
if (kissat_verbosity (solver) < 2)
return;
const double current_time = kissat_process_time ();
const double delta_time = current_time - solver->mode.entered;
statistics *statistics = &solver->statistics;
const uint64_t delta_conflicts =
statistics->conflicts - solver->mode.conflicts;
const uint64_t delta_ticks = statistics->search_ticks - solver->mode.ticks;
#ifndef NMETRICS
const uint64_t delta_propagations =
statistics->search_propagations - solver->mode.propagations;
#endif
solver->mode.entered = current_time;
// *INDENT-OFF*
kissat_very_verbose (solver, "%s mode took %.2f seconds "
"(%" PRIu64 " conflicts, %" PRIu64 " ticks"
#ifndef NMETRICS
", %" PRIu64 " propagations"
#endif
")", solver->stable ? "stable" : "focused",
delta_time, delta_conflicts, delta_ticks
#ifndef NMETRICS
, delta_propagations
#endif
);
// *INDENT-ON*
#else
(void) solver;
#endif
}
static void
switch_to_focused_mode (kissat * solver)
{
assert (solver->stable);
report_switching_from_mode (solver);
REPORT (0, ']');
STOP (stable);
INC (focused_modes);
kissat_phase (solver, "focus", GET (focused_modes),
"switching to focused mode after %" PRIu64
" conflicts", CONFLICTS);
solver->stable = false;
new_mode_limit (solver);
START (focused);
REPORT (0, '{');
const unsigned last = solver->queue.last;
assert (!DISCONNECTED (last));
kissat_update_queue (solver, solver->links, last);
kissat_new_focused_restart_limit (solver);
}
void
kissat_update_scores (kissat * solver)
{
heap *scores = solver->heuristic==0?&solver->scores:&solver->scores_chb;
for (all_variables (idx))
if (ACTIVE (idx) && !kissat_heap_contains (scores, idx))
kissat_push_heap (solver, scores, idx);
}
static void
switch_to_stable_mode (kissat * solver)
{
assert (!solver->stable);
report_switching_from_mode (solver);
REPORT (0, '}');
STOP (focused);
INC (stable_modes);
solver->stable = true;
kissat_phase (solver, "stable", GET (stable_modes),
"switched to stable mode after %" PRIu64
" conflicts", CONFLICTS);
new_mode_limit (solver);
START (stable);
REPORT (0, '[');
kissat_init_reluctant (solver);
kissat_update_scores (solver);
}
void
kissat_switch_search_mode (kissat * solver)
{
assert (!solver->inconsistent);
if (solver->rephased.type)
return;
if (GET_OPTION (stable) != 1)
return;
limits *limits = &solver->limits;
statistics *statistics = &solver->statistics;
if (solver->stable)
{
if (statistics->search_ticks < limits->mode.ticks)
return;
}
else if (statistics->conflicts < limits->mode.conflicts)
return;
INC (switched_modes);
if (solver->stable)
switch_to_focused_mode (solver);
else
switch_to_stable_mode (solver);
}