3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-19 02:42:02 +00:00

streamline condition, fix bugs in doc::subtract

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-09-22 01:54:51 -07:00
parent 3203b6e2db
commit 8c34cfca31
3 changed files with 19 additions and 22 deletions

View file

@ -119,6 +119,12 @@ bool doc_manager::set_and(doc& dst, doc const& src) {
} }
return (src.neg().is_empty() || fold_neg(dst)); return (src.neg().is_empty() || fold_neg(dst));
} }
bool doc_manager::set_and(doc& dst, tbv const& src) {
// (A \ B) & C = (A & C) \ B
if (!m.set_and(dst.pos(), src)) return false;
dst.neg().intersect(m, src);
return true;
}
bool doc_manager::well_formed(doc const& d) const { bool doc_manager::well_formed(doc const& d) const {
if (!m.is_well_formed(d.pos())) return false; if (!m.is_well_formed(d.pos())) return false;
@ -404,23 +410,21 @@ void doc_manager::complement(doc const& src, ptr_vector<doc>& result) {
// (A & !A1 & & !B) | (A & B1 & !A1) // (A & !A1 & & !B) | (A & B1 & !A1)
// A \ {A1 u B} u (A & B1) \ {A1} // A \ {A1 u B} u (A & B1) \ {A1}
void doc_manager::subtract(doc const& A, doc const& B, ptr_vector<doc>& result) { void doc_manager::subtract(doc const& A, doc const& B, ptr_vector<doc>& result) {
doc_ref r(*this), r2(*this); doc_ref r(*this);
tbv_ref t(m); tbv_ref t(m);
r = allocate(A); r = allocate(A);
t = m.allocate(B.pos()); t = m.allocate(B.pos());
if (m.set_and(*t, A.pos()) && r->neg().insert(m, t.detach())) { if (m.set_and(*t, A.pos()) && r->neg().insert(m, t.detach())) {
result.push_back(r.detach()); result.push_back(r.detach());
r = allocate(A);
} }
else { else {
result.push_back(allocate(A)); result.push_back(allocate(A));
} }
for (unsigned i = 0; i < B.neg().size(); ++i) { for (unsigned i = 0; i < B.neg().size(); ++i) {
r2 = allocate(B.neg()[i]); r = allocate(A);
if (set_and(*r, *r2)) { if (set_and(*r, B.neg()[i])) {
result.push_back(r.detach()); result.push_back(r.detach());
} }
r = allocate(A);
} }
} }
bool doc_manager::equals(doc const& a, doc const& b) const { bool doc_manager::equals(doc const& a, doc const& b) const {

View file

@ -59,6 +59,7 @@ public:
bool is_full(doc const& src) const; bool is_full(doc const& src) const;
bool is_empty(doc const& src); bool is_empty(doc const& src);
bool set_and(doc& dst, doc const& src); bool set_and(doc& dst, doc const& src);
bool set_and(doc& dst, tbv const& src);
bool fold_neg(doc& dst); bool fold_neg(doc& dst);
bool intersect(doc const& A, doc const& B, doc& result); bool intersect(doc const& A, doc const& B, doc& result);
void complement(doc const& src, ptr_vector<doc>& result); void complement(doc const& src, ptr_vector<doc>& result);

View file

@ -753,16 +753,17 @@ namespace datalog {
expr* e1, *e2; expr* e1, *e2;
if (result.is_empty()) { if (result.is_empty()) {
} }
else if (m.is_true(g)) {
}
else if (m.is_false(g)) {
result.reset(dm);
}
else if (m.is_and(g)) { else if (m.is_and(g)) {
for (unsigned i = 0; !result.is_empty() && i < to_app(g)->get_num_args(); ++i) { for (unsigned i = 0; !result.is_empty() && i < to_app(g)->get_num_args(); ++i) {
apply_guard(to_app(g)->get_arg(i), result, equalities, discard_cols); apply_guard(to_app(g)->get_arg(i), result, equalities, discard_cols);
} }
} }
else if (m.is_not(g, e1)) { else if (m.is_not(g, e1)) {
// REVIEW: (not (= x y)) should not cause
// the equivalence class to collapse.
// It seems the current organization with fix_eq_bits
// will merge the equivalence class as a side-effect.
udoc sub; udoc sub;
sub.push_back(dm.allocateX()); sub.push_back(dm.allocateX());
apply_guard(e1, sub, equalities, discard_cols); apply_guard(e1, sub, equalities, discard_cols);
@ -789,11 +790,6 @@ namespace datalog {
result.display(dm, tout << "result:") << "\n";); result.display(dm, tout << "result:") << "\n";);
sub.reset(dm); sub.reset(dm);
} }
else if (m.is_true(g)) {
}
else if (m.is_false(g)) {
result.reset(dm);
}
else if (is_var(g)) { else if (is_var(g)) {
SASSERT(m.is_bool(g)); SASSERT(m.is_bool(g));
unsigned v = to_var(g)->get_idx(); unsigned v = to_var(g)->get_idx();
@ -885,10 +881,8 @@ namespace datalog {
SASSERT(u.well_formed(dm)); SASSERT(u.well_formed(dm));
u.intersect(dm, m_udoc); u.intersect(dm, m_udoc);
SASSERT(u.well_formed(dm)); SASSERT(u.well_formed(dm));
if (!m.is_true(m_condition) && !u.is_empty()) { t.apply_guard(m_condition, u, m_equalities, m_empty_bv);
t.apply_guard(m_condition, u, m_equalities, m_empty_bv); SASSERT(u.well_formed(dm));
SASSERT(u.well_formed(dm));
}
u.simplify(dm); u.simplify(dm);
SASSERT(u.well_formed(dm)); SASSERT(u.well_formed(dm));
TRACE("doc", tout << "final size: " << t.get_size_estimate_rows() << '\n';); TRACE("doc", tout << "final size: " << t.get_size_estimate_rows() << '\n';);
@ -1041,10 +1035,8 @@ namespace datalog {
SASSERT(u2.well_formed(dm)); SASSERT(u2.well_formed(dm));
u2.merge(dm, m_roots, m_equalities, m_col_list); u2.merge(dm, m_roots, m_equalities, m_col_list);
SASSERT(u2.well_formed(dm)); SASSERT(u2.well_formed(dm));
if (!m.is_true(m_condition) && !u2.is_empty()) { t.apply_guard(m_condition, u2, m_equalities, m_col_list);
t.apply_guard(m_condition, u2, m_equalities, m_col_list); SASSERT(u2.well_formed(dm));
SASSERT(u2.well_formed(dm));
}
udoc_relation* r = get(t.get_plugin().mk_empty(get_result_signature())); udoc_relation* r = get(t.get_plugin().mk_empty(get_result_signature()));
doc_manager& dm2 = r->get_dm(); doc_manager& dm2 = r->get_dm();
for (unsigned i = 0; i < u2.size(); ++i) { for (unsigned i = 0; i < u2.size(); ++i) {