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:
parent
4142201d88
commit
e533c6c78d
2 changed files with 37 additions and 36 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue