mirror of
https://github.com/Z3Prover/z3
synced 2026-07-16 20:15:43 +00:00
seq_split: fix derivative-complement soundness+perf via canonical range_predicate
Resolves the WIP soundness bug. Root cause: the char-classes emitted for cofactor conditions were non-canonical and unrecognized downstream (of_pred(lambda) -> opaque select(lambda,ele); raw range unions carried (and true RANGE) that is_char_const_range rejected). Fix: mk_charclass_re maps the cofactor condition (true/false/and/or/not/=/char.<=) to the canonical seq::range_predicate via its Boolean ops, then range_predicate_to_regex (seq_range_collapse.h) yields a canonical char-class regex the derivative/emptiness/primitive path handles natively. Also: derive_of_pred beta-reduces select(lambda,ele) (general of_pred soundness fix). RESULT on gen-lb (119): 0 default disagreements, 0 nseq spurious-unsat. L15 negcount family (27) timeout->solved: e.g. l15-digit-m3-dash now sat in 0.02s (dfs-nodes 33071->55, split complement/max-split-set eliminated). No regression (L11 sat, L14 unsat). Validates the notes.md derivative-based split redesign for star-free complements. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
22eb098cd9
commit
07451d8922
3 changed files with 81 additions and 11 deletions
|
|
@ -427,10 +427,22 @@ namespace seq {
|
|||
expr_ref empty(re().mk_empty(re_sort), m);
|
||||
expr_ref eps(re().mk_to_re(u().str.mk_empty(seq_sort)), m);
|
||||
|
||||
// Apply predicate to the element
|
||||
array_util autil(m);
|
||||
expr* args[2] = { pred, m_ele };
|
||||
expr_ref cond(autil.mk_select(2, args), m);
|
||||
// Apply the predicate to the current element. When `pred` is a lambda,
|
||||
// beta-reduce select(lambda, ele) so the resulting character condition is
|
||||
// in the range/eq form the derivative's condition analysis
|
||||
// (is_char_const_range / eval_path_cond) understands; a raw
|
||||
// (select (lambda ..) ele) would be opaque and mishandled downstream.
|
||||
expr_ref cond(m);
|
||||
if (is_lambda(pred)) {
|
||||
var_subst subst(m);
|
||||
expr* arg = m_ele;
|
||||
cond = subst(to_quantifier(pred)->get_expr(), 1, &arg);
|
||||
}
|
||||
else {
|
||||
array_util autil(m);
|
||||
expr* args[2] = { pred, m_ele };
|
||||
cond = autil.mk_select(2, args);
|
||||
}
|
||||
return mk_ite(cond, eps, empty);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue