mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-29 03:37:42 +00:00
Merge branch 'change/web/fix-result-spaceId-remapping' into change/web/return-search-token-mapping
This commit is contained in:
commit
6e1cb03bc4
8 changed files with 29 additions and 23 deletions
|
|
@ -146,13 +146,15 @@ export class SearchNode {
|
|||
private readonly deleteAfterInsertEditPairs: number;
|
||||
|
||||
/**
|
||||
* A unique identifier corresponding to the earliest SearchPath containing
|
||||
* the correction-search graph edge represented by this instance.
|
||||
* A unique identifier corresponding to the SearchQuotientNode last passed
|
||||
* through by the represented search path.
|
||||
*
|
||||
* Corresponding search results will be tagged with this, which can be used
|
||||
* to identify the result's original source tokenization.
|
||||
* The correction-search results produced by this search path will be tagged
|
||||
* accordingly to match the correction with its original ContextTokenization.
|
||||
* This is necessary in order to properly construct suggestions that apply as
|
||||
* the user expects should the tokenization pattern itself be corrected.
|
||||
*/
|
||||
readonly spaceId: number;
|
||||
public spaceId: number;
|
||||
|
||||
/**
|
||||
* Notes the edit operation used for the most recent edge in the node's
|
||||
|
|
@ -580,7 +582,7 @@ export class SearchNode {
|
|||
* @param timer
|
||||
* @returns
|
||||
*/
|
||||
export async function *getBestMatches(searchModules: SearchQuotientNode[], timer: ExecutionTimer): AsyncGenerator<TokenResultMapping> {
|
||||
export async function *getBestMatches(searchModules: SearchQuotientNode[], timer: ExecutionTimer): AsyncGenerator<Readonly<TokenResultMapping>> {
|
||||
const spaceQueue = new PriorityQueue<SearchQuotientNode>((a, b) => a.currentCost - b.currentCost);
|
||||
|
||||
// Stage 1 - if we already have extracted results, build a queue just for them
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ export class LegacyQuotientRoot extends SearchQuotientRoot {
|
|||
return {
|
||||
type: 'complete',
|
||||
cost: node.currentCost,
|
||||
mapping: new TokenResultMapping(node),
|
||||
spaceId: this.spaceId
|
||||
mapping: new TokenResultMapping(node)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ export class SearchQuotientCluster implements SearchQuotientNode {
|
|||
|
||||
this.lowestPossibleSingleCost = lowestPossibleSingleCost;
|
||||
this.completedPaths = inboundPaths.flatMap(p => p.previousResults).map(r => r.node);
|
||||
this.completedPaths.forEach((p) => p.spaceId = this.spaceId);
|
||||
this.selectionQueue.enqueueAll(inboundPaths);
|
||||
|
||||
return;
|
||||
|
|
@ -144,15 +145,16 @@ export class SearchQuotientCluster implements SearchQuotientNode {
|
|||
this.selectionQueue.enqueue(bestPath);
|
||||
|
||||
if(currentResult.type == 'complete') {
|
||||
this.completedPaths?.push(currentResult.mapping.node);
|
||||
currentResult.spaceId = this.spaceId;
|
||||
const node = currentResult.mapping.node;
|
||||
node.spaceId = this.spaceId;
|
||||
this.completedPaths?.push(node);
|
||||
}
|
||||
|
||||
return currentResult;
|
||||
}
|
||||
|
||||
public get previousResults(): TokenResultMapping[] {
|
||||
return this.completedPaths?.map((n => new TokenResultMapping(n, this.spaceId))) ?? [];
|
||||
return this.completedPaths?.map((n) => new TokenResultMapping(n)) ?? [];
|
||||
}
|
||||
|
||||
get model(): LexicalModelTypes.LexicalModel {
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ type IntermediateSearchPath = {
|
|||
type CompleteSearchPath = {
|
||||
type: 'complete',
|
||||
cost: number,
|
||||
mapping: TokenResultMapping,
|
||||
spaceId: number
|
||||
mapping: TokenResultMapping
|
||||
}
|
||||
|
||||
export type PathResult = NullPath | IntermediateSearchPath | CompleteSearchPath;
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ export class SearchQuotientRoot implements SearchQuotientNode {
|
|||
return {
|
||||
type: 'complete',
|
||||
cost: 0,
|
||||
mapping: new TokenResultMapping(this.rootNode),
|
||||
spaceId: this.spaceId
|
||||
mapping: new TokenResultMapping(this.rootNode)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -404,8 +404,7 @@ export abstract class SearchQuotientSpur implements SearchQuotientNode {
|
|||
return {
|
||||
type: 'complete',
|
||||
cost: currentNode.currentCost,
|
||||
mapping: new TokenResultMapping(currentNode),
|
||||
spaceId: this.spaceId
|
||||
mapping: new TokenResultMapping(currentNode)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,13 @@
|
|||
/*
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*
|
||||
* Created by jahorton on 2026-04-02
|
||||
*
|
||||
* This file defines the type used for tracking critical graph-search properties
|
||||
* utilized during correction-search by the `getBestMatches` algorithm when run
|
||||
* against individual tokens / words.
|
||||
*/
|
||||
|
||||
import { LexicalModelTypes } from '@keymanapp/common-types';
|
||||
|
||||
import { SearchNode, TraversableToken } from "./distance-modeler.js";
|
||||
|
|
@ -9,12 +19,8 @@ import Transform = LexicalModelTypes.Transform;
|
|||
export class TokenResultMapping {
|
||||
readonly node: SearchNode;
|
||||
|
||||
// Supports SearchPath -> SearchSpace remapping.
|
||||
readonly spaceId: number;
|
||||
|
||||
constructor(node: SearchNode, spaceId?: number) {
|
||||
constructor(node: SearchNode) {
|
||||
this.node = node;
|
||||
this.spaceId = spaceId ?? node.spaceId;
|
||||
}
|
||||
|
||||
get inputSequence(): ProbabilityMass<Transform>[] {
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ export async function correctAndEnumerate(
|
|||
const correctionPredictionMap: Record<string, Distribution<Suggestion>> = {};
|
||||
for await(const match of getBestMatches(searchModules, timer)) {
|
||||
// Corrections obtained: now to predict from them!
|
||||
const tokenization = tokenizations.find(t => t.spaceId == match.spaceId);
|
||||
const tokenization = tokenizations.find(t => t.spaceId == match.node.spaceId);
|
||||
|
||||
// If our 'match' results in fully deleting the new token, reject it and try again.
|
||||
if(match.matchSequence.length == 0 && match.inputSequence.length != 0) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue