mirror of
https://github.com/Z3Prover/z3
synced 2025-10-09 01:11:55 +00:00
parent
e026f96ed4
commit
503bedbc7a
3 changed files with 99 additions and 84 deletions
|
@ -1487,8 +1487,7 @@ bool theory_seq::enforce_length(expr_ref_vector const& es, vector<rational> & le
|
|||
bool all_have_length = true;
|
||||
rational val;
|
||||
zstring s;
|
||||
for (unsigned i = 0; i < es.size(); ++i) {
|
||||
expr* e = es[i];
|
||||
for (expr* e : es) {
|
||||
if (m_util.str.is_unit(e)) {
|
||||
len.push_back(rational(1));
|
||||
}
|
||||
|
@ -3397,6 +3396,7 @@ bool theory_seq::check_int_string() {
|
|||
|
||||
bool theory_seq::check_int_string(expr* e) {
|
||||
return
|
||||
get_context().inconsistent() ||
|
||||
(m_util.str.is_itos(e) && add_itos_val_axiom(e)) ||
|
||||
(m_util.str.is_stoi(e) && add_stoi_val_axiom(e));
|
||||
}
|
||||
|
@ -3410,9 +3410,33 @@ void theory_seq::add_stoi_axiom(expr* e) {
|
|||
// stoi(s) >= -1
|
||||
literal l = mk_simplified_literal(m_autil.mk_ge(e, m_autil.mk_int(-1)));
|
||||
add_axiom(l);
|
||||
|
||||
|
||||
// stoi("") = -1
|
||||
add_axiom(mk_eq(m_util.str.mk_stoi(m_util.str.mk_empty(m.get_sort(s))), m_autil.mk_int(-1), false));
|
||||
}
|
||||
|
||||
void theory_seq::add_itos_axiom(expr* e) {
|
||||
rational val;
|
||||
expr* n = nullptr;
|
||||
TRACE("seq", tout << mk_pp(e, m) << "\n";);
|
||||
VERIFY(m_util.str.is_itos(e, n));
|
||||
|
||||
// itos(n) = "" <=> n < 0
|
||||
expr_ref zero(m_autil.mk_int(0), m);
|
||||
literal eq1 = mk_literal(m_util.str.mk_is_empty(e));
|
||||
literal ge0 = mk_literal(m_autil.mk_ge(n, zero));
|
||||
// n >= 0 => itos(n) != ""
|
||||
// itos(n) = "" or n >= 0
|
||||
add_axiom(~eq1, ~ge0);
|
||||
add_axiom(eq1, ge0);
|
||||
|
||||
// n >= 0 => stoi(itos(n)) = n
|
||||
app_ref stoi(m_util.str.mk_stoi(e), m);
|
||||
add_axiom(~ge0, mk_preferred_eq(stoi, n));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void theory_seq::ensure_digit_axiom() {
|
||||
|
||||
if (m_si_axioms.empty()) {
|
||||
|
@ -3425,7 +3449,7 @@ void theory_seq::ensure_digit_axiom() {
|
|||
}
|
||||
|
||||
bool theory_seq::add_itos_val_axiom(expr* e) {
|
||||
rational val;
|
||||
rational val, val2;
|
||||
expr* n = nullptr;
|
||||
TRACE("seq", tout << mk_pp(e, m) << "\n";);
|
||||
VERIFY(m_util.str.is_itos(e, n));
|
||||
|
@ -3435,11 +3459,11 @@ bool theory_seq::add_itos_val_axiom(expr* e) {
|
|||
}
|
||||
enforce_length(e);
|
||||
|
||||
if (get_length(e, val) && val.is_pos() && val.is_unsigned() && !m_si_axioms.contains(e)) {
|
||||
if (get_length(e, val) && val.is_pos() && val.is_unsigned() && (!m_si_axioms.find(e, val2) || val != val2)) {
|
||||
add_si_axiom(e, n, val.get_unsigned());
|
||||
m_si_axioms.insert(e);
|
||||
m_si_axioms.insert(e, val);
|
||||
m_trail_stack.push(push_replay(alloc(replay_is_axiom, m, e)));
|
||||
m_trail_stack.push(insert_map<theory_seq, obj_hashtable<expr>, expr*>(m_si_axioms, e));
|
||||
m_trail_stack.push(insert_map<theory_seq, obj_map<expr, rational>, expr*>(m_si_axioms, e));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3449,20 +3473,21 @@ bool theory_seq::add_itos_val_axiom(expr* e) {
|
|||
bool theory_seq::add_stoi_val_axiom(expr* e) {
|
||||
context& ctx = get_context();
|
||||
expr* n = nullptr;
|
||||
rational val;
|
||||
TRACE("seq", tout << mk_pp(e, m) << " " << ctx.get_scope_level () << "\n";);
|
||||
rational val, val2;
|
||||
VERIFY(m_util.str.is_stoi(e, n));
|
||||
|
||||
TRACE("seq", tout << mk_pp(e, m) << " " << ctx.get_scope_level () << " " << get_length(n, val) << " " << val << "\n";);
|
||||
|
||||
if (m_util.str.is_itos(n)) {
|
||||
return false;
|
||||
}
|
||||
enforce_length(n);
|
||||
|
||||
if (get_length(n, val) && val.is_pos() && val.is_unsigned() && !m_si_axioms.contains(e)) {
|
||||
if (get_length(n, val) && val.is_pos() && val.is_unsigned() && (!m_si_axioms.find(e, val2) || val2 != val)) {
|
||||
add_si_axiom(n, e, val.get_unsigned());
|
||||
m_si_axioms.insert(e);
|
||||
m_si_axioms.insert(e, val);
|
||||
m_trail_stack.push(push_replay(alloc(replay_is_axiom, m, e)));
|
||||
m_trail_stack.push(insert_map<theory_seq, obj_hashtable<expr>, expr*>(m_si_axioms, e));
|
||||
m_trail_stack.push(insert_map<theory_seq, obj_map<expr, rational>, expr*>(m_si_axioms, e));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3487,26 +3512,6 @@ expr_ref theory_seq::digit2int(expr* ch) {
|
|||
return expr_ref(mk_skolem(symbol("seq.digit2int"), ch, nullptr, nullptr, nullptr, m_autil.mk_int()), m);
|
||||
}
|
||||
|
||||
void theory_seq::add_itos_axiom(expr* e) {
|
||||
rational val;
|
||||
expr* n = nullptr;
|
||||
TRACE("seq", tout << mk_pp(e, m) << "\n";);
|
||||
VERIFY(m_util.str.is_itos(e, n));
|
||||
|
||||
// itos(n) = "" <=> n < 0
|
||||
expr_ref zero(arith_util(m).mk_int(0), m);
|
||||
literal eq1 = mk_literal(m_util.str.mk_is_empty(e));
|
||||
literal ge0 = mk_literal(m_autil.mk_ge(n, zero));
|
||||
// n >= 0 => itos(n) != ""
|
||||
// itos(n) = "" or n >= 0
|
||||
add_axiom(~eq1, ~ge0);
|
||||
add_axiom(eq1, ge0);
|
||||
|
||||
// n >= 0 => stoi(itos(n)) = n
|
||||
app_ref stoi(m_util.str.mk_stoi(e), m);
|
||||
add_axiom(~ge0, mk_preferred_eq(stoi, n));
|
||||
|
||||
}
|
||||
|
||||
|
||||
// n >= 0 & len(e) = k => is_digit(e_i) for i = 0..k-1
|
||||
|
@ -3550,7 +3555,7 @@ void theory_seq::add_si_axiom(expr* e, expr* n, unsigned k) {
|
|||
SASSERT(k > 0);
|
||||
rational lb = power(rational(10), k - 1);
|
||||
rational ub = power(rational(10), k) - 1;
|
||||
arith_util a (m);
|
||||
arith_util& a = m_autil;
|
||||
literal lbl = mk_literal(a.mk_ge(n, a.mk_int(lb)));
|
||||
literal ubl = mk_literal(a.mk_le(n, a.mk_int(ub)));
|
||||
literal ge_k = mk_literal(a.mk_ge(len, a.mk_int(k)));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue