#include "inline.h" #include "print.h" #include "reluctant.h" #include "rephase.h" #include "report.h" #include "restart.h" #include "resources.h" #include 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); }