3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

add ite-finder, profile

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-01-05 13:35:14 -08:00
parent a6c3c18e74
commit e1fb74edc5
17 changed files with 321 additions and 168 deletions

View file

@ -102,7 +102,7 @@ namespace dd {
pdd pdd_manager::one() { return pdd(one_pdd, this); }
pdd pdd_manager::mk_or(pdd const& p, pdd const& q) { return p + q - (p*q); }
pdd pdd_manager::mk_xor(pdd const& p, pdd const& q) { return (p*q*2) - p - q; }
pdd pdd_manager::mk_xor(pdd const& p, pdd const& q) { if (m_semantics == mod2_e) return p + q; return (p*q*2) - p - q; }
pdd pdd_manager::mk_not(pdd const& p) { return 1 - p; }
pdd pdd_manager::subst_val(pdd const& p, vector<std::pair<unsigned, rational>> const& _s) {
@ -152,7 +152,7 @@ namespace dd {
}
}
pdd_manager::PDD pdd_manager::apply_rec(PDD p, PDD q, pdd_op op) {
pdd_manager::PDD pdd_manager::apply_rec(PDD p, PDD q, pdd_op op) {
switch (op) {
case pdd_sub_op:
if (is_zero(q)) return p;

View file

@ -75,6 +75,7 @@ namespace dd {
}
}
catch (pdd_manager::mem_out) {
IF_VERBOSE(2, verbose_stream() << "simplifier memout\n");
// done reduce
DEBUG_CODE(s.invariant(););
}
@ -400,6 +401,7 @@ namespace dd {
for (pdd const& p : simp_eqs) {
s.add(p);
}
IF_VERBOSE(10, verbose_stream() << "simp_linear " << simp_eqs.size() << "\n";);
return !simp_eqs.empty() && simplify_linear_step(false);
}
@ -425,13 +427,14 @@ namespace dd {
*/
void simplifier::exlin_augment(vector<uint_set> const& orbits, vector<pdd>& eqs) {
IF_VERBOSE(10, verbose_stream() << "pdd-exlin augment\n";);
unsigned nv = s.m.num_vars();
random_gen rand(s.m_config.m_random_seed);
unsigned modest_num_eqs = std::min(eqs.size(), 500u);
unsigned max_xlin_eqs = modest_num_eqs*modest_num_eqs + eqs.size();
unsigned modest_num_eqs = std::max(eqs.size(), 500u);
unsigned max_xlin_eqs = modest_num_eqs;
unsigned max_degree = 5;
TRACE("dd.solver", tout << "augment " << nv << "\n";
for (auto const& o : orbits) tout << o.num_elems() << "\n";
);
for (auto const& o : orbits) tout << o.num_elems() << "\n";);
vector<pdd> n_eqs;
unsigned start = rand();
for (unsigned _v = 0; _v < nv; ++_v) {
@ -440,15 +443,16 @@ namespace dd {
if (orbitv.empty()) continue;
pdd pv = s.m.mk_var(v);
for (pdd p : eqs) {
if (p.degree() > max_degree) continue;
for (unsigned w : p.free_vars()) {
if (v != w && orbitv.contains(w)) {
n_eqs.push_back(pv * p);
if (n_eqs.size() > max_xlin_eqs) {
goto end_of_new_eqs;
}
break;
}
}
if (n_eqs.size() > max_xlin_eqs) {
goto end_of_new_eqs;
}
}
}
@ -462,12 +466,13 @@ namespace dd {
if (v >= w) continue;
pdd pw = s.m.mk_var(w);
for (pdd p : eqs) {
if (n_eqs.size() > max_xlin_eqs) {
goto end_of_new_eqs;
}
if (p.degree() + 1 > max_degree) continue;
for (unsigned u : p.free_vars()) {
if (orbits[w].contains(u) || orbits[v].contains(u)) {
n_eqs.push_back(pw * pv * p);
if (n_eqs.size() > max_xlin_eqs) {
goto end_of_new_eqs;
}
break;
}
}
@ -481,22 +486,53 @@ namespace dd {
}
void simplifier::simplify_exlin(vector<uint_set> const& orbits, vector<pdd> const& eqs, vector<pdd>& simp_eqs) {
IF_VERBOSE(10, verbose_stream() << "pdd simplify-exlin\n";);
// index monomials
unsigned_vector vars;
struct mon {
unsigned sz;
unsigned offset;
unsigned index;
unsigned_vector* vars;
mon(unsigned sz, unsigned offset, unsigned_vector* vars): sz(sz), offset(offset), index(UINT_MAX), vars(vars) {}
mon(): sz(0), offset(0), index(UINT_MAX), vars(nullptr) {}
bool is_valid() const { return index != UINT_MAX; }
struct hash {
bool operator()(mon const& m) const {
if (!m.vars) return 0;
return string_hash((const char*)(m.vars->c_ptr() + m.offset), m.sz*4, 1);
};
};
struct eq {
bool operator()(mon const& a, mon const& b) const {
if (a.sz != b.sz) return false;
for (unsigned i = 0; i < a.sz; ++i)
if ((*a.vars)[a.offset+i] != (*b.vars)[b.offset+i]) return false;
return true;
}
};
};
hashtable<mon, mon::hash, mon::eq> mon2idx;
svector<mon> idx2mon;
// create variables for each non-constant monomial.
u_map<unsigned> mon2idx;
vector<pdd> idx2mon;
auto insert_mon = [&,this](unsigned n, unsigned const* vs) {
mon mm(n, vars.size(), &vars);
vars.append(n, vs);
auto* e = mon2idx.insert_if_not_there2(mm);
if (!e->get_data().is_valid()) {
e->get_data().index = idx2mon.size();
idx2mon.push_back(e->get_data());
}
else {
vars.shrink(vars.size() - n);
}
};
// insert monomials of degree > 1
for (pdd const& p : eqs) {
for (auto const& m : p) {
if (m.vars.size() <= 1) continue;
pdd r = s.m.mk_val(m.coeff);
for (unsigned i = m.vars.size(); i-- > 0; )
r *= s.m.mk_var(m.vars[i]);
if (!mon2idx.contains(r.index())) {
mon2idx.insert(r.index(), idx2mon.size());
idx2mon.push_back(r);
}
insert_mon(m.vars.size(), m.vars.c_ptr());
}
}
@ -504,12 +540,13 @@ namespace dd {
unsigned nv = s.m.num_vars();
for (unsigned v = 0; v < nv; ++v) {
if (!orbits[v].empty()) { // not all variables are used.
pdd r = s.m.mk_var(v);
mon2idx.insert(r.index(), idx2mon.size());
idx2mon.push_back(r);
insert_mon(1, &v);
}
}
IF_VERBOSE(10, verbose_stream() << "extracted monomials: " << idx2mon.size() << "\n";);
bit_matrix bm;
unsigned const_idx = idx2mon.size();
bm.reset(const_idx + 1);
@ -526,19 +563,22 @@ namespace dd {
row.set(const_idx);
continue;
}
pdd r = s.m.one();
for (unsigned i = m.vars.size(); i-- > 0; )
r *= s.m.mk_var(m.vars[i]);
unsigned v = mon2idx[r.index()];
row.set(v);
unsigned n = m.vars.size();
mon mm(n, vars.size(), &vars);
vars.append(n, m.vars.c_ptr());
VERIFY(mon2idx.find(mm, mm));
vars.shrink(vars.size() - n);
row.set(mm.index);
}
}
TRACE("dd.solver", tout << bm << "\n";);
IF_VERBOSE(10, verbose_stream() << "bit-matrix solving\n");
bm.solve();
TRACE("dd.solver", tout << bm << "\n";);
IF_VERBOSE(10, verbose_stream() << "bit-matrix solved\n");
for (auto const& r : bm) {
bool is_linear = true;
@ -547,8 +587,7 @@ namespace dd {
if (c == const_idx) {
break;
}
pdd const& p = idx2mon[c];
if (!p.is_unary()) {
if (idx2mon[c].sz != 1) {
is_linear = false;
break;
}
@ -561,7 +600,8 @@ namespace dd {
p += s.m.one();
}
else {
p += idx2mon[c];
mon const& mm = idx2mon[c];
p += s.m.mk_var(vars[mm.offset]);
}
}
if (!p.is_zero()) {

View file

@ -14,6 +14,7 @@ Notes:
--*/
#include "math/simplex/bit_matrix.h"
#include "util/stopwatch.h"
bit_matrix::col_iterator bit_matrix::row::begin() const {
@ -68,11 +69,22 @@ bit_matrix::row& bit_matrix::row::operator+=(row const& other) {
return *this;
}
struct bit_matrix::report {
bit_matrix& b;
stopwatch m_watch;
report(bit_matrix& b) : b(b) { m_watch.start(); }
~report() {
m_watch.stop();
IF_VERBOSE(10, verbose_stream() << "solve " << b.m_rows.size() << " " << b.m_num_columns << " " << m_watch << "\n");
}
};
void bit_matrix::solve() {
basic_solve();
}
void bit_matrix::basic_solve() {
report _report(*this);
for (row& r : *this) {
auto ci = r.begin();
if (ci != r.end()) {

View file

@ -33,6 +33,8 @@ class bit_matrix {
unsigned m_num_chunks;
ptr_vector<uint64_t> m_rows;
struct report;
public:
class col_iterator;