177 lines
4.3 KiB
C
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);
|
|
}
|