mirror of
https://github.com/Z3Prover/z3
synced 2025-07-29 07:27:57 +00:00
implementing last-index-of #2089
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
62ec02e50f
commit
3c8fd83c97
10 changed files with 174 additions and 31 deletions
|
@ -4150,6 +4150,12 @@ expr_ref theory_seq::expand1(expr* e0, dependency*& eqs) {
|
|||
if (!arg1 || !arg2) return result;
|
||||
result = m_util.str.mk_index(arg1, arg2, e3);
|
||||
}
|
||||
else if (m_util.str.is_last_index(e, e1, e2)) {
|
||||
arg1 = try_expand(e1, deps);
|
||||
arg2 = try_expand(e2, deps);
|
||||
if (!arg1 || !arg2) return result;
|
||||
result = m_util.str.mk_last_index(arg1, arg2);
|
||||
}
|
||||
else if (m.is_ite(e, e1, e2, e3)) {
|
||||
if (ctx.e_internalized(e) && ctx.e_internalized(e2) && ctx.get_enode(e)->get_root() == ctx.get_enode(e2)->get_root()) {
|
||||
result = try_expand(e2, deps);
|
||||
|
@ -4288,6 +4294,9 @@ void theory_seq::deque_axiom(expr* n) {
|
|||
else if (m_util.str.is_index(n)) {
|
||||
add_indexof_axiom(n);
|
||||
}
|
||||
else if (m_util.str.is_last_index(n)) {
|
||||
add_last_indexof_axiom(n);
|
||||
}
|
||||
else if (m_util.str.is_replace(n)) {
|
||||
add_replace_axiom(n);
|
||||
}
|
||||
|
@ -4437,6 +4446,42 @@ void theory_seq::add_indexof_axiom(expr* i) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
!contains(t, s) => i = -1
|
||||
|t| = 0 => |s| = 0 or i = -1
|
||||
|t| = 0 & |s| = 0 => i = 0
|
||||
|t| != 0 & contains(t, s) => t = xsy & i = len(x)
|
||||
|s| = 0 or s = s_head*s_tail
|
||||
|s| = 0 or !contains(s_tail*y, s)
|
||||
|
||||
*/
|
||||
void theory_seq::add_last_indexof_axiom(expr* i) {
|
||||
expr* s = nullptr, *t = nullptr;
|
||||
VERIFY(m_util.str.is_last_index(i, t, s));
|
||||
expr_ref minus_one(m_autil.mk_int(-1), m);
|
||||
expr_ref zero(m_autil.mk_int(0), m);
|
||||
expr_ref s_head(m), s_tail(m);
|
||||
expr_ref x = mk_skolem(symbol("seq.last_indexof_left"), t, s);
|
||||
expr_ref y = mk_skolem(symbol("seq.last_indexof_right"), t, s);
|
||||
mk_decompose(s, s_head, s_tail);
|
||||
literal cnt = mk_literal(m_util.str.mk_contains(t, s));
|
||||
literal cnt2 = mk_literal(m_util.str.mk_contains(mk_concat(s_tail, y), s));
|
||||
literal i_eq_m1 = mk_eq(i, minus_one, false);
|
||||
literal i_eq_0 = mk_eq(i, zero, false);
|
||||
literal s_eq_empty = mk_eq_empty(s);
|
||||
literal t_eq_empty = mk_eq_empty(t);
|
||||
expr_ref xsy = mk_concat(x, s, y);
|
||||
|
||||
add_axiom(cnt, i_eq_m1);
|
||||
add_axiom(~t_eq_empty, s_eq_empty, i_eq_m1);
|
||||
add_axiom(~t_eq_empty, ~s_eq_empty, i_eq_0);
|
||||
add_axiom(t_eq_empty, ~cnt, mk_seq_eq(t, xsy));
|
||||
add_axiom(t_eq_empty, ~cnt, mk_eq(i, mk_len(x), false));
|
||||
add_axiom(s_eq_empty, mk_eq(s, mk_concat(s_head, s_tail), false));
|
||||
add_axiom(s_eq_empty, ~cnt2);
|
||||
}
|
||||
|
||||
/*
|
||||
let r = replace(a, s, t)
|
||||
|
||||
|
|
|
@ -550,6 +550,7 @@ namespace smt {
|
|||
void push_lit_as_expr(literal l, expr_ref_vector& buf);
|
||||
void add_axiom(literal l1, literal l2 = null_literal, literal l3 = null_literal, literal l4 = null_literal, literal l5 = null_literal);
|
||||
void add_indexof_axiom(expr* e);
|
||||
void add_last_indexof_axiom(expr* e);
|
||||
void add_replace_axiom(expr* e);
|
||||
void add_extract_axiom(expr* e);
|
||||
void add_length_axiom(expr* n);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue