mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 18:31:49 +00:00
seq
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
16ced7cda5
commit
5962ca2a62
|
@ -320,6 +320,17 @@ br_status bv_rewriter::mk_leq_core(bool is_signed, expr * a, expr * b, expr_ref
|
|||
}
|
||||
}
|
||||
|
||||
expr* a1, *a2, *a3, *a4, *a5, *a6;
|
||||
// (bvsle (- x (rem x c1)) c2) -> (bvsle x (+ c1 c2 - 1))
|
||||
if (is_signed && is_num2 && m_util.is_bv_add(a, a1, a2) &&
|
||||
m_util.is_bv_mul(a2, a3, a4) && is_numeral(a3, r3, sz) &&
|
||||
(r3 = m_util.norm(r3, sz, is_signed), r3.is_minus_one()) &&
|
||||
m_util.is_bv_sremi(a4, a5, a6) && is_numeral(a6, r3, sz) &&
|
||||
a1 == a5 /* && r1 + r3 - rational::one() < power(rational(2), sz) */) {
|
||||
result = m_util.mk_sle(a1, m_util.mk_numeral(r3 + r1 - rational::one(), sz));
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!is_signed && m_util.is_concat(b) && to_app(b)->get_num_args() == 2 && m_util.is_zero(to_app(b)->get_arg(0))) {
|
||||
//
|
||||
|
|
|
@ -233,6 +233,11 @@ final_check_status theory_seq::final_check_eh() {
|
|||
TRACE("seq", tout << ">>solve_nqs\n";);
|
||||
return FC_CONTINUE;
|
||||
}
|
||||
if (fixed_length()) {
|
||||
++m_stats.m_fixed_length;
|
||||
TRACE("seq", tout << ">>fixed_length\n";);
|
||||
return FC_CONTINUE;
|
||||
}
|
||||
if (branch_variable()) {
|
||||
++m_stats.m_branch_variable;
|
||||
TRACE("seq", tout << ">>branch_variable\n";);
|
||||
|
@ -430,6 +435,7 @@ lbool theory_seq::assume_equality(expr* l, expr* r) {
|
|||
return l_undef;
|
||||
}
|
||||
|
||||
|
||||
bool theory_seq::propagate_length_coherence(expr* e) {
|
||||
expr_ref head(m), tail(m);
|
||||
rational lo, hi;
|
||||
|
@ -509,6 +515,54 @@ bool theory_seq::check_length_coherence() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool theory_seq::fixed_length() {
|
||||
obj_hashtable<expr>::iterator it = m_length.begin(), end = m_length.end();
|
||||
for (; it != end; ++it) {
|
||||
if (fixed_length(*it)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool theory_seq::fixed_length(expr* e) {
|
||||
rational lo, hi;
|
||||
if (!(is_var(e) && lower_bound(e, lo) && upper_bound(e, hi) && lo == hi && lo.is_unsigned() && lo.is_pos())) {
|
||||
return false;
|
||||
}
|
||||
if (m_fixed.contains(e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
context& ctx = get_context();
|
||||
|
||||
m_trail_stack.push(insert_obj_trail<theory_seq, expr>(m_fixed, e));
|
||||
m_fixed.insert(e);
|
||||
|
||||
if (is_skolem(m_tail, e) || is_skolem(m_pre, e) || is_skolem(m_post, e) || is_skolem(m_seq_first, e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned _lo = lo.get_unsigned();
|
||||
expr_ref seq(e, m), head(m), tail(m);
|
||||
expr_ref_vector elems(m);
|
||||
|
||||
for (unsigned j = 0; j < _lo; ++j) {
|
||||
mk_decompose(seq, head, tail);
|
||||
elems.push_back(head);
|
||||
seq = tail;
|
||||
}
|
||||
seq = mk_concat(elems.size(), elems.c_ptr());
|
||||
std::cout << "Fixed " << mk_pp(e, m) << " " << lo << " " << get_context().get_scope_level() << "\n";
|
||||
TRACE("seq", tout << "Fixed: " << mk_pp(e, m) << " " << lo << "\n";);
|
||||
add_axiom(~mk_eq(m_util.str.mk_length(e), m_autil.mk_numeral(lo, true), false), mk_seq_eq(seq, e));
|
||||
if (!ctx.at_base_level()) {
|
||||
m_trail_stack.push(push_replay(alloc(replay_fixed_length, m, e)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
lit => s != ""
|
||||
*/
|
||||
|
@ -1778,6 +1832,7 @@ void theory_seq::collect_statistics(::statistics & st) const {
|
|||
st.update("seq solve =", m_stats.m_solve_eqs);
|
||||
st.update("seq add axiom", m_stats.m_add_axiom);
|
||||
st.update("seq extensionality", m_stats.m_extensionality);
|
||||
st.update("seq fixed length", m_stats.m_fixed_length);
|
||||
}
|
||||
|
||||
void theory_seq::init_model(expr_ref_vector const& es) {
|
||||
|
|
|
@ -208,6 +208,17 @@ namespace smt {
|
|||
}
|
||||
};
|
||||
|
||||
class replay_fixed_length : public apply {
|
||||
expr_ref m_e;
|
||||
public:
|
||||
replay_fixed_length(ast_manager& m, expr* e) : m_e(e, m) {}
|
||||
virtual ~replay_fixed_length() {}
|
||||
virtual void operator()(theory_seq& th) {
|
||||
th.fixed_length(m_e);
|
||||
m_e.reset();
|
||||
}
|
||||
};
|
||||
|
||||
class replay_axiom : public apply {
|
||||
expr_ref m_e;
|
||||
public:
|
||||
|
@ -251,6 +262,7 @@ namespace smt {
|
|||
unsigned m_solve_eqs;
|
||||
unsigned m_add_axiom;
|
||||
unsigned m_extensionality;
|
||||
unsigned m_fixed_length;
|
||||
};
|
||||
ast_manager& m;
|
||||
dependency_manager m_dm;
|
||||
|
@ -292,6 +304,8 @@ namespace smt {
|
|||
bool m_new_propagation; // new propagation to core
|
||||
re2automaton m_mk_aut;
|
||||
|
||||
obj_hashtable<expr> m_fixed; // string variables that are fixed length.
|
||||
|
||||
virtual final_check_status final_check_eh();
|
||||
virtual bool internalize_atom(app* atom, bool) { return internalize_term(atom); }
|
||||
virtual bool internalize_term(app*);
|
||||
|
@ -322,6 +336,8 @@ namespace smt {
|
|||
bool is_solved();
|
||||
bool check_length_coherence();
|
||||
bool check_length_coherence(expr* e);
|
||||
bool fixed_length();
|
||||
bool fixed_length(expr* e);
|
||||
bool propagate_length_coherence(expr* e);
|
||||
|
||||
bool check_extensionality();
|
||||
|
|
Loading…
Reference in a new issue