mirror of
https://github.com/Z3Prover/z3
synced 2025-05-08 08:15:47 +00:00
snapshot
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
fc3cbcbe02
commit
7afbf8165e
25 changed files with 230 additions and 332 deletions
|
@ -42,9 +42,13 @@ namespace sat {
|
|||
asymm_branch & m_asymm_branch;
|
||||
stopwatch m_watch;
|
||||
unsigned m_elim_literals;
|
||||
unsigned m_elim_learned_literals;
|
||||
unsigned m_hidden_tautologies;
|
||||
report(asymm_branch & a):
|
||||
m_asymm_branch(a),
|
||||
m_elim_literals(a.m_elim_literals) {
|
||||
m_elim_literals(a.m_elim_literals),
|
||||
m_elim_learned_literals(a.m_elim_learned_literals),
|
||||
m_hidden_tautologies(a.m_hidden_tautologies) {
|
||||
m_watch.start();
|
||||
}
|
||||
|
||||
|
@ -53,12 +57,35 @@ namespace sat {
|
|||
IF_VERBOSE(SAT_VB_LVL,
|
||||
verbose_stream() << " (sat-asymm-branch :elim-literals "
|
||||
<< (m_asymm_branch.m_elim_literals - m_elim_literals)
|
||||
<< " :elim-learned-literals " << (m_asymm_branch.m_elim_learned_literals - m_elim_learned_literals)
|
||||
<< " :hidden-tautologies " << (m_asymm_branch.m_hidden_tautologies - m_hidden_tautologies)
|
||||
<< " :cost " << m_asymm_branch.m_counter
|
||||
<< mem_stat()
|
||||
<< " :time " << std::fixed << std::setprecision(2) << m_watch.get_seconds() << ")\n";);
|
||||
}
|
||||
};
|
||||
|
||||
bool asymm_branch::process(scc* scc) {
|
||||
unsigned elim0 = m_elim_literals;
|
||||
unsigned eliml0 = m_elim_learned_literals;
|
||||
for (unsigned i = 0; i < m_asymm_branch_rounds; ++i) {
|
||||
unsigned elim = m_elim_literals;
|
||||
if (scc) scc->init_big(true);
|
||||
process(scc, s.m_clauses);
|
||||
process(scc, s.m_learned);
|
||||
s.propagate(false);
|
||||
if (s.m_inconsistent)
|
||||
break;
|
||||
std::cout << "elim: " << m_elim_literals - elim << "\n";
|
||||
if (m_elim_literals == elim)
|
||||
break;
|
||||
}
|
||||
std::cout << "elim-literals: " << m_elim_literals - elim0 << "\n";
|
||||
std::cout << "elim-learned-literals: " << m_elim_learned_literals - eliml0 << "\n";
|
||||
return m_elim_literals > elim0;
|
||||
}
|
||||
|
||||
|
||||
void asymm_branch::process(scc* scc, clause_vector& clauses) {
|
||||
int64 limit = -m_asymm_branch_limit;
|
||||
std::stable_sort(clauses.begin(), clauses.end(), clause_size_lt());
|
||||
|
@ -119,26 +146,23 @@ namespace sat {
|
|||
TRACE("asymm_branch_detail", s.display(tout););
|
||||
report rpt(*this);
|
||||
svector<char> saved_phase(s.m_phase);
|
||||
if (m_asymm_branch) {
|
||||
m_counter = 0;
|
||||
process(nullptr, s.m_clauses);
|
||||
m_counter = -m_counter;
|
||||
}
|
||||
if (m_asymm_branch_sampled) {
|
||||
scc scc(s, m_params);
|
||||
while (true) {
|
||||
unsigned elim = m_elim_literals;
|
||||
scc.init_big(true);
|
||||
process(&scc, s.m_clauses);
|
||||
process(&scc, s.m_learned);
|
||||
s.propagate(false);
|
||||
if (s.m_inconsistent)
|
||||
break;
|
||||
std::cout << m_elim_literals - elim << "\n";
|
||||
if (m_elim_literals == elim)
|
||||
break;
|
||||
|
||||
bool change = true;
|
||||
unsigned counter = 0;
|
||||
while (change && counter < 2) {
|
||||
++counter;
|
||||
change = false;
|
||||
if (m_asymm_branch_sampled) {
|
||||
scc sc(s, m_params);
|
||||
if (process(&sc)) change = true;
|
||||
}
|
||||
if (m_asymm_branch) {
|
||||
m_counter = 0;
|
||||
if (process(nullptr)) change = true;
|
||||
m_counter = -m_counter;
|
||||
}
|
||||
}
|
||||
|
||||
s.m_phase = saved_phase;
|
||||
m_asymm_branch_limit *= 2;
|
||||
if (m_asymm_branch_limit > UINT_MAX)
|
||||
|
@ -172,8 +196,13 @@ namespace sat {
|
|||
};
|
||||
|
||||
void asymm_branch::sort(scc& scc, clause const& c) {
|
||||
sort(scc, c.begin(), c.end());
|
||||
}
|
||||
|
||||
void asymm_branch::sort(scc& scc, literal const* begin, literal const* end) {
|
||||
m_pos.reset(); m_neg.reset();
|
||||
for (literal l : c) {
|
||||
for (; begin != end; ++begin) {
|
||||
literal l = *begin;
|
||||
m_pos.push_back(l);
|
||||
m_neg.push_back(~l);
|
||||
}
|
||||
|
@ -203,23 +232,42 @@ namespace sat {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool asymm_branch::uhle(scoped_detach& scoped_d, scc& scc, clause & c) {
|
||||
int right = scc.get_right(m_pos.back());
|
||||
m_to_delete.reset();
|
||||
for (unsigned i = m_pos.size() - 1; i-- > 0; ) {
|
||||
literal lit = m_pos[i];
|
||||
SASSERT(scc.get_left(lit) < scc.get_left(last));
|
||||
int right2 = scc.get_right(lit);
|
||||
if (right2 > right) {
|
||||
// lit => last, so lit can be deleted
|
||||
m_to_delete.push_back(lit);
|
||||
void asymm_branch::minimize(scc& scc, literal_vector& lemma) {
|
||||
scc.ensure_big(true);
|
||||
sort(scc, lemma.begin(), lemma.end());
|
||||
uhle(scc);
|
||||
if (!m_to_delete.empty()) {
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < lemma.size(); ++i) {
|
||||
literal l = lemma[i];
|
||||
if (!m_to_delete.contains(l)) {
|
||||
lemma[j++] = l;
|
||||
}
|
||||
}
|
||||
else {
|
||||
right = right2;
|
||||
// std::cout << lemma.size() << " -> " << j << "\n";
|
||||
lemma.shrink(j);
|
||||
}
|
||||
}
|
||||
|
||||
void asymm_branch::uhle(scc& scc) {
|
||||
m_to_delete.reset();
|
||||
if (m_to_delete.empty()) {
|
||||
int right = scc.get_right(m_pos.back());
|
||||
for (unsigned i = m_pos.size() - 1; i-- > 0; ) {
|
||||
literal lit = m_pos[i];
|
||||
SASSERT(scc.get_left(lit) < scc.get_left(last));
|
||||
int right2 = scc.get_right(lit);
|
||||
if (right2 > right) {
|
||||
// lit => last, so lit can be deleted
|
||||
m_to_delete.push_back(lit);
|
||||
}
|
||||
else {
|
||||
right = right2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_to_delete.empty()) {
|
||||
right = scc.get_right(m_neg[0]);
|
||||
int right = scc.get_right(m_neg[0]);
|
||||
for (unsigned i = 1; i < m_neg.size(); ++i) {
|
||||
literal lit = m_neg[i];
|
||||
int right2 = scc.get_right(lit);
|
||||
|
@ -232,20 +280,11 @@ namespace sat {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!m_to_delete.empty()) {
|
||||
#if 0
|
||||
std::cout << "delete " << m_to_delete << "\n";
|
||||
}
|
||||
|
||||
std::cout << "pos\n";
|
||||
for (literal l : m_pos) {
|
||||
std::cout << l << ": " << scc.get_left(l) << " " << scc.get_right(l) << "\n";
|
||||
}
|
||||
std::cout << "neg\n";
|
||||
for (literal l : m_neg) {
|
||||
std::cout << l << ": " << scc.get_left(l) << " " << scc.get_right(l) << "\n";
|
||||
}
|
||||
std::cout << "\n";
|
||||
#endif
|
||||
bool asymm_branch::uhle(scoped_detach& scoped_d, scc& scc, clause & c) {
|
||||
uhle(scc);
|
||||
if (!m_to_delete.empty()) {
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < c.size(); ++i) {
|
||||
if (!m_to_delete.contains(c[i])) {
|
||||
|
@ -314,10 +353,13 @@ namespace sat {
|
|||
return re_attach(scoped_d, c, new_sz);
|
||||
}
|
||||
|
||||
bool asymm_branch::re_attach(scoped_detach& scoped_d, clause& c, unsigned new_sz) {
|
||||
m_elim_literals += c.size() - new_sz;
|
||||
switch(new_sz) {
|
||||
case 0:
|
||||
bool asymm_branch::re_attach(scoped_detach& scoped_d, clause& c, unsigned new_sz) {
|
||||
m_elim_literals += c.size() - new_sz;
|
||||
if (c.is_learned()) {
|
||||
m_elim_learned_literals += c.size() - new_sz;
|
||||
}
|
||||
switch(new_sz) {
|
||||
case 0:
|
||||
s.set_conflict(justification());
|
||||
return false;
|
||||
case 1:
|
||||
|
@ -329,7 +371,7 @@ namespace sat {
|
|||
return false; // check_missed_propagation() may fail, since m_clauses is not in a consistent state.
|
||||
case 2:
|
||||
SASSERT(s.value(c[0]) == l_undef && s.value(c[1]) == l_undef);
|
||||
s.mk_bin_clause(c[0], c[1], false);
|
||||
s.mk_bin_clause(c[0], c[1], c.is_learned());
|
||||
scoped_d.del_clause();
|
||||
SASSERT(s.m_qhead == s.m_trail.size());
|
||||
return false;
|
||||
|
@ -345,10 +387,13 @@ namespace sat {
|
|||
bool asymm_branch::process_sampled(scc& scc, clause & c) {
|
||||
scoped_detach scoped_d(s, c);
|
||||
sort(scc, c);
|
||||
#if 0
|
||||
if (uhte(scc, c)) {
|
||||
++m_hidden_tautologies;
|
||||
scoped_d.del_clause();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return uhle(scoped_d, scc, c);
|
||||
}
|
||||
|
||||
|
@ -381,7 +426,7 @@ namespace sat {
|
|||
// clause must not be used for propagation
|
||||
scoped_detach scoped_d(s, c);
|
||||
unsigned new_sz = c.size();
|
||||
unsigned flip_position = 2 + m_rand(c.size() - 2); // don't flip on the watch literals.
|
||||
unsigned flip_position = m_rand(c.size());
|
||||
bool found_conflict = flip_literal_at(c, flip_position, new_sz);
|
||||
SASSERT(!s.inconsistent());
|
||||
SASSERT(s.scope_lvl() == 0);
|
||||
|
@ -399,11 +444,12 @@ namespace sat {
|
|||
|
||||
void asymm_branch::updt_params(params_ref const & _p) {
|
||||
sat_asymm_branch_params p(_p);
|
||||
m_asymm_branch = p.asymm_branch();
|
||||
m_asymm_branch_delay = p.asymm_branch_delay();
|
||||
m_asymm_branch = p.asymm_branch();
|
||||
m_asymm_branch_rounds = p.asymm_branch_rounds();
|
||||
m_asymm_branch_delay = p.asymm_branch_delay();
|
||||
m_asymm_branch_sampled = p.asymm_branch_sampled();
|
||||
m_asymm_branch_limit = p.asymm_branch_limit();
|
||||
m_asymm_branch_all = p.asymm_branch_all();
|
||||
m_asymm_branch_limit = p.asymm_branch_limit();
|
||||
m_asymm_branch_all = p.asymm_branch_all();
|
||||
if (m_asymm_branch_limit > UINT_MAX)
|
||||
m_asymm_branch_limit = UINT_MAX;
|
||||
}
|
||||
|
@ -414,10 +460,13 @@ namespace sat {
|
|||
|
||||
void asymm_branch::collect_statistics(statistics & st) const {
|
||||
st.update("elim literals", m_elim_literals);
|
||||
st.update("hidden tautologies", m_hidden_tautologies);
|
||||
}
|
||||
|
||||
void asymm_branch::reset_statistics() {
|
||||
m_elim_literals = 0;
|
||||
m_elim_learned_literals = 0;
|
||||
m_hidden_tautologies = 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue