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

work on tighten_with_S

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2024-09-04 09:20:21 -07:00 committed by Lev Nachmanson
parent f0b5cd1066
commit 1408fe60ab
2 changed files with 158 additions and 48 deletions

View file

@ -137,6 +137,7 @@ namespace lp {
std::list<unsigned> m_f; // F = {λ(t):t in m_f} std::list<unsigned> m_f; // F = {λ(t):t in m_f}
// set S // set S
std::list<unsigned> m_s; // S = {λ(t): t in m_s} std::list<unsigned> m_s; // S = {λ(t): t in m_s}
u_map<unsigned> m_k2s; // k is substituted by using equation in m_eprime[m_k2s[k]]
unsigned m_conflict_index = -1; // m_eprime[m_conflict_index] gives the conflict unsigned m_conflict_index = -1; // m_eprime[m_conflict_index] gives the conflict
@ -179,9 +180,9 @@ namespace lp {
continue; continue;
} }
eprime_pair pair = {t, lar_term(i)}; eprime_pair pair = {t, lar_term(i)};
m_f.push_back(m_f.size()); m_f.push_back(static_cast<unsigned>(m_f.size()));
m_eprime.push_back(pair); m_eprime.push_back(pair);
TRACE("dioph_eq", print_eprime_entry(m_f.size() - 1, tout);); TRACE("dioph_eq", print_eprime_entry(static_cast<unsigned>(m_f.size()) - 1, tout););
} }
} }
@ -189,11 +190,11 @@ namespace lp {
mpq gcd_of_coeffs(const term_o& t) { mpq gcd_of_coeffs(const term_o& t) {
mpq g(0); mpq g(0);
for (const auto & p : t) { for (const auto & p : t) {
if (g.is_zero()) { if (g.is_zero())
g = abs(p.coeff()); g = abs(p.coeff());
} else { else
g = gcd(g, p.coeff()); g = gcd(g, p.coeff());
} if (g.is_one()) break;
} }
return g; return g;
} }
@ -250,6 +251,91 @@ namespace lp {
} }
return true; return true;
} }
void init_term_from_constraint(term_o& t, const lar_base_constraint& c) {
for (const auto& p: c.coeffs()) {
t.add_monomial(p.first, p.second);
}
t.c() = - c.rhs();
}
void subs_k(const eprime_pair& e, unsigned k, term_o& t, std::queue<unsigned> & q) {
const mpq& k_coeff = e.m_e.get_coeff(k);
bool is_one = k_coeff.is_one();
SASSERT(is_one || k_coeff.is_minus_one());
t.erase_var(k);
if (is_one) {
for (const auto& p: e.m_e) {
if (p.j() == k) continue;
t.add_monomial(-p.coeff(), p.j());
if (m_k2s.contains(p.j()))
q.push(p.j());
}
t.c() -= e.m_e.c();
} else { // k_coeff is -1
for (const auto& p: e.m_e) {
if (p.j() == k) continue;
t.add_monomial(p.coeff(), p.j());
if (m_k2s.contains(p.j()))
q.push(p.j());
}
t.c() += e.m_e.c();
}
}
void process_q_with_S(std::queue<unsigned> &q, term_o& t, const lar_base_constraint& c) {
while (!q.empty()) {
unsigned k = q.front();
TRACE("dioph_eq", tout << "k:" << k << std::endl;);
q.pop();
const eprime_pair& e = m_eprime[m_k2s[k]];
TRACE("dioph_eq", tout << "k:" << k << " in: "; print_eprime_entry(m_k2s[k], tout) << std::endl;);
subs_k(e, k, t, q);
}
TRACE("dioph_eq", tout << "substituted t:"; print_term_o(t, tout) << std::endl;);
}
void tighten_with_S(const lar_base_constraint& c) {
TRACE("dioph_eq", tout << "constraint:"; lra.constraints().display(tout, c) << std::endl;);
SASSERT(c.is_active());
term_o t;
std::queue<unsigned> q;
for (const auto& p: c.coeffs()) {
if (m_k2s.contains(p.second))
q.push(p.second);
}
if (q.empty()) return;
init_term_from_constraint(t, c);
TRACE("dioph_eq", tout << "t:"; print_term_o(t, tout) << std::endl;);
process_q_with_S(q, t, c);
TRACE("dioph_eq", tout << "tighten:"; print_term_o(t, tout) << std::endl;);
mpq g = gcd_of_coeffs(t);
if (g.is_one()) return;
mpq new_c = t.c() / g;
if (new_c.is_int()) return;
std::cout << "."; return;
if (c.kind() == lconstraint_kind::EQ) {
TRACE("dioph_eq", tout << "conflict:" <<std::endl;);
NOT_IMPLEMENTED_YET();
} else if (c.kind() == lconstraint_kind::GE) {
for (auto& p: t.coeffs()) {
p.m_value /= g;
}
t.c() = ceil(new_c);
} else {
for (auto& p: t.coeffs()) {
p.m_value /= g;
}
t.c() = floor(new_c);
}
TRACE("dioph_eq", tout << "tighten/g:"; print_term_o(t, tout) << std::endl;);
NOT_IMPLEMENTED_YET();
}
lia_move tighten_with_S() {
for (const auto& c: lra.constraints().active()) {
tighten_with_S(c);
}
return lia_move::undef;
}
lia_move check() { lia_move check() {
init(); init();
@ -259,8 +345,8 @@ namespace lp {
rewrite_eqs(); rewrite_eqs();
} }
TRACE("dioph_eq", print_S(tout);); TRACE("dioph_eq", print_S(tout););
//NOT_IMPLEMENTED_YET();
return lia_move::sat; return lia_move::sat;
return tighten_with_S();
} }
std::list<unsigned>::iterator pick_eh() { std::list<unsigned>::iterator pick_eh() {
return m_f.begin(); // TODO: make a smarter joice return m_f.begin(); // TODO: make a smarter joice
@ -283,7 +369,10 @@ namespace lp {
TRACE("dioph_eq", print_eprime_entry(e_index, tout << "before:") << std::endl; TRACE("dioph_eq", print_eprime_entry(e_index, tout << "before:") << std::endl;
tout << "k_coeff:" << k_coeff << std::endl;); tout << "k_coeff:" << k_coeff << std::endl;);
if (!l_term.is_empty()) { if (!l_term.is_empty()) {
add_operator(m_eprime[e_index].m_l, -k_sign*k_coeff, l_term); if (k_sign == 1)
add_operator(m_eprime[e_index].m_l, -k_coeff, l_term);
else
add_operator(m_eprime[e_index].m_l, k_coeff, l_term);
} }
e.substitute(k_subst, k); e.substitute(k_subst, k);
TRACE("dioph_eq", print_eprime_entry(e_index, tout << "after :") << std::endl;); TRACE("dioph_eq", print_eprime_entry(e_index, tout << "after :") << std::endl;);
@ -381,6 +470,14 @@ namespace lp {
print_lar_term_L(m_eprime[i].m_l, out<< "\tm_l:") << "\n}"<< std::endl; print_lar_term_L(m_eprime[i].m_l, out<< "\tm_l:") << "\n}"<< std::endl;
return out; return out;
} }
// k is the index of the index of the variable with the coefficient +-1 that is being substituted
void move_from_f_to_s(unsigned k, std::list<unsigned>::iterator it) {
m_s.push_back(*it);
m_k2s.insert(k, *it);
m_f.erase(it);
}
// this is the step 6 or 7 of the algorithm // this is the step 6 or 7 of the algorithm
void rewrite_eqs() { void rewrite_eqs() {
auto eh_it = pick_eh(); auto eh_it = pick_eh();
@ -392,8 +489,7 @@ namespace lp {
if (ahk.is_one()) { if (ahk.is_one()) {
eprime_entry.m_e.j() = k; eprime_entry.m_e.j() = k;
TRACE("dioph_eq", tout << "push to S:\n"; print_eprime_entry(*eh_it, tout);); TRACE("dioph_eq", tout << "push to S:\n"; print_eprime_entry(*eh_it, tout););
m_s.push_back(*eh_it); move_from_f_to_s(k, eh_it);
m_f.erase(eh_it);
eliminate_var_in_f(eprime_entry, k , k_sign); eliminate_var_in_f(eprime_entry, k , k_sign);
} else { } else {
fresh_var_step(*eh_it, k); fresh_var_step(*eh_it, k);

View file

@ -59,7 +59,6 @@ public:
} }
} }
void add_var(lpvar j) { void add_var(lpvar j) {
rational c(1); rational c(1);
add_monomial(c, j); add_monomial(c, j);
@ -75,6 +74,11 @@ public:
return m_coeffs; return m_coeffs;
} }
u_map<mpq> &coeffs() {
return m_coeffs;
}
void subst_by_term(const lar_term& t, unsigned term_column) { void subst_by_term(const lar_term& t, unsigned term_column) {
auto it = this->m_coeffs.find_core(term_column); auto it = this->m_coeffs.find_core(term_column);
if (it == nullptr) return; if (it == nullptr) return;
@ -138,6 +142,16 @@ public:
SASSERT(it != nullptr); SASSERT(it != nullptr);
return it->get_data().m_value; return it->get_data().m_value;
} }
mpq & get_coeff(unsigned j){
auto* it = m_coeffs.find_core(j);
SASSERT(it != nullptr);
return it->get_data().m_value;
}
void erase_var(unsigned j) {
m_coeffs.erase(j);
}
// the monomial ax[j] is substituted by ax[k] // the monomial ax[j] is substituted by ax[k]
void subst_index(unsigned j, unsigned k) { void subst_index(unsigned j, unsigned k) {
auto* it = m_coeffs.find_core(j); auto* it = m_coeffs.find_core(j);