214 lines
5.6 KiB
C
214 lines
5.6 KiB
C
#include "bump.h"
|
|
#include "internal.h"
|
|
#include "logging.h"
|
|
#include "print.h"
|
|
#include "rank.h"
|
|
#include "sort.h"
|
|
|
|
static inline unsigned
|
|
rank_of_idxrank (idxrank ir)
|
|
{
|
|
return ir.rank;
|
|
}
|
|
|
|
static inline bool
|
|
smaller_idxrank (idxrank ir, idxrank jr)
|
|
{
|
|
return ir.rank < jr.rank;
|
|
}
|
|
|
|
#define RADIX_SORT_BUMP_LIMIT 800
|
|
#define RADIX_SORT_BUMP_LENGTH 8
|
|
|
|
static void
|
|
sort_bump (kissat * solver)
|
|
{
|
|
const size_t size = SIZE_STACK (solver->analyzed);
|
|
if (size < RADIX_SORT_BUMP_LIMIT)
|
|
{
|
|
LOG ("quick sorting %zu analyzed variables", size);
|
|
SORT_STACK (idxrank, solver->bump, smaller_idxrank);
|
|
}
|
|
else
|
|
{
|
|
LOG ("radix sorting %zu analyzed variables", size);
|
|
RADIX_STACK (RADIX_SORT_BUMP_LENGTH, idxrank,
|
|
unsigned, solver->bump, rank_of_idxrank);
|
|
}
|
|
}
|
|
|
|
static void
|
|
rescale_scores (kissat * solver, heap * scores)
|
|
{
|
|
INC (rescaled);
|
|
const double max_score = kissat_max_score_on_heap (scores);
|
|
kissat_phase (solver, "rescale", GET (rescaled),
|
|
"maximum score %g increment %g", max_score, solver->scinc);
|
|
const double rescale = MAX (max_score, solver->scinc);
|
|
assert (rescale > 0);
|
|
const double factor = 1.0 / rescale;
|
|
kissat_rescale_heap (solver, scores, factor);
|
|
solver->scinc *= factor;
|
|
kissat_phase (solver, "rescale",
|
|
GET (rescaled), "rescaled by factor %g", factor);
|
|
}
|
|
|
|
void kissat_init_shuffle(kissat * solver, int maxvar) {
|
|
int seed = GET_OPTION(order_reset);
|
|
if (seed != -1)
|
|
{
|
|
// printf("c init shuffle %d\n", seed);
|
|
int *id;
|
|
id = (int *)malloc(sizeof(int) * (maxvar + 1));
|
|
for (int i = 1; i <= maxvar; i++)
|
|
id[i] = i;
|
|
for (int i = 1; i <= maxvar; i++)
|
|
{
|
|
int j = (rand_r(&seed) % maxvar) + 1;
|
|
int x = id[i];
|
|
id[i] = id[j];
|
|
id[j] = x;
|
|
}
|
|
for (int i = 1; i <= maxvar; i++)
|
|
kissat_activate_literal(solver, kissat_import_literal(solver, id[i]));
|
|
free(id);
|
|
}
|
|
else
|
|
{
|
|
for (int i = 1; i <= maxvar; i++)
|
|
kissat_import_literal(solver, i);
|
|
}
|
|
}
|
|
|
|
void kissat_shuffle_score(kissat * solver) {
|
|
heap *scores = &solver->scores;
|
|
heap *scores_chb = &solver->scores_chb;
|
|
flags *flags = solver->flags;
|
|
int *id = (int *)malloc(sizeof(int) * (VARS));
|
|
for (int i = 0; i < VARS; i++) id[i] = i;
|
|
for (int i = 0; i < VARS; i++)
|
|
{
|
|
int j = (rand() % VARS);
|
|
int x = id[i];
|
|
id[i] = id[j];
|
|
id[j] = x;
|
|
}
|
|
for (int i = 0; i < VARS; i++) {
|
|
int idx = id[i];
|
|
if (flags[idx].active) {
|
|
double new_score = 1.0 * i / VARS;
|
|
kissat_update_heap (solver, scores, idx, new_score);
|
|
kissat_update_heap (solver, scores_chb, idx, new_score);
|
|
}
|
|
}
|
|
for (int i = 0; i < VARS; i++) {
|
|
int idx = id[i];
|
|
if (flags[idx].active)
|
|
kissat_move_to_front(solver, idx);
|
|
}
|
|
solver->scinc = 1.0;
|
|
free(id);
|
|
}
|
|
|
|
static void
|
|
bump_score_increment (kissat * solver, heap * scores)
|
|
{
|
|
const double old_scinc = solver->scinc;
|
|
const double decay = GET_OPTION (decay) * 1e-3;
|
|
assert (0 <= decay), assert (decay <= 0.5);
|
|
const double factor = 1.0 / (1.0 - decay);
|
|
const double new_scinc = old_scinc * factor;
|
|
LOG ("new score increment %g = %g * %g", new_scinc, factor, old_scinc);
|
|
solver->scinc = new_scinc;
|
|
if (new_scinc > MAX_SCORE)
|
|
rescale_scores (solver, scores);
|
|
}
|
|
|
|
static inline void
|
|
bump_variable_score (kissat * solver, heap * scores, unsigned idx)
|
|
{
|
|
const double old_score = kissat_get_heap_score (scores, idx);
|
|
const double new_score = old_score + solver->scinc;
|
|
LOG ("new score[%u] = %g = %g + %g",
|
|
idx, new_score, old_score, solver->scinc);
|
|
kissat_update_heap (solver, scores, idx, new_score);
|
|
if (new_score > MAX_SCORE)
|
|
rescale_scores (solver, scores);
|
|
}
|
|
|
|
static void
|
|
bump_analyzed_variable_scores (kissat * solver)
|
|
{
|
|
heap *scores = &solver->scores;
|
|
flags *flags = solver->flags;
|
|
|
|
for (all_stack (unsigned, idx, solver->analyzed))
|
|
if (flags[idx].active)
|
|
bump_variable_score (solver, scores, idx);
|
|
|
|
bump_score_increment (solver, scores);
|
|
}
|
|
|
|
static void
|
|
move_analyzed_variables_to_front_of_queue (kissat * solver)
|
|
{
|
|
assert (EMPTY_STACK (solver->bump));
|
|
const links *links = solver->links;
|
|
for (all_stack (unsigned, idx, solver->analyzed))
|
|
{
|
|
// *INDENT-OFF*
|
|
const idxrank idxrank = { .idx = idx, .rank = links[idx].stamp };
|
|
// *INDENT-ON*
|
|
PUSH_STACK (solver->bump, idxrank);
|
|
}
|
|
|
|
sort_bump (solver);
|
|
|
|
flags *flags = solver->flags;
|
|
unsigned idx;
|
|
|
|
for (all_stack (idxrank, idxrank, solver->bump))
|
|
if (flags[idx = idxrank.idx].active)
|
|
kissat_move_to_front (solver, idx);
|
|
|
|
CLEAR_STACK (solver->bump);
|
|
}
|
|
|
|
void
|
|
kissat_bump_variables (kissat * solver)
|
|
{
|
|
START (bump);
|
|
assert (!solver->probing);
|
|
if (solver->stable)
|
|
bump_analyzed_variable_scores (solver);
|
|
else
|
|
move_analyzed_variables_to_front_of_queue (solver);
|
|
STOP (bump);
|
|
}
|
|
|
|
// CHB
|
|
|
|
void kissat_bump_chb(kissat * solver, unsigned v, double multiplier) {
|
|
int64_t age = solver->statistics.conflicts - solver->conflicted_chb[v] + 1;
|
|
double reward_chb = multiplier / age;
|
|
double old_score = kissat_get_heap_score (&solver->scores_chb, v);
|
|
double new_score = solver->step_chb * reward_chb + (1 - solver->step_chb) * old_score;
|
|
LOG ("new score[%u] = %g vs %g",
|
|
v, new_score, old_score);
|
|
kissat_update_heap (solver, &solver->scores_chb, v, new_score);
|
|
}
|
|
|
|
void kissat_decay_chb(kissat * solver){
|
|
if (solver->step_chb > solver->step_min_chb) solver->step_chb -= solver->step_dec_chb;
|
|
}
|
|
|
|
void
|
|
kissat_update_conflicted_chb (kissat * solver)
|
|
{
|
|
flags *flags = solver->flags;
|
|
|
|
for (all_stack (unsigned, idx, solver->analyzed))
|
|
if (flags[idx].active)
|
|
solver->conflicted_chb[idx]=solver->statistics.conflicts;
|
|
}
|