UNPKG

fuzzy-rater

Version:

Tooling for fuzzily rating text according to some query

159 lines 12.9 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; /** * Converts the nfa input to a dfa input * @param nodes The nodes for a nfa automaton * @returns The dfa equivalent automaton template */ function convertNFATemplateToDFATemplate(nodes) { const nodeMap = new Map(nodes.map(node => [node.ID, node])); const outMap = new Map(); // Get the initial nodes const 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); stack.push(to); return transition; }); const { transition: remainingTransition, to } = getRemainingTransition(nodeMap, nodes); stack.push(to); // Create and store the node const node = { ID, transitions: [...characterTransitions, remainingTransition], metadata: { 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 * @returns The transition for this character */ function getCharacterTransition(template, nodes, char) { 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); if (charTransitions.length > 0) { transitions.push(...charTransitions); } else { const otherTransitions = node.transitions.filter(({ type }) => type == "remaining"); transitions.push(...otherTransitions); } }); // Get the ID of the end of the transition const toNodesDirect = transitions.map(transition => transition.to); const toNodes = getReachableNodes(template, getNodesFromIDs(template, toNodesDirect)); const to = createID(toNodes); // Construct the transition return { transition: { to, type: "character", character: char, metadata: { sources: transitions }, }, 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 * @returns The transition for the remaining characters */ function getRemainingTransition(template, nodes) { const transitions = []; // Obtain the transitions for each node for this character nodes.forEach(node => { const remainingTransitions = node.transitions.filter(({ type }) => type == "remaining"); transitions.push(...remainingTransitions); }); // Get the ID of the end of the transition const toNodesDirect = transitions.map(transition => transition.to); const toNodes = getReachableNodes(template, getNodesFromIDs(template, toNodesDirect)); const to = createID(toNodes); // Construct the transition return { transition: { to, type: "remaining", metadata: { sources: transitions }, }, 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); for (let node of reachableNodes) { const emptyTransitions = node.transitions.filter(({ type }) => type == "empty"); const transitionNodes = getNodesFromIDs(template, emptyTransitions.map(({ to }) => to)); transitionNodes.forEach(node => reachableNodes.add(node)); } return Array.from(reachableNodes); } 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydE5GQVRlbXBsYXRlVG9ERkFUZW1wbGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ERkEvY29udmVydE5GQVRlbXBsYXRlVG9ERkFUZW1wbGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFPQTs7OztHQUlHO0FBQ0gsU0FBZ0IsK0JBQStCLENBQzNDLEtBQW1DO0lBRW5DLE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxDQUNuQixLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQ3JDLENBQUM7SUFDRixNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBNkIsQ0FBQztJQUVwRCx3QkFBd0I7SUFDeEIsTUFBTSxTQUFTLEdBQUcsaUJBQWlCLENBQy9CLE9BQU8sRUFDUCxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBQyxPQUFPLEVBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQ3ZDLENBQUM7SUFDRixNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFdEMsc0RBQXNEO0lBQ3RELE1BQU0sS0FBSyxHQUFpQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3hELElBQUksR0FBMkMsQ0FBQztJQUNoRCxPQUFPLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFO1FBQzFCLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQztRQUVsQiw2Q0FBNkM7UUFDN0MsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNCLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFBRSxTQUFTO1FBRTdCLDZCQUE2QjtRQUM3QixNQUFNLGVBQWUsR0FBRywrQkFBK0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUUvRCxNQUFNLG9C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