mirror of
https://github.com/Z3Prover/z3
synced 2025-04-29 20:05:51 +00:00
str.from_ubv step2
This commit is contained in:
parent
1bc10cebc5
commit
b6a3891ac4
10 changed files with 230 additions and 2 deletions
|
@ -16,6 +16,7 @@ Author:
|
|||
--*/
|
||||
|
||||
#include "ast/rewriter/seq_eq_solver.h"
|
||||
#include "ast/bv_decl_plugin.h"
|
||||
|
||||
namespace seq {
|
||||
|
||||
|
@ -37,6 +38,10 @@ namespace seq {
|
|||
return true;
|
||||
if (reduce_itos3(e, r))
|
||||
return true;
|
||||
if (reduce_ubv2s1(e, r))
|
||||
return true;
|
||||
if (reduce_ubv2s2(e, r))
|
||||
return true;
|
||||
if (reduce_binary_eq(e, r))
|
||||
return true;
|
||||
if (reduce_nth_solved(e, r))
|
||||
|
@ -184,8 +189,8 @@ namespace seq {
|
|||
expr_ref digit = m_ax.sk().mk_digit2int(u);
|
||||
add_consequence(m_ax.mk_ge(digit, 1));
|
||||
}
|
||||
expr_ref y(seq.str.mk_concat(e.rs, e.ls[0]->get_sort()), m);
|
||||
ctx.add_solution(e.ls[0], y);
|
||||
expr_ref y(seq.str.mk_concat(es, es[0]->get_sort()), m);
|
||||
ctx.add_solution(seq.str.mk_itos(n), y);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -209,6 +214,105 @@ namespace seq {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* from_ubv(s) == from_ubv(t)
|
||||
* --------------------------
|
||||
* s = t
|
||||
*/
|
||||
|
||||
bool eq_solver::match_ubv2s1(eqr const& e, expr*& a, expr*& b) {
|
||||
return
|
||||
e.ls.size() == 1 && e.rs.size() == 1 &&
|
||||
seq.str.is_ubv2s(e.ls[0], a) && seq.str.is_ubv2s(e.rs[0], b);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool eq_solver::reduce_ubv2s1(eqr const& e, eq_ptr& r) {
|
||||
expr* s = nullptr, * t = nullptr;
|
||||
if (!match_ubv2s1(e, s, t))
|
||||
return false;
|
||||
expr_ref eq = mk_eq(s, t);
|
||||
add_consequence(eq);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* bv2s(n) = [d1]+[d2]+...+[dk]
|
||||
* ---------------------------------
|
||||
* n = 10^{k-1}*d1 + ... + dk
|
||||
*
|
||||
* k > 1 => d1 > 0
|
||||
*/
|
||||
bool eq_solver::match_ubv2s2(eqr const& e, expr*& n, expr_ref_vector const*& es) {
|
||||
if (e.ls.size() == 1 && seq.str.is_ubv2s(e.ls[0], n)) {
|
||||
es = &e.rs;
|
||||
return true;
|
||||
}
|
||||
if (e.rs.size() == 1 && seq.str.is_ubv2s(e.rs[0], n)) {
|
||||
es = &e.ls;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool eq_solver::reduce_ubv2s2(eqr const& e, eq_ptr& r) {
|
||||
expr* n = nullptr;
|
||||
expr_ref_vector const* _es = nullptr;
|
||||
if (!match_ubv2s2(e, n, _es))
|
||||
return false;
|
||||
|
||||
expr_ref_vector const& es = *_es;
|
||||
if (es.empty()) {
|
||||
set_conflict();
|
||||
return true;
|
||||
}
|
||||
expr* u = nullptr;
|
||||
for (expr* r : es) {
|
||||
if (seq.str.is_unit(r, u)) {
|
||||
expr_ref is_digit = m_ax.is_digit(u);
|
||||
if (!m.is_true(ctx.expr2rep(is_digit)))
|
||||
add_consequence(is_digit);
|
||||
}
|
||||
}
|
||||
if (!all_units(es, 0, es.size()))
|
||||
return false;
|
||||
|
||||
expr_ref num(m);
|
||||
bv_util bv(m);
|
||||
sort* bv_sort = n->get_sort();
|
||||
unsigned sz = bv.get_bv_size(n);
|
||||
if (es.size() > (sz + log2(10)-1)/log2(10)) {
|
||||
set_conflict();
|
||||
return true;
|
||||
}
|
||||
|
||||
for (expr* r : es) {
|
||||
VERIFY(seq.str.is_unit(r, u));
|
||||
expr_ref digit = m_ax.sk().mk_digit2bv(u, bv_sort);
|
||||
if (!num)
|
||||
num = digit;
|
||||
else
|
||||
num = bv.mk_bv_add(bv.mk_bv_mul(bv.mk_numeral(10, sz), num), digit);
|
||||
}
|
||||
|
||||
expr_ref eq(m.mk_eq(n, num), m);
|
||||
m_ax.rewrite(eq);
|
||||
add_consequence(eq);
|
||||
if (es.size() > 1) {
|
||||
VERIFY(seq.str.is_unit(es[0], u));
|
||||
expr_ref digit = m_ax.sk().mk_digit2bv(u, bv_sort);
|
||||
expr_ref eq0(m.mk_eq(digit, bv.mk_numeral(0, sz)), m);
|
||||
expr_ref neq0(m.mk_not(eq0), m);
|
||||
add_consequence(neq0);
|
||||
}
|
||||
expr_ref y(seq.str.mk_concat(es, es[0]->get_sort()), m);
|
||||
ctx.add_solution(seq.str.mk_ubv2s(n), y);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Equation is of the form x ++ xs = ys ++ x
|
||||
* where |xs| = |ys| are units of same length
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue