#include "internal.h" #include "logging.h" #include "print.h" #include "reduce.h" #include "resources.h" #include "restart.h" #include #include changes kissat_changes (kissat * solver) { changes res; res.variables.units = solver->statistics.units; res.variables.added = solver->statistics.variables_added; res.variables.removed = solver->statistics.variables_removed; res.eliminate.additional_clauses = solver->bounds.eliminate.additional_clauses; return res; } bool kissat_changed (changes b, changes a) { if (a.variables.added != b.variables.added) return true; if (a.variables.units != b.variables.units) return true; if (a.variables.removed != b.variables.removed) return true; if (a.eliminate.additional_clauses != b.eliminate.additional_clauses) return true; return false; } uint64_t kissat_logn (uint64_t count) { return log10 (count + 10); } static uint64_t kissat_lognlogn (uint64_t count) { const double tmp = log10 (count + 10); return tmp * tmp; } uint64_t kissat_ndivlogn (uint64_t count) { return count / kissat_logn (count); } uint64_t kissat_linear (uint64_t count) { return count; } uint64_t kissat_nlogn (uint64_t count) { return count * kissat_logn (count); } uint64_t kissat_nlognlogn (uint64_t count) { return count * kissat_lognlogn (count); } uint64_t kissat_quadratic (uint64_t count) { return count * count; } uint64_t kissat_scale_delta (kissat * solver, const char *pretty, uint64_t delta) { const uint64_t C = IRREDUNDANT_CLAUSES; const double f = kissat_logn (C); assert (f >= 1); const double ff = f * f; assert (ff >= 1); uint64_t scaled = ff * delta; assert (delta <= scaled); // *INDENT-OFF* kissat_very_verbose (solver, "scaled %s delta %" PRIu64 " = %g * %" PRIu64 " = %g^2 * %" PRIu64 " = log10^2(" PRIu64 ") * %" PRIu64, pretty, scaled, ff, delta, f, delta, C, delta); // *INDENT-ON* (void) pretty; return scaled; } uint64_t kissat_scale_limit (kissat * solver, const char *pretty, uint64_t count, int base) { assert (base >= 0); assert (count > 0); const double f = kissat_logn (count - 1); assert (f >= 1); uint64_t scaled = f * base; kissat_very_verbose (solver, "scaled %s limit %" PRIu64 " = " "log10 (%" PRIu64 ") * %d = %g * %d", pretty, scaled, count, base, f, base); (void) solver; (void) pretty; return scaled; } static void init_enabled (kissat * solver) { bool probe; if (!GET_OPTION (simplify)) probe = false; else if (!GET_OPTION (probe)) probe = false; else if (GET_OPTION (substitute)) probe = true; else if (GET_OPTION (failed)) probe = true; else if (GET_OPTION (transitive)) probe = true; else if (GET_OPTION (vivify)) probe = true; else probe = false; kissat_very_verbose (solver, "probing %sabled", probe ? "en" : "dis"); solver->enabled.probe = probe; bool eliminate; if (!GET_OPTION (simplify)) eliminate = false; else if (!GET_OPTION (eliminate)) eliminate = false; else eliminate = true; kissat_very_verbose (solver, "eliminate %sabled", eliminate ? "en" : "dis"); solver->enabled.eliminate = eliminate; bool autarky; if (!GET_OPTION (simplify)) autarky = false; else if (!GET_OPTION (autarky)) autarky = false; else autarky = true; kissat_very_verbose (solver, "autarky %sabled", autarky ? "en" : "dis"); solver->enabled.autarky = autarky; } static void init_mode_limit (kissat * solver) { limits *limits = &solver->limits; if (GET_OPTION (stable) == 1) { assert (!solver->stable); const uint64_t delta = GET_OPTION (modeinit); const uint64_t limit = CONFLICTS + delta; limits->mode.conflicts = limit; kissat_very_verbose (solver, "initial stable mode switching limit " "at %s conflicts", FORMAT_COUNT (limit)); solver->mode.ticks = solver->statistics.search_ticks; #ifndef QUIET solver->mode.conflicts = CONFLICTS; #ifndef NMETRICS solver->mode.propagations = solver->statistics.search_propagations; #endif // *INDENT-OFF* solver->mode.entered = kissat_process_time (); kissat_very_verbose (solver, "starting focused mode at %.2f seconds " "(%" PRIu64 " conflicts, %" PRIu64 " ticks" #ifndef NMETRICS ", %" PRIu64 " propagations, %" PRIu64 " visits" #endif ")", solver->mode.entered, solver->mode.conflicts, solver->mode.ticks #ifndef NMETRICS , solver->mode.propagations, solver->mode.visits #endif ); // *INDENT-ON* #endif } else kissat_very_verbose (solver, "no need to set mode limit (only %s mode enabled)", GET_OPTION (stable) ? "stable" : "focused"); } static void common_limits (kissat * solver) { init_mode_limit (solver); if (solver->enabled.eliminate) { solver->bounds.eliminate.max_bound_completed = 0; solver->bounds.eliminate.additional_clauses = 0; kissat_very_verbose (solver, "reset elimination bound to zero"); } } void kissat_init_limits (kissat * solver) { assert (solver->statistics.searches == 1); init_enabled (solver); limits *limits = &solver->limits; if (GET_OPTION (reduce)) INIT_CONFLICT_LIMIT (reduce, false); if (GET_OPTION (rephase)) INIT_CONFLICT_LIMIT (rephase, false); if (!solver->stable) kissat_new_focused_restart_limit (solver); common_limits (solver); if (solver->enabled.eliminate) INIT_CONFLICT_LIMIT (eliminate, true); if (solver->enabled.probe) INIT_CONFLICT_LIMIT (probe, true); }