#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; }