mirror of
https://github.com/Z3Prover/z3
synced 2026-03-16 18:20:00 +00:00
Bit-Propagation for most operations (Backtracking missing)
This commit is contained in:
parent
c8b9127028
commit
173fb9c2bd
7 changed files with 706 additions and 150 deletions
|
|
@ -113,8 +113,10 @@ namespace polysat {
|
|||
if (first)
|
||||
activate(s);
|
||||
|
||||
#if 0
|
||||
if (!propagate_bits(s, is_positive))
|
||||
return; // conflict
|
||||
#endif
|
||||
|
||||
if (clause_ref lemma = produce_lemma(s, s.assignment()))
|
||||
s.add_clause(*lemma);
|
||||
|
|
@ -360,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);
|
||||
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);
|
||||
unsigned sz = m_p.power_of_2();
|
||||
|
||||
auto [shift_min, shift_max] = s.m_fixed_bits.min_max(q_val);
|
||||
auto [shift_min, shift_max] = fixed_bits::min_max(*q_val);
|
||||
|
||||
unsigned shift_min_u, shift_max_u;
|
||||
|
||||
|
|
@ -388,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_value(s, m_r, i, BIT_0, bit_justication_constraint::mk_justify_at_least(this, m_q, *q_val, rational(i + 1))))
|
||||
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_value(s, m_r, i, val, bit_justication_constraint::mk_justify_between(this, m_q, *q_val, shift_min, shift_max)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -524,20 +526,22 @@ namespace polysat {
|
|||
return l_undef;
|
||||
}
|
||||
|
||||
bool op_constraint::propagate_bits_and(solver& s, bool is_positive){
|
||||
bool op_constraint::propagate_bits_and(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);
|
||||
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);
|
||||
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];
|
||||
|
||||
// TODO: Propagate from the result to the operands. e.g., 110... = xx1... & yyy...
|
||||
// TODO: ==> x = 111..., y = 110...
|
||||
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 })))
|
||||
|
|
@ -547,6 +551,22 @@ namespace polysat {
|
|||
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 })))
|
||||
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 })))
|
||||
return false;
|
||||
if (!s.m_fixed_bits.fix_value(s, m_q, i, BIT_1, bit_justication_constraint::mk_unary(this, { m_r, i })))
|
||||
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 })))
|
||||
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 })))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue