3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-07-14 19:15:41 +00:00

Fix sequence foldl nth model propagation

This commit is contained in:
copilot-swe-agent[bot] 2026-07-13 05:01:29 +00:00 committed by GitHub
parent 3bfc2ca0b7
commit 026971075b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 2 deletions

View file

@ -1000,10 +1000,24 @@ bool theory_seq::add_solution(expr* l, expr* r, dependency* deps) {
m_rep.update(l, r, deps);
enode* n1 = ensure_enode(l);
enode* n2 = ensure_enode(r);
ptr_vector<expr> len_parents;
auto collect_len_parents = [&](enode* n) {
for (enode* p : n->get_parents()) {
if (m_util.str.is_length(p->get_expr()))
len_parents.push_back(p->get_expr());
}
};
collect_len_parents(n1);
collect_len_parents(n2);
TRACE(seq, tout << mk_bounded_pp(l, m, 2) << " ==> " << mk_bounded_pp(r, m, 2) << "\n"; display_deps(tout, deps);
tout << "#" << n1->get_owner_id() << " ==> #" << n2->get_owner_id() << "\n";
tout << (n1->get_root() == n2->get_root()) << "\n";);
propagate_eq(deps, n1, n2);
for (expr* len_e : len_parents) {
expr_ref len_r(m_util.str.mk_length(r), m);
m_rewrite(len_r);
propagate_eq(deps, len_e, len_r, false);
}
return true;
}
@ -2632,14 +2646,14 @@ bool theory_seq::expand1(expr* e0, dependency*& eqs, expr_ref& result) {
result = m_util.str.mk_foldli(e1, e2, e3, arg4);
ctx.get_rewriter()(result);
}
#if 0
#if 0
else if (m_util.str.is_nth_i(e, e1, e2)) {
arg1 = try_expand(e1, deps);
if (!arg1) return true;
result = m_util.str.mk_nth_i(arg1, e2);
// m_rewrite(result);
}
#endif
#endif
else if (m_util.str.is_last_index(e, e1, e2)) {
arg1 = try_expand(e1, deps);
arg2 = try_expand(e2, deps);

View file

@ -22,7 +22,9 @@ Tests:
#include "ast/reg_decl_plugins.h"
#include "ast/rewriter/th_rewriter.h"
#include "ast/seq_decl_plugin.h"
#include "api/z3.h"
#include "smt/smt_context.h"
#include <cstring>
#include <iostream>
// Build a single-char string literal expression.
@ -30,6 +32,28 @@ static expr_ref mk_str(ast_manager& m, seq_util& su, unsigned c) {
return expr_ref(su.str.mk_string(zstring(c)), m);
}
static void test_seq_foldl_nth_model_validation() {
Z3_context ctx = Z3_mk_context(nullptr);
char const* result =
Z3_eval_smtlib2_string(ctx,
"(set-option :model_validate true)\n"
"(declare-const initial Int)\n"
"(declare-const all (Seq Int))\n"
"(declare-const final Int)\n"
"(declare-const elements (Seq Int))\n"
"(define-fun all_sums ((prev_sums (Seq Int)) (elem Int)) (Seq Int)\n"
" (seq.++ (seq.unit (+ (seq.nth prev_sums 0) elem)) prev_sums))\n"
"(assert (= all (seq.foldl all_sums (seq.unit initial) elements)))\n"
"(assert (= final (seq.nth all 0)))\n"
"(assert (= initial 0))\n"
"(assert (= final 6))\n"
"(check-sat)\n"
"(get-model)\n");
ENSURE(std::strstr(result, "sat") != nullptr);
ENSURE(std::strstr(result, "invalid model") == nullptr);
Z3_del_context(ctx);
}
void tst_seq_rewriter() {
ast_manager m;
reg_decl_plugins(m);
@ -255,5 +279,7 @@ void tst_seq_rewriter() {
}
}
test_seq_foldl_nth_model_validation();
std::cout << "tst_seq_rewriter: all tests passed\n";
}