UNPKG

fuzzy-rater

Version:

Tooling for fuzzily rating text according to some query

170 lines 15.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNodesFromIDs = exports.createID = exports.getReachableNodes = exports.getAvailableTransitionCharacter = exports.getRemainingTransition = exports.getCharacterTransition = exports.convertNFATemplateToDFATemplate = void 0; function convertNFATemplateToDFATemplate(nodes, getMeta) { const nodeMap = new Map(nodes.map(node => [node.ID, node])); const outMap = new Map(); // Get the initial nodes const { nodes: initNodes } = getReachableNodes(nodeMap, nodes.filter(({ initial }) => initial)); const initState = createID(initNodes); // Iteratively keep adding nodes and their transitions const stack = [initNodes]; let set; while ((set = stack.shift())) { const nodes = set; // First make sure the node doesn't exist yet const ID = createID(nodes); if (outMap.has(ID)) continue; // Figure out all transitions const transitionChars = getAvailableTransitionCharacter(nodes); const characterTransitions = transitionChars.map(char => { const { transition, to } = getCharacterTransition(nodeMap, nodes, char, getMeta === null || getMeta === void 0 ? void 0 : getMeta.transitionMeta); stack.push(to); return transition; }); const { transition: remainingTransition, to } = getRemainingTransition(nodeMap, nodes, getMeta === null || getMeta === void 0 ? void 0 : getMeta.transitionMeta); stack.push(to); // Create and store the node const node = { ID, transitions: [...characterTransitions, remainingTransition], metadata: getMeta ? { sources: nodes, ...getMeta.nodeMeta(nodes) } : { sources: nodes }, }; outMap.set(ID, node); } // Return the dfa template return { nodes: Array.from(outMap.values()), initial: initState }; } exports.convertNFATemplateToDFATemplate = convertNFATemplateToDFATemplate; /** * Creates a transition, given a character and the node sets to transition from * @param template All the nfa input nodes * @param nodes The current state * @param char The character to transition on * @param getMeta An optional function to get extra metadata for the transition * @returns The transition for this character */ function getCharacterTransition(template, nodes, char, getMeta) { const transitions = []; // Obtain the transitions for each node for this character nodes.forEach(node => { const charTransitions = node.transitions.filter(({ type, character }) => type == "character" && character == char); let nodeTransitions; if (charTransitions.length > 0) { nodeTransitions = charTransitions; } else { nodeTransitions = node.transitions.filter(({ type }) => type == "remaining"); } nodeTransitions.forEach(transition => transitions.push({ from: node.ID, ...transition })); }); // Get the ID of the end of the transition const toNodesDirect = transitions.map(transition => transition.to); const { nodes: toNodes, emptyTransitions } = getReachableNodes(template, getNodesFromIDs(template, toNodesDirect)); const to = createID(toNodes); // Construct the transition const sources = [...transitions, ...emptyTransitions]; return { transition: { to, type: "character", character: char, metadata: getMeta ? { sources, ...getMeta(sources) } : { sources }, }, to: toNodes, }; } exports.getCharacterTransition = getCharacterTransition; /** * Retrieves the transition for all characters for which no specific transition exists * @param template All the nfa input nodes * @param nodes The current state * @param getMeta An optional function to get extra metadata for the transition * @returns The transition for the remaining characters */ function getRemainingTransition(template, nodes, getMeta) { const transitions = []; // Obtain the transitions for each node for this character nodes.forEach(node => { const remainingTransitions = node.transitions.filter(({ type }) => type == "remaining"); remainingTransitions.forEach(transition => transitions.push({ from: node.ID, ...transition })); }); // Get the ID of the end of the transition const toNodesDirect = transitions.map(transition => transition.to); const { nodes: toNodes, emptyTransitions } = getReachableNodes(template, getNodesFromIDs(template, toNodesDirect)); const to = createID(toNodes); // Construct the transition const sources = [...transitions, ...emptyTransitions]; return { transition: { to, type: "remaining", metadata: getMeta ? { sources, ...getMeta(sources) } : { sources }, }, to: toNodes, }; } exports.getRemainingTransition = getRemainingTransition; /** * Retrieves the transition characters found in the given set of nodes * @param nodes The nodes in which to look for transition characters * @returns The transition character set */ function getAvailableTransitionCharacter(nodes) { return Array.from(new Set(nodes .flatMap(({ transitions }) => transitions) .filter(({ type }) => type == "character") .map(({ character }) => character) .filter((char) => !!char))); } exports.getAvailableTransitionCharacter = getAvailableTransitionCharacter; /** * Checks what nodes are reachable with the given set, by using empty transitions * @param template All the nfa input nodes * @param nodes The nodes to get the closure of, (may include duplicates, which will be removed) * @returns The reach of these nodes */ function getReachableNodes(template, nodes) { const reachableNodes = new Set(nodes); const emptyTransitions = []; for (let node of reachableNodes) { const nodeEmptyTransitions = node.transitions.filter(({ type }) => type == "empty"); const transitionNodes = getNodesFromIDs(template, nodeEmptyTransitions.map(({ to }) => to)); transitionNodes.forEach(node => reachableNodes.add(node)); nodeEmptyTransitions.forEach(transition => emptyTransitions.push({ from: node.ID, ...transition })); } return { nodes: Array.from(reachableNodes), emptyTransitions: Array.from(emptyTransitions), }; } exports.getReachableNodes = getReachableNodes; /** * Creates an ID to uniquely define a set of nodes, no matter what the order is * @param nodes The nodes to create the ID for * @returns The created ID */ function createID(nodes) { const IDs = nodes.map(node => (typeof node == "string" ? node : node.ID)); const sorted = IDs.sort(); return `{${sorted.join(",")}}`; } exports.createID = createID; /** * Retrieves nodes given the list of IDs * @param map The map of items that the nodes are in * @param IDs The IDs of the nodes to retrieve * @returns The nodes */ function getNodesFromIDs(map, IDs) { return IDs.map(ID => map.get(ID)).filter((n) => !!n); } exports.getNodesFromIDs = getNodesFromIDs; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydE5GQVRlbXBsYXRlVG9ERkFUZW1wbGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ERkEvTkZBREZBL2NvbnZlcnRORkFUZW1wbGF0ZVRvREZBVGVtcGxhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBaUNBLFNBQWdCLCtCQUErQixDQUMzQyxLQUFtQyxFQUNuQyxPQUEwQztJQUUxQyxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FDbkIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUNyQyxDQUFDO0lBQ0YsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQXFDLENBQUM7SUFFNUQsd0JBQXdCO0lBQ3hCLE1BQU0sRUFBQyxLQUFLLEVBQUUsU0FBUyxFQUFDLEdBQUcsaUJBQWlCLENBQ3hDLE9BQU8sRUFDUCxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBQyxPQUFPLEVBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQ3ZDLENBQUM7SUFDRixNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFdEMsc0RBQXNEO0lBQ3RELE1BQU0sS0FBSyxHQUFpQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3hELElBQUksR0FBMkMsQ0FBQztJQUNoRCxPQUFPLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFO1FBQzFCLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQztRQUVsQiw2Q0FBNkM7UUFDN0MsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNCLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFBRSxTQUFTO1FBRTdCLDZCQUE2QjtRQUM3QixNQUFNLGVBQWUsR0FBRywrQkFBK0IsQ0FB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