3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-06-10 19:07:18 +00:00

Bug fixing with unit replacement

This commit is contained in:
CEisenhofer 2026-03-26 15:56:58 +01:00
parent 17ca44b351
commit 3b5b53126e
6 changed files with 33 additions and 20 deletions

View file

@ -196,6 +196,12 @@ namespace seq {
return true;
}
bool nielsen_subst::is_char_subst() const {
SASSERT(m_var && m_replacement);
SASSERT(!m_var->is_unit() || m_replacement->is_char_or_unit());
return m_var->is_unit();
}
// -----------------------------------------------
// nielsen_edge
// -----------------------------------------------
@ -275,6 +281,13 @@ namespace seq {
mem.m_dep = m_graph.dep_mgr().mk_join(mem.m_dep, s.m_dep);
}
}
if (s.m_var->is_unit()) {
SASSERT(s.m_replacement->is_char_or_unit());
expr* v = s.m_var->arg(0)->get_expr();
expr* repl = s.m_replacement->arg(0)->get_expr();
expr* eq = sg.get_manager().mk_eq(v, repl);
m_constraints.push_back(constraint(eq, s.m_dep, sg.get_manager()));
}
}
void nielsen_node::add_char_range(euf::snode* sym_char, char_set const& range) {
@ -1601,14 +1614,12 @@ namespace seq {
eqs[eq_idx] = eqs.back();
eqs.pop_back();
nielsen_subst subst(lt->arg(0), rt->arg(0), eq.m_dep);
nielsen_subst subst(lt, rt, eq.m_dep);
e->add_subst(subst);
child->apply_subst(m_sg, subst);
if (!lhs_rest->is_empty() && !rhs_rest->is_empty())
eqs.push_back(str_eq(lhs_rest, rhs_rest, eq.m_dep));
// NSB review: lt->arg(0) == rt->arg(0) should also be a side constraint
return true;
}
else
@ -3657,6 +3668,8 @@ namespace seq {
svector<std::pair<unsigned, expr*>> lhs_exprs;
for (unsigned i = 0; i < substs.size(); ++i) {
auto const& s = substs[i];
if (s.is_char_subst())
continue;
SASSERT(s.m_var && s.m_var->is_var());
if (!m_seq.is_seq(s.m_var->get_expr()))
continue;

View file

@ -425,12 +425,13 @@ namespace seq {
SASSERT(repl != nullptr);
// var may be s_var or s_power; sgraph::subst uses pointer identity matching
SASSERT(var->is_var() || var->is_power() || var->is_unit());
SASSERT(!var->is_unit());
}
// an eliminating substitution does not contain the variable in the replacement
bool is_eliminating() const;
bool is_char_subst() const;
bool operator==(nielsen_subst const& other) const {
return m_var == other.m_var && m_replacement == other.m_replacement;
}
@ -463,7 +464,7 @@ namespace seq {
// relationships between length variables and power exponents.
// mirrors ZIPT's IntEq / IntLe over Presburger arithmetic polynomials.
struct constraint {
expr_ref fml; // the formula (eq, le, or ge expression)
expr_ref fml; // the formula (eq, le, or ge, unit-diseq expression)
dep_tracker dep; // tracks which input constraints contributed
constraint(ast_manager& m):
@ -479,7 +480,6 @@ namespace seq {
nielsen_node* m_src;
nielsen_node* m_tgt;
vector<nielsen_subst> m_subst;
vector<char_subst> m_char_subst; // character-level substitutions (mirrors ZIPT's SubstC)
vector<constraint> m_side_constraints; // side constraints: integer equalities/inequalities
bool m_is_progress; // does this edge represent progress?
bool m_len_constraints_computed = false; // lazily computed substitution length constraints
@ -496,9 +496,6 @@ namespace seq {
vector<nielsen_subst> const& subst() const { return m_subst; }
void add_subst(nielsen_subst const& s) { m_subst.push_back(s); }
vector<char_subst> const& char_substs() const { return m_char_subst; }
void add_char_subst(char_subst const& s) { m_char_subst.push_back(s); }
void add_side_constraint(constraint const& ic) { m_side_constraints.push_back(ic); }
vector<constraint> const& side_constraints() const { return m_side_constraints; }
@ -580,7 +577,7 @@ namespace seq {
void add_constraint(constraint const &ic);
vector<constraint> const& constraints() const { return m_constraints; }
vector<constraint>& constraints() { return m_constraints; }
vector<constraint>& constraints() { return m_constraints; }
// Query current bounds for a variable from the arithmetic subsolver.
// Falls der Subsolver keinen Bound liefert, werden konservative Defaults

View file

@ -618,12 +618,6 @@ namespace seq {
<< " &#8594; " // mapping arrow
<< snode_label_html(s.m_replacement, m);
}
for (auto const& cs : e->char_substs()) {
if (!first) out << "<br/>";
first = false;
out << "?" << cs.m_var->id()
<< " &#8594; ?" << cs.m_val->id();
}
// side constraints: integer equalities/inequalities
for (auto const& ic : e->side_constraints()) {
if (!first) out << "<br/>";