@turing-machine-js/machine 2.0.2 → 3.0.1
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/CHANGELOG.md +54 -0
- package/README.md +256 -12
- package/dist/classes/State.d.ts +27 -0
- package/dist/index.cjs +775 -173
- package/dist/index.d.ts +5 -1
- package/dist/index.mjs +771 -174
- package/dist/utilities/equivalence.d.ts +31 -0
- package/dist/utilities/graph.d.ts +29 -0
- package/dist/utilities/graphFormats.d.ts +3 -0
- package/dist/utilities/introspection.d.ts +15 -0
- package/package.json +2 -8
- package/dist/classes/Alphabet.js +0 -50
- package/dist/classes/Command.js +0 -38
- package/dist/classes/Lock.js +0 -34
- package/dist/classes/Reference.js +0 -31
- package/dist/classes/State.js +0 -113
- package/dist/classes/Tape.js +0 -95
- package/dist/classes/TapeBlock.js +0 -198
- package/dist/classes/TapeCommand.js +0 -46
- package/dist/classes/TuringMachine.js +0 -102
- package/dist/index.js +0 -8
- package/dist/utilities/functions.js +0 -13
- package/tsconfig.tsbuildinfo +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [3.0.1] - 2026-04-30
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **`graphFormats.ts` — polynomial-time regex (CodeQL `js/polynomial-redos`).** `alphabetsRegex` was `/^%%\s*alphabets:\s*(.+)$/`, where the `\s*` and `(.+)` both match whitespace, letting the engine try N+1 split points on inputs like `"%%alphabets:"` followed by many trailing spaces. Anchored the first captured char as `\S` to remove the ambiguity.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`MachineState` re-export** from `index.ts`. The type was always `export type MachineState = ...` in `classes/TuringMachine.ts`, but the package barrel didn't surface it. Consumers (notably `@post-machine-js/machine`'s `PostMachine` overrides of `run` / `runStepByStep`) can now `import { type MachineState } from '@turing-machine-js/machine'` directly, dropping any local `Generator<infer T>` workaround.
|
|
16
|
+
|
|
17
|
+
### Changed (internal)
|
|
18
|
+
|
|
19
|
+
- Removed the unreachable `if (hasCycles) return` guard at the top of `summarizeGraph`'s `visit()` cycle-detection. The recursive call pattern (outer for-loop checks before calling, inner loop checks after each recursive call) ensures `visit()` is never invoked when `hasCycles` is already true. Static analysis confirmed the guard was dead code.
|
|
20
|
+
- Tightened test coverage on `State.ts` and the v3 utilities — overall coverage rose from 95.64% / 88.39% / 95.5% (statements/branches/lines) to 98.39% / 94.01% / 98.34%. New tests cover invalid-input paths in the `State` constructor (string-keyed definitions, non-`State`/`Reference` `nextState`, empty-array commands), the `getSymbol` fallback to `ifOtherSymbol`, the `toGraph` skip of unbound `Reference` transitions, the `fromGraph` cyclic-override-halt error, and the previously-unexercised branches in `splitUnescaped`, `parsePatternString`, `parseMovementLabel`, and `fromMermaid`'s ensureNode update / error paths.
|
|
21
|
+
|
|
22
|
+
## [3.0.0] - 2026-04-30
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **`State.toGraph(state, tapeBlock)`** static — walks the reachable graph from a state and returns a serializable `Graph` (states, transitions, alphabets).
|
|
27
|
+
- **`State.fromGraph(graph)`** static — inverse of `toGraph`; rebuilds `State` instances + a fresh `TapeBlock` from a `Graph`. Round-trips losslessly via `toMermaid` / `fromMermaid`.
|
|
28
|
+
- **`State.inspect(state)`** static — single-state introspection (id, name, isHalt, override-halt target, transitions) without graph traversal or a tapeBlock.
|
|
29
|
+
- **`toMermaid(graph)`** — renders a `Graph` to Mermaid flowchart syntax.
|
|
30
|
+
- **`fromMermaid(text)`** — parses Mermaid produced by `toMermaid` back into a `Graph`.
|
|
31
|
+
- **`summarize(state, tapeBlock)`** / **`summarizeGraph(graph)`** — quantitative analysis of a state graph (state count, transition count, composition depth, cycles, alphabet sizes). Useful for comparing two implementations of the same algorithm.
|
|
32
|
+
- **`equivalentOn(reference, candidate, cases, options?)`** — behavioral equivalence checking. Runs both machines on test cases and reports agreement, first-divergence step, and per-side step counts. Supports same-alphabet and (with custom comparator) cross-alphabet comparison.
|
|
33
|
+
- New type exports: `Graph`, `GraphNode`, `GraphTransition`, `GraphCommand`, `GraphSummary`, `Runnable`, `EquivalenceCase`, `EquivalenceResult`, `EquivalenceReport`.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- TypeScript `target` and `module` raised from `ES6` to `ES2020` (consumers see compiled `dist/` only — no observable difference).
|
|
38
|
+
|
|
39
|
+
### Removed
|
|
40
|
+
|
|
41
|
+
- **BREAKING** — the `./src` subpath in `package.json` `exports` was removed. Consumers using `import { ... } from '@turing-machine-js/machine/src'` must drop the `/src` suffix and use `import { ... } from '@turing-machine-js/machine'`.
|
|
42
|
+
|
|
43
|
+
### Migration
|
|
44
|
+
|
|
45
|
+
```diff
|
|
46
|
+
- import { ... } from '@turing-machine-js/machine/src';
|
|
47
|
+
+ import { ... } from '@turing-machine-js/machine';
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The `/src` subpath was an in-monorepo dev-time shim that never had a real reason to be on the npm tarball.
|
|
51
|
+
|
|
52
|
+
## [2.0.2] - earlier
|
|
53
|
+
|
|
54
|
+
Initial public 2.x release.
|
package/README.md
CHANGED
|
@@ -13,48 +13,292 @@ Using npm:
|
|
|
13
13
|
npm install @turing-machine-js/machine
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
Replace every `b` on the tape with `*`:
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
import {
|
|
22
|
+
Alphabet,
|
|
23
|
+
State,
|
|
24
|
+
Tape,
|
|
25
|
+
TapeBlock,
|
|
26
|
+
TuringMachine,
|
|
27
|
+
haltState,
|
|
28
|
+
ifOtherSymbol,
|
|
29
|
+
movements,
|
|
30
|
+
} from '@turing-machine-js/machine';
|
|
31
|
+
|
|
32
|
+
const alphabet = new Alphabet([' ', 'a', 'b', 'c', '*']);
|
|
33
|
+
const tape = new Tape({ alphabet, symbols: ['a', 'b', 'c', 'b', 'a'] });
|
|
34
|
+
const tapeBlock = TapeBlock.fromTapes([tape]);
|
|
35
|
+
const machine = new TuringMachine({ tapeBlock });
|
|
36
|
+
|
|
37
|
+
machine.run({
|
|
38
|
+
initialState: new State({
|
|
39
|
+
[tapeBlock.symbol(['b'])]: {
|
|
40
|
+
command: [{ symbol: '*', movement: movements.right }],
|
|
41
|
+
},
|
|
42
|
+
[tapeBlock.symbol([alphabet.blankSymbol])]: {
|
|
43
|
+
command: [{ movement: movements.left }],
|
|
44
|
+
nextState: haltState,
|
|
45
|
+
},
|
|
46
|
+
[ifOtherSymbol]: {
|
|
47
|
+
command: [{ movement: movements.right }],
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
console.log(tape.symbols.join('').trim()); // a*c*a
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
A `State` is keyed by JS `Symbol`s returned from `tapeBlock.symbol(pattern)` — the pattern lists the expected symbol under each tape's head. `ifOtherSymbol` is the fallback key when nothing else matches; transitioning into `haltState` stops the run.
|
|
56
|
+
|
|
57
|
+
For multi-tape machines, pass one element per tape: `tapeBlock.symbol(['0', 'a'])` matches only when tape 1 is at `'0'` and tape 2 is at `'a'`.
|
|
58
|
+
|
|
59
|
+
## Building from a state table
|
|
60
|
+
|
|
61
|
+
If you prefer a textbook-style declarative API where every transition is one row of `(state, currentSymbol) → (nextState, nextSymbol, movement)`, you can build a small helper on top of the raw API. The whole thing fits in ~30 lines:
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
import {
|
|
65
|
+
Alphabet,
|
|
66
|
+
Reference,
|
|
67
|
+
State,
|
|
68
|
+
TapeBlock,
|
|
69
|
+
TuringMachine,
|
|
70
|
+
haltState,
|
|
71
|
+
ifOtherSymbol,
|
|
72
|
+
movements,
|
|
73
|
+
symbolCommands,
|
|
74
|
+
} from '@turing-machine-js/machine';
|
|
75
|
+
|
|
76
|
+
function buildFromTable({ alphabetString, initialState, finalStates, table }) {
|
|
77
|
+
const alphabet = new Alphabet(alphabetString.split(''));
|
|
78
|
+
const tapeBlock = TapeBlock.fromAlphabets([alphabet]);
|
|
79
|
+
const movementOf = { L: movements.left, R: movements.right, S: movements.stay };
|
|
80
|
+
|
|
81
|
+
// Pre-create a Reference per state name so transitions can point forward.
|
|
82
|
+
const refs = Object.fromEntries(Object.keys(table).map((name) => [name, new Reference()]));
|
|
83
|
+
const states = {};
|
|
84
|
+
|
|
85
|
+
for (const [name, row] of Object.entries(table)) {
|
|
86
|
+
const def = {};
|
|
87
|
+
for (const [read, action] of Object.entries(row)) {
|
|
88
|
+
const key = read === '*' ? ifOtherSymbol : tapeBlock.symbol([read]);
|
|
89
|
+
def[key] = {
|
|
90
|
+
command: {
|
|
91
|
+
symbol: action.write ?? symbolCommands.keep,
|
|
92
|
+
movement: movementOf[action.move ?? 'S'],
|
|
93
|
+
},
|
|
94
|
+
nextState: finalStates.includes(action.goto) ? haltState : refs[action.goto],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
states[name] = new State(def, name);
|
|
98
|
+
refs[name].bind(states[name]);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return { tapeBlock, machine: new TuringMachine({ tapeBlock }), initialState: states[initialState] };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Same "replace b with *" example as above, written declaratively:
|
|
105
|
+
const { tapeBlock, machine, initialState } = buildFromTable({
|
|
106
|
+
alphabetString: ' abc*',
|
|
107
|
+
initialState: 'scan',
|
|
108
|
+
finalStates: ['HALT'],
|
|
109
|
+
table: {
|
|
110
|
+
scan: {
|
|
111
|
+
'b': { write: '*', move: 'R', goto: 'scan' },
|
|
112
|
+
' ': { move: 'L', goto: 'HALT' },
|
|
113
|
+
'*': { move: 'R', goto: 'scan' }, // '*' = ifOtherSymbol
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
This is what [`@turing-machine-js/builder`](../builder) provides as a separate package. Inline lets you tweak the format (multi-tape, OR-patterns, custom action shapes) freely; the builder package is more opinionated and limited to single-tape, single-symbol-per-row transitions.
|
|
120
|
+
|
|
16
121
|
## Classes
|
|
17
122
|
|
|
18
123
|
### Alphabet
|
|
19
124
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
### Reference
|
|
125
|
+
The set of single-character symbols a tape can hold. The **first** symbol passed to the constructor is the blank — it fills any tape cell the head reaches before that cell has been written. At least two unique single-character symbols are required.
|
|
23
126
|
|
|
24
|
-
|
|
127
|
+
```javascript
|
|
128
|
+
const alphabet = new Alphabet([' ', '0', '1']);
|
|
129
|
+
alphabet.blankSymbol; // ' '
|
|
130
|
+
alphabet.symbols; // [' ', '0', '1']
|
|
131
|
+
alphabet.has('0'); // true
|
|
132
|
+
alphabet.index('1'); // 2
|
|
133
|
+
```
|
|
25
134
|
|
|
26
135
|
### Tape
|
|
27
136
|
|
|
137
|
+
An infinite-in-both-directions sequence of cells over an `Alphabet`, plus a head position. Cells the head moves into that haven't been written are blank.
|
|
138
|
+
|
|
139
|
+
```javascript
|
|
140
|
+
const tape = new Tape({ alphabet, symbols: ['a', 'b', 'c'], position: 0 });
|
|
141
|
+
tape.symbol; // 'a' (cell under head)
|
|
142
|
+
tape.right(); // move head right; auto-extends with blanks at the edge
|
|
143
|
+
tape.symbol = 'X'; // write the cell under head
|
|
144
|
+
```
|
|
145
|
+
|
|
28
146
|
### TapeBlock
|
|
29
147
|
|
|
148
|
+
A bundle of one or more `Tape`s that the machine reads/writes together in lock-step. Construct via either factory:
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
TapeBlock.fromAlphabets([alphabetA, alphabetB]); // creates fresh blank tapes
|
|
152
|
+
TapeBlock.fromTapes([tape1, tape2]); // reuses existing tapes
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The key method is **`tapeBlock.symbol(pattern)`**: it returns an interned JS `Symbol` that simultaneously serves as a `State`'s transition key *and* matches the current configuration across all tapes. The pattern is one alphabet character per tape; pass several patterns by concatenating to express alternatives.
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
tapeBlock.symbol(['^']); // single tape: matches '^'
|
|
159
|
+
tapeBlock.symbol(['^', '0', '1', '$']); // single tape: matches any of '^', '0', '1', '$'
|
|
160
|
+
tapeBlock.symbol(['0', 'a']); // 2 tapes: matches when tape 1 is '0' AND tape 2 is 'a'
|
|
161
|
+
```
|
|
162
|
+
|
|
30
163
|
### TapeCommand
|
|
31
164
|
|
|
165
|
+
A single-tape instruction the machine applies in one step: optionally write a symbol, optionally move the head. Defaults to *keep current symbol, do not move*.
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
const cmds = [
|
|
169
|
+
{ symbol: '0', movement: movements.right }, // write '0' and move right
|
|
170
|
+
{ movement: movements.left }, // keep current symbol, move left
|
|
171
|
+
{ symbol: symbolCommands.erase }, // write the blank, stay
|
|
172
|
+
{}, // no-op
|
|
173
|
+
];
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
You'll rarely construct `TapeCommand` instances yourself — pass plain objects in your `State` definitions and they're wrapped automatically.
|
|
177
|
+
|
|
178
|
+
### Command
|
|
179
|
+
|
|
180
|
+
A bundle of `TapeCommand`s, one per tape in the `TapeBlock`. Like `TapeCommand`, you usually pass a plain array in the `State` definition rather than constructing `Command` directly.
|
|
181
|
+
|
|
182
|
+
### State
|
|
183
|
+
|
|
184
|
+
A node in the transition graph. Construct with a definition object whose keys are JS `Symbol`s from `tapeBlock.symbol(...)` (or `ifOtherSymbol` for the catch-all). Each value is `{ command, nextState }`.
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
const s = new State({
|
|
188
|
+
[tapeBlock.symbol(['1'])]: { command: { symbol: '0', movement: movements.right } },
|
|
189
|
+
[tapeBlock.symbol(['$'])]: { nextState: haltState },
|
|
190
|
+
[ifOtherSymbol]: { command: { movement: movements.right } },
|
|
191
|
+
}, 'name');
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Notable members and statics:
|
|
195
|
+
|
|
196
|
+
- **`state.id`**, **`state.name`** — identity (`isHalt` is `id === 0`).
|
|
197
|
+
- **`state.withOverrodeHaltState(other)`** — returns a copy whose would-be halt transitions fall through to `other`. The subroutine-call composition mechanism (see `library-binary-numbers/src/index.ts` for examples).
|
|
198
|
+
- **`State.toGraph(state, tapeBlock)`** — walks the reachable graph from `state` and returns a serializable `Graph` (states, transitions, alphabets).
|
|
199
|
+
- **`State.fromGraph(graph)`** — inverse of `toGraph`: rebuilds `State` instances + a fresh `TapeBlock` from a `Graph`. Round-trips together with `toMermaid` / `fromMermaid`.
|
|
200
|
+
|
|
201
|
+
### Reference
|
|
202
|
+
|
|
203
|
+
A forward-declaration handle, used when a `State` needs to point at another `State` that doesn't exist yet (cyclic graphs). Construct unbound, pass as `nextState`, call `.bind(actualState)` once that state has been built.
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
const ref = new Reference();
|
|
207
|
+
const a = new State({ [symbol(['x'])]: { nextState: ref } }, 'a');
|
|
208
|
+
const b = new State({ [symbol(['y'])]: { nextState: a } }, 'b');
|
|
209
|
+
ref.bind(b); // a's transition now resolves to b at run time
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
`reference.ref` returns the bound state and throws if the reference is still unbound when the machine runs.
|
|
213
|
+
|
|
32
214
|
### TuringMachine
|
|
33
215
|
|
|
216
|
+
The runtime. Owns one `TapeBlock` and drives a state graph until it reaches `haltState`.
|
|
217
|
+
|
|
218
|
+
```javascript
|
|
219
|
+
const machine = new TuringMachine({ tapeBlock });
|
|
220
|
+
|
|
221
|
+
// Run to halt:
|
|
222
|
+
machine.run({ initialState, stepsLimit: 1e5 });
|
|
223
|
+
|
|
224
|
+
// Or step-by-step (useful for visualization / debugging):
|
|
225
|
+
for (const step of machine.runStepByStep({ initialState })) {
|
|
226
|
+
console.log(step.state.name, step.currentSymbols, '→', step.nextSymbols, step.movements);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`stepsLimit` (default `1e5`) guards against runaway loops — exceeding it throws.
|
|
231
|
+
|
|
34
232
|
## Special objects
|
|
35
233
|
|
|
36
234
|
### haltState
|
|
37
235
|
|
|
38
|
-
A
|
|
236
|
+
A singleton `State` (`id === 0`). Transitioning into it stops the run. Imported as a named export from `@turing-machine-js/machine`; do not construct your own — `state.isHalt` checks identity against this single instance.
|
|
39
237
|
|
|
40
238
|
### ifOtherSymbol
|
|
41
239
|
|
|
42
|
-
A
|
|
240
|
+
A sentinel `Symbol` used as a key in a `State` definition to mean *match any symbol not handled by the other keys* (the fallback transition).
|
|
43
241
|
|
|
44
242
|
### movements
|
|
45
243
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
*
|
|
244
|
+
Per-tape head movement directives passed in `TapeCommand.movement`:
|
|
245
|
+
|
|
246
|
+
* `movements.left` — move the head one cell left
|
|
247
|
+
* `movements.right` — move the head one cell right
|
|
248
|
+
* `movements.stay` — leave the head where it is
|
|
49
249
|
|
|
50
250
|
### symbolCommands
|
|
51
251
|
|
|
52
|
-
|
|
53
|
-
|
|
252
|
+
Special values for `TapeCommand.symbol`:
|
|
253
|
+
|
|
254
|
+
* `symbolCommands.keep` — leave the current cell unchanged (default)
|
|
255
|
+
* `symbolCommands.erase` — write the alphabet's blank symbol
|
|
256
|
+
|
|
257
|
+
## Introspection and testing
|
|
258
|
+
|
|
259
|
+
`@turing-machine-js/machine` ships two complementary runtime utilities:
|
|
260
|
+
|
|
261
|
+
**`summarize` / `summarizeGraph`** — *structural* analysis. Looks at the state graph without running it.
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
import { summarize } from '@turing-machine-js/machine';
|
|
265
|
+
|
|
266
|
+
const stats = summarize(myState, myTapeBlock);
|
|
267
|
+
// {
|
|
268
|
+
// stateCount, transitionCount,
|
|
269
|
+
// compositionEdgeCount, maxCompositionDepth,
|
|
270
|
+
// selfLoopCount, hasCycles,
|
|
271
|
+
// tapeCount, alphabetCardinalities,
|
|
272
|
+
// }
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
`State.inspect(state)` returns the same kind of data for a single state (transitions, override-halt target, etc.) without traversing the graph.
|
|
276
|
+
|
|
277
|
+
**`equivalentOn`** — *behavioral* comparison. Runs two machines on a list of test inputs and reports whether their outputs agree, where they first diverge, and how many steps each took.
|
|
278
|
+
|
|
279
|
+
```javascript
|
|
280
|
+
import { equivalentOn } from '@turing-machine-js/machine';
|
|
281
|
+
|
|
282
|
+
const report = equivalentOn(
|
|
283
|
+
{ state: referenceState, getTapeBlock: () => referenceTapeBlock.clone() },
|
|
284
|
+
{ state: candidateState, getTapeBlock: () => candidateTapeBlock.clone() },
|
|
285
|
+
['^1$', '^10$', '^11$', '^111$'], // test cases
|
|
286
|
+
);
|
|
287
|
+
// report.allAgree → true | false
|
|
288
|
+
// report.results[i] → { agree, referenceOutput, candidateOutput,
|
|
289
|
+
// referenceSteps, candidateSteps, firstDivergenceStep }
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
For different alphabets, pass `{ reference, candidate }` paired cases plus a custom output comparator. See [`packages/machine/src/utilities/equivalence.spec.ts`](src/utilities/equivalence.spec.ts) for worked examples.
|
|
293
|
+
|
|
294
|
+
Together: use `summarize` to ask "is this machine the right shape?" (size, composition, cycles), and `equivalentOn` to ask "does this machine compute the right thing?" (correctness against a reference). Useful when comparing two implementations of the same algorithm — e.g., the marker-based and bare binary libraries — or when grading student-written machines against a reference.
|
|
295
|
+
|
|
296
|
+
For visualization and round-tripping, see `State.toGraph` / `State.fromGraph` and `toMermaid` / `fromMermaid`.
|
|
54
297
|
|
|
55
298
|
## Libraries
|
|
56
299
|
|
|
57
|
-
- [@turing-machine-js/library-binary-numbers](https://github.com/mellonis/turing-machine-js/tree/master/packages/library-binary-numbers)
|
|
300
|
+
- [@turing-machine-js/library-binary-numbers](https://github.com/mellonis/turing-machine-js/tree/master/packages/library-binary-numbers) — binary arithmetic with `^…$` markers, multi-number-per-tape support
|
|
301
|
+
- [@turing-machine-js/library-binary-numbers-bare](https://github.com/mellonis/turing-machine-js/tree/master/packages/library-binary-numbers-bare) — same operations on a 3-symbol alphabet, single-number-per-tape, much smaller state graphs
|
|
58
302
|
|
|
59
303
|
## Links
|
|
60
304
|
|
package/dist/classes/State.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import Command from './Command';
|
|
|
2
2
|
import Reference from './Reference';
|
|
3
3
|
import TapeBlock from './TapeBlock';
|
|
4
4
|
import TapeCommand from './TapeCommand';
|
|
5
|
+
import { type Graph } from '../utilities/graph';
|
|
5
6
|
export declare const ifOtherSymbol: unique symbol;
|
|
6
7
|
export default class State {
|
|
7
8
|
#private;
|
|
@@ -18,5 +19,31 @@ export default class State {
|
|
|
18
19
|
getCommand(symbol: symbol): Command;
|
|
19
20
|
getNextState(symbol: symbol): State | Reference;
|
|
20
21
|
withOverrodeHaltState(overrodeHaltState: State): State;
|
|
22
|
+
static inspect(state: State): {
|
|
23
|
+
id: number;
|
|
24
|
+
name: string;
|
|
25
|
+
isHalt: boolean;
|
|
26
|
+
overrodeHaltState: {
|
|
27
|
+
id: number;
|
|
28
|
+
name: string;
|
|
29
|
+
} | null;
|
|
30
|
+
transitions: Array<{
|
|
31
|
+
rawPatternDescription: string | undefined;
|
|
32
|
+
command: Array<{
|
|
33
|
+
symbol: string;
|
|
34
|
+
movement: string;
|
|
35
|
+
}>;
|
|
36
|
+
nextState: {
|
|
37
|
+
id: number;
|
|
38
|
+
name: string;
|
|
39
|
+
} | null;
|
|
40
|
+
}>;
|
|
41
|
+
};
|
|
42
|
+
static toGraph(initialState: State, tapeBlock: TapeBlock): Graph;
|
|
43
|
+
static fromGraph(graph: Graph): {
|
|
44
|
+
start: State;
|
|
45
|
+
tapeBlock: TapeBlock;
|
|
46
|
+
states: Record<number, State>;
|
|
47
|
+
};
|
|
21
48
|
}
|
|
22
49
|
export declare const haltState: State;
|