3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-27 08:28:44 +00:00

fix transitive reduction bug, eliminate blocked tag on binary clauses, separate BIG structure from scc

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-12-13 02:38:06 -08:00
commit 71c52396cb
26 changed files with 572 additions and 355 deletions

View file

@ -683,7 +683,7 @@ namespace sat {
// NB. u.index() > l.index() iff u.index() > (~l).index().
// since indices for the same boolean variables occupy
// two adjacent numbers.
if (u.index() > l.index() && is_stamped(u)) {
if (u.index() > l.index() && is_stamped(u) && ~l != u) {
add_arc(~l, ~u);
add_arc( u, l);
}
@ -692,7 +692,8 @@ namespace sat {
lits.reset();
if (w.is_ext_constraint() && m_s.m_ext->is_extended_binary(w.get_ext_constraint_idx(), lits)) {
for (literal u : lits) {
if (u.index() > l.index() && is_stamped(u)) {
// u is positive in lits, l is negative:
if (~l != u && u.index() > l.index() && is_stamped(u)) {
add_arc(~l, ~u);
add_arc( u, l);
}
@ -1033,6 +1034,7 @@ namespace sat {
}
propagate();
m_qhead = m_trail.size();
m_init_freevars = m_freevars.size();
TRACE("sat", m_s.display(tout); display(tout););
}
@ -2018,6 +2020,35 @@ namespace sat {
st.update("lh cube conflicts", m_cube_state.m_conflicts);
}
double lookahead::psat_heur() {
double h = 0.0;
for (bool_var x : m_freevars) {
literal l(x, false);
for (literal lit : m_binary[l.index()]) {
h += l.index() > lit.index() ? 1.0 / m_config.m_cube_psat_clause_base : 0.0;
}
for (literal lit : m_binary[(~l).index()]) {
h += l.index() > lit.index() ? 1.0 / m_config.m_cube_psat_clause_base : 0.0;
}
for (binary b : m_ternary[l.index()]) {
h += l.index() > b.m_u.index() && l.index() > b.m_v.index() ?
1.0 / pow(m_config.m_cube_psat_clause_base, 2) :
0.0;
}
for (binary b : m_ternary[(~l).index()]) {
h += l.index() > b.m_u.index() && l.index() > b.m_v.index() ?
1.0 / pow(m_config.m_cube_psat_clause_base, 2) :
0.0;
}
}
for (nary * n : m_nary_clauses) {
h += 1.0 / pow(m_config.m_cube_psat_clause_base, n->size() - 1);
}
h /= pow(m_freevars.size(), m_config.m_cube_psat_var_exp);
IF_VERBOSE(10, verbose_stream() << "(sat-cube-psat :val " << h << ")\n";);
return h;
}
lbool lookahead::cube(bool_var_vector const& vars, literal_vector& lits, unsigned backtrack_level) {
scoped_ext _scoped_ext(*this);
lits.reset();
@ -2062,9 +2093,14 @@ namespace sat {
}
backtrack_level = UINT_MAX;
depth = m_cube_state.m_cube.size();
if ((m_config.m_cube_cutoff != 0 && depth == m_config.m_cube_cutoff) ||
(m_config.m_cube_cutoff == 0 && m_freevars.size() < m_cube_state.m_freevars_threshold)) {
m_cube_state.m_freevars_threshold *= (1.0 - pow(m_config.m_cube_fraction, depth));
if ((m_config.m_cube_cutoff == depth_cutoff && depth == m_config.m_cube_depth) ||
(m_config.m_cube_cutoff == freevars_cutoff && m_freevars.size() <= m_init_freevars * m_config.m_cube_freevars) ||
(m_config.m_cube_cutoff == psat_cutoff && psat_heur() >= m_config.m_cube_psat_trigger) ||
(m_config.m_cube_cutoff == adaptive_freevars_cutoff && m_freevars.size() < m_cube_state.m_freevars_threshold) ||
(m_config.m_cube_cutoff == adaptive_psat_cutoff && psat_heur() >= m_cube_state.m_psat_threshold)) {
double dec = (1.0 - pow(m_config.m_cube_fraction, depth));
m_cube_state.m_freevars_threshold *= dec;
m_cube_state.m_psat_threshold *= dec;
set_conflict();
m_cube_state.inc_cutoff();
#if 0
@ -2077,10 +2113,12 @@ namespace sat {
return l_undef;
}
int prev_nfreevars = m_freevars.size();
double prev_psat = m_config.m_cube_cutoff == adaptive_psat_cutoff ? psat_heur() : DBL_MAX; // MN. only compute PSAT if enabled
literal lit = choose();
if (inconsistent()) {
TRACE("sat", tout << "inconsistent: " << m_cube_state.m_cube << "\n";);
m_cube_state.m_freevars_threshold = prev_nfreevars;
m_cube_state.m_psat_threshold = prev_psat;
m_cube_state.inc_conflict();
if (!backtrack(m_cube_state.m_cube, m_cube_state.m_is_decision)) return l_false;
continue;
@ -2332,8 +2370,8 @@ namespace sat {
}
}
scc scc(m_s, m_s.m_params);
scc.init_big(true);
big big;
big.init_big(m_s, true);
svector<std::pair<literal, literal>> candidates;
unsigned_vector bin_size(num_lits);
@ -2350,14 +2388,14 @@ namespace sat {
if (v == get_parent(v) &&
!m_s.was_eliminated(v.var()) &&
!imp.contains(std::make_pair(u.index(), v.index())) &&
!scc.reaches(u, v)) {
!big.connected(u, v)) {
candidates.push_back(std::make_pair(u, v));
}
}
}
for (unsigned count = 0; count < 5; ++count) {
scc.init_big(true);
big.init_big(m_s, true);
unsigned k = 0;
union_find_default_ctx ufctx;
union_find<union_find_default_ctx> uf(ufctx);
@ -2365,7 +2403,7 @@ namespace sat {
for (unsigned j = 0; j < candidates.size(); ++j) {
literal u = candidates[j].first;
literal v = candidates[j].second;
if (!scc.reaches(u, v)) {
if (!big.connected(u, v)) {
if (uf.find(u.index()) != uf.find(v.index())) {
++num_bins;
uf.merge(u.index(), v.index());
@ -2457,6 +2495,11 @@ namespace sat {
m_config.m_reward_type = m_s.m_config.m_lookahead_reward;
m_config.m_cube_cutoff = m_s.m_config.m_lookahead_cube_cutoff;
m_config.m_cube_fraction = m_s.m_config.m_lookahead_cube_fraction;
m_config.m_cube_depth = m_s.m_config.m_lookahead_cube_depth;
m_config.m_cube_freevars = m_s.m_config.m_lookahead_cube_freevars;
m_config.m_cube_psat_var_exp = m_s.m_config.m_lookahead_cube_psat_var_exp;
m_config.m_cube_psat_clause_base = m_s.m_config.m_lookahead_cube_psat_clause_base;
m_config.m_cube_psat_trigger = m_s.m_config.m_lookahead_cube_psat_trigger;
}
void lookahead::collect_statistics(statistics& st) const {