3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-23 06:13:40 +00:00

z3str3: fix value cex in int.to.str model construction

This commit is contained in:
Murphy Berzish 2020-02-28 20:30:09 -05:00 committed by Nikolaj Bjorner
parent 069a5fba16
commit 6ec9f9112c

View file

@ -712,43 +712,45 @@ namespace smt {
eqc_chars.push_back(base_chars.get(pos_value.get_unsigned())); eqc_chars.push_back(base_chars.get(pos_value.get_unsigned()));
} }
return true; return true;
} else if (u.str.is_itos(term, arg0)) { } else if (u.str.is_itos(term, arg0)) {
expr_ref i(arg0, m); expr_ref i(arg0, m);
arith_value v(m); arith_value v(m);
v.init(&get_context()); v.init(&get_context());
rational iValue; rational iValue;
bool iValue_exists = v.get_value(i, iValue); bool iValue_exists = v.get_value(i, iValue);
if (!iValue_exists) { if (!iValue_exists) {
NOT_IMPLEMENTED_YET(); // TODO force assignment in arith solver cex = expr_ref(m.mk_or(m_autil.mk_ge(arg0, mk_int(0)), m_autil.mk_le(arg0, mk_int(0))), m);
} return false;
rational termLen; }
bool termLen_exists = v.get_value(mk_strlen(term), termLen); rational termLen;
if(!termLen_exists) { bool termLen_exists = v.get_value(mk_strlen(term), termLen);
NOT_IMPLEMENTED_YET(); // TODO force assignment in arith solver if(!termLen_exists) {
} cex = expr_ref(m.mk_or(m_autil.mk_ge(mk_strlen(term), mk_int(0)), m_autil.mk_le(mk_strlen(term), mk_int(0))), m);
TRACE("str_fl", tout << "reduce int.to.str: n=" << iValue << std::endl;); return false;
if (iValue.is_neg()) { }
if (!termLen.is_zero()) { TRACE("str_fl", tout << "reduce int.to.str: n=" << iValue << std::endl;);
// conflict if (iValue.is_neg()) {
cex = expr_ref(m.mk_not(m.mk_and(m_autil.mk_le(arg0, mk_int(-1)), m.mk_not(mk_strlen(term)))), m); if (!termLen.is_zero()) {
return false; // conflict
} cex = expr_ref(m.mk_not(m.mk_and(m_autil.mk_le(arg0, mk_int(-1)), m.mk_not(mk_strlen(term)))), m);
// return the empty string return false;
eqc_chars.reset(); }
return true; // return the empty string
} else { eqc_chars.reset();
if (termLen.get_unsigned() != iValue.to_string().length()) { return true;
// conflict } else {
cex = expr_ref(m.mk_not(m.mk_and(get_context().mk_eq_atom(mk_strlen(term), mk_int(termLen)), get_context().mk_eq_atom(arg0, mk_int(iValue)))), m); if (termLen.get_unsigned() != iValue.to_string().length()) {
return false; // conflict
} cex = expr_ref(m.mk_not(m.mk_and(get_context().mk_eq_atom(mk_strlen(term), mk_int(termLen)), get_context().mk_eq_atom(arg0, mk_int(iValue)))), m);
// convert iValue to a constant return false;
zstring iValue_str = zstring(iValue.to_string().c_str()); }
for (unsigned idx = 0; idx < iValue_str.length(); ++idx) { // convert iValue to a constant
expr_ref chTerm(bitvector_character_constants.get(iValue_str[idx]), sub_m); zstring iValue_str = zstring(iValue.to_string().c_str());
eqc_chars.push_back(chTerm); for (unsigned idx = 0; idx < iValue_str.length(); ++idx) {
} expr_ref chTerm(bitvector_character_constants.get(iValue_str[idx]), sub_m);
return true; eqc_chars.push_back(chTerm);
}
return true;
} }
} else { } else {
TRACE("str_fl", tout << "string term " << mk_pp(term, m) << " handled as uninterpreted function" << std::endl;); TRACE("str_fl", tout << "string term " << mk_pp(term, m) << " handled as uninterpreted function" << std::endl;);