3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 21:38:44 +00:00

throttle cce pass

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-01-31 21:15:07 -08:00
parent a639452553
commit 75bf942237
4 changed files with 117 additions and 104 deletions

View file

@ -64,7 +64,7 @@ namespace sat {
return true; return true;
if (c.size() == 3) { if (c.size() == 3) {
CTRACE("sat_ter_watch_bug", !contains_watched(s.get_wlist(~c[0]), c[1], c[2], c.is_learned()), tout << c << "\n"; CTRACE("sat_ter_watch_bug", !contains_watched(s.get_wlist(~c[0]), c[1], c[2]), tout << c << "\n";
tout << "watch_list:\n"; tout << "watch_list:\n";
sat::display_watch_list(tout, s.m_cls_allocator, s.get_wlist(~c[0])); sat::display_watch_list(tout, s.m_cls_allocator, s.get_wlist(~c[0]));
tout << "\n";); tout << "\n";);

View file

@ -94,23 +94,18 @@ namespace sat {
bool simplifier::single_threaded() const { return s.m_config.m_num_threads == 1; } bool simplifier::single_threaded() const { return s.m_config.m_num_threads == 1; }
bool simplifier::bce_enabled() const { bool simplifier::bce_enabled_base() const {
return return
!m_incremental_mode && !s.tracking_assumptions() && !m_learned_in_use_lists && m_num_calls >= m_bce_delay && !m_incremental_mode && !s.tracking_assumptions() &&
(m_elim_blocked_clauses || m_elim_blocked_clauses_at == m_num_calls || cce_enabled()); !m_learned_in_use_lists && m_num_calls >= m_bce_delay && single_threaded();
}
bool simplifier::acce_enabled() const {
return !s.m_ext && !m_incremental_mode && !s.tracking_assumptions() && !m_learned_in_use_lists && m_num_calls >= m_bce_delay && m_acce;
}
bool simplifier::cce_enabled() const {
return !s.m_ext && !m_incremental_mode && !s.tracking_assumptions() && !m_learned_in_use_lists && m_num_calls >= m_bce_delay && (m_cce || acce_enabled());
}
bool simplifier::abce_enabled() const {
return !s.m_ext && !m_incremental_mode && !s.tracking_assumptions() && !m_learned_in_use_lists && m_num_calls >= m_bce_delay && m_abce;
}
bool simplifier::bca_enabled() const {
return !s.m_ext && !m_incremental_mode && !s.tracking_assumptions() && m_bca && m_learned_in_use_lists && single_threaded();
} }
bool simplifier::ate_enabled() const { return m_ate; }
bool simplifier::bce_enabled() const { return bce_enabled_base() && (m_bce || m_bce_at == m_num_calls || m_acce || m_abce || m_cce); }
bool simplifier::acce_enabled() const { return bce_enabled_base() && m_acce; }
bool simplifier::cce_enabled() const { return bce_enabled_base() && (m_cce || m_acce); }
bool simplifier::abce_enabled() const { return bce_enabled_base() && m_abce; }
bool simplifier::bca_enabled() const { return bce_enabled_base() && m_bca; }
bool simplifier::elim_vars_bdd_enabled() const { bool simplifier::elim_vars_bdd_enabled() const {
return !m_incremental_mode && !s.tracking_assumptions() && m_elim_vars_bdd && m_num_calls >= m_elim_vars_bdd_delay && single_threaded(); return !m_incremental_mode && !s.tracking_assumptions() && m_elim_vars_bdd && m_num_calls >= m_elim_vars_bdd_delay && single_threaded();
} }
@ -219,7 +214,7 @@ namespace sat {
} }
register_clauses(s.m_clauses); register_clauses(s.m_clauses);
if (bce_enabled() || abce_enabled() || bca_enabled()) { if (bce_enabled() || bca_enabled() || ate_enabled()) {
elim_blocked_clauses(); elim_blocked_clauses();
} }
@ -1010,28 +1005,27 @@ namespace sat {
enum elim_type { enum elim_type {
cce_t, cce_t,
acce_t, acce_t,
abce_t abce_t,
}; ate_t,
no_t
enum verdict_type {
at_t, // asymmetric tautology
bc_t, // blocked clause
no_t // neither
}; };
void operator()() { void operator()() {
if (s.bce_enabled()) {
block_clauses();
}
if (s.abce_enabled()) {
cce<abce_t>();
}
if (s.cce_enabled()) {
cce<cce_t>();
}
if (s.acce_enabled()) { if (s.acce_enabled()) {
cce<acce_t>(); cce<acce_t>();
} }
if (s.ate_enabled() && !s.abce_enabled() && !s.acce_enabled()) {
cce<ate_t>();
}
if (s.cce_enabled() && !s.acce_enabled()) {
cce<cce_t>();
}
if (s.abce_enabled() && !s.acce_enabled()) {
cce<abce_t>();
}
if (s.bce_enabled() && !s.cce_enabled() && !s.abce_enabled()) {
block_clauses();
}
if (s.bca_enabled()) { if (s.bca_enabled()) {
bca(); bca();
} }
@ -1223,7 +1217,8 @@ namespace sat {
This routine removes literals that were not relevant to establishing it was blocked. This routine removes literals that were not relevant to establishing it was blocked.
*/ */
void minimize_covered_clause(unsigned idx) { void minimize_covered_clause(unsigned idx) {
// IF_VERBOSE(0, verbose_stream() << "minimize: " << m_covered_clause << " @ " << idx << "\n" << "tautology: " << m_tautology << "\n";); // IF_VERBOSE(0, verbose_stream() << "minimize: " << m_covered_clause
// << " @ " << idx << "\n" << "tautology: " << m_tautology << "\n";);
for (literal l : m_tautology) VERIFY(s.is_marked(l)); for (literal l : m_tautology) VERIFY(s.is_marked(l));
for (literal l : m_covered_clause) s.unmark_visited(l); for (literal l : m_covered_clause) s.unmark_visited(l);
for (literal l : m_tautology) s.mark_visited(l); for (literal l : m_tautology) s.mark_visited(l);
@ -1369,14 +1364,25 @@ namespace sat {
} }
template<elim_type et> template<elim_type et>
verdict_type cla(literal& blocked, model_converter::kind& k) { elim_type cce(literal& blocked, model_converter::kind& k) {
bool is_tautology = false; bool is_tautology = false, first = true;
unsigned sz = 0, sz0 = m_covered_clause.size();
for (literal l : m_covered_clause) s.mark_visited(l); for (literal l : m_covered_clause) s.mark_visited(l);
unsigned num_iterations = 0, sz; shuffle<literal>(m_covered_clause.size(), m_covered_clause.c_ptr(), s.s.m_rand);
m_elim_stack.reset(); m_elim_stack.reset();
m_ala_qhead = 0; m_ala_qhead = 0;
k = model_converter::CCE;
unsigned sz0 = m_covered_clause.size(); switch (et) {
case abce_t:
k = model_converter::BLOCK_LIT;
break;
case cce_t:
k = model_converter::CCE;
break;
case acce_t:
k = model_converter::ACCE;
break;
}
/* /*
* For blocked clause elimination with asymmetric literal addition (ABCE) * For blocked clause elimination with asymmetric literal addition (ABCE)
@ -1385,56 +1391,48 @@ namespace sat {
* So we record sz0, the original set of literals in the clause, mark additional literals, * So we record sz0, the original set of literals in the clause, mark additional literals,
* and then check if any of the first sz0 literals are blocked. * and then check if any of the first sz0 literals are blocked.
*/ */
if (et == abce_t) {
if (add_ala()) {
for (literal l : m_covered_clause) s.unmark_visited(l);
return at_t;
}
for (unsigned i = 0; i < sz0; ++i) {
if (check_abce_tautology(m_covered_clause[i])) {
blocked = m_covered_clause[i];
is_tautology = true;
break;
}
}
k = model_converter::BLOCK_LIT; // actually ABCE
for (literal l : m_covered_clause) s.unmark_visited(l);
m_covered_clause.shrink(sz0);
return is_tautology ? bc_t : no_t;
}
/* while (!is_tautology && m_covered_clause.size() > sz && !above_threshold(sz0)) {
* For CCE we add the resolution intersection while checking if the clause becomes a tautology. SASSERT(!is_tautology);
* For ACCE, in addition, we add literals. if ((et == abce_t || et == acce_t || et == ate_t) && add_ala()) {
*/ for (literal l : m_covered_clause) s.unmark_visited(l);
do { return ate_t;
do { }
if (above_threshold(sz0)) break;
++num_iterations; if (first) {
sz = m_covered_clause.size(); for (unsigned i = 0; i < sz0; ++i) {
if (check_abce_tautology(m_covered_clause[i])) {
blocked = m_covered_clause[i];
is_tautology = true;
break;
}
}
first = false;
}
if (is_tautology || et == abce_t) {
for (literal l : m_covered_clause) s.unmark_visited(l);
m_covered_clause.shrink(sz0);
return is_tautology ? abce_t : no_t;
}
/*
* Add resolution intersection while checking if the clause becomes a tautology.
*/
sz = m_covered_clause.size();
if (et == cce_t || et == acce_t) {
is_tautology = add_cla(blocked); is_tautology = add_cla(blocked);
} }
while (m_covered_clause.size() > sz && !is_tautology);
if (et == acce_t && !is_tautology) {
sz = m_covered_clause.size();
if (add_ala()) {
for (literal l : m_covered_clause) s.unmark_visited(l);
return at_t;
}
k = model_converter::ACCE;
}
if (above_threshold(sz0)) break;
} }
while (m_covered_clause.size() > sz && !is_tautology);
for (literal l : m_covered_clause) s.unmark_visited(l); for (literal l : m_covered_clause) s.unmark_visited(l);
return is_tautology ? bc_t : no_t; return is_tautology ? et : no_t;
} }
// perform covered clause elimination. // perform covered clause elimination.
// first extract the covered literal addition (CLA). // first extract the covered literal addition (CLA).
// then check whether the CLA is blocked. // then check whether the CLA is blocked.
template<elim_type et> template<elim_type et>
verdict_type cce(clause& c, literal& blocked, model_converter::kind& k) { elim_type cce(clause& c, literal& blocked, model_converter::kind& k) {
m_clause = clause_wrapper(c); m_clause = clause_wrapper(c);
m_covered_clause.reset(); m_covered_clause.reset();
m_covered_antecedent.reset(); m_covered_antecedent.reset();
@ -1443,11 +1441,11 @@ namespace sat {
m_covered_antecedent.push_back(clause_ante()); m_covered_antecedent.push_back(clause_ante());
} }
// shuffle<literal>(s.s.m_rand, m_covered_clause); // shuffle<literal>(s.s.m_rand, m_covered_clause);
return cla<et>(blocked, k); return cce<et>(blocked, k);
} }
template<elim_type et> template<elim_type et>
verdict_type cce(literal l1, literal l2, literal& blocked, model_converter::kind& k) { elim_type cce(literal l1, literal l2, literal& blocked, model_converter::kind& k) {
m_clause = clause_wrapper(l1, l2); m_clause = clause_wrapper(l1, l2);
m_covered_clause.reset(); m_covered_clause.reset();
m_covered_antecedent.reset(); m_covered_antecedent.reset();
@ -1455,7 +1453,7 @@ namespace sat {
m_covered_clause.push_back(l2); m_covered_clause.push_back(l2);
m_covered_antecedent.push_back(clause_ante()); m_covered_antecedent.push_back(clause_ante());
m_covered_antecedent.push_back(clause_ante()); m_covered_antecedent.push_back(clause_ante());
return cla<et>(blocked, k); return cce<et>(blocked, k);
} }
template<elim_type et> template<elim_type et>
@ -1481,21 +1479,22 @@ namespace sat {
model_converter::kind k; model_converter::kind k;
for (watched & w : wlist) { for (watched & w : wlist) {
if (!w.is_binary_non_learned_clause()) continue; if (!w.is_binary_non_learned_clause()) continue;
if (!select_clause<et>(2)) continue;
literal l2 = w.get_literal(); literal l2 = w.get_literal();
switch (cce<et>(l, l2, blocked, k)) { elim_type r = cce<et>(l, l2, blocked, k);
case bc_t: inc_bc(r);
inc_bc<et>(); switch (r) {
block_covered_binary(w, l, blocked, k); case ate_t:
w.set_learned(true);
s.s.set_learned1(l2, l, true);
break;
case at_t:
s.m_num_ate++;
w.set_learned(true); w.set_learned(true);
s.s.set_learned1(l2, l, true); s.s.set_learned1(l2, l, true);
break; break;
case no_t: case no_t:
break; break;
default:
block_covered_binary(w, l, blocked, k);
w.set_learned(true);
s.s.set_learned1(l2, l, true);
break;
} }
} }
} }
@ -1507,31 +1506,40 @@ namespace sat {
for (clause* cp : s.s.m_clauses) { for (clause* cp : s.s.m_clauses) {
clause& c = *cp; clause& c = *cp;
if (c.was_removed() || c.is_learned()) continue; if (c.was_removed() || c.is_learned()) continue;
switch (cce<et>(c, blocked, k)) { if (!select_clause<et>(c.size())) continue;
case bc_t: elim_type r = cce<et>(c, blocked, k);
inc_bc<et>(); inc_bc(r);
block_covered_clause(c, blocked, k); switch (r) {
s.set_learned(c); case ate_t:
break;
case at_t:
s.m_num_ate++;
s.set_learned(c); s.set_learned(c);
break; break;
case no_t: case no_t:
break; break;
default:
block_covered_clause(c, blocked, k);
s.set_learned(c);
break;
} }
} }
} }
template<elim_type et> void inc_bc(elim_type et) {
void inc_bc() {
switch (et) { switch (et) {
case cce_t: s.m_num_cce++; break; case cce_t: s.m_num_cce++; break;
case acce_t: s.m_num_acce++; break; case acce_t: s.m_num_acce++; break;
case abce_t: s.m_num_abce++; break; case abce_t: s.m_num_abce++; break;
case ate_t: s.m_num_ate++; break;
default: break;
} }
} }
// select 25% of clauses size 2, 3
// always try to remove larger clauses.
template<elim_type et>
bool select_clause(unsigned sz) {
return et == ate_t || (sz > 3) || s.s.m_rand(4) == 0;
}
void prepare_block_clause(clause& c, literal l, model_converter::entry*& new_entry, model_converter::kind k) { void prepare_block_clause(clause& c, literal l, model_converter::entry*& new_entry, model_converter::kind k) {
TRACE("blocked_clause", tout << "new blocked clause: " << c << "\n";); TRACE("blocked_clause", tout << "new blocked clause: " << c << "\n";);
VERIFY(!s.is_external(l)); VERIFY(!s.is_external(l));
@ -2070,9 +2078,10 @@ namespace sat {
m_acce = p.acce(); m_acce = p.acce();
m_bca = p.bca(); m_bca = p.bca();
m_abce = p.abce(); m_abce = p.abce();
m_ate = p.ate();
m_bce_delay = p.bce_delay(); m_bce_delay = p.bce_delay();
m_elim_blocked_clauses = p.elim_blocked_clauses(); m_bce = p.elim_blocked_clauses();
m_elim_blocked_clauses_at = p.elim_blocked_clauses_at(); m_bce_at = p.elim_blocked_clauses_at();
m_retain_blocked_clauses = p.retain_blocked_clauses(); m_retain_blocked_clauses = p.retain_blocked_clauses();
m_blocked_clause_limit = p.blocked_clause_limit(); m_blocked_clause_limit = p.blocked_clause_limit();
m_res_limit = p.resolution_limit(); m_res_limit = p.resolution_limit();

View file

@ -76,8 +76,9 @@ namespace sat {
bool m_acce; // cce with asymetric literal addition bool m_acce; // cce with asymetric literal addition
bool m_bca; // blocked (binary) clause addition. bool m_bca; // blocked (binary) clause addition.
unsigned m_bce_delay; unsigned m_bce_delay;
bool m_elim_blocked_clauses; bool m_bce; // blocked clause elimination
unsigned m_elim_blocked_clauses_at; bool m_ate; // asymmetric tautology elimination
unsigned m_bce_at;
bool m_retain_blocked_clauses; bool m_retain_blocked_clauses;
unsigned m_blocked_clause_limit; unsigned m_blocked_clause_limit;
bool m_incremental_mode; bool m_incremental_mode;
@ -176,6 +177,8 @@ namespace sat {
void elim_blocked_clauses(); void elim_blocked_clauses();
bool single_threaded() const; // { return s.m_config.m_num_threads == 1; } bool single_threaded() const; // { return s.m_config.m_num_threads == 1; }
bool bce_enabled_base() const;
bool ate_enabled() const;
bool bce_enabled() const; bool bce_enabled() const;
bool acce_enabled() const; bool acce_enabled() const;
bool cce_enabled() const; bool cce_enabled() const;

View file

@ -4,6 +4,7 @@ def_module_params(module_name='sat',
params=(('elim_blocked_clauses', BOOL, False, 'eliminate blocked clauses'), params=(('elim_blocked_clauses', BOOL, False, 'eliminate blocked clauses'),
('abce', BOOL, False, 'eliminate blocked clauses using asymmmetric literals'), ('abce', BOOL, False, 'eliminate blocked clauses using asymmmetric literals'),
('cce', BOOL, False, 'eliminate covered clauses'), ('cce', BOOL, False, 'eliminate covered clauses'),
('ate', BOOL, True, 'asymmetric tautology elimination'),
('acce', BOOL, False, 'eliminate covered clauses using asymmetric added literals'), ('acce', BOOL, False, 'eliminate covered clauses using asymmetric added literals'),
('elim_blocked_clauses_at', UINT, 2, 'eliminate blocked clauses only once at the given simplification round'), ('elim_blocked_clauses_at', UINT, 2, 'eliminate blocked clauses only once at the given simplification round'),
('bca', BOOL, False, 'blocked clause addition - add blocked binary clauses'), ('bca', BOOL, False, 'blocked clause addition - add blocked binary clauses'),