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

152 lines
3.6 KiB
C

#define INLINE_SORT
#include "inline.h"
#include "sort.c"
void
kissat_remove_blocking_watch (kissat * solver,
watches * watches, reference ref)
{
assert (solver->watching);
watch *begin = BEGIN_WATCHES (*watches);
watch *end = END_WATCHES (*watches);
watch *q = begin;
const watch *p = q;
#ifndef NDEBUG
bool found = false;
#endif
while (p != end)
{
const watch head = *q++ = *p++;
if (head.type.binary)
continue;
const watch tail = *q++ = *p++;
if (tail.raw != ref)
continue;
#ifndef NDEBUG
assert (!found);
found = true;
#endif
q -= 2;
}
assert (found);
watches->size -= 2;
const watch empty = {.raw = INVALID_VECTOR_ELEMENT };
end[-2] = end[-1] = empty;
assert (solver->vectors.usable < MAX_SECTOR - 2);
solver->vectors.usable += 2;
kissat_check_vectors (solver);
}
void
kissat_flush_large_watches (kissat * solver)
{
assert (solver->watching);
LOG ("flush large clause watches");
watches *all_watches = solver->watches;
for (all_literals (lit))
{
watches *lit_watches = all_watches + lit;
watch *begin = BEGIN_WATCHES (*lit_watches), *q = begin;
const watch *end = END_WATCHES (*lit_watches), *p = q;
while (p != end)
if (!(*q++ = *p++).type.binary)
q--;
SET_END_OF_WATCHES (*lit_watches, q);
}
}
void
kissat_watch_large_clauses (kissat * solver)
{
LOG ("watching all large clauses");
assert (solver->watching);
const value *values = solver->values;
const assigned *assigned = solver->assigned;
watches *watches = solver->watches;
const word *arena = BEGIN_STACK (solver->arena);
for (all_clauses (c))
{
if (c->garbage)
continue;
unsigned *lits = c->lits;
kissat_sort_literals (solver, values, assigned, c->size, lits);
c->searched = 2;
const reference ref = (word *) c - arena;
const unsigned l0 = lits[0];
const unsigned l1 = lits[1];
kissat_push_blocking_watch (solver, watches + l0, l1, ref);
kissat_push_blocking_watch (solver, watches + l1, l0, ref);
}
}
void
kissat_connect_irredundant_large_clauses (kissat * solver)
{
assert (!solver->watching);
LOG ("connecting all large irredundant clauses");
clause *last_irredundant = kissat_last_irredundant_clause (solver);
const value *values = solver->values;
watches *all_watches = solver->watches;
const word *arena = BEGIN_STACK (solver->arena);
for (all_clauses (c))
{
if (last_irredundant && c > last_irredundant)
break;
if (c->redundant)
continue;
if (c->garbage)
continue;
bool satisfied = false;
assert (!solver->level);
for (all_literals_in_clause (lit, c))
{
const value value = values[lit];
if (value <= 0)
continue;
satisfied = true;
break;
}
if (satisfied)
{
kissat_mark_clause_as_garbage (solver, c);
continue;
}
const reference ref = (word *) c - arena;
kissat_inlined_connect_clause (solver, all_watches, c, ref);
}
}
void
kissat_flush_large_connected (kissat * solver)
{
assert (!solver->watching);
LOG ("flushing large connected clause references");
size_t flushed = 0;
for (all_literals (lit))
{
watches *watches = &WATCHES (lit);
watch *begin = BEGIN_WATCHES (*watches), *q = begin;
const watch *end_watches = END_WATCHES (*watches), *p = q;
while (p != end_watches)
{
const watch head = *p++;
if (head.type.binary)
*q++ = head;
else
flushed++;
}
SET_END_OF_WATCHES (*watches, q);
}
LOG ("flushed %zu large clause references", flushed);
(void) flushed;
}