mirror of
https://github.com/Z3Prover/z3
synced 2025-06-16 10:56:16 +00:00
derived lemmas
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
ff1bfdbfc6
commit
6b96ba3ef7
1 changed files with 70 additions and 33 deletions
|
@ -682,6 +682,13 @@ struct solver::imp {
|
||||||
m_lar_solver.get_lower_bound(j) == lp::zero_of_type<lp::impq>();
|
m_lar_solver.get_lower_bound(j) == lp::zero_of_type<lp::impq>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool var_is_fixed(lpvar j) const {
|
||||||
|
return
|
||||||
|
m_lar_solver.column_has_upper_bound(j) &&
|
||||||
|
m_lar_solver.column_has_lower_bound(j) &&
|
||||||
|
m_lar_solver.get_upper_bound(j) == m_lar_solver.get_lower_bound(j);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream & print_ineq(const ineq & in, std::ostream & out) const {
|
std::ostream & print_ineq(const ineq & in, std::ostream & out) const {
|
||||||
m_lar_solver.print_term(in.m_term, out);
|
m_lar_solver.print_term(in.m_term, out);
|
||||||
out << " " << lconstraint_kind_string(in.m_cmp) << " " << in.m_rs;
|
out << " " << lconstraint_kind_string(in.m_cmp) << " " << in.m_rs;
|
||||||
|
@ -772,7 +779,7 @@ struct solver::imp {
|
||||||
|
|
||||||
// here we use the fact
|
// here we use the fact
|
||||||
// xy = 0 -> x = 0 or y = 0
|
// xy = 0 -> x = 0 or y = 0
|
||||||
bool basic_lemma_for_mon_zero(const rooted_mon& rm, const factorization& f) {
|
bool basic_lemma_for_mon_zero(const rooted_mon& rm, const factorization& f, bool derived) {
|
||||||
TRACE("nla_solver", trace_print_monomial_and_factorization(rm, f, tout););
|
TRACE("nla_solver", trace_print_monomial_and_factorization(rm, f, tout););
|
||||||
SASSERT(vvr(rm).is_zero());
|
SASSERT(vvr(rm).is_zero());
|
||||||
for (auto j : f) {
|
for (auto j : f) {
|
||||||
|
@ -804,13 +811,24 @@ struct solver::imp {
|
||||||
print_factorization(f, out << "fact: ") << "\n";
|
print_factorization(f, out << "fact: ") << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void explain_fixed_var(unsigned j) {
|
||||||
|
SASSERT(var_is_fixed(j));
|
||||||
|
current_expl().add(m_lar_solver.get_column_upper_bound_witness(j));
|
||||||
|
current_expl().add(m_lar_solver.get_column_lower_bound_witness(j));
|
||||||
|
}
|
||||||
// x = 0 or y = 0 -> xy = 0
|
// x = 0 or y = 0 -> xy = 0
|
||||||
bool basic_lemma_for_mon_non_zero(const rooted_mon& rm, const factorization& f) {
|
bool basic_lemma_for_mon_non_zero(const rooted_mon& rm, const factorization& f, bool derived) {
|
||||||
TRACE("nla_solver", trace_print_monomial_and_factorization(rm, f, tout););
|
TRACE("nla_solver", trace_print_monomial_and_factorization(rm, f, tout););
|
||||||
SASSERT (!vvr(rm).is_zero());
|
SASSERT (!vvr(rm).is_zero());
|
||||||
int zero_j = -1;
|
int zero_j = -1;
|
||||||
for (auto j : f) {
|
for (auto j : f) {
|
||||||
if (vvr(j).is_zero()) {
|
if (derived) {
|
||||||
|
if (var_is_fixed_to_zero(var(j))) {
|
||||||
|
zero_j = var(j);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vvr(j).is_zero()) {
|
||||||
zero_j = var(j);
|
zero_j = var(j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -820,11 +838,16 @@ struct solver::imp {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
add_empty_lemma_and_explanation();
|
add_empty_lemma_and_explanation();
|
||||||
|
if (derived) {
|
||||||
|
explain_fixed_var(zero_j);
|
||||||
|
}
|
||||||
|
else {
|
||||||
mk_ineq(zero_j, llc::NE, current_lemma());
|
mk_ineq(zero_j, llc::NE, current_lemma());
|
||||||
|
}
|
||||||
mk_ineq(var(rm), llc::EQ, current_lemma());
|
mk_ineq(var(rm), llc::EQ, current_lemma());
|
||||||
|
|
||||||
explain(rm, current_expl());
|
explain(rm, current_expl());
|
||||||
TRACE("nla_solver", print_lemma(current_lemma(), tout););
|
TRACE("nla_solver", print_lemma_and_expl(tout););
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -934,7 +957,7 @@ struct solver::imp {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool basic_lemma_for_mon_neutral(const rooted_mon& rm, const factorization& factorization) {
|
bool basic_lemma_for_mon_neutral(const rooted_mon& rm, const factorization& factorization, bool derived) {
|
||||||
return
|
return
|
||||||
basic_lemma_for_mon_neutral_monomial_to_factor(rm, factorization) ||
|
basic_lemma_for_mon_neutral_monomial_to_factor(rm, factorization) ||
|
||||||
basic_lemma_for_mon_neutral_from_factors_to_monomial(rm, factorization);
|
basic_lemma_for_mon_neutral_from_factors_to_monomial(rm, factorization);
|
||||||
|
@ -1003,15 +1026,16 @@ struct solver::imp {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// use basic multiplication properties to create a lemma
|
// Use basic multiplication properties to create a lemma
|
||||||
// for the given monomial
|
// for the given monomial.
|
||||||
bool basic_lemma_for_mon(const rooted_mon& rm) {
|
// "derived" means derived from constraints - the alternative is model based
|
||||||
|
bool basic_lemma_for_mon(const rooted_mon& rm, bool derived) {
|
||||||
if (vvr(rm).is_zero()) {
|
if (vvr(rm).is_zero()) {
|
||||||
for (auto factorization : factorization_factory_imp(rm.m_vars, *this)) {
|
for (auto factorization : factorization_factory_imp(rm.m_vars, *this)) {
|
||||||
if (factorization.is_empty())
|
if (factorization.is_empty())
|
||||||
continue;
|
continue;
|
||||||
if (basic_lemma_for_mon_zero(rm, factorization) ||
|
if (basic_lemma_for_mon_zero(rm, factorization, derived) ||
|
||||||
basic_lemma_for_mon_neutral(rm, factorization)) {
|
basic_lemma_for_mon_neutral(rm, factorization, derived)) {
|
||||||
explain(factorization, current_expl());
|
explain(factorization, current_expl());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1020,8 +1044,8 @@ struct solver::imp {
|
||||||
for (auto factorization : factorization_factory_imp(rm.m_vars, *this)) {
|
for (auto factorization : factorization_factory_imp(rm.m_vars, *this)) {
|
||||||
if (factorization.is_empty())
|
if (factorization.is_empty())
|
||||||
continue;
|
continue;
|
||||||
if (basic_lemma_for_mon_non_zero(rm, factorization) ||
|
if (basic_lemma_for_mon_non_zero(rm, factorization, derived) ||
|
||||||
basic_lemma_for_mon_neutral(rm, factorization) ||
|
basic_lemma_for_mon_neutral(rm, factorization, derived) ||
|
||||||
proportion_lemma(rm, factorization)) {
|
proportion_lemma(rm, factorization)) {
|
||||||
explain(factorization, current_expl());
|
explain(factorization, current_expl());
|
||||||
return true;
|
return true;
|
||||||
|
@ -1040,7 +1064,7 @@ struct solver::imp {
|
||||||
unsigned random() {return m_lar_solver.settings().random_next();}
|
unsigned random() {return m_lar_solver.settings().random_next();}
|
||||||
|
|
||||||
// use basic multiplication properties to create a lemma
|
// use basic multiplication properties to create a lemma
|
||||||
bool basic_lemma() {
|
bool basic_lemma(bool derived) {
|
||||||
if (basic_sign_lemma())
|
if (basic_sign_lemma())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1051,7 +1075,7 @@ struct solver::imp {
|
||||||
do {
|
do {
|
||||||
const rooted_mon& r = m_rm_table.vec()[rm_ref[i]];
|
const rooted_mon& r = m_rm_table.vec()[rm_ref[i]];
|
||||||
SASSERT (!check_monomial(m_monomials[r.orig_index()]));
|
SASSERT (!check_monomial(m_monomials[r.orig_index()]));
|
||||||
if (basic_lemma_for_mon(r)) {
|
if (basic_lemma_for_mon(r, derived)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (++i == rm_ref.size()) {
|
if (++i == rm_ref.size()) {
|
||||||
|
@ -2030,6 +2054,33 @@ struct solver::imp {
|
||||||
TRACE("nla_solver", tout << "pushed a = "; print_point(a, tout); tout << "\npushed b = "; print_point(b, tout); tout << std::endl;);
|
TRACE("nla_solver", tout << "pushed a = "; print_point(a, tout); tout << "\npushed b = "; print_point(b, tout); tout << std::endl;);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lbool inner_check(bool derived) {
|
||||||
|
lbool ret = l_undef;
|
||||||
|
for (int search_level = 0; search_level < 3 && ret == l_undef; search_level++) {
|
||||||
|
TRACE("nla_solver", tout << "search_level = " << search_level << "\n";);
|
||||||
|
if (search_level == 0) {
|
||||||
|
if (basic_lemma(derived)) {
|
||||||
|
ret = l_false;
|
||||||
|
}
|
||||||
|
} else if (search_level == 1) {
|
||||||
|
if (order_lemma(derived)) {
|
||||||
|
ret = l_false;
|
||||||
|
}
|
||||||
|
} else { // search_level == 3
|
||||||
|
if (monotonicity_lemma() || tangent_lemma()) {
|
||||||
|
ret = l_false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lbool check(vector<lp::explanation> & expl_vec, vector<lemma>& l_vec) {
|
lbool check(vector<lp::explanation> & expl_vec, vector<lemma>& l_vec) {
|
||||||
TRACE("nla_solver", tout << "check of nla";);
|
TRACE("nla_solver", tout << "check of nla";);
|
||||||
m_expl_vec = &expl_vec;
|
m_expl_vec = &expl_vec;
|
||||||
|
@ -2044,23 +2095,9 @@ struct solver::imp {
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
init_search();
|
init_search();
|
||||||
lbool ret = l_undef;
|
lbool ret = inner_check(true);
|
||||||
for (int search_level = 0; search_level < 3 && ret == l_undef; search_level++) {
|
if (ret == l_undef)
|
||||||
TRACE("nla_solver", tout << "search_level = " << search_level << "\n";);
|
ret = inner_check(false);
|
||||||
if (search_level == 0) {
|
|
||||||
if (basic_lemma()) {
|
|
||||||
ret = l_false;
|
|
||||||
}
|
|
||||||
} else if (search_level == 1) {
|
|
||||||
if (order_lemma(false) /* || order_lemma(true)*/) {
|
|
||||||
ret = l_false;
|
|
||||||
}
|
|
||||||
} else { // search_level == 3
|
|
||||||
if (monotonicity_lemma() || tangent_lemma()) {
|
|
||||||
ret = l_false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IF_VERBOSE(2, if(ret == l_undef) {verbose_stream() << "Monomials\n"; print_monomials(verbose_stream());});
|
IF_VERBOSE(2, if(ret == l_undef) {verbose_stream() << "Monomials\n"; print_monomials(verbose_stream());});
|
||||||
CTRACE("nla_solver", ret == l_undef, tout << "Monomials\n"; print_monomials(tout););
|
CTRACE("nla_solver", ret == l_undef, tout << "Monomials\n"; print_monomials(tout););
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue