export type Machine = Fa | Pda | Tm; export function parse_machine_from_json(json: string): Machine { const machine: Machine = JSON.parse(json); machine.states = new Map(Object.entries(machine.states)); if (machine.alphabet) { machine.alphabet = new Map(Object.entries(machine.alphabet)); } if (machine.final_states) { machine.final_states = new Map(Object.entries(machine.final_states)); } // deno-lint-ignore no-explicit-any const transitions = machine.transitions as any as [any, any]; machine.transitions = new Map(); for (const [key, value] of transitions) { machine.transitions.set(key, value); } machine.edges = new Map(); machine.transitions_components = new Map(); switch (machine.type) { case "fa": { for (const [from, tos] of machine.transitions) { for (const to of tos) { const layer_0 = machine.transitions_components; if (!layer_0.has(from.state)) layer_0.set(from.state, new Map()); const layer_1 = machine.transitions_components.get(from.state)!; if (!layer_1.has(from.letter)) layer_1.set(from.letter, []); const layer_2 = layer_1.get(from.letter)!; layer_2.push(to); const edge = from.state + "#" + to.state; if (!machine.edges.has(edge)) machine.edges.set(edge, []); machine.edges.get(edge)?.push({ repr: from.letter ? from.letter : "ε", function: to.function, transition: to.transition, }); } } } break; case "pda": { machine.symbols = new Map(Object.entries(machine.symbols)); for (const [from, tos] of machine.transitions) { for (const to of tos) { const layer_0 = machine.transitions_components; if (!layer_0.has(from.state)) layer_0.set(from.state, new Map()); const layer_1 = machine.transitions_components.get(from.state)!; if (!layer_1.has(from.symbol)) layer_1.set(from.symbol, new Map()); const layer_2 = layer_1.get(from.symbol)!; if (!layer_2.has(from.letter)) layer_2.set(from.letter, []); const layer_3 = layer_2.get(from.letter)!; layer_3.push(to); const edge = from.state + "#" + to.state; if (!machine.edges.has(edge)) machine.edges.set(edge, []); machine.edges.get(edge)?.push({ repr: (from.letter ? from.letter : "ε") + "," + from.symbol + "->[" + to.stack + "]", function: to.function, transition: to.transition, }); } } } break; case "tm": { machine.symbols = new Map(Object.entries(machine.symbols)); for (const [from, tos] of machine.transitions) { for (const to of tos) { const layer_0 = machine.transitions_components; if (!layer_0.has(from.state)) layer_0.set(from.state, new Map()); const layer_1 = machine.transitions_components.get(from.state)!; if (!layer_1.has(from.symbol)) layer_1.set(from.symbol, []); const layer_2 = layer_1.get(from.symbol)!; layer_2.push(to); const edge = from.state + "#" + to.state; if (!machine.edges.has(edge)) machine.edges.set(edge, []); machine.edges.get(edge)?.push({ repr: from.symbol + "->" + to.symbol + "," + to.direction, function: to.function, transition: to.transition, }); } } } break; } return machine; } export type State = string; export type Symbol = string; export type Letter = string; export type Span = readonly [number, number]; export type StateInfo = { readonly definition: Span }; export type LetterInfo = { readonly definition: Span }; export type SymbolInfo = { readonly definition: Span }; export type FaTransFrom = { state: State; letter: Letter | null; }; export type FaTransTo = { readonly state: State; readonly transition: Span; readonly function: Span; }; export type Edge = { readonly repr: string; readonly function: Span; readonly transition: Span; }; export type Fa = { type: "fa"; initial_state: State; states: Map; alphabet: Map; final_states: Map; transitions: Map; transitions_components: Map>; edges: Map; }; export type PdaTransFrom = { readonly state: State; readonly letter: Letter | null; readonly symbol: Symbol; }; export type PdaTransTo = { readonly state: State; readonly stack: readonly Symbol[]; readonly transition: Span; readonly function: Span; }; export type Pda = { type: "pda"; initial_state: State; initial_stack: Symbol; states: Map; symbols: Map; alphabet: Map; final_states: Map | null; transitions: Map; transitions_components: Map< State, Map> >; edges: Map; }; export type TmTransFrom = { readonly state: State; readonly symbol: Symbol; }; export type TmTransTo = { readonly state: State; readonly symbol: Symbol; readonly direction: "<" | ">" | "_"; readonly transition: Span; readonly function: Span; }; export type Tm = { type: "tm"; initial_state: State; blank_symbol: Symbol; states: Map; symbols: Map; alphabet: Map; final_states: Map; transitions: Map; transitions_components: Map>; edges: Map; };