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

177 lines
4.3 KiB
C

#include "analyze.h"
#include "backtrack.h"
#include "inline.h"
#include "propsearch.h"
#include "report.h"
#include "trail.h"
static inline void
unassign (kissat * solver, value * values, unsigned lit)
{
LOG ("unassign %s", LOGLIT (lit));
assert (values[lit] > 0);
const unsigned not_lit = NOT (lit);
values[lit] = values[not_lit] = 0;
assert (solver->unassigned < VARS);
solver->unassigned++;
}
static inline void
add_unassigned_variable_back_to_queue (kissat * solver,
links * links, unsigned lit)
{
assert (!solver->stable);
const unsigned idx = IDX (lit);
if (links[idx].stamp > solver->queue.search.stamp)
kissat_update_queue (solver, links, idx);
}
static inline void
add_unassigned_variable_back_to_heap (kissat * solver,
heap * scores, unsigned lit)
{
assert (solver->stable);
const unsigned idx = IDX (lit);
if (!kissat_heap_contains (scores, idx))
kissat_push_heap (solver, scores, idx);
}
static void
update_phases (kissat * solver)
{
const char type = solver->rephased.type;
const bool reset = (type && CONFLICTS > solver->rephased.last);
if (!solver->probing)
{
if (reset)
kissat_reset_target_assigned (solver);
if (solver->target_assigned < solver->consistently_assigned)
{
LOG ("updating target assigned from %u to %u",
solver->target_assigned, solver->consistently_assigned);
solver->target_assigned = solver->consistently_assigned;
kissat_save_target_phases (solver);
}
if (solver->best_assigned < solver->consistently_assigned)
{
LOG ("updating best assigned from %u to %u",
solver->best_assigned, solver->consistently_assigned);
solver->best_assigned = solver->consistently_assigned;
kissat_save_best_phases (solver);
}
kissat_reset_consistently_assigned (solver);
}
if (reset)
{
REPORT (0, type);
solver->rephased.type = 0;
}
}
void
kissat_backtrack (kissat * solver, unsigned new_level)
{
assert (solver->level >= new_level);
if (solver->level == new_level)
return;
update_phases (solver);
LOG ("backtracking to decision level %u", new_level);
frame *new_frame = &FRAME (new_level + 1);
const unsigned new_size = new_frame->trail;
SET_END_OF_STACK (solver->frames, new_frame);
value *values = solver->values;
unsigned *trail = BEGIN_STACK (solver->trail);
assigned *assigned = solver->assigned;
const unsigned old_size = SIZE_STACK (solver->trail);
unsigned unassigned = 0, reassigned = 0;
unsigned j = new_size;
if (solver->stable)
{
heap *scores = solver->heuristic==0?&solver->scores:&solver->scores_chb;
for (unsigned i = j; i != old_size; i++)
{
const unsigned lit = trail[i];
const unsigned idx = IDX (lit);
assert (idx < VARS);
const unsigned level = assigned[idx].level;
if (level <= new_level)
{
trail[j++] = lit;
LOG ("reassign %s", LOGLIT (lit));
reassigned++;
}
else
{
unassign (solver, values, lit);
add_unassigned_variable_back_to_heap (solver, scores, lit);
unassigned++;
}
}
}
else
{
links *links = solver->links;
for (unsigned i = j; i != old_size; i++)
{
const unsigned lit = trail[i];
const unsigned idx = IDX (lit);
assert (idx < VARS);
const unsigned level = assigned[idx].level;
if (level <= new_level)
{
trail[j++] = lit;
LOG ("reassign %s", LOGLIT (lit));
reassigned++;
}
else
{
unassign (solver, values, lit);
add_unassigned_variable_back_to_queue (solver, links, lit);
unassigned++;
}
}
}
RESIZE_STACK (solver->trail, j);
solver->level = new_level;
LOG ("unassigned %u literals", unassigned);
LOG ("reassigned %u literals", reassigned);
(void) unassigned, (void) reassigned;
assert (new_size <= SIZE_STACK (solver->trail));
LOG ("propagation will resume at trail position %u", new_size);
solver->propagated = new_size;
assert (!solver->extended);
}
void
kissat_backtrack_propagate_and_flush_trail (kissat * solver)
{
if (solver->level)
{
assert (solver->watching);
assert (solver->level > 0);
kissat_backtrack (solver, 0);
#ifndef NDEBUG
clause *conflict =
#endif
kissat_search_propagate (solver);
assert (!conflict);
}
else
assert (kissat_propagated (solver));
if (solver->unflushed)
kissat_flush_trail (solver);
}