3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-18 06:39:02 +00:00

passing test solver::test_order_lemma()

Signed-off-by: Lev <levnach@hotmail.com>
This commit is contained in:
Lev 2018-12-05 19:30:27 -10:00 committed by Lev Nachmanson
parent 5c0f76a702
commit 95ee5fa681

View file

@ -28,7 +28,9 @@ namespace nla {
// returns true if a factor of b
template <typename T>
bool is_factor(const T & a, const T & b) {
bool is_proper_factor(const T & a, const T & b) {
if (a.size() >= b.size())
return false;
SASSERT(lp::is_non_decreasing(a) && lp::is_non_decreasing(b));
auto i = a.begin();
auto j = b.begin();
@ -55,7 +57,7 @@ template <typename T>
svector<unsigned> vector_div(const T & b, const T & a) {
SASSERT(lp::is_non_decreasing(a));
SASSERT(lp::is_non_decreasing(b));
SASSERT(is_factor(a, b));
SASSERT(is_proper_factor(a, b));
svector<unsigned> r;
auto i = a.begin();
auto j = b.begin();
@ -901,25 +903,29 @@ struct solver::imp {
return true;
}
void register_key_mono_in_rooted_monomials(monomial_coeff const& mc, unsigned i) {
void register_key_mono_in_rooted_monomials(monomial_coeff const& mc, unsigned i_mon) {
TRACE("nla_solver", tout << "mc = "; print_product(mc.vars(), tout);
tout << " i_mon = " << i_mon;);
SASSERT(vars_are_roots(mc.vars()));
SASSERT(lp::is_non_decreasing(mc.vars()));
index_with_sign ms(i, mc.coeff());
index_with_sign ms(i_mon, mc.coeff());
auto it = m_rooted_monomials_map.find(mc.vars());
if (it == m_rooted_monomials_map.end()) {
TRACE("nla_solver", tout << "size = " << m_vector_of_rooted_monomials.size(););
rooted_mon_info rmi(m_vector_of_rooted_monomials.size(), ms);
m_rooted_monomials_map.emplace(mc.vars(), rmi);
m_vector_of_rooted_monomials.push_back(rooted_mon(mc.vars(), i, mc.coeff()));
m_vector_of_rooted_monomials.push_back(rooted_mon(mc.vars(), i_mon, mc.coeff()));
}
else {
it->second.push_back(ms);
TRACE("nla_solver", tout << "add ms.m_i = " << ms.m_i;);
}
}
void register_monomial_in_tables(unsigned i) {
m_vars_equivalence.register_monomial_in_abs_vals(i, m_monomials[i]);
monomial_coeff mc = canonize_monomial(m_monomials[i]);
register_key_mono_in_rooted_monomials(mc, i);
void register_monomial_in_tables(unsigned i_mon) {
m_vars_equivalence.register_monomial_in_abs_vals(i_mon, m_monomials[i_mon]);
monomial_coeff mc = canonize_monomial(m_monomials[i_mon]);
register_key_mono_in_rooted_monomials(mc, i_mon);
}
void intersect_set(std::unordered_set<unsigned>& p, const std::unordered_set<unsigned>& w) {
@ -932,10 +938,10 @@ struct solver::imp {
}
}
void reduce_set_by_checking_actual_containment(std::unordered_set<unsigned>& p,
void reduce_set_by_checking_proper_containment(std::unordered_set<unsigned>& p,
const rooted_mon & rm ) {
for (auto it = p.begin(); it != p.end();) {
if (is_factor(rm.m_vars, m_vector_of_rooted_monomials[*it].m_vars)) {
if (is_proper_factor(rm.m_vars, m_vector_of_rooted_monomials[*it].m_vars)) {
it++;
continue;
}
@ -945,48 +951,66 @@ struct solver::imp {
it = iit;
}
}
template <typename T>
void trace_print_rms(const T& p, std::ostream& out) {
out << "p = {";
for (auto j : p) {
out << "\nj = " << j <<
", rm = ";
print_rooted_monomial(m_vector_of_rooted_monomials[j], out);
}
out << "\n}";
}
// here i is the index of a monomial in m_vector_of_rooted_monomials
void find_containing_rooted_monomials(unsigned i) {
const auto & rm = m_vector_of_rooted_monomials[i];
TRACE("nla_solver", tout << "i = " << i << ", rm = "; print_rooted_monomial(rm, tout););
void find_rooted_monomials_containing_rm(unsigned i_rm) {
const auto & rm = m_vector_of_rooted_monomials[i_rm];
std::unordered_set<unsigned> p = m_rooted_monomials_containing_var[rm[0]];
TRACE("nla_solver",
tout << "i_rm = " << i_rm << ", rm = ";
print_rooted_monomial(rm, tout);
tout << "\n rm[0] =" << rm[0] << " var = ";
print_var(rm[0], tout);
tout << "\n";
trace_print_rms(p, tout);
);
for (unsigned k = 1; k < rm.size(); k++) {
intersect_set(p, m_rooted_monomials_containing_var[rm[k]]);
}
reduce_set_by_checking_actual_containment(p, rm);
TRACE("nla_solver",
tout << "p = " << p.size();
for (auto j : p)
TRACE("nla_solver", tout << "j = " << j << ", rm = "; print_rooted_monomial(m_vector_of_rooted_monomials[j], tout););
);
m_rooted_factor_to_product[i] = p;
TRACE("nla_solver", trace_print_rms(p, tout););
reduce_set_by_checking_proper_containment(p, rm);
TRACE("nla_solver", trace_print_rms(p, tout););
m_rooted_factor_to_product[i_rm] = p;
}
void fill_rooted_factor_to_product() {
for (unsigned i = 0; i < m_vector_of_rooted_monomials.size(); i++) {
find_containing_rooted_monomials(i);
find_rooted_monomials_containing_rm(i);
}
}
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);
void register_rooted_monomial_containing_vars(unsigned i_rm) {
TRACE("nla_solver", print_rooted_monomial(m_vector_of_rooted_monomials[i_rm], tout););
for (lpvar j_var : m_vector_of_rooted_monomials[i_rm].vars()) {
TRACE("nla_solver", print_var(j_var, tout););
auto it = m_rooted_monomials_containing_var.find(j_var);
if (it == m_rooted_monomials_containing_var.end()) {
std::unordered_set<unsigned> s;
s.insert(i);
m_rooted_monomials_containing_var[i] = s;
s.insert(i_rm);
m_rooted_monomials_containing_var[j_var] = s;
} else {
it->second.insert(i);
it->second.insert(i_rm);
}
}
}
void fill_rooted_monomials_containing_var() {
for (unsigned i = 0; i < m_vector_of_rooted_monomials.size(); i++) {
register_monomial_containing_vars(i);
register_rooted_monomial_containing_vars(i);
}
}
@ -1011,16 +1035,16 @@ struct solver::imp {
bool divide(const rooted_mon& bc, const factor& c, factor & b) const {
svector<lpvar> c_vars = sorted_vars(c);
TRACE("nla_solver",
TRACE("nla_solver_div",
tout << "c_vars = ";
print_product(c_vars, tout);
tout << "\nbc_vars = ";
print_product(bc.vars(), tout););
if (!is_factor(c_vars, bc.vars()))
if (!is_proper_factor(c_vars, bc.vars()))
return false;
auto b_vars = vector_div(bc.vars(), c_vars);
TRACE("nla_solver", tout << "b_vars = "; print_product(b_vars, tout););
TRACE("nla_solver_div", tout << "b_vars = "; print_product(b_vars, tout););
SASSERT(b_vars.size() > 0);
if (b_vars.size() == 1) {
b = factor(b_vars[0]);
@ -1028,9 +1052,11 @@ struct solver::imp {
}
auto it = m_rooted_monomials_map.find(b_vars);
if (it == m_rooted_monomials_map.end()) {
TRACE("nla_solver_div", tout << "not in rooted";);
return false;
}
b = factor(it->second.m_i, factor_type::RM);
TRACE("nla_solver_div", tout << "success div:"; print_factor(b, tout););
return true;
}
@ -1085,12 +1111,18 @@ struct solver::imp {
auto ac_v = vvr(ac);
auto bd_v = vvr(bd);
TRACE("nla_solver",
tout << "ac_m = " << ac_m << ", ";
tout << "bd_m = " << bd_m << ", ";
tout << "ac_v = " << ac_v << ", ";
tout << "bd_v = " << bd_v;
);
if (ac_m < bd_m && !(ac_v < bd_v)) {
generate_ol(ac, a, c, bd, b, d, lp::lconstraint_kind::LT);
return true;
}
else if (ac_m > bd_m && !(ac_v > bd_v)) {
if (ac_m > bd_m && !(ac_v > bd_v)) {
generate_ol(ac, a, c, bd, b, d, lp::lconstraint_kind::GT);
return true;
}
@ -1113,10 +1145,12 @@ struct solver::imp {
tout << ", d = "; print_factor(d, tout););
SASSERT(abs(vvr(ac_f[k])) == abs(vvr(d)));
factor b;
if (!divide(rm_bd, d, b))
if (!divide(rm_bd, d, b)){
TRACE("nla_solver", tout << "no division";);
return false;
}
TRACE("nla_solver", tout << "factor b = ";
TRACE("nla_solver", tout << "div factor b = ";
print_factor(b, tout););
TRACE("nla_solver", tout << "vvr(b) = " << vvr(b););
@ -1149,7 +1183,7 @@ struct solver::imp {
if (!contains(found_rm, i)) {
found_rm.insert(i);
r.push_back(factor(i, factor_type::RM));
TRACE("nla_solver", tout << "ins "; print_factor(factor(i, factor_type::RM), tout); );
TRACE("nla_solver", tout << "insering factor = "; print_factor(factor(i, factor_type::RM), tout); );
}
}
@ -1175,7 +1209,7 @@ struct solver::imp {
}
}
} else {
TRACE("nla_solver", tout << "size = " << m_rooted_factor_to_product[d.index()].size() ;);
TRACE("nla_solver", tout << "not a var = " << m_rooted_factor_to_product[d.index()].size() ;);
for (unsigned rm_bd : m_rooted_factor_to_product[d.index()]) {
TRACE("nla_solver", );
if (order_lemma_on_ac_and_bd(rm , ac, k, m_vector_of_rooted_monomials[rm_bd], d)) {
@ -1191,7 +1225,10 @@ struct solver::imp {
// ac is a factorization of m_monomials[i_mon]
bool order_lemma_on_factorization(const rooted_mon& rm, const factorization& ac) {
SASSERT(ac.size() == 2);
TRACE("nla_solver", tout << "factorization = "; print_factorization(ac, tout););
CTRACE("nla_solver",
rm.vars().size() == 4,
tout << "rm = "; print_rooted_monomial(rm, tout);
tout << ", factorization = "; print_factorization(ac, tout););
for (unsigned k = 0; k < ac.size(); k++) {
const rational & v = vvr(ac[k]);
if (v.is_zero())
@ -1931,7 +1968,7 @@ void solver::test_order_lemma() {
s.set_column_value(lp_b, rational(4));
s.set_column_value(lp_c, rational(2));
s.set_column_value(lp_d, rational(3));
//create monomial abef
//create monomial (ab)(ef)
vec.clear();
vec.push_back(lp_e);
vec.push_back(lp_a);
@ -1942,7 +1979,7 @@ void solver::test_order_lemma() {
s.set_column_value(lp_e, rational(9));
s.set_column_value(lp_f, rational(11));
//create monomial cdij
//create monomial (cd)(ij)
vec.clear();
vec.push_back(lp_i);
vec.push_back(lp_j);
@ -1955,6 +1992,7 @@ void solver::test_order_lemma() {
s.set_column_value(lp_ef, rational(17));
// set abef = cdij, while it has to be abef < cdij
// because ab < cd and ef = ij > 0
s.set_column_value(lp_abef, rational(18));
s.set_column_value(lp_cdij, rational(18));