2023-03-26 19:15:17 +08:00

244 lines
5.4 KiB
C

#include "internal.h"
#include "logging.h"
#include "print.h"
#include "reduce.h"
#include "resources.h"
#include "restart.h"
#include <inttypes.h>
#include <math.h>
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);
}