@turing-machine-js/machine 2.0.0-alpha.0 → 2.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/classes/Alphabet.d.ts +9 -0
- package/dist/classes/Alphabet.js +50 -0
- package/dist/classes/Command.d.ts +6 -0
- package/dist/classes/Command.js +38 -0
- package/dist/classes/Lock.d.ts +6 -0
- package/dist/classes/Lock.js +34 -0
- package/dist/classes/Reference.d.ts +6 -0
- package/dist/classes/Reference.js +31 -0
- package/dist/classes/State.d.ts +22 -0
- package/dist/classes/State.js +113 -0
- package/dist/classes/Tape.d.ts +24 -0
- package/dist/classes/Tape.js +95 -0
- package/dist/classes/TapeBlock.d.ts +28 -0
- package/dist/classes/TapeBlock.js +198 -0
- package/dist/classes/TapeCommand.d.ts +20 -0
- package/dist/classes/TapeCommand.js +46 -0
- package/dist/classes/TuringMachine.d.ts +26 -0
- package/dist/classes/TuringMachine.js +102 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/utilities/functions.d.ts +4 -0
- package/dist/utilities/functions.js +13 -0
- package/package.json +2 -2
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _Alphabet_symbols;
|
|
13
|
+
import { uniquePredicate } from '../utilities/functions';
|
|
14
|
+
class Alphabet {
|
|
15
|
+
constructor(symbols) {
|
|
16
|
+
_Alphabet_symbols.set(this, void 0);
|
|
17
|
+
if (symbols instanceof Alphabet) {
|
|
18
|
+
symbols = symbols.symbols;
|
|
19
|
+
}
|
|
20
|
+
const uniqueSymbols = symbols.filter(uniquePredicate);
|
|
21
|
+
if (uniqueSymbols.length < 2) {
|
|
22
|
+
throw new Error('Invalid symbols length');
|
|
23
|
+
}
|
|
24
|
+
const isSymbolsValid = uniqueSymbols.every((symbol) => symbol.length === 1);
|
|
25
|
+
if (!isSymbolsValid) {
|
|
26
|
+
throw new Error('symbols contains invalid symbol');
|
|
27
|
+
}
|
|
28
|
+
__classPrivateFieldSet(this, _Alphabet_symbols, Array.from(uniqueSymbols), "f");
|
|
29
|
+
}
|
|
30
|
+
get symbols() {
|
|
31
|
+
return Array.from(__classPrivateFieldGet(this, _Alphabet_symbols, "f"));
|
|
32
|
+
}
|
|
33
|
+
get blankSymbol() {
|
|
34
|
+
return __classPrivateFieldGet(this, _Alphabet_symbols, "f")[0];
|
|
35
|
+
}
|
|
36
|
+
has(symbol) {
|
|
37
|
+
return __classPrivateFieldGet(this, _Alphabet_symbols, "f").indexOf(symbol) >= 0;
|
|
38
|
+
}
|
|
39
|
+
get(index) {
|
|
40
|
+
if (index < 0 || index >= __classPrivateFieldGet(this, _Alphabet_symbols, "f").length) {
|
|
41
|
+
throw new Error('Invalid index');
|
|
42
|
+
}
|
|
43
|
+
return __classPrivateFieldGet(this, _Alphabet_symbols, "f")[index];
|
|
44
|
+
}
|
|
45
|
+
index(symbol) {
|
|
46
|
+
return __classPrivateFieldGet(this, _Alphabet_symbols, "f").indexOf(symbol);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
_Alphabet_symbols = new WeakMap();
|
|
50
|
+
export default Alphabet;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _Command_tapesCommands;
|
|
13
|
+
import TapeCommand from './TapeCommand';
|
|
14
|
+
class Command {
|
|
15
|
+
constructor(tapesCommands) {
|
|
16
|
+
_Command_tapesCommands.set(this, void 0);
|
|
17
|
+
if (tapesCommands.length === 0) {
|
|
18
|
+
throw new Error('invalid parameter');
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
__classPrivateFieldSet(this, _Command_tapesCommands, tapesCommands.map((tapeCommand) => {
|
|
22
|
+
if (tapeCommand instanceof TapeCommand) {
|
|
23
|
+
return tapeCommand;
|
|
24
|
+
}
|
|
25
|
+
return new TapeCommand(tapeCommand);
|
|
26
|
+
}), "f");
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
void error;
|
|
30
|
+
throw new Error('invalid tapeCommand');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
get tapesCommands() {
|
|
34
|
+
return [...__classPrivateFieldGet(this, _Command_tapesCommands, "f")];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
_Command_tapesCommands = new WeakMap();
|
|
38
|
+
export default Command;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _Lock_lockSymbol;
|
|
13
|
+
class Lock {
|
|
14
|
+
constructor() {
|
|
15
|
+
_Lock_lockSymbol.set(this, null);
|
|
16
|
+
}
|
|
17
|
+
lock(symbol) {
|
|
18
|
+
if (__classPrivateFieldGet(this, _Lock_lockSymbol, "f") === null) {
|
|
19
|
+
__classPrivateFieldSet(this, _Lock_lockSymbol, symbol, "f");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
unlock(symbol) {
|
|
23
|
+
if (__classPrivateFieldGet(this, _Lock_lockSymbol, "f") === symbol) {
|
|
24
|
+
__classPrivateFieldSet(this, _Lock_lockSymbol, null, "f");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
check(symbol) {
|
|
28
|
+
if (__classPrivateFieldGet(this, _Lock_lockSymbol, "f") && __classPrivateFieldGet(this, _Lock_lockSymbol, "f") !== symbol) {
|
|
29
|
+
throw new Error('Lock check failed');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
_Lock_lockSymbol = new WeakMap();
|
|
34
|
+
export default Lock;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _Reference_referenceBinding;
|
|
13
|
+
class Reference {
|
|
14
|
+
constructor() {
|
|
15
|
+
_Reference_referenceBinding.set(this, null);
|
|
16
|
+
}
|
|
17
|
+
get ref() {
|
|
18
|
+
if (!__classPrivateFieldGet(this, _Reference_referenceBinding, "f")) {
|
|
19
|
+
throw new Error('unbounded reference');
|
|
20
|
+
}
|
|
21
|
+
return __classPrivateFieldGet(this, _Reference_referenceBinding, "f");
|
|
22
|
+
}
|
|
23
|
+
bind(state) {
|
|
24
|
+
if (__classPrivateFieldGet(this, _Reference_referenceBinding, "f") == null) {
|
|
25
|
+
__classPrivateFieldSet(this, _Reference_referenceBinding, state, "f");
|
|
26
|
+
}
|
|
27
|
+
return __classPrivateFieldGet(this, _Reference_referenceBinding, "f");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
_Reference_referenceBinding = new WeakMap();
|
|
31
|
+
export default Reference;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Command from './Command';
|
|
2
|
+
import Reference from './Reference';
|
|
3
|
+
import TapeBlock from './TapeBlock';
|
|
4
|
+
import TapeCommand from './TapeCommand';
|
|
5
|
+
export declare const ifOtherSymbol: unique symbol;
|
|
6
|
+
export default class State {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(stateDefinition?: Record<string | symbol, {
|
|
9
|
+
command?: Command | ConstructorParameters<typeof TapeCommand>[0] | ConstructorParameters<typeof TapeCommand>[0][];
|
|
10
|
+
nextState?: State | Reference;
|
|
11
|
+
}> | null, name?: string);
|
|
12
|
+
get id(): number;
|
|
13
|
+
get name(): string;
|
|
14
|
+
get isHalt(): boolean;
|
|
15
|
+
get overrodeHaltState(): State | null;
|
|
16
|
+
get ref(): this;
|
|
17
|
+
getSymbol(tapeBlock: TapeBlock): symbol;
|
|
18
|
+
getCommand(symbol: symbol): Command;
|
|
19
|
+
getNextState(symbol: symbol): State | Reference;
|
|
20
|
+
withOverrodeHaltState(overrodeHaltState: State): State;
|
|
21
|
+
}
|
|
22
|
+
export declare const haltState: State;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _State_id, _State_name, _State_overrodeHaltState, _State_symbolToDataMap;
|
|
13
|
+
import Command from './Command';
|
|
14
|
+
import Reference from './Reference';
|
|
15
|
+
import TapeCommand from './TapeCommand';
|
|
16
|
+
import { id } from '../utilities/functions';
|
|
17
|
+
export const ifOtherSymbol = Symbol('other symbol');
|
|
18
|
+
class State {
|
|
19
|
+
constructor(stateDefinition = null, name) {
|
|
20
|
+
_State_id.set(this, id(this));
|
|
21
|
+
_State_name.set(this, void 0);
|
|
22
|
+
_State_overrodeHaltState.set(this, null);
|
|
23
|
+
_State_symbolToDataMap.set(this, new Map());
|
|
24
|
+
if (stateDefinition) {
|
|
25
|
+
const keys = Object.getOwnPropertyNames(stateDefinition);
|
|
26
|
+
if (keys.length) {
|
|
27
|
+
throw new Error(`invalid state definition while constructing state #${__classPrivateFieldGet(this, _State_id, "f")}`);
|
|
28
|
+
}
|
|
29
|
+
const symbols = Object.getOwnPropertySymbols(stateDefinition);
|
|
30
|
+
if (symbols.length === 0) {
|
|
31
|
+
throw new Error(`invalid state definition while constructing state #${__classPrivateFieldGet(this, _State_id, "f")}`);
|
|
32
|
+
}
|
|
33
|
+
symbols.forEach((symbol) => {
|
|
34
|
+
const { nextState } = stateDefinition[symbol];
|
|
35
|
+
const nextStateLocal = nextState !== null && nextState !== void 0 ? nextState : this;
|
|
36
|
+
if (!(nextStateLocal instanceof State) && !(nextStateLocal instanceof Reference)) {
|
|
37
|
+
throw new Error('invalid nextState');
|
|
38
|
+
}
|
|
39
|
+
let { command } = stateDefinition[symbol];
|
|
40
|
+
if (command == null) {
|
|
41
|
+
command = new Command([
|
|
42
|
+
new TapeCommand({}),
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
45
|
+
if (!(command instanceof Command) && !Array.isArray(command)) {
|
|
46
|
+
command = [command];
|
|
47
|
+
}
|
|
48
|
+
let commandLocal = command;
|
|
49
|
+
if (Array.isArray(command)) {
|
|
50
|
+
try {
|
|
51
|
+
commandLocal = new Command(command);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
void error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!(commandLocal instanceof Command)) {
|
|
58
|
+
throw new Error('invalid command');
|
|
59
|
+
}
|
|
60
|
+
__classPrivateFieldGet(this, _State_symbolToDataMap, "f").set(symbol, {
|
|
61
|
+
command: commandLocal,
|
|
62
|
+
nextState: nextStateLocal,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
__classPrivateFieldSet(this, _State_name, name !== null && name !== void 0 ? name : `id:${__classPrivateFieldGet(this, _State_id, "f")}`, "f");
|
|
67
|
+
}
|
|
68
|
+
get id() {
|
|
69
|
+
return __classPrivateFieldGet(this, _State_id, "f");
|
|
70
|
+
}
|
|
71
|
+
get name() {
|
|
72
|
+
return __classPrivateFieldGet(this, _State_name, "f");
|
|
73
|
+
}
|
|
74
|
+
get isHalt() {
|
|
75
|
+
return __classPrivateFieldGet(this, _State_id, "f") === 0;
|
|
76
|
+
}
|
|
77
|
+
get overrodeHaltState() {
|
|
78
|
+
return __classPrivateFieldGet(this, _State_overrodeHaltState, "f");
|
|
79
|
+
}
|
|
80
|
+
get ref() {
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
getSymbol(tapeBlock) {
|
|
84
|
+
const symbol = [...__classPrivateFieldGet(this, _State_symbolToDataMap, "f").keys()].find((currentSymbol) => tapeBlock.isMatched({
|
|
85
|
+
symbol: currentSymbol,
|
|
86
|
+
}));
|
|
87
|
+
if (symbol) {
|
|
88
|
+
return symbol;
|
|
89
|
+
}
|
|
90
|
+
return ifOtherSymbol;
|
|
91
|
+
}
|
|
92
|
+
getCommand(symbol) {
|
|
93
|
+
if (__classPrivateFieldGet(this, _State_symbolToDataMap, "f").has(symbol)) {
|
|
94
|
+
return __classPrivateFieldGet(this, _State_symbolToDataMap, "f").get(symbol).command;
|
|
95
|
+
}
|
|
96
|
+
throw new Error(`No command for symbol at state named ${__classPrivateFieldGet(this, _State_name, "f")}`);
|
|
97
|
+
}
|
|
98
|
+
getNextState(symbol) {
|
|
99
|
+
if (__classPrivateFieldGet(this, _State_symbolToDataMap, "f").has(symbol)) {
|
|
100
|
+
return __classPrivateFieldGet(this, _State_symbolToDataMap, "f").get(symbol).nextState;
|
|
101
|
+
}
|
|
102
|
+
throw new Error(`No nextState for symbol at state named ${__classPrivateFieldGet(this, _State_id, "f")}`);
|
|
103
|
+
}
|
|
104
|
+
withOverrodeHaltState(overrodeHaltState) {
|
|
105
|
+
const state = new State(null, `${this.name}>${overrodeHaltState.name}`);
|
|
106
|
+
__classPrivateFieldSet(state, _State_symbolToDataMap, __classPrivateFieldGet(this, _State_symbolToDataMap, "f"), "f");
|
|
107
|
+
__classPrivateFieldSet(state, _State_overrodeHaltState, overrodeHaltState, "f");
|
|
108
|
+
return state;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
_State_id = new WeakMap(), _State_name = new WeakMap(), _State_overrodeHaltState = new WeakMap(), _State_symbolToDataMap = new WeakMap();
|
|
112
|
+
export default State;
|
|
113
|
+
export const haltState = new State(null);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Alphabet from './Alphabet';
|
|
2
|
+
type TapeConstructorParameter = {
|
|
3
|
+
alphabet: Alphabet;
|
|
4
|
+
symbols?: string[];
|
|
5
|
+
position?: number;
|
|
6
|
+
viewportWidth?: number;
|
|
7
|
+
};
|
|
8
|
+
export default class Tape {
|
|
9
|
+
#private;
|
|
10
|
+
constructor({ alphabet, symbols, position, viewportWidth, }: TapeConstructorParameter);
|
|
11
|
+
get alphabet(): Alphabet;
|
|
12
|
+
get extraCellsCount(): number;
|
|
13
|
+
get position(): number;
|
|
14
|
+
get symbol(): string;
|
|
15
|
+
set symbol(symbol: string);
|
|
16
|
+
get symbols(): string[];
|
|
17
|
+
get viewport(): string[];
|
|
18
|
+
get viewportWidth(): number;
|
|
19
|
+
set viewportWidth(width: number);
|
|
20
|
+
left(): void;
|
|
21
|
+
normalise(): void;
|
|
22
|
+
right(): void;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _Tape_alphabet, _Tape_symbols, _Tape_position, _Tape_viewportWidth;
|
|
13
|
+
import Alphabet from './Alphabet';
|
|
14
|
+
class Tape {
|
|
15
|
+
constructor({ alphabet, symbols = [], position = 0, viewportWidth = 1, }) {
|
|
16
|
+
_Tape_alphabet.set(this, void 0);
|
|
17
|
+
_Tape_symbols.set(this, void 0);
|
|
18
|
+
_Tape_position.set(this, void 0);
|
|
19
|
+
_Tape_viewportWidth.set(this, void 0);
|
|
20
|
+
const isSymbolsValid = symbols.every((symbol) => alphabet.has(symbol));
|
|
21
|
+
if (!isSymbolsValid) {
|
|
22
|
+
throw new Error('symbolList contains invalid symbol');
|
|
23
|
+
}
|
|
24
|
+
__classPrivateFieldSet(this, _Tape_alphabet, new Alphabet(alphabet), "f");
|
|
25
|
+
__classPrivateFieldSet(this, _Tape_position, position, "f");
|
|
26
|
+
__classPrivateFieldSet(this, _Tape_viewportWidth, viewportWidth, "f");
|
|
27
|
+
const symbolsCopy = Array.from(symbols);
|
|
28
|
+
if (symbolsCopy.length === 0) {
|
|
29
|
+
symbolsCopy.push(__classPrivateFieldGet(this, _Tape_alphabet, "f").blankSymbol);
|
|
30
|
+
}
|
|
31
|
+
__classPrivateFieldSet(this, _Tape_symbols, symbolsCopy.map((symbol) => __classPrivateFieldGet(this, _Tape_alphabet, "f").index(symbol)), "f");
|
|
32
|
+
}
|
|
33
|
+
get alphabet() {
|
|
34
|
+
return __classPrivateFieldGet(this, _Tape_alphabet, "f");
|
|
35
|
+
}
|
|
36
|
+
get extraCellsCount() {
|
|
37
|
+
return (__classPrivateFieldGet(this, _Tape_viewportWidth, "f") - 1) / 2;
|
|
38
|
+
}
|
|
39
|
+
get position() {
|
|
40
|
+
return __classPrivateFieldGet(this, _Tape_position, "f");
|
|
41
|
+
}
|
|
42
|
+
get symbol() {
|
|
43
|
+
return __classPrivateFieldGet(this, _Tape_alphabet, "f").get(__classPrivateFieldGet(this, _Tape_symbols, "f")[__classPrivateFieldGet(this, _Tape_position, "f")]);
|
|
44
|
+
}
|
|
45
|
+
set symbol(symbol) {
|
|
46
|
+
if (!__classPrivateFieldGet(this, _Tape_alphabet, "f").has(symbol)) {
|
|
47
|
+
throw new Error('Invalid symbol');
|
|
48
|
+
}
|
|
49
|
+
__classPrivateFieldGet(this, _Tape_symbols, "f")[__classPrivateFieldGet(this, _Tape_position, "f")] = __classPrivateFieldGet(this, _Tape_alphabet, "f").index(symbol);
|
|
50
|
+
}
|
|
51
|
+
get symbols() {
|
|
52
|
+
return __classPrivateFieldGet(this, _Tape_symbols, "f")
|
|
53
|
+
.map((index) => __classPrivateFieldGet(this, _Tape_alphabet, "f").get(index));
|
|
54
|
+
}
|
|
55
|
+
get viewport() {
|
|
56
|
+
const startIx = __classPrivateFieldGet(this, _Tape_position, "f") - this.extraCellsCount;
|
|
57
|
+
const endIx = __classPrivateFieldGet(this, _Tape_position, "f") + this.extraCellsCount + 1;
|
|
58
|
+
return __classPrivateFieldGet(this, _Tape_symbols, "f")
|
|
59
|
+
.slice(startIx, endIx)
|
|
60
|
+
.map((index) => __classPrivateFieldGet(this, _Tape_alphabet, "f").get(index));
|
|
61
|
+
}
|
|
62
|
+
get viewportWidth() {
|
|
63
|
+
return __classPrivateFieldGet(this, _Tape_viewportWidth, "f");
|
|
64
|
+
}
|
|
65
|
+
set viewportWidth(width) {
|
|
66
|
+
let finalWidth = width;
|
|
67
|
+
if (finalWidth < 1) {
|
|
68
|
+
throw new Error('Invalid viewportWidth');
|
|
69
|
+
}
|
|
70
|
+
if (finalWidth % 2 === 0) {
|
|
71
|
+
finalWidth += 1;
|
|
72
|
+
}
|
|
73
|
+
__classPrivateFieldSet(this, _Tape_viewportWidth, finalWidth, "f");
|
|
74
|
+
this.normalise();
|
|
75
|
+
}
|
|
76
|
+
left() {
|
|
77
|
+
__classPrivateFieldSet(this, _Tape_position, __classPrivateFieldGet(this, _Tape_position, "f") - 1, "f");
|
|
78
|
+
this.normalise();
|
|
79
|
+
}
|
|
80
|
+
normalise() {
|
|
81
|
+
while (__classPrivateFieldGet(this, _Tape_position, "f") - this.extraCellsCount < 0) {
|
|
82
|
+
__classPrivateFieldGet(this, _Tape_symbols, "f").unshift(0);
|
|
83
|
+
__classPrivateFieldSet(this, _Tape_position, __classPrivateFieldGet(this, _Tape_position, "f") + 1, "f");
|
|
84
|
+
}
|
|
85
|
+
while (__classPrivateFieldGet(this, _Tape_position, "f") + this.extraCellsCount >= __classPrivateFieldGet(this, _Tape_symbols, "f").length) {
|
|
86
|
+
__classPrivateFieldGet(this, _Tape_symbols, "f").push(0);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
right() {
|
|
90
|
+
__classPrivateFieldSet(this, _Tape_position, __classPrivateFieldGet(this, _Tape_position, "f") + 1, "f");
|
|
91
|
+
this.normalise();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
_Tape_alphabet = new WeakMap(), _Tape_symbols = new WeakMap(), _Tape_position = new WeakMap(), _Tape_viewportWidth = new WeakMap();
|
|
95
|
+
export default Tape;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Alphabet from './Alphabet';
|
|
2
|
+
import Command from './Command';
|
|
3
|
+
import Tape from './Tape';
|
|
4
|
+
import Lock from './Lock';
|
|
5
|
+
declare const symbolToPatternListMapSymbol: unique symbol;
|
|
6
|
+
export declare const lockSymbol: unique symbol;
|
|
7
|
+
type PatternList = (string | symbol)[][];
|
|
8
|
+
type SymbolToPatternListMap = Map<symbol, PatternList>;
|
|
9
|
+
export default class TapeBlock {
|
|
10
|
+
#private;
|
|
11
|
+
private constructor();
|
|
12
|
+
get alphabets(): Alphabet[];
|
|
13
|
+
get currentSymbols(): string[];
|
|
14
|
+
get [lockSymbol](): Lock;
|
|
15
|
+
get symbol(): (symbols: (symbol | string)[] | symbol | string) => symbol;
|
|
16
|
+
get tapes(): Tape[];
|
|
17
|
+
set [symbolToPatternListMapSymbol](symbolToPatternListMap: SymbolToPatternListMap);
|
|
18
|
+
static fromAlphabets: (alphabets: Alphabet[]) => TapeBlock;
|
|
19
|
+
static fromTapes: (tapes: Tape[]) => TapeBlock;
|
|
20
|
+
applyCommand(command: Command, executionSymbol?: symbol | null): void;
|
|
21
|
+
clone(cloneTapes?: boolean): TapeBlock;
|
|
22
|
+
isMatched({ currentSymbols, symbol }: {
|
|
23
|
+
currentSymbols?: string[];
|
|
24
|
+
symbol: symbol;
|
|
25
|
+
}): boolean;
|
|
26
|
+
replaceTape(tape: Tape, tapeIx?: number): void;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _a, _TapeBlock_symbolToPatternListMap, _TapeBlock_lock, _TapeBlock_tapes, _TapeBlock_generateSymbolHint, _TapeBlock_buildPatternList, _TapeBlock_getSymbolForPatternList, _TapeBlock_symbol;
|
|
13
|
+
import Tape from './Tape';
|
|
14
|
+
import { ifOtherSymbol } from './State';
|
|
15
|
+
import { movements, symbolCommands } from './TapeCommand';
|
|
16
|
+
import Lock from './Lock';
|
|
17
|
+
const symbolToPatternListMapSymbol = Symbol('symbol for symbolToPatternListMap setter');
|
|
18
|
+
export const lockSymbol = Symbol('capture symbol');
|
|
19
|
+
class TapeBlock {
|
|
20
|
+
constructor(argument) {
|
|
21
|
+
_TapeBlock_symbolToPatternListMap.set(this, new Map());
|
|
22
|
+
_TapeBlock_lock.set(this, new Lock());
|
|
23
|
+
_TapeBlock_tapes.set(this, void 0);
|
|
24
|
+
_TapeBlock_buildPatternList.set(this, (symbolList) => symbolList.reduce((result, symbol, ix) => {
|
|
25
|
+
const row = Math.floor(ix / __classPrivateFieldGet(this, _TapeBlock_tapes, "f").length);
|
|
26
|
+
if (!Array.isArray(result[row])) {
|
|
27
|
+
result[row] = [];
|
|
28
|
+
}
|
|
29
|
+
result[row].push(symbol);
|
|
30
|
+
return result;
|
|
31
|
+
}, [])
|
|
32
|
+
.filter((pattern, ix, patternList) => {
|
|
33
|
+
const samePatternIx = patternList.findIndex((otherPattern) => (pattern
|
|
34
|
+
.every((symbol, symbolIx) => symbol === otherPattern[symbolIx])));
|
|
35
|
+
return samePatternIx === ix;
|
|
36
|
+
}));
|
|
37
|
+
_TapeBlock_getSymbolForPatternList.set(this, (patternList) => {
|
|
38
|
+
if (patternList.some((pattern) => pattern.every((symbol) => symbol === ifOtherSymbol))) {
|
|
39
|
+
return ifOtherSymbol;
|
|
40
|
+
}
|
|
41
|
+
const [storedPatternListSymbol] = [...__classPrivateFieldGet(this, _TapeBlock_symbolToPatternListMap, "f").entries()]
|
|
42
|
+
.find(([, storedPatternList]) => {
|
|
43
|
+
if (storedPatternList.length !== patternList.length) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return patternList
|
|
47
|
+
.every((pattern, patternIx) => pattern
|
|
48
|
+
.every((symbol, symbolIx) => symbol === storedPatternList[patternIx][symbolIx]));
|
|
49
|
+
}) || [null, null];
|
|
50
|
+
let symbol;
|
|
51
|
+
if (storedPatternListSymbol) {
|
|
52
|
+
symbol = storedPatternListSymbol;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
symbol = Symbol(__classPrivateFieldGet(_a, _a, "f", _TapeBlock_generateSymbolHint).call(_a, patternList));
|
|
56
|
+
__classPrivateFieldGet(this, _TapeBlock_symbolToPatternListMap, "f").set(symbol, patternList);
|
|
57
|
+
}
|
|
58
|
+
return symbol;
|
|
59
|
+
});
|
|
60
|
+
_TapeBlock_symbol.set(this, (symbols) => {
|
|
61
|
+
let localSymbols = [];
|
|
62
|
+
if (symbols === ifOtherSymbol) {
|
|
63
|
+
return ifOtherSymbol;
|
|
64
|
+
}
|
|
65
|
+
if (typeof symbols === 'string') {
|
|
66
|
+
localSymbols = symbols.split('');
|
|
67
|
+
}
|
|
68
|
+
else if (Array.isArray(symbols)) {
|
|
69
|
+
localSymbols = [...symbols];
|
|
70
|
+
}
|
|
71
|
+
if (localSymbols.length === 0 || localSymbols.length % __classPrivateFieldGet(this, _TapeBlock_tapes, "f").length > 0) {
|
|
72
|
+
throw new Error('invalid symbol parameter');
|
|
73
|
+
}
|
|
74
|
+
const invalidSymbolIndex = localSymbols.findIndex((symbol, ix) => (symbol !== ifOtherSymbol
|
|
75
|
+
&& !__classPrivateFieldGet(this, _TapeBlock_tapes, "f")[ix % __classPrivateFieldGet(this, _TapeBlock_tapes, "f").length].alphabet.has(symbol)));
|
|
76
|
+
if (invalidSymbolIndex >= 0) {
|
|
77
|
+
throw new Error('invalid symbol parameter');
|
|
78
|
+
}
|
|
79
|
+
if (localSymbols.every((symbol) => symbol === ifOtherSymbol)) {
|
|
80
|
+
return ifOtherSymbol;
|
|
81
|
+
}
|
|
82
|
+
return __classPrivateFieldGet(this, _TapeBlock_getSymbolForPatternList, "f").call(this, __classPrivateFieldGet(this, _TapeBlock_buildPatternList, "f").call(this, localSymbols));
|
|
83
|
+
});
|
|
84
|
+
__classPrivateFieldSet(this, _TapeBlock_tapes, [], "f");
|
|
85
|
+
if ('alphabets' in argument) {
|
|
86
|
+
const { alphabets } = argument;
|
|
87
|
+
if (alphabets.length === 0) {
|
|
88
|
+
throw new Error('empty alphabet list');
|
|
89
|
+
}
|
|
90
|
+
__classPrivateFieldSet(this, _TapeBlock_tapes, alphabets.map((alphabet) => new Tape({
|
|
91
|
+
alphabet,
|
|
92
|
+
})), "f");
|
|
93
|
+
}
|
|
94
|
+
else if ('tapes' in argument) {
|
|
95
|
+
__classPrivateFieldSet(this, _TapeBlock_tapes, argument.tapes, "f");
|
|
96
|
+
}
|
|
97
|
+
if (__classPrivateFieldGet(this, _TapeBlock_tapes, "f").length === 0) {
|
|
98
|
+
throw new Error('empty tape list');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
get alphabets() {
|
|
102
|
+
return [...__classPrivateFieldGet(this, _TapeBlock_tapes, "f").map((tape) => tape.alphabet)];
|
|
103
|
+
}
|
|
104
|
+
get currentSymbols() {
|
|
105
|
+
return __classPrivateFieldGet(this, _TapeBlock_tapes, "f").map((tape) => tape.symbol);
|
|
106
|
+
}
|
|
107
|
+
get [(_TapeBlock_symbolToPatternListMap = new WeakMap(), _TapeBlock_lock = new WeakMap(), _TapeBlock_tapes = new WeakMap(), _TapeBlock_buildPatternList = new WeakMap(), _TapeBlock_getSymbolForPatternList = new WeakMap(), _TapeBlock_symbol = new WeakMap(), lockSymbol)]() {
|
|
108
|
+
return __classPrivateFieldGet(this, _TapeBlock_lock, "f");
|
|
109
|
+
}
|
|
110
|
+
get symbol() {
|
|
111
|
+
return __classPrivateFieldGet(this, _TapeBlock_symbol, "f").bind(this);
|
|
112
|
+
}
|
|
113
|
+
get tapes() {
|
|
114
|
+
return [...__classPrivateFieldGet(this, _TapeBlock_tapes, "f")];
|
|
115
|
+
}
|
|
116
|
+
set [symbolToPatternListMapSymbol](symbolToPatternListMap) {
|
|
117
|
+
__classPrivateFieldSet(this, _TapeBlock_symbolToPatternListMap, new Map(symbolToPatternListMap), "f");
|
|
118
|
+
}
|
|
119
|
+
applyCommand(command, executionSymbol = null) {
|
|
120
|
+
__classPrivateFieldGet(this, _TapeBlock_lock, "f").check(executionSymbol);
|
|
121
|
+
if (__classPrivateFieldGet(this, _TapeBlock_tapes, "f").length !== command.tapesCommands.length) {
|
|
122
|
+
throw new Error('invalid command');
|
|
123
|
+
}
|
|
124
|
+
__classPrivateFieldGet(this, _TapeBlock_tapes, "f").forEach((tape, ix) => {
|
|
125
|
+
const { movement, symbol } = command.tapesCommands[ix];
|
|
126
|
+
if (typeof symbol === 'string') {
|
|
127
|
+
tape.symbol = symbol;
|
|
128
|
+
}
|
|
129
|
+
if (typeof symbol === 'symbol') {
|
|
130
|
+
switch (symbol) {
|
|
131
|
+
case symbolCommands.keep:
|
|
132
|
+
break;
|
|
133
|
+
case symbolCommands.erase:
|
|
134
|
+
tape.symbol = tape.alphabet.blankSymbol;
|
|
135
|
+
break;
|
|
136
|
+
// no default
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
switch (movement) {
|
|
140
|
+
case movements.left:
|
|
141
|
+
tape.left();
|
|
142
|
+
break;
|
|
143
|
+
case movements.stay:
|
|
144
|
+
break;
|
|
145
|
+
case movements.right:
|
|
146
|
+
tape.right();
|
|
147
|
+
break;
|
|
148
|
+
// no default
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
clone(cloneTapes = false) {
|
|
153
|
+
let tapeBlock;
|
|
154
|
+
if (cloneTapes) {
|
|
155
|
+
tapeBlock = _a.fromTapes(this.tapes.map((tape) => new Tape(tape)));
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
tapeBlock = _a.fromAlphabets(this.alphabets);
|
|
159
|
+
}
|
|
160
|
+
tapeBlock[symbolToPatternListMapSymbol] = __classPrivateFieldGet(this, _TapeBlock_symbolToPatternListMap, "f");
|
|
161
|
+
return tapeBlock;
|
|
162
|
+
}
|
|
163
|
+
isMatched({ currentSymbols = this.currentSymbols, symbol }) {
|
|
164
|
+
var _b;
|
|
165
|
+
if (symbol === ifOtherSymbol) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
if (!__classPrivateFieldGet(this, _TapeBlock_symbolToPatternListMap, "f").has(symbol)) {
|
|
169
|
+
throw new Error('invalid symbol');
|
|
170
|
+
}
|
|
171
|
+
const patternList = __classPrivateFieldGet(this, _TapeBlock_symbolToPatternListMap, "f").get(symbol);
|
|
172
|
+
return (_b = patternList === null || patternList === void 0 ? void 0 : patternList.some((pattern) => (pattern
|
|
173
|
+
.every((everySymbol, ix) => (everySymbol === ifOtherSymbol
|
|
174
|
+
|| everySymbol === currentSymbols[ix]))))) !== null && _b !== void 0 ? _b : false;
|
|
175
|
+
}
|
|
176
|
+
replaceTape(tape, tapeIx = 0) {
|
|
177
|
+
if (__classPrivateFieldGet(this, _TapeBlock_tapes, "f")[tapeIx] == null) {
|
|
178
|
+
throw new Error('invalid tapeIx');
|
|
179
|
+
}
|
|
180
|
+
if (tape.alphabet.symbols.join('') === __classPrivateFieldGet(this, _TapeBlock_tapes, "f")[tapeIx].alphabet.symbols.join('')) {
|
|
181
|
+
__classPrivateFieldGet(this, _TapeBlock_tapes, "f")[tapeIx] = tape;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
throw new Error('invalid tape');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
_a = TapeBlock;
|
|
189
|
+
TapeBlock.fromAlphabets = (alphabets) => {
|
|
190
|
+
return new _a({ alphabets });
|
|
191
|
+
};
|
|
192
|
+
TapeBlock.fromTapes = (tapes) => {
|
|
193
|
+
return new _a({ tapes });
|
|
194
|
+
};
|
|
195
|
+
_TapeBlock_generateSymbolHint = { value: (patternList) => JSON.stringify(patternList
|
|
196
|
+
.map((pattern) => pattern
|
|
197
|
+
.map((symbol) => (symbol === ifOtherSymbol ? null : symbol)))) };
|
|
198
|
+
export default TapeBlock;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const movements: {
|
|
2
|
+
left: symbol;
|
|
3
|
+
right: symbol;
|
|
4
|
+
stay: symbol;
|
|
5
|
+
};
|
|
6
|
+
export declare const symbolCommands: {
|
|
7
|
+
erase: symbol;
|
|
8
|
+
keep: symbol;
|
|
9
|
+
};
|
|
10
|
+
type TapeCommandConstructorParam = {
|
|
11
|
+
movement?: symbol;
|
|
12
|
+
symbol?: string | symbol;
|
|
13
|
+
};
|
|
14
|
+
export default class TapeCommand {
|
|
15
|
+
#private;
|
|
16
|
+
constructor({ movement, symbol, }: TapeCommandConstructorParam);
|
|
17
|
+
get symbol(): string | symbol;
|
|
18
|
+
get movement(): symbol;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _TapeCommand_movement, _TapeCommand_symbol;
|
|
13
|
+
export const movements = {
|
|
14
|
+
left: Symbol('move caret left command'),
|
|
15
|
+
right: Symbol('move caret right command'),
|
|
16
|
+
stay: Symbol('do not move carer'),
|
|
17
|
+
};
|
|
18
|
+
export const symbolCommands = {
|
|
19
|
+
erase: Symbol('erase symbol command'),
|
|
20
|
+
keep: Symbol('keep symbol command'),
|
|
21
|
+
};
|
|
22
|
+
class TapeCommand {
|
|
23
|
+
constructor({ movement = movements.stay, symbol = symbolCommands.keep, }) {
|
|
24
|
+
_TapeCommand_movement.set(this, void 0);
|
|
25
|
+
_TapeCommand_symbol.set(this, void 0);
|
|
26
|
+
const isValidMovement = [movements.left, movements.stay, movements.right].includes(movement);
|
|
27
|
+
if (!isValidMovement) {
|
|
28
|
+
throw new Error('invalid movement');
|
|
29
|
+
}
|
|
30
|
+
__classPrivateFieldSet(this, _TapeCommand_movement, movement, "f");
|
|
31
|
+
const isValidSymbol = ((typeof symbol === 'string' && symbol.length === 1)
|
|
32
|
+
|| [symbolCommands.keep, symbolCommands.erase].includes(symbol));
|
|
33
|
+
if (!isValidSymbol) {
|
|
34
|
+
throw new Error('invalid symbol');
|
|
35
|
+
}
|
|
36
|
+
__classPrivateFieldSet(this, _TapeCommand_symbol, symbol, "f");
|
|
37
|
+
}
|
|
38
|
+
get symbol() {
|
|
39
|
+
return __classPrivateFieldGet(this, _TapeCommand_symbol, "f");
|
|
40
|
+
}
|
|
41
|
+
get movement() {
|
|
42
|
+
return __classPrivateFieldGet(this, _TapeCommand_movement, "f");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
_TapeCommand_movement = new WeakMap(), _TapeCommand_symbol = new WeakMap();
|
|
46
|
+
export default TapeCommand;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import State from './State';
|
|
2
|
+
import TapeBlock from './TapeBlock';
|
|
3
|
+
type RunParameter = {
|
|
4
|
+
initialState: State;
|
|
5
|
+
stepsLimit?: number;
|
|
6
|
+
};
|
|
7
|
+
export type MachineState = {
|
|
8
|
+
step: number;
|
|
9
|
+
state: State;
|
|
10
|
+
currentSymbols: string[];
|
|
11
|
+
nextSymbols: string[];
|
|
12
|
+
movements: symbol[];
|
|
13
|
+
nextState: State;
|
|
14
|
+
};
|
|
15
|
+
export default class TuringMachine {
|
|
16
|
+
#private;
|
|
17
|
+
constructor({ tapeBlock, }?: {
|
|
18
|
+
tapeBlock?: TapeBlock;
|
|
19
|
+
});
|
|
20
|
+
get tapeBlock(): TapeBlock;
|
|
21
|
+
run({ initialState, stepsLimit, onStep }: RunParameter & {
|
|
22
|
+
onStep?: (machineState: MachineState) => void;
|
|
23
|
+
}): void;
|
|
24
|
+
runStepByStep({ initialState, stepsLimit }: RunParameter): Generator<MachineState>;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _TuringMachine_tapeBlock, _TuringMachine_stack;
|
|
13
|
+
import { haltState } from './State';
|
|
14
|
+
import { lockSymbol } from './TapeBlock';
|
|
15
|
+
import { symbolCommands } from './TapeCommand';
|
|
16
|
+
class TuringMachine {
|
|
17
|
+
constructor({ tapeBlock, } = {}) {
|
|
18
|
+
_TuringMachine_tapeBlock.set(this, void 0);
|
|
19
|
+
_TuringMachine_stack.set(this, []);
|
|
20
|
+
if (!tapeBlock) {
|
|
21
|
+
throw new Error('invalid tapeBlock');
|
|
22
|
+
}
|
|
23
|
+
__classPrivateFieldSet(this, _TuringMachine_tapeBlock, tapeBlock, "f");
|
|
24
|
+
}
|
|
25
|
+
get tapeBlock() {
|
|
26
|
+
return __classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f");
|
|
27
|
+
}
|
|
28
|
+
run({ initialState, stepsLimit = 1e5, onStep }) {
|
|
29
|
+
const generator = this.runStepByStep({ initialState, stepsLimit });
|
|
30
|
+
for (const machineState of generator) {
|
|
31
|
+
if (onStep instanceof Function) {
|
|
32
|
+
onStep(machineState);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
*runStepByStep({ initialState, stepsLimit = 1e5 }) {
|
|
37
|
+
const executionSymbol = Symbol('execution');
|
|
38
|
+
try {
|
|
39
|
+
__classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f")[lockSymbol].check(executionSymbol);
|
|
40
|
+
__classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f")[lockSymbol].lock(executionSymbol);
|
|
41
|
+
const stack = __classPrivateFieldGet(this, _TuringMachine_stack, "f");
|
|
42
|
+
let state = initialState;
|
|
43
|
+
if (state.overrodeHaltState) {
|
|
44
|
+
stack.push(state.overrodeHaltState);
|
|
45
|
+
}
|
|
46
|
+
let i = 0;
|
|
47
|
+
while (!state.isHalt) {
|
|
48
|
+
if (i === stepsLimit) {
|
|
49
|
+
throw new Error('Long execution');
|
|
50
|
+
}
|
|
51
|
+
i += 1;
|
|
52
|
+
const symbol = state.getSymbol(__classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f"));
|
|
53
|
+
const command = state.getCommand(symbol);
|
|
54
|
+
let nextState = state.getNextState(symbol).ref;
|
|
55
|
+
try {
|
|
56
|
+
const nextStateForYield = nextState.isHalt && stack.length
|
|
57
|
+
? stack.slice(-1)[0]
|
|
58
|
+
: nextState;
|
|
59
|
+
yield {
|
|
60
|
+
step: i,
|
|
61
|
+
state,
|
|
62
|
+
currentSymbols: __classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f").currentSymbols,
|
|
63
|
+
nextSymbols: command.tapesCommands.map((tapeCommand, ix) => {
|
|
64
|
+
if (typeof tapeCommand.symbol === 'symbol') {
|
|
65
|
+
switch (tapeCommand.symbol) {
|
|
66
|
+
case symbolCommands.erase:
|
|
67
|
+
return __classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f").tapes[ix].alphabet.blankSymbol;
|
|
68
|
+
case symbolCommands.keep:
|
|
69
|
+
return __classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f").tapes[ix].symbol;
|
|
70
|
+
default:
|
|
71
|
+
throw new Error('invalid symbol command');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return tapeCommand.symbol;
|
|
75
|
+
}),
|
|
76
|
+
movements: command.tapesCommands.map((tapeCommand) => tapeCommand.movement),
|
|
77
|
+
nextState: nextStateForYield,
|
|
78
|
+
};
|
|
79
|
+
__classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f").applyCommand(command, executionSymbol);
|
|
80
|
+
if (nextState.isHalt && stack.length) {
|
|
81
|
+
nextState = stack.pop();
|
|
82
|
+
}
|
|
83
|
+
if (state !== nextState && nextState.overrodeHaltState) {
|
|
84
|
+
stack.push(nextState.overrodeHaltState);
|
|
85
|
+
}
|
|
86
|
+
state = nextState;
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (error !== haltState) {
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
__classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f")[lockSymbol].unlock(executionSymbol);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
_TuringMachine_tapeBlock = new WeakMap(), _TuringMachine_stack = new WeakMap();
|
|
102
|
+
export default TuringMachine;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as Alphabet } from './classes/Alphabet';
|
|
2
|
+
export { default as Command } from './classes/Command';
|
|
3
|
+
export { default as Reference } from './classes/Reference';
|
|
4
|
+
export { default as State, haltState, ifOtherSymbol } from './classes/State';
|
|
5
|
+
export { default as Tape } from './classes/Tape';
|
|
6
|
+
export { default as TapeBlock } from './classes/TapeBlock';
|
|
7
|
+
export { default as TapeCommand, movements, symbolCommands } from './classes/TapeCommand';
|
|
8
|
+
export { default as TuringMachine } from './classes/TuringMachine';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as Alphabet } from './classes/Alphabet';
|
|
2
|
+
export { default as Command } from './classes/Command';
|
|
3
|
+
export { default as Reference } from './classes/Reference';
|
|
4
|
+
export { default as State, haltState, ifOtherSymbol } from './classes/State';
|
|
5
|
+
export { default as Tape } from './classes/Tape';
|
|
6
|
+
export { default as TapeBlock } from './classes/TapeBlock';
|
|
7
|
+
export { default as TapeCommand, movements, symbolCommands } from './classes/TapeCommand';
|
|
8
|
+
export { default as TuringMachine } from './classes/TuringMachine';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const uniquePredicate = (v, i, a) => a.indexOf(v) === i;
|
|
2
|
+
const idKey = Symbol('idCurrentKey');
|
|
3
|
+
const idWeakMapKey = Symbol('idWeakMapKey');
|
|
4
|
+
function id(object) {
|
|
5
|
+
if (!id[idWeakMapKey].has(object)) {
|
|
6
|
+
id[idWeakMapKey].set(object, id[idKey]);
|
|
7
|
+
id[idKey] += 1;
|
|
8
|
+
}
|
|
9
|
+
return id[idWeakMapKey].get(object);
|
|
10
|
+
}
|
|
11
|
+
id[idKey] = 0;
|
|
12
|
+
id[idWeakMapKey] = new WeakMap();
|
|
13
|
+
export { id, uniquePredicate, };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turing-machine-js/machine",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.2",
|
|
4
4
|
"description": "A convenient Turing machine",
|
|
5
5
|
"author": "Ruslan Gilmullin <mellonis14@gmain.com>",
|
|
6
6
|
"homepage": "https://github.com/mellonis/turing-machine-js#readme",
|
|
@@ -21,5 +21,5 @@
|
|
|
21
21
|
"machine"
|
|
22
22
|
],
|
|
23
23
|
"module": "dist/index.js",
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "5f0e4eaf5c2671438590a479261481ad4bec58bd"
|
|
25
25
|
}
|