3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 20:18:18 +00:00
This commit is contained in:
trinhmt 2020-04-24 01:04:10 +08:00 committed by GitHub
parent 8fe3caa101
commit 08290230db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 141 deletions

View file

@ -229,7 +229,7 @@ bool theory_seq::occurs(expr* a, expr* b) {
G |- len(r3) = len(r2) G |- len(r3) = len(r2)
r2, r3 are not identical r2, r3 are not identical
---------------------------------- ----------------------------------
e'' : l1 + l2 + l3 + l = r3 + r' e'' : r3 + r' = r1 + r2 + r
e: l1 + l2 + l3 + l = r1 + r2 + r e: l1 + l2 + l3 + l = r1 + r2 + r
G |- len(l1) = len(l2) = len(r1) = 0 G |- len(l1) = len(l2) = len(r1) = 0
@ -237,7 +237,7 @@ bool theory_seq::occurs(expr* a, expr* b) {
G |- len(r3) = len(r2) + offset G |- len(r3) = len(r2) + offset
r2, r3 are not identical r2, r3 are not identical
---------------------------------- ----------------------------------
e'' : l1 + l2 + l3 + l = r3 + r' e'' : r3 + r' = r1 + r2 + r
NB, this doesn't make sense because e'' is just e', which already occurs. NB, this doesn't make sense because e'' is just e', which already occurs.
It doesn't inherit the constraints from e either, which would get lost. It doesn't inherit the constraints from e either, which would get lost.
@ -299,7 +299,6 @@ bool theory_seq::find_better_rep(expr_ref_vector const& ls, expr_ref_vector cons
enode * root1 = get_root(len_l_fst); enode * root1 = get_root(len_l_fst);
if (m_offset_eq.contains(root1, root2)) { if (m_offset_eq.contains(root1, root2)) {
TRACE("seq", tout << "(" << mk_pp(l_fst, m) << ", " << mk_pp(r_fst,m) << ")\n";); TRACE("seq", tout << "(" << mk_pp(l_fst, m) << ", " << mk_pp(r_fst,m) << ")\n";);
find_max_eq_len(ls, rs);
return false; return false;
} }
} }
@ -319,7 +318,6 @@ bool theory_seq::find_better_rep(expr_ref_vector const& ls, expr_ref_vector cons
res.reset(); res.reset();
res.append(e.rs()); res.append(e.rs());
deps = m_dm.mk_join(e.dep(), deps); deps = m_dm.mk_join(e.dep(), deps);
find_max_eq_len(res, rs);
return true; return true;
} }
} }
@ -405,7 +403,6 @@ bool theory_seq::len_based_split() {
propagate ls = rs & len(x12 + Z) == len(y11) => x11 + Z == y11 propagate ls = rs & len(x12 + Z) == len(y11) => x11 + Z == y11
propagate ls = rs & len(x11 + Z) == len(y11) => x12 == Z + y12 propagate ls = rs & len(x11 + Z) == len(y11) => x12 == Z + y12
propagate ls = rs & len(x12 + Z) == len(y11) => len(Z) = offset propagate ls = rs & len(x12 + Z) == len(y11) => len(Z) = offset
propagate ls = rs & len(ls[2:]) == len(rs[2:]) => ls[2:] == rs[2:]
*/ */
@ -452,26 +449,6 @@ bool theory_seq::len_based_split(eq const& e) {
} }
lits.push_back(lit1); lits.push_back(lit1);
if (ls.size() >= 2 && rs.size() >= 2 && (ls.size() > 2 || rs.size() > 2)) {
expr_ref len1(m_autil.mk_int(0),m), len2(m_autil.mk_int(0),m);
for (unsigned i = 2; i < ls.size(); ++i) {
len1 = mk_add(len1, mk_len(ls[i]));
}
for (unsigned i = 2; i < rs.size(); ++i) {
len2 = mk_add(len2, mk_len(rs[i]));
}
literal lit2 = mk_eq(len1, len2, false);
if (ctx.get_assignment(lit2) == l_true) {
lits.push_back(lit2);
TRACE("seq", tout << len1 << " = " << len2 << "\n";);
expr_ref lhs = mk_concat(ls.size()-2, ls.c_ptr()+2, srt);
expr_ref rhs = mk_concat(rs.size()-2, rs.c_ptr()+2, srt);
propagate_eq(dep, lits, lhs, rhs, true);
lits.pop_back();
}
}
if (offset != 0) { if (offset != 0) {
expr_ref lenZ = mk_len(Z); expr_ref lenZ = mk_len(Z);
propagate_eq(dep, lits, lenZ, m_autil.mk_int(offset), false); propagate_eq(dep, lits, lenZ, m_autil.mk_int(offset), false);
@ -1174,116 +1151,6 @@ expr* theory_seq::find_fst_non_empty_var(expr_ref_vector const& x) {
return nullptr; return nullptr;
} }
void theory_seq::find_max_eq_len(expr_ref_vector const& ls, expr_ref_vector const& rs) {
context& ctx = get_context();
if (ls.size() >= 2 && rs.size() >= 2) {
expr_ref len1(m_autil.mk_int(0), m), len2(m_autil.mk_int(0), m);
int l_fst = find_fst_non_empty_idx(ls);
int r_fst = find_fst_non_empty_idx(rs);
if (l_fst<0 || r_fst<0)
return;
unsigned j = 2 + l_fst;
rational lo1(-1), hi1(-1), lo2(-1), hi2(-1);
if (j >= ls.size()) {
lo1 = 0;
hi1 = 0;
}
while (j < ls.size()) {
rational lo(-1), hi(-1);
if (m_util.str.is_unit(ls.get(j))) {
lo = 1;
hi = 1;
}
else {
expr_ref len_s = mk_len(ls.get(j));
lower_bound(len_s, lo);
upper_bound(len_s, hi);
}
if (!lo.is_minus_one()) {
if (lo1.is_minus_one())
lo1 = lo;
else
lo1 += lo;
}
if (!hi.is_minus_one()) {
if (hi1.is_minus_one())
hi1 = hi;
else if (hi1.is_nonneg())
hi1 += hi;
}
else {
hi1 = rational(-2);
}
len1 = mk_add(len1, mk_len(ls.get(j)));
j++;
}
j = 2 + r_fst;
if (j >= rs.size()) {
lo2 = 0;
hi2 = 0;
}
while (j < rs.size()) {
rational lo(-1), hi(-1);
if (m_util.str.is_unit(rs.get(j))) {
lo = 1;
hi = 1;
}
else {
expr_ref len_s = mk_len(rs.get(j));
lower_bound(len_s, lo);
upper_bound(len_s, hi);
}
if (!lo.is_minus_one()) {
if (lo2.is_minus_one())
lo2 = lo;
else
lo2 += lo;
}
if (!hi.is_minus_one()) {
if (hi2.is_minus_one())
hi2 = hi;
else if (hi1.is_nonneg())
hi2 += hi;
}
else {
hi2 = rational(-2);
}
len2 = mk_add(len2, mk_len(rs.get(j)));
j++;
}
if (m_autil.is_numeral(len1) && m_autil.is_numeral(len2))
return;
TRACE("seq", tout << lo1 << ", " << hi1 << ", " << lo2 << ", " << hi2 << "\n";);
if (!lo1.is_neg() && !hi2.is_neg() && lo1 > hi2)
return;
if (!lo2.is_neg() && !hi1.is_neg() && lo2 > hi1)
return;
literal lit1 = null_literal;
if (hi1.is_zero()) {
if (!is_var(rs[1 + r_fst]))
return;
lit1 = mk_literal(m_autil.mk_le(len2, len1));
TRACE("seq", tout << mk_pp(len1, m) << " >= " << mk_pp(len2, m) << "\n";);
}
else if (hi2.is_zero()) {
if (!is_var(ls[1 + l_fst]))
return;
lit1 = mk_literal(m_autil.mk_le(len1, len2));
TRACE("seq", tout << mk_pp(len1, m) << " <= " << mk_pp(len2, m) << "\n";);
}
else {
lit1 = mk_eq(len1, len2, false);
TRACE("seq", tout << mk_pp(len1, m) << " = " << mk_pp(len2, m) << "\n";);
}
if (ctx.get_assignment(lit1) == l_undef) {
ctx.mark_as_relevant(lit1);
ctx.force_phase(lit1);
}
}
}
bool theory_seq::branch_variable_eq() { bool theory_seq::branch_variable_eq() {
context& ctx = get_context(); context& ctx = get_context();
unsigned sz = m_eqs.size(); unsigned sz = m_eqs.size();
@ -1640,7 +1507,7 @@ bool theory_seq::is_binary_eq(expr_ref_vector const& ls, expr_ref_vector const&
} }
/* /*
match: Description TBD match: X abc Y..Y' = Z def T..T', where X,Z are variables or concatenation of variables
*/ */
bool theory_seq::is_quat_eq(expr_ref_vector const& ls, expr_ref_vector const& rs, bool theory_seq::is_quat_eq(expr_ref_vector const& ls, expr_ref_vector const& rs,
@ -1689,7 +1556,10 @@ bool theory_seq::is_quat_eq(expr_ref_vector const& ls, expr_ref_vector const& rs
} }
/* /*
match: Description TBD match: X..X' abc = Y..Y' mnp Z // flag1 = false
e..X abc = Y..Y' mnp Z // flag1 = true
where Z is a variable or concatenation of variables
*/ */
bool theory_seq::is_ternary_eq(expr_ref_vector const& ls, expr_ref_vector const& rs, bool theory_seq::is_ternary_eq(expr_ref_vector const& ls, expr_ref_vector const& rs,
@ -1732,7 +1602,9 @@ bool theory_seq::is_ternary_eq(expr_ref_vector const& ls, expr_ref_vector const&
} }
/* /*
match: Description TBD match: abc X..X' = Y def Z..Z' // flag1 is false
abc X..e = Y def Z..Z' // flag1 is true
where Y is a variable or concatenation of variables
*/ */
bool theory_seq::is_ternary_eq2(expr_ref_vector const& ls, expr_ref_vector const& rs, bool theory_seq::is_ternary_eq2(expr_ref_vector const& ls, expr_ref_vector const& rs,

View file

@ -462,7 +462,6 @@ namespace smt {
int find_fst_non_empty_idx(expr_ref_vector const& x); int find_fst_non_empty_idx(expr_ref_vector const& x);
expr* find_fst_non_empty_var(expr_ref_vector const& x); expr* find_fst_non_empty_var(expr_ref_vector const& x);
void find_max_eq_len(expr_ref_vector const& ls, expr_ref_vector const& rs);
bool has_len_offset(expr_ref_vector const& ls, expr_ref_vector const& rs, int & diff); bool has_len_offset(expr_ref_vector const& ls, expr_ref_vector const& rs, int & diff);
bool find_better_rep(expr_ref_vector const& ls, expr_ref_vector const& rs, unsigned idx, dependency*& deps, expr_ref_vector & res); bool find_better_rep(expr_ref_vector const& ls, expr_ref_vector const& rs, unsigned idx, dependency*& deps, expr_ref_vector & res);
@ -472,8 +471,8 @@ namespace smt {
bool branch_unit_variable(); // branch on XYZ = abcdef bool branch_unit_variable(); // branch on XYZ = abcdef
bool branch_binary_variable(); // branch on abcX = Ydefg bool branch_binary_variable(); // branch on abcX = Ydefg
bool branch_variable(); // branch on bool branch_variable(); // branch on
bool branch_ternary_variable1(); // branch on XabcY = Zdefg or XabcY = defgZ bool branch_ternary_variable1(); // branch on XabcY = Zdefg
bool branch_ternary_variable2(); // branch on XabcY = defgZmnpq bool branch_ternary_variable2(); // branch on XabcY = defgZ
bool branch_quat_variable(); // branch on XabcY = ZdefgT bool branch_quat_variable(); // branch on XabcY = ZdefgT
bool len_based_split(); // split based on len offset bool len_based_split(); // split based on len offset
bool branch_variable_mb(); // branch on a variable, model based on length bool branch_variable_mb(); // branch on a variable, model based on length