22 const unsigned not_lit =
NOT (
lit);
30static void transitive_backtrack (
kissat *
solver,
unsigned *saved) {
36 while (end_trail != saved) {
37 const unsigned lit = *--end_trail;
39 const unsigned not_lit =
NOT (
lit);
42 values[
lit] = values[not_lit] = 0;
60 while (
p != end_watches) {
61 const watch head = *q++ = *
p++;
71 while (r != end_large)
79static bool transitive_reduce (
kissat *
solver,
unsigned src, uint64_t limit,
80 uint64_t *reduced_ptr,
unsigned *units) {
83 LOG (
"transitive reduce %s",
LOGLIT (src));
85 watches *src_watches = all_watches + src;
88 const size_t size_src_watches =
SIZE_WATCHES (*src_watches);
89 const unsigned src_ticks =
90 1 + kissat_cache_lines (size_src_watches,
sizeof (
watch));
91 ADD (transitive_ticks, src_ticks);
92 ADD (probing_ticks, src_ticks);
93 ADD (ticks, src_ticks);
94 INC (transitive_probes);
95 const unsigned not_src =
NOT (src);
98 for (
watch *
p = begin_src;
p != end_src;
p++) {
99 const watch src_watch = *
p;
102 const unsigned dst = src_watch.
binary.
lit;
108 unsigned *saved =
solver->propagate;
111 transitive_assign (
solver, not_src);
112 bool transitive =
false;
113 unsigned inner_ticks = 0;
114 unsigned *propagate =
solver->propagate;
115 while (!transitive && !failed &&
117 const unsigned lit = *propagate++;
120 const unsigned not_lit =
NOT (
lit);
121 watches *lit_watches = all_watches + not_lit;
124 const size_t size_lit_watches =
SIZE_WATCHES (*lit_watches);
126 1 + kissat_cache_lines (size_lit_watches,
sizeof (
watch));
127 for (
const watch *q = begin_lit; q != end_lit; q++) {
130 const watch lit_watch = *q;
135 const unsigned other = lit_watch.
binary.
lit;
142 LOG (
"both %s and %s reachable from %s",
LOGLIT (
NOT (other)),
148 transitive_assign (
solver, other);
155 const unsigned propagated = propagate -
solver->propagate;
157 ADD (transitive_propagations, propagated);
158 ADD (probing_propagations, propagated);
159 ADD (propagations, propagated);
161 ADD (transitive_ticks, inner_ticks);
162 ADD (probing_ticks, inner_ticks);
163 ADD (ticks, inner_ticks);
165 transitive_backtrack (
solver, saved);
168 LOGBINARY (src, dst,
"transitive reduce");
169 INC (transitive_reduced);
170 watches *dst_watches = all_watches + dst;
171 watch dst_watch = src_watch;
183 if (
solver->statistics_.transitive_ticks > limit)
190 *reduced_ptr += reduced;
193 watch *q = begin_src;
194 for (
const watch *
p = begin_src;
p != end_src;
p++) {
195 const watch src_watch = *q++ = *
p;
208 LOG (
"transitive failed literal %s",
LOGLIT (not_src));
209 INC (transitive_units);
222static inline bool less_stable_transitive (
kissat *
solver,
229 const unsigned i =
IDX (a);
230 const unsigned j =
IDX (b);
237 const double s = kissat_get_heap_score (
scores, i);
238 const double t = kissat_get_heap_score (
scores, j);
246static inline unsigned less_focused_transitive (
kissat *
solver,
249 unsigned a,
unsigned b) {
253 const unsigned i =
IDX (a);
254 const unsigned j =
IDX (b);
266#define LESS_STABLE_PROBE(A, B) \
267 less_stable_transitive (solver, flags, scores, (A), (B))
269#define LESS_FOCUSED_PROBE(A, B) \
270 less_focused_transitive (solver, flags, links, (A), (B))
272static void sort_stable_transitive (
kissat *
solver, unsigneds *probes) {
278static void sort_focused_transitive (
kissat *
solver, unsigneds *probes) {
284static void sort_transitive (
kissat *
solver, unsigneds *probes) {
286 sort_stable_transitive (
solver, probes);
288 sort_focused_transitive (
solver, probes);
291static void schedule_transitive (
kissat *
solver, unsigneds *probes) {
296 sort_transitive (
solver, probes);
312 INC (transitive_reductions);
313#if !defined(KISSAT_NDEBUG) || defined(METRICS)
315 solver->transitive_reducing =
true;
317 prioritize_binaries (
solver);
318 bool success =
false;
319 uint64_t reduced = 0;
325 const unsigned active =
solver->active;
326 const uint64_t old_ticks =
solver->statistics_.transitive_ticks;
328 solver,
"starting with %" PRIu64
" transitive ticks", old_ticks);
333 schedule_transitive (
solver, &probes);
334 bool terminate =
false;
337 solver->flags[idx].transitive =
false;
340 for (
unsigned sign = 0; !terminate && sign < 2; sign++) {
341 const unsigned lit = 2 * idx + sign;
347 if (transitive_reduce (
solver,
lit, limit, &reduced, &units))
351 else if (
solver->statistics_.transitive_ticks > limit)
361 solver,
"dropping remaining %zu transitive candidates", remain);
364 solver->flags[idx].transitive =
false;
372 const uint64_t new_ticks =
solver->statistics_.transitive_ticks;
373 const uint64_t delta_ticks = new_ticks - old_ticks;
375 solver,
"finished at %" PRIu64
" after %" PRIu64
" transitive ticks",
376 new_ticks, delta_ticks);
379 "probed %u (%.0f%%): reduced %" PRIu64
", units %u", probed,
380 kissat_percent (probed, 2 * active), reduced, units);
382#if !defined(KISSAT_NDEBUG) || defined(METRICS)
384 solver->transitive_reducing =
false;
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void kissat_learned_unit(kissat *solver, unsigned lit)
ABC_NAMESPACE_IMPL_START typedef signed char value
void kissat_delete_binary(kissat *solver, unsigned a, unsigned b)
#define all_variables(IDX)
#define all_literals(LIT)
#define KISSAT_assert(ignore)
#define SORT_STACK(TYPE, S, LESS)
#define SET_EFFORT_LIMIT(LIMIT, NAME, THRESHHOLD)
#define kissat_extremely_verbose(...)
#define kissat_very_verbose(...)
#define kissat_phase(...)
clause * kissat_probing_propagate(kissat *solver, clause *ignore, bool flush)
#define transitive_terminated_2
#define transitive_terminated_3
#define transitive_terminated_1
#define LESS_FOCUSED_PROBE(A, B)
void kissat_transitive_reduction(kissat *solver)
#define LESS_STABLE_PROBE(A, B)
#define BEGIN_WATCHES(WS)
#define REMOVE_WATCHES(W, E)
#define SET_END_OF_WATCHES(WS, P)