mirror of
https://github.com/Z3Prover/z3
synced 2025-07-18 02:16:40 +00:00
use the new throttle in order lemmas
This commit is contained in:
parent
832cfb3c41
commit
727dfd2d8d
2 changed files with 9 additions and 143 deletions
|
@ -89,55 +89,13 @@ void order::order_lemma_on_binomial_sign(const monic& xy, lpvar x, lpvar y, int
|
|||
SASSERT(!_().mon_has_zero(xy.vars()));
|
||||
int sy = rat_sign(val(y));
|
||||
// throttle here
|
||||
if (throttle_binomial_sign(xy, x, y, sign, sy))
|
||||
if (c().throttle().insert_new(nla_throttle::BINOMIAL_SIGN_LEMMA, xy.var(), x, y, sign, sy))
|
||||
return;
|
||||
|
||||
lemma_builder lemma(c(), __FUNCTION__);
|
||||
lemma |= ineq(y, sy == 1 ? llc::LE : llc::GE, 0); // negate sy
|
||||
lemma |= ineq(x, sy*sign == 1 ? llc::GT : llc::LT , val(x));
|
||||
lemma |= ineq(term(xy.var(), - val(x), y), sign == 1 ? llc::LE : llc::GE, 0);
|
||||
}
|
||||
|
||||
bool order::throttle_mon_ol(const monic& ac, lpvar a, const rational& c_sign, lpvar c_var,
|
||||
const monic& bd, const factor& b, const rational& d_sign,
|
||||
lpvar d, llc ab_cmp) {
|
||||
// Check if throttling is enabled
|
||||
if (!c().params().arith_nl_thrl())
|
||||
return false;
|
||||
|
||||
// Create the key for this specific generate_mon_ol invocation
|
||||
mon_ol_key key(ac.var(), a, c_sign, c_var, bd.var(), b.var(), d_sign, d, ab_cmp);
|
||||
|
||||
// Check if this combination has already been processed
|
||||
if (m_processed_mon_ol.contains(key)) {
|
||||
TRACE(nla_solver, tout << "throttled generate_mon_ol\n";);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mark this combination as processed and add to trail for backtracking
|
||||
m_processed_mon_ol.insert(key);
|
||||
c().trail().push(insert_map(m_processed_mon_ol, key));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool order::throttle_binomial_sign(const monic& xy, lpvar x, lpvar y, int sign, int sy) {
|
||||
// Check if throttling is enabled
|
||||
if (!c().params().arith_nl_thrl())
|
||||
return false;
|
||||
|
||||
// Create the key for this specific order_lemma_on_binomial_sign invocation
|
||||
binomial_sign_key key(xy.var(), x, y, sign, sy);
|
||||
|
||||
// Check if this combination has already been processed
|
||||
if (m_processed_binomial_sign.contains(key)) {
|
||||
TRACE(nla_solver, tout << "throttled order_lemma_on_binomial_sign\n";);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mark this combination as processed and add to trail for backtracking
|
||||
m_processed_binomial_sign.insert(key);
|
||||
c().trail().push(insert_map(m_processed_binomial_sign, key));
|
||||
return false;
|
||||
lemma |= ineq(lp::lar_term(xy.var(), - val(x), y), sign == 1 ? llc::LE : llc::GE, 0);
|
||||
}
|
||||
|
||||
// We look for monics e = m.rvars()[k]*d and see if we can create an order lemma for m and e
|
||||
|
@ -206,7 +164,7 @@ void order::order_lemma_on_binomial_ac_bd(const monic& ac, bool k, const monic&
|
|||
void order::generate_mon_ol(const monic& ac,
|
||||
lpvar a,
|
||||
const rational& c_sign,
|
||||
lpvar c,
|
||||
lpvar c_par,
|
||||
const monic& bd,
|
||||
const factor& b,
|
||||
const rational& d_sign,
|
||||
|
@ -217,14 +175,14 @@ void order::generate_mon_ol(const monic& ac,
|
|||
SASSERT(ab_cmp != llc::GT || (var_val(ac) <= var_val(bd) && val(a)*c_sign > val(b)*d_sign));
|
||||
|
||||
// Check if this specific combination should be throttled
|
||||
if (throttle_mon_ol(ac, a, c_sign, c, bd, b, d_sign, d, ab_cmp))
|
||||
if (c().throttle().insert_new(nla_throttle::ORDER_LEMMA, ac.var(), a, c_sign, c_par, bd.var(), b.var(), d_sign, d, ab_cmp))
|
||||
return;
|
||||
|
||||
lemma_builder lemma(_(), __FUNCTION__);
|
||||
lemma |= ineq(term(c_sign, c), llc::LE, 0);
|
||||
lemma &= c; // this explains c == +- d
|
||||
lemma |= ineq(term(c_sign, a, -d_sign * b.rat_sign(), b.var()), negate(ab_cmp), 0);
|
||||
lemma |= ineq(term(ac.var(), rational(-1), var(bd)), ab_cmp, 0);
|
||||
lemma |= ineq(lp::lar_term(c_sign, c_par), llc::LE, 0);
|
||||
lemma &= c_par; // this explains c_par == +- d
|
||||
lemma |= ineq(lp::lar_term(c_sign, a, -d_sign * b.rat_sign(), b.var()), negate(ab_cmp), 0);
|
||||
lemma |= ineq(lp::lar_term(rational(1), ac.var(), rational(-1), var(bd)), ab_cmp, 0);
|
||||
lemma &= bd;
|
||||
lemma &= b;
|
||||
lemma &= d;
|
||||
|
@ -367,7 +325,7 @@ bool order::order_lemma_on_ac_and_bc_and_factors(const monic& ac,
|
|||
const monic& bc,
|
||||
const factor& b) {
|
||||
SASSERT(!val(c).is_zero());
|
||||
rational c_sign = rational(nla::rat_sign(val(c)));
|
||||
rational c_sign = rational(rat_sign(val(c)));
|
||||
auto av_c_s = val(a) * c_sign;
|
||||
auto bv_c_s = val(b) * c_sign;
|
||||
if ((var_val(ac) > var_val(bc) && av_c_s < bv_c_s) ||
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#pragma once
|
||||
#include "math/lp/factorization.h"
|
||||
#include "math/lp/nla_common.h"
|
||||
#include "util/hashtable.h"
|
||||
#include "util/hash.h"
|
||||
|
||||
namespace nla {
|
||||
class core;
|
||||
|
@ -20,96 +18,6 @@ public:
|
|||
order(core *c) : common(c) {}
|
||||
void order_lemma();
|
||||
|
||||
// Structure to represent the key parameters for throttling generate_mon_ol
|
||||
// Optimized for memory efficiency with packed fields
|
||||
struct mon_ol_key {
|
||||
short ac_var;
|
||||
short a;
|
||||
signed char c_sign; // -1, 0, 1 fits in signed char
|
||||
short c;
|
||||
short bd_var;
|
||||
short b_var;
|
||||
signed char d_sign; // -1, 0, 1 fits in signed char
|
||||
short d;
|
||||
unsigned char ab_cmp; // llc enum fits in unsigned char
|
||||
|
||||
// Default constructor for hashtable
|
||||
mon_ol_key() : ac_var(0), a(0), c_sign(0), c(0), bd_var(0), b_var(0), d_sign(0), d(0), ab_cmp(static_cast<unsigned char>(llc::EQ)) {}
|
||||
|
||||
mon_ol_key(lpvar ac_var, lpvar a, const rational& c_sign_rat, lpvar c,
|
||||
lpvar bd_var, lpvar b_var, const rational& d_sign_rat, lpvar d, llc ab_cmp)
|
||||
: ac_var(static_cast<short>(ac_var)), a(static_cast<short>(a)),
|
||||
c_sign(c_sign_rat.is_pos() ? 1 : (c_sign_rat.is_neg() ? -1 : 0)),
|
||||
c(static_cast<short>(c)), bd_var(static_cast<short>(bd_var)),
|
||||
b_var(static_cast<short>(b_var)),
|
||||
d_sign(d_sign_rat.is_pos() ? 1 : (d_sign_rat.is_neg() ? -1 : 0)),
|
||||
d(static_cast<short>(d)), ab_cmp(static_cast<unsigned char>(ab_cmp)) {}
|
||||
|
||||
bool operator==(const mon_ol_key& other) const {
|
||||
return ac_var == other.ac_var && a == other.a && c_sign == other.c_sign &&
|
||||
c == other.c && bd_var == other.bd_var && b_var == other.b_var &&
|
||||
d_sign == other.d_sign && d == other.d && ab_cmp == other.ab_cmp;
|
||||
}
|
||||
};
|
||||
|
||||
struct mon_ol_key_hash {
|
||||
unsigned operator()(const mon_ol_key& k) const {
|
||||
// Optimized hash with better distribution using bit shifts
|
||||
unsigned h1 = (static_cast<unsigned>(k.ac_var) << 16) | static_cast<unsigned>(k.a);
|
||||
unsigned h2 = (static_cast<unsigned>(k.c_sign + 1) << 24) |
|
||||
(static_cast<unsigned>(k.c) << 8) | static_cast<unsigned>(k.bd_var);
|
||||
unsigned h3 = (static_cast<unsigned>(k.b_var) << 16) |
|
||||
((static_cast<unsigned>(k.d_sign + 1) << 8)) |
|
||||
static_cast<unsigned>(k.d);
|
||||
unsigned h4 = static_cast<unsigned>(k.ab_cmp);
|
||||
|
||||
return combine_hash(combine_hash(h1, h2), combine_hash(h3, h4));
|
||||
}
|
||||
};
|
||||
|
||||
hashtable<mon_ol_key, mon_ol_key_hash, default_eq<mon_ol_key>> m_processed_mon_ol;
|
||||
bool throttle_mon_ol(const monic& ac, lpvar a, const rational& c_sign, lpvar c_var,
|
||||
const monic& bd, const factor& b, const rational& d_sign,
|
||||
lpvar d, llc ab_cmp);
|
||||
|
||||
// Structure to represent the key parameters for throttling order_lemma_on_binomial_sign
|
||||
// Optimized for memory efficiency with packed fields
|
||||
struct binomial_sign_key {
|
||||
short xy_var;
|
||||
short x;
|
||||
short y;
|
||||
signed char sign;
|
||||
signed char sy;
|
||||
|
||||
// Default constructor for hashtable
|
||||
binomial_sign_key() : xy_var(0), x(0), y(0), sign(0), sy(0) {}
|
||||
|
||||
binomial_sign_key(lpvar xy_var, lpvar x, lpvar y, int sign, int sy)
|
||||
: xy_var(static_cast<short>(xy_var)), x(static_cast<short>(x)),
|
||||
y(static_cast<short>(y)), sign(static_cast<signed char>(sign)),
|
||||
sy(static_cast<signed char>(sy)) {}
|
||||
|
||||
bool operator==(const binomial_sign_key& other) const {
|
||||
return xy_var == other.xy_var && x == other.x && y == other.y &&
|
||||
sign == other.sign && sy == other.sy;
|
||||
}
|
||||
};
|
||||
|
||||
struct binomial_sign_key_hash {
|
||||
unsigned operator()(const binomial_sign_key& k) const {
|
||||
// Optimized hash with better distribution
|
||||
unsigned h1 = (static_cast<unsigned>(k.xy_var) << 16) | static_cast<unsigned>(k.x);
|
||||
unsigned h2 = (static_cast<unsigned>(k.y) << 16) |
|
||||
((static_cast<unsigned>(k.sign + 127) << 8)) | // shift sign to positive range
|
||||
static_cast<unsigned>(k.sy + 127); // shift sy to positive range
|
||||
|
||||
return combine_hash(h1, h2);
|
||||
}
|
||||
};
|
||||
|
||||
hashtable<binomial_sign_key, binomial_sign_key_hash, default_eq<binomial_sign_key>> m_processed_binomial_sign;
|
||||
bool throttle_binomial_sign(const monic& xy, lpvar x, lpvar y, int sign, int sy);
|
||||
|
||||
private:
|
||||
|
||||
bool order_lemma_on_ac_and_bc_and_factors(const monic& ac,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue