24 if (!
solver->enabled.eliminate)
29 const uint64_t conflicts =
statistics->conflicts;
30 if (
solver->last.conflicts.reduce == conflicts)
43static inline double variable_score (
kissat *
solver,
unsigned idx) {
44 const unsigned lit =
LIT (idx);
45 const unsigned not_lit =
NOT (
lit);
53 double prod =
pos * neg;
54 double sum =
pos + neg;
55 double occlim2 = occlim * (double) occlim;
57 double score = prod - sum;
61 relevancy = kissat_get_heap_score (&
solver->scores, idx);
63 relevancy =
LINK (idx).stamp;
64 double res = relevancy + score - occlim2;
65 LOG (
"variable score of %s computed as "
66 "%g = %g + (%zu*%zu - %zu - %zu) - %g"
68 LOGVAR (idx), res, relevancy,
pos, neg,
pos, neg, occlim2, relevancy,
77 double new_score = variable_score (
solver, idx);
78 LOG (
"new score %g for variable %s", new_score, LOGVAR (idx));
79 kissat_update_heap (
solver, schedule, idx, -new_score);
86static inline void update_after_adding_stack (
kissat *
solver,
96static inline void update_after_removing_variable (
kissat *
solver,
106 update_variable_score (
solver, schedule, idx);
107 if (!kissat_heap_contains (schedule, idx))
108 kissat_push_heap (
solver, schedule, idx);
113 if (!
solver->schedule.size)
123 kissat_disconnect_binary (
solver, other,
lit);
125 update_after_removing_variable (
solver,
IDX (other));
130 update_after_removing_clause (
solver, c,
lit);
134 LOG (
"initializing variable schedule");
141 size_t scheduled = 0;
148 LOG (
"scheduling %s", LOGVAR (idx));
150 update_after_removing_variable (
solver, idx);
154 size_t active =
solver->active;
156 "scheduled %zu variables %.0f%%", scheduled,
157 kissat_percent (scheduled, active));
163 const unsigned *propagate =
solver->propagate;
166 const size_t units = end_trail - propagate;
170 LOG (
"propagating and flushing %zu units", units);
174 LOG (
"marking and flushing unit satisfied clauses");
177 while (propagate != end_trail) {
178 const unsigned unit = *propagate++;
184 LOG (
"marking %s satisfied clauses as garbage",
LOGLIT (unit));
189 if (!
solver->values[other])
190 update_after_removing_variable (
solver,
IDX (other));
201 size_t flushed = end - q;
204 LOG (
"flushing %zu references satisfied by %s", flushed,
LOGLIT (unit));
212 bool satisfied =
false;
221 LOGTMP (
"temporary resolvent");
225 LOG (
"resolved empty clause");
228 solver->inconsistent =
true;
230 }
else if (size == 1) {
232 LOG (
"resolved unit clause %s",
LOGLIT (unit));
244 }
else if (!satisfied) {
249 }
else if (
value < 0)
250 LOG2 (
"dropping now falsified literal %s",
LOGLIT (other));
255 LOG (
"added %" PRIu64
" new clauses", added);
260 const unsigned not_lit =
NOT (
lit);
279 bool satisfied =
false;
302 if (!optimize &&
value <= 0)
310 bool satisfied =
false;
318 if (!optimize && !satisfied)
331static void try_to_eliminate_all_variables_again (
kissat *
solver) {
332 LOG (
"trying to elimination all variables again");
338 solver->limits.eliminate.variables.eliminate = 0;
341static void set_next_elimination_bound (
kissat *
solver,
bool complete) {
342 const unsigned max_bound =
GET_OPTION (eliminatebound);
343 const unsigned current_bound =
344 solver->bounds.eliminate.additional_clauses;
348 if (current_bound == max_bound) {
350 "completed maximum elimination bound %u",
358 bool first = !
solver->bounds.eliminate.max_bound_completed++;
359 REPORT (!first, first ?
'!' :
':');
362 const unsigned next_bound =
363 !current_bound ? 1 :
MIN (2 * current_bound, max_bound);
365 "completed elimination bound %u next %u", current_bound,
367 solver->bounds.eliminate.additional_clauses = next_bound;
368 try_to_eliminate_all_variables_again (
solver);
373 "incomplete elimination bound %u", current_bound);
376static bool can_eliminate_variable (
kissat *
solver,
unsigned idx) {
387static bool eliminate_variable (
kissat *
solver,
unsigned idx) {
388 LOG (
"next elimination candidate %s", LOGVAR (idx));
391 (void) variable_score (
solver, idx);
397 LOG (
"marking %s as not removed", LOGVAR (idx));
398 FLAGS (idx)->eliminate =
false;
403 connect_resolvents (
solver);
404 if (!
solver->inconsistent)
408 if (
solver->gate_eliminated) {
409 INC (gates_eliminated);
412 *
solver->gate_eliminated += 1;
420 "trying to eliminate variables with bound %u",
421 solver->bounds.eliminate.additional_clauses);
424 unsigned before =
solver->active;
425 unsigned eliminated = 0;
428 unsigned last_round_eliminated = 0;
439 LOG (
"starting new elimination round %d", round);
442 unsigned *propagate =
solver->propagate;
448 solver->propagate = propagate;
458 const unsigned last_round_scheduled =
460 schedule_variables (
solver);
463 "scheduled %u variables %.0f%% to eliminate "
465 last_round_scheduled,
466 kissat_percent (last_round_scheduled,
solver->active), round);
468 unsigned last_round_eliminated = 0;
470 while (!
solver->inconsistent &&
471 !kissat_empty_heap (&
solver->schedule)) {
476 unsigned idx = kissat_pop_max_heap (
solver, &
solver->schedule);
477 if (!can_eliminate_variable (
solver, idx))
480 if (s->eliminate_resolutions > resolution_limit) {
483 "eliminate round %u hits "
484 "resolution limit %" PRIu64
" at %" PRIu64
" resolutions",
485 round, resolution_limit, s->eliminate_resolutions);
492 if (eliminate_variable (
solver, idx))
493 last_round_eliminated++;
499 if (last_round_eliminated) {
502 eliminated += last_round_eliminated;
506 if (!
solver->inconsistent) {
513 "eliminated %u variables %.0f%% in round %u", last_round_eliminated,
514 kissat_percent (last_round_eliminated, last_round_scheduled),
516 REPORT (!last_round_eliminated,
'e');
525 if (
solver->statistics_.eliminate_resolutions > resolution_limit)
531 const unsigned remain = kissat_size_heap (&
solver->schedule);
535 "eliminated %u variables %.0f%% of %" PRIu64
" tried"
536 " (%u remain %.0f%%)",
537 eliminated, kissat_percent (eliminated, tried),
539 kissat_percent (remain,
solver->active));
541 "eliminated %u variables %.0f%% out of %u in %d rounds",
542 eliminated, kissat_percent (eliminated, before), before,
545 if (!
solver->inconsistent) {
546 const bool complete = !remain && !last_round_eliminated;
547 set_next_elimination_bound (
solver, complete);
551 unsigned dropped = 0;
553 for (
struct flags *f =
solver->flags; f != end; f++)
586 "elimination limit of %" PRIu64
" conflicts hit",
587 solver->limits.eliminate.conflicts);
588 init_map_and_kitten (
solver);
590 eliminate_variables (
solver);
592 reset_map_and_kitten (
solver);
603 solver->last.ticks.eliminate =
solver->statistics_.search_ticks;
604 return solver->inconsistent ? 20 : 0;
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void kissat_learned_unit(kissat *solver, unsigned lit)
void kissat_backtrack_propagate_and_flush_trail(kissat *solver)
#define all_stack(T, E, S)
ABC_NAMESPACE_IMPL_START typedef signed char value
#define CHECK_AND_ADD_EMPTY(...)
ABC_NAMESPACE_IMPL_START void kissat_classify(struct kissat *solver)
reference kissat_new_irredundant_clause(kissat *solver)
void kissat_mark_clause_as_garbage(kissat *solver, clause *c)
void kissat_delete_binary(kissat *solver, unsigned a, unsigned b)
void kissat_dense_collect(kissat *solver)
void kissat_enter_dense_mode(kissat *solver, litpairs *irredundant)
void kissat_resume_sparse_mode(kissat *solver, bool flush_eliminated, litpairs *irredundant)
void kissat_flush_units_while_connected(kissat *solver)
void kissat_eliminate_clause(kissat *solver, clause *c, unsigned lit)
ABC_NAMESPACE_IMPL_START bool kissat_eliminating(kissat *solver)
void kissat_update_variable_score(kissat *solver, unsigned idx)
void kissat_eliminate_binary(kissat *solver, unsigned lit, unsigned other)
int kissat_eliminate(kissat *solver)
void kissat_mark_eliminated_variable(kissat *solver, unsigned idx)
bool kissat_forward_subsume_during_elimination(kissat *solver)
ABC_NAMESPACE_IMPL_START void kissat_release_heap(kissat *solver, heap *heap)
void kissat_resize_heap(kissat *solver, heap *heap, unsigned new_size)
#define all_variables(IDX)
#define UPDATE_CONFLICT_LIMIT(NAME, COUNT, SCALE_COUNT_FUNCTION, SCALE_DELTA)
#define all_literals_in_clause(LIT, C)
#define KISSAT_assert(ignore)
kitten * kitten_embedded(struct kissat *kissat)
void kitten_release(kitten *kitten)
#define SET_EFFORT_LIMIT(LIMIT, NAME, THRESHHOLD)
#define kissat_extremely_verbose(...)
#define kissat_very_verbose(...)
#define kissat_phase(...)
#define STOP_SEARCH_AND_START_SIMPLIFIER(...)
#define STOP_SIMPLIFIER_AND_RESUME_SEARCH(...)
#define ADD_EMPTY_TO_PROOF(...)
bool kissat_dense_propagate(kissat *solver)
ABC_NAMESPACE_HEADER_START typedef unsigned reference
bool kissat_generate_resolvents(kissat *solver, unsigned idx, unsigned *lit_ptr)
#define kissat_check_statistics(...)
#define eliminate_terminated_2
#define eliminate_terminated_1
void kissat_connect_irredundant_large_clauses(kissat *solver)
void kissat_flush_large_connected(kissat *solver)
#define BEGIN_WATCHES(WS)
#define RELEASE_WATCHES(WS)
#define SET_END_OF_WATCHES(WS, P)
#define all_binary_large_watches(WATCH, WATCHES)
void kissat_weaken_binary(kissat *solver, unsigned lit, unsigned other)
void kissat_weaken_clause(kissat *solver, unsigned lit, clause *c)
void kissat_weaken_unit(kissat *solver, unsigned lit)