mirror of
https://github.com/Z3Prover/z3
synced 2025-04-22 16:45:31 +00:00
work on niil base case
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
406a021310
commit
b4aaaffc99
2 changed files with 90 additions and 16 deletions
|
@ -260,6 +260,30 @@ public:
|
|||
unsigned adjust_column_index_to_term_index(unsigned j) const;
|
||||
|
||||
var_index local2external(var_index idx) const { return m_var_register.local_to_external(idx); }
|
||||
|
||||
var_index external2local(unsigned j) const {
|
||||
var_index local_j;
|
||||
lp_assert(m_var_register.external_is_used(j, local_j));
|
||||
m_var_register.external_is_used(j, local_j);
|
||||
return local_j;
|
||||
}
|
||||
|
||||
bool column_has_upper_bound(unsigned j) const {
|
||||
return m_mpq_lar_core_solver.m_r_solver.column_has_upper_bound(j);
|
||||
}
|
||||
|
||||
bool column_has_lower_bound(unsigned j) const {
|
||||
return m_mpq_lar_core_solver.m_r_solver.column_has_lower_bound(j);
|
||||
}
|
||||
|
||||
const impq& get_upper_bound(unsigned j) const {
|
||||
return m_mpq_lar_core_solver.m_r_solver.m_upper_bounds[j];
|
||||
}
|
||||
|
||||
const impq& get_lower_bound(unsigned j) const {
|
||||
return m_mpq_lar_core_solver.m_r_solver.m_lower_bounds[j];
|
||||
}
|
||||
|
||||
|
||||
void propagate_bounds_on_a_term(const lar_term& t, bound_propagator & bp, unsigned term_offset);
|
||||
|
||||
|
|
|
@ -27,11 +27,24 @@ typedef nra::mon_eq mon_eq;
|
|||
typedef lp::var_index lpvar;
|
||||
struct solver::imp {
|
||||
struct vars_equivalence {
|
||||
typedef std::pair<lpvar, lpvar> lppair;
|
||||
std::unordered_map<lppair,
|
||||
int,
|
||||
std::hash<lppair>
|
||||
> m_map;
|
||||
struct signed_var {
|
||||
lpvar m_var;
|
||||
int m_sign;
|
||||
signed_var(lpvar j, int sign) : m_var(j), m_sign(sign) {}
|
||||
};
|
||||
struct equiv {
|
||||
lpvar m_i;
|
||||
signed_var m_signed_var;
|
||||
equiv(lpvar i, lpvar j, int sign) :m_i(i), m_signed_var(j, sign) {
|
||||
SASSERT(i > j);
|
||||
}
|
||||
};
|
||||
|
||||
// the resulting mapping
|
||||
std::unordered_map<lpvar, signed_var> m_map;
|
||||
// all equivalences extracted from constraints
|
||||
vector<equiv> m_equivs;
|
||||
unsigned size() const { return m_map.size(); }
|
||||
void add_equivalence_maybe(const lp::lar_term *t) {
|
||||
if (t->size() != 2)
|
||||
return;
|
||||
|
@ -53,20 +66,55 @@ struct solver::imp {
|
|||
j = p.var();
|
||||
}
|
||||
SASSERT(i != j && i != static_cast<lpvar>(-1));
|
||||
if (i < j) { // swap if i > j ordered
|
||||
if (i < j) { // swap
|
||||
lpvar tmp = i;
|
||||
i = j;
|
||||
j = tmp;
|
||||
}
|
||||
if (seen_minus && seen_plus)
|
||||
m_map[lppair(i, j)] = -1; // we have x_i == - x_j
|
||||
else
|
||||
m_map[lppair(i, j)] = 1; // we have an equality
|
||||
|
||||
int sign = (seen_minus && seen_plus)? 1 : -1;
|
||||
m_equivs.push_back(equiv(i, j, sign));
|
||||
}
|
||||
void collect_equivs(const lp::lar_solver& s) {
|
||||
for (unsigned i = 0; i < s.terms().size(); i++) {
|
||||
unsigned ti = i + s.terms_start_index();
|
||||
if (!s.term_is_used_as_row(ti))
|
||||
continue;
|
||||
lpvar j = s.external2local(ti);
|
||||
if (!s.column_has_upper_bound(j) ||
|
||||
!s.column_has_lower_bound(j))
|
||||
continue;
|
||||
if (s.get_upper_bound(j) != lp::zero_of_type<lp::impq>() ||
|
||||
s.get_lower_bound(j) != lp::zero_of_type<lp::impq>())
|
||||
continue;
|
||||
add_equivalence_maybe(s.terms()[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void create_map() {
|
||||
bool progress = true;
|
||||
while (progress) {
|
||||
progress = false;
|
||||
for (const auto & e : m_equivs) {
|
||||
unsigned i = e.m_i;
|
||||
auto it = m_map.find(i);
|
||||
if (it == m_map.end()) {
|
||||
m_map.insert(std::pair<lpvar, signed_var>(i, e.m_signed_var));
|
||||
progress = true;
|
||||
} else {
|
||||
if (it->second.m_var > e.m_signed_var.m_var) {
|
||||
it->second = signed_var(
|
||||
e.m_signed_var.m_var,
|
||||
e.m_signed_var.m_sign * it->second.m_sign);
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vars_equivalence(const lp::lar_solver& s) {
|
||||
for (const lp::lar_term *t : s.terms())
|
||||
add_equivalence_maybe(t);
|
||||
collect_equivs(s);
|
||||
create_map();
|
||||
}
|
||||
lpvar get_equivalent_var(lpvar j, bool & sign) {
|
||||
SASSERT(false);
|
||||
|
@ -113,10 +161,10 @@ struct solver::imp {
|
|||
|
||||
bool generate_basic_lemma_for_mon_sign_var_other_mon( unsigned j_var,
|
||||
const svector<unsigned> & mon_vars,
|
||||
const mon_eq& om, bool sign, lemma& l) {
|
||||
if (mon_vars.size() != om.size())
|
||||
const mon_eq& other_m, bool sign, lemma& l) {
|
||||
if (mon_vars.size() != other_m.size())
|
||||
return false;
|
||||
SASSERT(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -141,6 +189,8 @@ struct solver::imp {
|
|||
if (m_vars_equivalence.empty()) {
|
||||
std::cout << "empty m_vars_equivalence\n";
|
||||
return false;
|
||||
} else {
|
||||
std::cout << "m_vars_equivalence size = " << m_vars_equivalence.size() << std::endl;
|
||||
}
|
||||
const mon_eq& m_of_i = m_monomials[i_mon];
|
||||
int sign = 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue