3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-12-09 23:19:16 -08:00
parent d58c219b54
commit f9ca66d90b
3 changed files with 66 additions and 44 deletions

View file

@ -154,6 +154,12 @@ br_status seq_rewriter::mk_seq_length(expr* a, expr_ref& result) {
if (m_util.str.is_string(m_es[i], b)) { if (m_util.str.is_string(m_es[i], b)) {
len += b.length(); len += b.length();
} }
else if (m_util.str.is_unit(m_es[i])) {
len += 1;
}
else if (m_util.str.is_empty(m_es[i])) {
// skip
}
else { else {
m_es[j] = m_es[i]; m_es[j] = m_es[i];
++j; ++j;

View file

@ -655,16 +655,34 @@ void theory_seq::propagate() {
while (m_axioms_head < m_axioms.size() && !ctx.inconsistent()) { while (m_axioms_head < m_axioms.size() && !ctx.inconsistent()) {
expr_ref e(m); expr_ref e(m);
e = m_axioms[m_axioms_head].get(); e = m_axioms[m_axioms_head].get();
assert_axiom(e); deque_axiom(e);
++m_axioms_head; ++m_axioms_head;
} }
} }
void theory_seq::create_axiom(expr_ref& e) { void theory_seq::enque_axiom(expr* e) {
m_trail_stack.push(push_back_vector<theory_seq, expr_ref_vector>(m_axioms)); m_trail_stack.push(push_back_vector<theory_seq, expr_ref_vector>(m_axioms));
m_axioms.push_back(e); m_axioms.push_back(e);
} }
void theory_seq::deque_axiom(expr* n) {
if (m_util.str.is_length(n)) {
add_length_axiom(n);
}
else if (m_util.str.is_index(n)) {
add_indexof_axiom(n);
}
else if (m_util.str.is_replace(n)) {
add_replace_axiom(n);
}
else if (m_util.str.is_extract(n)) {
add_extract_axiom(n);
}
else if (m_util.str.is_at(n)) {
add_at_axiom(n);
}
}
/* /*
\brief nodes n1 and n2 are about to get merged. \brief nodes n1 and n2 are about to get merged.
if n1 occurs in the context of a length application, if n1 occurs in the context of a length application,
@ -694,10 +712,13 @@ void theory_seq::new_eq_len_concat(enode* n1, enode* n2) {
} }
enode* start2 = n2; enode* start2 = n2;
do { do {
if (m_util.str.is_concat(n2->get_owner())) { expr* o = n2->get_owner();
expr_ref ln(m); if (m_util.str.is_concat(o) ||
ln = m_util.str.mk_length(n2->get_owner()); m_util.str.is_unit(o) ||
add_len_axiom(ln); m_util.str.is_string(o) ||
m_util.str.is_empty(o)) {
expr_ref ln(m_util.str.mk_length(o), m);
enque_axiom(ln);
} }
n2 = n2->get_next(); n2 = n2->get_next();
} }
@ -786,23 +807,37 @@ void theory_seq::add_replace_axiom(expr* r) {
x = "" => len(x) = 0 x = "" => len(x) = 0
len(x) = rewrite(len(x)) len(x) = rewrite(len(x))
*/ */
void theory_seq::add_len_axiom(expr* n) { void theory_seq::add_length_axiom(expr* n) {
expr* x, *a, *b; expr* x, *a, *b;
VERIFY(m_util.str.is_length(n, x)); VERIFY(m_util.str.is_length(n, x));
expr_ref zero(m), emp(m); expr_ref zero(m), one(m), emp(m);
zero = m_autil.mk_int(0); zero = m_autil.mk_int(0);
emp = m_util.str.mk_empty(m.get_sort(x)); std::string s;
literal eq1(mk_eq(zero, n, false)); if (m_util.str.is_unit(n)) {
literal eq2(mk_eq(x, emp, false)); one = m_autil.mk_int(1);
add_axiom(mk_literal(m_autil.mk_le(zero, n))); add_axiom(mk_eq(n, one, false));
add_axiom(~eq1, eq2); }
add_axiom(~eq2, eq1); else if (m_util.str.is_empty(n)) {
if (m_util.str.is_concat(n, a, b)) { add_axiom(mk_eq(n, zero, false));
}
else if (m_util.str.is_string(n, s)) {
expr_ref ls(m_autil.mk_numeral(rational(s.length(), rational::ui64()), true), m);
add_axiom(mk_eq(n, ls, false));
}
else if (m_util.str.is_concat(n, a, b)) {
expr_ref _a(m_util.str.mk_length(a), m); expr_ref _a(m_util.str.mk_length(a), m);
expr_ref _b(m_util.str.mk_length(b), m); expr_ref _b(m_util.str.mk_length(b), m);
expr_ref a_p_b(m_autil.mk_add(_a, _b), m); expr_ref a_p_b(m_autil.mk_add(_a, _b), m);
add_axiom(mk_eq(n, a_p_b, false)); add_axiom(mk_eq(n, a_p_b, false));
} }
else {
emp = m_util.str.mk_empty(m.get_sort(x));
literal eq1(mk_eq(zero, n, false));
literal eq2(mk_eq(x, emp, false));
add_axiom(mk_literal(m_autil.mk_ge(n, zero)));
add_axiom(~eq1, eq2);
add_axiom(~eq2, eq1);
}
} }
/* /*
@ -883,15 +918,6 @@ void theory_seq::add_axiom(literal l1, literal l2, literal l3, literal l4) {
get_context().mk_th_axiom(get_id(), lits.size(), lits.c_ptr()); get_context().mk_th_axiom(get_id(), lits.size(), lits.c_ptr());
} }
void theory_seq::assert_axiom(expr_ref& e) {
context & ctx = get_context();
if (m.is_true(e)) return;
TRACE("seq", tout << "asserting " << e << "\n";);
ctx.internalize(e, false);
literal lit(ctx.get_literal(e));
ctx.mark_as_relevant(lit);
ctx.mk_th_axiom(get_id(), 1, &lit);
}
expr_ref theory_seq::mk_skolem(symbol const& name, expr* e1, expr* e2) { expr_ref theory_seq::mk_skolem(symbol const& name, expr* e1, expr* e2) {
expr* es[2] = { e1, e2 }; expr* es[2] = { e1, e2 };
@ -1024,21 +1050,12 @@ void theory_seq::restart_eh() {
#endif #endif
} }
void theory_seq::relevant_eh(app* n) { void theory_seq::relevant_eh(app* n) {
if (m_util.str.is_length(n)) { if (m_util.str.is_length(n) ||
add_len_axiom(n); m_util.str.is_index(n) ||
} m_util.str.is_replace(n) ||
else if (m_util.str.is_index(n)) { m_util.str.is_extract(n) ||
add_indexof_axiom(n); m_util.str.is_at(n)) {
} enque_axiom(n);
else if (m_util.str.is_replace(n)) {
add_replace_axiom(n);
}
else if (m_util.str.is_extract(n)) {
add_extract_axiom(n);
}
else if (m_util.str.is_at(n)) {
add_at_axiom(n);
} }
} }

View file

@ -168,15 +168,14 @@ namespace smt {
bool is_left_select(expr* a, expr*& b); bool is_left_select(expr* a, expr*& b);
bool is_right_select(expr* a, expr*& b); bool is_right_select(expr* a, expr*& b);
void assert_axiom(expr_ref& e); void enque_axiom(expr* e);
void create_axiom(expr_ref& e); void deque_axiom(expr* e);
void add_axiom(literal l1, literal l2 = null_literal, literal l3 = null_literal, literal l4 = null_literal); void add_axiom(literal l1, literal l2 = null_literal, literal l3 = null_literal, literal l4 = null_literal);
void add_indexof_axiom(expr* e); void add_indexof_axiom(expr* e);
void add_replace_axiom(expr* e); void add_replace_axiom(expr* e);
void add_extract_axiom(expr* e); void add_extract_axiom(expr* e);
void add_len_concat_axiom(expr* c); void add_length_axiom(expr* n);
void add_len_axiom(expr* n);
void add_at_axiom(expr* n); void add_at_axiom(expr* n);
literal mk_literal(expr* n); literal mk_literal(expr* n);
void tightest_prefix(expr* s, expr* x, literal lit); void tightest_prefix(expr* s, expr* x, literal lit);