fauton
Version:
A library to test any finite automaton with arbitrary alphabets
67 lines (66 loc) • 3.19 kB
JavaScript
;
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;