Skip to content

Commit cc8cd2c

Browse files
na
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent 9c3f019 commit cc8cd2c

File tree

4 files changed

+58
-60
lines changed

4 files changed

+58
-60
lines changed

src/ast/rewriter/seq_rewriter.cpp

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,13 +2210,21 @@ br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) {
22102210
return BR_REWRITE3;
22112211
}
22122212

2213-
void seq_rewriter::remove_empty(expr_ref_vector& es) {
2213+
void seq_rewriter::remove_empty_and_concats(expr_ref_vector& es) {
22142214
unsigned j = 0;
2215+
bool has_concat = false;
22152216
for (expr* e : es) {
2217+
has_concat |= m_util.str.is_concat(e);
22162218
if (!m_util.str.is_empty(e))
22172219
es[j++] = e;
22182220
}
22192221
es.shrink(j);
2222+
if (has_concat) {
2223+
expr_ref_vector fs(m());
2224+
for (expr* e : es)
2225+
m_util.str.get_concat(e, fs);
2226+
es.swap(fs);
2227+
}
22202228
}
22212229

22222230
void seq_rewriter::remove_leading(unsigned n, expr_ref_vector& es) {
@@ -2229,15 +2237,15 @@ void seq_rewriter::remove_leading(unsigned n, expr_ref_vector& es) {
22292237
es.shrink(es.size() - n);
22302238
}
22312239

2232-
bool seq_rewriter::reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs, bool& change) {
2240+
bool seq_rewriter::reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs) {
22332241
expr* a, *b;
22342242
zstring s, s1, s2;
22352243
while (true) {
22362244
if (ls.empty() || rs.empty()) {
22372245
break;
22382246
}
22392247
expr* l = ls.back();
2240-
expr* r = rs.back();
2248+
expr* r = rs.back();
22412249
if (m_util.str.is_unit(r) && m_util.str.is_string(l)) {
22422250
std::swap(l, r);
22432251
ls.swap(rs);
@@ -2289,12 +2297,11 @@ bool seq_rewriter::reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_re
22892297
else {
22902298
break;
22912299
}
2292-
change = true;
22932300
}
22942301
return true;
22952302
}
22962303

2297-
bool seq_rewriter::reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs, bool& change) {
2304+
bool seq_rewriter::reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs) {
22982305
expr* a, *b;
22992306
zstring s, s1, s2;
23002307
unsigned head1 = 0, head2 = 0;
@@ -2364,7 +2371,6 @@ bool seq_rewriter::reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_r
23642371
else {
23652372
break;
23662373
}
2367-
change = true;
23682374
}
23692375
remove_leading(head1, ls);
23702376
remove_leading(head2, rs);
@@ -2376,17 +2382,24 @@ bool seq_rewriter::reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_r
23762382
- New equalities are inserted into eqs.
23772383
- Last remaining equalities that cannot be simplified further are kept in ls, rs
23782384
- returns false if equality is unsatisfiable
2385+
- sets change to true if some simplification occurred
23792386
*/
23802387
bool seq_rewriter::reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change) {
23812388
TRACE("seq_verbose", tout << ls << "\n"; tout << rs << "\n";);
2382-
remove_empty(ls);
2383-
remove_empty(rs);
2389+
unsigned hash_l = ls.hash();
2390+
unsigned hash_r = rs.hash();
2391+
unsigned sz_eqs = eqs.size();
2392+
remove_empty_and_concats(ls);
2393+
remove_empty_and_concats(rs);
23842394
return
2385-
reduce_back(ls, rs, eqs, change) &&
2386-
reduce_front(ls, rs, eqs, change) &&
2387-
reduce_itos(ls, rs, eqs, change) &&
2388-
reduce_by_length(ls, rs, eqs, change) &&
2389-
reduce_subsequence(ls, rs, eqs, change);
2395+
reduce_back(ls, rs, eqs) &&
2396+
reduce_front(ls, rs, eqs) &&
2397+
reduce_itos(ls, rs, eqs) &&
2398+
reduce_itos(rs, ls, eqs) &&
2399+
reduce_by_length(ls, rs, eqs) &&
2400+
reduce_subsequence(ls, rs, eqs) &&
2401+
(change = (hash_l != ls.hash() || hash_r != rs.hash() || eqs.size() != sz_eqs),
2402+
true);
23902403
}
23912404

23922405
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 {
25522565
return true;
25532566
}
25542567

2555-
bool seq_rewriter::reduce_itos(expr_ref_vector& ls, expr_ref_vector& rs,
2556-
expr_ref_pair_vector& eqs, bool& change) {
2557-
expr* n = nullptr;
2558-
if (ls.size() == 1 && m_util.str.is_itos(ls.get(0), n) &&
2559-
solve_itos(n, rs, eqs)) {
2560-
ls.reset(); rs.reset();
2561-
change = true;
2562-
}
2563-
else if (rs.size() == 1 && m_util.str.is_itos(rs.get(0), n) &&
2564-
solve_itos(n, ls, eqs)) {
2565-
ls.reset(); rs.reset();
2566-
change = true;
2567-
}
2568-
return true;
2569-
}
2570-
25712568
/**
25722569
* itos(n) = <numeric string> -> n = numeric
25732570
*/
25742571

2575-
bool seq_rewriter::solve_itos(expr* n, expr_ref_vector const& es, expr_ref_pair_vector& eqs) {
2572+
bool seq_rewriter::reduce_itos(expr_ref_vector& ls, expr_ref_vector& rs,
2573+
expr_ref_pair_vector& eqs) {
2574+
expr* n = nullptr;
25762575
zstring s;
2577-
if (is_string(es.size(), es.c_ptr(), s)) {
2576+
if (ls.size() == 1 &&
2577+
m_util.str.is_itos(ls.get(0), n) &&
2578+
is_string(rs.size(), rs.c_ptr(), s)) {
25782579
std::string s1 = s.encode();
25792580
rational r(s1.c_str());
25802581
if (s1 == r.to_string()) {
25812582
eqs.push_back(n, m_autil.mk_numeral(r, true));
2583+
ls.reset();
2584+
rs.reset();
25822585
return true;
25832586
}
2584-
}
2585-
return false;
2587+
}
2588+
return true;
25862589
}
25872590

25882591
bool seq_rewriter::reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs,
2589-
expr_ref_pair_vector& eqs, bool& change) {
2592+
expr_ref_pair_vector& eqs) {
25902593

25912594
if (ls.empty() && rs.empty())
25922595
return true;
@@ -2599,15 +2602,13 @@ bool seq_rewriter::reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs,
25992602
if (bounded2 && len2 < len1)
26002603
return false;
26012604
if (bounded1 && len1 == len2 && len1 > 0) {
2602-
change = true;
26032605
if (!set_empty(rs.size(), rs.c_ptr(), false, eqs))
26042606
return false;
26052607
eqs.push_back(concat_non_empty(ls), concat_non_empty(rs));
26062608
ls.reset();
26072609
rs.reset();
26082610
}
26092611
else if (bounded2 && len1 == len2 && len1 > 0) {
2610-
change = true;
26112612
if (!set_empty(ls.size(), ls.c_ptr(), false, eqs))
26122613
return false;
26132614
eqs.push_back(concat_non_empty(ls), concat_non_empty(rs));
@@ -2623,7 +2624,7 @@ bool seq_rewriter::is_epsilon(expr* e) const {
26232624
return m_util.re.is_to_re(e, e1) && m_util.str.is_empty(e1);
26242625
}
26252626

2626-
bool seq_rewriter::reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change) {
2627+
bool seq_rewriter::reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs) {
26272628

26282629
if (ls.size() > rs.size())
26292630
ls.swap(rs);
@@ -2663,7 +2664,6 @@ bool seq_rewriter::reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs,
26632664
if (j == rs.size()) {
26642665
return true;
26652666
}
2666-
change = true;
26672667
rs.shrink(j);
26682668
SASSERT(ls.size() == rs.size());
26692669
if (!ls.empty()) {

src/ast/rewriter/seq_rewriter.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,9 @@ class seq_rewriter {
174174
bool sign_is_determined(expr* len, sign& s);
175175

176176
bool set_empty(unsigned sz, expr* const* es, bool all, expr_ref_pair_vector& eqs);
177-
bool reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change);
178-
bool reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change);
179-
bool reduce_itos(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs, bool& change);
180-
bool solve_itos(expr* n, expr_ref_vector const& es, expr_ref_pair_vector& eqs);
177+
bool reduce_subsequence(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
178+
bool reduce_by_length(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
179+
bool reduce_itos(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& eqs);
181180
bool min_length(expr_ref_vector const& es, unsigned& len);
182181
expr* concat_non_empty(expr_ref_vector& es);
183182

@@ -188,9 +187,9 @@ class seq_rewriter {
188187
bool is_sequence(eautomaton& aut, expr_ref_vector& seq);
189188
bool is_epsilon(expr* e) const;
190189
bool get_lengths(expr* e, expr_ref_vector& lens, rational& pos);
191-
bool reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs, bool& change);
192-
bool reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs, bool& change);
193-
void remove_empty(expr_ref_vector& es);
190+
bool reduce_back(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs);
191+
bool reduce_front(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_pair_vector& new_eqs);
192+
void remove_empty_and_concats(expr_ref_vector& es);
194193
void remove_leading(unsigned n, expr_ref_vector& es);
195194

196195
public:

src/smt/theory_seq.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2288,7 +2288,6 @@ void theory_seq::validate_fmls(enode_pair_vector const& eqs, literal_vector cons
22882288
for (expr* f : fmls) {
22892289
k.assert_expr(f);
22902290
}
2291-
IF_VERBOSE(0, verbose_stream() << "validate: " << fmls << "\n";);
22922291
lbool r = k.check();
22932292
if (r != l_false && !m.limit().get_cancel_flag()) {
22942293
model_ref mdl;

src/util/ref_vector.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ class ref_vector_core : public Ref {
4141
dec_ref(*it);
4242
}
4343

44+
struct hash_proc {
45+
unsigned operator()(ref_vector_core const* v, unsigned idx) const {
46+
return (*v)[idx]->get_id();
47+
}
48+
};
4449
public:
4550
typedef T * data;
4651

@@ -129,6 +134,14 @@ class ref_vector_core : public Ref {
129134

130135
T ** c_ptr() { return m_nodes.begin(); }
131136

137+
unsigned hash() const {
138+
unsigned sz = size();
139+
if (sz == 0) {
140+
return 0;
141+
}
142+
return get_composite_hash(this, sz, default_kind_hash_proc<ref_vector_core const*>(), hash_proc());
143+
}
144+
132145
iterator begin() const { return m_nodes.begin(); }
133146
iterator end() const { return begin() + size(); }
134147

@@ -400,21 +413,8 @@ struct ref_vector_ptr_hash {
400413

401414
typedef ref_vector<T,TM> RefV;
402415

403-
struct hash_proc {
404-
unsigned operator()(RefV* v, unsigned idx) const {
405-
return (*v)[idx]->get_id();
406-
}
407-
};
408-
409416
unsigned operator()(RefV* v) const {
410-
if (!v) {
411-
return 0;
412-
}
413-
unsigned sz = v->size();
414-
if (sz == 0) {
415-
return 0;
416-
}
417-
return get_composite_hash(v, sz, default_kind_hash_proc<RefV*>(), hash_proc());
417+
return v ? v->hash() : 0;
418418
}
419419
};
420420

0 commit comments

Comments
 (0)