3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-20 11:22:04 +00:00

toward order lemma

Signed-off-by: Lev <levnach@hotmail.com>
This commit is contained in:
Lev 2018-11-29 16:39:25 -08:00 committed by Lev Nachmanson
parent f211be1e49
commit 82589ad325
2 changed files with 116 additions and 55 deletions

View file

@ -38,6 +38,7 @@ public:
unsigned& index() {return m_index;} unsigned& index() {return m_index;}
factor_type type() const {return m_type;} factor_type type() const {return m_type;}
factor_type& type() {return m_type;} factor_type& type() {return m_type;}
bool is_var() const { return m_type == factor_type::VAR; }
}; };
class factorization { class factorization {

View file

@ -90,6 +90,18 @@ struct solver::imp {
rational vvr(const rooted_mon& rm) const { return vvr(m_monomials[rm.m_orig.m_i].var()) * rm.m_orig.m_sign; } rational vvr(const rooted_mon& rm) const { return vvr(m_monomials[rm.m_orig.m_i].var()) * rm.m_orig.m_sign; }
rational vvr(const factor& f) const { return f.is_var()? vvr(f.index()) : vvr(m_vector_of_rooted_monomials[f.index()]); }
lpvar var(const factor& f) const {
return f.is_var()?
f.index() : orig_mon_var(m_vector_of_rooted_monomials[f.index()]);
}
rational flip_sign(const factor& f) const {
return f.is_var()?
rational(1) : m_vector_of_rooted_monomials[f.index()].m_orig.sign();
}
void add(lpvar v, unsigned sz, lpvar const* vs) { void add(lpvar v, unsigned sz, lpvar const* vs) {
m_monomials.push_back(monomial(v, sz, vs)); m_monomials.push_back(monomial(v, sz, vs));
m_var_to_its_monomial.insert(v, m_monomials.size() - 1); m_var_to_its_monomial.insert(v, m_monomials.size() - 1);
@ -480,9 +492,25 @@ struct solver::imp {
return true; return true;
} }
std::ostream & print_factor(const factor& f, std::ostream& out) const {
if (f.is_var()) {
print_var(f.index(), out);
} else {
print_product(m_vector_of_rooted_monomials[f.index()].vars(), out);
}
return out;
}
std::ostream & print_factorization(const factorization& f, std::ostream& out) const { std::ostream & print_factorization(const factorization& f, std::ostream& out) const {
for (unsigned k = 0; k < f.size(); k++ ) { for (unsigned k = 0; k < f.size(); k++ ) {
print_var(f[k], out); if (f[k].is_var())
print_var(f[k].index(), out);
else {
print_product(m_vector_of_rooted_monomials[f[k].index()].vars(), out);
}
if (k < f.size() - 1) if (k < f.size() - 1)
out << "*"; out << "*";
} }
@ -496,15 +524,13 @@ struct solver::imp {
factorization_factory(m_vars), factorization_factory(m_vars),
m_imp(s) { } m_imp(s) { }
bool find_monomial_of_vars(const svector<lpvar>& vars, monomial& m, rational & sign) const { bool find_monomial_of_vars(const svector<lpvar>& vars, unsigned & i) const {
auto it = m_imp.m_rooted_monomials_map.find(vars); auto it = m_imp.m_rooted_monomials_map.find(vars);
if (it == m_imp.m_rooted_monomials_map.end()) { if (it == m_imp.m_rooted_monomials_map.end()) {
return false; return false;
} }
const index_with_sign & mi = *(it->second.begin()); i = it->second.begin()->m_i;
sign = mi.m_sign;
m = m_imp.m_monomials[mi.m_i];
return true; return true;
} }
@ -518,7 +544,7 @@ struct solver::imp {
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) {
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 (lpvar j : f) { for (auto j : f) {
if (vvr(j).is_zero()) { if (vvr(j).is_zero()) {
return false; return false;
} }
@ -527,8 +553,8 @@ struct solver::imp {
SASSERT(m_lemma->empty()); SASSERT(m_lemma->empty());
mk_ineq(orig_mon_var(rm), lp::lconstraint_kind::NE); mk_ineq(orig_mon_var(rm), lp::lconstraint_kind::NE);
for (lpvar j : f) { for (auto j : f) {
mk_ineq(j, lp::lconstraint_kind::EQ); mk_ineq(var(j), lp::lconstraint_kind::EQ);
} }
explain(rm); explain(rm);
@ -562,9 +588,9 @@ struct solver::imp {
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 (lpvar j : f) { for (auto j : f) {
if (vvr(j).is_zero()) { if (vvr(j).is_zero()) {
zero_j = j; zero_j = var(j);
break; break;
} }
} }
@ -574,7 +600,7 @@ struct solver::imp {
} }
mk_ineq(zero_j, lp::lconstraint_kind::NE); mk_ineq(zero_j, lp::lconstraint_kind::NE);
mk_ineq(m_monomials[rm.orig_index()].var(), lp::lconstraint_kind::EQ); mk_ineq(orig_mon_var(rm), lp::lconstraint_kind::EQ);
explain(rm); explain(rm);
TRACE("nla_solver", print_lemma(tout);); TRACE("nla_solver", print_lemma(tout););
@ -596,21 +622,21 @@ struct solver::imp {
return false; return false;
} }
lpvar jl = -1; lpvar jl = -1;
for (lpvar j : f ) { for (auto j : f ) {
if (abs(vvr(j)) == abs_mv) { if (abs(vvr(j)) == abs_mv) {
jl = j; jl = var(j);
break; break;
} }
} }
if (jl == static_cast<lpvar>(-1)) if (jl == static_cast<lpvar>(-1))
return false; return false;
lpvar not_one_j = -1; lpvar not_one_j = -1;
for (lpvar j : f ) { for (auto j : f ) {
if (j == jl) { if (var(j) == jl) {
continue; continue;
} }
if (abs(vvr(j)) != rational(1)) { if (abs(vvr(j)) != rational(1)) {
not_one_j = j; not_one_j = var(j);
break; break;
} }
} }
@ -640,8 +666,8 @@ struct solver::imp {
// 1 * 1 ... * 1 * x * 1 ... * 1 = x // 1 * 1 ... * 1 * x * 1 ... * 1 = x
bool basic_lemma_for_mon_neutral_from_factors_to_monomial(const rooted_mon& rm, const factorization& f) { bool basic_lemma_for_mon_neutral_from_factors_to_monomial(const rooted_mon& rm, const factorization& f) {
rational sign = rm.m_orig.m_sign; rational sign = rm.m_orig.m_sign;
lpvar not_one_j = -1; lpvar not_one = -1;
for (lpvar j : f){ for (auto j : f){
if (vvr(j) == rational(1)) { if (vvr(j) == rational(1)) {
continue; continue;
} }
@ -651,8 +677,8 @@ struct solver::imp {
continue; continue;
} }
if (not_one_j == static_cast<lpvar>(-1)) { if (not_one == static_cast<lpvar>(-1)) {
not_one_j = j; not_one = var(j);
continue; continue;
} }
@ -662,18 +688,16 @@ struct solver::imp {
explain(rm); explain(rm);
for (lpvar j : f){ for (auto j : f){
if (vvr(j) == rational(1)) { lpvar var_j = var(j);
mk_ineq(j, lp::lconstraint_kind::NE, rational(1)); if (not_one == var_j) continue;
} else if (vvr(j) == -rational(1)) { mk_ineq(var_j, lp::lconstraint_kind::NE, j.is_var()? vvr(j) : flip_sign(j) * vvr(j) );
mk_ineq(j, lp::lconstraint_kind::NE, -rational(1));
}
} }
if (not_one_j == static_cast<lpvar>(-1)) { if (not_one == static_cast<lpvar>(-1)) {
mk_ineq(m_monomials[rm.orig_index()].var(), lp::lconstraint_kind::EQ, rational(sign)); mk_ineq(m_monomials[rm.orig_index()].var(), lp::lconstraint_kind::EQ, sign);
} else { } else {
mk_ineq(m_monomials[rm.orig_index()].var(), -rational(sign), not_one_j, lp::lconstraint_kind::EQ); mk_ineq(m_monomials[rm.orig_index()].var(), -sign, not_one, lp::lconstraint_kind::EQ);
} }
TRACE("nla_solver", print_lemma(tout);); TRACE("nla_solver", print_lemma(tout););
return true; return true;
@ -896,11 +920,32 @@ struct solver::imp {
} }
} }
void register_monomial_containing_vars(unsigned i) {
for (lpvar j : m_vector_of_rooted_monomials[i].vars()) {
auto it = m_rooted_monomials_containing_var.find(j);
if (it == m_rooted_monomials_containing_var.end()) {
std::unordered_set<unsigned> s;
s.insert(i);
m_rooted_monomials_containing_var[i] = s;
} else {
it->second.insert(i);
}
}
}
void fill_rooted_monomials_containing_var() {
for (unsigned i = 0; i < m_vector_of_rooted_monomials.size(); i++) {
register_monomial_containing_vars(i);
}
}
void register_monomials_in_tables() { void register_monomials_in_tables() {
m_vars_equivalence.clear_monomials_by_abs_vals(); m_vars_equivalence.clear_monomials_by_abs_vals();
for (unsigned i = 0; i < m_monomials.size(); i++) for (unsigned i = 0; i < m_monomials.size(); i++)
register_monomial_in_tables(i); register_monomial_in_tables(i);
fill_rooted_monomials_containing_var();
fill_rooted_factor_to_product(); fill_rooted_factor_to_product();
} }
@ -923,6 +968,7 @@ struct solver::imp {
} }
bool order_lemma_on_ac_and_bc(const rooted_mon& rm, const factorization& ac, unsigned k, const rooted_mon& rm_bc) { bool order_lemma_on_ac_and_bc(const rooted_mon& rm, const factorization& ac, unsigned k, const rooted_mon& rm_bc) {
NOT_IMPLEMENTED_YET();
return false; return false;
} }
@ -930,14 +976,28 @@ struct solver::imp {
// ac is a factorization of m_monomials[i_mon] // ac is a factorization of m_monomials[i_mon]
// ac[k] plays the role of c // ac[k] plays the role of c
bool order_lemma_on_factor(const rooted_mon& rm, const factorization& ac, unsigned k) { bool order_lemma_on_factor(const rooted_mon& rm, const factorization& ac, unsigned k) {
lpvar c = ac[k]; auto c = ac[k];
TRACE("nla_solver", tout << "k = " << k << ", c = " << c; ); TRACE("nla_solver", tout << "k = " << k << ", c = "; print_factor(c, tout); );
SASSERT(m_rooted_monomials_containing_var.find(c) != m_rooted_monomials_containing_var.end());
for (unsigned rm_bc : m_rooted_monomials_containing_var[c]) { if (c.is_var()) {
TRACE("nla_solver", );
for (unsigned rm_bc : m_rooted_monomials_containing_var[var(c)]) {
TRACE("nla_solver", );
if (order_lemma_on_ac_and_bc(rm , ac, k, m_vector_of_rooted_monomials[rm_bc])) { if (order_lemma_on_ac_and_bc(rm , ac, k, m_vector_of_rooted_monomials[rm_bc])) {
return true; return true;
} }
} }
} else {
TRACE("nla_solver", );
for (unsigned rm_bc : m_rooted_factor_to_product[var(c)]) {
TRACE("nla_solver", );
if (order_lemma_on_ac_and_bc(rm , ac, k, m_vector_of_rooted_monomials[rm_bc])) {
return true;
}
}
}
return false; return false;
} }
@ -1072,8 +1132,8 @@ struct solver::imp {
for (auto f : fc) { for (auto f : fc) {
if (f.is_empty()) continue; if (f.is_empty()) continue;
found_factorizations ++; found_factorizations ++;
for (lpvar j : f) { for (auto j : f) {
std::cout << "j = "; print_var(j, std::cout); std::cout << "j = "; print_factor(j, std::cout);
} }
std::cout << std::endl; std::cout << std::endl;
} }