mirror of
https://github.com/Z3Prover/z3
synced 2025-06-20 21:03:39 +00:00
work on order lemma
Signed-off-by: Lev <levnach@hotmail.com>
This commit is contained in:
parent
f926ec7f4a
commit
d63c051d20
2 changed files with 32 additions and 19 deletions
|
@ -756,6 +756,9 @@ struct solver::imp {
|
||||||
m_vars_equivalence.clear();
|
m_vars_equivalence.clear();
|
||||||
collect_equivs();
|
collect_equivs();
|
||||||
m_vars_equivalence.create_tree();
|
m_vars_equivalence.create_tree();
|
||||||
|
for (lpvar j = 0; j < m_lar_solver.number_of_vars(); j++) {
|
||||||
|
m_vars_equivalence.register_var(j, vvr(j));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_key_mono_in_rooted_monomials(monomial_coeff const& mc, unsigned i) {
|
void register_key_mono_in_rooted_monomials(monomial_coeff const& mc, unsigned i) {
|
||||||
|
@ -873,7 +876,9 @@ struct solver::imp {
|
||||||
|
|
||||||
bool order_lemma_on_factor(unsigned i_mon, const factorization& f, unsigned k, int sign) {
|
bool order_lemma_on_factor(unsigned i_mon, const factorization& f, unsigned k, int sign) {
|
||||||
lpvar j = f[k];
|
lpvar j = f[k];
|
||||||
for (const index_with_sign& p : m_vars_equivalence.get_equivalent_vars(j)) {
|
TRACE("nla_solver", tout << "k = " << k << ", j = " << j; );
|
||||||
|
for (const index_with_sign& p : m_vars_equivalence.get_equivalent_vars(j, [this](unsigned h) {return vvr(h);})) {
|
||||||
|
TRACE("nla_solver", tout << "p.var() = " << p.var() << ", p.sign() = " << p.sign(); );
|
||||||
if (order_lemma_on_factor_and_equiv(p.m_i, i_mon, f, k, sign * p.m_sign)) {
|
if (order_lemma_on_factor_and_equiv(p.m_i, i_mon, f, k, sign * p.m_sign)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -888,7 +893,7 @@ struct solver::imp {
|
||||||
if (v.is_zero())
|
if (v.is_zero())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int sign = ((v.is_pos() && f.sign().is_pos()) || (v.is_neg() && f.sign().is_neg()))? 1 : -1;
|
int sign = (v.is_pos() == f.sign().is_pos())? 1 : -1;
|
||||||
|
|
||||||
if (order_lemma_on_factor(i_mon, f, k, sign)) {
|
if (order_lemma_on_factor(i_mon, f, k, sign)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -72,6 +72,7 @@ struct vars_equivalence {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//fields
|
||||||
|
|
||||||
// The map from the variables to m_equivs indices
|
// The map from the variables to m_equivs indices
|
||||||
// m_tree is a spanning tree of the graph of equivs represented by m_equivs
|
// m_tree is a spanning tree of the graph of equivs represented by m_equivs
|
||||||
|
@ -79,28 +80,24 @@ struct vars_equivalence {
|
||||||
// If m_tree[v] == -1 then the variable is a root.
|
// If m_tree[v] == -1 then the variable is a root.
|
||||||
// if m_tree[v] is not equal to -1 then m_equivs[m_tree[v]] = (k, v) or (v, k), that k is the parent of v
|
// if m_tree[v] is not equal to -1 then m_equivs[m_tree[v]] = (k, v) or (v, k), that k is the parent of v
|
||||||
vector<equiv> m_equivs; // all equivalences extracted from constraints
|
vector<equiv> m_equivs; // all equivalences extracted from constraints
|
||||||
|
std::unordered_map<rational,unsigned_vector> m_vars_by_abs_values;
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
m_equivs.clear();
|
m_equivs.clear();
|
||||||
m_tree.clear();
|
m_tree.clear();
|
||||||
}
|
}
|
||||||
// it also returns (j, 1)
|
// it also returns (j, 1)
|
||||||
vector<index_with_sign> get_equivalent_vars(lpvar j) const {
|
vector<index_with_sign> get_equivalent_vars(lpvar j, std::function<rational(lpvar)> vvr) const {
|
||||||
// it is just a place holder, see if we need something more substantial
|
|
||||||
vector<index_with_sign> ret;
|
vector<index_with_sign> ret;
|
||||||
|
|
||||||
|
rational val = vvr(j);
|
||||||
|
for (lpvar j : m_vars_by_abs_values.find(abs(val))->second) {
|
||||||
|
if (val.is_pos())
|
||||||
ret.push_back(index_with_sign(j, rational(1)));
|
ret.push_back(index_with_sign(j, rational(1)));
|
||||||
|
else
|
||||||
|
ret.push_back(index_with_sign(j, rational(-1)));
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
/*
|
|
||||||
vector<index_with_sign> ret;
|
|
||||||
std::unordered_set<unsigned> returned;
|
|
||||||
std::unordered_set<unsigned> processed;
|
|
||||||
ret.push_back(std::make_pair(j, 1));
|
|
||||||
returned.insert(j);
|
|
||||||
processed.insert(j);
|
|
||||||
std::queue<unsigned> q;
|
|
||||||
q.enqueue(j);
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned size() const { return static_cast<unsigned>(m_tree.size()); }
|
unsigned size() const { return static_cast<unsigned>(m_tree.size()); }
|
||||||
|
@ -194,5 +191,16 @@ struct vars_equivalence {
|
||||||
add_equiv_exp(j, exp);
|
add_equiv_exp(j, exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void register_var(unsigned j, const rational& val) {
|
||||||
|
rational v = abs(val);
|
||||||
|
auto it = m_vars_by_abs_values.find(v);
|
||||||
|
if (it == m_vars_by_abs_values.end()) {
|
||||||
|
unsigned_vector uv;
|
||||||
|
uv.push_back(j);
|
||||||
|
m_vars_by_abs_values[val] = uv;
|
||||||
|
} else {
|
||||||
|
it->second.push_back(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
}; // end of vars_equivalence
|
}; // end of vars_equivalence
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue