Introduces a first-class AST kind OP_RE_CHARCLASS for ground char-class
regexes, encoded as a nullary op with 2N int parameters that name the
sorted, disjoint, non-adjacent ranges of its predicate. The seq decl
plugin owns the construction and validation; seq_rewriter lifts existing
re.range / re.empty / re.full_char into CHARCLASS and collapses
union/intersection/difference of CHARCLASS-like operands into a single
node via seq::range_predicate.
Highlights:
* Move range_predicate.{h,cpp} from ast/rewriter/ into ast/ so the seq
plugin can use it.
* mk_re_union / mk_re_inter / mk_re_diff and mk_regex_union_normalize /
mk_regex_inter_normalize all short-circuit to a single CHARCLASS when
both operands are charclass-like.
* mk_re_range lifts concrete-bounded ranges at construction.
* mk_antimirov_deriv_rec and mk_derivative_rec both handle the CHARCLASS
case so derivatives reduce normally during simplification and bisim.
* is_nullable_rec, get_info_rec, can_skip_parenth, and the rex pretty
printer all recognise the new kind.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Introduce a specialized range-algebra over the unsigned character
domain [0, max_char], with canonical sorted-disjoint-non-adjacent
representation and linear-time union, intersection, complement,
difference, and symmetric difference operations.
This is Stage 1 of the derive-with-ranges plan: the value type only,
with unit tests covering factories, ordering, hashing, hand-picked
instances, and exhaustive de-Morgan / lattice laws over a small
domain (verified by enumerating all 64 subsets).
Integration with seq::derive's path conditions, the OneStep cache,
and the R&psi smart-constructor rewrite are deferred to later stages.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>