3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-24 23:03:41 +00:00

more tests and fixes in order lemma

Signed-off-by: Lev <levnach@hotmail.com>
This commit is contained in:
Lev 2018-12-07 18:31:10 -10:00 committed by Lev Nachmanson
parent 261c664654
commit 70612fb109

View file

@ -893,23 +893,25 @@ struct solver::imp {
} }
} }
void negate_factor_relation(const factor& a, const factor& b) { void negate_factor_relation(const rational& a_sign, const factor& a, const rational& b_sign, const factor& b) {
rational a_fs = flip_sign(a); rational a_fs = flip_sign(a);
rational b_fs = flip_sign(b); rational b_fs = flip_sign(b);
lp::lconstraint_kind cmp = vvr(a) < vvr(b)? lp::lconstraint_kind::GE : lp::lconstraint_kind::LE; lp::lconstraint_kind cmp = a_sign*vvr(a) < b_sign*vvr(b)? lp::lconstraint_kind::GE : lp::lconstraint_kind::LE;
mk_ineq(a_fs, var(a), - b_fs, var(b), cmp); mk_ineq(a_fs*a_sign, var(a), - b_fs*b_sign, var(b), cmp);
} }
void generate_ol(const rooted_mon& ac, void generate_ol(const rooted_mon& ac,
const factor& a, const factor& a,
int c_sign,
const factor& c, const factor& c,
const rooted_mon& bd, const rooted_mon& bd,
const factor& b, const factor& b,
int d_sign,
const factor& d, const factor& d,
lp::lconstraint_kind cmp) { lp::lconstraint_kind ab_cmp) {
negate_factor_equality(c, d); negate_factor_equality(c, d);
negate_factor_relation(a, b); negate_factor_relation(rational(c_sign), a, rational(d_sign), b);
mk_ineq(flip_sign(ac), var(ac), -flip_sign(bd), var(bd), cmp); mk_ineq(flip_sign(ac), var(ac), -flip_sign(bd), var(bd), ab_cmp);
} }
bool order_lemma_on_ac_and_bd_and_factors(const rooted_mon& ac, bool order_lemma_on_ac_and_bd_and_factors(const rooted_mon& ac,
@ -918,37 +920,92 @@ struct solver::imp {
const rooted_mon& bd, const rooted_mon& bd,
const factor& b, const factor& b,
const factor& d) { const factor& d) {
TRACE("nla_solver", TRACE("nla_solver", tout << "a = "; print_factor(a, tout); tout << ", b = "; print_factor(b, tout););
tout << "factor a = "; SASSERT(abs(vvr(c)) == abs(vvr(d)));
print_factor(a, tout); auto av = vvr(a); auto bv = vvr(b);
tout << ", factor b = "; auto cv = vvr(c); auto dv = vvr(d);
print_factor(b, tout);); auto acv = vvr(ac); auto bdv = vvr(bd);
auto ac_m = vvr(a) * vvr(c); if (cv == dv) {
auto bd_m = vvr(b) * vvr(d); if (cv.is_pos()) {
if (av < bv){
auto ac_v = vvr(ac); if(!(acv < bdv)) {
auto bd_v = vvr(bd); generate_ol(ac, a, 1, c, bd, b, 1, d, lp::lconstraint_kind::LT);
TRACE("nla_solver", return true;
tout << "ac_m = " << ac_m << ", "; }
tout << "bd_m = " << bd_m << ", "; return false;
tout << "ac_v = " << ac_v << ", "; } else if (av > bv){
tout << "bd_v = " << bd_v; if(!(acv > bdv)) {
); generate_ol(ac, a, 1, c, bd, b, 1, d, lp::lconstraint_kind::GT);
return true;
if (ac_m < bd_m && !(ac_v < bd_v)) { }
generate_ol(ac, a, c, bd, b, d, lp::lconstraint_kind::LT); return false;
return true; } else {
SASSERT(av == bv);
// the sign lemma should take care of this case
}
} else {
SASSERT(cv.is_neg());
if (av < bv){
if(!(acv > bdv)) {
generate_ol(ac, a, 1, c, bd, b, 1, d, lp::lconstraint_kind::GT);
return true;
}
return false;
} else if (av > bv){
if(!(acv < bdv)) {
generate_ol(ac, a, 1, c, bd, b, 1, d, lp::lconstraint_kind::LT);
return true;
}
return false;
} else {
SASSERT(av == bv);
// the sign lemma should take care of this case
}
}
} else { // cv == -dv
if (cv.is_pos()) {
if (av < -bv){
if(!(acv < bdv)) {
generate_ol(ac, a, 1, c, bd, b, -1, d, lp::lconstraint_kind::LT);
return true;
}
return false;
} else if (av > -bv){
if(!(acv > bdv)) {
generate_ol(ac, a, 1, c, bd, b, -1, d, lp::lconstraint_kind::GT);
return true;
}
return false;
} else {
SASSERT(av == bv);
// the sign lemma should take care of this case
}
} else {
SASSERT(cv.is_neg());
if (-av < bv){
if(!(acv < bdv)) {
generate_ol(ac, a, -1, c, bd, b, 1, d, lp::lconstraint_kind::LT);
return true;
}
return false;
} else if (-av > bv){
if(!(acv > bdv)) {
generate_ol(ac, a, -1, c, bd, b, 1, d, lp::lconstraint_kind::GT);
return true;
}
return false;
} else {
SASSERT(av == bv);
// the sign lemma should take care of this case
}
}
} }
if (ac_m > bd_m && !(ac_v > bd_v)) {
generate_ol(ac, a, c, bd, b, d, lp::lconstraint_kind::GT);
return true;
}
return false; return false;
} }
// a > b && c > 0 && d = |c => ac > bd // a > b && c > 0 && d = c => ac > bd
// 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_ac_and_bd(const rooted_mon& rm_ac, bool order_lemma_on_ac_and_bd(const rooted_mon& rm_ac,
@ -964,16 +1021,9 @@ struct solver::imp {
SASSERT(abs(vvr(ac_f[k])) == abs(vvr(d))); SASSERT(abs(vvr(ac_f[k])) == abs(vvr(d)));
factor b; factor b;
if (!divide(rm_bd, d, b)){ if (!divide(rm_bd, d, b)){
TRACE("nla_solver", tout << "no division";);
return false; return false;
} }
TRACE("nla_solver", tout << "div factor b = ";
print_factor(b, tout););
TRACE("nla_solver", tout << "vvr(b) = " << vvr(b););
return order_lemma_on_ac_and_bd_and_factors(rm_ac, ac_f[(k + 1) % 2], ac_f[k], rm_bd, b, d); return order_lemma_on_ac_and_bd_and_factors(rm_ac, ac_f[(k + 1) % 2], ac_f[k], rm_bd, b, d);
} }
@ -1783,7 +1833,7 @@ void solver::test_order_lemma_params(int sign) {
vec.push_back(lp_a); vec.push_back(lp_a);
vec.push_back(lp_b); vec.push_back(lp_b);
vec.push_back(lp_f); vec.push_back(lp_f);
auto mon_abef = nla.add_monomial(lp_abef, vec.size(), vec.begin()); nla.add_monomial(lp_abef, vec.size(), vec.begin());
//create monomial (cd)(ij) //create monomial (cd)(ij)
vec.clear(); vec.clear();
@ -1805,20 +1855,22 @@ void solver::test_order_lemma_params(int sign) {
s.set_column_value(lp_ij, nla.m_imp->mon_value_by_vars(mon_ij)); s.set_column_value(lp_ij, nla.m_imp->mon_value_by_vars(mon_ij));
// set abef = cdij, while it has to be abef < cdij // set abef = cdij, while it has to be abef < cdij
SASSERT(s.get_column_value(lp_ab) < s.get_column_value(lp_cd));
// we have ab < cd
s.set_column_value(lp_abef, nla.m_imp->mon_value_by_vars(mon_abef));
s.set_column_value(lp_cdij, nla.m_imp->mon_value_by_vars(mon_cdij));
if (sign > 0) { if (sign > 0) {
// we need to have abef < cdij, so let us make abef > cdij SASSERT(s.get_column_value(lp_ab) < s.get_column_value(lp_cd));
// we have ab < cd
// we need to have ab*ef < cd*ij, so let us make ab*ef > cd*ij
s.set_column_value(lp_cdij, nla.m_imp->mon_value_by_vars(mon_cdij));
s.set_column_value(lp_abef, nla.m_imp->mon_value_by_vars(mon_cdij) s.set_column_value(lp_abef, nla.m_imp->mon_value_by_vars(mon_cdij)
+ rational(1)); + rational(1));
} }
else { else {
// we need to have abef > cdij, so let us make abef < cdij SASSERT(-s.get_column_value(lp_ab) < s.get_column_value(lp_cd));
// we need to have abef < cdij, so let us make abef < cdij
s.set_column_value(lp_cdij, nla.m_imp->mon_value_by_vars(mon_cdij));
s.set_column_value(lp_abef, nla.m_imp->mon_value_by_vars(mon_cdij) s.set_column_value(lp_abef, nla.m_imp->mon_value_by_vars(mon_cdij)
- rational(1)); + rational(1));
} }
vector<ineq> lemma; vector<ineq> lemma;
lp::explanation exp; lp::explanation exp;