mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 10:25:18 +00:00
fixes for #4688
https://github.com/Z3Prover/z3/issues/4866#issuecomment-778721073
This commit is contained in:
parent
2dcfe799bc
commit
804f065215
|
@ -1157,6 +1157,17 @@ br_status seq_rewriter::mk_seq_extract(expr* a, expr* b, expr* c, expr_ref& resu
|
|||
return BR_REWRITE3;
|
||||
}
|
||||
|
||||
// (extract (extract a p l) 0 (len a)) -> (extract a p l)
|
||||
if (str().is_extract(a, a1, b1, c1) && constantPos && pos == 0 && str().is_length(c, b1) && a1 == b1) {
|
||||
result = a;
|
||||
return BR_DONE;
|
||||
}
|
||||
|
||||
// (extract (extract a p l) 0 l) -> (extract a p l)
|
||||
if (str().is_extract(a, a1, b1, c1) && constantPos && pos == 0 && c == c1) {
|
||||
result = a;
|
||||
return BR_DONE;
|
||||
}
|
||||
|
||||
// extract(extract(a, 3, 6), 1, len(extract(a, 3, 6)) - 1) -> extract(a, 4, 5)
|
||||
if (str().is_extract(a, a1, b1, c1) && is_suffix(a, b, c) &&
|
||||
|
@ -4382,6 +4393,29 @@ br_status seq_rewriter::reduce_re_eq(expr* l, expr* r, expr_ref& result) {
|
|||
return BR_FAILED;
|
||||
}
|
||||
|
||||
br_status seq_rewriter::mk_le_core(expr * l, expr * r, expr_ref & result) {
|
||||
|
||||
// k <= len(x) -> true if k <= 0
|
||||
rational n;
|
||||
if (str().is_length(r) && m_autil.is_numeral(l, n) && n <= 0) {
|
||||
result = m().mk_true();
|
||||
return BR_DONE;
|
||||
}
|
||||
// len(x) <= 0 -> x = ""
|
||||
// len(x) <= k -> false if k < 0
|
||||
expr* e = nullptr;
|
||||
if (str().is_length(l, e) && m_autil.is_numeral(r, n)) {
|
||||
if (n == 0)
|
||||
result = str().mk_is_empty(e);
|
||||
else if (n < 0)
|
||||
result = m().mk_false();
|
||||
else
|
||||
return BR_FAILED;
|
||||
return BR_REWRITE1;
|
||||
}
|
||||
return BR_FAILED;
|
||||
}
|
||||
|
||||
br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) {
|
||||
expr_ref_vector res(m());
|
||||
expr_ref_pair_vector new_eqs(m());
|
||||
|
|
|
@ -330,6 +330,7 @@ public:
|
|||
|
||||
br_status mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result);
|
||||
br_status mk_eq_core(expr * lhs, expr * rhs, expr_ref & result);
|
||||
br_status mk_le_core(expr* lhs, expr* rhs, expr_ref& result);
|
||||
br_status mk_bool_app(func_decl* f, unsigned n, expr* const* args, expr_ref& result);
|
||||
|
||||
expr_ref mk_app(func_decl* f, expr_ref_vector const& args) { return mk_app(f, args.size(), args.c_ptr()); }
|
||||
|
|
|
@ -176,11 +176,8 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
// theory dispatch for =
|
||||
SASSERT(num == 2);
|
||||
family_id s_fid = args[0]->get_sort()->get_family_id();
|
||||
if (s_fid == m_a_rw.get_fid()) {
|
||||
if (s_fid == m_a_rw.get_fid())
|
||||
st = m_a_rw.mk_eq_core(args[0], args[1], result);
|
||||
if (st == BR_FAILED && is_app(args[0]) && to_app(args[0])->get_family_id() == m_seq_rw.get_fid())
|
||||
st = m_seq_rw.mk_eq_core(args[0], args[1], result);
|
||||
}
|
||||
else if (s_fid == m_bv_rw.get_fid())
|
||||
st = m_bv_rw.mk_eq_core(args[0], args[1], result);
|
||||
else if (s_fid == m_dt_rw.get_fid())
|
||||
|
@ -208,13 +205,30 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
if (st != BR_FAILED)
|
||||
return st;
|
||||
}
|
||||
if ((k == OP_AND || k == OP_OR /*|| k == OP_EQ*/) && m_seq_rw.u().has_re()) {
|
||||
if ((k == OP_AND || k == OP_OR) && m_seq_rw.u().has_re()) {
|
||||
st = m_seq_rw.mk_bool_app(f, num, args, result);
|
||||
if (st != BR_FAILED)
|
||||
return st;
|
||||
}
|
||||
if (k == OP_EQ && m_seq_rw.u().has_seq() && is_app(args[0]) &&
|
||||
to_app(args[0])->get_family_id() == m_seq_rw.get_fid()) {
|
||||
st = m_seq_rw.mk_eq_core(args[0], args[1], result);
|
||||
if (st != BR_FAILED)
|
||||
return st;
|
||||
}
|
||||
|
||||
return m_b_rw.mk_app_core(f, num, args, result);
|
||||
}
|
||||
if (fid == m_a_rw.get_fid() && OP_LE == f->get_decl_kind() && m_seq_rw.u().has_seq()) {
|
||||
st = m_seq_rw.mk_le_core(args[0], args[1], result);
|
||||
if (st != BR_FAILED)
|
||||
return st;
|
||||
}
|
||||
if (fid == m_a_rw.get_fid() && OP_GE == f->get_decl_kind() && m_seq_rw.u().has_seq()) {
|
||||
st = m_seq_rw.mk_le_core(args[1], args[0], result);
|
||||
if (st != BR_FAILED)
|
||||
return st;
|
||||
}
|
||||
if (fid == m_a_rw.get_fid())
|
||||
return m_a_rw.mk_app_core(f, num, args, result);
|
||||
if (fid == m_bv_rw.get_fid())
|
||||
|
|
|
@ -1933,7 +1933,9 @@ model_value_proc * theory_seq::mk_value(enode * n, model_generator & mg) {
|
|||
sv->add_string(c);
|
||||
}
|
||||
else {
|
||||
sv->add_string(mk_value(to_app(c)));
|
||||
app_ref val(mk_value(to_app(c)), m);
|
||||
TRACE("seq", tout << "WARNING: " << val << " is prone to result in incorrect model\n";);
|
||||
sv->add_string(val);
|
||||
}
|
||||
}
|
||||
m_concat.shrink(start);
|
||||
|
@ -2777,6 +2779,7 @@ bool theory_seq::propagate_eq(dependency* deps, literal_vector const& _lits, exp
|
|||
literal_vector lits(_lits);
|
||||
enode_pair_vector eqs;
|
||||
linearize(deps, eqs, lits);
|
||||
|
||||
if (add_to_eqs) {
|
||||
deps = mk_join(deps, _lits);
|
||||
new_eq_eh(deps, n1, n2);
|
||||
|
@ -3219,6 +3222,7 @@ void theory_seq::get_ite_concat(ptr_vector<expr>& concats, ptr_vector<expr>& tod
|
|||
todo.pop_back();
|
||||
e = m_rep.find(e);
|
||||
e = get_ite_value(e);
|
||||
e = m_rep.find(e);
|
||||
if (m_util.str.is_concat(e, e1, e2)) {
|
||||
todo.push_back(e2, e1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue