152 lines
3.6 KiB
C
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;
|
|
}
|