3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-02-20 15:34:41 +00:00

fix the factorization sign to be equal to the monomial sign

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2019-05-10 12:08:56 -07:00
parent df5f3f9722
commit 375027d195
13 changed files with 185 additions and 151 deletions

View file

@ -93,7 +93,7 @@ svector<lpvar> core::sorted_rvars(const factor& f) const {
// the value of the factor is equal to the value of the variable multiplied
// by the canonize_sign
bool core::canonize_sign(const factor& f) const {
return f.sign() ^ (f.is_var()? canonize_sign(f.var()) : m_emons[f.var()].rsign());
return f.sign() ^ (f.is_var()? canonize_sign(f.var()) : canonize_sign(m_emons[f.var()]));
}
bool core::canonize_sign(lpvar j) const {
@ -113,6 +113,14 @@ bool core::canonize_sign(const monomial& m) const {
return m.rsign();
}
bool core::canonize_sign(const factorization& f) const {
bool r = false;
for (const factor & a : f) {
r ^= canonize_sign(a);
}
return r;
}
void core::add(lpvar v, unsigned sz, lpvar const* vs) {
m_emons.add(v, sz, vs);
}
@ -180,7 +188,7 @@ std::ostream & core::print_factor(const factor& f, std::ostream& out) const {
out << "VAR, ";
print_var(f.var(), out);
} else {
out << "MON, ";
out << "MON, v" << m_emons[f.var()] << " = ";
print_product(m_emons[f.var()].rvars(), out);
}
out << "\n";
@ -192,7 +200,7 @@ std::ostream & core::print_factor_with_vars(const factor& f, std::ostream& out)
print_var(f.var(), out);
}
else {
out << " RM = " << pp_rmon(*this, m_emons[f.var()]);
out << " MON = " << pp_rmon(*this, m_emons[f.var()]);
}
return out;
}
@ -216,11 +224,12 @@ std::ostream& core::print_tangent_domain(const point &a, const point &b, std::os
return out;
}
std::ostream& core::print_bfc(const bfc& m, std::ostream& out) const {
std::ostream& core::print_bfc(const factorization& m, std::ostream& out) const {
SASSERT(m.size() == 2);
out << "( x = ";
print_factor(m.m_x, out);
out << ", y = ";
print_factor(m.m_y, out); out << ")";
print_factor(m[0], out);
out << "* y = ";
print_factor(m[1], out); out << ")";
return out;
}
@ -748,7 +757,8 @@ std::ostream & core::print_var(lpvar j, std::ostream & out) const {
}
m_lar_solver.print_column_info(j, out);
out << "root=" << m_evars.find(j) << "\n";
signed_var jr = m_evars.find(j);
out << "root=" << (jr.sign()? "-v":"v") << jr.var() << "\n";
return out;
}
@ -783,7 +793,7 @@ std::ostream & core::print_ineqs(const lemma& l, std::ostream & out) const {
std::ostream & core::print_factorization(const factorization& f, std::ostream& out) const {
if (f.is_mon()){
out << "is_mon " << pp_mon(*this, *f.mon());
out << "is_mon " << pp_mon(*this, f.mon());
}
else {
for (unsigned k = 0; k < f.size(); k++ ) {
@ -795,18 +805,12 @@ std::ostream & core::print_factorization(const factorization& f, std::ostream& o
return out;
}
bool core:: find_rm_monomial_of_vars(const svector<lpvar>& vars, unsigned & i) const {
bool core::find_canonical_monomial_of_vars(const svector<lpvar>& vars, unsigned & i) const {
SASSERT(vars_are_roots(vars));
monomial const* sv = m_emons.find_canonical(vars);
return sv && (i = sv->var(), true);
}
const monomial* core::find_monomial_of_vars(const svector<lpvar>& vars) const {
monomial const* sv = m_emons.find_canonical(vars);
return sv ? &m_emons[sv->var()] : nullptr;
}
void core::explain_existing_lower_bound(lpvar j) {
SASSERT(has_lower_bound(j));
current_expl().add(m_lar_solver.get_column_lower_bound_witness(j));
@ -1571,13 +1575,17 @@ void core::add_abs_bound(lpvar v, llc cmp, rational const& bound) {
*/
bool core::find_bfc_to_refine_on_rmonomial(const monomial& rm, bfc & bf) {
for (auto factorization : factorization_factory_imp(rm, *this)) {
if (factorization.size() == 2) {
auto a = factorization[0];
auto b = factorization[1];
if (val(rm) != val(a) * val(b)) {
bf = bfc(a, b);
bool core::find_bfc_to_refine_on_monomial(const monomial& m, factorization & bf) {
for (auto f : factorization_factory_imp(m, *this)) {
if (f.size() == 2) {
auto a = f[0];
auto b = f[1];
if (val(m) != val(a) * val(b)) {
bf = f;
TRACE("nla_solver", tout << "found bf";
tout << ":m:" << pp_rmon(*this, m) << "\n";
tout << "bf:"; print_bfc(bf, tout););
return true;
}
}
@ -1585,30 +1593,23 @@ bool core::find_bfc_to_refine_on_rmonomial(const monomial& rm, bfc & bf) {
return false;
}
bool core::find_bfc_to_refine(bfc& bf, lpvar &j, rational& sign, const monomial*& rm_found){
rm_found = nullptr;
bool core::find_bfc_to_refine(const monomial* & m, factorization & bf){
m = nullptr;
// todo: randomise loop
for (unsigned i: m_to_refine) {
const auto& rm = m_emons[i];
SASSERT (!check_monomial(m_emons[rm.var()]));
if (rm.size() == 2) {
sign = rational(1);
const monomial & m = m_emons[rm.var()];
j = m.var();
rm_found = nullptr;
bf.m_x = factor(m.vars()[0], factor_type::VAR);
bf.m_y = factor(m.vars()[1], factor_type::VAR);
m = &m_emons[i];
SASSERT (!check_monomial(*m));
if (m->size() == 2) {
bf.set_mon(m);
bf.push_back(factor(m->vars()[0], factor_type::VAR));
bf.push_back(factor(m->vars()[1], factor_type::VAR));
return true;
}
rm_found = &rm;
if (find_bfc_to_refine_on_rmonomial(rm, bf)) {
j = rm.var();
sign = sign_to_rat(rm.rsign());
TRACE("nla_solver", tout << "found bf";
tout << ":rm:" << pp_rmon(*this, rm) << "\n";
tout << "bf:"; print_bfc(bf, tout);
tout << ", product = " << val(rm) << ", but should be =" << val(bf.m_x)*val(bf.m_y);
tout << ", j == "; print_var(j, tout) << "\n";);
if (find_bfc_to_refine_on_monomial(*m, bf)) {
TRACE("nla_solver",
tout << "bf = "; print_factorization(bf, tout);
tout << "\nval(*m) = " << val(*m) << ", should be = (val(bf[0])=" << val(bf[0]) << ")*(val(bf[1]) = " << val(bf[1]) << ") = " << val(bf[0])*val(bf[1]) << "\n";);
return true;
}
}