mirror of
https://github.com/Z3Prover/z3
synced 2025-06-06 14:13:23 +00:00
some micro tuning
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
8b23a1701a
commit
200f47369d
6 changed files with 81 additions and 12 deletions
|
@ -61,6 +61,9 @@ namespace sat {
|
||||||
else if (n.is_var()) {
|
else if (n.is_var()) {
|
||||||
SASSERT(!n.sign());
|
SASSERT(!n.sign());
|
||||||
}
|
}
|
||||||
|
else if (n.is_lut()) {
|
||||||
|
augment_lut(id, n, cs);
|
||||||
|
}
|
||||||
else if (n.is_ite()) {
|
else if (n.is_ite()) {
|
||||||
augment_ite(id, n, cs);
|
augment_ite(id, n, cs);
|
||||||
}
|
}
|
||||||
|
@ -97,6 +100,47 @@ namespace sat {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void aig_cuts::augment_lut(unsigned v, node const& n, cut_set& cs) {
|
||||||
|
IF_VERBOSE(4, display(verbose_stream() << "augment_lut " << v << " ", n) << "\n");
|
||||||
|
literal l1 = child(n, 0);
|
||||||
|
for (auto const& a : m_cuts[l1.var()]) {
|
||||||
|
m_tables[0] = &a;
|
||||||
|
cut b(a);
|
||||||
|
augment_lut_rec(v, n, b, 1, cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void aig_cuts::augment_lut_rec(unsigned v, node const& n, cut& a, unsigned idx, cut_set& cs) {
|
||||||
|
if (idx < n.size()) {
|
||||||
|
for (auto const& b : m_cuts[child(n, idx).var()]) {
|
||||||
|
cut ab;
|
||||||
|
if (ab.merge(a, b)) {
|
||||||
|
m_tables[idx] = &b;
|
||||||
|
augment_lut_rec(v, n, ab, idx + 1, cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < n.size(); ++i) {
|
||||||
|
m_luts[i] = m_tables[i]->shift_table(a);
|
||||||
|
}
|
||||||
|
uint64_t r = 0;
|
||||||
|
SASSERT(a.size() <= 6);
|
||||||
|
SASSERT(n.size() <= 6);
|
||||||
|
for (unsigned j = (1u << a.size()); j-- > 0; ) {
|
||||||
|
unsigned w = 0;
|
||||||
|
// when computing the output at position j,
|
||||||
|
// the i'th bit to index into n.lut() is
|
||||||
|
// based on the j'th output bit in lut[i]
|
||||||
|
for (unsigned i = n.size(); i-- > 0; ) {
|
||||||
|
w |= ((m_luts[i] >> j) & 0x1) << i;
|
||||||
|
}
|
||||||
|
r |= ((n.lut() >> w) & 0x1) << j;
|
||||||
|
}
|
||||||
|
a.set_table(r);
|
||||||
|
insert_cut(v, a, cs);
|
||||||
|
}
|
||||||
|
|
||||||
void aig_cuts::augment_ite(unsigned v, node const& n, cut_set& cs) {
|
void aig_cuts::augment_ite(unsigned v, node const& n, cut_set& cs) {
|
||||||
IF_VERBOSE(4, display(verbose_stream() << "augment_ite " << v << " ", n) << "\n");
|
IF_VERBOSE(4, display(verbose_stream() << "augment_ite " << v << " ", n) << "\n");
|
||||||
literal l1 = child(n, 0);
|
literal l1 = child(n, 0);
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace sat {
|
||||||
and_op,
|
and_op,
|
||||||
ite_op,
|
ite_op,
|
||||||
xor_op,
|
xor_op,
|
||||||
|
lut_op,
|
||||||
no_op
|
no_op
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ namespace sat {
|
||||||
case and_op: return out << "&";
|
case and_op: return out << "&";
|
||||||
case ite_op: return out << "?";
|
case ite_op: return out << "?";
|
||||||
case xor_op: return out << "^";
|
case xor_op: return out << "^";
|
||||||
|
case lut_op: return out << "#";
|
||||||
default: return out << "";
|
default: return out << "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +71,7 @@ namespace sat {
|
||||||
class node {
|
class node {
|
||||||
bool m_sign;
|
bool m_sign;
|
||||||
bool_op m_op;
|
bool_op m_op;
|
||||||
|
uint64_t m_lut;
|
||||||
unsigned m_size;
|
unsigned m_size;
|
||||||
unsigned m_offset;
|
unsigned m_offset;
|
||||||
public:
|
public:
|
||||||
|
@ -78,17 +81,21 @@ namespace sat {
|
||||||
m_sign(false), m_op(var_op), m_size(0), m_offset(v) {}
|
m_sign(false), m_op(var_op), m_size(0), m_offset(v) {}
|
||||||
explicit node(bool sign, bool_op op, unsigned nc, unsigned o) :
|
explicit node(bool sign, bool_op op, unsigned nc, unsigned o) :
|
||||||
m_sign(sign), m_op(op), m_size(nc), m_offset(o) {}
|
m_sign(sign), m_op(op), m_size(nc), m_offset(o) {}
|
||||||
|
explicit node(uint64_t lut, unsigned nc, unsigned o):
|
||||||
|
m_sign(false), m_op(lut_op), m_size(nc), m_offset(o) {}
|
||||||
bool is_valid() const { return m_offset != UINT_MAX; }
|
bool is_valid() const { return m_offset != UINT_MAX; }
|
||||||
bool_op op() const { return m_op; }
|
bool_op op() const { return m_op; }
|
||||||
bool is_var() const { return m_op == var_op; }
|
bool is_var() const { return m_op == var_op; }
|
||||||
bool is_and() const { return m_op == and_op; }
|
bool is_and() const { return m_op == and_op; }
|
||||||
bool is_xor() const { return m_op == xor_op; }
|
bool is_xor() const { return m_op == xor_op; }
|
||||||
bool is_ite() const { return m_op == ite_op; }
|
bool is_ite() const { return m_op == ite_op; }
|
||||||
|
bool is_lut() const { return m_op == lut_op; }
|
||||||
bool is_const() const { return is_and() && size() == 0; }
|
bool is_const() const { return is_and() && size() == 0; }
|
||||||
unsigned var() const { SASSERT(is_var()); return m_offset; }
|
unsigned var() const { SASSERT(is_var()); return m_offset; }
|
||||||
bool sign() const { return m_sign; }
|
bool sign() const { return m_sign; }
|
||||||
unsigned size() const { return m_size; }
|
unsigned size() const { return m_size; }
|
||||||
unsigned offset() const { return m_offset; }
|
unsigned offset() const { return m_offset; }
|
||||||
|
uint64_t lut() const { return m_lut; }
|
||||||
};
|
};
|
||||||
random_gen m_rand;
|
random_gen m_rand;
|
||||||
config m_config;
|
config m_config;
|
||||||
|
@ -106,6 +113,8 @@ namespace sat {
|
||||||
on_clause_t m_on_clause_add, m_on_clause_del;
|
on_clause_t m_on_clause_add, m_on_clause_del;
|
||||||
cut_set::on_update_t m_on_cut_add, m_on_cut_del;
|
cut_set::on_update_t m_on_cut_add, m_on_cut_del;
|
||||||
literal_vector m_clause;
|
literal_vector m_clause;
|
||||||
|
cut const* m_tables[6];
|
||||||
|
uint64_t m_luts[6];
|
||||||
|
|
||||||
bool is_touched(bool_var v, node const& n);
|
bool is_touched(bool_var v, node const& n);
|
||||||
bool is_touched(literal lit) const { return is_touched(lit.var()); }
|
bool is_touched(literal lit) const { return is_touched(lit.var()); }
|
||||||
|
@ -119,12 +128,15 @@ namespace sat {
|
||||||
unsigned_vector filter_valid_nodes() const;
|
unsigned_vector filter_valid_nodes() const;
|
||||||
void augment(unsigned_vector const& ids);
|
void augment(unsigned_vector const& ids);
|
||||||
void augment(unsigned id, node const& n);
|
void augment(unsigned id, node const& n);
|
||||||
void augment_ite(unsigned v, node const& n, cut_set& cs);
|
void augment_ite(unsigned v, node const& n, cut_set& cs);
|
||||||
void augment_aig0(unsigned v, node const& n, cut_set& cs);
|
void augment_aig0(unsigned v, node const& n, cut_set& cs);
|
||||||
void augment_aig1(unsigned v, node const& n, cut_set& cs);
|
void augment_aig1(unsigned v, node const& n, cut_set& cs);
|
||||||
void augment_aig2(unsigned v, node const& n, cut_set& cs);
|
void augment_aig2(unsigned v, node const& n, cut_set& cs);
|
||||||
void augment_aigN(unsigned v, node const& n, cut_set& cs);
|
void augment_aigN(unsigned v, node const& n, cut_set& cs);
|
||||||
|
|
||||||
|
void augment_lut(unsigned v, node const& n, cut_set& cs);
|
||||||
|
void augment_lut_rec(unsigned v, node const& n, cut& a, unsigned idx, cut_set& cs);
|
||||||
|
|
||||||
bool insert_cut(unsigned v, cut const& c, cut_set& cs);
|
bool insert_cut(unsigned v, cut const& c, cut_set& cs);
|
||||||
|
|
||||||
void flush_roots();
|
void flush_roots();
|
||||||
|
|
|
@ -277,6 +277,9 @@ void asserted_formulas::reduce() {
|
||||||
TRACE("macros", m_macro_manager.display(tout););
|
TRACE("macros", m_macro_manager.display(tout););
|
||||||
flush_cache();
|
flush_cache();
|
||||||
CASSERT("well_sorted",check_well_sorted());
|
CASSERT("well_sorted",check_well_sorted());
|
||||||
|
|
||||||
|
// display(std::cout);
|
||||||
|
// exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2003,12 +2003,14 @@ namespace smt {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void context::add_lit_occs(clause const& cls) {
|
void context::add_lit_occs(clause const& cls) {
|
||||||
|
if (!track_occs()) return;
|
||||||
for (literal l : cls) {
|
for (literal l : cls) {
|
||||||
inc_ref(l);
|
inc_ref(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::remove_lit_occs(clause const& cls, unsigned nbv) {
|
void context::remove_lit_occs(clause const& cls, unsigned nbv) {
|
||||||
|
if (!track_occs()) return;
|
||||||
for (literal l : cls) {
|
for (literal l : cls) {
|
||||||
if (l.var() < static_cast<int>(nbv))
|
if (l.var() < static_cast<int>(nbv))
|
||||||
dec_ref(l);
|
dec_ref(l);
|
||||||
|
@ -2016,9 +2018,9 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TBD: enable as assertion when ready to re-check
|
// TBD: enable as assertion when ready to re-check
|
||||||
void context::dec_ref(literal l) { if (m_lit_occs[l.index()] > 0) m_lit_occs[l.index()]--; }
|
void context::dec_ref(literal l) { if (track_occs() && m_lit_occs[l.index()] > 0) m_lit_occs[l.index()]--; }
|
||||||
|
|
||||||
void context::inc_ref(literal l) { m_lit_occs[l.index()]++; }
|
void context::inc_ref(literal l) { if (track_occs()) m_lit_occs[l.index()]++; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Delete the given clause.
|
\brief Delete the given clause.
|
||||||
|
|
|
@ -839,6 +839,8 @@ namespace smt {
|
||||||
|
|
||||||
void mk_ite_cnstr(app * n);
|
void mk_ite_cnstr(app * n);
|
||||||
|
|
||||||
|
bool track_occs() const { return m_fparams.m_phase_selection == PS_THEORY; }
|
||||||
|
|
||||||
void dec_ref(literal l);
|
void dec_ref(literal l);
|
||||||
|
|
||||||
void inc_ref(literal l);
|
void inc_ref(literal l);
|
||||||
|
|
|
@ -357,7 +357,8 @@ class theory_lra::imp {
|
||||||
scoped_ptr<lp::lar_solver> m_solver;
|
scoped_ptr<lp::lar_solver> m_solver;
|
||||||
resource_limit m_resource_limit;
|
resource_limit m_resource_limit;
|
||||||
lp_bounds m_new_bounds;
|
lp_bounds m_new_bounds;
|
||||||
switcher m_switcher;
|
switcher m_switcher;
|
||||||
|
symbol m_farkas;
|
||||||
|
|
||||||
context& ctx() const { return th.get_context(); }
|
context& ctx() const { return th.get_context(); }
|
||||||
theory_id get_id() const { return th.get_id(); }
|
theory_id get_id() const { return th.get_id(); }
|
||||||
|
@ -1001,7 +1002,8 @@ public:
|
||||||
m_model_eqs(DEFAULT_HASHTABLE_INITIAL_CAPACITY, var_value_hash(*this), var_value_eq(*this)),
|
m_model_eqs(DEFAULT_HASHTABLE_INITIAL_CAPACITY, var_value_hash(*this), var_value_eq(*this)),
|
||||||
m_solver(nullptr),
|
m_solver(nullptr),
|
||||||
m_resource_limit(*this),
|
m_resource_limit(*this),
|
||||||
m_switcher(*this) {
|
m_switcher(*this),
|
||||||
|
m_farkas("farkas") {
|
||||||
}
|
}
|
||||||
|
|
||||||
~imp() {
|
~imp() {
|
||||||
|
@ -1911,17 +1913,19 @@ public:
|
||||||
if (m_idiv_terms.empty()) {
|
if (m_idiv_terms.empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
init_variable_values();
|
// init_variable_values();
|
||||||
bool all_divs_valid = true;
|
bool all_divs_valid = true;
|
||||||
for (expr* n : m_idiv_terms) {
|
for (expr* n : m_idiv_terms) {
|
||||||
expr* p = nullptr, *q = nullptr;
|
expr* p = nullptr, *q = nullptr;
|
||||||
VERIFY(a.is_idiv(n, p, q));
|
VERIFY(a.is_idiv(n, p, q));
|
||||||
theory_var v = mk_var(n);
|
theory_var v = mk_var(n);
|
||||||
theory_var v1 = mk_var(p);
|
theory_var v1 = mk_var(p);
|
||||||
rational r1 = get_value(v1);
|
lp::impq r1 = get_ivalue(v1);
|
||||||
|
SASSERT(r1.y.is_zero());
|
||||||
|
SASSERT(r1.x.is_int());
|
||||||
rational r2;
|
rational r2;
|
||||||
|
|
||||||
if (!r1.is_int() || r1.is_neg()) {
|
if (!r1.x.is_int() || r1.x.is_neg()) {
|
||||||
// TBD
|
// TBD
|
||||||
// r1 = 223/4, r2 = 2, r = 219/8
|
// r1 = 223/4, r2 = 2, r = 219/8
|
||||||
// take ceil(r1), floor(r1), ceil(r2), floor(r2), for floor(r2) > 0
|
// take ceil(r1), floor(r1), ceil(r2), floor(r2), for floor(r2) > 0
|
||||||
|
@ -1932,15 +1936,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.is_numeral(q, r2) && r2.is_pos()) {
|
if (a.is_numeral(q, r2) && r2.is_pos()) {
|
||||||
rational val_v = get_value(v);
|
|
||||||
if (val_v == div(r1, r2)) continue;
|
|
||||||
if (!is_bounded(n)) {
|
if (!is_bounded(n)) {
|
||||||
TRACE("arith", tout << "unbounded " << expr_ref(n, m) << "\n";);
|
TRACE("arith", tout << "unbounded " << expr_ref(n, m) << "\n";);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
lp::impq val_v = get_ivalue(v);
|
||||||
|
SASSERT(val_v.y.is_zero());
|
||||||
|
SASSERT(val_v.x.is_int());
|
||||||
|
if (val_v.x == div(r1.x, r2)) continue;
|
||||||
|
|
||||||
TRACE("arith", tout << get_value(v) << " != " << r1 << " div " << r2 << "\n";);
|
TRACE("arith", tout << get_value(v) << " != " << r1 << " div " << r2 << "\n";);
|
||||||
rational div_r = div(r1, r2);
|
rational div_r = div(r1.x, r2);
|
||||||
// p <= q * div(r1, q) + q - 1 => div(p, q) <= div(r1, r2)
|
// p <= q * div(r1, q) + q - 1 => div(p, q) <= div(r1, r2)
|
||||||
// p >= q * div(r1, q) => div(r1, q) <= div(p, q)
|
// p >= q * div(r1, q) => div(r1, q) <= div(p, q)
|
||||||
rational mul(1);
|
rational mul(1);
|
||||||
|
@ -2842,7 +2848,7 @@ public:
|
||||||
m_core.reset();
|
m_core.reset();
|
||||||
m_eqs.reset();
|
m_eqs.reset();
|
||||||
m_core.push_back(lit1);
|
m_core.push_back(lit1);
|
||||||
m_params.push_back(parameter(symbol("farkas")));
|
m_params.push_back(parameter(m_farkas));
|
||||||
m_params.push_back(parameter(rational(1)));
|
m_params.push_back(parameter(rational(1)));
|
||||||
m_params.push_back(parameter(rational(1)));
|
m_params.push_back(parameter(rational(1)));
|
||||||
assign(lit2);
|
assign(lit2);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue