diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index 9c70f5999..17c3b1b88 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -980,6 +980,10 @@ namespace smt { void push_eq(enode * lhs, enode * rhs, eq_justification const & js) { SASSERT(lhs != rhs); + { + seq_util u(get_manager()); + SASSERT(!u.is_re(lhs->get_owner())); + } m_eq_propagation_queue.push_back(new_eq(lhs, rhs, js)); } diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index af8b9e395..da275de24 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -2176,8 +2176,59 @@ bool theory_seq::simplify_and_solve_eqs() { return m_new_propagation || ctx.inconsistent(); } -void theory_seq::internalize_eq_eh(app * atom, bool_var v) {} +void theory_seq::internalize_eq_eh(app * atom, bool_var v) { +} +bool theory_seq::internalize_atom(app* a, bool) { + context & ctx = get_context(); + bool_var bv = ctx.mk_bool_var(a); + ctx.set_var_theory(bv, get_id()); + ctx.mark_as_relevant(bv); + + expr* e1, *e2; + if (m_util.str.is_in_re(a, e1, e2)) { + return internalize_term(to_app(e1)) && internalize_re(e2); + } + if (m_util.str.is_contains(a, e1, e2) || + m_util.str.is_prefix(a, e1, e2) || + m_util.str.is_suffix(a, e1, e2)) { + return internalize_term(to_app(e1)) && internalize_term(to_app(e2)); + } + if (is_accept(a) || is_reject(a) || is_skolem(m_eq, a) || is_step(a) || is_skolem(symbol("seq.is_digit"), a)) { + return true; + } + UNREACHABLE(); + return internalize_term(a); +} + +bool theory_seq::internalize_re(expr* e) { + expr* e1, *e2; + unsigned lc; + if (m_util.re.is_to_re(e, e1)) { + return internalize_term(to_app(e1)); + } + if (m_util.re.is_star(e, e1) || + m_util.re.is_plus(e, e1) || + m_util.re.is_opt(e, e1) || + m_util.re.is_loop(e, e1, lc) || + m_util.re.is_complement(e, e1)) { + return internalize_re(e1); + } + if (m_util.re.is_union(e, e1, e2) || + m_util.re.is_intersection(e, e1, e2) || + m_util.re.is_concat(e, e1, e2)) { + return internalize_re(e1) && internalize_re(e2); + } + if (m_util.re.is_full(e) || + m_util.re.is_empty(e)) { + return true; + } + if (m_util.re.is_range(e, e1, e2)) { + return internalize_term(to_app(e1)) && internalize_term(to_app(e2)); + } + UNREACHABLE(); + return internalize_term(to_app(e)); +} bool theory_seq::internalize_term(app* term) { context & ctx = get_context(); @@ -3875,7 +3926,9 @@ void theory_seq::new_eq_eh(dependency* deps, enode* n1, enode* n2) { enforce_length_coherence(n1, n2); } else if (n1 != n2 && m_util.is_re(n1->get_owner())) { - warning_msg("equality between regular expressions is not yet supported"); + // ignore + UNREACHABLE(); + // eautomaton* a1 = get_automaton(n1->get_owner()); // eautomaton* a2 = get_automaton(n2->get_owner()); // eautomaton* b1 = mk_difference(*a1, *a2); diff --git a/src/smt/theory_seq.h b/src/smt/theory_seq.h index e145d3077..5fd31e2ca 100644 --- a/src/smt/theory_seq.h +++ b/src/smt/theory_seq.h @@ -341,8 +341,8 @@ namespace smt { virtual void init(context* ctx); virtual final_check_status final_check_eh(); - virtual bool internalize_atom(app* atom, bool) { return internalize_term(atom); } - virtual bool internalize_term(app*); + virtual bool internalize_atom(app* atom, bool); + virtual bool internalize_term(app*); virtual void internalize_eq_eh(app * atom, bool_var v); virtual void new_eq_eh(theory_var, theory_var); virtual void new_diseq_eh(theory_var, theory_var); @@ -387,6 +387,7 @@ namespace smt { vector const& ll, vector const& rl); bool set_empty(expr* x); bool is_complex(eq const& e); + bool internalize_re(expr* e); bool check_extensionality(); bool check_contains();