3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-04-19 18:33:35 +00:00

Added classical regex factorization

This commit is contained in:
CEisenhofer 2026-04-02 20:03:22 +02:00
parent 3ca960d679
commit a81ce477f5
8 changed files with 258 additions and 6 deletions

View file

@ -390,6 +390,38 @@ namespace smt {
expr* s_expr = mem.m_str->get_expr();
if (s_expr)
ensure_length_var(s_expr);
if (!get_fparams().m_nseq_regex_factorization)
return;
// Boolean Closure Propagations
expr* re_expr = mem.m_regex->get_expr();
if (m_seq.re.is_intersection(re_expr)) {
for (expr* arg : *to_app(re_expr)) {
expr_ref in_r(m_seq.re.mk_in_re(s_expr, arg), m);
literal_vector lits;
lits.push_back(~mem.lit);
lits.push_back(mk_literal(in_r));
ctx.mk_th_axiom(get_id(), lits.size(), lits.data());
}
}
else if (m_seq.re.is_union(re_expr)) {
literal_vector lits;
lits.push_back(~mem.lit);
for (expr* arg : *to_app(re_expr)) {
expr_ref in_r(m_seq.re.mk_in_re(s_expr, arg), m);
lits.push_back(mk_literal(in_r));
}
ctx.mk_th_axiom(get_id(), lits.size(), lits.data());
}
else if (m_seq.re.is_complement(re_expr)) {
expr* arg = to_app(re_expr)->get_arg(0);
expr_ref in_r(m_seq.re.mk_in_re(s_expr, arg), m);
literal_vector lits;
lits.push_back(~mem.lit);
lits.push_back(~mk_literal(in_r));
ctx.mk_th_axiom(get_id(), lits.size(), lits.data());
}
}
void theory_nseq::ensure_length_var(expr* e) {
@ -578,6 +610,7 @@ namespace smt {
m_nielsen.set_max_nodes(get_fparams().m_nseq_max_nodes);
m_nielsen.set_parikh_enabled(get_fparams().m_nseq_parikh);
m_nielsen.set_signature_split(get_fparams().m_nseq_signature);
m_nielsen.set_regex_factorization(get_fparams().m_nseq_regex_factorization);
// Regex membership pre-check: before running DFS, check intersection
// emptiness for each variable's regex constraints. This handles
@ -1221,6 +1254,7 @@ namespace smt {
lbool result = m_regex.check_intersection_emptiness(regexes);
if (result == l_true) {
// TODO: Incorporate that we might know the maximum length generated by a regex [in those cases, the gradients will never work]
// It is empty. Try gradient.
regexes.pop_back(); // Remove loop_l