162 lines
4.1 KiB
C
162 lines
4.1 KiB
C
#define INLINE_ASSIGN
|
|
|
|
#include "inline.h"
|
|
#include "dominate.h"
|
|
#include "prophyper.h"
|
|
|
|
// Keep this 'inlined' file separate:
|
|
|
|
#include "assign.c"
|
|
|
|
static inline void
|
|
watch_hyper_delayed (kissat * solver, unsigneds * delayed)
|
|
{
|
|
const unsigned *end_delayed = END_STACK (*delayed);
|
|
const unsigned *d = BEGIN_STACK (*delayed);
|
|
watches *all_watches = solver->watches;
|
|
while (d != end_delayed)
|
|
{
|
|
const unsigned lit = *d++;
|
|
assert (d != end_delayed);
|
|
const watch watch = {.raw = *d++ };
|
|
watches *lit_watches = all_watches + lit;
|
|
if (watch.type.binary)
|
|
{
|
|
assert (solver->probing);
|
|
assert (watch.binary.hyper);
|
|
assert (watch.binary.redundant);
|
|
LOGBINARY (lit, watch.binary.lit,
|
|
"watching blocking %s in %s",
|
|
LOGLIT (lit), LOGLIT (watch.binary.lit));
|
|
assert (lit < LITS);
|
|
PUSH_WATCHES (*lit_watches, watch);
|
|
}
|
|
else
|
|
{
|
|
assert (d != end_delayed);
|
|
const reference ref = *d++;
|
|
const unsigned blocking = watch.blocking.lit;
|
|
LOGREF (ref, "watching %s blocking %s in", LOGLIT (lit),
|
|
LOGLIT (blocking));
|
|
kissat_push_blocking_watch (solver, lit_watches, blocking, ref);
|
|
}
|
|
}
|
|
CLEAR_STACK (*delayed);
|
|
}
|
|
|
|
static inline void
|
|
delay_watching_hyper (kissat * solver, unsigneds * delayed,
|
|
unsigned lit, unsigned other)
|
|
{
|
|
const watch watch = kissat_binary_watch (other, true, true);
|
|
PUSH_STACK (*delayed, lit);
|
|
PUSH_STACK (*delayed, watch.raw);
|
|
}
|
|
|
|
#define HYPER_PROPAGATION
|
|
#define PROPAGATE_LITERAL large_propagate_literal
|
|
#define PROPAGATION_TYPE "large"
|
|
|
|
#include "proplit.h"
|
|
|
|
static inline clause *
|
|
binary_propagate_literal (kissat * solver, unsigned lit)
|
|
{
|
|
assert (solver->probing);
|
|
assert (solver->watching);
|
|
assert (solver->level == 1);
|
|
|
|
LOG ("binary propagating %s", LOGLIT (lit));
|
|
assert (VALUE (lit) > 0);
|
|
const unsigned not_lit = NOT (lit);
|
|
|
|
watches *watches = &WATCHES (not_lit);
|
|
value *values = solver->values;
|
|
assigned *assigned = solver->assigned;
|
|
|
|
const watch *begin = BEGIN_WATCHES (*watches);
|
|
const watch *end = END_WATCHES (*watches);
|
|
const watch *p = begin;
|
|
int ticks = kissat_cache_lines (watches->size, sizeof (watch));
|
|
solver->dps_ticks +=ticks;
|
|
if (solver->dps == 1 && solver->dps_ticks >= solver->dps_period) {
|
|
solver->dps_ticks -= solver->dps_period;
|
|
solver->cbk_start_new_period(solver->issuer);
|
|
}
|
|
|
|
clause *res = 0;
|
|
|
|
while (p != end)
|
|
{
|
|
watch head = *p++;
|
|
if (!head.type.binary)
|
|
{
|
|
p++;
|
|
continue;
|
|
}
|
|
const unsigned other = head.binary.lit;
|
|
assert (VALID_INTERNAL_LITERAL (other));
|
|
const value other_value = values[other];
|
|
if (other_value > 0)
|
|
continue;
|
|
const bool redundant = head.binary.redundant;
|
|
if (other_value < 0)
|
|
{
|
|
res = kissat_binary_conflict (solver, redundant, not_lit, other);
|
|
break;
|
|
}
|
|
assert (!other_value);
|
|
kissat_assign_binary (solver, values, assigned, redundant, other,
|
|
not_lit);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static inline clause *
|
|
hyper_propagate (kissat * solver, const clause * ignore)
|
|
{
|
|
assert (solver->probing);
|
|
assert (solver->watching);
|
|
assert (solver->level == 1);
|
|
clause *res = 0;
|
|
unsigned binary_propagated = solver->propagated;
|
|
while (!res && solver->propagated < SIZE_STACK (solver->trail))
|
|
{
|
|
assert (solver->propagated <= binary_propagated);
|
|
if (binary_propagated < SIZE_STACK (solver->trail))
|
|
{
|
|
const unsigned lit = PEEK_STACK (solver->trail, binary_propagated);
|
|
res = binary_propagate_literal (solver, lit);
|
|
binary_propagated++;
|
|
}
|
|
else
|
|
{
|
|
const unsigned lit = PEEK_STACK (solver->trail, solver->propagated);
|
|
res = large_propagate_literal (solver, ignore, lit);
|
|
solver->propagated++;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
clause *
|
|
kissat_hyper_propagate (kissat * solver, const clause * ignore)
|
|
{
|
|
assert (solver->probing);
|
|
assert (solver->watching);
|
|
assert (!solver->inconsistent);
|
|
assert (solver->level == 1);
|
|
assert (!solver->unflushed);
|
|
|
|
START (propagate);
|
|
|
|
solver->ticks = 0;
|
|
const unsigned propagated = solver->propagated;
|
|
clause *conflict = hyper_propagate (solver, ignore);
|
|
kissat_update_probing_propagation_statistics (solver, propagated);
|
|
|
|
STOP (propagate);
|
|
|
|
return conflict;
|
|
}
|