3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-06-29 03:48:51 +00:00

Add interval-based range simplification for ITE conditions

Introduce exclusion intervals alongside the existing path-based condition
tracking in simplify_ite_rec. The intervals track which character values
are still possible at each point in the ITE tree, enabling simplification
of nested range conditions that the per-entry path approach cannot handle.

Key additions:
- intervals_t type and push_intervals() to maintain live character ranges
- eval_range_cond() checks AND-of-char_le conditions against intervals
- intersect_intervals/exclude_interval utilities from seq_rewriter pattern
- Negated AND handling: ¬(lo<=x ∧ x<=hi) excludes [lo,hi] from intervals

The interval check runs before the existing eval_path_cond logic, catching
cases like: if(0<=x<=10, t, if(1<=x<=8, t2, e2)) → if(0<=x<=10, t, e2)
where the inner range [1,8] is fully contained in the excluded outer range.

Fixes remaining regression timeouts on 5728 P2 and 5731 P4.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Nikolaj Bjorner 2026-06-04 16:59:59 -07:00
parent d54d62a07a
commit 6289b91f17
2 changed files with 169 additions and 37 deletions

View file

@ -116,14 +116,19 @@ namespace seq {
// Path of signed conditions for ITE simplification
using path_t = svector<std::pair<expr*, bool>>;
using intervals_t = svector<std::pair<unsigned, unsigned>>;
// Simplify ITE conditions w.r.t. m_ele and path knowledge
expr_ref simplify_ite(expr* d);
expr_ref simplify_ite_rec(path_t& path, expr* d);
std::pair<expr_ref, expr_ref> simplify_ite_rec(path_t& path, expr* c, expr* t, expr* e);
expr_ref simplify_ite_rec(path_t& path, intervals_t& intervals, expr* d);
std::pair<expr_ref, expr_ref> simplify_ite_rec(path_t& path, intervals_t& intervals, expr* c, expr* t, expr* e);
void push_path(path_t& path, expr* c, bool sign);
void push_intervals(intervals_t& intervals, expr* c, bool sign);
lbool eval_cond(expr* cond);
lbool eval_path_cond(path_t const& path, expr* c);
lbool eval_range_cond(intervals_t const& intervals, expr* c);
static void intersect_intervals(unsigned lo, unsigned hi, intervals_t& ranges);
static void exclude_interval(unsigned lo, unsigned hi, intervals_t& ranges, unsigned max_char);
sort* re_sort(expr* r) { return r->get_sort(); }
sort* seq_sort(expr* r) { sort* s = nullptr; m_util.is_re(r, s); return s; }