63 int real_size_subsuming = 0, real_size_subsumed = 0;
64 for (
auto lit : *subsuming) {
66 ++real_size_subsuming;
70 for (
auto lit : *subsumed) {
78 LOG (subsumed,
"subsumed");
89 "binary subsuming clause was already deleted, so undeleting");
92 ++
stats.current.total;
94 stats.current.redundant++;
102 LOG (
"turning redundant subsuming clause into irredundant clause");
105 proof->strengthen (subsuming->
id);
108 stats.current.irredundant++;
109 stats.added.irredundant++;
112 stats.current.redundant--;
114 stats.added.redundant--;
122 stats.vivifydemote++;
128 stats.current.irredundant--;
130 stats.added.irredundant--;
132 stats.current.redundant++;
133 stats.added.redundant++;
159 const signed char tmp =
sign (
lit);
165 LOG (reason,
"vivify assign %d",
lit);
174 LOG (
"vivify decide %d",
lit);
192 LOG (
"vivify propagating %d over binary clauses", -
lit);
196 for (
const auto &w : ws) {
199 const signed char b =
val (w.blit);
213 LOG (
"vivify propagating %d over large clauses", -
lit);
220 const Watch w = *j++ = *i++;
232 const signed char u =
val (other);
242 while (k != end && (v =
val (r = *k)) < 0)
247 while (k != middle && (v =
val (r = *k)) < 0)
264 LOG (
"ignoring propagation due to clause to vivify");
274 LOG (
"ignoring conflict due to clause to vivify");
287 ws.resize (j - ws.begin ());
293 stats.propagations.vivify += delta;
321 return abs (a) < abs (b);
334 return ((t - s) | ((b - a) & ~(s - t))) >> 31;
420 const auto eoa = a->
end (), eob = b->
end ();
421 auto j = b->
begin ();
422 for (
auto i = a->
begin (); i != eoa && j != eob; i++, j++)
446 const auto eoa = a->
end (), eob = b->
end ();
448 for (; i != eoa && j != eob; i++, j++)
452 return j == eob && i != eoa;
461 const auto end = schedule.end ();
462 auto j = schedule.begin (), i = j;
465 int64_t subsumed = 0;
466 for (; i != end; i++) {
469 if (!prev || c->
size < prev->
size) {
473 const auto eop = prev->
end ();
474 auto k = prev->
begin ();
475 for (
auto l = c->
begin (); k != eop; k++, l++)
479 LOG (c,
"found subsumed");
480 LOG (prev,
"subsuming");
493 "flushed %" PRId64
" subsumed scheduled clauses", subsumed);
495 stats.vivifysubs += subsumed;
498 schedule.resize (j - schedule.begin ());
543 if (av >= 0 && bv < 0)
545 if (av < 0 && bv >= 0)
559 if (
clause.size () == 1) {
562 const int unit =
clause[0];
563 LOG (c,
"vivification shrunken to unit %d", unit);
579 int new_level =
level;
581 const int lit0 =
clause[0];
582 signed char val0 =
val (lit0);
584 const int level0 =
var (lit0).
level;
585 LOG (
"1st watch %d negative at level %d", lit0, level0);
586 new_level = level0 - 1;
589 const int lit1 =
clause[1];
590 const signed char val1 =
val (lit1);
592 const int level1 =
var (lit1).
level;
593 LOG (
"2nd watch %d negative at level %d", lit1, level1);
594 new_level = level1 - 1;
598 if (new_level <
level)
606 LOG (c,
"before vivification");
607 LOG (d,
"after vivification");
620 int new_level =
level;
623 signed char val0 =
val (lit0);
625 const int level0 =
var (lit0).
level;
626 LOG (
"1st watch %d negative at level %d", lit0, level0);
627 new_level = level0 - 1;
631 const signed char val1 =
val (lit1);
633 const int level1 =
var (lit1).
level;
634 LOG (
"2nd watch %d negative at level %d", lit1, level1);
635 new_level = level1 - 1;
639 if (new_level <
level)
656 const auto &t = &
trail;
661 int uip =
trail.back ();
667 subsumes = (start != reason && reason->
size <= start->
size);
668 LOG (reason,
"resolving on %d with", uip);
669 for (
auto other : *reason) {
670 const Var v =
var (other);
673 LOG (
"not subsuming due to lit %d", other);
677 LOG (
"skipping unset lit %d", other);
684 if (f.
seen || !
lrat || reason == start)
686 LOG (
"unit reason for %d", other);
688 LOG (
"adding unit reason %zd for %d",
id, other);
694 if (mark_implied && other !=
implied) {
695 LOG (
"skipping non-implied literal %d on current level", other);
702 LOG (
"pushing lit %d", other);
712 LOG (reason,
"clause found subsuming");
718 LOG (
"vivify analyzed decision %d", uip);
721 mark_implied =
false;
724 while (!uip && i > 0) {
726 const int lit = (*t)[--i];
734 LOG (
"uip is %d", uip);
754 const int not_implied = -
implied;
758 LOG (
"pushing implied lit %d", not_implied);
768 LOG (reason,
"resolving with");
771 for (
auto lit : *reason) {
778 LOG (
"adding unit %d",
lit);
783 LOG (
"adding unit reason %zd for %d",
id,
lit);
792 LOG (
"lit %d is not marked",
lit);
795 LOG (
"analyzing lit %d",
lit);
796 LOG (
"pushing lit %d",
lit);
800 if (reason !=
candidate && reason->redundant) {
806#ifndef CADICAL_NDEBUG
807 int nonfalse_reason = 0;
808 for (
auto lit : *reason)
812 int nonfalse_candidate = 0;
815 ++nonfalse_candidate;
820 LOG (reason,
"vivify subsuming 0");
835 LOG (*subsuming,
"vivify subsuming");
845 unsigned count_implied = 0;
846 for (
auto lit : sorted) {
849 LOG (
"vivification unassigned %d",
lit);
853 LOG (
"vivification implied satisfied %d",
lit);
856 if (count_implied++) {
857 LOG (
"at least one implied literal with conflict thus shrinking");
867 LOG (
"vivification non-analyzed %d",
lit);
871 LOG (
"vivification implied falsified %d",
lit);
883 ++
stats.vivifystred1;
886 ++
stats.vivifystred2;
889 ++
stats.vivifystred3;
893 ++
stats.vivifystrirr;
902 const std::vector<int> &sorted,
Clause *c,
903 std::vector<std::tuple<int, Clause *, bool>> &lrat_stack,
905 LOG (
"now trying instantiation");
907 const int lit = sorted.back ();
908 LOG (
"vivify instantiation");
918 LOG (c,
"instantiate success with literal %d in",
lit);
938 LOG (
"vivify instantiation failed");
957 auto &lrat_stack =
vivifier.lrat_stack;
970 for (
const auto &
lit : *c) {
973 LOG (c,
"satisfied by propagated unit %d",
lit);
977 sorted.push_back (
lit);
981 if (sorted.size () == 2) {
982 LOG (
"skipping actual binary");
993 LOG (c,
"vivification checking");
994 stats.vivifychecks++;
1005 int orig_level =
level;
1024 for (
const auto &
lit : *c) {
1025 const signed char tmp =
val (
lit);
1028 if (tmp > 0 &&
var (
lit).reason == c)
1033 LOG (
"clause is reason forcing %d", forced);
1045 for (
const auto &
lit : sorted) {
1047 const int decision =
control[l].decision;
1048 if (-
lit == decision) {
1049 LOG (
"reusing decision %d at decision level %d", decision, l);
1050 stats.vivifyreused++;
1054 LOG (
"literal %d does not match decision %d at decision level %d",
1062 LOG (
"reused %d decision levels from %d",
level, orig_level);
1065 LOG (sorted,
"sorted size %zd probing schedule", sorted.size ());
1091 for (
const auto &
lit : sorted) {
1105 const signed char tmp =
val (
lit);
1112 LOG (
"skipping decision %d",
lit);
1118 LOG (
"literal %d is already false and can be removed",
lit);
1123 LOG (
"subsumed since literal %d already true",
lit);
1141 for (
auto lit : sorted) {
1145 if (v.
trail < better_subsume_trail) {
1146 LOG (
"improving subsume from %d at %d to %d at %d",
subsume,
1147 better_subsume_trail,
lit, v.
trail);
1148 better_subsume_trail = v.
trail;
1154 Clause *subsuming =
nullptr;
1156 const int level_after_assumptions =
level;
1174 LOG (c,
"deleting subsumed clause");
1183 LOG (
"vivify succeeded, learning new clause");
1191 LOG (c,
"vivification implied");
1193 ++
stats.vivifyimplied;
1196 LOG (
"demote clause from irredundant to redundant");
1197 if (
opts.vivifydemote) {
1204 ++
stats.vivifyimplied;
1208 LOG (c,
"no vivification instantiation with implied literal %d",
1213 ++
stats.vivifyimplied;
1217 LOG (c,
"vivification failed on");
1224 LOG (
"cannot apply instantiation");
1230 LOG (
"forcing backtracking at least one level after conflict");
1259 std::vector<std::tuple<int, Clause *, bool>> &stack) {
1261 stack.push_back ({
lit, reason,
false});
1262 while (!stack.empty ()) {
1266 std::tie (
lit, reason, finished) = stack.back ();
1267 LOG (
"VIVIFY LRAT justifying %d",
lit);
1270 LOG (
"skipping already justified");
1275 if (
lit && reason) {
1283 stack.push_back ({
lit, reason,
true});
1284 for (
const auto &other : *reason) {
1292 const int64_t
id =
unit_id (-other);
1299 LOG (
"VIVIFY LRAT pushing %d", other);
1300 stack.push_back ({other, v.
reason,
false});
1317 for (
auto &reason_lit : *reason) {
1318 if (
lit == reason_lit)
1321 const int signed_reason_lit =
val (reason_lit) * reason_lit;
1322 int64_t
id =
unit_id (signed_reason_lit);
1329 LOG (c,
"creating vivify_refs of clause");
1339 unsigned best_count = 0;
1340 for (
auto lit : *c) {
1341 LOG (
"to find best number of occurrences for literal %d, looking at "
1344 for (
int j = 0; j != i; ++j) {
1345 LOG (
"comparing %d with literal %d",
lit, lits[j]);
1347 goto CONTINUE_WITH_NEXT_LITERAL;
1350 const int64_t lit_count = internal->
noccs (
lit);
1352 LOG (
"checking literal %d with %zd occurrences",
lit, lit_count);
1353 if (lit_count <= best_count)
1355 best_count = lit_count;
1358 CONTINUE_WITH_NEXT_LITERAL:;
1364 ((uint64_t) best_count << 32) + (uint64_t) internal->
vlit (best);
1365 LOG (
"final count at position %d is %d - %d: %lu", i, best, best_count,
1375 std::vector<Clause *> &schedule) {
1378 "[phase %c] leftovers of %" PRId64
" clause", tag, prioritized);
1381 "[phase %c] prioritizing all clause", tag);
1382 for (
auto c : schedule)
1385 const size_t max =
opts.vivifyschedmax;
1386 if (schedule.size () > max) {
1388 std::partition (begin (schedule), end (schedule),
1391 schedule.resize (max);
1414 size_t prioritized_irred = 0, prioritized_tier1 = 0,
1415 prioritized_tier2 = 0, prioritized_tier3 = 0;
1416 for (
const auto &c :
clauses) {
1433 const int shift = 12 - c->size;
1434 const int64_t
score = shift < 1 ? 1 : (1l << shift);
1435 for (
const auto lit : *c) {
1438 LOG (c,
"putting clause in candidates");
1440 vivifier.schedule_irred.push_back (c),
1441 prioritized_irred += (c->vivify);
1442 else if (c->glue <=
tier1)
1443 vivifier.schedule_tier1.push_back (c),
1444 prioritized_tier1 += (c->vivify);
1445 else if (c->glue <=
tier2)
1446 vivifier.schedule_tier2.push_back (c),
1447 prioritized_tier2 += (c->vivify);
1449 vivifier.schedule_tier3.push_back (c),
1450 prioritized_tier3 += (c->vivify);
1463 if (
opts.vivifyflush) {
1465 for (
auto &sched :
vivifier.schedules) {
1466 for (
const auto &c : sched) {
1492 return vivifier.refs_schedule_tier1;
1495 return vivifier.refs_schedule_tier2;
1498 return vivifier.refs_schedule_tier3;
1501 return vivifier.refs_schedule_irred;
1507 __builtin_unreachable ();
1529 __builtin_unreachable ();
1584 "starting %c vivification round ticks limit %" PRId64
"",
1588 "starting %c vivification round ticks limit %" PRId64
"",
1596 int64_t ticks = 1 + schedule.size ();
1612 auto end_schedule = end (schedule);
1613 refs_schedule.resize (schedule.size ());
1614 std::transform (begin (schedule), end_schedule, begin (refs_schedule),
1617 MSORT (
opts.radixsortlim, refs_schedule.begin (), refs_schedule.end (),
1622 MSORT (
opts.radixsortlim, refs_schedule.begin (),
1627 std::stable_partition (begin (refs_schedule), end (refs_schedule),
1629 std::transform (begin (refs_schedule), end (refs_schedule),
1633 LOG (
"clause after sorting final:");
1638 std::stable_partition (begin (schedule), end (schedule),
1645 int64_t checked =
stats.vivifychecks;
1646 int64_t subsumed =
stats.vivifysubs;
1647 int64_t strengthened =
stats.vivifystrs;
1648 int64_t units =
stats.vivifyunits;
1650 int64_t scheduled = schedule.size ();
1651 stats.vivifysched += scheduled;
1654 "scheduled %" PRId64
" clauses to be vivified %.0f%%", scheduled,
1659 const int64_t
limit = ticks_limit -
stats.ticks.vivify;
1667 LOG (
"propagation after connecting watches in inconsistency");
1675 Clause *c = schedule.back ();
1676 schedule.pop_back ();
1678 retry <
opts.vivifyretry) {
1680 schedule.push_back (c);
1689 int64_t still_need_to_be_vivified = schedule.size ();
1697 for (
auto c : schedule)
1702 if (!schedule.empty () && !schedule.front ()->vivify &&
1703 schedule.back ()->vivify)
1704 for (
auto c : schedule)
1711 if (still_need_to_be_vivified)
1713 "still need to vivify %" PRId64
" clauses %.02f%% of %" PRId64
1715 still_need_to_be_vivified,
1716 percent (still_need_to_be_vivified, scheduled), scheduled);
1719 "no previously not yet vivified clause left");
1736 LOG (
"propagating vivified units leads to conflict");
1741 checked =
stats.vivifychecks - checked;
1742 subsumed =
stats.vivifysubs - subsumed;
1743 strengthened =
stats.vivifystrs - strengthened;
1744 units =
stats.vivifyunits - units;
1747 "checked %" PRId64
" clauses %.02f%% of %" PRId64
1748 " scheduled using %" PRIu64
" ticks",
1752 "found %" PRId64
" units %.02f%% of %" PRId64
" checked", units,
1753 percent (units, checked), checked);
1756 "subsumed %" PRId64
" clauses %.02f%% of %" PRId64
" checked",
1757 subsumed,
percent (subsumed, checked), checked);
1760 "strengthened %" PRId64
" clauses %.02f%% of %" PRId64
1762 strengthened,
percent (strengthened, checked), checked);
1764 stats.subsumed += subsumed;
1765 stats.strengthened += strengthened;
1768 bool unsuccessful = !(subsumed + strengthened + units);
1793 if (!
opts.vivifycalctier) {
1812 if (!
stats.current.irredundant)
1824 stats.vivifications++;
1828 double tier1effort = !
opts.vivifytier1 ? 0 : (double)
opts.vivifytier1eff;
1829 double tier2effort = !
opts.vivifytier2 ? 0 : (double)
opts.vivifytier2eff;
1830 double tier3effort = !
opts.vivifytier3 ? 0 : (double)
opts.vivifytier3eff;
1834 : (double)
opts.vivifyirredeff;
1835 double sumeffort = tier1effort + tier2effort + tier3effort + irreffort;
1836 if (!
stats.current.redundant)
1837 tier1effort = tier2effort = tier3effort = 0;
1839 sumeffort = irreffort = 1;
1840 int64_t total = totallimit -
stats.ticks.vivify;
1843 "vivification limit of %" PRId64
" ticks", total);
1848 tier1effort += tier2effort;
1850 LOG (
"vivification tier1 matches tier2 "
1851 "thus using tier2 budget for tier1");
1853 int64_t init_ticks = 0;
1861 stats.ticks.vivify += init_ticks;
1863 const double shared_effort = (double) init_ticks / 4.0;
1864 if (
opts.vivifytier1) {
1868 const double effort = (total * tier1effort) / sumeffort;
1869 CADICAL_assert (std::numeric_limits<int64_t>::max () - (int64_t) effort >=
1872 if (
limit - shared_effort >
stats.ticks.vivify) {
1873 limit -= shared_effort;
1877 LOG (
"building the schedule already used our entire ticks budget for "
1882 if (!
unsat && tier2effort) {
1888 const double effort = (total * tier2effort) / sumeffort;
1889 CADICAL_assert (std::numeric_limits<int64_t>::max () - (int64_t) effort >=
1892 if (
limit - shared_effort >
stats.ticks.vivify) {
1893 limit -= shared_effort;
1898 LOG (
"building the schedule already used our entire ticks budget for "
1903 if (!
unsat && tier3effort) {
1907 const double effort = (total * tier3effort) / sumeffort;
1908 CADICAL_assert (std::numeric_limits<int64_t>::max () - (int64_t) effort >=
1911 if (
limit - shared_effort >
stats.ticks.vivify) {
1912 limit -= shared_effort;
1917 LOG (
"building the schedule already used our entire ticks budget for "
1922 if (!
unsat && irreffort) {
1926 const double effort = (total * irreffort) / sumeffort;
1927 CADICAL_assert (std::numeric_limits<int64_t>::max () - (int64_t) effort >=
1930 if (
limit - shared_effort >
stats.ticks.vivify) {
1931 limit -= shared_effort;
1934 const int old =
stats.vivifystrirr;
1935 const int old_tried =
stats.vivifychecks;
1937 if (
stats.vivifychecks - old_tried == 0 ||
1938 (
float) (
stats.vivifystrirr - old) /
1939 (
float) (
stats.vivifychecks - old_tried) <
1947 LOG (
"building the schedule already used our entire ticks budget for "
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
ABC_NAMESPACE_IMPL_START typedef signed char value
#define SET_EFFORT_LIMIT(LIMIT, NAME, THRESHHOLD)
void shrink_vector(std::vector< T > &v)
Watches::const_iterator const_watch_iterator
const int * const_literal_iterator
std::vector< vivify_ref > & current_refs_schedule(Vivifier &vivifier)
vivify_ref create_ref(Internal *internal, Clause *c)
void set_vivifier_mode(Vivifier &vivifier, Vivify_Mode tier)
std::vector< Clause * > & current_schedule(Vivifier &vivifier)
void erase_vector(std::vector< T > &v)
double percent(double a, double b)
Watches::iterator watch_iterator
#define START_SIMPLIFIER(S, M)
#define STOP_SIMPLIFIER(S, M)
#define MSORT(LIMIT, FIRST, LAST, RANK, LESS)
void vivify_round(Vivifier &, int64_t delta)
void watch_literal(int lit, int blit, Clause *c)
int64_t cache_lines(size_t bytes)
bool vivify_clause(Vivifier &, Clause *candidate)
int64_t irredundant() const
void vivify_sort_watched(Clause *c)
void unwatch_clause(Clause *c)
Delay delaying_vivify_irredundant
void mark_garbage(Clause *)
void vivify_prioritize_leftovers(char, size_t prioritized, std::vector< Clause * > &schedule)
vector< int64_t > lrat_chain
void report(char type, int verbose_level=0)
void implied(std::vector< int > &entrailed)
bool terminated_asynchronously(int factor=1)
void mark_removed(int lit)
void promote_clause(Clause *, int new_glue)
void vivify_assume(int lit)
void flush_vivification_schedule(std::vector< Clause * > &, int64_t &)
void vivify_increment_stats(const Vivifier &vivifier)
void watch_clause(Clause *c)
void learn_empty_clause()
void assign_unit(int lit)
void vivify_subsume_clause(Clause *subsuming, Clause *subsumed)
void demote_clause(Clause *)
signed char val(int lit) const
bool limit(const char *name, int)
int64_t unit_id(int lit) const
vector< int64_t > unit_chain
void vivify_build_lrat(int, Clause *, std::vector< std::tuple< int, Clause *, bool > > &)
void backtrack_without_updating_phases(int target_level=0)
void backtrack(int target_level=0)
int recompute_glue(Clause *)
unsigned vlit(int lit) const
void strengthen_clause(Clause *, int)
void vivify_strengthen(Clause *candidate)
void vivify_analyze(Clause *start, bool &, Clause **, const Clause *const, int implied, bool &)
vector< Clause * > clauses
void vivify_deduce(Clause *candidate, Clause *conflct, int implied, Clause **, bool &)
void clear_analyzed_literals()
void vivify_chain_for_units(int lit, Clause *reason)
void require_mode(Mode m) const
bool consider_to_vivify_clause(Clause *candidate)
bool vivify_propagate(int64_t &)
void vivify_assign(int lit, Clause *)
bool marked2(int lit) const
void learn_unit_clause(int lit)
void mark_added(int lit, int size, bool redundant)
void vivify_initialize(Vivifier &vivifier, int64_t &ticks)
Clause * new_clause_as(const Clause *orig)
bool vivify_instantiate(const std::vector< int > &, Clause *, std::vector< std::tuple< int, Clause *, bool > > &lrat_stack, int64_t &ticks)
int64_t redundant() const
void compute_tier_limits(Vivifier &)
void build_chain_for_units(int lit, Clause *reason, bool forced)
bool vivify_shrinkable(const std::vector< int > &sorted, Clause *c)
void connect_watches(bool irredundant_only=false)
bool operator()(int a, int b)
vivify_better_watch(Internal *i)
vivify_clause_later(Internal *i)
bool operator()(Clause *a, Clause *b) const
bool operator()(Clause *a, Clause *b) const
vivify_inversesize_rank()
Type operator()(const vivify_ref &a) const
bool operator()(const vivify_ref &a, const vivify_ref &b) const
vivify_inversesize_smaller()
bool operator()(int a, int b)
vivify_more_noccs_kissat(Internal *i)
bool operator()(int a, int b)
vivify_more_noccs(Internal *i)
uint64_t count[COUNTREF_COUNTS]
Type operator()(const vivify_ref &a) const
vivify_refcount_rank(int j)
vivify_refcount_smaller(int j)
bool operator()(const vivify_ref &a, const vivify_ref &b) const