fas-js 1.3.2 → 1.4.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/lib/index.cjs ADDED
@@ -0,0 +1,644 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __typeError = (msg) => {
7
+ throw TypeError(msg);
8
+ };
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
23
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
24
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
25
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
26
+
27
+ // src/modules.ts
28
+ var modules_exports = {};
29
+ __export(modules_exports, {
30
+ createFSA: () => createFSA,
31
+ simulateFSA: () => simulateFSA,
32
+ stepOnceFSA: () => stepOnceFSA
33
+ });
34
+ module.exports = __toCommonJS(modules_exports);
35
+
36
+ // src/globals/errors.ts
37
+ var ErrorCode = Object.freeze({
38
+ DUPLICATE_ALPHABET_VALS: "E-001",
39
+ DUPLICATE_STATE_NAMES: "E-002",
40
+ INVALID_STATE_NAME: "E-003",
41
+ START_STATE_NOT_FOUND: "E-004",
42
+ ACCEPTS_NOT_SUBSET: "E-005",
43
+ ORIGIN_STATE_NOT_FOUND: "E-006",
44
+ DEST_STATE_NOT_FOUND: "E-007",
45
+ MISSING_REQUIRED_TRANSITION: "E-008",
46
+ INVALID_INPUT_CHAR: "E-009",
47
+ INPUT_STATE_NOT_FOUND: "E-010",
48
+ INVALID_TRANSITION_OBJECT: "E-011",
49
+ DUPLICATE_TRANSITION_OBJECT: "E-012",
50
+ INVALID_STATE_ARRAY: "E-013"
51
+ });
52
+
53
+ // src/components/State.ts
54
+ var State = class {
55
+ constructor(name) {
56
+ this.name = name;
57
+ if (!this.name) throw new Error(ErrorCode.INVALID_STATE_NAME);
58
+ }
59
+ };
60
+
61
+ // src/globals/globals.ts
62
+ var count = (names) => names.reduce((a, b) => Object.assign(a, { [b]: (a[b] || 0) + 1 }), {});
63
+ var duplicates = (dict) => Object.keys(dict).filter((a) => dict[a] > 1);
64
+ var checkStateDuplicates = (states) => {
65
+ const check = /* @__PURE__ */ new Set();
66
+ for (const item of states) {
67
+ if (check.has(item.name)) return true;
68
+ check.add(item.name);
69
+ }
70
+ return false;
71
+ };
72
+ var getOrDefault = (map, key, defaultValue) => {
73
+ const val = map.get(key);
74
+ return val == null ? defaultValue : val;
75
+ };
76
+ var instanceOf = (ctor, obj) => {
77
+ return obj instanceof ctor || Boolean(ctor.name) && ctor.name === obj.constructor.name;
78
+ };
79
+ var isSubsetOf = (subset, superset) => {
80
+ for (const item of subset) {
81
+ if (!superset.has(item)) return false;
82
+ }
83
+ return true;
84
+ };
85
+
86
+ // src/components/Alphabet.ts
87
+ var Alphabet = class {
88
+ constructor(sigma) {
89
+ if (!Array.isArray(sigma)) {
90
+ if (typeof sigma === "string") sigma = [...sigma];
91
+ else throw new TypeError();
92
+ }
93
+ this.sigma = sigma;
94
+ if (duplicates(count(this.sigma)).length > 0) throw new Error(ErrorCode.DUPLICATE_ALPHABET_VALS);
95
+ }
96
+ };
97
+
98
+ // src/components/NFATransition.ts
99
+ var NFATransition = class {
100
+ constructor(origin, dest, input) {
101
+ this.origin = origin;
102
+ this.dest = dest;
103
+ this.input = input;
104
+ }
105
+ };
106
+
107
+ // src/components/Transition.ts
108
+ var Transition = class {
109
+ constructor(origin, dest, input) {
110
+ this.origin = origin;
111
+ this.dest = dest;
112
+ this.input = input;
113
+ }
114
+ };
115
+
116
+ // src/utils/DFAUtils.ts
117
+ var DFAUtils = class {
118
+ /*
119
+ * Transition function should only contain states in Q, and one transition should exist
120
+ * for each combination of Q x Σ
121
+ */
122
+ static validateTFunc(_states, _paths, _tfunc, _alph) {
123
+ const newTFunc = /* @__PURE__ */ new Set();
124
+ for (const _t of _tfunc) {
125
+ if (!_states.has(_t.origin)) {
126
+ console.error("Origin state was invalid: %o", JSON.stringify(_t.origin));
127
+ throw new Error(ErrorCode.ORIGIN_STATE_NOT_FOUND);
128
+ }
129
+ if (!_states.has(_t.dest)) {
130
+ console.error("Dest state was invalid: %o", JSON.stringify(_t.dest));
131
+ throw new Error(ErrorCode.DEST_STATE_NOT_FOUND);
132
+ }
133
+ const pathStateVals = getOrDefault(_paths, _t.origin, /* @__PURE__ */ new Set());
134
+ if (this.isValidInputChar(_t.input, _alph)) {
135
+ if (_paths.has(_t.origin) && pathStateVals.has(_t.input)) {
136
+ newTFunc.add(_t);
137
+ pathStateVals.delete(_t.input);
138
+ if (pathStateVals.size === 0) {
139
+ _paths.delete(_t.origin);
140
+ }
141
+ } else {
142
+ throw new Error(ErrorCode.DUPLICATE_TRANSITION_OBJECT);
143
+ }
144
+ } else {
145
+ throw new Error(ErrorCode.INVALID_INPUT_CHAR);
146
+ }
147
+ }
148
+ if (_paths.size > 0) {
149
+ console.error("Not all FSA paths have a transition specified:");
150
+ for (const [key, val] of _paths) {
151
+ console.error("State %s on input(s): %s", key.name, [...val].join(" "));
152
+ }
153
+ throw new Error(ErrorCode.MISSING_REQUIRED_TRANSITION);
154
+ }
155
+ return newTFunc;
156
+ }
157
+ static createPaths(_states, _alph) {
158
+ const _paths = /* @__PURE__ */ new Map();
159
+ for (const state of _states) {
160
+ for (const char of _alph.sigma) {
161
+ const pathStateVals = getOrDefault(_paths, state, /* @__PURE__ */ new Set());
162
+ if (_paths.has(state)) pathStateVals.add(char);
163
+ else _paths.set(state, /* @__PURE__ */ new Set([char]));
164
+ }
165
+ }
166
+ return _paths;
167
+ }
168
+ // Determine digraph order based on start state, then following the chain
169
+ static determineStateOrder(_links, _tfunc, _states, _start, _accepts) {
170
+ const statesOrder = [];
171
+ _links = /* @__PURE__ */ new Map();
172
+ for (const tr of _tfunc) {
173
+ const linkStateVals = getOrDefault(_links, tr.origin.name, /* @__PURE__ */ new Set());
174
+ if (_links.has(tr.origin.name)) linkStateVals.add(tr.dest.name);
175
+ else _links.set(tr.origin.name, /* @__PURE__ */ new Set([tr.dest.name]));
176
+ }
177
+ this.parseLinks(statesOrder, _start.name, _links);
178
+ const stateArr = [];
179
+ Object.values([..._states]).map((state) => stateArr.push(state.name));
180
+ const deadStates = stateArr.filter((x) => !statesOrder.includes(x));
181
+ if (deadStates.length > 0) {
182
+ console.warn("Dead states detected, removing them and associated transitions: %O", deadStates);
183
+ this.removeDeadStates(deadStates, _states, _accepts, _tfunc);
184
+ }
185
+ return statesOrder;
186
+ }
187
+ // Reduce FSA by removing dead states and associated transitions
188
+ static removeDeadStates(deadStates, _states, _accepts, _tfunc) {
189
+ for (const state of _states) {
190
+ if (deadStates.indexOf(state.name) !== -1) _states.delete(state);
191
+ }
192
+ for (const state of _accepts) {
193
+ if (deadStates.indexOf(state.name) !== -1) _accepts.delete(state);
194
+ }
195
+ for (const tr of _tfunc) {
196
+ if (deadStates.indexOf(tr.origin.name) !== -1 || deadStates.indexOf(tr.dest.name) !== -1) _tfunc.delete(tr);
197
+ }
198
+ }
199
+ // Recursively parse graph while adding to an array in order, beginning with q0
200
+ static parseLinks(arr, name, _links) {
201
+ arr.push(name);
202
+ const nameVal = getOrDefault(_links, name, /* @__PURE__ */ new Set());
203
+ for (const st of nameVal) {
204
+ if (arr.indexOf(st) === -1) this.parseLinks(arr, st, _links);
205
+ }
206
+ }
207
+ // DFA does not allow empty symbol
208
+ static isValidInputChar(input, _alph) {
209
+ if (input === "") return false;
210
+ return _alph.sigma.indexOf(input) !== -1;
211
+ }
212
+ };
213
+ var createDFA = (states, alphabet, transitions, start, accepts) => {
214
+ const _tfunc = /* @__PURE__ */ new Set();
215
+ for (const tr of transitions) {
216
+ if (!tr.from || !tr.to || !tr.input) throw new Error(ErrorCode.INVALID_TRANSITION_OBJECT);
217
+ const fromVal = getOrDefault(states, tr.from, null);
218
+ const toVal = getOrDefault(states, tr.to, null);
219
+ _tfunc.add(new Transition(fromVal, toVal, tr.input));
220
+ }
221
+ return new DFA(new Set(states.values()), alphabet, _tfunc, start, accepts);
222
+ };
223
+
224
+ // src/utils/NFAUtils.ts
225
+ var NFAUtils = class extends DFAUtils {
226
+ // NFA inheritly allows for ε (empty string) transition if specified
227
+ static isValidInputChar(input, _alph) {
228
+ return _alph.sigma.indexOf(input) !== -1 || input === "";
229
+ }
230
+ // Follow all ε transitions and add to `state` (origin states)
231
+ static populateEpsilons(_tfunc, state) {
232
+ let cont = true;
233
+ while (cont) {
234
+ cont = false;
235
+ const epsTransitions = Array.from(_tfunc).filter((obj) => {
236
+ return state.includes(obj.origin) && obj.input === "";
237
+ });
238
+ for (const _t of epsTransitions) {
239
+ if (!state.includes(_t.dest)) {
240
+ state.push(_t.dest);
241
+ cont = true;
242
+ }
243
+ }
244
+ }
245
+ return state;
246
+ }
247
+ // Validate tfunc according to NFA rules
248
+ static validateTFunc(_states, _paths, _tfunc, _alph) {
249
+ const newTFunc = /* @__PURE__ */ new Set();
250
+ for (const _t of _tfunc) {
251
+ let skip = false;
252
+ if (!_states.has(_t.origin)) {
253
+ console.error("Origin state was invalid: %o", JSON.stringify(_t.origin));
254
+ throw new Error(ErrorCode.ORIGIN_STATE_NOT_FOUND);
255
+ }
256
+ if (!_states.has(_t.dest)) {
257
+ console.error("Dest state was invalid: %o", JSON.stringify(_t.dest));
258
+ throw new Error(ErrorCode.DEST_STATE_NOT_FOUND);
259
+ }
260
+ const pathStateVals = getOrDefault(_paths, _t.origin, /* @__PURE__ */ new Set());
261
+ for (const _checkT of newTFunc) {
262
+ if (_checkT.origin === _t.origin && _checkT.dest === _t.dest && _checkT.input === _t.input) skip = true;
263
+ }
264
+ if (!skip) {
265
+ if (_paths.has(_t.origin)) {
266
+ if (this.isValidInputChar(_t.input, _alph)) {
267
+ newTFunc.add(_t);
268
+ } else {
269
+ throw new Error(ErrorCode.INVALID_INPUT_CHAR);
270
+ }
271
+ }
272
+ }
273
+ }
274
+ return newTFunc;
275
+ }
276
+ };
277
+ var createNFA = (states, alphabet, transitions, start, accepts) => {
278
+ const _tfunc = /* @__PURE__ */ new Set();
279
+ for (const tr of transitions) {
280
+ if (!tr.from || !tr.to || !tr.input && tr.input !== "")
281
+ throw new Error(ErrorCode.INVALID_TRANSITION_OBJECT);
282
+ const fromVal = getOrDefault(states, tr.from, null);
283
+ const toVal = tr.to.split(",");
284
+ const destStates = [];
285
+ toVal.forEach((_dest) => {
286
+ destStates.push(getOrDefault(states, _dest, null));
287
+ });
288
+ _tfunc.add(new NFATransition(fromVal, destStates, tr.input));
289
+ }
290
+ return new NFA(new Set(states.values()), alphabet, _tfunc, start, accepts);
291
+ };
292
+
293
+ // src/utils/FSAUtils.ts
294
+ var FSAUtils = /* @__PURE__ */ (() => {
295
+ function receiveInputDFA(dfa, input, state) {
296
+ if (dfa.getAlphabet().sigma.indexOf(input) === -1) throw new Error(ErrorCode.INVALID_INPUT_CHAR);
297
+ if (!dfa.getStates().has(state)) throw new Error(ErrorCode.INPUT_STATE_NOT_FOUND);
298
+ const path = Array.from(dfa.getTFunc()).find((obj) => {
299
+ return obj.origin === state && obj.input === input;
300
+ });
301
+ if (path) return path.dest;
302
+ else throw new Error(ErrorCode.INVALID_TRANSITION_OBJECT);
303
+ }
304
+ function receiveInputNFA(nfa, input, state) {
305
+ let path = [];
306
+ if (nfa.getAlphabet().sigma.indexOf(input) === -1) throw new Error(ErrorCode.INVALID_INPUT_CHAR);
307
+ state = populateEpsilons(nfa.getTFunc(), state);
308
+ if (input === "") return new Set(state);
309
+ for (const _s of state) {
310
+ const _addToPath = Array.from(nfa.getTFunc()).filter((obj) => {
311
+ return obj.origin === _s && obj.input === input;
312
+ });
313
+ path = path.concat(_addToPath);
314
+ }
315
+ let resultArr = [];
316
+ if (path.length > 1) {
317
+ for (const _s of path) resultArr.push(_s.dest);
318
+ } else if (path.length === 1) {
319
+ resultArr.push(path[0].dest);
320
+ } else {
321
+ return /* @__PURE__ */ new Set();
322
+ }
323
+ const retSet = new Set(populateEpsilons(nfa.getTFunc(), resultArr));
324
+ return retSet;
325
+ }
326
+ function populateEpsilons(_tfunc, state) {
327
+ return NFAUtils.populateEpsilons(_tfunc, state);
328
+ }
329
+ class FSAUtils2 {
330
+ constructor(v) {
331
+ this._type = v;
332
+ }
333
+ receiveInput(fsa, input, state) {
334
+ if (instanceOf(NFA, fsa)) {
335
+ if (state instanceof State) return receiveInputNFA(fsa, input, [state]);
336
+ else return receiveInputNFA(fsa, input, state);
337
+ } else {
338
+ if (Array.isArray(state)) {
339
+ if (state.length > 1) {
340
+ console.error("State array can only contain one state for DFAs");
341
+ throw new Error(ErrorCode.INVALID_STATE_ARRAY);
342
+ } else {
343
+ state = state[0];
344
+ }
345
+ }
346
+ return receiveInputDFA(fsa, input, state);
347
+ }
348
+ }
349
+ validateTFunc(_states, _paths, _tfunc, _alph) {
350
+ if (this._type === NFA) {
351
+ return NFAUtils.validateTFunc(_states, _paths, _tfunc, _alph);
352
+ } else {
353
+ return DFAUtils.validateTFunc(_states, _paths, _tfunc, _alph);
354
+ }
355
+ }
356
+ createPaths(_states, _alph) {
357
+ return DFAUtils.createPaths(_states, _alph);
358
+ }
359
+ determineStateOrder(_links, _tfunc, _states, _start, _accepts) {
360
+ return DFAUtils.determineStateOrder(_links, _tfunc, _states, _start, _accepts);
361
+ }
362
+ }
363
+ return FSAUtils2;
364
+ })();
365
+ var createFSA = (states, alphabet, transitions, start, accepts) => {
366
+ const _states = /* @__PURE__ */ new Map();
367
+ if (typeof states === "string") {
368
+ _states.set(states, new State(states));
369
+ } else if (Array.isArray(states)) {
370
+ for (const state of states) {
371
+ if (!_states.has(state)) _states.set(state, new State(state));
372
+ }
373
+ } else {
374
+ throw new TypeError(String(states));
375
+ }
376
+ const _alphabet = new Alphabet(alphabet);
377
+ if (typeof start !== "string") throw new TypeError(String(start));
378
+ const _start = getOrDefault(_states, start, null);
379
+ const _accepts = /* @__PURE__ */ new Set();
380
+ if (typeof accepts === "string") {
381
+ if (_states.has(accepts)) _accepts.add(getOrDefault(_states, accepts, null));
382
+ } else if (Array.isArray(accepts)) {
383
+ for (const state of accepts) {
384
+ _accepts.add(getOrDefault(_states, state, null));
385
+ }
386
+ } else {
387
+ throw new TypeError(String(accepts));
388
+ }
389
+ let transitionList;
390
+ if (!Array.isArray(transitions) && typeof transitions === "object") transitionList = [transitions];
391
+ else if (Array.isArray(transitions)) transitionList = transitions;
392
+ else throw new TypeError(String(transitions));
393
+ for (const tr of transitionList) {
394
+ if (tr.to.indexOf(",") != -1 || tr.input === "")
395
+ return createNFA(_states, _alphabet, transitionList, _start, _accepts);
396
+ }
397
+ return createDFA(_states, _alphabet, transitionList, _start, _accepts);
398
+ };
399
+
400
+ // src/automata/DFA.ts
401
+ var DFA = /* @__PURE__ */ (() => {
402
+ var _states, _alphabet, _tfunc, _start, _accepts, _paths, _links, _utils;
403
+ class DFA3 {
404
+ constructor(states, alphabet, tfunc, start, accepts) {
405
+ // Primary FSA attributes
406
+ __privateAdd(this, _states);
407
+ __privateAdd(this, _alphabet);
408
+ __privateAdd(this, _tfunc);
409
+ __privateAdd(this, _start);
410
+ __privateAdd(this, _accepts);
411
+ // Intermediary attributes used in constructor
412
+ __privateAdd(this, _paths);
413
+ // States mapped to each member of Σ, will be empty after constructor returns
414
+ __privateAdd(this, _links, /* @__PURE__ */ new Map());
415
+ // State names mapped to their dest state names
416
+ __privateAdd(this, _utils);
417
+ __privateSet(this, _utils, new FSAUtils(this.constructor));
418
+ if (checkStateDuplicates(states)) throw new Error(ErrorCode.DUPLICATE_STATE_NAMES);
419
+ __privateSet(this, _states, states);
420
+ __privateSet(this, _alphabet, alphabet);
421
+ __privateSet(this, _paths, __privateGet(this, _utils).createPaths(__privateGet(this, _states), __privateGet(this, _alphabet)));
422
+ if (!states.has(start)) throw new Error(ErrorCode.START_STATE_NOT_FOUND);
423
+ __privateSet(this, _start, start);
424
+ if (Object.keys(accepts).length === 0 && accepts.constructor === Object) accepts = /* @__PURE__ */ new Set([]);
425
+ if (!isSubsetOf(accepts, states)) throw new Error(ErrorCode.ACCEPTS_NOT_SUBSET);
426
+ __privateSet(this, _accepts, accepts);
427
+ __privateSet(this, _tfunc, __privateGet(this, _utils).validateTFunc(__privateGet(this, _states), __privateGet(this, _paths), tfunc, __privateGet(this, _alphabet)));
428
+ }
429
+ /*
430
+ * Getters
431
+ */
432
+ getStates() {
433
+ return __privateGet(this, _states);
434
+ }
435
+ getAlphabet() {
436
+ return __privateGet(this, _alphabet);
437
+ }
438
+ getTFunc() {
439
+ return __privateGet(this, _tfunc);
440
+ }
441
+ getStartState() {
442
+ return __privateGet(this, _start);
443
+ }
444
+ getAcceptStates() {
445
+ return __privateGet(this, _accepts);
446
+ }
447
+ getType() {
448
+ return "DFA";
449
+ }
450
+ generateDigraph() {
451
+ const acceptArr = [];
452
+ for (const state of __privateGet(this, _accepts)) acceptArr.push(state.name);
453
+ const pairs = /* @__PURE__ */ new Map();
454
+ Object.values([...__privateGet(this, _tfunc)]).map(function(t) {
455
+ const key = t.origin.name + t.dest.name;
456
+ let _input = t.input;
457
+ if (_input === "") _input = "\u03B5";
458
+ if (!pairs.has(key)) {
459
+ pairs.set(key, t.origin.name + " -> " + t.dest.name + ' [ label = "' + _input + '" ];');
460
+ } else {
461
+ let _line = getOrDefault(pairs, key, "");
462
+ const _oldinput = _line.split('"')[1];
463
+ const _toAdd = _oldinput.split(",");
464
+ _toAdd.push(_input);
465
+ _toAdd.sort();
466
+ _line = _line.replace('"' + _oldinput + '"', '"' + _toAdd.toString() + '"');
467
+ pairs.set(key, _line);
468
+ }
469
+ });
470
+ return `digraph fsa {
471
+ ${Object.values(
472
+ __privateGet(this, _utils).determineStateOrder(__privateGet(this, _links), __privateGet(this, _tfunc), __privateGet(this, _states), __privateGet(this, _start), __privateGet(this, _accepts))
473
+ ).map(function(str) {
474
+ if (acceptArr.indexOf(str) !== -1) return str + " [shape = doublecircle];";
475
+ else return str;
476
+ }).join("\n ")}
477
+ rankdir=LR;
478
+ node [shape = point ]; qi;
479
+ node [shape = circle];
480
+ qi -> ${__privateGet(this, _start).name};
481
+ ${Object.values([...pairs]).map(function([, val]) {
482
+ return val;
483
+ }).join("\n ")}
484
+ }
485
+ `;
486
+ }
487
+ }
488
+ _states = new WeakMap();
489
+ _alphabet = new WeakMap();
490
+ _tfunc = new WeakMap();
491
+ _start = new WeakMap();
492
+ _accepts = new WeakMap();
493
+ _paths = new WeakMap();
494
+ _links = new WeakMap();
495
+ _utils = new WeakMap();
496
+ return DFA3;
497
+ })();
498
+
499
+ // src/automata/NFA.ts
500
+ var NFA = /* @__PURE__ */ (() => {
501
+ class NFA2 extends DFA {
502
+ // Transition function is different for NFA
503
+ constructor(states, alphabet, tfunc, start, accepts) {
504
+ if (!alphabet.sigma.includes("")) alphabet.sigma.push("");
505
+ const expandedTfunc = /* @__PURE__ */ new Set();
506
+ for (const _t of tfunc) {
507
+ _t.dest.forEach((_dest) => {
508
+ expandedTfunc.add(new Transition(_t.origin, _dest, _t.input));
509
+ });
510
+ }
511
+ super(states, alphabet, expandedTfunc, start, accepts);
512
+ }
513
+ getType() {
514
+ return "NFA";
515
+ }
516
+ }
517
+ return NFA2;
518
+ })();
519
+
520
+ // src/engine/Simulators.ts
521
+ var simulateFSA = (w, fsa, logging = false, returnEndState = false) => {
522
+ if (instanceOf(NFA, fsa)) {
523
+ return simulateNFA(w, fsa, new FSAUtils(NFA), logging, returnEndState);
524
+ } else {
525
+ return simulateDFA(w, fsa, new FSAUtils(DFA), logging, returnEndState);
526
+ }
527
+ };
528
+ var stepOnceFSA = (w, qin, fsa, logging = false) => {
529
+ if (typeof w !== "string") {
530
+ if (logging) console.error("Input w was invalid type: %O", w);
531
+ throw new TypeError();
532
+ }
533
+ if (typeof qin !== "string" && !Array.isArray(qin)) {
534
+ if (logging) console.error("Input state was invalid type: %O", qin);
535
+ throw new TypeError();
536
+ }
537
+ if (logging) console.log("Input Processing Started");
538
+ let prevState = [];
539
+ if (typeof qin === "string") {
540
+ for (const state of fsa.getStates().values()) {
541
+ if (qin === state.name) prevState = state;
542
+ }
543
+ if (!prevState || Array.isArray(prevState) && prevState.length === 0)
544
+ throw new Error(ErrorCode.INVALID_STATE_NAME);
545
+ } else {
546
+ prevState = [];
547
+ for (const state of fsa.getStates().values()) {
548
+ if (qin.includes(state.name)) prevState.push(state);
549
+ }
550
+ if (prevState.length !== qin.length) {
551
+ throw new Error(ErrorCode.INVALID_STATE_NAME);
552
+ }
553
+ }
554
+ let newState;
555
+ if (instanceOf(NFA, fsa)) newState = [...new FSAUtils(NFA).receiveInput(fsa, w, prevState)];
556
+ else newState = new FSAUtils(DFA).receiveInput(fsa, w, prevState);
557
+ if (logging) console.log("%o x '%s' -> %o", JSON.stringify(prevState), w, JSON.stringify(newState));
558
+ if (logging) console.log("Input Processing Ended");
559
+ if (newState instanceof State) return newState.name;
560
+ else {
561
+ const retArray = [];
562
+ for (const _s of newState) {
563
+ retArray.push(_s.name);
564
+ }
565
+ return retArray;
566
+ }
567
+ };
568
+ function simulateDFA(w, dfa, utils, logging, returnEndState) {
569
+ if (logging) console.log("Beginning DFA Simulation");
570
+ if (!Array.isArray(w)) {
571
+ if (typeof w === "string") w = [...w];
572
+ else {
573
+ if (logging) console.error("Input w was invalid type: %O", w);
574
+ throw new TypeError();
575
+ }
576
+ }
577
+ if (logging) console.log("Input Processing Started");
578
+ let currentState = dfa.getStartState();
579
+ for (const char of w) {
580
+ const prevState = currentState;
581
+ currentState = utils.receiveInput(dfa, char, prevState);
582
+ if (logging) console.log("%o x '%s' -> %o", JSON.stringify(prevState), char, JSON.stringify(currentState));
583
+ }
584
+ if (logging) console.log("Input Processing Ended");
585
+ if (dfa.getAcceptStates().has(currentState)) {
586
+ if (logging) console.log("Input Accepted!");
587
+ if (returnEndState) return currentState.name;
588
+ else return true;
589
+ } else {
590
+ if (logging) console.log("Input Rejected!");
591
+ if (returnEndState) return currentState.name;
592
+ else return false;
593
+ }
594
+ }
595
+ function simulateNFA(w, nfa, utils, logging, returnEndState) {
596
+ if (logging) console.log("Beginning NFA Simulation");
597
+ if (!(w instanceof Array)) {
598
+ if (typeof w === "string") {
599
+ if (w === "") w = [""];
600
+ else w = [...w];
601
+ } else {
602
+ if (logging) console.error("Input w was invalid type: %O", w);
603
+ throw new TypeError();
604
+ }
605
+ }
606
+ if (logging) console.log("Input Processing Started");
607
+ let currentState = [nfa.getStartState()];
608
+ for (const char of w) {
609
+ const prevState = currentState;
610
+ currentState = [...utils.receiveInput(nfa, char, currentState)];
611
+ if (logging) console.log("%o x '%s' -> %o", JSON.stringify(prevState), char, JSON.stringify(currentState));
612
+ }
613
+ if (logging) console.log("Input Processing Ended");
614
+ const retObj = [];
615
+ for (const _accState of nfa.getAcceptStates()) {
616
+ if (currentState.includes(_accState)) {
617
+ if (!returnEndState) {
618
+ if (logging) console.log("Input Accepted!");
619
+ return true;
620
+ }
621
+ retObj.push(_accState.name);
622
+ }
623
+ }
624
+ if (retObj.length > 0) {
625
+ if (logging) console.log("Input Accepted!");
626
+ return retObj;
627
+ }
628
+ if (logging) console.log("Input Rejected!");
629
+ if (returnEndState) {
630
+ if (currentState.length > 0) {
631
+ for (const _cState of currentState) retObj.push(_cState.name);
632
+ }
633
+ return retObj;
634
+ } else {
635
+ return false;
636
+ }
637
+ }
638
+ // Annotate the CommonJS export names for ESM import in node:
639
+ 0 && (module.exports = {
640
+ createFSA,
641
+ simulateFSA,
642
+ stepOnceFSA
643
+ });
644
+ //# sourceMappingURL=index.cjs.map