mirror of
https://github.com/Z3Prover/z3
synced 2025-07-18 18:36:41 +00:00
integrate aig further
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
ca243428f8
commit
20618ff3b3
3 changed files with 80 additions and 44 deletions
|
@ -38,29 +38,43 @@ namespace sat {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
aig_simplifier::aig_simplifier(solver& s):s(s), m_aig_cuts(m_config.m_max_cut_size, m_config.m_max_cutset_size) {
|
aig_simplifier::aig_simplifier(solver& s):
|
||||||
|
s(s),
|
||||||
|
m_aig_cuts(m_config.m_max_cut_size, m_config.m_max_cutset_size),
|
||||||
|
m_trail_size(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void aig_simplifier::add_and(literal head, unsigned sz, literal const* lits) {
|
void aig_simplifier::add_and(literal head, unsigned sz, literal const* lits) {
|
||||||
m_aig_cuts.add_node(head, and_op, sz, lits);
|
m_aig_cuts.add_node(head, and_op, sz, lits);
|
||||||
|
m_stats.m_num_ands++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// head == l1 or l2 or l3
|
||||||
|
// <=>
|
||||||
|
// ~head == ~l1 and ~l2 and ~l3
|
||||||
void aig_simplifier::add_or(literal head, unsigned sz, literal const* lits) {
|
void aig_simplifier::add_or(literal head, unsigned sz, literal const* lits) {
|
||||||
m_aig_cuts.add_node(head, and_op, sz, lits);
|
m_lits.reset();
|
||||||
|
m_lits.append(sz, lits);
|
||||||
|
for (unsigned i = 0; i < sz; ++i) m_lits[i].neg();
|
||||||
|
m_aig_cuts.add_node(~head, and_op, sz, m_lits.c_ptr());
|
||||||
|
m_stats.m_num_ands++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aig_simplifier::add_xor(literal head, unsigned sz, literal const* lits) {
|
void aig_simplifier::add_xor(literal head, unsigned sz, literal const* lits) {
|
||||||
m_aig_cuts.add_node(head, xor_op, sz, lits);
|
m_aig_cuts.add_node(head, xor_op, sz, lits);
|
||||||
|
m_stats.m_num_xors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aig_simplifier::add_ite(literal head, literal c, literal t, literal e) {
|
void aig_simplifier::add_ite(literal head, literal c, literal t, literal e) {
|
||||||
literal lits[3] = { c, t, e };
|
literal lits[3] = { c, t, e };
|
||||||
m_aig_cuts.add_node(head, ite_op, 3, lits);
|
m_aig_cuts.add_node(head, ite_op, 3, lits);
|
||||||
|
m_stats.m_num_ites++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aig_simplifier::add_iff(literal head, literal l1, literal l2) {
|
void aig_simplifier::add_iff(literal head, literal l1, literal l2) {
|
||||||
literal lits[2] = { l1, ~l2 };
|
literal lits[2] = { l1, ~l2 };
|
||||||
m_aig_cuts.add_node(head, xor_op, 2, lits);
|
m_aig_cuts.add_node(head, xor_op, 2, lits);
|
||||||
|
m_stats.m_num_xors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aig_simplifier::operator()() {
|
void aig_simplifier::operator()() {
|
||||||
|
@ -75,7 +89,14 @@ namespace sat {
|
||||||
Ensure that they are sorted and variables have unique definitions.
|
Ensure that they are sorted and variables have unique definitions.
|
||||||
*/
|
*/
|
||||||
void aig_simplifier::clauses2aig() {
|
void aig_simplifier::clauses2aig() {
|
||||||
literal_vector literals;
|
|
||||||
|
// update units
|
||||||
|
for (; m_trail_size < s.init_trail_size(); ++m_trail_size) {
|
||||||
|
literal lit = s.trail_literal(m_trail_size);
|
||||||
|
m_aig_cuts.add_node(lit, and_op, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::function<void (literal head, literal_vector const& ands)> on_and =
|
std::function<void (literal head, literal_vector const& ands)> on_and =
|
||||||
[&,this](literal head, literal_vector const& ands) {
|
[&,this](literal head, literal_vector const& ands) {
|
||||||
m_aig_cuts.add_node(head, and_op, ands.size(), ands.c_ptr());
|
m_aig_cuts.add_node(head, and_op, ands.size(), ands.c_ptr());
|
||||||
|
@ -112,10 +133,10 @@ namespace sat {
|
||||||
unsigned sz = xors.size() - 1;
|
unsigned sz = xors.size() - 1;
|
||||||
for (unsigned i = xors.size(); i-- > 0; ) {
|
for (unsigned i = xors.size(); i-- > 0; ) {
|
||||||
if (i != index)
|
if (i != index)
|
||||||
literals.push_back(xors[i]);
|
m_lits.push_back(xors[i]);
|
||||||
}
|
}
|
||||||
m_aig_cuts.add_node(head, xor_op, sz, literals.c_ptr());
|
m_aig_cuts.add_node(head, xor_op, sz, m_lits.c_ptr());
|
||||||
literals.reset();
|
m_lits.reset();
|
||||||
m_stats.m_num_xors++;
|
m_stats.m_num_xors++;
|
||||||
};
|
};
|
||||||
xor_finder xf(s);
|
xor_finder xf(s);
|
||||||
|
@ -134,7 +155,7 @@ namespace sat {
|
||||||
uf.merge(l1.index(), l2.index());
|
uf.merge(l1.index(), l2.index());
|
||||||
uf.merge((~l1).index(), (~l2).index());
|
uf.merge((~l1).index(), (~l2).index());
|
||||||
};
|
};
|
||||||
unsigned old_num_eqs = m_stats.m_num_eqs;
|
bool new_eq = false;
|
||||||
for (unsigned i = cuts.size(); i-- > 0; ) {
|
for (unsigned i = cuts.size(); i-- > 0; ) {
|
||||||
m_stats.m_num_cuts += cuts[i].size();
|
m_stats.m_num_cuts += cuts[i].size();
|
||||||
for (auto& cut : cuts[i]) {
|
for (auto& cut : cuts[i]) {
|
||||||
|
@ -145,7 +166,7 @@ namespace sat {
|
||||||
literal w(j, false);
|
literal w(j, false);
|
||||||
add_eq(v, w);
|
add_eq(v, w);
|
||||||
TRACE("aig_simplifier", tout << v << " == " << ~w << "\n";);
|
TRACE("aig_simplifier", tout << v << " == " << ~w << "\n";);
|
||||||
++m_stats.m_num_eqs;
|
new_eq = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cut.negate();
|
cut.negate();
|
||||||
|
@ -154,16 +175,19 @@ namespace sat {
|
||||||
literal w(j, true);
|
literal w(j, true);
|
||||||
add_eq(v, w);
|
add_eq(v, w);
|
||||||
TRACE("aig_simplifier", tout << v << " == " << w << "\n";);
|
TRACE("aig_simplifier", tout << v << " == " << w << "\n";);
|
||||||
++m_stats.m_num_eqs;
|
new_eq = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cut.negate();
|
cut.negate();
|
||||||
cut2id.insert(&cut, i);
|
cut2id.insert(&cut, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (old_num_eqs < m_stats.m_num_eqs) {
|
if (!new_eq) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new_eq = false;
|
||||||
|
for (unsigned i = 2*s.num_vars(); i--> 0; ) uf2.mk_var();
|
||||||
// extract equivalences over non-eliminated literals.
|
// extract equivalences over non-eliminated literals.
|
||||||
bool new_eq = false;
|
|
||||||
for (unsigned idx = 0; idx < uf.get_num_vars(); ++idx) {
|
for (unsigned idx = 0; idx < uf.get_num_vars(); ++idx) {
|
||||||
if (!uf.is_root(idx) || 1 == uf.size(idx)) continue;
|
if (!uf.is_root(idx) || 1 == uf.size(idx)) continue;
|
||||||
literal root = null_literal;
|
literal root = null_literal;
|
||||||
|
@ -177,18 +201,19 @@ namespace sat {
|
||||||
else {
|
else {
|
||||||
uf2.merge(lit.index(), root.index());
|
uf2.merge(lit.index(), root.index());
|
||||||
new_eq = true;
|
new_eq = true;
|
||||||
|
++m_stats.m_num_eqs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx = uf.next(idx);
|
idx = uf.next(idx);
|
||||||
}
|
}
|
||||||
while (first != idx);
|
while (first != idx);
|
||||||
}
|
}
|
||||||
if (new_eq) {
|
if (!new_eq) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
elim_eqs elim(s);
|
elim_eqs elim(s);
|
||||||
elim(uf2);
|
elim(uf2);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void aig_simplifier::collect_statistics(statistics& st) const {
|
void aig_simplifier::collect_statistics(statistics& st) const {
|
||||||
st.update("sat-aig.eqs", m_stats.m_num_eqs);
|
st.update("sat-aig.eqs", m_stats.m_num_eqs);
|
||||||
|
@ -272,8 +297,11 @@ namespace sat {
|
||||||
SASSERT(n.is_and());
|
SASSERT(n.is_and());
|
||||||
cut c;
|
cut c;
|
||||||
cs.reset();
|
cs.reset();
|
||||||
if (!n.sign()) {
|
if (n.sign()) {
|
||||||
c.m_table = 3;
|
c.m_table = 0; // constant false
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c.m_table = 0x3; // constant true
|
||||||
}
|
}
|
||||||
cs.insert(c);
|
cs.insert(c);
|
||||||
}
|
}
|
||||||
|
@ -374,7 +402,7 @@ namespace sat {
|
||||||
add_var(args[i].var());
|
add_var(args[i].var());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!m_aig[v].is_valid() || m_aig[v].is_var()) {
|
if (!m_aig[v].is_valid() || m_aig[v].is_var() || (sz == 0)) {
|
||||||
m_aig[v] = n;
|
m_aig[v] = n;
|
||||||
init_cut_set(v);
|
init_cut_set(v);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +417,10 @@ namespace sat {
|
||||||
SASSERT(n.is_valid());
|
SASSERT(n.is_valid());
|
||||||
auto& cut_set = m_cuts[id];
|
auto& cut_set = m_cuts[id];
|
||||||
cut_set.init(m_region, m_max_cutset_size + 1);
|
cut_set.init(m_region, m_max_cutset_size + 1);
|
||||||
cut_set.push_back(cut(id));
|
cut_set.push_back(cut(id)); // TBD: if entry is a constant?
|
||||||
|
if (m_aux_aig.size() < id) {
|
||||||
|
m_aux_aig[id].reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void aig_cuts::insert_aux(unsigned v, node const& n) {
|
void aig_cuts::insert_aux(unsigned v, node const& n) {
|
||||||
|
|
|
@ -100,6 +100,8 @@ namespace sat {
|
||||||
stats m_stats;
|
stats m_stats;
|
||||||
config m_config;
|
config m_config;
|
||||||
aig_cuts m_aig_cuts;
|
aig_cuts m_aig_cuts;
|
||||||
|
unsigned m_trail_size;
|
||||||
|
literal_vector m_lits;
|
||||||
|
|
||||||
struct report;
|
struct report;
|
||||||
void clauses2aig();
|
void clauses2aig();
|
||||||
|
|
|
@ -1937,10 +1937,9 @@ namespace sat {
|
||||||
// TBD: throttle anf_delay based on yield
|
// TBD: throttle anf_delay based on yield
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_config.m_aig_simplify && m_simplifications > m_config.m_aig_delay && !inconsistent()) {
|
if (m_aig_simplifier && m_simplifications > m_config.m_aig_delay && !inconsistent()) {
|
||||||
aig_simplifier aig(*this);
|
(*m_aig_simplifier)();
|
||||||
aig();
|
m_aig_simplifier->collect_statistics(m_aux_stats);
|
||||||
aig.collect_statistics(m_aux_stats);
|
|
||||||
// TBD: throttle aig_delay based on yield
|
// TBD: throttle aig_delay based on yield
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3922,6 +3921,10 @@ namespace sat {
|
||||||
m_fast_glue_backup.set_alpha(m_config.m_fast_glue_avg);
|
m_fast_glue_backup.set_alpha(m_config.m_fast_glue_avg);
|
||||||
m_slow_glue_backup.set_alpha(m_config.m_slow_glue_avg);
|
m_slow_glue_backup.set_alpha(m_config.m_slow_glue_avg);
|
||||||
m_trail_avg.set_alpha(m_config.m_slow_glue_avg);
|
m_trail_avg.set_alpha(m_config.m_slow_glue_avg);
|
||||||
|
|
||||||
|
if (m_config.m_aig_simplify && !m_aig_simplifier) {
|
||||||
|
m_aig_simplifier = alloc(aig_simplifier, *this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::collect_param_descrs(param_descrs & d) {
|
void solver::collect_param_descrs(param_descrs & d) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue