3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-27 08:28:44 +00:00

chain viables

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2024-01-03 20:22:01 -08:00
parent 1cdefa81b7
commit f805130c0b
3 changed files with 35 additions and 25 deletions

View file

@ -546,6 +546,12 @@ br_status arith_rewriter::mk_le_ge_eq_core(expr * arg1, expr * arg2, op_kind kin
} }
} }
expr* x, * y;
if (kind == EQ && is_zero(arg2) && m_util.is_mul(arg1, x, y)) {
result = m.mk_or(m.mk_eq(x, arg2), m.mk_eq(y, arg2));
return BR_REWRITE2;
}
#define ANUM_LE_GE_EQ() { \ #define ANUM_LE_GE_EQ() { \
switch (kind) { \ switch (kind) { \
case LE: result = am.le(v1, v2) ? m.mk_true() : m.mk_false(); return BR_DONE; \ case LE: result = am.le(v1, v2) ? m.mk_true() : m.mk_false(); return BR_DONE; \
@ -1293,7 +1299,12 @@ br_status arith_rewriter::mk_mod_core(expr * arg1, expr * arg2, expr_ref & resul
expr* x, *y; expr* x, *y;
if (is_num2 && v2.is_pos() && m_util.is_mul(arg1, x, y) && m_util.is_numeral(x, v1, is_int) && divides(v1, v2)) { if (is_num2 && v2.is_pos() && m_util.is_mul(arg1, x, y) && m_util.is_numeral(x, v1, is_int) && divides(v1, v2)) {
result = m_util.mk_mul(x, m_util.mk_mod(y, m_util.mk_int(v2/v1))); result = m_util.mk_mul(x, m_util.mk_mod(y, m_util.mk_int(v2/v1)));
return BR_REWRITE1; return BR_REWRITE2;
}
if (is_num2 && v2 == 2 && m_util.is_mul(arg1, x, y)) {
result = m_util.mk_mul(m_util.mk_mod(x, m_util.mk_int(2)), m_util.mk_mod(y, m_util.mk_int(2)));
return BR_REWRITE2;
} }
return BR_FAILED; return BR_FAILED;

View file

@ -227,6 +227,12 @@ namespace intblast {
m_solver->assert_expr(a.mk_lt(v, a.mk_int(b))); m_solver->assert_expr(a.mk_lt(v, a.mk_int(b)));
} }
for (unsigned i = 0; i < es.size(); ++i) {
expr_ref tmp(es.get(i), m);
ctx.get_rewriter()(tmp);
es[i] = tmp;
}
IF_VERBOSE(2, verbose_stream() << "check\n" << original_es << "\n"); IF_VERBOSE(2, verbose_stream() << "check\n" << original_es << "\n");
IF_VERBOSE(2, IF_VERBOSE(2,

View file

@ -118,8 +118,8 @@ namespace polysat {
m_overlaps.reset(); m_overlaps.reset();
c.get_bitvector_suffixes(v, m_overlaps); c.get_bitvector_suffixes(v, m_overlaps);
std::sort(m_overlaps.begin(), m_overlaps.end(), [&](auto const& x, auto const& y) { return c.size(x.v) < c.size(y.v); }); std::sort(m_overlaps.begin(), m_overlaps.end(), [&](auto const& x, auto const& y) { return c.size(x.v) < c.size(y.v); });
display_state(verbose_stream()); //display_state(verbose_stream());
display(verbose_stream()); //display(verbose_stream());
} }
@ -531,11 +531,8 @@ namespace polysat {
* *
* Note that x in [lo, hi[ <=> x - lo < hi - lo * Note that x in [lo, hi[ <=> x - lo < hi - lo
* If k' = 0, w' = w, there is nothing to do. * If k' = 0, w' = w, there is nothing to do.
* If w' > w, then hi <- zero_extend(w' - w, hi)
* If w' < w, then hi <- hi[w' - 1:0]
* If k' > 0, then hi <- 2^k' hi
* *
* TODO: So far we assume that hi is divisible by 2^k. * TODO - describe.
* *
*/ */
@ -548,40 +545,36 @@ namespace polysat {
auto lo = after.e->interval.lo(); auto lo = after.e->interval.lo();
auto hi = after.e->interval.hi(); auto hi = after.e->interval.hi();
verbose_stream() << e.e->interval << " " << e.value << " " << t << " then " << after.e->interval << "\n";
SASSERT(after.e->bit_width <= bw_after); SASSERT(after.e->bit_width <= bw_after);
SASSERT(ebw <= bw); SASSERT(ebw <= bw);
if (ebw < bw) { auto const& p2b = rational::power_of_two(bw);
NOT_IMPLEMENTED_YET(); auto const& p2eb = rational::power_of_two(bw - ebw);
}
if (bw_after > bw) { auto t_equal_value = [&]() {
auto eq = cs.eq(t, c.value(mod(e.value, rational::power_of_two(bw)), bw)); auto vhi = c.value(mod(e.value * p2eb + 1, p2b), bw);
auto vlo = c.value(mod((e.value - 1) * p2eb - 1, p2b), bw);
// t in ] (value - 1) * 2^{bw - ebw} ; value * 2^{bw - ebw} ]
// t in [ (value - 1) * 2^{bw - ebw} - 1 ; value * 2^{bw - ebw} + 1 [
auto eq = cs.ult(t - vlo, vhi - vlo);
SASSERT(!eq.is_always_false()); SASSERT(!eq.is_always_false());
if (!eq.is_always_true()) if (!eq.is_always_true())
deps.push_back(c.propagate(eq, c.explain_eval(eq))); deps.push_back(c.propagate(eq, c.explain_eval(eq)));
t.reset(lo.manager()); };
t = c.value(e.value, bw_after);
}
if (bw_after < bw) {
auto eq = cs.eq(t, c.value(e.value, bw)); if (ebw < bw || bw_after != bw) {
SASSERT(!eq.is_always_false()); t_equal_value();
if (!eq.is_always_true())
deps.push_back(c.propagate(eq, c.explain_eval(eq)));
t.reset(lo.manager()); t.reset(lo.manager());
t = c.value(mod(e.value, rational::power_of_two(bw_after)), bw_after); t = c.value(mod(e.value, rational::power_of_two(bw_after)), bw_after);
} }
if (abw < bw_after) if (abw < bw_after)
t *= rational::power_of_two(bw_after - after.e->bit_width); t *= rational::power_of_two(bw_after - abw);
auto sc = cs.ult(t - lo, hi - lo); auto sc = cs.ult(t - lo, hi - lo);
if (sc.is_always_true()) if (sc.is_always_true())
return; return;
verbose_stream() << "in interval: " << sc << "\n";
SASSERT(!sc.is_always_false()); SASSERT(!sc.is_always_false());
deps.push_back(c.propagate(sc, c.explain_eval(sc))); deps.push_back(c.propagate(sc, c.explain_eval(sc)));
} }
@ -627,7 +620,7 @@ namespace polysat {
unsigned const k = ne->coeff.parity(w); unsigned const k = ne->coeff.parity(w);
SASSERT(k > 0); SASSERT(k > 0);
IF_VERBOSE(13, display_one(verbose_stream() << "try to reduce entry: ", v, ne) << "\n"); IF_VERBOSE(3, display_one(verbose_stream() << "try to reduce entry: ", v, ne) << "\n");
// reduction of coeff gives us a unit entry // reduction of coeff gives us a unit entry
// //