3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-13 20:38:43 +00:00

cleanup mostly, more asserts in tangent lemma

This commit is contained in:
Lev Nachmanson 2019-03-22 17:37:19 -07:00
parent 9c62b431e4
commit 1810d7e77d
8 changed files with 186 additions and 146 deletions

View file

@ -238,7 +238,7 @@ public :
bound /= u_coeff;
if (numeric_traits<impq>::is_pos(u_coeff)) {
if (u_coeff.is_pos()) {
limit_j(m_column_of_u, bound, true, true, strict);
} else {
limit_j(m_column_of_u, bound, false, false, strict);

View file

@ -35,12 +35,12 @@ public:
m_explanation.push_back(std::make_pair(one_of_type<mpq>(), j));
}
template <typename A>
void add(const A& a) { for (auto j : a) add(j); }
void add(const explanation& e) { for (auto j: e.m_set_of_ci) add(j); }
void add(unsigned ci) { push_justification(ci); }
void add(const std::pair<mpq, constraint_index>& j) { push_justification(j.second, j.first); }
void add(unsigned j) { push_justification(j); }
bool empty() const { return m_explanation.empty(); }
size_t size() const { return m_explanation.size(); }
};

View file

@ -122,11 +122,11 @@ bool int_solver::current_solution_is_inf_on_cut() const {
const auto & x = m_lar_solver->m_mpq_lar_core_solver.m_r_x;
impq v = m_t.apply(x);
mpq sign = m_upper ? one_of_type<mpq>() : -one_of_type<mpq>();
CTRACE("current_solution_is_inf_on_cut", v * sign <= m_k * sign,
CTRACE("current_solution_is_inf_on_cut", v * sign <= impq(m_k) * sign,
tout << "m_upper = " << m_upper << std::endl;
tout << "v = " << v << ", k = " << m_k << std::endl;
);
return v * sign > m_k * sign;
return v * sign > impq(m_k) * sign;
}
constraint_index int_solver::column_lower_bound_constraint(unsigned j) const {
@ -483,7 +483,7 @@ void int_solver::patch_nbasic_column(unsigned j, bool patch_only_int_vals) {
tout << "]";
tout << ", m: " << m << ", val: " << val << ", is_int: " << m_lar_solver->column_is_int(j) << "\n";);
if (!inf_l) {
l = m_is_one ? ceil(l) : m * ceil(l / m);
l = impq(m_is_one ? ceil(l) : m * ceil(l / m));
if (inf_u || l <= u) {
TRACE("patch_int",
tout << "patching with l: " << l << '\n';);
@ -495,7 +495,7 @@ void int_solver::patch_nbasic_column(unsigned j, bool patch_only_int_vals) {
}
}
else if (!inf_u) {
u = m_is_one ? floor(u) : m * floor(u / m);
u = impq(m_is_one ? floor(u) : m * floor(u / m));
m_lar_solver->set_value_for_nbasic_column(j, u);
TRACE("patch_int",
tout << "patching with u: " << u << '\n';);
@ -920,14 +920,14 @@ bool int_solver::shift_var(unsigned j, unsigned range) {
}
if (column_is_int(j)) {
if (!inf_l) {
l = ceil(l);
l = impq(ceil(l));
if (!m.is_one())
l = m*ceil(l/m);
l = impq(m*ceil(l/m));
}
if (!inf_u) {
u = floor(u);
u = impq(floor(u));
if (!m.is_one())
u = m*floor(u/m);
u = impq(m*floor(u/m));
}
}
if (!inf_l && !inf_u && l >= u)

View file

@ -2237,11 +2237,11 @@ void lar_solver::round_to_integer_solution() {
if (v.is_int())
continue;
SASSERT(is_base(j));
impq flv = floor(v);
impq flv = impq(floor(v));
auto del = flv - v; // del is negative
if (del < - mpq(1, 2)) {
if (del < - impq(mpq(1, 2))) {
del = impq(one_of_type<mpq>()) + del;
v = ceil(v);
v = impq(ceil(v));
} else {
v = flv;
}

View file

@ -474,7 +474,7 @@ public:
break;
default:
lp_assert(false);
new_val_for_leaving = numeric_traits<T>::zero(); // does not matter
new_val_for_leaving = numeric_traits<X>::zero(); // does not matter
}
return j;
}

View file

@ -389,6 +389,7 @@ struct solver::imp {
std::ostream& print_explanation(lp::explanation& exp, std::ostream& out) const {
out << "expl: ";
for (auto &p : exp) {
out << "(" << p.second << ")";
m_lar_solver.print_constraint(p.second, out);
out << " ";
}
@ -501,7 +502,6 @@ struct solver::imp {
break;
case llc::NE:
r = explain_lower_bound(t, rs + rational(1), exp) || explain_upper_bound(t, rs - rational(1), exp);
CTRACE("nla_solver", r, tout << "ineq:"; print_ineq(ineq(cmp, t, rs), tout); print_explanation(exp, tout << ", "););
break;
default:
SASSERT(false);
@ -673,7 +673,7 @@ struct solver::imp {
}
void negate_strict_sign(lpvar j) {
TRACE("nla_solver", print_var(j, tout););
TRACE("nla_solver_details", print_var(j, tout););
if (!vvr(j).is_zero()) {
int sign = rat_sign(vvr(j));
mk_ineq(j, (sign == 1? llc::LE : llc::GE));
@ -690,7 +690,7 @@ struct solver::imp {
}
void generate_strict_case_zero_lemma(const monomial& m, unsigned zero_j, int sign_of_zj) {
TRACE("nla_solver", tout << "sign_of_zj = " << sign_of_zj << "\n";);
TRACE("nla_solver_bl", tout << "sign_of_zj = " << sign_of_zj << "\n";);
// we know all the signs
add_empty_lemma();
mk_ineq(zero_j, (sign_of_zj == 1? llc::GT : llc::LT));
@ -700,6 +700,7 @@ struct solver::imp {
}
}
negate_strict_sign(m.var());
TRACE("nla_solver", print_lemma(tout););
}
bool has_upper_bound(lpvar j) const {
@ -770,6 +771,13 @@ struct solver::imp {
static bool is_even(unsigned k) {
return (k >> 1) << 1 == k;
}
void add_trival_zero_lemma(lpvar zero_j, const monomial& m) {
add_empty_lemma();
mk_ineq(zero_j, llc::NE);
mk_ineq(m.var(), llc::EQ);
TRACE("nla_solver", print_lemma(tout););
}
void generate_zero_lemmas(const monomial& m) {
SASSERT(!vvr(m).is_zero() && product_value(m).is_zero());
@ -789,15 +797,12 @@ struct solver::imp {
}
if (sign && is_even(zero_power))
sign = 0;
TRACE("nla_solver", tout << "zero_j = " << zero_j << ", sign = " << sign << "\n";);
if (sign == 0) {
add_empty_lemma();
mk_ineq(zero_j, llc::NE);
mk_ineq(m.var(), llc::EQ);
} else {
TRACE("nla_solver_details", tout << "zero_j = " << zero_j << ", sign = " << sign << "\n";);
if (sign == 0) { // have to generate a non-convex lemma
add_trival_zero_lemma(zero_j, m);
} else {
generate_strict_case_zero_lemma(m, zero_j, sign);
}
TRACE("nla_solver", print_lemma(tout););
for (lpvar j : fixed_zeros)
add_fixed_zero_lemma(m, j);
}
@ -886,7 +891,7 @@ struct solver::imp {
void basic_sign_lemma_model_based_one_mon(const monomial& m, int product_sign) {
if (product_sign == 0) {
TRACE("nla_solver", tout << "zero product sign\n";);
TRACE("nla_solver_bl", tout << "zero product sign\n";);
generate_zero_lemmas(m);
} else {
add_empty_lemma();
@ -969,7 +974,7 @@ struct solver::imp {
return
m_lar_solver.column_has_upper_bound(j) &&
m_lar_solver.column_has_lower_bound(j) &&
m_lar_solver.get_upper_bound(j) == v && m_lar_solver.get_lower_bound(j) == v;
m_lar_solver.get_upper_bound(j) == lp::impq(v) && m_lar_solver.get_lower_bound(j) == lp::impq(v);
}
bool var_is_fixed(lpvar j) const {
@ -1006,18 +1011,22 @@ struct solver::imp {
std::ostream & print_ineqs(const lemma& l, std::ostream & out) const {
std::unordered_set<lpvar> vars;
out << "ineqs: ";
for (unsigned i = 0; i < l.ineqs().size(); i++) {
auto & in = l.ineqs()[i];
print_ineq(in, out);
if (i + 1 < l.ineqs().size()) out << " or ";
for (const auto & p: in.m_term)
vars.insert(p.var());
if (l.ineqs().size() == 0) {
out << "conflict\n";
} else {
for (unsigned i = 0; i < l.ineqs().size(); i++) {
auto & in = l.ineqs()[i];
print_ineq(in, out);
if (i + 1 < l.ineqs().size()) out << " or ";
for (const auto & p: in.m_term)
vars.insert(p.var());
}
out << std::endl;
for (lpvar j : vars) {
print_var(j, out);
}
out << "\n";
}
out << std::endl;
for (lpvar j : vars) {
print_var(j, out);
}
out << "\n";
return out;
}
@ -1155,7 +1164,7 @@ struct solver::imp {
}
// x = 0 or y = 0 -> xy = 0
bool basic_lemma_for_mon_non_zero_model_based(const rooted_mon& rm, const factorization& f) {
TRACE("nla_solver", trace_print_monomial_and_factorization(rm, f, tout););
TRACE("nla_solver_bl", trace_print_monomial_and_factorization(rm, f, tout););
SASSERT (!vvr(rm).is_zero());
int zero_j = -1;
for (auto j : f) {
@ -1218,10 +1227,10 @@ struct solver::imp {
// use the fact that
// |xabc| = |x| and x != 0 -> |a| = |b| = |c| = 1
bool basic_lemma_for_mon_neutral_monomial_to_factor_model_based(const rooted_mon& rm, const factorization& f) {
TRACE("nla_solver", trace_print_monomial_and_factorization(rm, f, tout););
TRACE("nla_solver_bl", trace_print_monomial_and_factorization(rm, f, tout););
lpvar mon_var = m_monomials[rm.orig_index()].var();
TRACE("nla_solver", trace_print_monomial_and_factorization(rm, f, tout); tout << "\nmon_var = " << mon_var << "\n";);
TRACE("nla_solver_bl", trace_print_monomial_and_factorization(rm, f, tout); tout << "\nmon_var = " << mon_var << "\n";);
const auto & mv = vvr(mon_var);
const auto abs_mv = abs(mv);
@ -1358,9 +1367,9 @@ struct solver::imp {
rational sign = rm.orig().m_sign;
lpvar not_one = -1;
TRACE("nla_solver", tout << "f = "; print_factorization(f, tout););
TRACE("nla_solver_bl", tout << "f = "; print_factorization(f, tout););
for (auto j : f){
TRACE("nla_solver", tout << "j = "; print_factor_with_vars(j, tout););
TRACE("nla_solver_bl", tout << "j = "; print_factor_with_vars(j, tout););
auto v = vvr(j);
if (v == rational(1)) {
continue;
@ -1404,8 +1413,9 @@ struct solver::imp {
}
explain(f, current_expl());
TRACE("nla_solver",
print_lemma(tout);
tout << "rm = "; print_rooted_monomial_with_vars(rm, tout);
print_lemma(tout););
);
return true;
}
// use the fact
@ -1567,7 +1577,7 @@ struct solver::imp {
}
void basic_lemma_for_mon_model_based(const rooted_mon& rm) {
TRACE("nla_solver", tout << "rm = "; print_rooted_monomial(rm, tout););
TRACE("nla_solver_bl", tout << "rm = "; print_rooted_monomial(rm, tout););
if (vvr(rm).is_zero()) {
for (auto factorization : factorization_factory_imp(rm.m_vars, *this)) {
if (factorization.is_empty())
@ -1730,7 +1740,7 @@ struct solver::imp {
SASSERT(m_vars_equivalence.empty());
collect_equivs();
m_vars_equivalence.create_tree();
TRACE("nla_solver", tout << "number of equivs = " << m_vars_equivalence.size(););
TRACE("nla_solver_details", tout << "number of equivs = " << m_vars_equivalence.size(););
SASSERT((settings().random_next() % 100) || tables_are_ok());
}
@ -1857,7 +1867,7 @@ struct solver::imp {
m_to_refine.push_back(i);
}
TRACE("nla_solver",
tout << m_to_refine.size() << " mons to refine: ";
tout << m_to_refine.size() << " mons to refine:\n";
for (unsigned i: m_to_refine) {
print_monomial_with_vars(m_monomials[i], tout);
}
@ -1968,8 +1978,7 @@ struct solver::imp {
}
void print_lemma(std::ostream& out) {
static int n = 0;
out << "lemma:" << ++n << " ";
out << "lemma:";
print_ineqs(current_lemma(), out);
print_explanation(current_expl(), out);
std::unordered_set<lpvar> vars = collect_vars(current_lemma());
@ -2163,6 +2172,7 @@ struct solver::imp {
for (unsigned j = 0, k = 1; j < 2; j++, k--) {
order_lemma_on_ab(m, sign, var(ab[k]), var(ab[j]), gt);
explain(ab, current_expl()); explain(m, current_expl());
explain(rm, current_expl());
order_lemma_on_factor_explore(rm, ab, j);
}
@ -2536,7 +2546,6 @@ struct solver::imp {
do {
unsigned rm_i = m_rm_table.m_to_refine[i];
monotonicity_lemma(m_rm_table.rms()[rm_i].orig_index());
TRACE("nla_solver", print_lemma(tout); );
if (done()) return;
i++;
if (i == m_rm_table.m_to_refine.size())
@ -2608,13 +2617,23 @@ struct solver::imp {
for (unsigned i: m_rm_table.to_refine()) {
const auto& rm = m_rm_table.rms()[i];
SASSERT (!check_monomial(m_monomials[rm.orig_index()]));
if (rm.size() == 2) {
sign = rational(1);
const monomial & m = m_monomials[rm.orig_index()];
j = m.var();
rm_found = nullptr;
bf.m_x = m[0];
bf.m_y = m[1];
return true;
}
rm_found = &rm;
if (find_bfc_on_monomial(rm, bf)) {
j = m_monomials[rm.orig_index()].var();
sign = rm.orig_sign();
TRACE("nla_solver", tout << "found bf";
tout << ":rm:"; print_rooted_monomial(rm, tout) << "\n";
print_bfc(bf, tout);
tout << "bf:"; print_bfc(bf, tout);
tout << ", product = " << vvr(rm) << ", but should be =" << vvr(bf.m_x)*vvr(bf.m_y);
tout << ", j == "; print_var(j, tout) << "\n";);
return true;
@ -2687,7 +2706,7 @@ struct solver::imp {
TRACE("nla_solver", tout << "cannot find a bfc to refine\n"; );
return false;
}
tangent_lemma_bf(bf, j, sign, *rm);
tangent_lemma_bf(bf, j, sign, rm);
return true;
}
@ -2698,7 +2717,7 @@ struct solver::imp {
explain(bf.m_y, exp);
}
void tangent_lemma_bf(const bfc& bf, lpvar j, const rational& sign, const rooted_mon& rm){
void tangent_lemma_bf(const bfc& bf, lpvar j, const rational& sign, const rooted_mon* rm){
point a, b;
point xy (vvr(bf.m_x), vvr(bf.m_y));
rational correct_mult_val = xy.x * xy.y;
@ -2707,19 +2726,25 @@ struct solver::imp {
TRACE("nla_solver", tout << "below = " << below << std::endl;);
get_tang_points(a, b, below, val, xy);
TRACE("nla_solver", tout << "sign = " << sign << ", tang domain = "; print_tangent_domain(a, b, tout); tout << std::endl;);
lp::explanation expl;
unsigned lemmas_start = m_lemma_vec->size();
generate_explanations_of_tang_lemma(rm, bf, expl);
generate_two_tang_lines(bf, xy, sign, j);
generate_tang_plane(a.x, a.y, bf.m_x, bf.m_y, below, j, sign);
generate_tang_plane(b.x, b.y, bf.m_x, bf.m_y, below, j, sign);
for (unsigned i = lemmas_start; i < m_lemma_vec->size(); i++) {
auto &l = (*m_lemma_vec)[i];
l.expl().add(expl);
TRACE("nla_solver",
print_ineqs(l, tout);
print_explanation(l.expl(), tout););
// if rm == nullptr there is no need to explain equivs since we work on a monomial and not on a rooted monomial
if (rm != nullptr) {
lp::explanation expl;
generate_explanations_of_tang_lemma(*rm, bf, expl);
for (unsigned i = m_lemma_vec->size() - 3; i < m_lemma_vec->size(); i++) {
auto &l = (*m_lemma_vec)[i];
l.expl().add(expl);
}
}
TRACE("nla_solver",
for (unsigned i = m_lemma_vec->size() - 3; i < m_lemma_vec->size(); i++) {
auto &l = (*m_lemma_vec)[i];
tout << "lemma:";
print_ineqs(l, tout);
print_explanation(l.expl(), tout);
} );
}
void add_empty_lemma() {
@ -2730,14 +2755,20 @@ struct solver::imp {
add_empty_lemma();
negate_relation(jx, a);
negate_relation(jy, b);
// If "below" holds then ay + bx - ab < xy, otherwise ay + bx - ab > xy,
// j_sign*vvr(j) stands for xy. So, finally we have ay + bx - j_sign*j < ab ( or > )
bool sbelow = j_sign.is_pos()? below: !below;
#if Z3DEBUG
int mult_sign = rat_sign(a - vvr(jx))*rat_sign(b - vvr(jy));
SASSERT((mult_sign == 1) == sbelow);
// If "mult_sign is 1" then (a - x)(b-y) > 0 and ab - bx - ay + xy > 0
// or -ab + bx + ay < xy or -ay - bx + xy > -ab
// j_sign*vvr(j) stands for xy. So, finally we have -ay - bx + j_sign*j > - ab
#endif
lp::lar_term t;
t.add_coeff_var(a, jy);
t.add_coeff_var(b, jx);
t.add_coeff_var( -j_sign, j);
mk_ineq(t, below? llc::LT : llc::GT, a*b);
TRACE("nla_solver", print_lemma(tout););
t.add_coeff_var(-a, jy);
t.add_coeff_var(-b, jx);
t.add_coeff_var( j_sign, j);
mk_ineq(t, sbelow? llc::GT : llc::LT, - a*b);
}
void negate_relation(unsigned j, const rational& a) {
@ -2754,12 +2785,10 @@ struct solver::imp {
add_empty_lemma();
mk_ineq(bf.m_x, llc::NE, xy.x);
mk_ineq(sign, j, - xy.x, bf.m_y, llc::EQ);
TRACE("nla_solver", print_lemma(tout););
add_empty_lemma();
mk_ineq(bf.m_y, llc::NE, xy.y);
mk_ineq(sign, j, - xy.y, bf.m_x, llc::EQ);
TRACE("nla_solver", print_lemma(tout););
}
// Get two planes tangent to surface z = xy, one at point a, and another at point b.
// One can show that these planes still create a cut.
@ -2786,7 +2815,7 @@ struct solver::imp {
point na = xy + del;
TRACE("nla_solver", tout << "del = "; print_point(del, tout); tout << std::endl;);
if (!plane_is_correct_cut(na, xy, correct_val, val, below)) {
TRACE("nla_solver", tout << "exit";tout << std::endl;);
TRACE("nla_solver_tp", tout << "exit";tout << std::endl;);
return;
}
a = na;
@ -2851,6 +2880,7 @@ struct solver::imp {
return l_false;
}
if (derived) continue;
TRACE("nla_solver", tout << "passed derived and basic lemmas\n";);
if (search_level == 1) {
order_lemma();
} else { // search_level == 2
@ -3073,14 +3103,14 @@ void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_0() {
// set abcde = ac * bde
// ac = 1 then abcde = bde, but we have abcde < bde
s.set_column_value(lp_a, rational(4));
s.set_column_value(lp_b, rational(4));
s.set_column_value(lp_c, rational(4));
s.set_column_value(lp_d, rational(4));
s.set_column_value(lp_e, rational(4));
s.set_column_value(lp_abcde, rational(15));
s.set_column_value(lp_ac, rational(1));
s.set_column_value(lp_bde, rational(16));
s.set_column_value(lp_a, lp::impq(rational(4)));
s.set_column_value(lp_b, lp::impq(rational(4)));
s.set_column_value(lp_c, lp::impq(rational(4)));
s.set_column_value(lp_d, lp::impq(rational(4)));
s.set_column_value(lp_e, lp::impq(rational(4)));
s.set_column_value(lp_abcde, lp::impq(rational(15)));
s.set_column_value(lp_ac, lp::impq(rational(1)));
s.set_column_value(lp_bde, lp::impq(rational(16)));
SASSERT(nla.m_imp->test_check(lv) == l_false);
@ -3113,6 +3143,14 @@ void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_0() {
}
void solver::s_set_column_value(lp::lar_solver&s, lpvar j, const rational & v) {
s.set_column_value(j, lp::impq(v));
}
void solver::s_set_column_value(lp::lar_solver&s, lpvar j, const lp::impq & v) {
s.set_column_value(j, v);
}
void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_1() {
std::cout << "test_basic_lemma_for_mon_neutral_from_factors_to_monomial_1\n";
TRACE("nla_solver",);
@ -3134,12 +3172,12 @@ void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_1() {
vector<lemma> lemma;
s.set_column_value(lp_a, rational(1));
s.set_column_value(lp_b, rational(1));
s.set_column_value(lp_c, rational(1));
s.set_column_value(lp_d, rational(1));
s.set_column_value(lp_e, rational(1));
s.set_column_value(lp_bde, rational(3));
s_set_column_value(s, lp_a, rational(1));
s_set_column_value(s, lp_b, rational(1));
s_set_column_value(s, lp_c, rational(1));
s_set_column_value(s, lp_d, rational(1));
s_set_column_value(s, lp_e, rational(1));
s_set_column_value(s, lp_bde, rational(3));
SASSERT(nla.m_imp->test_check(lemma) == l_false);
SASSERT(lemma[0].size() == 4);
@ -3209,16 +3247,16 @@ void solver::test_basic_lemma_for_mon_zero_from_factors_to_monomial() {
vector<lemma> lemma;
// set vars
s.set_column_value(lp_a, rational(1));
s.set_column_value(lp_b, rational(0));
s.set_column_value(lp_c, rational(1));
s.set_column_value(lp_d, rational(1));
s.set_column_value(lp_e, rational(1));
s.set_column_value(lp_abcde, rational(0));
s.set_column_value(lp_ac, rational(1));
s.set_column_value(lp_bde, rational(0));
s.set_column_value(lp_acd, rational(1));
s.set_column_value(lp_be, rational(1));
s_set_column_value(s, lp_a, rational(1));
s_set_column_value(s, lp_b, rational(0));
s_set_column_value(s, lp_c, rational(1));
s_set_column_value(s, lp_d, rational(1));
s_set_column_value(s, lp_e, rational(1));
s_set_column_value(s, lp_abcde, rational(0));
s_set_column_value(s, lp_ac, rational(1));
s_set_column_value(s, lp_bde, rational(0));
s_set_column_value(s, lp_acd, rational(1));
s_set_column_value(s, lp_be, rational(1));
SASSERT(nla.m_imp->test_check(lemma) == l_false);
nla.m_imp->print_lemma(std::cout);
@ -3264,10 +3302,10 @@ void solver::test_basic_lemma_for_mon_zero_from_monomial_to_factors() {
nla.add_monomial(lp_acd, vec.size(), vec.begin());
vector<lemma> lemma;
s.set_column_value(lp_a, rational(1));
s.set_column_value(lp_c, rational(1));
s.set_column_value(lp_d, rational(1));
s.set_column_value(lp_acd, rational(0));
s_set_column_value(s, lp_a, rational(1));
s_set_column_value(s, lp_c, rational(1));
s_set_column_value(s, lp_d, rational(1));
s_set_column_value(s, lp_acd, rational(0));
SASSERT(nla.m_imp->test_check(lemma) == l_false);
@ -3332,22 +3370,22 @@ void solver::test_basic_lemma_for_mon_neutral_from_monomial_to_factors() {
vector<lemma> lemma;
// set all vars to 1
s.set_column_value(lp_a, rational(1));
s.set_column_value(lp_b, rational(1));
s.set_column_value(lp_c, rational(1));
s.set_column_value(lp_d, rational(1));
s.set_column_value(lp_e, rational(1));
s.set_column_value(lp_abcde, rational(1));
s.set_column_value(lp_ac, rational(1));
s.set_column_value(lp_bde, rational(1));
s.set_column_value(lp_acd, rational(1));
s.set_column_value(lp_be, rational(1));
s_set_column_value(s, lp_a, rational(1));
s_set_column_value(s, lp_b, rational(1));
s_set_column_value(s, lp_c, rational(1));
s_set_column_value(s, lp_d, rational(1));
s_set_column_value(s, lp_e, rational(1));
s_set_column_value(s, lp_abcde, rational(1));
s_set_column_value(s, lp_ac, rational(1));
s_set_column_value(s, lp_bde, rational(1));
s_set_column_value(s, lp_acd, rational(1));
s_set_column_value(s, lp_be, rational(1));
// set bde to 2, b to minus 2
s.set_column_value(lp_bde, rational(2));
s.set_column_value(lp_b, - rational(2));
s_set_column_value(s, lp_bde, rational(2));
s_set_column_value(s, lp_b, - rational(2));
// we have bde = -b, therefore d = +-1 and e = +-1
s.set_column_value(lp_d, rational(3));
s_set_column_value(s, lp_d, rational(3));
SASSERT(nla.m_imp->test_check(lemma) == l_false);
@ -3405,18 +3443,18 @@ void solver::test_basic_sign_lemma() {
// set the values of the factors so it should be bde = -acd according to the model
// b = -a
s.set_column_value(lp_a, rational(7));
s.set_column_value(lp_b, rational(-7));
s_set_column_value(s, lp_a, rational(7));
s_set_column_value(s, lp_b, rational(-7));
// e - c = 0
s.set_column_value(lp_e, rational(4));
s.set_column_value(lp_c, rational(4));
s_set_column_value(s, lp_e, rational(4));
s_set_column_value(s, lp_c, rational(4));
s.set_column_value(lp_d, rational(6));
s_set_column_value(s, lp_d, rational(6));
// make bde != -acd according to the model
s.set_column_value(lp_bde, lp::impq(rational(5)));
s.set_column_value(lp_acd, lp::impq(rational(3)));
s_set_column_value(s, lp_bde, rational(5));
s_set_column_value(s, lp_acd, rational(3));
vector<lemma> lemma;
SASSERT(nla.m_imp->test_check(lemma) == l_false);
@ -3467,7 +3505,7 @@ void solver::test_order_lemma_params(bool var_equiv, int sign) {
lpvar lp_cdij = s.add_named_var(cdij, true, "cdij");
for (unsigned j = 0; j < s.number_of_vars(); j++) {
s.set_column_value(j, rational(j + 2));
s_set_column_value(s, j, rational(j + 2));
}
reslimit l;
@ -3523,17 +3561,17 @@ void solver::test_order_lemma_params(bool var_equiv, int sign) {
auto mon_cdij = nla.add_monomial(lp_cdij, vec.size(), vec.begin());
// set i == e
s.set_column_value(lp_e, s.get_column_value(lp_i));
s_set_column_value(s, lp_e, s.get_column_value(lp_i));
// set f == sign*j
s.set_column_value(lp_f, rational(sign) * s.get_column_value(lp_j));
s_set_column_value(s, lp_f, rational(sign) * s.get_column_value(lp_j));
if (var_equiv) {
s.set_column_value(lp_k, s.get_column_value(lp_j));
s_set_column_value(s, lp_k, s.get_column_value(lp_j));
}
// set the values of ab, ef, cd, and ij correctly
s.set_column_value(lp_ab, nla.m_imp->mon_value_by_vars(mon_ab));
s.set_column_value(lp_ef, nla.m_imp->mon_value_by_vars(mon_ef));
s.set_column_value(lp_cd, nla.m_imp->mon_value_by_vars(mon_cd));
s.set_column_value(lp_ij, nla.m_imp->mon_value_by_vars(mon_ij));
s_set_column_value(s, lp_ab, nla.m_imp->mon_value_by_vars(mon_ab));
s_set_column_value(s, lp_ef, nla.m_imp->mon_value_by_vars(mon_ef));
s_set_column_value(s, lp_cd, nla.m_imp->mon_value_by_vars(mon_cd));
s_set_column_value(s, lp_ij, nla.m_imp->mon_value_by_vars(mon_ij));
// set abef = cdij, while it has to be abef < cdij
if (sign > 0) {
@ -3541,16 +3579,16 @@ void solver::test_order_lemma_params(bool var_equiv, int sign) {
// 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(s, lp_cdij, nla.m_imp->mon_value_by_vars(mon_cdij));
s_set_column_value(s, lp_abef, nla.m_imp->mon_value_by_vars(mon_cdij)
+ rational(1));
}
else {
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(s, lp_cdij, nla.m_imp->mon_value_by_vars(mon_cdij));
s_set_column_value(s, lp_abef, nla.m_imp->mon_value_by_vars(mon_cdij)
+ rational(1));
}
vector<lemma> lemma;
@ -3596,7 +3634,7 @@ void solver::test_monotone_lemma() {
lpvar lp_ef = s.add_named_var(ef, true, "ef");
lpvar lp_ij = s.add_named_var(ij, true, "ij");
for (unsigned j = 0; j < s.number_of_vars(); j++) {
s.set_column_value(j, rational((j + 2)*(j + 2)));
s_set_column_value(s, j, rational((j + 2)*(j + 2)));
}
reslimit l;
@ -3624,17 +3662,17 @@ void solver::test_monotone_lemma() {
int mon_ij = nla.add_monomial(lp_ij, vec.size(), vec.begin());
// set e == i + 1
s.set_column_value(lp_e, s.get_column_value(lp_i) + rational(1));
s_set_column_value(s, lp_e, s.get_column_value(lp_i) + lp::impq(rational(1)));
// set f == j + 1
s.set_column_value(lp_f, s.get_column_value(lp_j) + rational(1));
s_set_column_value(s, lp_f, s.get_column_value(lp_j) +lp::impq( rational(1)));
// set the values of ab, ef, cd, and ij correctly
s.set_column_value(lp_ab, nla.m_imp->mon_value_by_vars(mon_ab));
s.set_column_value(lp_cd, nla.m_imp->mon_value_by_vars(mon_cd));
s.set_column_value(lp_ij, nla.m_imp->mon_value_by_vars(mon_ij));
s_set_column_value(s, lp_ab, nla.m_imp->mon_value_by_vars(mon_ab));
s_set_column_value(s, lp_cd, nla.m_imp->mon_value_by_vars(mon_cd));
s_set_column_value(s, lp_ij, nla.m_imp->mon_value_by_vars(mon_ij));
// set ef = ij while it has to be ef > ij
s.set_column_value(lp_ef, s.get_column_value(lp_ij));
s_set_column_value(s, lp_ef, s.get_column_value(lp_ij));
vector<lemma> lemma;
SASSERT(nla.m_imp->test_check(lemma) == l_false);
@ -3658,7 +3696,7 @@ void solver::test_tangent_lemma_reg() {
int sign = 1;
for (unsigned j = 0; j < s.number_of_vars(); j++) {
sign *= -1;
s.set_column_value(j, sign * rational((j + 2) * (j + 2)));
s_set_column_value(s, j, sign * rational((j + 2) * (j + 2)));
}
reslimit l;
@ -3670,7 +3708,7 @@ void solver::test_tangent_lemma_reg() {
vec.push_back(lp_b);
int mon_ab = nla.add_monomial(lp_ab, vec.size(), vec.begin());
s.set_column_value(lp_ab, nla.m_imp->mon_value_by_vars(mon_ab) + rational(10)); // greater by ten than the correct value
s_set_column_value(s, lp_ab, nla.m_imp->mon_value_by_vars(mon_ab) + rational(10)); // greater by ten than the correct value
vector<lemma> lemma;
SASSERT(nla.m_imp->test_check(lemma) == l_false);
nla.m_imp->print_lemma(std::cout);
@ -3694,7 +3732,7 @@ void solver::test_tangent_lemma_equiv() {
int sign = 1;
for (unsigned j = 0; j < s.number_of_vars(); j++) {
sign *= -1;
s.set_column_value(j, sign * rational((j + 2) * (j + 2)));
s_set_column_value(s, j, sign * rational((j + 2) * (j + 2)));
}
// make k == -a
@ -3704,7 +3742,7 @@ void solver::test_tangent_lemma_equiv() {
lpvar kj = s.add_term(t.coeffs_as_vector(), -1);
s.add_var_bound(kj, llc::LE, rational(0));
s.add_var_bound(kj, llc::GE, rational(0));
s.set_column_value(lp_a, - s.get_column_value(lp_k));
s_set_column_value(s, lp_a, - s.get_column_value(lp_k));
reslimit l;
params_ref p;
solver nla(s, l, p);
@ -3714,7 +3752,7 @@ void solver::test_tangent_lemma_equiv() {
vec.push_back(lp_b);
int mon_ab = nla.add_monomial(lp_ab, vec.size(), vec.begin());
s.set_column_value(lp_ab, nla.m_imp->mon_value_by_vars(mon_ab) + rational(10)); // greater by ten than the correct value
s_set_column_value(s, lp_ab, nla.m_imp->mon_value_by_vars(mon_ab) + rational(10)); // greater by ten than the correct value
vector<lemma> lemma;
SASSERT(nla.m_imp->test_check(lemma) == l_false);

View file

@ -82,5 +82,7 @@ public:
static void test_tangent_lemma();
static void test_tangent_lemma_reg();
static void test_tangent_lemma_equiv();
static void s_set_column_value(lp::lar_solver&, unsigned, const rational &);
static void s_set_column_value(lp::lar_solver&, unsigned, const lp::impq &);
};
}

View file

@ -140,7 +140,7 @@ struct numeric_pair {
numeric_pair(T xp, T yp) : x(xp), y(yp) {}
template <typename X>
numeric_pair(const X & n) : x(n), y(0) {
explicit numeric_pair(const X & n) : x(n), y(0) {
}
numeric_pair(const numeric_pair<T> & n) : x(n.x), y(n.y) {}