@turing-machine-js/builder 6.0.0 → 6.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/README.md +11 -12
- package/dist/index.cjs +35 -1
- package/dist/index.mjs +35 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -12,31 +12,30 @@ Constructs a Turing machine from a declarative state-table object. Every transit
|
|
|
12
12
|
import { Tape } from '@turing-machine-js/machine';
|
|
13
13
|
import buildMachine from '@turing-machine-js/builder';
|
|
14
14
|
|
|
15
|
+
// Flip every bit on the tape; halt when the head reaches a blank.
|
|
15
16
|
const [machine, initialState] = buildMachine({
|
|
16
|
-
alphabetString: '
|
|
17
|
-
initialState: '
|
|
18
|
-
finalStateList: ['
|
|
17
|
+
alphabetString: ' 01',
|
|
18
|
+
initialState: 'flip',
|
|
19
|
+
finalStateList: ['DONE'],
|
|
19
20
|
states: {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'#': { state: 'Q2', symbol: '#', movement: 'R' },
|
|
21
|
+
flip: {
|
|
22
|
+
'0': { state: 'flip', symbol: '1', movement: 'R' },
|
|
23
|
+
'1': { state: 'flip', symbol: '0', movement: 'R' },
|
|
24
|
+
' ': { state: 'DONE', symbol: ' ', movement: 'S' },
|
|
25
25
|
},
|
|
26
|
-
// ... more states ...
|
|
27
26
|
},
|
|
28
27
|
});
|
|
29
28
|
|
|
30
29
|
machine.tapeBlock.replaceTape(new Tape({
|
|
31
30
|
alphabet: machine.tapeBlock.alphabets[0],
|
|
32
|
-
symbols: '
|
|
31
|
+
symbols: '0101'.split(''),
|
|
33
32
|
}));
|
|
34
33
|
|
|
35
34
|
await machine.run({ initialState, stepsLimit: 100 });
|
|
36
|
-
|
|
35
|
+
console.log(machine.tapeBlock.tapes[0].symbols.join('').trim()); // "1010"
|
|
37
36
|
```
|
|
38
37
|
|
|
39
|
-
See [`builder.spec.ts`](src/builder.spec.ts) for a
|
|
38
|
+
See [`builder.spec.ts`](src/builder.spec.ts) for a longer worked example — a 27-state binary-string-duplicator (input `#011#` → output `#011#011#`) — including a small parser that reads the textbook `(state,symbol)→(state,symbol,movement);` notation.
|
|
40
39
|
|
|
41
40
|
## Limitations
|
|
42
41
|
|
package/dist/index.cjs
CHANGED
|
@@ -9,7 +9,7 @@ const movementsMap = {
|
|
|
9
9
|
};
|
|
10
10
|
const referenceKey = Symbol('reference');
|
|
11
11
|
const stateKey = Symbol('state');
|
|
12
|
-
function buildMachine({ alphabetString, initialState, finalStateList, states: stateNameToStateDeclarationMap, }) {
|
|
12
|
+
function buildMachine({ alphabetString, initialState, finalStateList, states: stateNameToStateDeclarationMap, debug, }) {
|
|
13
13
|
const alphabet = new machine.Alphabet(alphabetString.split(''));
|
|
14
14
|
const machine$1 = new machine.TuringMachine({
|
|
15
15
|
tapeBlock: machine.TapeBlock.fromAlphabets([alphabet]),
|
|
@@ -66,6 +66,40 @@ function buildMachine({ alphabetString, initialState, finalStateList, states: st
|
|
|
66
66
|
...result,
|
|
67
67
|
[stateName]: stateOrReference[stateKey],
|
|
68
68
|
}), {});
|
|
69
|
+
// #101: apply per-state debug config. Filter values are raw alphabet
|
|
70
|
+
// characters; translate each via tapeBlock.symbol([char]) so they match
|
|
71
|
+
// the same interned Symbol used in transitions. `true` passes through
|
|
72
|
+
// as-is (wildcard). final-state names are rejected — they alias to
|
|
73
|
+
// haltState which is out of scope per the issue spec.
|
|
74
|
+
if (debug) {
|
|
75
|
+
Object.entries(debug).forEach(([stateName, config]) => {
|
|
76
|
+
if (finalStateList.includes(stateName)) {
|
|
77
|
+
throw new Error(`debug cannot be set on final state '${stateName}': finalStateList `
|
|
78
|
+
+ 'entries map to haltState, which is out of scope for the builder. '
|
|
79
|
+
+ 'Set haltState.debug directly on the imported singleton if needed.');
|
|
80
|
+
}
|
|
81
|
+
const state = resultStates[stateName];
|
|
82
|
+
if (!state) {
|
|
83
|
+
throw new Error(`debug references unknown state '${stateName}'`);
|
|
84
|
+
}
|
|
85
|
+
const translateFilter = (f) => {
|
|
86
|
+
if (f === undefined)
|
|
87
|
+
return undefined;
|
|
88
|
+
if (f === true)
|
|
89
|
+
return true;
|
|
90
|
+
return f.map((c) => {
|
|
91
|
+
if (!alphabet.has(c)) {
|
|
92
|
+
throw new Error(`debug filter symbol '${c}' for state '${stateName}' is not in the alphabet`);
|
|
93
|
+
}
|
|
94
|
+
return getSymbol([c]);
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
state.debug = {
|
|
98
|
+
before: translateFilter(config.before),
|
|
99
|
+
after: translateFilter(config.after),
|
|
100
|
+
};
|
|
101
|
+
});
|
|
102
|
+
}
|
|
69
103
|
return [
|
|
70
104
|
machine$1,
|
|
71
105
|
resultStates[initialState],
|
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@ const movementsMap = {
|
|
|
7
7
|
};
|
|
8
8
|
const referenceKey = Symbol('reference');
|
|
9
9
|
const stateKey = Symbol('state');
|
|
10
|
-
function buildMachine({ alphabetString, initialState, finalStateList, states: stateNameToStateDeclarationMap, }) {
|
|
10
|
+
function buildMachine({ alphabetString, initialState, finalStateList, states: stateNameToStateDeclarationMap, debug, }) {
|
|
11
11
|
const alphabet = new Alphabet(alphabetString.split(''));
|
|
12
12
|
const machine = new TuringMachine({
|
|
13
13
|
tapeBlock: TapeBlock.fromAlphabets([alphabet]),
|
|
@@ -64,6 +64,40 @@ function buildMachine({ alphabetString, initialState, finalStateList, states: st
|
|
|
64
64
|
...result,
|
|
65
65
|
[stateName]: stateOrReference[stateKey],
|
|
66
66
|
}), {});
|
|
67
|
+
// #101: apply per-state debug config. Filter values are raw alphabet
|
|
68
|
+
// characters; translate each via tapeBlock.symbol([char]) so they match
|
|
69
|
+
// the same interned Symbol used in transitions. `true` passes through
|
|
70
|
+
// as-is (wildcard). final-state names are rejected — they alias to
|
|
71
|
+
// haltState which is out of scope per the issue spec.
|
|
72
|
+
if (debug) {
|
|
73
|
+
Object.entries(debug).forEach(([stateName, config]) => {
|
|
74
|
+
if (finalStateList.includes(stateName)) {
|
|
75
|
+
throw new Error(`debug cannot be set on final state '${stateName}': finalStateList `
|
|
76
|
+
+ 'entries map to haltState, which is out of scope for the builder. '
|
|
77
|
+
+ 'Set haltState.debug directly on the imported singleton if needed.');
|
|
78
|
+
}
|
|
79
|
+
const state = resultStates[stateName];
|
|
80
|
+
if (!state) {
|
|
81
|
+
throw new Error(`debug references unknown state '${stateName}'`);
|
|
82
|
+
}
|
|
83
|
+
const translateFilter = (f) => {
|
|
84
|
+
if (f === undefined)
|
|
85
|
+
return undefined;
|
|
86
|
+
if (f === true)
|
|
87
|
+
return true;
|
|
88
|
+
return f.map((c) => {
|
|
89
|
+
if (!alphabet.has(c)) {
|
|
90
|
+
throw new Error(`debug filter symbol '${c}' for state '${stateName}' is not in the alphabet`);
|
|
91
|
+
}
|
|
92
|
+
return getSymbol([c]);
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
state.debug = {
|
|
96
|
+
before: translateFilter(config.before),
|
|
97
|
+
after: translateFilter(config.after),
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
}
|
|
67
101
|
return [
|
|
68
102
|
machine,
|
|
69
103
|
resultStates[initialState],
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turing-machine-js/builder",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "A turing machine builder — declarative state-table construction. Not actively developed by the author; the same state-table pattern is also shown as an inline example in @turing-machine-js/machine's README. Contributions welcome.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"npm": ">=7.0.0"
|
|
7
7
|
},
|
|
8
|
-
"author": "Ruslan Gilmullin <
|
|
8
|
+
"author": "Ruslan Gilmullin <mellonis@yandex.ru>",
|
|
9
9
|
"homepage": "https://github.com/mellonis/turing-machine-js#readme",
|
|
10
10
|
"license": "GPL-3.0-or-later",
|
|
11
11
|
"publishConfig": {
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"default": "./dist/index.mjs"
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "d7ebca4e8379a548e3ca97eb83e96387de2cda32"
|
|
42
42
|
}
|