3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-19 19:02:02 +00:00

fix #1816 - m_parent_selects gets updated while accessing an interator, fix is to rely on the size of the vector for iteration

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-11-25 14:04:17 -08:00
parent aa723f1eee
commit 16be5b0e7d
3 changed files with 75 additions and 84 deletions

View file

@ -65,10 +65,14 @@ namespace smt {
bool result = false; bool result = false;
var_data * d = m_var_data[v]; var_data * d = m_var_data[v];
var_data_full * d_full = m_var_data_full[v]; var_data_full * d_full = m_var_data_full[v];
for (enode* pm : d_full->m_parent_maps) for (unsigned i = 0; i < d_full->m_parent_maps.size(); ++i) {
for (enode* ps : d->m_parent_selects) enode* pm = d_full->m_parent_maps[i];
for (unsigned j = 0; j < d->m_parent_selects.size(); ++j) {
enode* ps = d->m_parent_selects[j];
if (instantiate_select_map_axiom(ps, pm)) if (instantiate_select_map_axiom(ps, pm))
result = true; result = true;
}
}
return result; return result;
} }

View file

@ -495,6 +495,9 @@ void theory_seq::branch_unit_variable(dependency* dep, expr* X, expr_ref_vector
} }
bool theory_seq::branch_ternary_variable1() { bool theory_seq::branch_ternary_variable1() {
//std::function<bool(eq const& e)> branch = [&](eq const& e) { return branch_ternary_variable(e) || branch_ternary_variable2(e); };
//return m_eqs.exists(branch);
for (auto const& e : m_eqs) { for (auto const& e : m_eqs) {
if (branch_ternary_variable(e) || branch_ternary_variable2(e)) { if (branch_ternary_variable(e) || branch_ternary_variable2(e)) {
return true; return true;
@ -1085,59 +1088,40 @@ bool theory_seq::find_better_rep(expr_ref_vector const& ls, expr_ref_vector cons
expr* r_fst = find_fst_non_empty_var(rs); expr* r_fst = find_fst_non_empty_var(rs);
if (!r_fst) return false; if (!r_fst) return false;
expr_ref len_r_fst = mk_len(r_fst); expr_ref len_r_fst = mk_len(r_fst);
expr_ref len_l_fst(m);
enode * root2; enode * root2;
if (!ctx.e_internalized(len_r_fst)) if (!ctx.e_internalized(len_r_fst)) {
return false; return false;
else }
if (l_fst) {
len_l_fst = mk_len(l_fst);
}
root2 = get_root(len_r_fst); root2 = get_root(len_r_fst);
// Offset = 0, No change // Offset = 0, No change
if (l_fst) { if (l_fst && get_root(len_l_fst) == root2) {
expr_ref len_l_fst = mk_len(l_fst);
if (ctx.e_internalized(len_l_fst)) {
enode * root1 = get_root(len_l_fst);
if (root1 == root2) {
TRACE("seq", tout << "(" << mk_pp(l_fst, m) << ", " << mk_pp(r_fst,m) << ")\n";); TRACE("seq", tout << "(" << mk_pp(l_fst, m) << ", " << mk_pp(r_fst,m) << ")\n";);
return false; return false;
} }
}
}
// Offset = 0, Changed // Offset = 0, Changed
{
for (unsigned i = 0; i < idx; ++i) { for (unsigned i = 0; i < idx; ++i) {
eq const& e = m_eqs[i]; eq const& e = m_eqs[i];
if (e.ls().size() == ls.size()) { if (e.ls() != ls) continue;
bool flag = true;
for (unsigned j = 0; j < ls.size(); ++j)
if (e.ls().get(j) != ls.get(j)) {
flag = false;
break;
}
if (flag) {
expr* nl_fst = nullptr; expr* nl_fst = nullptr;
if (e.rs().size() > 1 && is_var(e.rs().get(0))) if (e.rs().size() > 1 && is_var(e.rs().get(0)))
nl_fst = e.rs().get(0); nl_fst = e.rs().get(0);
if (nl_fst && nl_fst != r_fst) { if (nl_fst && nl_fst != r_fst && root2 == get_root(mk_len(nl_fst))) {
expr_ref len_nl_fst = mk_len(nl_fst);
if (ctx.e_internalized(len_nl_fst)) {
enode * root1 = get_root(len_nl_fst);
if (root1 == root2) {
res.reset(); res.reset();
res.append(e.rs().size(), e.rs().c_ptr()); res.append(e.rs().size(), e.rs().c_ptr());
deps = m_dm.mk_join(e.dep(), deps); deps = m_dm.mk_join(e.dep(), deps);
return true; return true;
} }
} }
}
}
}
}
}
// Offset != 0, No change // Offset != 0, No change
if (l_fst) { if (l_fst && ctx.e_internalized(len_l_fst)) {
expr_ref len_l_fst = mk_len(l_fst);
if (ctx.e_internalized(len_l_fst)) {
enode * root1 = get_root(len_l_fst); enode * root1 = get_root(len_l_fst);
obj_map<enode, int> tmp; obj_map<enode, int> tmp;
int offset; int offset;
@ -1154,20 +1138,12 @@ bool theory_seq::find_better_rep(expr_ref_vector const& ls, expr_ref_vector cons
} }
} }
} }
}
// Offset != 0, Changed // Offset != 0, Changed
obj_map<enode, int> tmp; obj_map<enode, int> tmp;
if (!m_autil.is_numeral(root2->get_owner()) && m_len_offset.find(root2, tmp)) { if (!m_autil.is_numeral(root2->get_owner()) && m_len_offset.find(root2, tmp)) {
for (unsigned i = 0; i < idx; ++i) { for (unsigned i = 0; i < idx; ++i) {
eq const& e = m_eqs[i]; eq const& e = m_eqs[i];
if (e.ls().size() == ls.size()) { if (e.ls() != ls) continue;
bool flag = true;
for (unsigned j = 0; j < ls.size(); ++j)
if (e.ls().get(j) != ls.get(j)) {
flag = false;
break;
}
if (flag) {
expr* nl_fst = nullptr; expr* nl_fst = nullptr;
if (e.rs().size()>1 && is_var(e.rs().get(0))) if (e.rs().size()>1 && is_var(e.rs().get(0)))
nl_fst = e.rs().get(0); nl_fst = e.rs().get(0);
@ -1187,8 +1163,6 @@ bool theory_seq::find_better_rep(expr_ref_vector const& ls, expr_ref_vector cons
} }
} }
} }
}
}
return false; return false;
} }
@ -1255,6 +1229,7 @@ bool theory_seq::len_based_split() {
} }
} }
} }
std::function<bool(eq const&)> split = [&](eq const& e) { return len_based_split(e); };
for (auto const& e : m_eqs) { for (auto const& e : m_eqs) {
if (len_based_split(e)) { if (len_based_split(e)) {

View file

@ -306,6 +306,18 @@ public:
// prevent abuse: // prevent abuse:
ref_vector & operator=(ref_vector const & other) = delete; ref_vector & operator=(ref_vector const & other) = delete;
bool operator==(ref_vector const& other) const {
if (other.size() != size()) return false;
for (unsigned i = size(); i-- > 0; ) {
if (other[i] != (*this)[i]) return false;
}
return true;
}
bool operator!=(ref_vector const& other) const {
return !(*this == other);
}
bool forall(std::function<bool(T*)>& predicate) const { bool forall(std::function<bool(T*)>& predicate) const {
for (T* t : *this) for (T* t : *this)
if (!predicate(t)) if (!predicate(t))