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:
parent
aa723f1eee
commit
16be5b0e7d
3 changed files with 75 additions and 84 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue