@turing-machine-js/machine 2.0.0-alpha.1 → 2.0.0
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/Lock.d.ts +6 -0
- package/dist/classes/Lock.js +34 -0
- package/dist/classes/State.js +1 -1
- package/dist/classes/TapeBlock.d.ts +7 -4
- package/dist/classes/TapeBlock.js +20 -13
- package/dist/classes/TuringMachine.js +60 -51
- package/dist/utilities/functions.d.ts +1 -1
- package/package.json +2 -2
|
@@ -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;
|
package/dist/classes/State.js
CHANGED
|
@@ -93,7 +93,7 @@ class State {
|
|
|
93
93
|
if (__classPrivateFieldGet(this, _State_symbolToDataMap, "f").has(symbol)) {
|
|
94
94
|
return __classPrivateFieldGet(this, _State_symbolToDataMap, "f").get(symbol).command;
|
|
95
95
|
}
|
|
96
|
-
throw new Error(`No command for symbol at state named ${__classPrivateFieldGet(this,
|
|
96
|
+
throw new Error(`No command for symbol at state named ${__classPrivateFieldGet(this, _State_name, "f")}`);
|
|
97
97
|
}
|
|
98
98
|
getNextState(symbol) {
|
|
99
99
|
if (__classPrivateFieldGet(this, _State_symbolToDataMap, "f").has(symbol)) {
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import Alphabet from './Alphabet';
|
|
2
2
|
import Command from './Command';
|
|
3
3
|
import Tape from './Tape';
|
|
4
|
+
import Lock from './Lock';
|
|
4
5
|
declare const symbolToPatternListMapSymbol: unique symbol;
|
|
6
|
+
export declare const lockSymbol: unique symbol;
|
|
5
7
|
type PatternList = (string | symbol)[][];
|
|
6
8
|
type SymbolToPatternListMap = Map<symbol, PatternList>;
|
|
7
9
|
export default class TapeBlock {
|
|
8
10
|
#private;
|
|
9
|
-
static fromAlphabets: (alphabets: Alphabet[]) => TapeBlock;
|
|
10
|
-
static fromTapes: (tapes: Tape[]) => TapeBlock;
|
|
11
11
|
private constructor();
|
|
12
12
|
get alphabets(): Alphabet[];
|
|
13
13
|
get currentSymbols(): string[];
|
|
14
|
+
get [lockSymbol](): Lock;
|
|
14
15
|
get symbol(): (symbols: (symbol | string)[] | symbol | string) => symbol;
|
|
15
16
|
get tapes(): Tape[];
|
|
16
|
-
|
|
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;
|
|
17
21
|
clone(cloneTapes?: boolean): TapeBlock;
|
|
18
22
|
isMatched({ currentSymbols, symbol }: {
|
|
19
23
|
currentSymbols?: string[];
|
|
20
24
|
symbol: symbol;
|
|
21
25
|
}): boolean;
|
|
22
26
|
replaceTape(tape: Tape, tapeIx?: number): void;
|
|
23
|
-
[symbolToPatternListMapSymbol]: (symbolToPatternListMap: SymbolToPatternListMap) => void;
|
|
24
27
|
}
|
|
25
28
|
export {};
|
|
@@ -9,18 +9,18 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
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
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _a, _TapeBlock_symbolToPatternListMap, _TapeBlock_tapes, _TapeBlock_generateSymbolHint, _TapeBlock_buildPatternList, _TapeBlock_getSymbolForPatternList, _TapeBlock_symbol
|
|
12
|
+
var _a, _TapeBlock_symbolToPatternListMap, _TapeBlock_lock, _TapeBlock_tapes, _TapeBlock_generateSymbolHint, _TapeBlock_buildPatternList, _TapeBlock_getSymbolForPatternList, _TapeBlock_symbol;
|
|
13
13
|
import Tape from './Tape';
|
|
14
14
|
import { ifOtherSymbol } from './State';
|
|
15
15
|
import { movements, symbolCommands } from './TapeCommand';
|
|
16
|
+
import Lock from './Lock';
|
|
16
17
|
const symbolToPatternListMapSymbol = Symbol('symbol for symbolToPatternListMap setter');
|
|
18
|
+
export const lockSymbol = Symbol('capture symbol');
|
|
17
19
|
class TapeBlock {
|
|
18
20
|
constructor(argument) {
|
|
19
21
|
_TapeBlock_symbolToPatternListMap.set(this, new Map());
|
|
22
|
+
_TapeBlock_lock.set(this, new Lock());
|
|
20
23
|
_TapeBlock_tapes.set(this, void 0);
|
|
21
|
-
this[_b] = (symbolToPatternListMap) => {
|
|
22
|
-
__classPrivateFieldSet(this, _TapeBlock_symbolToPatternListMap, new Map(symbolToPatternListMap), "f");
|
|
23
|
-
};
|
|
24
24
|
_TapeBlock_buildPatternList.set(this, (symbolList) => symbolList.reduce((result, symbol, ix) => {
|
|
25
25
|
const row = Math.floor(ix / __classPrivateFieldGet(this, _TapeBlock_tapes, "f").length);
|
|
26
26
|
if (!Array.isArray(result[row])) {
|
|
@@ -104,13 +104,20 @@ class TapeBlock {
|
|
|
104
104
|
get currentSymbols() {
|
|
105
105
|
return __classPrivateFieldGet(this, _TapeBlock_tapes, "f").map((tape) => tape.symbol);
|
|
106
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
|
+
}
|
|
107
110
|
get symbol() {
|
|
108
111
|
return __classPrivateFieldGet(this, _TapeBlock_symbol, "f").bind(this);
|
|
109
112
|
}
|
|
110
113
|
get tapes() {
|
|
111
114
|
return [...__classPrivateFieldGet(this, _TapeBlock_tapes, "f")];
|
|
112
115
|
}
|
|
113
|
-
|
|
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);
|
|
114
121
|
if (__classPrivateFieldGet(this, _TapeBlock_tapes, "f").length !== command.tapesCommands.length) {
|
|
115
122
|
throw new Error('invalid command');
|
|
116
123
|
}
|
|
@@ -150,11 +157,11 @@ class TapeBlock {
|
|
|
150
157
|
else {
|
|
151
158
|
tapeBlock = _a.fromAlphabets(this.alphabets);
|
|
152
159
|
}
|
|
153
|
-
tapeBlock[symbolToPatternListMapSymbol]
|
|
160
|
+
tapeBlock[symbolToPatternListMapSymbol] = __classPrivateFieldGet(this, _TapeBlock_symbolToPatternListMap, "f");
|
|
154
161
|
return tapeBlock;
|
|
155
162
|
}
|
|
156
163
|
isMatched({ currentSymbols = this.currentSymbols, symbol }) {
|
|
157
|
-
var
|
|
164
|
+
var _b;
|
|
158
165
|
if (symbol === ifOtherSymbol) {
|
|
159
166
|
return true;
|
|
160
167
|
}
|
|
@@ -162,9 +169,9 @@ class TapeBlock {
|
|
|
162
169
|
throw new Error('invalid symbol');
|
|
163
170
|
}
|
|
164
171
|
const patternList = __classPrivateFieldGet(this, _TapeBlock_symbolToPatternListMap, "f").get(symbol);
|
|
165
|
-
return (
|
|
172
|
+
return (_b = patternList === null || patternList === void 0 ? void 0 : patternList.some((pattern) => (pattern
|
|
166
173
|
.every((everySymbol, ix) => (everySymbol === ifOtherSymbol
|
|
167
|
-
|| everySymbol === currentSymbols[ix]))))) !== null &&
|
|
174
|
+
|| everySymbol === currentSymbols[ix]))))) !== null && _b !== void 0 ? _b : false;
|
|
168
175
|
}
|
|
169
176
|
replaceTape(tape, tapeIx = 0) {
|
|
170
177
|
if (__classPrivateFieldGet(this, _TapeBlock_tapes, "f")[tapeIx] == null) {
|
|
@@ -178,14 +185,14 @@ class TapeBlock {
|
|
|
178
185
|
}
|
|
179
186
|
}
|
|
180
187
|
}
|
|
181
|
-
_a = TapeBlock
|
|
182
|
-
_TapeBlock_generateSymbolHint = { value: (patternList) => JSON.stringify(patternList
|
|
183
|
-
.map((pattern) => pattern
|
|
184
|
-
.map((symbol) => (symbol === ifOtherSymbol ? null : symbol)))) };
|
|
188
|
+
_a = TapeBlock;
|
|
185
189
|
TapeBlock.fromAlphabets = (alphabets) => {
|
|
186
190
|
return new _a({ alphabets });
|
|
187
191
|
};
|
|
188
192
|
TapeBlock.fromTapes = (tapes) => {
|
|
189
193
|
return new _a({ tapes });
|
|
190
194
|
};
|
|
195
|
+
_TapeBlock_generateSymbolHint = { value: (patternList) => JSON.stringify(patternList
|
|
196
|
+
.map((pattern) => pattern
|
|
197
|
+
.map((symbol) => (symbol === ifOtherSymbol ? null : symbol)))) };
|
|
191
198
|
export default TapeBlock;
|
|
@@ -11,6 +11,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
};
|
|
12
12
|
var _TuringMachine_tapeBlock, _TuringMachine_stack;
|
|
13
13
|
import { haltState } from './State';
|
|
14
|
+
import { lockSymbol } from './TapeBlock';
|
|
14
15
|
import { symbolCommands } from './TapeCommand';
|
|
15
16
|
class TuringMachine {
|
|
16
17
|
constructor({ tapeBlock, } = {}) {
|
|
@@ -25,67 +26,75 @@ class TuringMachine {
|
|
|
25
26
|
return __classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f");
|
|
26
27
|
}
|
|
27
28
|
run({ initialState, stepsLimit = 1e5, onStep }) {
|
|
28
|
-
const
|
|
29
|
-
for (const machineState of
|
|
29
|
+
const generator = this.runStepByStep({ initialState, stepsLimit });
|
|
30
|
+
for (const machineState of generator) {
|
|
30
31
|
if (onStep instanceof Function) {
|
|
31
32
|
onStep(machineState);
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
*runStepByStep({ initialState, stepsLimit = 1e5 }) {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
throw new Error('Long execution');
|
|
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
45
|
}
|
|
46
|
-
i
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
+
}
|
|
67
73
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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;
|
|
78
93
|
}
|
|
79
|
-
throw error;
|
|
80
|
-
}
|
|
81
|
-
__classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f").applyCommand(command);
|
|
82
|
-
if (nextState.isHalt && stack.length) {
|
|
83
|
-
nextState = stack.pop();
|
|
84
|
-
}
|
|
85
|
-
if (state !== nextState && nextState.overrodeHaltState) {
|
|
86
|
-
stack.push(nextState.overrodeHaltState);
|
|
87
94
|
}
|
|
88
|
-
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
__classPrivateFieldGet(this, _TuringMachine_tapeBlock, "f")[lockSymbol].unlock(executionSymbol);
|
|
89
98
|
}
|
|
90
99
|
}
|
|
91
100
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turing-machine-js/machine",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
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": "7ed5b8d294b24bf92c1d26e27b752004fe5055dc"
|
|
25
25
|
}
|