3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

str.from_ubv step2

This commit is contained in:
Nikolaj Bjorner 2021-07-12 15:00:36 +02:00
parent 1bc10cebc5
commit b6a3891ac4
10 changed files with 230 additions and 2 deletions

View file

@ -79,6 +79,7 @@ namespace smt {
void add_stoi_axiom(expr* n) { m_ax.stoi_axiom(n); }
void add_stoi_axiom(expr* e, unsigned k) { m_ax.stoi_axiom(e, k); }
void add_itos_axiom(expr* s, unsigned k) { m_ax.itos_axiom(s, k); }
void add_ubv2s_axiom(expr* b, unsigned k) { m_ax.ubv2s_axiom(b, k); }
void add_lt_axiom(expr* n) { m_ax.lt_axiom(n); }
void add_le_axiom(expr* n) { m_ax.le_axiom(n); }
void add_is_digit_axiom(expr* n) { m_ax.is_digit_axiom(n); }

View file

@ -262,6 +262,7 @@ theory_seq::theory_seq(context& ctx):
m_axioms(m),
m_axioms_head(0),
m_int_string(m),
m_ubv_string(m),
m_length(m),
m_length_limit(m),
m_mg(nullptr),
@ -368,6 +369,11 @@ final_check_status theory_seq::final_check_eh() {
TRACEFIN("int_string");
return FC_CONTINUE;
}
if (check_ubv_string()) {
++m_stats.m_ubv_string;
TRACEFIN("ubv_string");
return FC_CONTINUE;
}
if (reduce_length_eq()) {
++m_stats.m_branch_variable;
TRACEFIN("reduce_length");
@ -1525,6 +1531,60 @@ bool theory_seq::add_length_to_eqc(expr* e) {
return change;
}
void theory_seq::add_ubv_string(expr* e) {
m_ubv_string.push_back(e);
m_trail_stack.push(push_back_vector<expr_ref_vector>(m_ubv_string));
}
bool theory_seq::check_ubv_string() {
bool change = false;
for (expr* e : m_ubv_string) {
if (check_ubv_string(e))
change = true;
}
return change;
}
bool theory_seq::check_ubv_string(expr* e) {
expr* n = nullptr;
if (ctx.inconsistent())
return true;
if (m_has_ubv_axiom.contains(e))
return false;
expr* b = nullptr;
bv_util bv(m);
VERIFY(m_util.str.is_ubv2s(e, b));
unsigned sz = bv.get_bv_size(b);
rational value(0);
bool all_bits_assigned = true;
for (unsigned i = 0; i < sz; ++i) {
expr_ref bit(bv.mk_bit2bool(b, i), m);
literal lit = mk_literal(bit);
switch (ctx.get_assignment(lit)) {
case l_undef:
ctx.mark_as_relevant(lit);
all_bits_assigned = false;
break;
case l_true:
value += rational::power_of_two(i);
break;
case l_false:
break;
}
}
if (!all_bits_assigned)
return true;
unsigned k = 0;
while (value >= 10) {
k++;
value = div(value, rational(10));
}
m_has_ubv_axiom.insert(e);
m_trail_stack.push(insert_obj_trail<expr>(m_has_ubv_axiom, e));
m_ax.add_ubv2s_axiom(b, k);
return true;
}
void theory_seq::add_int_string(expr* e) {
m_int_string.push_back(e);
m_trail_stack.push(push_back_vector<expr_ref_vector>(m_int_string));
@ -1761,6 +1821,7 @@ void theory_seq::collect_statistics(::statistics & st) const {
st.update("seq extensionality", m_stats.m_extensionality);
st.update("seq fixed length", m_stats.m_fixed_length);
st.update("seq int.to.str", m_stats.m_int_string);
st.update("seq str.from_ubv", m_stats.m_ubv_string);
}
void theory_seq::init_search_eh() {
@ -3099,6 +3160,9 @@ void theory_seq::relevant_eh(app* n) {
add_int_string(n);
}
if (m_util.str.is_ubv2s(n))
add_ubv_string(n);
expr* arg = nullptr;
if (m_sk.is_tail(n, arg)) {
add_length_limit(arg, m_max_unfolding_depth, true);

View file

@ -323,6 +323,7 @@ namespace smt {
unsigned m_fixed_length;
unsigned m_propagate_contains;
unsigned m_int_string;
unsigned m_ubv_string;
};
typedef hashtable<rational, rational::hash_proc, rational::eq_proc> rational_set;
@ -348,6 +349,8 @@ namespace smt {
unsigned m_axioms_head; // index of first axiom to add.
bool m_incomplete; // is the solver (clearly) incomplete for the fragment.
expr_ref_vector m_int_string;
expr_ref_vector m_ubv_string; // list all occurrences of str.from_ubv that have been seen
obj_hashtable<expr> m_has_ubv_axiom; // keep track of ubv that have been axiomatized within scope.
obj_hashtable<expr> m_has_length; // is length applied
expr_ref_vector m_length; // length applications themselves
obj_map<expr, unsigned> m_length_limit_map; // sequences that have length limit predicates
@ -569,6 +572,11 @@ namespace smt {
bool branch_itos();
bool branch_itos(expr* e);
// functions that convert ubv to string
void add_ubv_string(expr* e);
bool check_ubv_string();
bool check_ubv_string(expr* e);
expr_ref add_elim_string_axiom(expr* n);
void add_in_re_axiom(expr* n);
literal mk_simplified_literal(expr* n);