3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

create class lemma

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2019-02-10 21:40:47 -08:00
parent 4243bd3e2a
commit b2943c34f1
4 changed files with 119 additions and 131 deletions

View file

@ -2153,7 +2153,7 @@ public:
void false_case_of_check_nla() {
literal_vector core;
for (auto const& ineq : m_lemma) {
for (auto const& ineq : m_lemma.ineqs()) {
bool is_lower = true, pos = true, is_eq = false;
switch (ineq.m_cmp) {
case lp::LE: is_lower = false; pos = false; break;
@ -2181,14 +2181,12 @@ public:
set_conflict_or_lemma(core, false);
}
lbool check_aftermath_nla(lbool r, const vector<nla::lemma>& l,
const vector<lp::explanation>& e) {
lbool check_aftermath_nla(lbool r, const vector<nla::lemma>& lv) {
switch (r) {
case l_false: {
SASSERT(l.size() == e.size());
for(unsigned i = 0; i < l.size(); i++) {
m_lemma = l[i];
m_explanation = e[i];
for(const nla::lemma & l : lv) {
m_lemma = l; //todo avoit the copy
m_explanation = l.expl();
false_case_of_check_nla();
}
break;
@ -2217,9 +2215,8 @@ public:
m_explanation.clear();
return check_aftermath_nra(m_nra->check(m_explanation));
}
vector<nla::lemma> l;
vector<lp::explanation> e;
return check_aftermath_nla(m_nla->check(e, l), l, e);
vector<nla::lemma> lv;
return check_aftermath_nla(m_nla->check(lv), lv);
}
/**

View file

@ -41,5 +41,6 @@ public:
void add(unsigned j) { push_justification(j); }
bool empty() const { return m_explanation.empty(); }
size_t size() const { return m_explanation.size(); }
};
}

View file

@ -96,7 +96,6 @@ struct solver::imp {
// m_var_to_its_monomial[m_monomials[i].var()] = i
std::unordered_map<lpvar, unsigned> m_var_to_its_monomial;
vector<lp::explanation> * m_expl_vec;
vector<lemma> * m_lemma_vec;
unsigned_vector m_to_refine;
std::unordered_map<unsigned_vector, unsigned, hash_svector> m_mkeys; // the key is the sorted vars of a monomial
@ -147,12 +146,12 @@ struct solver::imp {
return compare_holds(value(n.term()), n.cmp(), n.rs());
}
bool lemma_holds(const lemma& l) const {
for(auto &i : l) {
bool an_ineq_holds(const lemma& l) const {
for(const ineq &i : l.ineqs()) {
if (!ineq_holds(i))
return false;
}
return true;
return false;
}
rational vvr(lpvar j) const { return m_lar_solver.get_column_value_rational(j); }
@ -540,16 +539,16 @@ struct solver::imp {
// the monomials should be equal by modulo sign but this is not so in the model
void fill_explanation_and_lemma_sign(const monomial& a, const monomial & b, rational const& sign) {
SASSERT(sign == 1 || sign == -1);
explain(a, m_expl_vec->back());
explain(b, m_expl_vec->back());
explain(a, current_expl());
explain(b, current_expl());
TRACE("nla_solver",
tout << "used constraints: ";
for (auto &p : m_expl_vec->back())
for (auto &p : current_expl())
m_lar_solver.print_constraint(p.second, tout); tout << "\n";
);
SASSERT(m_lemma_vec->back().size() == 0);
mk_ineq(rational(1), a.var(), -sign, b.var(), llc::EQ, rational::zero(), m_lemma_vec->back());
TRACE("nla_solver", print_lemma(m_lemma_vec->back(), tout););
SASSERT(current_ineqs().size() == 0);
mk_ineq(rational(1), a.var(), -sign, b.var(), llc::EQ, rational::zero(), current_lemma());
TRACE("nla_solver", print_lemma(tout););
}
// Replaces each variable index by the root in the tree and flips the sign if the var comes with a minus.
@ -586,7 +585,7 @@ struct solver::imp {
// the value of the i-th monomial has to be equal to the value of the k-th monomial modulo sign
// but it is not the case in the model
void generate_sign_lemma(const monomial& m, const monomial& n, const rational& sign) {
add_empty_lemma_and_explanation();
add_empty_lemma();
TRACE("nla_solver",
tout << "m = "; print_monomial_with_vars(m, tout);
tout << "n = "; print_monomial_with_vars(n, tout);
@ -594,7 +593,7 @@ struct solver::imp {
mk_ineq(m.var(), -sign, n.var(), llc::EQ, current_lemma());
explain(m, current_expl());
explain(n, current_expl());
TRACE("nla_solver", print_lemma_and_expl(tout););
TRACE("nla_solver", print_lemma(tout););
}
// the value of the i-th monomial has to be equal to the value of the k-th monomial modulo sign
@ -602,7 +601,7 @@ struct solver::imp {
// abs_vars_key is formed by m_vars_equivalence.get_abs_root_for_var(k), where
// k runs over m.
void generate_sign_lemma_model_based(const monomial& m, const monomial& n, const rational& sign) {
add_empty_lemma_and_explanation();
add_empty_lemma();
if (sign.is_zero()) {
// either m or n has to be equal zero, but it is not the case
SASSERT(!vvr(m).is_zero() || !vvr(n).is_zero());
@ -610,7 +609,7 @@ struct solver::imp {
generate_zero_lemma(m);
if (!vvr(n).is_zero())
generate_zero_lemma(n);
TRACE("nla_solver", print_lemma_and_expl(tout););
TRACE("nla_solver", print_lemma(tout););
return;
}
unsigned_vector mvars(m.vars());
@ -647,11 +646,12 @@ struct solver::imp {
}
mk_ineq(m.var(), -sign, n.var(), llc::EQ, current_lemma());
TRACE("nla_solver", print_lemma(current_lemma(), tout););
TRACE("nla_solver", print_lemma(tout););
}
lemma& current_lemma() {return m_lemma_vec->back();}
lp::explanation& current_expl() {return m_expl_vec->back();}
lemma& current_lemma() { return m_lemma_vec->back(); }
vector<ineq>& current_ineqs() { return current_lemma().ineqs(); }
lp::explanation& current_expl() { return current_lemma().expl(); }
static int rat_sign(const rational& r) {
return r.is_pos()? 1 : ( r.is_neg()? -1 : 0);
@ -881,18 +881,17 @@ struct solver::imp {
return out;
}
std::ostream & print_lemma(const lemma& l, std::ostream & out) const {
out << "lemma: ";
for (unsigned i = 0; i < l.size(); i++) {
print_ineq(l[i], out);
if (i + 1 < l.size()) out << " or ";
}
out << std::endl;
std::ostream & print_ineqs(const lemma& l, std::ostream & out) const {
std::unordered_set<lpvar> vars;
for (auto & in: l) {
out << "lemma: ";
for (unsigned i = 0; i < l.ineqs().size(); i++) {
auto & in = l.ineqs()[i];
print_ineq(in, out);
if (i + 1 < l.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);
}
@ -950,7 +949,7 @@ struct solver::imp {
}
}
add_empty_lemma_and_explanation();
add_empty_lemma();
if (derived)
mk_ineq(var(rm), llc::NE, current_lemma());
for (auto j : f) {
@ -958,7 +957,7 @@ struct solver::imp {
}
explain(rm, current_expl());
TRACE("nla_solver", print_lemma(current_lemma(), tout););
TRACE("nla_solver", print_lemma(tout););
return true;
}
@ -967,7 +966,7 @@ struct solver::imp {
// xy = 0 -> x = 0 or y = 0
bool basic_lemma_for_mon_zero_derived(const rooted_mon& rm, const factorization& f) {
TRACE("nla_solver", trace_print_monomial_and_factorization(rm, f, tout););
add_empty_lemma_and_explanation();
add_empty_lemma();
explain_fixed_var(var(rm));
std::unordered_set<lpvar> processed;
for (auto j : f) {
@ -975,7 +974,7 @@ struct solver::imp {
mk_ineq(var(j), llc::EQ, current_lemma());
}
explain(rm, current_expl());
TRACE("nla_solver", print_lemma(current_lemma(), tout););
TRACE("nla_solver", print_lemma(tout););
return true;
}
@ -983,13 +982,13 @@ struct solver::imp {
bool basic_lemma_for_mon_zero_model_based(const rooted_mon& rm, const factorization& f) {
TRACE("nla_solver", trace_print_monomial_and_factorization(rm, f, tout););
SASSERT(vvr(rm).is_zero());
add_empty_lemma_and_explanation();
add_empty_lemma();
mk_ineq(var(rm), llc::NE, current_lemma());
for (auto j : f) {
mk_ineq(var(j), llc::EQ, current_lemma());
}
explain(rm, current_expl());
TRACE("nla_solver", print_lemma(current_lemma(), tout););
TRACE("nla_solver", print_lemma(tout););
return true;
}
@ -1031,12 +1030,12 @@ struct solver::imp {
if (zero_j == -1) {
return false;
}
add_empty_lemma_and_explanation();
add_empty_lemma();
mk_ineq(zero_j, llc::NE, current_lemma());
mk_ineq(var(rm), llc::EQ, current_lemma());
explain(rm, current_expl());
TRACE("nla_solver", print_lemma_and_expl(tout););
TRACE("nla_solver", print_lemma(tout););
return true;
}
@ -1062,11 +1061,11 @@ struct solver::imp {
if (zero_j == -1) {
return false;
}
add_empty_lemma_and_explanation();
add_empty_lemma();
explain_fixed_var(zero_j);
explain_var_separated_from_zero(var(rm));
explain(rm, current_expl());
TRACE("nla_solver", print_lemma_and_expl(tout););
TRACE("nla_solver", print_lemma(tout););
return true;
}
@ -1108,7 +1107,7 @@ struct solver::imp {
return false;
}
add_empty_lemma_and_explanation();
add_empty_lemma();
// mon_var = 0
mk_ineq(mon_var, llc::EQ, current_lemma());
@ -1124,7 +1123,7 @@ struct solver::imp {
// not_one_j = -1
mk_ineq(not_one_j, llc::EQ, -rational(1), current_lemma());
explain(rm, current_expl());
TRACE("nla_solver", print_lemma(current_lemma(), tout); );
TRACE("nla_solver", print_lemma(tout); );
return true;
}
@ -1186,7 +1185,7 @@ struct solver::imp {
return false;
}
add_empty_lemma_and_explanation();
add_empty_lemma();
// mon_var = 0
if (mon_var_is_sep_from_zero)
explain_var_separated_from_zero(mon_var);
@ -1201,7 +1200,7 @@ struct solver::imp {
// not_one_j = -1
mk_ineq(not_one_j, llc::EQ, -rational(1), current_lemma());
explain(rm, current_expl());
TRACE("nla_solver", print_lemma_and_expl(tout); );
TRACE("nla_solver", print_lemma(tout); );
return true;
}
@ -1241,7 +1240,7 @@ struct solver::imp {
}
}
add_empty_lemma_and_explanation();
add_empty_lemma();
explain(rm, current_expl());
for (auto j : f){
@ -1257,7 +1256,7 @@ struct solver::imp {
}
TRACE("nla_solver",
tout << "rm = "; print_rooted_monomial_with_vars(rm, tout);
print_lemma_and_expl(tout););
print_lemma(tout););
return true;
}
// use the fact
@ -1289,7 +1288,7 @@ struct solver::imp {
return false;
}
add_empty_lemma_and_explanation();
add_empty_lemma();
explain(rm, current_expl());
for (auto j : f){
@ -1305,7 +1304,7 @@ struct solver::imp {
}
TRACE("nla_solver",
tout << "rm = "; print_rooted_monomial_with_vars(rm, tout);
print_lemma(current_lemma(), tout););
print_lemma(tout););
return true;
}
@ -1343,7 +1342,7 @@ struct solver::imp {
print_rooted_monomial_with_vars(rm, tout);
tout << "fc = "; print_factorization(fc, tout);
tout << "orig mon = "; print_monomial(m_monomials[rm.orig_index()], tout););
add_empty_lemma_and_explanation();
add_empty_lemma();
int fi = 0;
for (factor f : fc) {
if (fi++ != factor_index) {
@ -1364,7 +1363,7 @@ struct solver::imp {
}
explain(fc, current_expl());
explain(rm, current_expl());
TRACE("nla_solver", print_lemma(current_lemma(), tout); print_explanation(current_expl(), tout););
TRACE("nla_solver", print_lemma(tout); );
}
template <typename T>
@ -1661,7 +1660,6 @@ struct solver::imp {
m_vars_equivalence.clear();
m_rm_table.clear();
m_monomials_containing_var.clear();
m_expl_vec->clear();
m_lemma_vec->clear();
}
@ -1743,7 +1741,7 @@ struct solver::imp {
llc ab_cmp,
bool derived
) {
add_empty_lemma_and_explanation();
add_empty_lemma();
mk_ineq(rational(c_sign) * flip_sign(c), var(c), llc::LE, current_lemma());
negate_factor_equality(c, d);
negate_factor_relation(rational(c_sign), a, rational(d_sign), b);
@ -1756,11 +1754,11 @@ struct solver::imp {
explain(c, current_expl());
explain(d, current_expl()); // todo: double check that these explanations are enough, too much!?
}
TRACE("nla_solver", print_lemma_and_expl(tout););
TRACE("nla_solver", print_lemma(tout););
}
void print_lemma_and_expl(std::ostream& out) {
print_lemma(current_lemma(), out);
void print_lemma(std::ostream& out) {
print_ineqs(current_lemma(), out);
print_explanation(current_expl(), out);
}
@ -2124,7 +2122,7 @@ struct solver::imp {
void generate_monl_strict(const rooted_mon& a,
const rooted_mon& b,
unsigned strict) {
add_empty_lemma_and_explanation();
add_empty_lemma();
auto akey = get_sorted_key_with_vars(a);
auto bkey = get_sorted_key_with_vars(b);
SASSERT(akey.size() == bkey.size());
@ -2139,13 +2137,13 @@ struct solver::imp {
assert_abs_val_a_le_abs_var_b(a, b, true);
explain(a, current_expl());
explain(b, current_expl());
TRACE("nla_solver", print_lemma_and_expl(tout););
TRACE("nla_solver", print_lemma(tout););
}
// not a strict version
void generate_monl(const rooted_mon& a,
const rooted_mon& b) {
add_empty_lemma_and_explanation();
add_empty_lemma();
auto akey = get_sorted_key_with_vars(a);
auto bkey = get_sorted_key_with_vars(b);
SASSERT(akey.size() == bkey.size());
@ -2155,7 +2153,7 @@ struct solver::imp {
assert_abs_val_a_le_abs_var_b(a, b, false);
explain(a, current_expl());
explain(b, current_expl());
TRACE("nla_solver", print_lemma_and_expl(tout););
TRACE("nla_solver", print_lemma(tout););
}
bool monotonicity_lemma_on_lex_sorted_rm_upper(const vector<std::pair<std::vector<rational>, unsigned>>& lex_sorted, unsigned i, const rooted_mon& rm) {
@ -2312,11 +2310,11 @@ struct solver::imp {
}
}
mk_ineq(m.var(), (sign.is_pos()? llc::GT : llc ::LT), current_lemma());
TRACE("nla_solver", print_lemma_and_expl(tout););
TRACE("nla_solver", print_lemma(tout););
}
bool generate_simple_tangent_lemma(const rooted_mon* rm) {
add_empty_lemma_and_explanation();
add_empty_lemma();
unsigned i_mon = rm->orig_index();
const monomial & m = m_monomials[i_mon];
const rational v = product_value(m);
@ -2348,7 +2346,7 @@ struct solver::imp {
mk_ineq(sign, m.var(), llc::LT, current_lemma());
mk_ineq(sign, m.var(), llc::GE, v, current_lemma());
}
TRACE("nla_solver", print_lemma_and_expl(tout););
TRACE("nla_solver", print_lemma(tout););
return true;
}
@ -2390,13 +2388,12 @@ struct solver::imp {
generate_explanations_of_tang_lemma(rm, bf);
}
void add_empty_lemma_and_explanation() {
void add_empty_lemma() {
m_lemma_vec->push_back(lemma());
m_expl_vec->push_back(lp::explanation());
}
void generate_tang_plane(const rational & a, const rational& b, lpvar jx, lpvar jy, bool below, lpvar j, const rational& j_sign) {
add_empty_lemma_and_explanation();
add_empty_lemma();
lemma& l = m_lemma_vec->back();
negate_relation(jx, a, l);
negate_relation(jy, b, l);
@ -2407,7 +2404,7 @@ struct solver::imp {
t.add_coeff_var(b, jx);
t.add_coeff_var( -j_sign, j);
l.push_back(ineq(below? llc::LT : llc::GT, t, a*b));
TRACE("nla_solver", print_lemma(l, tout););
TRACE("nla_solver", print_lemma(tout););
}
void negate_relation(unsigned j, const rational& a, lemma& l) {
@ -2418,18 +2415,18 @@ struct solver::imp {
else {
mk_ineq(j, llc::LE, a, l);
}
TRACE("nla_solver", print_ineq(l.back(), tout););
TRACE("nla_solver", print_ineq(l.ineqs().back(), tout););
}
void generate_two_tang_lines(const bfc & bf, const point& xy, const rational& sign, lpvar j) {
add_empty_lemma_and_explanation();
add_empty_lemma();
mk_ineq(bf.m_x, llc::NE, xy.x, current_lemma());
mk_ineq(sign, j, - xy.x, bf.m_y, llc::EQ, current_lemma());
TRACE("nla_solver", print_lemma_and_expl(tout););
add_empty_lemma_and_explanation();
TRACE("nla_solver", print_lemma(tout););
add_empty_lemma();
mk_ineq(bf.m_y, llc::NE, xy.y, current_lemma());
mk_ineq(sign, j, - xy.y, bf.m_x, llc::EQ, current_lemma());
TRACE("nla_solver", print_lemma_and_expl(tout););
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.
@ -2527,9 +2524,8 @@ struct solver::imp {
lbool check(vector<lp::explanation> & expl_vec, vector<lemma>& l_vec) {
lbool check(vector<lemma>& l_vec) {
TRACE("nla_solver", tout << "check of nla";);
m_expl_vec = &expl_vec;
m_lemma_vec = &l_vec;
if (!(m_lar_solver.get_status() == lp::lp_status::OPTIMAL || m_lar_solver.get_status() == lp::lp_status::FEASIBLE )) {
TRACE("nla_solver", tout << "unknown because of the m_lar_solver.m_status = " << lp_status_to_string(m_lar_solver.get_status()) << "\n";);
@ -2554,7 +2550,7 @@ struct solver::imp {
bool no_lemmas_hold() const {
for (auto & l : * m_lemma_vec) {
if ((!l.empty()) && lemma_holds(l))
if (an_ineq_holds(l))
return false;
}
return true;
@ -2581,11 +2577,10 @@ struct solver::imp {
}
lbool test_check(
vector<vector<ineq>>& lemma,
vector<lp::explanation>& exp )
vector<lemma>& l)
{
m_lar_solver.set_status(lp::lp_status::OPTIMAL);
return check(exp, lemma);
return check(l);
}
}; // end of imp
@ -2596,8 +2591,8 @@ unsigned solver::add_monomial(lpvar v, unsigned sz, lpvar const* vs) {
bool solver::need_check() { return true; }
lbool solver::check(vector<lp::explanation> & ex, vector<lemma>& l) {
return m_imp->check(ex, l);
lbool solver::check(vector<lemma>& l) {
return m_imp->check(l);
}
void solver::push(){
@ -2734,8 +2729,7 @@ void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_0() {
v.push_back(lp_a);v.push_back(lp_c);
nla.add_monomial(lp_ac, v.size(), v.begin());
vector<lemma> lemma;
vector<lp::explanation> exp;
vector<lemma> lv;
// set abcde = ac * bde
// ac = 1 then abcde = bde, but we have abcde < bde
@ -2749,9 +2743,9 @@ void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_0() {
s.set_column_value(lp_bde, rational(16));
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
SASSERT(nla.m_imp->test_check(lv) == l_false);
nla.m_imp->print_lemma(lemma.back(), std::cout << "expl & lemma: ");
nla.m_imp->print_lemma(std::cout);
ineq i0(llc::NE, lp::lar_term(), rational(1));
i0.m_term.add_var(lp_ac);
@ -2764,7 +2758,7 @@ void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_0() {
bool found0 = false;
bool found1 = false;
bool found2 = false;
for (const auto& k : lemma[0]){
for (const auto& k : lv[0].ineqs()){
if (k == i0) {
found0 = true;
} else if (k == i1) {
@ -2799,7 +2793,6 @@ void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_1() {
nla.add_monomial(lp_bde, v.size(), v.begin());
vector<lemma> lemma;
vector<lp::explanation> exp;
s.set_column_value(lp_a, rational(1));
s.set_column_value(lp_b, rational(1));
@ -2808,9 +2801,9 @@ void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_1() {
s.set_column_value(lp_e, rational(1));
s.set_column_value(lp_bde, rational(3));
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
SASSERT(nla.m_imp->test_check(lemma) == l_false);
SASSERT(lemma[0].size() == 4);
nla.m_imp->print_lemma(lemma.back(), std::cout << "expl & lemma: ");
nla.m_imp->print_lemma(std::cout);
ineq i0(llc::NE, lp::lar_term(), rational(1));
i0.m_term.add_var(lp_b);
@ -2824,7 +2817,7 @@ void solver::test_basic_lemma_for_mon_neutral_from_factors_to_monomial_1() {
bool found1 = false;
bool found2 = false;
bool found3 = false;
for (const auto& k : lemma[0]){
for (const auto& k : lemma[0].ineqs()){
if (k == i0) {
found0 = true;
} else if (k == i1) {
@ -2874,8 +2867,6 @@ void solver::test_basic_lemma_for_mon_zero_from_factors_to_monomial() {
lp_acd,
lp_be);
vector<lemma> lemma;
vector<lp::explanation> exp;
// set vars
s.set_column_value(lp_a, rational(1));
@ -2889,8 +2880,8 @@ void solver::test_basic_lemma_for_mon_zero_from_factors_to_monomial() {
s.set_column_value(lp_acd, rational(1));
s.set_column_value(lp_be, rational(1));
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
nla.m_imp->print_lemma_and_expl(std::cout);
SASSERT(nla.m_imp->test_check(lemma) == l_false);
nla.m_imp->print_lemma(std::cout);
SASSERT(lemma.size() == 1 && lemma[0].size() == 2);
ineq i0(llc::NE, lp::lar_term(), rational(0));
i0.m_term.add_var(lp_b);
@ -2899,7 +2890,7 @@ void solver::test_basic_lemma_for_mon_zero_from_factors_to_monomial() {
bool found0 = false;
bool found1 = false;
for (const auto& k : lemma[0]){
for (const auto& k : lemma[0].ineqs()){
if (k == i0) {
found0 = true;
} else if (k == i1) {
@ -2933,18 +2924,14 @@ void solver::test_basic_lemma_for_mon_zero_from_monomial_to_factors() {
nla.add_monomial(lp_acd, vec.size(), vec.begin());
vector<lemma> lemma;
vector<lp::explanation> exp;
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));
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
SASSERT(nla.m_imp->test_check(lemma) == l_false);
nla.m_imp->print_lemma_and_expl(std::cout);
nla.m_imp->print_lemma(std::cout);
ineq i0(llc::EQ, lp::lar_term(), rational(0));
i0.m_term.add_var(lp_a);
@ -2956,7 +2943,7 @@ void solver::test_basic_lemma_for_mon_zero_from_monomial_to_factors() {
bool found1 = false;
bool found2 = false;
for (const auto& k : lemma[0]){
for (const auto& k : lemma[0].ineqs()){
if (k == i0) {
found0 = true;
} else if (k == i1) {
@ -3003,7 +2990,6 @@ void solver::test_basic_lemma_for_mon_neutral_from_monomial_to_factors() {
lp_acd,
lp_be);
vector<lemma> lemma;
vector<lp::explanation> exp;
// set all vars to 1
s.set_column_value(lp_a, rational(1));
@ -3022,10 +3008,10 @@ void solver::test_basic_lemma_for_mon_neutral_from_monomial_to_factors() {
s.set_column_value(lp_b, - rational(2));
// we have bde = -b, therefore d = +-1 and e = +-1
s.set_column_value(lp_d, rational(3));
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
SASSERT(nla.m_imp->test_check(lemma) == l_false);
nla.m_imp->print_lemma_and_expl(std::cout);
nla.m_imp->print_lemma(std::cout);
ineq i0(llc::EQ, lp::lar_term(), rational(1));
i0.m_term.add_var(lp_d);
ineq i1(llc::EQ, lp::lar_term(), -rational(1));
@ -3033,7 +3019,7 @@ void solver::test_basic_lemma_for_mon_neutral_from_monomial_to_factors() {
bool found0 = false;
bool found1 = false;
for (const auto& k : lemma[0]){
for (const auto& k : lemma[0].ineqs()){
if (k == i0) {
found0 = true;
} else if (k == i1) {
@ -3093,22 +3079,20 @@ void solver::test_basic_sign_lemma() {
s.set_column_value(lp_acd, lp::impq(rational(3)));
vector<lemma> lemma;
vector<lp::explanation> exp;
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
SASSERT(nla.m_imp->test_check(lemma) == l_false);
lp::lar_term t;
t.add_var(lp_bde);
t.add_var(lp_acd);
ineq q(llc::EQ, t, rational(0));
nla.m_imp->print_lemma_and_expl(std::cout);
SASSERT(q == lemma[0].back());
nla.m_imp->print_lemma(std::cout);
SASSERT(q == lemma[0].ineqs().back());
ineq i0(llc::EQ, lp::lar_term(), rational(0));
i0.m_term.add_var(lp_bde);
i0.m_term.add_var(lp_acd);
bool found = false;
for (const auto& k : lemma[0]){
for (const auto& k : lemma[0].ineqs()){
if (k == i0) {
found = true;
}
@ -3230,16 +3214,15 @@ void solver::test_order_lemma_params(bool var_equiv, int sign) {
+ rational(1));
}
vector<lemma> lemma;
vector<lp::explanation> exp;
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
SASSERT(!var_equiv || !exp.empty());
SASSERT(nla.m_imp->test_check(lemma) == l_false);
SASSERT(!var_equiv || !nla.m_imp->current_expl().empty());
// lp::lar_term t;
// t.add_coeff_var(lp_bde);
// t.add_coeff_var(lp_acd);
// ineq q(llc::EQ, t, rational(0));
nla.m_imp->print_lemma(lemma.back(), std::cout << "lemma: ");
nla.m_imp->print_lemma(std::cout);
// SASSERT(q == lemma.back());
// ineq i0(llc::EQ, lp::lar_term(), rational(0));
// i0.m_term.add_coeff_var(lp_bde);
@ -3315,9 +3298,8 @@ void solver::test_monotone_lemma() {
s.set_column_value(lp_ef, s.get_column_value(lp_ij));
vector<lemma> lemma;
vector<lp::explanation> exp;
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
nla.m_imp->print_lemma(lemma.back(), std::cout << "lemma: ");
SASSERT(nla.m_imp->test_check(lemma) == l_false);
nla.m_imp->print_lemma(std::cout);
}
void solver::test_tangent_lemma_reg() {
@ -3351,10 +3333,8 @@ void solver::test_tangent_lemma_reg() {
s.set_column_value(lp_ab, nla.m_imp->mon_value_by_vars(mon_ab) + rational(10)); // greater by ten than the correct value
vector<lemma> lemma;
vector<lp::explanation> exp;
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
nla.m_imp->print_lemma(lemma.back(), std::cout << "lemma: ");
SASSERT(nla.m_imp->test_check(lemma) == l_false);
nla.m_imp->print_lemma(std::cout);
}
void solver::test_tangent_lemma_equiv() {
@ -3397,10 +3377,9 @@ void solver::test_tangent_lemma_equiv() {
s.set_column_value(lp_ab, nla.m_imp->mon_value_by_vars(mon_ab) + rational(10)); // greater by ten than the correct value
vector<lemma> lemma;
vector<lp::explanation> exp;
SASSERT(nla.m_imp->test_check(lemma, exp) == l_false);
nla.m_imp->print_lemma(lemma.back(), std::cout << "lemma: ");
SASSERT(nla.m_imp->test_check(lemma) == l_false);
nla.m_imp->print_lemma(std::cout);
}

View file

@ -47,7 +47,18 @@ struct ineq {
};
typedef vector<ineq> lemma;
class lemma {
vector<ineq> m_ineqs;
lp::explanation m_expl;
public:
void push_back(const ineq& i) { m_ineqs.push_back(i);}
size_t size() const { return m_ineqs.size() + m_expl.size(); }
const vector<ineq>& ineqs() const { return m_ineqs; }
vector<ineq>& ineqs() { return m_ineqs; }
lp::explanation& expl() { return m_expl; }
const lp::explanation& expl() const { return m_expl; }
};
typedef vector<monomial> polynomial;
// nonlinear integer incremental linear solver
class solver {
@ -62,7 +73,7 @@ public:
void push();
void pop(unsigned scopes);
bool need_check();
lbool check(vector<lp::explanation>&, vector<lemma>&);
lbool check(vector<lemma>&);
static void test_factorization();
static void test_basic_sign_lemma();
static void test_basic_lemma_for_mon_zero_from_monomial_to_factors();