From 445cca21c43aa04df454cbabcc444a31d7a8f258 Mon Sep 17 00:00:00 2001 From: Joshua Horton Date: Wed, 7 Jan 2026 13:42:11 -0600 Subject: [PATCH] refactor(web): refactor local input cost heuristic These changes were previously part of #14987 and have been extracted for ease of review. Build-bot: skip build:web Test-bot: skip --- .../src/main/correction/search-quotient-node.ts | 10 ++++++++++ .../src/main/correction/search-quotient-spur.ts | 17 ++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/web/src/engine/predictive-text/worker-thread/src/main/correction/search-quotient-node.ts b/web/src/engine/predictive-text/worker-thread/src/main/correction/search-quotient-node.ts index e5a7802dc81..e22f38c4f8c 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/correction/search-quotient-node.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/correction/search-quotient-node.ts @@ -64,6 +64,16 @@ export interface SearchQuotientNode { */ readonly currentCost: number; + /** + * Provides a heuristic for the base cost at this path's depth if the best + * individual input were taken here, regardless of whether or not that's + * possible. + * + * This cost is based on the negative log-likelihood of the probability and + * includes the cost from the lowest possible parent nodes visited. + */ + readonly lowestPossibleSingleCost: number; + /** * Returns the set of previously-processed results under this batcher's domain. */ diff --git a/web/src/engine/predictive-text/worker-thread/src/main/correction/search-quotient-spur.ts b/web/src/engine/predictive-text/worker-thread/src/main/correction/search-quotient-spur.ts index b8b2a4d5456..536e9a9ec27 100644 --- a/web/src/engine/predictive-text/worker-thread/src/main/correction/search-quotient-spur.ts +++ b/web/src/engine/predictive-text/worker-thread/src/main/correction/search-quotient-spur.ts @@ -34,16 +34,16 @@ export class SearchQuotientSpur implements SearchQuotientNode { readonly spaceId: number; /** - * Marks all results that have already been returned since the last input was received. - * Is cleared after .addInput() calls. + * Marks all results that have already been returned from this instance of SearchPath. + * Should be deleted and cleared if any paths consider this one as a parent. */ private returnedValues?: {[resultKey: string]: SearchNode} = {}; /** - * Provides a heuristic for the base cost at each depth if the best - * individual input were taken at that level. + * Provides a heuristic for the base cost at this path's depth if the best + * individual input were taken here, regardless of whether or not that's possible. */ - private lowestCostAtDepth: number[]; + readonly lowestPossibleSingleCost: number; /** * Constructs a fresh SearchSpace instance for used in predictive-text correction @@ -61,7 +61,7 @@ export class SearchQuotientSpur implements SearchQuotientNode { const logTierCost = -Math.log(bestProbFromSet); this.inputs = inputs; - this.lowestCostAtDepth = parentNode.lowestCostAtDepth.concat(logTierCost); + this.lowestPossibleSingleCost = parentNode.lowestPossibleSingleCost + logTierCost; this.parentPath = parentNode; this.addEdgesForNodes(parentNode.previousResults.map(v => v.node)); @@ -71,7 +71,7 @@ export class SearchQuotientSpur implements SearchQuotientNode { const model = arg1 as LexicalModel; this.selectionQueue.enqueue(new SearchNode(model.traverseFromRoot(), this.spaceId, t => model.toKey(t))); - this.lowestCostAtDepth = []; + this.lowestPossibleSingleCost = 0; } /** @@ -202,8 +202,7 @@ export class SearchQuotientSpur implements SearchQuotientNode { // ... or even just not the then-current layer of the keyboard. // // TODO: still consider the lowest-cost individual edges for THIS specific criterion. - const tierMinCost = this.lowestCostAtDepth[currentNode.priorInput.length-1]; - if(currentNode.currentCost > tierMinCost + 2.5 * EDIT_DISTANCE_COST_SCALE) { + if(currentNode.currentCost > this.lowestPossibleSingleCost + 2.5 * EDIT_DISTANCE_COST_SCALE) { return unmatchedResult; }