3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-03 11:25:40 +00:00

extract method add_equation

This commit is contained in:
Jakob Rath 2023-07-20 15:21:22 +02:00
parent 4142201d88
commit e533c6c78d
2 changed files with 37 additions and 36 deletions

View file

@ -732,25 +732,31 @@ namespace polysat {
SASSERT(!is_conflict()); SASSERT(!is_conflict());
if (!c->is_eq()) if (!c->is_eq())
return; return;
dep_t const d = c.blit();
pdd const& p = c->to_eq(); pdd const& p = c->to_eq();
auto& m = p.manager(); auto& m = p.manager();
for (auto& [a, x] : p.linear_monomials()) { for (auto& [a, x] : p.linear_monomials()) {
if (a != 1 && a != m.max_value()) if (a != 1 && a != m.max_value())
continue; continue;
pdd body = a.is_one() ? (m.mk_var(x) - p) : (m.mk_var(x) + p); pdd const body = a.is_one() ? (m.mk_var(x) - p) : (m.mk_var(x) + p);
// c is either x = body or x != body, depending on polarity // c is either x = body or x != body, depending on polarity
LOG("Equation from lit(" << c.blit() << ") " << c << ": v" << x << " = " << body); LOG("Equation from lit(" << c.blit() << ") " << c << ": v" << x << " = " << body);
enode* const sx = var2slice(x); if (!add_equation(x, body, c.blit())) {
if (c.is_positive() && body.is_val()) {
LOG(" simple assignment");
// Simple assignment x = value
enode* const sval = mk_value_slice(body.val(), body.power_of_2());
if (!merge(sx, sval, d)) {
SASSERT(is_conflict()); SASSERT(is_conflict());
return; return;
} }
continue; // without this check, when p = x - y we would handle both x = y and y = x separately
if (body.is_unary())
break;
}
}
bool slicing::add_equation(pvar x, pdd const& body, sat::literal lit) {
enode* const sx = var2slice(x);
if (!lit.sign() && body.is_val()) {
LOG(" simple assignment");
// Simple assignment x = value
enode* const sval = mk_value_slice(body.val(), body.power_of_2());
return merge(sx, sval, lit);
} }
pvar const y = m_solver.m_names.get_name(body); pvar const y = m_solver.m_names.get_name(body);
if (y == null_var) { if (y == null_var) {
@ -758,28 +764,21 @@ namespace polysat {
// TODO: register name trigger (if a name for value 'body' is created later, then merge x=y at that time) // TODO: register name trigger (if a name for value 'body' is created later, then merge x=y at that time)
// could also count how often 'body' was registered and introduce name when more than once. // could also count how often 'body' was registered and introduce name when more than once.
// maybe better: register x as an existing name for 'body'? question is how to track the dependency on c. // maybe better: register x as an existing name for 'body'? question is how to track the dependency on c.
continue; return true;
} }
enode* const sy = var2slice(y); enode* const sy = var2slice(y);
if (c.is_positive()) { if (!lit.sign())
if (!merge(sx, sy, d)) { return merge(sx, sy, lit);
SASSERT(is_conflict());
return;
}
}
else { else {
SASSERT(c.is_negative()); enode* n = find_or_alloc_disequality(sy, sx, lit);
enode* n = find_or_alloc_disequality(sy, sx, c.blit());
if (!m_disequality_conflict && is_equal(sx, sy)) { if (!m_disequality_conflict && is_equal(sx, sy)) {
add_congruence_if_needed(x); add_congruence_if_needed(x);
add_congruence_if_needed(y); add_congruence_if_needed(y);
m_disequality_conflict = n; m_disequality_conflict = n;
return false;
} }
} }
// without this check, when p = x - y we would handle both x = y and y = x separately return true;
if (body.is_unary())
break;
}
} }
void slicing::add_value(pvar v, rational const& val) { void slicing::add_value(pvar v, rational const& val) {

View file

@ -227,6 +227,8 @@ namespace polysat {
/** Get variable representing src[hi:lo] */ /** Get variable representing src[hi:lo] */
pvar mk_extract(enode* src, unsigned hi, unsigned lo); pvar mk_extract(enode* src, unsigned hi, unsigned lo);
bool add_equation(pvar x, pdd const& body, sat::literal lit);
bool invariant() const; bool invariant() const;
bool invariant_needs_congruence() const; bool invariant_needs_congruence() const;