diff --git a/src/smt/theory_seq.cpp b/src/smt/theory_seq.cpp index 609181538..0702bac69 100644 --- a/src/smt/theory_seq.cpp +++ b/src/smt/theory_seq.cpp @@ -2197,16 +2197,37 @@ bool theory_seq::check_int_string() { if (m_util.str.is_itos(e) && add_itos_axiom(e)) { change = true; } - else if (m_util.str.is_stoi(e, n)) { - // not (yet) handled. - // we would check that in the current proto-model - // the string at 'n', when denoting integer would map to the - // proper integer. + else if (m_util.str.is_stoi(e, n) && add_stoi_axiom(e)) { + change = true; } } return change; } +bool theory_seq::add_stoi_axiom(expr* e) { + context& ctx = get_context(); + expr* n; + rational val; + VERIFY(m_util.str.is_stoi(e, n)); + if (get_value(e, val) && !m_stoi_axioms.contains(val)) { + m_stoi_axioms.insert(val); + if (!val.is_minus_one()) { + app_ref e1(m_util.str.mk_string(symbol(val.to_string().c_str())), m); + expr_ref n1(arith_util(m).mk_numeral(val, true), m); + literal eq1 = mk_eq(e, n1, false); + literal eq2 = mk_eq(n, e1, false); + add_axiom(~eq1, eq2); + add_axiom(~eq2, eq1); + ctx.force_phase(eq1); + ctx.force_phase(eq2); + m_trail_stack.push(insert_map(m_stoi_axioms, val)); + m_trail_stack.push(push_replay(alloc(replay_axiom, m, e))); + return true; + } + } + return false; +} + bool theory_seq::add_itos_axiom(expr* e) { context& ctx = get_context(); rational val; diff --git a/src/smt/theory_seq.h b/src/smt/theory_seq.h index 136a84520..c1e179f67 100644 --- a/src/smt/theory_seq.h +++ b/src/smt/theory_seq.h @@ -308,6 +308,7 @@ namespace smt { bool m_incomplete; // is the solver (clearly) incomplete for the fragment. expr_ref_vector m_int_string; rational_set m_itos_axioms; + rational_set m_stoi_axioms; obj_hashtable m_length; // is length applied scoped_ptr_vector m_replay; // set of actions to replay model_generator* m_mg; @@ -493,6 +494,7 @@ namespace smt { void add_elim_string_axiom(expr* n); void add_at_axiom(expr* n); void add_in_re_axiom(expr* n); + bool add_stoi_axiom(expr* n); bool add_itos_axiom(expr* n); void add_itos_length_axiom(expr* n); literal mk_literal(expr* n);