mirror of
https://github.com/Z3Prover/z3
synced 2026-07-17 04:25:44 +00:00
`seq_rewriter::is_subset` was too localized and missed key subset
implications for regex concatenations. This change extracts subset
reasoning into a dedicated component and adds heuristic
closure/monotonicity rules, then tunes the recursion strategy based on
profiling feedback.
- **Architecture: isolate subset reasoning**
- Introduce `seq_subset` in `src/ast/rewriter` (`seq_subset.h/.cpp`).
- Add `seq_subset` as an attribute on `seq_rewriter` and route
`seq_rewriter::is_subset` through it.
- Keep `seq_rewriter` focused on rewrite orchestration while subset
logic evolves independently.
- **Subset rules: broaden inferable cases**
- Add derive-style subset decomposition across `union`, `intersection`,
`complement`, `concat`, and bounded `loop`.
- Add E3-style closure rules:
- `R ⊆ R*`
- `R1* ⊆ R2* ⇐ R1 ⊆ R2`
- `R1+ ⊆ R2+ ⇐ R1 ⊆ R2`
- Add missing cheap cases:
- `ε ⊆ R` when `R` is nullable
- `R ⊆ R+`
- `R+ ⊆ R*`
- Range containment: `[c1–c2] ⊆ [c3–c4]` when `c3 ≤ c1 ∧ c2 ≤ c4`
- `to_re(s) ⊆ range` for single-character string constants
- Difference monotonicity: `a1 \ a2 ⊆ b` when `a1 ⊆ b`
- Star absorption checks for concat/star combinations (`R·R* ⊆ R*`,
`R*·R ⊆ R*`)
- Preserve nullable-based `. +` handling and top/bottom regular-language
shortcuts.
- **Concatenation reasoning and traversal tuning**
- Remove `flatten_concat` and assume right-associative concatenation
traversal.
- Keep containment shortcuts for both `R ⊆ Σ*·R'` and `R ⊆ R'·Σ*` when
`R ⊆ R'`.
- Make concat/concat handling tail-recursive on second arguments.
- **Depth-bounded recursion (profiling follow-up)**
- Replace visited-pair hash-table recursion state with an explicit depth
parameter in `is_subset_rec`.
- Add `m_max_depth = 3` and return `false` when the bound is reached.
- Increment depth on recursive calls, except for the tail-recursive
concat-second-argument step.
- **Build integration**
- Register `seq_subset.cpp` in `src/ast/rewriter/CMakeLists.txt`.
```cpp
// seq_rewriter.cpp
bool seq_rewriter::is_subset(expr* r1, expr* r2) const {
return m_subset.is_subset(r1, r2);
}
```
---------
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
|
||
|---|---|---|
| .. | ||
| bit_blaster | ||
| arith_rewriter.cpp | ||
| arith_rewriter.h | ||
| array_rewriter.cpp | ||
| array_rewriter.h | ||
| ast_counter.cpp | ||
| ast_counter.h | ||
| bit2int.cpp | ||
| bit2int.h | ||
| bool_rewriter.cpp | ||
| bool_rewriter.h | ||
| bv2int_translator.cpp | ||
| bv2int_translator.h | ||
| bv_bounds.cpp | ||
| bv_bounds.h | ||
| bv_bounds_base.h | ||
| bv_elim.cpp | ||
| bv_elim.h | ||
| bv_rewriter.cpp | ||
| bv_rewriter.h | ||
| cached_var_subst.cpp | ||
| cached_var_subst.h | ||
| char_rewriter.cpp | ||
| char_rewriter.h | ||
| CMakeLists.txt | ||
| datatype_rewriter.cpp | ||
| datatype_rewriter.h | ||
| der.cpp | ||
| der.h | ||
| distribute_forall.cpp | ||
| distribute_forall.h | ||
| dl_rewriter.cpp | ||
| dl_rewriter.h | ||
| dom_simplifier.cpp | ||
| dom_simplifier.h | ||
| elim_bounds.cpp | ||
| elim_bounds.h | ||
| enum2bv_rewriter.cpp | ||
| enum2bv_rewriter.h | ||
| expr_replacer.cpp | ||
| expr_replacer.h | ||
| expr_safe_replace.cpp | ||
| expr_safe_replace.h | ||
| factor_equivs.cpp | ||
| factor_equivs.h | ||
| factor_rewriter.cpp | ||
| factor_rewriter.h | ||
| finite_set_axioms.cpp | ||
| finite_set_axioms.h | ||
| finite_set_rewriter.cpp | ||
| finite_set_rewriter.h | ||
| fpa_rewriter.cpp | ||
| fpa_rewriter.h | ||
| func_decl_replace.cpp | ||
| func_decl_replace.h | ||
| inj_axiom.cpp | ||
| inj_axiom.h | ||
| label_rewriter.cpp | ||
| label_rewriter.h | ||
| macro_replacer.cpp | ||
| macro_replacer.h | ||
| maximize_ac_sharing.cpp | ||
| maximize_ac_sharing.h | ||
| mk_extract_proc.cpp | ||
| mk_extract_proc.h | ||
| mk_simplified_app.cpp | ||
| mk_simplified_app.h | ||
| pb2bv_rewriter.cpp | ||
| pb2bv_rewriter.h | ||
| pb_rewriter.cpp | ||
| pb_rewriter.h | ||
| pb_rewriter_def.h | ||
| poly_rewriter.h | ||
| poly_rewriter_def.h | ||
| push_app_ite.cpp | ||
| push_app_ite.h | ||
| quant_hoist.cpp | ||
| quant_hoist.h | ||
| recfun_replace.h | ||
| recfun_rewriter.cpp | ||
| recfun_rewriter.h | ||
| rewriter.cpp | ||
| rewriter.h | ||
| rewriter.txt | ||
| rewriter_def.h | ||
| rewriter_types.h | ||
| seq_axioms.cpp | ||
| seq_axioms.h | ||
| seq_eq_solver.cpp | ||
| seq_eq_solver.h | ||
| seq_rewriter.cpp | ||
| seq_rewriter.h | ||
| seq_skolem.cpp | ||
| seq_skolem.h | ||
| seq_subset.cpp | ||
| seq_subset.h | ||
| th_rewriter.cpp | ||
| th_rewriter.h | ||
| value_sweep.cpp | ||
| value_sweep.h | ||
| var_subst.cpp | ||
| var_subst.h | ||