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