mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 18:31:49 +00:00
fix bug in definition of rewrite rule for replace, tighten constraints for tightest-prefix
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
12458b1a84
commit
d5383e2387
|
@ -444,11 +444,12 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) {
|
|||
|
||||
bool found = false;
|
||||
for (unsigned i = 0; !found && i < as.size(); ++i) {
|
||||
if (bs.size() > as.size() - i) break;
|
||||
all_values &= m().is_value(as[i].get());
|
||||
unsigned j = 0;
|
||||
for (; j < bs.size() && as[j+i].get() == bs[j].get(); ++j) {};
|
||||
found = j == bs.size();
|
||||
if (bs.size() <= as.size() - i) {
|
||||
unsigned j = 0;
|
||||
for (; j < bs.size() && as[j+i].get() == bs[j].get(); ++j) {};
|
||||
found = j == bs.size();
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
result = m().mk_true();
|
||||
|
|
|
@ -2135,13 +2135,13 @@ void theory_seq::deque_axiom(expr* n) {
|
|||
lit or s = "" or s = s1*(unit c)
|
||||
lit or s = "" or !contains(x*s1, s)
|
||||
*/
|
||||
void theory_seq::tightest_prefix(expr* s, expr* x, literal lit1, literal lit2) {
|
||||
void theory_seq::tightest_prefix(expr* s, expr* x) {
|
||||
expr_ref s1 = mk_first(s);
|
||||
expr_ref c = mk_last(s);
|
||||
expr_ref s1c = mk_concat(s1, m_util.str.mk_unit(c));
|
||||
literal s_eq_emp = mk_eq_empty(s);
|
||||
add_axiom(s_eq_emp, mk_seq_eq(s, s1c));
|
||||
add_axiom(lit1, lit2, s_eq_emp, ~mk_literal(m_util.str.mk_contains(mk_concat(x, s1), s)));
|
||||
add_axiom(s_eq_emp, ~mk_literal(m_util.str.mk_contains(mk_concat(x, s1), s)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2155,7 +2155,7 @@ void theory_seq::tightest_prefix(expr* s, expr* x, literal lit1, literal lit2) {
|
|||
|
||||
len(t) != 0 & !contains(t, s) => i = -1
|
||||
len(t) != 0 & contains(t, s) => t = xsy & i = len(x)
|
||||
len(t) != 0 & contains(t, s) & s != emp => tightest_prefix(x, s)
|
||||
tightest_prefix(x, s)
|
||||
|
||||
offset not fixed:
|
||||
|
||||
|
@ -2193,7 +2193,7 @@ void theory_seq::add_indexof_axiom(expr* i) {
|
|||
add_axiom(s_eq_empty, ~mk_eq_empty(t), mk_eq(i, minus_one, false));
|
||||
add_axiom(~cnt, s_eq_empty, mk_seq_eq(t, xsy));
|
||||
add_axiom(~cnt, s_eq_empty, mk_eq(i, lenx, false));
|
||||
tightest_prefix(s, x, ~cnt);
|
||||
tightest_prefix(s, x);
|
||||
}
|
||||
else {
|
||||
// offset >= len(t) => indexof(s, t, offset) = -1
|
||||
|
@ -2227,7 +2227,7 @@ void theory_seq::add_indexof_axiom(expr* i) {
|
|||
/*
|
||||
let r = replace(a, s, t)
|
||||
|
||||
(contains(a, s) -> tightest_prefix(s,xs))
|
||||
tightest_prefix(s, x)
|
||||
(contains(a, s) -> r = xty & a = xsy) &
|
||||
(!contains(a, s) -> r = a)
|
||||
|
||||
|
@ -2243,7 +2243,7 @@ void theory_seq::add_replace_axiom(expr* r) {
|
|||
add_axiom(cnt, mk_seq_eq(r, a));
|
||||
add_axiom(~cnt, mk_seq_eq(a, xsy));
|
||||
add_axiom(~cnt, mk_seq_eq(r, xty));
|
||||
tightest_prefix(s, x, ~cnt);
|
||||
tightest_prefix(s, x);
|
||||
}
|
||||
|
||||
void theory_seq::add_elim_string_axiom(expr* n) {
|
||||
|
@ -3382,6 +3382,7 @@ bool theory_seq::add_prefix2prefix(expr* e, bool& change) {
|
|||
VERIFY(m_util.str.is_prefix(e, e1, e2));
|
||||
SASSERT(ctx.get_assignment(e) == l_false);
|
||||
if (canonizes(false, e)) {
|
||||
TRACE("seq", tout << mk_pp(e, m) << " is false\n";);
|
||||
return false;
|
||||
}
|
||||
expr_ref head1(m), tail1(m), head2(m), tail2(m), conc(m);
|
||||
|
@ -3515,11 +3516,13 @@ bool theory_seq::canonizes(bool sign, expr* e) {
|
|||
TRACE("seq", tout << mk_pp(e, m) << " -> " << cont << "\n";);
|
||||
if ((m.is_true(cont) && !sign) ||
|
||||
(m.is_false(cont) && sign)) {
|
||||
TRACE("seq", display(tout););
|
||||
propagate_lit(deps, 0, 0, ctx.get_literal(e));
|
||||
return true;
|
||||
}
|
||||
if ((m.is_false(cont) && !sign) ||
|
||||
(m.is_true(cont) && sign)) {
|
||||
TRACE("seq", display(tout););
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -443,7 +443,7 @@ namespace smt {
|
|||
literal mk_literal(expr* n);
|
||||
literal mk_eq_empty(expr* n);
|
||||
literal mk_seq_eq(expr* a, expr* b);
|
||||
void tightest_prefix(expr* s, expr* x, literal lit, literal lit2 = null_literal);
|
||||
void tightest_prefix(expr* s, expr* x);
|
||||
expr_ref mk_sub(expr* a, expr* b);
|
||||
enode* ensure_enode(expr* a);
|
||||
|
||||
|
|
Loading…
Reference in a new issue