Skip to content

Minimal failing cases for the traversal dedup (for #511) - #516

Merged
jtmaxwell3 merged 1 commit into
add-allMatches-to-Traversefrom
review/pr511-minimal-cases
Sep 21, 2026
Merged

jtmaxwell3 merged 1 commit into
add-allMatches-to-Traversefrom
review/pr511-minimal-cases

Conversation

@johnml1135

@johnml1135 johnml1135 commented Sep 19, 2026 •

Copy link
Copy Markdown
Collaborator

The two minimal cases you asked for, as unit tests on top of add-allMatches-to-Traverse. Both fail on this branch and pass on master — that is intentional; they are here so the failure is inspectable, not to be made green by weakening them.

Each asserts master's behaviour rather than snapshotting the branch's, and each carries a comment explaining what the traversal does differently, since you wanted to see why they fail.

NondeterministicTraversal_DedupOnVariableBindingLosesMatch — pattern high=$v0+, anchored both ends, 5 annotations. The variable makes Matcher.Compile skip determinization, so this runs NondeterministicFsaTraversalMethod. Covering [0,5) needs the run of high- annotations under a single consistent v0. A parallel instance consumes the high+ annotation [0,1), binds v0=+, and dead-ends because nothing starts at offset 1. Both reach the same (State, AnnotationIndex) with different VariableBindings, so the skip can retain the one that can never complete.

master: success=True; range=[0,5); v0=high-
branch: success=False; range=<null>

DeterministicTraversal_DedupOnRegistersShortensMatch — pattern (g0(back=back+)|g1(high=high+ back=back+)), anchored to start, no variables, so this one is determinized (IsDeterministic=True, two groups). Annotation [0,2) satisfies both alternatives' first constraint, so two lineages consume it: one has closed g0, the other still has g1 open. They converge on the same (State, AnnotationIndex) with different open-group registers.

master: success=True; range=[0,4); g0=<uncaptured>, g1=[0,4)
branch: success=True; range=[0,1); g0=[0,1),        g1=<uncaptured>

This second one is the case I'd flag hardest: it is variable-free and on the deterministic path, and it shortens the match range, not just the captures. So a guard of "deterministic method only" would not be sufficient.

Both cases came out of a 20,000-case differential fuzz (fuzz cases 4447 and 15319); I rebuilt them by hand from the recorded annotations rather than depending on the generator. AllMatches().First() was identical between master and this branch in all 20,000 cases, which is what isolates the divergence to the allMatches=false path.

Full SIL.Machine.Tests on this branch: 826 passed, 2 failed (these), 3 skipped — no other regressions.

On a better fix: gating the skip on the deterministic method and the absence of capture groups (!allMatches && Fst.GroupNames.Count() <= 1), with NondeterministicFsaTraversalMethod left as master has it, takes the fuzz to 0 divergences while keeping your instance-count bound cell-for-cell identical on group-free patterns. Whether that is good enough depends on whether the matcher that was hot for you has capture groups — I am measuring that on a build with change-add-to-priority-union and filter-final-templates-in-analysis included, now that I know that is what you measured against.

🤖 Generated with Claude Code


This change is Reviewable

Two hand-built cases distilled from a 20,000-case differential fuzz
(TraversalDedupDifferentialFuzzTests) comparing this branch against
master. Both fail here and pass on master:

- NondeterministicTraversal_DedupOnVariableBindingLosesMatch: an
  anchored high=$v0+ match disappears entirely because two instances
  reach the same (State, AnnotationIndex) with different
  VariableBindings, and the surviving one can never complete.
- DeterministicTraversal_DedupOnRegistersShortensMatch: an alternation
  match is shortened because two lineages converge on the same
  (State, AnnotationIndex) with different open-group registers, and
  the surviving lineage completes earlier than the correct one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jtmaxwell3
jtmaxwell3 merged commit e9e8d12 into add-allMatches-to-Traverse Sep 21, 2026
1 of 3 checks passed
@jtmaxwell3
jtmaxwell3 deleted the review/pr511-minimal-cases branch September 21, 2026 15:05
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.

2 participants