3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-05 23:05:46 +00:00
This commit is contained in:
Nikolaj Bjorner 2021-12-11 08:41:04 -08:00
parent 9c3489ba4b
commit 83efb1413a
10 changed files with 99 additions and 57 deletions

View file

@ -24,8 +24,8 @@ namespace polysat {
LOG_H3("Resolving upon v" << v);
LOG("c1: " << c1);
LOG("c2: " << c2);
pdd a = c1->to_ule().p();
pdd b = c2->to_ule().p();
pdd a = c1.eq();
pdd b = c2.eq();
pdd r = a;
if (!a.resolve(v, b, r) && !b.resolve(v, a, r))
return {};
@ -40,30 +40,19 @@ namespace polysat {
return c;
}
bool ex_polynomial_superposition::is_positive_equality_over(pvar v, signed_constraint const& c) {
return c.is_positive() && c->is_eq() && c->contains_var(v);
}
// c2 ... constraint that is currently false
// Try to replace it with a new false constraint (derived from superposition with a true constraint)
lbool ex_polynomial_superposition::find_replacement(signed_constraint c2, pvar v, conflict& core) {
vector<signed_constraint> premises;
// TBD: replacement can be obtained from stack not just core.
// see test_l5. Exposes unsoundness bug: a new consequence is derived
// after some variable decision was already processed. Then the
// behavior of evaluating literals "is_currently_true" and bvalue
// uses the full search stack
#if 1
for (auto si : s.m_search) {
if (!si.is_boolean())
continue;
auto c1 = s.lit2cnstr(si.lit());
#else
for (auto c1 : core) {
#endif
if (!is_positive_equality_over(v, c1))
auto c1 = s.lit2cnstr(si.lit());
if (!c1->contains_var(v))
continue;
if (!c1.is_eq())
continue;
if (!c1.is_currently_true(s))
continue;
@ -107,7 +96,9 @@ namespace polysat {
// TODO: can try multiple replacements at once; then the c2 loop needs to be done only once... (requires some reorganization for storing the premises)
lbool ex_polynomial_superposition::try_explain1(pvar v, conflict& core) {
for (auto c2 : core) {
if (!is_positive_equality_over(v, c2))
if (!c2->contains_var(v))
continue;
if (!c2.is_eq())
continue;
if (!c2.is_currently_false(s))
continue;
@ -124,52 +115,68 @@ namespace polysat {
}
void ex_polynomial_superposition::reduce_by(pvar v, conflict& core) {
//return;
bool progress = true;
while (progress) {
progress = false;
for (auto c : core) {
if (is_positive_equality_over(v, c) && c.is_currently_true(s) && reduce_by(v, c, core)) {
progress = true;
break;
}
if (!c->contains_var(v))
continue;
if (!c.is_eq())
continue;
#if 0
if (!c.is_currently_true(s))
continue;
#endif
if (!reduce_by(v, c, core))
continue;
progress = true;
break;
}
}
}
bool ex_polynomial_superposition::reduce_by(pvar v, signed_constraint eq, conflict& core) {
pdd p = eq->to_ule().p();
pdd p = eq.eq();
LOG("using v" << v << " " << eq);
for (auto c : core) {
if (c == eq)
continue;
if (is_positive_equality_over(v, c))
if (!c->contains_var(v))
continue;
if (c.is_eq())
continue;
LOG("try-reduce: " << c << " " << c.is_currently_false(s));
#if 0
if (!c.is_currently_false(s))
continue;
if (c->is_ule()) {
auto lhs = c->to_ule().lhs();
auto rhs = c->to_ule().rhs();
auto a = lhs.reduce(v, p);
auto b = rhs.reduce(v, p);
if (a == lhs && b == rhs)
continue;
auto c2 = s.ule(a, b);
if (!c.is_positive())
c2 = ~c2;
SASSERT(c2.is_currently_false(s));
if (!c2->has_bvar() || l_undef == c2.bvalue(s))
core.keep(c2); // adds propagation of c to the search stack
core.reset();
LOG_H3("Polynomial superposition " << eq << " " << c << " reduced to " << c2);
if (c2.bvalue(s) == l_false) {
core.insert(eq);
core.insert(c);
core.insert(~c2);
return false;
}
core.set(c2);
return true;
#endif
if (!c->is_ule())
continue;
auto lhs = c->to_ule().lhs();
auto rhs = c->to_ule().rhs();
auto a = lhs.reduce(v, p);
auto b = rhs.reduce(v, p);
if (a == lhs && b == rhs)
continue;
auto c2 = s.ule(a, b);
if (!c.is_positive())
c2 = ~c2;
if (!c2.is_currently_false(s))
continue;
SASSERT(c2.is_currently_false(s));
if (!c2->has_bvar() || l_undef == c2.bvalue(s))
core.keep(c2); // adds propagation of c to the search stack
core.reset();
LOG_H3("Polynomial superposition " << eq << " " << c << " reduced to " << c2);
if (c2.bvalue(s) == l_false) {
core.insert(eq);
core.insert(c);
core.insert(~c2);
return false;
}
core.set(c2);
return true;
}
return false;
}