3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-03-18 02:53:46 +00:00

Move nseq_regex/state into smt/seq and seq_model into smt/; rename to seq_* prefix (#8984)

* Initial plan

* build verified: nseq_regex moved to smt/seq

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* rename nseq_regex/state/model to seq_regex/state/model in smt/seq; add Clemens Eisenhofer as co-author

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* seq_model: remove theory_nseq dependency; get family_id from seq_util

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Add comments for regex enhancements in seq_model

Added comments regarding future improvements for regex handling.

* Add comments for large exponent handling

Add comments for handling large exponents in seq_model.cpp

* Revise comments for clarity on sort usage

Updated comments to reflect review suggestions regarding the use of the sort of 'n'.

* seq_state: remove sgraph dep; seq_model: use snode sort for is_empty; remove NSB review comments

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Update seq_state.h

* Remove unnecessary include for smt_context.h

* move seq_model from smt/seq/ to smt/; fix seq_state.h add_str_mem typo

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Copilot 2026-03-14 11:45:32 -07:00 committed by GitHub
parent 27f5541b0b
commit 5a3dbaf9f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 172 additions and 164 deletions

View file

@ -21,7 +21,7 @@ Author:
#include "smt/seq/seq_nielsen.h"
#include "smt/seq/seq_parikh.h"
#include "smt/nseq_regex.h"
#include "smt/seq/seq_regex.h"
#include "ast/arith_decl_plugin.h"
#include "ast/ast_pp.h"
#include "ast/rewriter/seq_rewriter.h"
@ -513,13 +513,13 @@ namespace seq {
m_sg(sg),
m_solver(solver),
m_parikh(alloc(seq_parikh, sg)),
m_nseq_regex(alloc(smt::nseq_regex, sg)),
m_seq_regex(alloc(seq::seq_regex, sg)),
m_len_vars(sg.get_manager()) {
}
nielsen_graph::~nielsen_graph() {
dealloc(m_parikh);
dealloc(m_nseq_regex);
dealloc(m_seq_regex);
reset();
}
@ -1798,7 +1798,7 @@ namespace seq {
// and check if the result intersected with the target regex is empty.
// Detects infeasible constraints that would otherwise require
// expensive exploration. Mirrors ZIPT NielsenNode.CheckRegexWidening.
if (g.m_nseq_regex) {
if (g.m_seq_regex) {
for (str_mem const& mem : m_str_mem) {
if (!mem.m_str || !mem.m_regex)
continue;
@ -3290,11 +3290,11 @@ namespace seq {
// 3. Fall back to simple star(R)
euf::snode* stab_base = nullptr;
if (m_nseq_regex && m_nseq_regex->is_self_stabilizing(mem.m_regex)) {
if (m_seq_regex && m_seq_regex->is_self_stabilizing(mem.m_regex)) {
stab_base = mem.m_regex;
}
else if (m_nseq_regex && mem.m_history) {
stab_base = m_nseq_regex->strengthened_stabilizer(mem.m_regex, mem.m_history);
else if (m_seq_regex && mem.m_history) {
stab_base = m_seq_regex->strengthened_stabilizer(mem.m_regex, mem.m_history);
}
if (!stab_base) {
@ -3303,12 +3303,12 @@ namespace seq {
}
// Register the stabilizer
if (m_nseq_regex)
m_nseq_regex->add_stabilizer(mem.m_regex, stab_base);
if (m_seq_regex)
m_seq_regex->add_stabilizer(mem.m_regex, stab_base);
// Check if stabilizer equals regex → self-stabilizing
if (m_nseq_regex && stab_base == mem.m_regex)
m_nseq_regex->set_self_stabilizing(mem.m_regex);
if (m_seq_regex && stab_base == mem.m_regex)
m_seq_regex->set_self_stabilizing(mem.m_regex);
// Build stab_star = star(stab_base)
expr* stab_expr = stab_base->get_expr();
@ -3320,7 +3320,7 @@ namespace seq {
continue;
// Try subsumption: if L(x_range) ⊆ L(stab_star), drop the constraint
if (m_nseq_regex && m_nseq_regex->try_subsume(mem, *node))
if (m_seq_regex && m_seq_regex->try_subsume(mem, *node))
continue;
// Create child: x → pr · po
@ -4281,7 +4281,7 @@ namespace seq {
bool nielsen_graph::check_regex_widening(nielsen_node const& node,
euf::snode* str, euf::snode* regex) {
if (!str || !regex || !m_nseq_regex)
if (!str || !regex || !m_seq_regex)
return false;
// Only apply to ground regexes with non-trivial strings
if (!regex->is_ground())
@ -4313,7 +4313,7 @@ namespace seq {
}
else if (tok->is_var()) {
// Variable → intersection of primitive regex constraints, or Σ*
euf::snode* x_range = m_nseq_regex->collect_primitive_regex_intersection(tok, node);
euf::snode* x_range = m_seq_regex->collect_primitive_regex_intersection(tok, node);
if (x_range) {
tok_re = x_range;
} else {
@ -4389,7 +4389,7 @@ namespace seq {
if (!inter_sn)
return false;
lbool result = m_nseq_regex->is_empty_bfs(inter_sn, 5000);
lbool result = m_seq_regex->is_empty_bfs(inter_sn, 5000);
return result == l_true;
}
@ -4399,7 +4399,7 @@ namespace seq {
// -----------------------------------------------------------------------
bool nielsen_graph::check_leaf_regex(nielsen_node const& node) {
if (!m_nseq_regex)
if (!m_seq_regex)
return true;
// Group str_mem constraints by variable (primitive constraints only)
@ -4421,7 +4421,7 @@ namespace seq {
for (auto& [var_id, regexes] : var_regexes) {
if (regexes.size() < 2)
continue;
lbool result = m_nseq_regex->check_intersection_emptiness(regexes, 5000);
lbool result = m_seq_regex->check_intersection_emptiness(regexes, 5000);
if (result == l_true) {
// Intersection is empty — infeasible
return false;