3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-10-04 15:03:57 +00:00

Merge branch 'master' of https://github.com/z3prover/z3 into opt

This commit is contained in:
Nikolaj Bjorner 2017-05-22 12:59:36 -07:00
commit f698efa403
92 changed files with 8030 additions and 1822 deletions

View file

@ -440,24 +440,16 @@ br_status seq_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con
* (seq.unit (_ BitVector 8)) ==> String constant
*/
br_status seq_rewriter::mk_seq_unit(expr* e, expr_ref& result) {
sort * s = m().get_sort(e);
bv_util bvu(m());
if (is_sort_of(s, bvu.get_family_id(), BV_SORT)) {
// specifically we want (_ BitVector 8)
rational n_val;
unsigned int n_size;
if (bvu.is_numeral(e, n_val, n_size)) {
if (n_size == 8) {
// convert to string constant
char ch = (char)n_val.get_int32();
TRACE("seq", tout << "rewrite seq.unit of 8-bit value " << n_val.to_string() << " to string constant \"" << ch << "\"" << std::endl;);
char s_tmp[2] = {ch, '\0'};
symbol s(s_tmp);
result = m_util.str.mk_string(s);
return BR_DONE;
}
}
rational n_val;
unsigned int n_size;
// specifically we want (_ BitVector 8)
if (bvu.is_bv(e) && bvu.is_numeral(e, n_val, n_size) && n_size == 8) {
// convert to string constant
zstring str(n_val.get_unsigned());
TRACE("seq", tout << "rewrite seq.unit of 8-bit value " << n_val.to_string() << " to string constant \"" << str<< "\"" << std::endl;);
result = m_util.str.mk_string(str);
return BR_DONE;
}
return BR_FAILED;
@ -1431,37 +1423,10 @@ br_status seq_rewriter::mk_re_star(expr* a, expr_ref& result) {
}
/*
* (re.range c_1 c_n) = (re.union (str.to.re c1) (str.to.re c2) ... (str.to.re cn))
* (re.range c_1 c_n)
*/
br_status seq_rewriter::mk_re_range(expr* lo, expr* hi, expr_ref& result) {
return BR_FAILED;
TRACE("seq", tout << "rewrite re.range [" << mk_pp(lo, m()) << " " << mk_pp(hi, m()) << "]\n";);
zstring str_lo, str_hi;
if (m_util.str.is_string(lo, str_lo) && m_util.str.is_string(hi, str_hi)) {
if (str_lo.length() == 1 && str_hi.length() == 1) {
unsigned int c1 = str_lo[0];
unsigned int c2 = str_hi[0];
if (c1 > c2) {
// exchange c1 and c2
unsigned int tmp = c1;
c2 = c1;
c1 = tmp;
}
zstring s(c1);
expr_ref acc(m_util.re.mk_to_re(m_util.str.mk_string(s)), m());
for (unsigned int ch = c1 + 1; ch <= c2; ++ch) {
zstring s_ch(ch);
expr_ref acc2(m_util.re.mk_to_re(m_util.str.mk_string(s_ch)), m());
acc = m_util.re.mk_union(acc, acc2);
}
result = acc;
return BR_REWRITE2;
} else {
m().raise_exception("string constants in re.range must have length 1");
}
}
return BR_FAILED;
}
/*
@ -1506,6 +1471,7 @@ br_status seq_rewriter::mk_re_opt(expr* a, expr_ref& result) {
}
br_status seq_rewriter::mk_eq_core(expr * l, expr * r, expr_ref & result) {
TRACE("seq", tout << mk_pp(l, m()) << " = " << mk_pp(r, m()) << "\n";);
expr_ref_vector lhs(m()), rhs(m()), res(m());
bool changed = false;
if (!reduce_eq(l, r, lhs, rhs, changed)) {

View file

@ -876,6 +876,36 @@ bool seq_decl_plugin::is_value(app* e) const {
}
}
bool seq_decl_plugin::are_equal(app* a, app* b) const {
if (a == b) return true;
// handle concatenations
return false;
}
bool seq_decl_plugin::are_distinct(app* a, app* b) const {
if (a == b) {
return false;
}
if (is_app_of(a, m_family_id, OP_STRING_CONST) &&
is_app_of(b, m_family_id, OP_STRING_CONST)) {
return true;
}
if (is_app_of(a, m_family_id, OP_SEQ_UNIT) &&
is_app_of(b, m_family_id, OP_SEQ_UNIT)) {
return true;
}
if (is_app_of(a, m_family_id, OP_SEQ_EMPTY) &&
is_app_of(b, m_family_id, OP_SEQ_UNIT)) {
return true;
}
if (is_app_of(b, m_family_id, OP_SEQ_EMPTY) &&
is_app_of(a, m_family_id, OP_SEQ_UNIT)) {
return true;
}
return false;
}
expr* seq_decl_plugin::get_some_value(sort* s) {
seq_util util(*m_manager);
if (util.is_seq(s)) {

View file

@ -182,7 +182,11 @@ public:
virtual bool is_value(app * e) const;
virtual bool is_unique_value(app * e) const { return is_value(e); }
virtual bool is_unique_value(app * e) const { return false; }
virtual bool are_equal(app* a, app* b) const;
virtual bool are_distinct(app* a, app* b) const;
virtual expr * get_some_value(sort * s);