UNPKG

fauton

Version:

A library to test any finite automaton with arbitrary alphabets

67 lines (66 loc) 3.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertToDeterministicFiniteAutomaton = void 0; const epsilonClosureOfState_1 = require("./epsilonClosureOfState"); const moveAndEpsilonClosureStateSet_1 = require("./moveAndEpsilonClosureStateSet"); function convertToDeterministicFiniteAutomaton(automaton, generatedAutomatonOptions) { const separator = generatedAutomatonOptions?.separator ?? ','; const startState = automaton.start_state; const newStartStates = automaton.epsilon_transitions ? (0, epsilonClosureOfState_1.epsilonClosureOfState)(automaton.epsilon_transitions, startState) : [automaton.start_state]; const newStartStateString = newStartStates.sort().join(separator); const newStates = new Set(); const unmarkedStates = [newStartStateString]; const newTransitionsRecord = {}; const totalAlphabets = automaton.alphabets.length; const newFinalStates = new Set(); newStates.add(newStartStateString); let hasDeadState = false; while (unmarkedStates.length !== 0) { const currentStatesString = unmarkedStates.shift(); for (let symbolIndex = 0; symbolIndex < automaton.alphabets.length; symbolIndex += 1) { const symbol = automaton.alphabets[symbolIndex]; const newStateString = (0, moveAndEpsilonClosureStateSet_1.moveAndEpsilonClosureStateSet)(automaton.transitions, automaton.epsilon_transitions, currentStatesString.split(separator), symbol) .sort() .join(separator); if (!newStates.has(newStateString) && newStateString) { newStates.add(newStateString); unmarkedStates.push(newStateString); } if (!newStateString) { hasDeadState = true; newStates.add(`Ø`); } if (!newTransitionsRecord[currentStatesString]) { newTransitionsRecord[currentStatesString] = new Array(totalAlphabets).fill(null); } if (newStateString) newTransitionsRecord[currentStatesString][symbolIndex] = [newStateString]; else { newTransitionsRecord[currentStatesString][symbolIndex] = [`Ø`]; } } } automaton.final_states.forEach((finalState) => { newStates.forEach((newState) => { if (newState.includes(finalState)) { newFinalStates.add(newState); } }); }); if (hasDeadState) { newTransitionsRecord['Ø'] = new Array(totalAlphabets).fill('Ø'); } return { alphabets: automaton.alphabets, final_states: Array.from(newFinalStates), label: generatedAutomatonOptions?.label ?? automaton.label, start_state: newStartStateString, states: Array.from(newStates), transitions: newTransitionsRecord, epsilon_transitions: null, description: generatedAutomatonOptions?.description ?? automaton.description, }; } exports.convertToDeterministicFiniteAutomaton = convertToDeterministicFiniteAutomaton;