3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-06 09:34:08 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-04-23 21:28:19 -07:00
parent 9c3f0190f4
commit cc8cd2cc2f
4 changed files with 58 additions and 60 deletions

View file

@ -2210,13 +2210,21 @@ br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) {
return BR_REWRITE3;
}
void seq_rewriter::remove_empty(expr_ref_vector& es) {
void seq_rewriter::remove_empty_and_concats(expr_ref_vector& es) {
unsigned j = 0;
bool has_concat = false;
for (expr* e : es) {
has_concat |= m_util.str.is_concat(e);
if (!m_util.str.is_empty(e))
es[j++] = e;
}
es.shrink(j);
if (has_concat) {
expr_ref_vector fs(m());
for (expr* e : es)
m_util.str.get_concat(e, fs);
es.swap(fs);
}
}
void seq_rewriter::remove_leading(unsigned n, expr_ref_vector& es) {
@ -2229,7 +2237,7 @@ void seq_rewriter::remove_leading(unsigned n, expr_ref_vector& es) {
es.shrink(es.size() - n);
}
bool seq_rewriter::reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs, bool& change) {
bool seq_rewriter::reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs) {
expr* a, *b;
zstring s, s1, s2;
while (true) {
@ -2237,7 +2245,7 @@ bool seq_rewriter::reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_re
break;
}
expr* l = ls.back();
expr* r = rs.back();
expr* r = rs.back();
if (m_util.str.is_unit(r) && m_util.str.is_string(l)) {
std::swap(l, r);
ls.swap(rs);
@ -2289,12 +2297,11 @@ bool seq_rewriter::reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_re
else {
break;
}
change = true;
}
return true;
}
bool seq_rewriter::reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs, bool& change) {
bool seq_rewriter::reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs) {
expr* a, *b;
zstring s, s1, s2;
unsigned head1 = 0, head2 = 0;
@ -2364,7 +2371,6 @@ bool seq_rewriter::reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_r
else {
break;
}
change = true;
}
remove_leading(head1, ls);
remove_leading(head2, rs);
@ -2376,17 +2382,24 @@ bool seq_rewriter::reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_r
- New equalities are inserted into eqs.
- Last remaining equalities that cannot be simplified further are kept in ls, rs
- returns false if equality is unsatisfiable
- sets change to true if some simplification occurred
*/
bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change) {
TRACE("seq_verbose", tout << ls << "\n"; tout << rs << "\n";);
remove_empty(ls);
remove_empty(rs);
unsigned hash_l = ls.hash();
unsigned hash_r = rs.hash();
unsigned sz_eqs = eqs.size();
remove_empty_and_concats(ls);
remove_empty_and_concats(rs);
return
reduce_back(ls, rs, eqs, change) &&
reduce_front(ls, rs, eqs, change) &&
reduce_itos(ls, rs, eqs, change) &&
reduce_by_length(ls, rs, eqs, change) &&
reduce_subsequence(ls, rs, eqs, change);
reduce_back(ls, rs, eqs) &&
reduce_front(ls, rs, eqs) &&
reduce_itos(ls, rs, eqs) &&
reduce_itos(rs, ls, eqs) &&
reduce_by_length(ls, rs, eqs) &&
reduce_subsequence(ls, rs, eqs) &&
(change = (hash_l != ls.hash() || hash_r != rs.hash() || eqs.size() != sz_eqs),
true);
}
bool seq_rewriter::reduce_eq(expr* l, expr* r, expr_ref_pair_vector& new_eqs, bool& changed) {
@ -2552,41 +2565,31 @@ bool seq_rewriter::is_string(unsigned n, expr* const* es, zstring& s) const {
return true;
}
bool seq_rewriter::reduce_itos(expr_ref_vector& ls, expr_ref_vector& rs,
expr_ref_pair_vector& eqs, bool& change) {
expr* n = nullptr;
if (ls.size() == 1 && m_util.str.is_itos(ls.get(0), n) &&
solve_itos(n, rs, eqs)) {
ls.reset(); rs.reset();
change = true;
}
else if (rs.size() == 1 && m_util.str.is_itos(rs.get(0), n) &&
solve_itos(n, ls, eqs)) {
ls.reset(); rs.reset();
change = true;
}
return true;
}
/**
* itos(n) = <numeric string> -> n = numeric
*/
bool seq_rewriter::solve_itos(expr* n, expr_ref_vector const& es, expr_ref_pair_vector& eqs) {
bool seq_rewriter::reduce_itos(expr_ref_vector& ls, expr_ref_vector& rs,
expr_ref_pair_vector& eqs) {
expr* n = nullptr;
zstring s;
if (is_string(es.size(), es.c_ptr(), s)) {
if (ls.size() == 1 &&
m_util.str.is_itos(ls.get(0), n) &&
is_string(rs.size(), rs.c_ptr(), s)) {
std::string s1 = s.encode();
rational r(s1.c_str());
if (s1 == r.to_string()) {
eqs.push_back(n, m_autil.mk_numeral(r, true));
ls.reset();
rs.reset();
return true;
}
}
return false;
}
return true;
}
bool seq_rewriter::reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs,
expr_ref_pair_vector& eqs, bool& change) {
expr_ref_pair_vector& eqs) {
if (ls.empty() && rs.empty())
return true;
@ -2599,7 +2602,6 @@ bool seq_rewriter::reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs,
if (bounded2 && len2 < len1)
return false;
if (bounded1 && len1 == len2 && len1 > 0) {
change = true;
if (!set_empty(rs.size(), rs.c_ptr(), false, eqs))
return false;
eqs.push_back(concat_non_empty(ls), concat_non_empty(rs));
@ -2607,7 +2609,6 @@ bool seq_rewriter::reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs,
rs.reset();
}
else if (bounded2 && len1 == len2 && len1 > 0) {
change = true;
if (!set_empty(ls.size(), ls.c_ptr(), false, eqs))
return false;
eqs.push_back(concat_non_empty(ls), concat_non_empty(rs));
@ -2623,7 +2624,7 @@ bool seq_rewriter::is_epsilon(expr* e) const {
return m_util.re.is_to_re(e, e1) && m_util.str.is_empty(e1);
}
bool seq_rewriter::reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change) {
bool seq_rewriter::reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs) {
if (ls.size() > rs.size())
ls.swap(rs);
@ -2663,7 +2664,6 @@ bool seq_rewriter::reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs,
if (j == rs.size()) {
return true;
}
change = true;
rs.shrink(j);
SASSERT(ls.size() == rs.size());
if (!ls.empty()) {

View file

@ -174,10 +174,9 @@ class seq_rewriter {
bool sign_is_determined(expr* len, sign& s);
bool set_empty(unsigned sz, expr* const* es, bool all, expr_ref_pair_vector& eqs);
bool reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change);
bool reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change);
bool reduce_itos(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change);
bool solve_itos(expr* n, expr_ref_vector const& es, expr_ref_pair_vector& eqs);
bool reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
bool reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
bool reduce_itos(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
bool min_length(expr_ref_vector const& es, unsigned& len);
expr* concat_non_empty(expr_ref_vector& es);
@ -188,9 +187,9 @@ class seq_rewriter {
bool is_sequence(eautomaton& aut, expr_ref_vector& seq);
bool is_epsilon(expr* e) const;
bool get_lengths(expr* e, expr_ref_vector& lens, rational& pos);
bool reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs, bool& change);
bool reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs, bool& change);
void remove_empty(expr_ref_vector& es);
bool reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs);
bool reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs);
void remove_empty_and_concats(expr_ref_vector& es);
void remove_leading(unsigned n, expr_ref_vector& es);
public:

View file

@ -2288,7 +2288,6 @@ void theory_seq::validate_fmls(enode_pair_vector const& eqs, literal_vector cons
for (expr* f : fmls) {
k.assert_expr(f);
}
IF_VERBOSE(0, verbose_stream() << "validate: " << fmls << "\n";);
lbool r = k.check();
if (r != l_false && !m.limit().get_cancel_flag()) {
model_ref mdl;

View file

@ -41,6 +41,11 @@ protected:
dec_ref(*it);
}
struct hash_proc {
unsigned operator()(ref_vector_core const* v, unsigned idx) const {
return (*v)[idx]->get_id();
}
};
public:
typedef T * data;
@ -129,6 +134,14 @@ public:
T ** c_ptr() { return m_nodes.begin(); }
unsigned hash() const {
unsigned sz = size();
if (sz == 0) {
return 0;
}
return get_composite_hash(this, sz, default_kind_hash_proc<ref_vector_core const*>(), hash_proc());
}
iterator begin() const { return m_nodes.begin(); }
iterator end() const { return begin() + size(); }
@ -400,21 +413,8 @@ struct ref_vector_ptr_hash {
typedef ref_vector<T,TM> RefV;
struct hash_proc {
unsigned operator()(RefV* v, unsigned idx) const {
return (*v)[idx]->get_id();
}
};
unsigned operator()(RefV* v) const {
if (!v) {
return 0;
}
unsigned sz = v->size();
if (sz == 0) {
return 0;
}
return get_composite_hash(v, sz, default_kind_hash_proc<RefV*>(), hash_proc());
return v ? v->hash() : 0;
}
};