mirror of
https://github.com/Z3Prover/z3
synced 2025-06-28 08:58:44 +00:00
add stubs for monomial unit propagation
This commit is contained in:
parent
00593609c5
commit
38b131386d
7 changed files with 84 additions and 10 deletions
|
@ -646,7 +646,6 @@ class lar_solver : public column_namer {
|
||||||
inline const static_matrix<mpq, impq>& A_r() const { return m_mpq_lar_core_solver.m_r_A; }
|
inline const static_matrix<mpq, impq>& A_r() const { return m_mpq_lar_core_solver.m_r_A; }
|
||||||
// columns
|
// columns
|
||||||
bool column_is_int(column_index const& j) const { return column_is_int((unsigned)j); }
|
bool column_is_int(column_index const& j) const { return column_is_int((unsigned)j); }
|
||||||
// const impq& get_ivalue(column_index const& j) const { return get_column_value(j); }
|
|
||||||
const impq& get_column_value(column_index const& j) const { return m_mpq_lar_core_solver.m_r_x[j]; }
|
const impq& get_column_value(column_index const& j) const { return m_mpq_lar_core_solver.m_r_x[j]; }
|
||||||
inline var_index external_to_local(unsigned j) const {
|
inline var_index external_to_local(unsigned j) const {
|
||||||
var_index local_j;
|
var_index local_j;
|
||||||
|
|
|
@ -1574,10 +1574,10 @@ lbool core::check(vector<ineq>& lits, vector<lemma>& l_vec) {
|
||||||
if (no_effect())
|
if (no_effect())
|
||||||
m_divisions.check();
|
m_divisions.check();
|
||||||
|
|
||||||
if (!conflict_found() && !done() && run_bounded_nlsat)
|
if (no_effect() && run_bounded_nlsat)
|
||||||
ret = bounded_nlsat();
|
ret = bounded_nlsat();
|
||||||
|
|
||||||
if (l_vec.empty() && !done() && ret == l_undef) {
|
if (no_effect() && ret == l_undef) {
|
||||||
std::function<void(void)> check1 = [&]() { m_order.order_lemma(); };
|
std::function<void(void)> check1 = [&]() { m_order.order_lemma(); };
|
||||||
std::function<void(void)> check2 = [&]() { m_monotone.monotonicity_lemma(); };
|
std::function<void(void)> check2 = [&]() { m_monotone.monotonicity_lemma(); };
|
||||||
std::function<void(void)> check3 = [&]() { m_tangents.tangent_lemma(); };
|
std::function<void(void)> check3 = [&]() { m_tangents.tangent_lemma(); };
|
||||||
|
@ -1593,7 +1593,7 @@ lbool core::check(vector<ineq>& lits, vector<lemma>& l_vec) {
|
||||||
ret = bounded_nlsat();
|
ret = bounded_nlsat();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l_vec.empty() && !done() && params().arith_nl_nra() && ret == l_undef) {
|
if (no_effect() && params().arith_nl_nra() && ret == l_undef) {
|
||||||
ret = m_nra.check();
|
ret = m_nra.check();
|
||||||
m_stats.m_nra_calls++;
|
m_stats.m_nra_calls++;
|
||||||
}
|
}
|
||||||
|
@ -1811,6 +1811,46 @@ bool core::improve_bounds() {
|
||||||
return bounds_improved;
|
return bounds_improved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void core::propagate(vector<lemma>& lemmas) {
|
||||||
|
// disable for now
|
||||||
|
return;
|
||||||
|
|
||||||
|
// propagate linear monomials
|
||||||
|
lemmas.reset();
|
||||||
|
for (auto const& m : m_emons)
|
||||||
|
if (propagate(m, lemmas))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool core::propagate(monic const& m, vector<lemma>& lemmas) {
|
||||||
|
m_propagated.reserve(m.var() + 1, false);
|
||||||
|
if (m_propagated[m.var()])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!is_linear(m))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
trail().push(set_bitvector_trail(m_propagated, m.var()));
|
||||||
|
|
||||||
|
mpq k = fixed_var_product(m);
|
||||||
|
// todo
|
||||||
|
|
||||||
|
// return true if m_emons changes (so the iterator is invalid)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool core::is_linear(monic const& m) {
|
||||||
|
// todo
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mpq core::fixed_var_product(monic const& m) {
|
||||||
|
// todo
|
||||||
|
return mpq(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // end of nla
|
} // end of nla
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ class core {
|
||||||
friend class solver;
|
friend class solver;
|
||||||
friend class monomial_bounds;
|
friend class monomial_bounds;
|
||||||
friend class nra::solver;
|
friend class nra::solver;
|
||||||
|
friend class divisions;
|
||||||
|
|
||||||
struct stats {
|
struct stats {
|
||||||
unsigned m_nla_explanations;
|
unsigned m_nla_explanations;
|
||||||
|
@ -390,6 +391,8 @@ public:
|
||||||
void check_bounded_divisions(vector<lemma>&);
|
void check_bounded_divisions(vector<lemma>&);
|
||||||
|
|
||||||
bool no_lemmas_hold() const;
|
bool no_lemmas_hold() const;
|
||||||
|
|
||||||
|
void propagate(vector<lemma>& lemmas);
|
||||||
|
|
||||||
lbool test_check(vector<lemma>& l);
|
lbool test_check(vector<lemma>& l);
|
||||||
lpvar map_to_root(lpvar) const;
|
lpvar map_to_root(lpvar) const;
|
||||||
|
@ -432,6 +435,13 @@ private:
|
||||||
void restore_tableau();
|
void restore_tableau();
|
||||||
void save_tableau();
|
void save_tableau();
|
||||||
bool integrality_holds();
|
bool integrality_holds();
|
||||||
|
|
||||||
|
// monomial propagation
|
||||||
|
bool_vector m_propagated;
|
||||||
|
bool propagate(monic const& m, vector<lemma>& lemmas);
|
||||||
|
bool is_linear(monic const& m);
|
||||||
|
mpq fixed_var_product(monic const& m);
|
||||||
|
|
||||||
}; // end of core
|
}; // end of core
|
||||||
|
|
||||||
struct pp_mon {
|
struct pp_mon {
|
||||||
|
|
|
@ -19,19 +19,30 @@ Description:
|
||||||
namespace nla {
|
namespace nla {
|
||||||
|
|
||||||
void divisions::add_idivision(lpvar q, lpvar x, lpvar y) {
|
void divisions::add_idivision(lpvar q, lpvar x, lpvar y) {
|
||||||
|
auto& lra = m_core.lra;
|
||||||
if (x == null_lpvar || y == null_lpvar || q == null_lpvar)
|
if (x == null_lpvar || y == null_lpvar || q == null_lpvar)
|
||||||
return;
|
return;
|
||||||
if (lp::tv::is_term(x) || lp::tv::is_term(y) || lp::tv::is_term(q))
|
if (lp::tv::is_term(x))
|
||||||
return;
|
x = lra.map_term_index_to_column_index(x);
|
||||||
|
if (lp::tv::is_term(y))
|
||||||
|
y = lra.map_term_index_to_column_index(y);
|
||||||
|
if (lp::tv::is_term(q))
|
||||||
|
q = lra.map_term_index_to_column_index(q);
|
||||||
m_idivisions.push_back({q, x, y});
|
m_idivisions.push_back({q, x, y});
|
||||||
m_core.trail().push(push_back_vector(m_idivisions));
|
m_core.trail().push(push_back_vector(m_idivisions));
|
||||||
}
|
}
|
||||||
|
|
||||||
void divisions::add_rdivision(lpvar q, lpvar x, lpvar y) {
|
void divisions::add_rdivision(lpvar q, lpvar x, lpvar y) {
|
||||||
|
auto& lra = m_core.lra;
|
||||||
if (x == null_lpvar || y == null_lpvar || q == null_lpvar)
|
if (x == null_lpvar || y == null_lpvar || q == null_lpvar)
|
||||||
return;
|
return;
|
||||||
if (lp::tv::is_term(x) || lp::tv::is_term(y) || lp::tv::is_term(q))
|
if (lp::tv::is_term(x))
|
||||||
return;
|
x = lra.map_term_index_to_column_index(x);
|
||||||
|
if (lp::tv::is_term(y))
|
||||||
|
y = lra.map_term_index_to_column_index(y);
|
||||||
|
if (lp::tv::is_term(q))
|
||||||
|
q = lra.map_term_index_to_column_index(q);
|
||||||
|
|
||||||
m_rdivisions.push_back({ q, x, y });
|
m_rdivisions.push_back({ q, x, y });
|
||||||
m_core.trail().push(push_back_vector(m_rdivisions));
|
m_core.trail().push(push_back_vector(m_rdivisions));
|
||||||
}
|
}
|
||||||
|
@ -52,7 +63,7 @@ namespace nla {
|
||||||
// y2 <= y1 < 0 & x1 <= x2 <= 0 => x1/y1 >= x2/y2
|
// y2 <= y1 < 0 & x1 <= x2 <= 0 => x1/y1 >= x2/y2
|
||||||
|
|
||||||
void divisions::check() {
|
void divisions::check() {
|
||||||
core& c = m_core;
|
core& c = m_core;
|
||||||
if (c.use_nra_model())
|
if (c.use_nra_model())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -132,7 +143,7 @@ namespace nla {
|
||||||
auto x2val = c.val(x2);
|
auto x2val = c.val(x2);
|
||||||
auto y2val = c.val(y2);
|
auto y2val = c.val(y2);
|
||||||
auto q2val = c.val(q2);
|
auto q2val = c.val(q2);
|
||||||
if (monotonicity(x, xval, y, yval, r, rval, x2, x2val, y2, y2val, q2, q2val))
|
if (monotonicity(x, xval, y, yval, r, rval, x2, x2val, y2, y2val, q2, q2val))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,10 @@ namespace nla {
|
||||||
lbool solver::check(vector<ineq>& lits, vector<lemma>& lemmas) {
|
lbool solver::check(vector<ineq>& lits, vector<lemma>& lemmas) {
|
||||||
return m_core->check(lits, lemmas);
|
return m_core->check(lits, lemmas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void solver::propagate(vector<lemma>& lemmas) {
|
||||||
|
m_core->propagate(lemmas);
|
||||||
|
}
|
||||||
|
|
||||||
void solver::push(){
|
void solver::push(){
|
||||||
m_core->push();
|
m_core->push();
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace nla {
|
||||||
void pop(unsigned scopes);
|
void pop(unsigned scopes);
|
||||||
bool need_check();
|
bool need_check();
|
||||||
lbool check(vector<ineq>& lits, vector<lemma>&);
|
lbool check(vector<ineq>& lits, vector<lemma>&);
|
||||||
|
void propagate(vector<lemma>& lemmas);
|
||||||
lbool check_power(lpvar r, lpvar x, lpvar y, vector<lemma>&);
|
lbool check_power(lpvar r, lpvar x, lpvar y, vector<lemma>&);
|
||||||
bool is_monic_var(lpvar) const;
|
bool is_monic_var(lpvar) const;
|
||||||
bool influences_nl_var(lpvar) const;
|
bool influences_nl_var(lpvar) const;
|
||||||
|
|
|
@ -2152,11 +2152,20 @@ public:
|
||||||
propagate_bounds_with_lp_solver();
|
propagate_bounds_with_lp_solver();
|
||||||
break;
|
break;
|
||||||
case l_undef:
|
case l_undef:
|
||||||
|
propagate_nla();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void propagate_nla() {
|
||||||
|
if (!m_nla)
|
||||||
|
return;
|
||||||
|
m_nla->propagate(m_nla_lemma_vector);
|
||||||
|
for (nla::lemma const& l : m_nla_lemma_vector)
|
||||||
|
false_case_of_check_nla(l);
|
||||||
|
}
|
||||||
|
|
||||||
bool should_propagate() const {
|
bool should_propagate() const {
|
||||||
return bound_prop_mode::BP_NONE != propagation_mode();
|
return bound_prop_mode::BP_NONE != propagation_mode();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue