3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2019-08-02 19:31:02 +08:00
parent c4480337c4
commit 584eee2cf4
6 changed files with 43 additions and 57 deletions

View file

@ -478,11 +478,12 @@ br_status seq_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
SASSERT(num_args == 2);
st = mk_seq_at(args[0], args[1], result);
break;
#if 1
case OP_SEQ_NTH:
SASSERT(num_args == 2);
return mk_seq_nth(args[0], args[1], result);
#endif
case OP_SEQ_NTH_I:
SASSERT(num_args == 2);
return mk_seq_nth_i(args[0], args[1], result);
case OP_SEQ_PREFIX:
SASSERT(num_args == 2);
st = mk_seq_prefix(args[0], args[1], result);
@ -991,6 +992,16 @@ br_status seq_rewriter::mk_seq_at(expr* a, expr* b, expr_ref& result) {
}
br_status seq_rewriter::mk_seq_nth(expr* a, expr* b, expr_ref& result) {
expr* es[2] = { a, b};
expr* la = m_util.str.mk_length(a);
result = m().mk_ite(m().mk_and(m_autil.mk_le(m_autil.mk_int(0), b), m_autil.mk_lt(b, la)),
m().mk_app(m_util.get_family_id(), OP_SEQ_NTH_I, 2, es),
m().mk_app(m_util.get_family_id(), OP_SEQ_NTH_U, 2, es));
return BR_REWRITE_FULL;
}
br_status seq_rewriter::mk_seq_nth_i(expr* a, expr* b, expr_ref& result) {
zstring c;
rational r;
if (!m_autil.is_numeral(b, r) || !r.is_unsigned()) {

View file

@ -115,6 +115,7 @@ class seq_rewriter {
br_status mk_seq_contains(expr* a, expr* b, expr_ref& result);
br_status mk_seq_at(expr* a, expr* b, expr_ref& result);
br_status mk_seq_nth(expr* a, expr* b, expr_ref& result);
br_status mk_seq_nth_i(expr* a, expr* b, expr_ref& result);
br_status mk_seq_index(expr* a, expr* b, expr* c, expr_ref& result);
br_status mk_seq_last_index(expr* a, expr* b, expr_ref& result);
br_status mk_seq_replace(expr* a, expr* b, expr* c, expr_ref& result);

View file

@ -559,6 +559,8 @@ void seq_decl_plugin::init() {
m_sigs[OP_SEQ_LAST_INDEX] = alloc(psig, m, "seq.last_indexof", 1, 2, seqAseqA, intT);
m_sigs[OP_SEQ_AT] = alloc(psig, m, "seq.at", 1, 2, seqAintT, seqA);
m_sigs[OP_SEQ_NTH] = alloc(psig, m, "seq.nth", 1, 2, seqAintT, A);
m_sigs[OP_SEQ_NTH_I] = alloc(psig, m, "seq.nth_i", 1, 2, seqAintT, A);
m_sigs[OP_SEQ_NTH_U] = alloc(psig, m, "seq.nth_u", 1, 2, seqAintT, A);
m_sigs[OP_SEQ_LENGTH] = alloc(psig, m, "seq.len", 1, 1, &seqA, intT);
m_sigs[OP_RE_PLUS] = alloc(psig, m, "re.+", 1, 1, &reA, reA);
m_sigs[OP_RE_STAR] = alloc(psig, m, "re.*", 1, 1, &reA, reA);
@ -852,6 +854,8 @@ func_decl * seq_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters,
return mk_str_fun(k, arity, domain, range, OP_SEQ_AT);
case OP_SEQ_NTH:
case OP_SEQ_NTH_I:
case OP_SEQ_NTH_U:
match(*m_sigs[k], arity, domain, range, rng);
return m.mk_func_decl(m_sigs[k]->m_name, arity, domain, rng, func_decl_info(m_family_id, k));
@ -1035,14 +1039,14 @@ bool seq_util::str::is_string(expr const* n, zstring& s) const {
}
}
bool seq_util::str::is_nth(expr const* n, expr*& s, unsigned& idx) const {
bool seq_util::str::is_nth_i(expr const* n, expr*& s, unsigned& idx) const {
expr* i = nullptr;
if (!is_nth(n, s, i)) return false;
if (!is_nth_i(n, s, i)) return false;
return arith_util(m).is_unsigned(i, idx);
}
app* seq_util::str::mk_nth(expr* s, unsigned i) const {
return mk_nth(s, arith_util(m).mk_int(i));
app* seq_util::str::mk_nth_i(expr* s, unsigned i) const {
return mk_nth_i(s, arith_util(m).mk_int(i));
}
void seq_util::str::get_concat(expr* e, expr_ref_vector& es) const {

View file

@ -41,6 +41,8 @@ enum seq_op_kind {
OP_SEQ_REPLACE,
OP_SEQ_AT,
OP_SEQ_NTH,
OP_SEQ_NTH_I,
OP_SEQ_NTH_U,
OP_SEQ_LENGTH,
OP_SEQ_INDEX,
OP_SEQ_LAST_INDEX,
@ -259,8 +261,8 @@ public:
expr* mk_concat(expr_ref_vector const& es) const { return mk_concat(es.size(), es.c_ptr()); }
app* mk_length(expr* a) const { return m.mk_app(m_fid, OP_SEQ_LENGTH, 1, &a); }
app* mk_at(expr* s, expr* i) const { expr* es[2] = { s, i }; return m.mk_app(m_fid, OP_SEQ_AT, 2, es); }
app* mk_nth(expr* s, expr* i) const { expr* es[2] = { s, i }; return m.mk_app(m_fid, OP_SEQ_NTH, 2, es); }
app* mk_nth(expr* s, unsigned i) const;
app* mk_nth_i(expr* s, expr* i) const { expr* es[2] = { s, i }; return m.mk_app(m_fid, OP_SEQ_NTH_I, 2, es); }
app* mk_nth_i(expr* s, unsigned i) const;
app* mk_substr(expr* a, expr* b, expr* c) const { expr* es[3] = { a, b, c }; return m.mk_app(m_fid, OP_SEQ_EXTRACT, 3, es); }
app* mk_contains(expr* a, expr* b) const { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_SEQ_CONTAINS, 2, es); }
@ -277,7 +279,8 @@ public:
app* mk_lex_le(expr* a, expr* b) const { expr* es[2] = { a, b }; return m.mk_app(m_fid, OP_STRING_LE, 2, es); }
bool is_nth(func_decl* f) const { return is_decl_of(f, m_fid, OP_SEQ_NTH); }
bool is_nth_i(func_decl* f) const { return is_decl_of(f, m_fid, OP_SEQ_NTH_I); }
bool is_nth_u(func_decl* f) const { return is_decl_of(f, m_fid, OP_SEQ_NTH_U); }
bool is_string(expr const * n) const { return is_app_of(n, m_fid, OP_STRING_CONST); }
bool is_string(expr const* n, symbol& s) const {
@ -292,8 +295,9 @@ public:
bool is_extract(expr const* n) const { return is_app_of(n, m_fid, OP_SEQ_EXTRACT); }
bool is_contains(expr const* n) const { return is_app_of(n, m_fid, OP_SEQ_CONTAINS); }
bool is_at(expr const* n) const { return is_app_of(n, m_fid, OP_SEQ_AT); }
bool is_nth(expr const* n) const { return is_app_of(n, m_fid, OP_SEQ_NTH); }
bool is_nth(expr const* n, expr*& s, unsigned& idx) const;
bool is_nth_i(expr const* n) const { return is_app_of(n, m_fid, OP_SEQ_NTH_I); }
bool is_nth_u(expr const* n) const { return is_app_of(n, m_fid, OP_SEQ_NTH_U); }
bool is_nth_i(expr const* n, expr*& s, unsigned& idx) const;
bool is_index(expr const* n) const { return is_app_of(n, m_fid, OP_SEQ_INDEX); }
bool is_last_index(expr const* n) const { return is_app_of(n, m_fid, OP_SEQ_LAST_INDEX); }
bool is_replace(expr const* n) const { return is_app_of(n, m_fid, OP_SEQ_REPLACE); }
@ -321,7 +325,8 @@ public:
MATCH_TERNARY(is_extract);
MATCH_BINARY(is_contains);
MATCH_BINARY(is_at);
MATCH_BINARY(is_nth);
MATCH_BINARY(is_nth_i);
MATCH_BINARY(is_nth_u);
MATCH_BINARY(is_index);
MATCH_TERNARY(is_index);
MATCH_BINARY(is_last_index);