docs(algorithm): update walk algorithm documentation for Viterbi - #785
docs(algorithm): update walk algorithm documentation for Viterbi#785tianjianjiang wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the algorithm.md documentation to accurately reflect the Viterbi algorithm implementation that replaced the previous DAG shortest-path approach in PR #777. The documentation now describes a streamlined 2-step process (forward pass with relaxation + backward path reconstruction) instead of the previous 4-step DAG algorithm.
Changes:
- Replaced DAG shortest-path algorithm documentation with Viterbi algorithm explanation
- Updated TOC link from "最佳路徑演算法:DAG 最短路徑" to "最佳路徑演算法:Viterbi"
- Removed code reference table entries for deprecated
TopologicalSort()andRelax()functions - Updated reading references to cite Jurafsky & Martin's textbook and vene.ro lattice Viterbi resource
- Bumped document version to 1.3 with updated timestamp
fb72feb to
15820a9
Compare
|
Claude Code Review Failed The automated Claude review encountered an error and could not complete. You can:
This does not affect the PR approval process. |
6106a7a to
e246baa
Compare
15820a9 to
02b06d1
Compare
There was a problem hiding this comment.
Critical Issues
Line reference error: The main walk() method reference points to line 216, but the actual implementation is at line 132. This must be corrected.
Code snippet accuracy: The documentation code snippets omit important implementation details (comments, assertions, metrics tracking) that exist in the actual code. While educational simplification is reasonable, key correctness guarantees like the totalReadingLen assertion should be included.
All other aspects (algorithm description, complexity analysis, reference updates) appear correct and consistent with the merged Viterbi implementation in #777.
e246baa to
c9154c8
Compare
02b06d1 to
104108a
Compare
There was a problem hiding this comment.
Reviewed documentation update for Viterbi algorithm. Found two critical issues requiring attention:
- Missing line number reference in code reference table (inconsistent with other entries)
- Unverified complexity and performance claims that need fact-checking against PR #777 or removal
The code snippets accurately match the implementation in reading_grid.cpp:132-198.
c9154c8 to
8df0535
Compare
325ef66 to
4f90773
Compare
|
Claude Code Review Failed The automated Claude review encountered an error and could not complete. You can:
This does not affect the PR approval process. |
4f90773 to
8b213a9
Compare
8df0535 to
0ab7122
Compare
8b213a9 to
eedacac
Compare
|
Claude Code Review Failed The automated Claude review encountered an error and could not complete. You can:
This does not affect the PR approval process. |
0ab7122 to
edb593e
Compare
eedacac to
16b1f7d
Compare
edb593e to
d39c375
Compare
16b1f7d to
bb597f0
Compare
|
Claude Code Review Failed The automated Claude review encountered an error and could not complete. You can:
This does not affect the PR approval process. |
d39c375 to
05b59d5
Compare
bb597f0 to
004f316
Compare
There was a problem hiding this comment.
Documentation-only PR. Two issues found:
-
Non-existent file references (critical): The new "演算法擴展" table references
walk_strategy.h/cppandcontextual_user_model.h/cpp, which don't exist inmaster. These are forward references to files introduced by downstream PRs (#779–#781). Merging this PR as-is leaves broken references in the documentation. -
Version number mismatch: PR description says "Bump to 1.3" but the diff sets
**文件版本**:2.1.
The Viterbi algorithm description, pseudocode, complexity analysis, and example table are all technically accurate and match the actual implementation in reading_grid.cpp.
|
Claude Code Review Failed The automated Claude review encountered an error and could not complete. You can:
This does not affect the PR approval process. |
004f316 to
87bac41
Compare
There was a problem hiding this comment.
This is a documentation-only PR. Three issues found:
1. "演算法擴展" table references unmerged PRs (critical for readers)
The table entries for walk_strategy.h/cpp (PR #779) and contextual_user_model.h/cpp (PR #780) point to files that don't exist in master yet. This breaks the PR's own test plan item: "Verify code snippets match master:Source/Engine/...". Suggest labeling these rows as pending or deferring them to a follow-up doc PR after #779/#780 land.
2. VITERBI-BACKWARD: no guard against nil fromNode
If walk() is ever called when no complete path exists through the lattice, the backward pass silently appends nil nodes. In normal operation insertReading prevents this via hasUnigrams, but the pseudocode should document the precondition. Inline suggestion added.
3. VITERBI-FORWARD: unreachable positions not skipped
Minor clarity/performance issue — iterating over positions with maxScore = -infinity is harmless but obscures the invariant. Inline suggestion added.
The algorithm descriptions, KN smoothing formulas, and complexity analysis all look technically correct.
Describe the forward-pass Viterbi DP walk (PR #777) with verified file/line references against current master, an O(|V| + |E|) complexity analysis matching the implementation comment, and measured stress-test numbers (vertices/edges from WalkResult). Replace the dropped WalkStrategy/fixedSpans walk-integration design with the actual candidate-override mechanism (overrideCandidate plus re-walk), and align the contextual user model section with the shipped ContextualUserModel design (PR #780): two-level interpolated Kneser-Ney with per-reading continuation normalization, wall-clock decay with a 5400-second half-life, LRU capacity bound, TSV persistence, and implicit base-LM fallback via empty suggestions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
87bac41 to
8175575
Compare
There was a problem hiding this comment.
Documentation-only PR; no code correctness or security concerns. Three issues found:
-
Unreleased code referenced — The new
情境式使用者模型section and演算法擴展table documentContextualUserModelfrom PRs #780/#781, which are not yet inmaster. This breaks the PR's own test-plan item ("Verify code snippets matchmaster:…") and will mislead readers who follow the file paths. -
Version number mismatch — PR description says "Bump to 1.3" but the document is set to 1.4.
-
Missing precondition on backward-pass pseudocode — The assert
viterbi[curr].fromNode is not nilis correct but relies on an implicit invariant (every position is reachable) that is only guaranteed becauseinsertReading()validates unigrams. Worth documenting inline so the invariant is explicit.
|
|
||
| --- | ||
|
|
||
| ## 情境式使用者模型 |
There was a problem hiding this comment.
Documentation accuracy: references unreleased code
The new 情境式使用者模型 section (and the 演算法擴展 table later) explicitly references Source/Engine/ContextualUserModel.h / .cpp from PR #780, and Source/KeyHandler.mm changes from PR #781 — neither of which is merged into master yet.
This means:
- The test plan item "Verify code snippets match
master:Source/Engine/gramambular2/reading_grid.cpp" cannot pass for this section (the referenced files don't exist onmaster). - Readers on
masterwho follow the file paths will find nothing.
Suggestion: Either gate this section behind a clearly marked callout ("Planned in PR #780, not yet merged"), or extract it into a separate follow-up PR that is stacked on #780/#781.
| - [X/Twitter 演算法說明串](https://x.com/McBopomofo/status/1559356063622631424) | ||
| - DAG 最短路徑演算法:Cormen et al., *Introduction to Algorithms*, 3rd Edition | ||
|
|
||
| --- |
There was a problem hiding this comment.
Version number mismatch with PR description
The PR summary says "Bump document version to 1.3", but this line sets it to 1.4, skipping 1.3 entirely. Either the PR description or the version number is wrong.
| --- | |
| **文件版本**:1.3 |
| | 轉移機率 | $a_{ij}$(狀態間轉移) | 隱含 = 1(無 bigram 模型) | | ||
| | 發射機率 | $b_j(o_t)$ | `node->score()`(unigram 對數機率) | | ||
| | DP 遞迴式 | $v_t(j) = \max_i [v_{t-1}(i) \cdot a_{ij} \cdot b_j(o_t)]$ | `viterbi[i+L] = max(viterbi[i] + score)` | | ||
| | DP 表格形狀 | N x T(狀態數 x 時間步) | 一維:n+1 個位置 | |
There was a problem hiding this comment.
Correctness: backward-pass assertion can fail on an empty or unreachable grid
The pseudocode asserts viterbi[curr].fromNode is not nil unconditionally before dereferencing it. If readingLen > 0 but position readingLen was never reached (e.g. there is a gap in the lattice — though the insertReading guard makes this unlikely in practice), the assert fires without any explanation.
Consider adding a precondition note so readers understand the invariant being relied upon:
| | DP 表格形狀 | N x T(狀態數 x 時間步) | 一維:n+1 個位置 | | |
| // Precondition: every position 1..readingLen must be reachable; | |
| // insertReading() guarantees this by rejecting readings with no unigrams. | |
| curr = readingLen | |
| while curr > 0: | |
| assert viterbi[curr].fromNode is not nil | |
| append viterbi[curr].fromNode to nodes | |
| curr = viterbi[curr].fromIndex |
Summary
algorithm.mdwith the Viterbi implementation merged in Refactor DAG shortest path algorithm using Viterbi #777#785 (independent, base: master)
Test plan
master:Source/Engine/gramambular2/reading_grid.cppGenerated with Claude Code