Repository navigation
Prune affix template partials whose required slots cannot find their material, in order and at the word edges - #575
johnml1135 wants to merge 5 commits into
Conversation
…erial An analysis template partial now stops as soon as a required slot can no longer find the segments its affix inserts, instead of paying for every optional slot before the required one. The test is used only while every slot walked since is a pure copy-and-insert rule, so parses do not change. A count-only shadow mode and a null-by-default check observer let a harness verify soundness and cost on real grammars. Closes #561 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #575 +/- ##
==========================================
+ Coverage 74.57% 74.79% +0.22%
==========================================
Files 453 454 +1
Lines 38342 38729 +387
Branches 5284 5372 +88
==========================================
+ Hits 28593 28968 +375
Misses 8583 8583
- Partials 1166 1178 +12 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This comment has been minimized.
This comment has been minimized.
…lking a template The required-slot look-ahead now needs each rule's inserted segments to match distinct segments in the order the rule inserts them, a slot that inserts only before or after its copied parts to find that material within the reach of the outer slots' own edge material, and the material of a required ordered slot to lie after the prefix and before the suffix of the required slots that unapply first. Slots that can reorder, repeat or remove from the middle switch the order and edge tests off for the slots behind them. Closes #567 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hed parts are unbounded runs, which restore no segments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…y rules conservatively - Morpher.PruneRequiredSlots turns the prune off (default on); set it before parsing. - Tracing runs the slot rules without pruning, so failure reasons stay. - An allomorph with an untyped constraint is impure and unprunable, so a grammar that compiled before cannot throw. - A boundary-only insertion no longer counts as an infix. - Drop the redundant HasSegmentConstraint guard. - Tests for the optional-node rule, the suffix-side window, empty and deleted unbounded runs, and ordered copies.
This comment has been minimized.
This comment has been minimized.
Centralize opaque required-slot summary updates.
| .ToArray() | ||
| ); | ||
| } | ||
| Assert.That(parses[0], Is.Not.Empty); |
There was a problem hiding this comment.
Major: F10. This test fails once merged with master: on the merge commit 724c90f, both cases fail at this line because the parse with pruning off is empty, so the prune is not the cause. Since master's 98d902a, partial lexical entries no longer set HasPartialRules. The deletion rule leaves the word NonTemplate, and TemplateOf's template defaults to IsFinal, so it is now blocked. CI runs on push, so it tests the head, not the merge. Rebase, then set IsFinal = false here.
|
Verdict: request changes. F8 and F9 are fixed in 07d7dca, but the branch fails a test once merged with master. Most important: F10 (Critical), Counts: 1 new Critical (F10), 0 Important, 0 new Low. Ran: Not verified: I could not run the tests at 07d7dca alone, since a separate worktree was not approved here. That the test passes there rests on the PR body (199/199 at 91ee3da). The cause in F10 comes from reading Public API: Findings: F1 addressed, F2 addressed, F3 addressed, F4 accepted (#598), F5 accepted (#598, unverified), F6 addressed, F7 addressed, F8 addressed, F9 addressed, F10 new. Reviewed at 07d7dca |
Start here:
src/SIL.Machine.Morphology.HermitCrab/RequiredSlotMaterial.cs-- the class remarks (Presence, Order) give the soundness argument for dropping a partial; the rest is wiring.Status: open, review required; head 91ee3da. CI was still running when this was written. #576 and #579 are folded into this branch (both show as merged); #580 (draft) is parked on top and #577 (draft) is parked.
HermitCrab's affix-template walk now drops a partial as soon as a required slot can no longer find the segments its affix inserts. Parses are unchanged; doomed partials stop paying for every optional slot between them and the required one. The slot's literals must appear in the order the rule inserts them and, for prefix-only or suffix-only slots, near the word edge; slots whose unmatched parts are unbounded runs keep being tested. Pruning is on by default;
Morpher.PruneRequiredSlots = falseturns it off (set it before parsing), and tracing never prunes, so failure reasons stay.The question a reviewer arrives with is "does it lose a parse?". Tests assert identical parses with pruning off and on for each hard case, and a shadow pass found 0 violations (carried over, see Evidence). A slot is tested only while every slot walked since is pure, ordered where order is used, and typed; untyped constraints and boundary-only inserts are handled conservatively. The question worth your time is the cost side: the look-ahead has its own unification cost, so whether it pays on real grammars.
Where to look
Apply_ImpureSlotBetween_DoesNotPruneForTheInnerRequiredSlot(purity gate),AnalysisAffixTemplateOrderTests(order and edge windowSlotWalk.Lo/Hi),AnalysisAffixTemplateFusionTests(unbounded runs).RequiredSlotMaterial.RestoredSegmentsagainstAnalysisMorphologicalTransform.Untruncate: an unbounded run must restore nothing, or the purity test is unsound.Apply_Parallel_ReturnsTheSameParsesAsSequential,Apply_Tracing_RunsTheRulesForDetailedFailureInformation.Apply_PublicPruningSwitch_ControlsRuleAttempts,Compile_UntypedConstraints_DisablesTheSummaryConservatively,Apply_BoundaryOnlyInfix_DoesNotMakeReachUnbounded.Not here: the performance follow-ups (repeated shape scans, narrowing, keeping shadow mode) are tracked in #598; #580 is parked; the stack was not re-measured on top of #569, which may reduce its value.
Verification at 91ee3da: HermitCrab tests 199/199 pass (Release);
dotnet csharpierand comment hygiene clean; the HermitCrab project builds with 0 warnings. The fulllocal_check.shdid not complete (cmake is missing for SentencePiece). The measurements below were not re-run at this head.Next: review
RequiredSlotMaterial.cs, and say whether the cost side justifies merging before #569 is measured.Reading this a year from now -- start here
This branch is four commits on master c245476: 0bf9e64 (the required-slot prune, issue #561), 28cbee1 (was PR #576: slot literals in order and at reachable edges, issue #567), faa2499 (was PR #579: keep testing behind slots whose unmatched parts are unbounded runs) and 91ee3da (review fixes). #576 and #579 were separate stacked PRs and were folded in so the look-ahead is reviewed once. All of it runs under the internal
RequiredSlotLookaheadMode(Off,Shadow,On);Morpher.PruneRequiredSlotsis the public on/off view of it. The unification and census counters that produced the numbers below are not in this PR; they live on the research branchesresearch/hc-rsl-census@6ad11702andresearch/hc-ordered-census@4bb687f0.Decisions, and why
RequiredSlotCheckObserver(null by default) are kept for the soundness tests; whether to keep them is part of HermitCrab analysis: measure the required-slot look-ahead's repeated scans, narrowing and shadow diagnostics in steps #598.Untruncatewrites nothing for it, so a slot whose unmatched parts are unbounded runs stays pure. Bounded runs, bare restored segments, alternations with an optional branch andModifyFromInputstay impure.Paths not taken
Evidence (carried over, not re-run at 91ee3da)
All figures are from the bodies of #575, #576 and #579 before the fold, measured on those PRs' own heads (before the review-fix commit; the #579 figures also before #522 removed the analysis memo). They are not from 91ee3da.
Deferred, and what would unblock it
🤖 Generated with Claude Code
This change is