3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-03-09 23:00:30 +00:00

Propagate assignment if all bits are assigned and use better justification if any found

This commit is contained in:
Clemens Eisenhofer 2022-12-27 08:44:55 +01:00
parent 52eefb6e85
commit 39a4bb025b
7 changed files with 460 additions and 313 deletions

View file

@ -362,12 +362,12 @@ namespace polysat {
bool op_constraint::propagate_bits_shl(solver& s, bool is_positive) {
// TODO: Implement: negative case
tbv_ref* p_val = s.m_fixed_bits.eval(s, m_p);
tbv_ref* q_val = s.m_fixed_bits.eval(s, m_q);
tbv_ref* r_val = s.m_fixed_bits.eval(s, m_r);
const tbv_ref& p_val = *s.m_fixed_bits.eval(s, m_p);
const tbv_ref& q_val = *s.m_fixed_bits.eval(s, m_q);
const tbv_ref& r_val = *s.m_fixed_bits.eval(s, m_r);
unsigned sz = m_p.power_of_2();
auto [shift_min, shift_max] = fixed_bits::min_max(*q_val);
auto [shift_min, shift_max] = fixed_bits::min_max(q_val);
unsigned shift_min_u, shift_max_u;
@ -390,23 +390,23 @@ namespace polysat {
// TODO: Improve performance; we can reuse the justifications from the previous iteration
if (shift_min_u > 0) {
for (unsigned i = 0; i < shift_min_u; i++) {
if (!s.m_fixed_bits.fix_value(s, m_r, i, BIT_0, bit_justication_constraint::mk_justify_at_least(this, m_q, *q_val, rational(i + 1))))
if (!s.m_fixed_bits.fix_bit(s, m_r, i, BIT_0, bit_justification_constraint::mk_justify_at_least(s, this, m_q, q_val, rational(i + 1)), true))
return false;
}
}
for (unsigned i = shift_min_u; i < sz; i++) {
unsigned j = 0;
tbit val = (*p_val)[i - shift_min_u];
tbit val = p_val[i - shift_min_u];
if (val == BIT_z)
continue;
for (; j < span; j++) {
if ((*p_val)[i - shift_min_u + 1] != val)
if (p_val[i - shift_min_u + 1] != val)
break;
}
if (j == span) { // all elements we could shift there are equal. We can safely set this value
// TODO: Relax. Sometimes we can reduce the span if further elements in q are set to the respective value
if (!s.m_fixed_bits.fix_value(s, m_r, i, val, bit_justication_constraint::mk_justify_between(this, m_q, *q_val, shift_min, shift_max)))
if (!s.m_fixed_bits.fix_bit(s, m_r, i, val, bit_justification_constraint::mk_justify_between(s, this, m_q, q_val, shift_min, shift_max), true))
return false;
}
}
@ -529,41 +529,41 @@ namespace polysat {
bool op_constraint::propagate_bits_and(solver& s, bool is_positive) {
// TODO: Implement: negative case
LOG_H2("Bit-Propagating: " << m_r << " = (" << m_p << ") & (" << m_q << ")");
tbv_ref* p_val = s.m_fixed_bits.eval(s, m_p);
tbv_ref* q_val = s.m_fixed_bits.eval(s, m_q);
tbv_ref* r_val = s.m_fixed_bits.eval(s, m_r);
LOG("p: " << m_p << " = " << *p_val);
LOG("q: " << m_q << " = " << *q_val);
LOG("r: " << m_r << " = " << *r_val);
const tbv_ref& p_val = *s.m_fixed_bits.eval(s, m_p);
const tbv_ref& q_val = *s.m_fixed_bits.eval(s, m_q);
const tbv_ref& r_val = *s.m_fixed_bits.eval(s, m_r);
LOG("p: " << m_p << " = " << p_val);
LOG("q: " << m_q << " = " << q_val);
LOG("r: " << m_r << " = " << r_val);
unsigned sz = m_p.power_of_2();
for (unsigned i = 0; i < sz; i++) {
tbit bp = (*p_val)[i];
tbit bq = (*q_val)[i];
tbit br = (*r_val)[i];
tbit bp = p_val[i];
tbit bq = q_val[i];
tbit br = r_val[i];
if (bp == BIT_0 || bq == BIT_0) {
// TODO: In case both are 0 use the one with the lower decision-level and not necessarily p
if (!s.m_fixed_bits.fix_value(s, m_r, i, BIT_0, bit_justication_constraint::mk_unary(this, { bp == BIT_0 ? m_p : m_q, i })))
if (!s.m_fixed_bits.fix_bit(s, m_r, i, BIT_0, bit_justification_constraint::mk_unary(s, this, { bp == BIT_0 ? m_p : m_q, i }), true))
return false;
}
else if (bp == BIT_1 && bq == BIT_1) {
if (!s.m_fixed_bits.fix_value(s, m_r, i, BIT_1, bit_justication_constraint::mk_binary(this, { m_p, i }, { m_q, i })))
if (!s.m_fixed_bits.fix_bit(s, m_r, i, BIT_1, bit_justification_constraint::mk_binary(s, this, { m_p, i }, { m_q, i }), true))
return false;
}
else if (br == BIT_1) {
if (!s.m_fixed_bits.fix_value(s, m_p, i, BIT_1, bit_justication_constraint::mk_unary(this, { m_r, i })))
if (!s.m_fixed_bits.fix_bit(s, m_p, i, BIT_1, bit_justification_constraint::mk_unary(s, this, { m_r, i }), true))
return false;
if (!s.m_fixed_bits.fix_value(s, m_q, i, BIT_1, bit_justication_constraint::mk_unary(this, { m_r, i })))
if (!s.m_fixed_bits.fix_bit(s, m_q, i, BIT_1, bit_justification_constraint::mk_unary(s, this, { m_r, i }), true))
return false;
}
else if (br == BIT_0) {
if (bp == BIT_1) {
if (!s.m_fixed_bits.fix_value(s, m_q, i, BIT_1, bit_justication_constraint::mk_binary(this, { m_p, i }, { m_r, i })))
if (!s.m_fixed_bits.fix_bit(s, m_q, i, BIT_1, bit_justification_constraint::mk_binary(s, this, { m_p, i }, { m_r, i }), true))
return false;
}
else if (bq == BIT_1) {
if (!s.m_fixed_bits.fix_value(s, m_p, i, BIT_1, bit_justication_constraint::mk_binary(this, { m_q, i }, { m_r, i })))
if (!s.m_fixed_bits.fix_bit(s, m_p, i, BIT_1, bit_justification_constraint::mk_binary(s, this, { m_q, i }, { m_r, i }), true))
return false;
}
}