mirror of
https://github.com/Z3Prover/z3
synced 2025-06-25 07:13:41 +00:00
more tests and fixes in order lemma
Signed-off-by: Lev <levnach@hotmail.com>
This commit is contained in:
parent
261c664654
commit
70612fb109
1 changed files with 101 additions and 49 deletions
|
@ -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",
|
|
||||||
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;
|
return true;
|
||||||
}
|
}
|
||||||
if (ac_m > bd_m && !(ac_v > bd_v)) {
|
return false;
|
||||||
generate_ol(ac, a, c, bd, b, d, lp::lconstraint_kind::GT);
|
} else if (av > bv){
|
||||||
|
if(!(acv > bdv)) {
|
||||||
|
generate_ol(ac, a, 1, c, bd, b, 1, d, lp::lconstraint_kind::GT);
|
||||||
return true;
|
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::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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
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
|
||||||
|
if (sign > 0) {
|
||||||
SASSERT(s.get_column_value(lp_ab) < s.get_column_value(lp_cd));
|
SASSERT(s.get_column_value(lp_ab) < s.get_column_value(lp_cd));
|
||||||
// we have ab < cd
|
// we have ab < cd
|
||||||
s.set_column_value(lp_abef, nla.m_imp->mon_value_by_vars(mon_abef));
|
|
||||||
|
// 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_cdij, nla.m_imp->mon_value_by_vars(mon_cdij));
|
||||||
if (sign > 0) {
|
|
||||||
// we need to have abef < cdij, so let us make abef > 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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue