3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-11 21:50:52 +00:00

patch seq theory using purification to avoid unsoundness caused by interaction with canonization and rewriting

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-02-14 17:40:41 -08:00
parent 2db2767e7a
commit 70b4822571
6 changed files with 45 additions and 42 deletions

View file

@ -106,10 +106,6 @@ void seq_axioms::add_extract_axiom(expr* e) {
add_extract_prefix_axiom(e, s, l);
return;
}
if (is_extract_suffix(s, i, l)) {
add_extract_suffix_axiom(e, s, i);
return;
}
expr_ref x = m_sk.mk_pre(s, i);
expr_ref ls = mk_len(s);
expr_ref lx = mk_len(x);
@ -195,24 +191,18 @@ bool seq_axioms::is_extract_prefix0(expr* s, expr* i, expr* l) {
return a.is_numeral(i, i1) && i1.is_zero();
}
bool seq_axioms::is_extract_suffix(expr* s, expr* i, expr* l) {
expr_ref len(a.mk_add(l, i), m);
m_rewrite(len);
return seq.str.is_length(len, l) && l == s;
}
/*
s = ey
l <= 0 => e = empty
0 <= l <= len(s) => len(e) = l
len(s) < l => len(e) = len(s)
len(s) < l => e = s
*/
void seq_axioms::add_extract_prefix_axiom(expr* e, expr* s, expr* l) {
TRACE("seq", tout << "prefix " << mk_bounded_pp(e, m, 2) << " " << mk_bounded_pp(s, m, 2) << " " << mk_bounded_pp(l, m, 2) << "\n";);
expr_ref le = mk_len(e);
expr_ref ls = mk_len(s);
expr_ref ls_minus_l(mk_sub(ls, l), m);
expr_ref zero(a.mk_int(0), m);
expr_ref y = m_sk.mk_post(s, l);
expr_ref ey = mk_concat(e, y);
literal l_le_s = mk_le(mk_sub(l, ls), 0);
@ -222,26 +212,6 @@ void seq_axioms::add_extract_prefix_axiom(expr* e, expr* s, expr* l) {
add_axiom(l_le_s, mk_eq(e, s));
}
/*
0 <= i <= len(s) => s = xe & i = len(x)
i < 0 => e = empty
i > len(s) => e = empty
*/
void seq_axioms::add_extract_suffix_axiom(expr* e, expr* s, expr* i) {
TRACE("seq", tout << "suffix " << mk_bounded_pp(e, m, 2) << " " << mk_bounded_pp(s, m, 2) << "\n";);
expr_ref x = m_sk.mk_pre(s, i);
expr_ref lx = mk_len(x);
expr_ref ls = mk_len(s);
expr_ref zero(a.mk_int(0), m);
expr_ref xe = mk_concat(x, e);
literal le_is_0 = mk_eq_empty(e);
literal i_ge_0 = mk_ge(i, 0);
literal i_le_s = mk_le(mk_sub(i, ls), 0);
add_axiom(~i_ge_0, ~i_le_s, mk_seq_eq(s, xe));
add_axiom(~i_ge_0, ~i_le_s, mk_eq(i, lx));
add_axiom(i_ge_0, le_is_0);
add_axiom(i_le_s, le_is_0);
}
/*
encode that s is not contained in of xs1