Skip to content

Commit d2df8c0

Browse files
committed
Continue patching UOM APIs.
1 parent c1dffcc commit d2df8c0

File tree

3 files changed

+38
-11
lines changed

3 files changed

+38
-11
lines changed

Sources/Megrez/3_KeyValuePaired.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,10 @@ extension Megrez {
403403

404404
// 選擇用來形成觀測 key 的資料源:長→短使用 after,其他使用 before
405405
let keySource = isBreakingUp ? currentAssembled : previouslyAssembled
406-
let keyCursorRaw = Swift.max(afterHit.range.lowerBound, afterHit.range.upperBound - 1)
406+
let keyCursorRaw = Swift.max(
407+
afterHit.range.lowerBound,
408+
Swift.min(cursor, afterHit.range.upperBound - 1)
409+
)
407410
guard keySource.totalKeyCount > 0 else { return nil }
408411
let keyCursor = Swift.max(0, Swift.min(keyCursorRaw, keySource.totalKeyCount - 1))
409412

Sources/Megrez/8_GramInPath.swift

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,15 +159,27 @@ extension Array where Element == Megrez.GramInPath {
159159
maxContext: Int = 3
160160
)
161161
-> (ngramKey: String, candidate: String, headReading: String)? {
162-
let perceptedGIP: Megrez.GramInPath?
163-
if let cursor, (0 ..< self.totalKeyCount).contains(cursor) {
164-
perceptedGIP = findGram(at: cursor)?.gram
162+
let headInfo: (pair: Megrez.GramInPath, range: Range<Int>)?
163+
let resolvedCursor: Int
164+
if let cursor, (0 ..< totalKeyCount).contains(cursor), let hit = findGram(at: cursor) {
165+
headInfo = (pair: hit.gram, range: hit.range)
166+
resolvedCursor = Swift.max(hit.range.lowerBound, Swift.min(cursor, hit.range.upperBound - 1))
167+
} else if let tail = last {
168+
let lowerBound = totalKeyCount - tail.keyArray.count
169+
headInfo = (pair: tail, range: lowerBound ..< totalKeyCount)
170+
resolvedCursor = Swift.max(lowerBound, totalKeyCount - 1)
165171
} else {
166-
perceptedGIP = last
172+
headInfo = nil
173+
resolvedCursor = 0
167174
}
168-
guard let perceptedGIP else { return nil }
175+
guard let headInfo else { return nil }
176+
let headPair = headInfo.pair
177+
let headRange = headInfo.range
178+
let headKeyOffset = Swift.max(0, resolvedCursor - headRange.lowerBound)
179+
guard headPair.keyArray.indices.contains(headKeyOffset) else { return nil }
180+
169181
var arrGIPs = self
170-
while arrGIPs.last?.gram !== perceptedGIP.gram { arrGIPs.removeLast() }
182+
while arrGIPs.last?.gram !== headPair.gram { arrGIPs.removeLast() }
171183
var isHead = true
172184
var outputCells = [String]()
173185
loopProc: while !arrGIPs.isEmpty, let frontendPair = arrGIPs.last {
@@ -178,10 +190,17 @@ extension Array where Element == Megrez.GramInPath {
178190
guard !frontendPair.isReadingMismatched else { return nil }
179191
guard !frontendPair.value.isEmpty else { return nil }
180192
guard !frontendPair.keyArray.joined().isEmpty else { return nil }
193+
if isHead {
194+
let index = headKeyOffset
195+
guard frontendPair.keyArray.indices.contains(index) else { return nil }
196+
let key = frontendPair.keyArray[index]
197+
guard !key.contains("_") else { return nil }
198+
return key
199+
}
181200
let keyChain = frontendPair.keyArray.joined(separator: "-")
182201
guard !keyChain.contains("_") else { return nil }
183202
// 前置單元只記錄讀音,在其後的單元則同時記錄讀音與字詞
184-
return isHead ? keyChain : "(\(keyChain):\(frontendPair.value))"
203+
return "(\(keyChain):\(frontendPair.value))"
185204
}
186205

187206
guard let keyCellStr = makeNGramKeyCell(isHead: isHead) else { break loopProc }
@@ -190,10 +209,11 @@ extension Array where Element == Megrez.GramInPath {
190209
if isHead { isHead = false }
191210
}
192211
guard !outputCells.isEmpty else { return nil }
212+
let headReading = headPair.keyArray[headKeyOffset]
193213
return (
194214
"(\(outputCells.joined(separator: ",")))",
195-
perceptedGIP.gram.value,
196-
perceptedGIP.joinedCurrentKey(by: "-")
215+
headPair.value,
216+
headReading
197217
)
198218
}
199219
}

Tests/MegrezTests/MegrezTests.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,13 +658,17 @@ final class MegrezTestsAdvanced: XCTestCase {
658658
compositor.assemble()
659659
let assembledBefore = compositor.assembledSentence.map(\.value).joined(separator: " ")
660660
XCTAssertTrue("再 創 是的 凱歌" == assembledBefore)
661+
// 測試此時生成的 keyForQueryingData 是否正確
662+
let cursorShi = 2
663+
let keyForQueryingData = compositor.assembledSentence
664+
.generateKeyForPerception(cursor: cursorShi)
665+
XCTAssertEqual(keyForQueryingData?.ngramKey, "((zai4:再),(chuang4:創),shi4)")
661666
// 應能提供『是的』『似的』『凱歌』等候選
662667
let pairsAtShiDeEnd = compositor.fetchCandidates(at: 4, filter: .endAt)
663668
XCTAssertTrue(pairsAtShiDeEnd.map(\.value).contains("是的"))
664669
XCTAssertTrue(pairsAtShiDeEnd.map(\.value).contains("似的"))
665670
// 模擬使用者把『是』改為『世』,再合成:觀測應為 shortToLong
666671
var obsCaptured: Megrez.PerceptionIntel?
667-
let cursorShi = 2
668672
_ = compositor.overrideCandidate(
669673
.init(keyArray: ["shi4"], value: ""),
670674
at: cursorShi

0 commit comments

Comments
 (0)