mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
fixes and more porting seq_eq_solver to self-contained module
This commit is contained in:
parent
847724fb21
commit
38737db802
21 changed files with 354 additions and 230 deletions
|
@ -75,13 +75,10 @@ bool theory_seq::solve_eq(unsigned idx) {
|
|||
}
|
||||
|
||||
TRACE("seq_verbose", tout << ls << " = " << rs << "\n";);
|
||||
if (!ctx.inconsistent() && solve_nth_eq1(ls, rs, deps)) {
|
||||
if (!ctx.inconsistent() && solve_nth_eq(ls, rs, deps)) {
|
||||
return true;
|
||||
}
|
||||
if (!ctx.inconsistent() && solve_nth_eq1(rs, ls, deps)) {
|
||||
return true;
|
||||
}
|
||||
if (!ctx.inconsistent() && solve_itos(rs, ls, deps)) {
|
||||
if (!ctx.inconsistent() && solve_nth_eq(rs, ls, deps)) {
|
||||
return true;
|
||||
}
|
||||
if (!ctx.inconsistent() && change) {
|
||||
|
@ -674,42 +671,11 @@ bool theory_seq::can_align_from_lhs(expr_ref_vector const& ls, expr_ref_vector c
|
|||
expr_ref r = mk_concat(rs);
|
||||
expr_ref pair(m.mk_eq(l,r), m);
|
||||
bool result;
|
||||
if (m_overlap_lhs.find(pair, result)) {
|
||||
return result;
|
||||
if (!m_overlap_lhs.find(pair, result)) {
|
||||
result = m_eq.can_align_from_lhs_aux(ls, rs);
|
||||
m_overlap_lhs.insert(pair, result);
|
||||
}
|
||||
for (unsigned i = 0; i < ls.size(); ++i) {
|
||||
if (!m.are_distinct(ls[i], rs.back())) {
|
||||
bool same = true;
|
||||
if (i == 0) {
|
||||
m_overlap_lhs.insert(pair, true);
|
||||
return true;
|
||||
}
|
||||
// ls = rs' ++ y && rs = x ++ rs', diff = |x|
|
||||
if (rs.size() > i) {
|
||||
unsigned diff = rs.size() - (i + 1);
|
||||
for (unsigned j = 0; same && j < i; ++j) {
|
||||
same = !m.are_distinct(ls[j], rs[diff + j]);
|
||||
}
|
||||
if (same) {
|
||||
m_overlap_lhs.insert(pair, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ls = x ++ rs ++ y, diff = |x|
|
||||
else {
|
||||
unsigned diff = (i + 1) - rs.size();
|
||||
for (unsigned j = 0; same && j + 1 < rs.size(); ++j) {
|
||||
same = !m.are_distinct(ls[diff + j], rs[j]);
|
||||
}
|
||||
if (same) {
|
||||
m_overlap_lhs.insert(pair, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_overlap_lhs.insert(pair, false);
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
|
||||
// exists x, y, rs' != empty s.t. (ls = x ++ rs ++ y) || (ls = x ++ rs' && rs = rs' ++ y)
|
||||
|
@ -717,45 +683,16 @@ bool theory_seq::can_align_from_rhs(expr_ref_vector const& ls, expr_ref_vector c
|
|||
SASSERT(!ls.empty() && !rs.empty());
|
||||
expr_ref l = mk_concat(ls);
|
||||
expr_ref r = mk_concat(rs);
|
||||
expr_ref pair(m.mk_eq(l,r), m);
|
||||
expr_ref pair(m.mk_eq(l, r), m);
|
||||
bool result;
|
||||
if (m_overlap_rhs.find(pair, result)) {
|
||||
return result;
|
||||
if (!m_overlap_rhs.find(pair, result)) {
|
||||
result = m_eq.can_align_from_rhs_aux(ls, rs);
|
||||
m_overlap_rhs.insert(pair, result);
|
||||
}
|
||||
for (unsigned i = 0; i < ls.size(); ++i) {
|
||||
unsigned diff = ls.size()-1-i;
|
||||
if (!m.are_distinct(ls[diff], rs[0])) {
|
||||
bool same = true;
|
||||
if (i == 0) {
|
||||
m_overlap_rhs.insert(pair, true);
|
||||
return true;
|
||||
}
|
||||
// ls = x ++ rs' && rs = rs' ++ y, diff = |x|
|
||||
if (rs.size() > i) {
|
||||
for (unsigned j = 1; same && j <= i; ++j) {
|
||||
same = !m.are_distinct(ls[diff+j], rs[j]);
|
||||
}
|
||||
if (same) {
|
||||
m_overlap_rhs.insert(pair, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ls = x ++ rs ++ y, diff = |x|
|
||||
else {
|
||||
for (unsigned j = 1; same && j < rs.size(); ++j) {
|
||||
same = !m.are_distinct(ls[diff + j], rs[j]);
|
||||
}
|
||||
if (same) {
|
||||
m_overlap_rhs.insert(pair, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_overlap_rhs.insert(pair, false);
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Equation is of the form x ++ xs = y1 ++ ys ++ y2 where xs, ys are units.
|
||||
// If xs and ys cannot align then
|
||||
// x ++ xs = y1 ++ ys ++ y2 => x = y1 ++ ys ++ z, z ++ xs = y2
|
||||
|
@ -1365,7 +1302,7 @@ struct remove_obj_pair_map : public trail {
|
|||
x = pre(x, idx) ++ unit(rhs) ++ post(x, idx + 1)
|
||||
NB: need 0 <= idx < len(rhs)
|
||||
*/
|
||||
bool theory_seq::solve_nth_eq2(expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* deps) {
|
||||
bool theory_seq::solve_nth_eq(expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* deps) {
|
||||
expr* s = nullptr, *idx = nullptr;
|
||||
if (ls.size() == 1 && m_util.str.is_nth_i(ls[0], s, idx)) {
|
||||
rational r;
|
||||
|
@ -1389,32 +1326,4 @@ bool theory_seq::solve_nth_eq2(expr_ref_vector const& ls, expr_ref_vector const&
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
match
|
||||
x = unit(nth_i(x,0)) + unit(nth_i(x,1)) + .. + unit(nth_i(x,k-1))
|
||||
*/
|
||||
|
||||
bool theory_seq::solve_nth_eq1(expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* dep) {
|
||||
if (solve_nth_eq2(ls, rs, dep)) {
|
||||
return true;
|
||||
}
|
||||
if (ls.size() != 1 || rs.size() <= 1) {
|
||||
return false;
|
||||
}
|
||||
expr* l = ls.get(0);
|
||||
rational val;
|
||||
if (!get_length(l, val) || val != rational(rs.size())) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned i = 0; i < rs.size(); ++i) {
|
||||
unsigned k = 0;
|
||||
expr* ru = nullptr, *r = nullptr;
|
||||
if (m_util.str.is_unit(rs.get(i), ru) && m_util.str.is_nth_i(ru, r, k) && k == i && r == l) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
add_solution(l, mk_concat(rs, l->get_sort()), dep);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ namespace smt {
|
|||
SASSERT(proc);
|
||||
}
|
||||
else {
|
||||
TRACE("model", tout << "creating fresh value for #" << r->get_owner_id() << "\n";);
|
||||
TRACE("model", tout << "creating fresh value for #" << mk_pp(r->get_expr(), m) << "\n";);
|
||||
proc = alloc(fresh_value_proc, mk_extra_fresh_value(r->get_sort()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -931,57 +931,6 @@ bool theory_seq::simplify_eq(expr_ref_vector& ls, expr_ref_vector& rs, dependenc
|
|||
return true;
|
||||
}
|
||||
|
||||
bool theory_seq::solve_itos(expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* dep) {
|
||||
expr* e = nullptr;
|
||||
|
||||
if (rs.size() == 1 && m_util.str.is_itos(rs[0], e) && solve_itos(e, ls, dep))
|
||||
return true;
|
||||
if (ls.size() == 1 && m_util.str.is_itos(ls[0], e) && solve_itos(e, rs, dep))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool theory_seq::solve_itos(expr* n, expr_ref_vector const& rs, dependency* dep) {
|
||||
if (rs.empty()) {
|
||||
literal lit = m_ax.mk_le(n, -1);
|
||||
propagate_lit(dep, 0, nullptr, lit);
|
||||
return true;
|
||||
}
|
||||
expr* u = nullptr;
|
||||
for (expr* r : rs) {
|
||||
if (m_util.str.is_unit(r, u) && !m_is_digit.contains(u)) {
|
||||
m_is_digit.insert(u);
|
||||
m_trail_stack.push(insert_obj_trail<expr>(m_is_digit, u));
|
||||
literal is_digit = m_ax.is_digit(u);
|
||||
if (ctx.get_assignment(is_digit) != l_true) {
|
||||
propagate_lit(dep, 0, nullptr, is_digit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expr_ref num(m), digit(m);
|
||||
for (expr* r : rs) {
|
||||
if (!m_util.str.is_unit(r, u))
|
||||
return false;
|
||||
digit = m_sk.mk_digit2int(u);
|
||||
if (!num) {
|
||||
num = digit;
|
||||
}
|
||||
else {
|
||||
num = m_autil.mk_add(m_autil.mk_mul(m_autil.mk_int(10), num), digit);
|
||||
}
|
||||
}
|
||||
|
||||
propagate_lit(dep, 0, nullptr, mk_simplified_literal(m.mk_eq(n, num)));
|
||||
if (rs.size() > 1) {
|
||||
VERIFY (m_util.str.is_unit(rs[0], u));
|
||||
digit = m_sk.mk_digit2int(u);
|
||||
propagate_lit(dep, 0, nullptr, m_ax.mk_ge(digit, 1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool theory_seq::reduce_length(expr* l, expr* r, literal_vector& lits) {
|
||||
expr_ref len1(m), len2(m);
|
||||
|
|
|
@ -464,11 +464,8 @@ namespace smt {
|
|||
bool solve_eq(unsigned idx);
|
||||
bool simplify_eq(expr_ref_vector& l, expr_ref_vector& r, dependency* dep);
|
||||
bool lift_ite(expr_ref_vector const& l, expr_ref_vector const& r, dependency* dep);
|
||||
bool solve_nth_eq1(expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* dep);
|
||||
obj_pair_hashtable<expr, expr> m_nth_eq2_cache;
|
||||
bool solve_nth_eq2(expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* dep);
|
||||
bool solve_itos(expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* dep);
|
||||
bool solve_itos(expr* n, expr_ref_vector const& rs, dependency* dep);
|
||||
bool solve_nth_eq(expr_ref_vector const& ls, expr_ref_vector const& rs, dependency* dep);
|
||||
|
||||
bool solve_binary_eq(expr_ref_vector const& l, expr_ref_vector const& r, dependency* dep);
|
||||
bool propagate_max_length(expr* l, expr* r, dependency* dep);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue