mirror of
https://github.com/Z3Prover/z3
synced 2025-08-20 18:20:22 +00:00
Merge branch 'str-at-semantics' into develop
This commit is contained in:
commit
94d5f242b8
35 changed files with 799 additions and 66 deletions
|
@ -315,6 +315,8 @@ protected:
|
|||
template<bool ProofGen>
|
||||
void process_app(app * t, frame & fr);
|
||||
|
||||
bool constant_fold(app* t, frame& fr);
|
||||
|
||||
template<bool ProofGen>
|
||||
void process_quantifier(quantifier * q, frame & fr);
|
||||
|
||||
|
|
|
@ -174,6 +174,38 @@ bool rewriter_tpl<Config>::visit(expr * t, unsigned max_depth) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename Config>
|
||||
bool rewriter_tpl<Config>::constant_fold(app * t, frame & fr) {
|
||||
if (fr.m_i == 1 && m().is_ite(t)) {
|
||||
expr * cond = result_stack()[fr.m_spos].get();
|
||||
expr* arg = 0;
|
||||
if (m().is_true(cond)) {
|
||||
arg = t->get_arg(1);
|
||||
}
|
||||
else if (m().is_false(cond)) {
|
||||
arg = t->get_arg(2);
|
||||
}
|
||||
if (arg) {
|
||||
result_stack().shrink(fr.m_spos);
|
||||
result_stack().push_back(arg);
|
||||
fr.m_state = REWRITE_BUILTIN;
|
||||
unsigned max_depth = fr.m_max_depth;
|
||||
if (visit<false>(arg, fr.m_max_depth)) {
|
||||
m_r = result_stack().back();
|
||||
result_stack().pop_back();
|
||||
result_stack().pop_back();
|
||||
result_stack().push_back(m_r);
|
||||
cache_result<false>(t, m_r, m_pr, fr.m_cache_result);
|
||||
frame_stack().pop_back();
|
||||
set_new_child_flag(t);
|
||||
}
|
||||
m_r = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Config>
|
||||
template<bool ProofGen>
|
||||
void rewriter_tpl<Config>::process_app(app * t, frame & fr) {
|
||||
|
@ -183,10 +215,15 @@ void rewriter_tpl<Config>::process_app(app * t, frame & fr) {
|
|||
case PROCESS_CHILDREN: {
|
||||
unsigned num_args = t->get_num_args();
|
||||
while (fr.m_i < num_args) {
|
||||
if (!ProofGen && constant_fold(t, fr)) {
|
||||
return;
|
||||
}
|
||||
expr * arg = t->get_arg(fr.m_i);
|
||||
fr.m_i++;
|
||||
if (!visit<ProofGen>(arg, fr.m_max_depth))
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
func_decl * f = t->get_decl();
|
||||
|
||||
|
|
|
@ -632,14 +632,25 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) {
|
|||
return BR_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* (str.at s i), constants s/i, i < 0 or i >= |s| ==> (str.at s i) = ""
|
||||
*/
|
||||
br_status seq_rewriter::mk_seq_at(expr* a, expr* b, expr_ref& result) {
|
||||
zstring c;
|
||||
rational r;
|
||||
if (m_util.str.is_string(a, c) && m_autil.is_numeral(b, r) && r.is_unsigned()) {
|
||||
unsigned j = r.get_unsigned();
|
||||
if (j < c.length()) {
|
||||
result = m_util.str.mk_string(c.extract(j, 1));
|
||||
if (m_util.str.is_string(a, c) && m_autil.is_numeral(b, r)) {
|
||||
if (r.is_neg()) {
|
||||
result = m_util.str.mk_string(symbol(""));
|
||||
return BR_DONE;
|
||||
} else if (r.is_unsigned()) {
|
||||
unsigned j = r.get_unsigned();
|
||||
if (j < c.length()) {
|
||||
result = m_util.str.mk_string(c.extract(j, 1));
|
||||
return BR_DONE;
|
||||
} else {
|
||||
result = m_util.str.mk_string(symbol(""));
|
||||
return BR_DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return BR_FAILED;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue