Skip to content

Add neural synthesis for simple regex generation - #20

Merged
alexvbrdn merged 6 commits into
mainfrom
add-neural-synthesis
Oct 10, 2026
Merged

alexvbrdn merged 6 commits into
mainfrom
add-neural-synthesis

Conversation

@alexvbrdn

@alexvbrdn alexvbrdn commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

What this changes

Adds an optional neural-synthesis feature, off by default. It converts automata to regexes with a learned model (Kleene), which gives shorter, more readable patterns than state elimination. Every pattern the model proposes is checked against the automaton, so the result is never wrong.

  • New RegexSynthesizer trait, plus to_regex_with on FastAutomaton and Term.
  • NeuralSynthesizer loads models from files or from the Hugging Face Hub (neural-synthesis-hub), and can run on a GPU.
  • evaluate_complexity now scores how hard a pattern is to read, and state elimination uses that score too, so some to_regex outputs change (about 9% shorter on the test corpus).

Checklist

  • cargo fmt --all --check and cargo clippy --all-targets -- -D warnings pass
  • cargo test and cargo test --no-default-features pass
  • New public items are documented
  • A test covers the change
  • CHANGELOG.md is updated under ## [Unreleased]
  • The change builds on Rust 1.88, or the MSRV bump is intentional and noted

Adds the optional `neural-synthesis` feature (off by default):
`FastAutomaton::to_regex_with` and `Term::to_regex_with` convert an
automaton with the help of a learned model, a
`neural_synthesis::NeuralSynthesizer`. Every candidate the model
proposes
is checked for equivalence before use, and the simpler of the verified
proposal and state elimination's regex is returned, so the result is
never
wrong.

Models are loaded from `config.json` and `model.safetensors`, or from
the
Hugging Face Hub with `neural-synthesis-hub`, and run with candle on the
CPU or a GPU (`-cuda`, `-cudnn`, `-metal`; `-mkl` and `-accelerate` for
the CPU). The first supported format is `kleene` v1, for minimal DFAs of
at most 16 states and 16 bases. The module lives next to state
elimination, in `fast_automaton/convert/to_regex/neural_synthesis`, and
is
re-exported as `regexsolver::neural_synthesis`.

`RegularExpression::evaluate_complexity` now returns the cognitive
complexity the models are trained to minimize, computed iteratively.
State elimination orders eliminations by it too, which shortens patterns
converted from DFAs by about 9% over the test corpus.

CI and CONTRIBUTING.md also lint, test and document the crate with
`neural-synthesis-hub`.
`FastAutomaton::to_regex_with` and `Term::to_regex_with` take any
`fast_automaton::RegexSynthesizer`: `StateElimination`, the conversion
`to_regex` uses (now documented as such), `NeuralSynthesizer`, or a
dependent's own. They no longer need the `neural-synthesis` feature.

When the model has no correct regex for an automaton, or the automaton
is beyond its limits, `NeuralSynthesizer` splits the minimal DFA into
independent pieces (star, concatenation, frontier, union and hub
splits, all exact), converts each by the model or state elimination,
whichever is simpler, and combines their regexes.
`with_decomposition(false)` turns this off. Over automata of 17 to 80
states from set operations, the result is simpler than state
elimination's for 74% of them, at about half its complexity (geometric
mean).

The model runs on several automata at once (`propose_batch`): the
encoder runs all their graphs together, and the decoder keeps its
self-attention cache in place and computes attention in one fused pass
on the CPU. Decoding is up to 2.8x faster, and decomposition about
twice as fast. Each sampled candidate has its own generator, so a
seed's samples differ from before; greedy decoding is unchanged.

CI tests neural synthesis on wasm: on `wasm32-unknown-unknown`, in a
module with no imports, so with no source of randomness, using a tiny
untrained model (`tests/data/kleene_tiny`); on `wasm32-wasip1`, with
the rest of the tests.
@alexvbrdn alexvbrdn self-assigned this Oct 10, 2026
@alexvbrdn
alexvbrdn merged commit 3de8636 into main Oct 10, 2026
8 checks passed
@alexvbrdn
alexvbrdn deleted the add-neural-synthesis branch October 10, 2026 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant