3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-25 05:37:00 +00:00

extra px < qx axioms

This commit is contained in:
Jakob Rath 2024-05-13 22:46:49 +02:00
parent d28441bd8f
commit 1292fb2adb
3 changed files with 43 additions and 16 deletions

View file

@ -100,13 +100,14 @@ namespace polysat {
bool verify_YX_l_zX(pvar z, pdd const& x, pdd const& y) const; bool verify_YX_l_zX(pvar z, pdd const& x, pdd const& y) const;
// c := xY <= xZ // c := xY <= xZ
bool is_xY_l_xZ(pvar x, pdd& y, pdd& z) const { return is_xY(x, lhs(), y) && is_xY(x, rhs(), z); } bool is_xY_l_xZ(pvar x, pdd& y, pdd& z) const { return is_xY_2(x, lhs(), y) && is_xY_2(x, rhs(), z); }
/** /// Match xy = x * Y s.t. Y is free of x
* Match xy = x * Y
*/
static bool is_xY(pvar x, pdd const& xy, pdd& y) { return xy.degree(x) == 1 && xy.factor(x, 1, y); } static bool is_xY(pvar x, pdd const& xy, pdd& y) { return xy.degree(x) == 1 && xy.factor(x, 1, y); }
/// Match xy = x * Y
static bool is_xY_2(pvar x, pdd const& xy, pdd& y) { return xy.factor(x, 1, y); }
/** /**
* Rewrite to one of six equivalent forms: * Rewrite to one of six equivalent forms:
* *
@ -165,7 +166,7 @@ namespace polysat {
r.d -= d; r.d -= d;
return r; return r;
} }
}; };
inline std::ostream& operator<<(std::ostream& out, bilinear const& b) { inline std::ostream& operator<<(std::ostream& out, bilinear const& b) {
return out << b.a << "*x*y + " << b.b << "*x + " << b.c << "*y + " << b.d; return out << b.a << "*x*y + " << b.b << "*x + " << b.c << "*y + " << b.d;

View file

@ -118,22 +118,48 @@ namespace polysat {
/** /**
* Implement the inferences * Implement the inferences
* [x] yx < zx ==> Ω*(x,y) \/ y < z * [x] px < qx ==> p != q
* [x] yx <= zx ==> Ω*(x,y) \/ y <= z \/ x = 0 * [x] px < qx ==> Ω*(p,x) \/ p < q
* [x] px < qx ==> Ω*(-q,x) \/ p < q
* [x] px < qx ==> Ω*(q,-x) \/ p > q \/ p = 0
* [x] px < qx ==> Ω*(-p,-x) \/ p > q \/ p = 0
*
* [x] px <= qx ==> Ω*(p,x) \/ p <= q \/ x = 0
* [x] px <= qx ==> Ω*(-q,x) \/ p <= q \/ x = 0 \/ q = 0
* [x] px <= qx ==> Ω*(q,-x) \/ p >= q \/ x = 0 \/ p = 0
* [x] px <= qx ==> Ω*(-p,-x) \/ p >= q \/ x = 0 \/ p = 0
*/ */
void saturation::try_ugt_x(pvar v, inequality const& i) { void saturation::try_ugt_x(pvar v, inequality const& i) {
pdd x = c.var(v); pdd x = c.var(v);
pdd y = x; pdd p = x;
pdd z = x; pdd q = x;
auto const& d = i.dep();
if (!i.is_xY_l_xZ(v, y, z)) if (!i.is_xY_l_xZ(v, p, q))
return; return;
auto ovfl = C.umul_ovfl(x, y); if (i.is_strict()) {
if (i.is_strict()) if (!c.inconsistent())
add_clause("[x] yx < zx ==> Ω*(x,y) \\/ y < z", { i.dep(), ovfl, C.ult(y, z)}, true); add_clause("[x] px < qx ==> p != q", { d, C.diseq(p, q) });
else if (!c.inconsistent())
add_clause("[x] yx <= zx ==> Ω*(x,y) \\/ y <= z \\/ x = 0", { i.dep(), ovfl, C.eq(x), C.ule(y, z) }, true); add_clause("[x] px < qx ==> Ω*(p,x) \\/ p < q", { d, C.umul_ovfl(p, x), C.ult(p, q) });
if (!c.inconsistent())
add_clause("[x] px < qx ==> Ω*(-q,x) \\/ p < q", { d, C.umul_ovfl(-q, x), C.ult(p, q) });
if (!c.inconsistent())
add_clause("[x] px < qx ==> Ω*(q,-x) \\/ p > q \\/ p = 0", { d, C.umul_ovfl(q, -x), C.ugt(p, q), C.eq(p) });
if (!c.inconsistent())
add_clause("[x] px < qx ==> Ω*(-p,-x) \\/ p > q \\/ p = 0", { d, C.umul_ovfl(-p, -x), C.ugt(p, q), C.eq(p) });
}
else {
if (!c.inconsistent())
add_clause("[x] px <= qx ==> Ω*(p,x) \\/ p <= q \\/ x = 0", { d, C.umul_ovfl(p, x), C.eq(x), C.ule(p, q) });
if (!c.inconsistent())
add_clause("[x] px <= qx ==> Ω*(-q,x) \\/ p <= q \\/ x = 0 \\/ q = 0", { d, C.umul_ovfl(-q, x), C.eq(x), C.eq(q), C.ule(p, q) });
if (!c.inconsistent())
add_clause("[x] px <= qx ==> Ω*(q,-x) \\/ p >= q \\/ x = 0 \\/ p = 0", { d, C.umul_ovfl(q, -x), C.eq(x), C.eq(p), C.uge(p, q) });
if (!c.inconsistent())
add_clause("[x] px <= qx ==> Ω*(-p,-x) \\/ p >= q \\/ x = 0 \\/ p = 0", { d, C.umul_ovfl(-p, -x), C.eq(x), C.eq(p), C.uge(p, q) });
}
} }
/** /**

View file

@ -29,7 +29,7 @@ namespace polysat {
core& c; core& c;
constraints& C; constraints& C;
void add_clause(char const* name, clause const& cs, bool is_redundant); void add_clause(char const* name, clause const& cs, bool is_redundant = true);
struct constraint_filter { struct constraint_filter {
core& c; core& c;