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/README.md +20 -7
- package/lib/.gitkeep +0 -0
- package/lib/bundle.js +12 -1
- package/lib/bundle.js.map +1 -0
- package/lib/demo-bundle.global.js.map +1 -0
- package/lib/demo-bundle.js +12 -0
- package/lib/index.cjs +636 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +39 -0
- package/lib/index.d.ts +39 -0
- package/lib/index.js +608 -0
- package/lib/index.js.map +1 -0
- package/package.json +46 -49
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";var fasJs=(()=>{var q=Object.defineProperty;var ht=Object.getOwnPropertyDescriptor;var At=Object.getOwnPropertyNames;var Tt=Object.prototype.hasOwnProperty;var ot=o=>{throw TypeError(o)};var dt=(o,t)=>{for(var e in t)q(o,e,{get:t[e],enumerable:!0})},yt=(o,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of At(t))!Tt.call(o,s)&&s!==e&&q(o,s,{get:()=>t[s],enumerable:!(r=ht(t,s))||r.enumerable});return o};var bt=o=>yt(q({},"__esModule",{value:!0}),o);var st=(o,t,e)=>t.has(o)||ot("Cannot "+e);var u=(o,t,e)=>(st(o,t,"read from private field"),e?e.call(o):t.get(o)),h=(o,t,e)=>t.has(o)?ot("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(o):t.set(o,e),A=(o,t,e,r)=>(st(o,t,"write to private field"),r?r.call(o,e):t.set(o,e),e);var Ot={};dt(Ot,{RegularLanguage:()=>$,createFSA:()=>k,simulateFSA:()=>j,stepOnceFSA:()=>tt});var f=Object.freeze({DUPLICATE_ALPHABET_VALS:"E-001",DUPLICATE_STATE_NAMES:"E-002",INVALID_STATE_NAME:"E-003",START_STATE_NOT_FOUND:"E-004",ACCEPTS_NOT_SUBSET:"E-005",ORIGIN_STATE_NOT_FOUND:"E-006",DEST_STATE_NOT_FOUND:"E-007",MISSING_REQUIRED_TRANSITION:"E-008",INVALID_INPUT_CHAR:"E-009",INPUT_STATE_NOT_FOUND:"E-010",INVALID_TRANSITION_OBJECT:"E-011",DUPLICATE_TRANSITION_OBJECT:"E-012",INVALID_STATE_ARRAY:"E-013"});var I=class{constructor(t){if(this.name=t,!this.name)throw new Error(f.INVALID_STATE_NAME)}};var it=o=>o.reduce((t,e)=>Object.assign(t,{[e]:(t[e]||0)+1}),{}),at=o=>Object.keys(o).filter(t=>o[t]>1);var ct=o=>{let t=new Set;for(let e of o){if(t.has(e.name))return!0;t.add(e.name)}return!1},S=(o,t,e)=>{let r=o.get(t);return r??e},y=(o,t)=>t instanceof o||!!o.name&&o.name===t.constructor.name,pt=(o,t)=>{for(let e of o)if(!t.has(e))return!1;return!0};var G=class{constructor(t){if(!Array.isArray(t))if(typeof t=="string")t=[...t];else throw new TypeError;if(this.sigma=t,at(it(this.sigma)).length>0)throw new Error(f.DUPLICATE_ALPHABET_VALS)}};var K=class{constructor(t,e,r){this.origin=t,this.dest=e,this.input=r}};var C=class{constructor(t,e,r){this.origin=t,this.dest=e,this.input=r}};var F=class{static validateTFunc(t,e,r,s){let n=new Set;for(let i of r){if(!t.has(i.origin))throw console.error("Origin state was invalid: %o",JSON.stringify(i.origin)),new Error(f.ORIGIN_STATE_NOT_FOUND);if(!t.has(i.dest))throw console.error("Dest state was invalid: %o",JSON.stringify(i.dest)),new Error(f.DEST_STATE_NOT_FOUND);let a=S(e,i.origin,new Set);if(this.isValidInputChar(i.input,s))if(e.has(i.origin)&&a.has(i.input))n.add(i),a.delete(i.input),a.size===0&&e.delete(i.origin);else throw new Error(f.DUPLICATE_TRANSITION_OBJECT);else throw new Error(f.INVALID_INPUT_CHAR)}if(e.size>0){console.error("Not all FSA paths have a transition specified:");for(let[i,a]of e)console.error("State %s on input(s): %s",i.name,[...a].join(" "));throw new Error(f.MISSING_REQUIRED_TRANSITION)}return n}static createPaths(t,e){let r=new Map;for(let s of t)for(let n of e.sigma){let i=S(r,s,new Set);r.has(s)?i.add(n):r.set(s,new Set([n]))}return r}static determineStateOrder(t,e,r,s,n){let i=[];t=new Map;for(let p of e){let l=S(t,p.origin.name,new Set);t.has(p.origin.name)?l.add(p.dest.name):t.set(p.origin.name,new Set([p.dest.name]))}this.parseLinks(i,s.name,t);let a=[];Object.values([...r]).map(p=>a.push(p.name));let c=a.filter(p=>!i.includes(p));return c.length>0&&(console.warn("Dead states detected, removing them and associated transitions: %O",c),this.removeDeadStates(c,r,n,e)),i}static removeDeadStates(t,e,r,s){for(let n of e)t.indexOf(n.name)!==-1&&e.delete(n);for(let n of r)t.indexOf(n.name)!==-1&&r.delete(n);for(let n of s)(t.indexOf(n.origin.name)!==-1||t.indexOf(n.dest.name)!==-1)&&s.delete(n)}static parseLinks(t,e,r){t.push(e);let s=S(r,e,new Set);for(let n of s)t.indexOf(n)===-1&&this.parseLinks(t,n,r)}static isValidInputChar(t,e){return t===""?!1:e.sigma.indexOf(t)!==-1}},ft=(o,t,e,r,s)=>{let n=new Set;for(let i of e){if(!i.from||!i.to||!i.input)throw new Error(f.INVALID_TRANSITION_OBJECT);let a=S(o,i.from,null),c=S(o,i.to,null);n.add(new C(a,c,i.input))}return new b(new Set(o.values()),t,n,r,s)};var V=class extends F{static isValidInputChar(t,e){return e.sigma.indexOf(t)!==-1||t===""}static populateEpsilons(t,e){let r=!0;for(;r;){r=!1;let s=Array.from(t).filter(n=>e.includes(n.origin)&&n.input==="");for(let n of s)e.includes(n.dest)||(e.push(n.dest),r=!0)}return e}static validateTFunc(t,e,r,s){let n=new Set;for(let i of r){let a=!1;if(!t.has(i.origin))throw console.error("Origin state was invalid: %o",JSON.stringify(i.origin)),new Error(f.ORIGIN_STATE_NOT_FOUND);if(!t.has(i.dest))throw console.error("Dest state was invalid: %o",JSON.stringify(i.dest)),new Error(f.DEST_STATE_NOT_FOUND);for(let c of n)c.origin===i.origin&&c.dest===i.dest&&c.input===i.input&&(a=!0);if(!a&&e.has(i.origin))if(this.isValidInputChar(i.input,s))n.add(i);else throw new Error(f.INVALID_INPUT_CHAR)}return n}},ut=(o,t,e,r,s)=>{let n=new Set;for(let i of e){if(!i.from||!i.to||!i.input&&i.input!=="")throw new Error(f.INVALID_TRANSITION_OBJECT);let a=S(o,i.from,null),c=i.to.split(","),p=[];c.forEach(l=>{p.push(S(o,l,null))}),n.add(new K(a,p,i.input))}return new g(new Set(o.values()),t,n,r,s)};var E=(()=>{function o(s,n,i){if(s.getAlphabet().sigma.indexOf(n)===-1)throw new Error(f.INVALID_INPUT_CHAR);if(!s.getStates().has(i))throw new Error(f.INPUT_STATE_NOT_FOUND);let a=Array.from(s.getTFunc()).find(c=>c.origin===i&&c.input===n);if(a)return a.dest;throw new Error(f.INVALID_TRANSITION_OBJECT)}function t(s,n,i){let a=[];if(s.getAlphabet().sigma.indexOf(n)===-1)throw new Error(f.INVALID_INPUT_CHAR);if(i=e(s.getTFunc(),i),n==="")return new Set(i);for(let l of i){let U=Array.from(s.getTFunc()).filter(d=>d.origin===l&&d.input===n);a=a.concat(U)}let c=[];if(a.length>1)for(let l of a)c.push(l.dest);else if(a.length===1)c.push(a[0].dest);else return new Set;return new Set(e(s.getTFunc(),c))}function e(s,n){return V.populateEpsilons(s,n)}class r{constructor(n){this._type=n}receiveInput(n,i,a){if(y(g,n))return a instanceof I?t(n,i,[a]):t(n,i,a);if(Array.isArray(a)){if(a.length>1)throw console.error("State array can only contain one state for DFAs"),new Error(f.INVALID_STATE_ARRAY);a=a[0]}return o(n,i,a)}validateTFunc(n,i,a,c){return this._type===g?V.validateTFunc(n,i,a,c):F.validateTFunc(n,i,a,c)}createPaths(n,i){return F.createPaths(n,i)}determineStateOrder(n,i,a,c,p){return F.determineStateOrder(n,i,a,c,p)}}return r})(),k=(o,t,e,r,s)=>{let n=new Map;if(typeof o=="string")n.set(o,new I(o));else if(Array.isArray(o))for(let l of o)n.has(l)||n.set(l,new I(l));else throw new TypeError(String(o));let i=new G(t);if(typeof r!="string")throw new TypeError(String(r));let a=S(n,r,null),c=new Set;if(typeof s=="string")n.has(s)&&c.add(S(n,s,null));else if(Array.isArray(s))for(let l of s)c.add(S(n,l,null));else throw new TypeError(String(s));let p;if(!Array.isArray(e)&&typeof e=="object")p=[e];else if(Array.isArray(e))p=e;else throw new TypeError(String(e));for(let l of p)if(l.to.indexOf(",")!=-1||l.input==="")return ut(n,i,p,a,c);return ft(n,i,p,a,c)};var w,D,O,_,x,P,Q,R,b=class{constructor(t,e,r,s,n){h(this,w);h(this,D);h(this,O);h(this,_);h(this,x);h(this,P);h(this,Q,new Map);h(this,R);if(A(this,R,new E(this.constructor)),ct(t))throw new Error(f.DUPLICATE_STATE_NAMES);if(A(this,w,t),A(this,D,e),A(this,P,u(this,R).createPaths(u(this,w),u(this,D))),!t.has(s))throw new Error(f.START_STATE_NOT_FOUND);if(A(this,_,s),Object.keys(n).length===0&&n.constructor===Object&&(n=new Set([])),!pt(n,t))throw new Error(f.ACCEPTS_NOT_SUBSET);A(this,x,n),A(this,O,u(this,R).validateTFunc(u(this,w),u(this,P),r,u(this,D)))}getStates(){return u(this,w)}getAlphabet(){return u(this,D)}getTFunc(){return u(this,O)}getStartState(){return u(this,_)}getAcceptStates(){return u(this,x)}getType(){return"DFA"}generateDigraph(){let t=[];for(let r of u(this,x))t.push(r.name);let e=new Map;return Object.values([...u(this,O)]).map(function(r){let s=r.origin.name+r.dest.name,n=r.input;if(n===""&&(n="\u03B5"),!e.has(s))e.set(s,r.origin.name+" -> "+r.dest.name+' [ label = "'+n+'" ];');else{let i=S(e,s,""),a=i.split('"')[1],c=a.split(",");c.push(n),c.sort(),i=i.replace('"'+a+'"','"'+c.toString()+'"'),e.set(s,i)}}),`digraph fsa {
|
|
2
|
+
${Object.values(u(this,R).determineStateOrder(u(this,Q),u(this,O),u(this,w),u(this,_),u(this,x))).map(function(r){return t.indexOf(r)!==-1?r+" [shape = doublecircle];":r}).join(`
|
|
3
|
+
`)}
|
|
4
|
+
rankdir=LR;
|
|
5
|
+
node [shape = point ]; qi;
|
|
6
|
+
node [shape = circle];
|
|
7
|
+
qi -> ${u(this,_).name};
|
|
8
|
+
${Object.values([...e]).map(function([,r]){return r}).join(`
|
|
9
|
+
`)}
|
|
10
|
+
}
|
|
11
|
+
`}};w=new WeakMap,D=new WeakMap,O=new WeakMap,_=new WeakMap,x=new WeakMap,P=new WeakMap,Q=new WeakMap,R=new WeakMap;var g=class extends b{constructor(t,e,r,s,n){e.sigma.includes("")||e.sigma.push("");let i=new Set;for(let a of r)a.dest.forEach(c=>{i.add(new C(a.origin,c,a.input))});super(t,e,i,s,n)}getType(){return"NFA"}};var j=(o,t,e=!1,r=!1)=>y(g,t)?Ft(o,t,new E(g),e,r):It(o,t,new E(b),e,r),tt=(o,t,e,r=!1)=>{if(typeof o!="string")throw r&&console.error("Input w was invalid type: %O",o),new TypeError;if(typeof t!="string"&&!Array.isArray(t))throw r&&console.error("Input state was invalid type: %O",t),new TypeError;r&&console.log("Input Processing Started");let s=[];if(typeof t=="string"){for(let i of e.getStates().values())t===i.name&&(s=i);if(!s||Array.isArray(s)&&s.length===0)throw new Error(f.INVALID_STATE_NAME)}else{s=[];for(let i of e.getStates().values())t.includes(i.name)&&s.push(i);if(s.length!==t.length)throw new Error(f.INVALID_STATE_NAME)}let n;if(y(g,e)?n=[...new E(g).receiveInput(e,o,s)]:n=new E(b).receiveInput(e,o,s),r&&console.log("%o x '%s' -> %o",JSON.stringify(s),o,JSON.stringify(n)),r&&console.log("Input Processing Ended"),n instanceof I)return n.name;{let i=[];for(let a of n)i.push(a.name);return i}};function It(o,t,e,r,s){if(r&&console.log("Beginning DFA Simulation"),!Array.isArray(o))if(typeof o=="string")o=[...o];else throw r&&console.error("Input w was invalid type: %O",o),new TypeError;r&&console.log("Input Processing Started");let n=t.getStartState();for(let i of o){let a=n;n=e.receiveInput(t,i,a),r&&console.log("%o x '%s' -> %o",JSON.stringify(a),i,JSON.stringify(n))}return r&&console.log("Input Processing Ended"),t.getAcceptStates().has(n)?(r&&console.log("Input Accepted!"),s?n.name:!0):(r&&console.log("Input Rejected!"),s?n.name:!1)}function Ft(o,t,e,r,s){if(r&&console.log("Beginning NFA Simulation"),!(o instanceof Array))if(typeof o=="string")o===""?o=[""]:o=[...o];else throw r&&console.error("Input w was invalid type: %O",o),new TypeError;r&&console.log("Input Processing Started");let n=[t.getStartState()];for(let a of o){let c=n;n=[...e.receiveInput(t,a,n)],r&&console.log("%o x '%s' -> %o",JSON.stringify(c),a,JSON.stringify(n))}r&&console.log("Input Processing Ended");let i=[];for(let a of t.getAcceptStates())if(n.includes(a)){if(!s)return r&&console.log("Input Accepted!"),!0;i.push(a.name)}if(i.length>0)return r&&console.log("Input Accepted!"),i;if(r&&console.log("Input Rejected!"),s){if(n.length>0)for(let a of n)i.push(a.name);return i}else return!1}var J=class{};function B(o){return o.getAlphabet().sigma.filter(t=>t!=="").sort()}function et(o,t){return[...new Set([...o,...t])].sort()}function lt(o){let t=[...o.getStates()].map(a=>a.name).sort(),e=B(o),r=[...o.getAcceptStates()].map(a=>a.name).sort(),s=o.getStartState().name,n=new Map;for(let a of o.getTFunc()){let c=`${a.origin.name}\0${a.input}`,p=n.get(c)??new Set;p.add(a.dest.name),n.set(c,p)}let i=[];for(let[a,c]of n){let[p,l]=a.split("\0");i.push({from:p,to:[...c].sort().join(","),input:l})}return i.sort((a,c)=>{let p=a.from.localeCompare(c.from);return p!==0?p:a.input.localeCompare(c.input)}),{states:t,alphabet:e,transitions:i,start:s,accepts:r}}function v(o,t){let e=r=>`${t}${r}`;return{states:o.states.map(e),alphabet:[...o.alphabet],start:e(o.start),accepts:o.accepts.map(e),transitions:o.transitions.map(r=>({from:e(r.from),to:r.to.split(",").map(s=>e(s.trim())).join(","),input:r.input}))}}function H(o){return k(o.states,o.alphabet,o.transitions,o.start,o.accepts)}function wt(o,t){let e=v(o,"L1_"),r=v(t,"L2_"),s="union_start",n=[s,...e.states,...r.states],i=[{from:s,to:e.start,input:""},{from:s,to:r.start,input:""},...e.transitions,...r.transitions];return{states:n,alphabet:et(e.alphabet,r.alphabet),transitions:i,start:s,accepts:[...e.accepts,...r.accepts]}}function Nt(o,t){let e=v(o,"C1_"),r=v(t,"C2_"),s=[];for(let n of e.accepts)s.push({from:n,to:r.start,input:""});return{states:[...e.states,...r.states],alphabet:et(e.alphabet,r.alphabet),transitions:[...e.transitions,...r.transitions,...s],start:e.start,accepts:[...r.accepts]}}function Et(o){let t=v(o,"K_"),e="star_hub",r=[{from:e,to:t.start,input:""}];for(let s of t.accepts)r.push({from:s,to:e,input:""}),r.push({from:s,to:t.start,input:""});return{states:[e,...t.states],alphabet:[...t.alphabet],transitions:[...t.transitions,...r],start:e,accepts:[e,...t.accepts]}}var Y={unionDefinitions:wt,concatDefinitions:Nt,kleeneStarDefinition:Et};function St(o,t){let e=new Map,r=[];for(let s of o)e.set(s.name,s),r.push(s);for(;r.length>0;){let s=r.pop();for(let n of t.getTFunc())n.origin===s&&n.input===""&&(e.has(n.dest.name)||(e.set(n.dest.name,n.dest),r.push(n.dest)))}return[...e.values()].sort((s,n)=>s.name.localeCompare(n.name))}function Dt(o,t,e){let r=new Map;for(let s of o)for(let n of e.getTFunc())n.origin===s&&n.input===t&&r.set(n.dest.name,n.dest);return[...r.values()].sort((s,n)=>s.name.localeCompare(n.name))}function nt(o){return o.map(t=>t.name).join(",")}function gt(o){if(!y(g,o))throw new TypeError("subsetConstruction requires an NFA");let t=B(o),e=new Set([...o.getAcceptStates()].map(m=>m.name)),r=St([o.getStartState()],o),s=new Map,n=new Map,i=[],a=m=>{let N=nt(m);if(!s.has(N)){let M=`d${s.size}`;s.set(N,M),n.set(M,m)}return s.get(N)},c=a(r),p=[r],l=new Set([nt(r)]),U=!1,d="dead";for(;p.length>0;){let m=p.pop(),N=a(m);for(let M of t){let rt=Dt(m,M,o),z=rt.length>0?St(rt,o):[],Z;if(z.length===0){if(!U){U=!0,n.set(d,[]);for(let W of t)i.push({from:d,to:d,input:W})}Z=d}else{let W=nt(z);Z=a(z),l.has(W)||(l.add(W),p.push(z))}i.push({from:N,to:Z,input:M})}}let X=[...n.keys()];U&&!X.includes(d)&&X.push(d);let mt=[...n.entries()].filter(([,m])=>m.some(N=>e.has(N.name))).map(([m])=>m);return{states:X,alphabet:t,transitions:i,start:c,accepts:mt}}var T,L=class L extends J{constructor(e){super();h(this,T);A(this,T,e)}getClassification(){return"regular"}static fromAutomaton(e){return new L(e)}contains(e){try{return!!j(e,u(this,T))}catch(r){if(r instanceof Error&&r.message===f.INVALID_INPUT_CHAR)return!1;throw r}}getAutomaton(){return u(this,T)}getAlphabetSymbols(){return B(u(this,T))}toDefinition(){return lt(u(this,T))}union(e){let r=Y.unionDefinitions(this.toDefinition(),e.toDefinition());return L.fromAutomaton(H(r))}concat(e){let r=Y.concatDefinitions(this.toDefinition(),e.toDefinition());return L.fromAutomaton(H(r))}kleeneStar(){let e=Y.kleeneStarDefinition(this.toDefinition());return L.fromAutomaton(H(e))}toDFA(){if(!y(g,u(this,T)))return this;let e=gt(u(this,T));return L.fromAutomaton(H(e))}};T=new WeakMap;var $=L;return bt(Ot);})();
|
|
12
|
+
//# sourceMappingURL=demo-bundle.global.js.map
|
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,636 @@
|
|
|
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(_states2, _paths2, _tfunc2, _alph) {
|
|
123
|
+
const newTFunc = /* @__PURE__ */ new Set();
|
|
124
|
+
for (const _t of _tfunc2) {
|
|
125
|
+
if (!_states2.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 (!_states2.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(_paths2, _t.origin, /* @__PURE__ */ new Set());
|
|
134
|
+
if (this.isValidInputChar(_t.input, _alph)) {
|
|
135
|
+
if (_paths2.has(_t.origin) && pathStateVals.has(_t.input)) {
|
|
136
|
+
newTFunc.add(_t);
|
|
137
|
+
pathStateVals.delete(_t.input);
|
|
138
|
+
if (pathStateVals.size === 0) {
|
|
139
|
+
_paths2.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 (_paths2.size > 0) {
|
|
149
|
+
console.error("Not all FSA paths have a transition specified:");
|
|
150
|
+
for (const [key, val] of _paths2) {
|
|
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(_states2, _alph) {
|
|
158
|
+
const _paths2 = /* @__PURE__ */ new Map();
|
|
159
|
+
for (const state of _states2) {
|
|
160
|
+
for (const char of _alph.sigma) {
|
|
161
|
+
const pathStateVals = getOrDefault(_paths2, state, /* @__PURE__ */ new Set());
|
|
162
|
+
if (_paths2.has(state)) pathStateVals.add(char);
|
|
163
|
+
else _paths2.set(state, /* @__PURE__ */ new Set([char]));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return _paths2;
|
|
167
|
+
}
|
|
168
|
+
// Determine digraph order based on start state, then following the chain
|
|
169
|
+
static determineStateOrder(_links2, _tfunc2, _states2, _start2, _accepts2) {
|
|
170
|
+
const statesOrder = [];
|
|
171
|
+
_links2 = /* @__PURE__ */ new Map();
|
|
172
|
+
for (const tr of _tfunc2) {
|
|
173
|
+
const linkStateVals = getOrDefault(_links2, tr.origin.name, /* @__PURE__ */ new Set());
|
|
174
|
+
if (_links2.has(tr.origin.name)) linkStateVals.add(tr.dest.name);
|
|
175
|
+
else _links2.set(tr.origin.name, /* @__PURE__ */ new Set([tr.dest.name]));
|
|
176
|
+
}
|
|
177
|
+
this.parseLinks(statesOrder, _start2.name, _links2);
|
|
178
|
+
const stateArr = [];
|
|
179
|
+
Object.values([..._states2]).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, _states2, _accepts2, _tfunc2);
|
|
184
|
+
}
|
|
185
|
+
return statesOrder;
|
|
186
|
+
}
|
|
187
|
+
// Reduce FSA by removing dead states and associated transitions
|
|
188
|
+
static removeDeadStates(deadStates, _states2, _accepts2, _tfunc2) {
|
|
189
|
+
for (const state of _states2) {
|
|
190
|
+
if (deadStates.indexOf(state.name) !== -1) _states2.delete(state);
|
|
191
|
+
}
|
|
192
|
+
for (const state of _accepts2) {
|
|
193
|
+
if (deadStates.indexOf(state.name) !== -1) _accepts2.delete(state);
|
|
194
|
+
}
|
|
195
|
+
for (const tr of _tfunc2) {
|
|
196
|
+
if (deadStates.indexOf(tr.origin.name) !== -1 || deadStates.indexOf(tr.dest.name) !== -1) _tfunc2.delete(tr);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Recursively parse graph while adding to an array in order, beginning with q0
|
|
200
|
+
static parseLinks(arr, name, _links2) {
|
|
201
|
+
arr.push(name);
|
|
202
|
+
const nameVal = getOrDefault(_links2, name, /* @__PURE__ */ new Set());
|
|
203
|
+
for (const st of nameVal) {
|
|
204
|
+
if (arr.indexOf(st) === -1) this.parseLinks(arr, st, _links2);
|
|
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 _tfunc2 = /* @__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
|
+
_tfunc2.add(new Transition(fromVal, toVal, tr.input));
|
|
220
|
+
}
|
|
221
|
+
return new DFA(new Set(states.values()), alphabet, _tfunc2, 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(_tfunc2, state) {
|
|
232
|
+
let cont = true;
|
|
233
|
+
while (cont) {
|
|
234
|
+
cont = false;
|
|
235
|
+
const epsTransitions = Array.from(_tfunc2).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(_states2, _paths2, _tfunc2, _alph) {
|
|
249
|
+
const newTFunc = /* @__PURE__ */ new Set();
|
|
250
|
+
for (const _t of _tfunc2) {
|
|
251
|
+
let skip = false;
|
|
252
|
+
if (!_states2.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 (!_states2.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
|
+
for (const _checkT of newTFunc) {
|
|
261
|
+
if (_checkT.origin === _t.origin && _checkT.dest === _t.dest && _checkT.input === _t.input) skip = true;
|
|
262
|
+
}
|
|
263
|
+
if (!skip) {
|
|
264
|
+
if (_paths2.has(_t.origin)) {
|
|
265
|
+
if (this.isValidInputChar(_t.input, _alph)) {
|
|
266
|
+
newTFunc.add(_t);
|
|
267
|
+
} else {
|
|
268
|
+
throw new Error(ErrorCode.INVALID_INPUT_CHAR);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return newTFunc;
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
var createNFA = (states, alphabet, transitions, start, accepts) => {
|
|
277
|
+
const _tfunc2 = /* @__PURE__ */ new Set();
|
|
278
|
+
for (const tr of transitions) {
|
|
279
|
+
if (!tr.from || !tr.to || !tr.input && tr.input !== "")
|
|
280
|
+
throw new Error(ErrorCode.INVALID_TRANSITION_OBJECT);
|
|
281
|
+
const fromVal = getOrDefault(states, tr.from, null);
|
|
282
|
+
const toVal = tr.to.split(",");
|
|
283
|
+
const destStates = [];
|
|
284
|
+
toVal.forEach((_dest) => {
|
|
285
|
+
destStates.push(getOrDefault(states, _dest, null));
|
|
286
|
+
});
|
|
287
|
+
_tfunc2.add(new NFATransition(fromVal, destStates, tr.input));
|
|
288
|
+
}
|
|
289
|
+
return new NFA(new Set(states.values()), alphabet, _tfunc2, start, accepts);
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// src/utils/FSAUtils.ts
|
|
293
|
+
var FSAUtils = /* @__PURE__ */ (() => {
|
|
294
|
+
function receiveInputDFA(dfa, input, state) {
|
|
295
|
+
if (dfa.getAlphabet().sigma.indexOf(input) === -1) throw new Error(ErrorCode.INVALID_INPUT_CHAR);
|
|
296
|
+
if (!dfa.getStates().has(state)) throw new Error(ErrorCode.INPUT_STATE_NOT_FOUND);
|
|
297
|
+
const path = Array.from(dfa.getTFunc()).find((obj) => {
|
|
298
|
+
return obj.origin === state && obj.input === input;
|
|
299
|
+
});
|
|
300
|
+
if (path) return path.dest;
|
|
301
|
+
else throw new Error(ErrorCode.INVALID_TRANSITION_OBJECT);
|
|
302
|
+
}
|
|
303
|
+
function receiveInputNFA(nfa, input, state) {
|
|
304
|
+
let path = [];
|
|
305
|
+
if (nfa.getAlphabet().sigma.indexOf(input) === -1) throw new Error(ErrorCode.INVALID_INPUT_CHAR);
|
|
306
|
+
state = populateEpsilons(nfa.getTFunc(), state);
|
|
307
|
+
if (input === "") return new Set(state);
|
|
308
|
+
for (const _s of state) {
|
|
309
|
+
const _addToPath = Array.from(nfa.getTFunc()).filter((obj) => {
|
|
310
|
+
return obj.origin === _s && obj.input === input;
|
|
311
|
+
});
|
|
312
|
+
path = path.concat(_addToPath);
|
|
313
|
+
}
|
|
314
|
+
const resultArr = [];
|
|
315
|
+
if (path.length > 1) {
|
|
316
|
+
for (const _s of path) resultArr.push(_s.dest);
|
|
317
|
+
} else if (path.length === 1) {
|
|
318
|
+
resultArr.push(path[0].dest);
|
|
319
|
+
} else {
|
|
320
|
+
return /* @__PURE__ */ new Set();
|
|
321
|
+
}
|
|
322
|
+
const retSet = new Set(populateEpsilons(nfa.getTFunc(), resultArr));
|
|
323
|
+
return retSet;
|
|
324
|
+
}
|
|
325
|
+
function populateEpsilons(_tfunc2, state) {
|
|
326
|
+
return NFAUtils.populateEpsilons(_tfunc2, state);
|
|
327
|
+
}
|
|
328
|
+
class FSAUtils2 {
|
|
329
|
+
constructor(v) {
|
|
330
|
+
this._type = v;
|
|
331
|
+
}
|
|
332
|
+
receiveInput(fsa, input, state) {
|
|
333
|
+
if (instanceOf(NFA, fsa)) {
|
|
334
|
+
if (state instanceof State) return receiveInputNFA(fsa, input, [state]);
|
|
335
|
+
else return receiveInputNFA(fsa, input, state);
|
|
336
|
+
} else {
|
|
337
|
+
if (Array.isArray(state)) {
|
|
338
|
+
if (state.length > 1) {
|
|
339
|
+
console.error("State array can only contain one state for DFAs");
|
|
340
|
+
throw new Error(ErrorCode.INVALID_STATE_ARRAY);
|
|
341
|
+
} else {
|
|
342
|
+
state = state[0];
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return receiveInputDFA(fsa, input, state);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
validateTFunc(_states2, _paths2, _tfunc2, _alph) {
|
|
349
|
+
if (this._type === NFA) {
|
|
350
|
+
return NFAUtils.validateTFunc(_states2, _paths2, _tfunc2, _alph);
|
|
351
|
+
} else {
|
|
352
|
+
return DFAUtils.validateTFunc(_states2, _paths2, _tfunc2, _alph);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
createPaths(_states2, _alph) {
|
|
356
|
+
return DFAUtils.createPaths(_states2, _alph);
|
|
357
|
+
}
|
|
358
|
+
determineStateOrder(_links2, _tfunc2, _states2, _start2, _accepts2) {
|
|
359
|
+
return DFAUtils.determineStateOrder(_links2, _tfunc2, _states2, _start2, _accepts2);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return FSAUtils2;
|
|
363
|
+
})();
|
|
364
|
+
var createFSA = (states, alphabet, transitions, start, accepts) => {
|
|
365
|
+
const _states2 = /* @__PURE__ */ new Map();
|
|
366
|
+
if (typeof states === "string") {
|
|
367
|
+
_states2.set(states, new State(states));
|
|
368
|
+
} else if (Array.isArray(states)) {
|
|
369
|
+
for (const state of states) {
|
|
370
|
+
if (!_states2.has(state)) _states2.set(state, new State(state));
|
|
371
|
+
}
|
|
372
|
+
} else {
|
|
373
|
+
throw new TypeError(String(states));
|
|
374
|
+
}
|
|
375
|
+
const _alphabet2 = new Alphabet(alphabet);
|
|
376
|
+
if (typeof start !== "string") throw new TypeError(String(start));
|
|
377
|
+
const _start2 = getOrDefault(_states2, start, null);
|
|
378
|
+
const _accepts2 = /* @__PURE__ */ new Set();
|
|
379
|
+
if (typeof accepts === "string") {
|
|
380
|
+
if (_states2.has(accepts)) _accepts2.add(getOrDefault(_states2, accepts, null));
|
|
381
|
+
} else if (Array.isArray(accepts)) {
|
|
382
|
+
for (const state of accepts) {
|
|
383
|
+
_accepts2.add(getOrDefault(_states2, state, null));
|
|
384
|
+
}
|
|
385
|
+
} else {
|
|
386
|
+
throw new TypeError(String(accepts));
|
|
387
|
+
}
|
|
388
|
+
let transitionList;
|
|
389
|
+
if (!Array.isArray(transitions) && typeof transitions === "object") transitionList = [transitions];
|
|
390
|
+
else if (Array.isArray(transitions)) transitionList = transitions;
|
|
391
|
+
else throw new TypeError(String(transitions));
|
|
392
|
+
for (const tr of transitionList) {
|
|
393
|
+
if (tr.to.indexOf(",") != -1 || tr.input === "")
|
|
394
|
+
return createNFA(_states2, _alphabet2, transitionList, _start2, _accepts2);
|
|
395
|
+
}
|
|
396
|
+
return createDFA(_states2, _alphabet2, transitionList, _start2, _accepts2);
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
// src/automata/DFA.ts
|
|
400
|
+
var _states, _alphabet, _tfunc, _start, _accepts, _paths, _links, _utils;
|
|
401
|
+
var DFA = class {
|
|
402
|
+
constructor(states, alphabet, tfunc, start, accepts) {
|
|
403
|
+
// Primary FSA attributes
|
|
404
|
+
__privateAdd(this, _states);
|
|
405
|
+
__privateAdd(this, _alphabet);
|
|
406
|
+
__privateAdd(this, _tfunc);
|
|
407
|
+
__privateAdd(this, _start);
|
|
408
|
+
__privateAdd(this, _accepts);
|
|
409
|
+
// Intermediary attributes used in constructor
|
|
410
|
+
__privateAdd(this, _paths);
|
|
411
|
+
// States mapped to each member of Σ, will be empty after constructor returns
|
|
412
|
+
__privateAdd(this, _links, /* @__PURE__ */ new Map());
|
|
413
|
+
// State names mapped to their dest state names
|
|
414
|
+
__privateAdd(this, _utils);
|
|
415
|
+
__privateSet(this, _utils, new FSAUtils(this.constructor));
|
|
416
|
+
if (checkStateDuplicates(states)) throw new Error(ErrorCode.DUPLICATE_STATE_NAMES);
|
|
417
|
+
__privateSet(this, _states, states);
|
|
418
|
+
__privateSet(this, _alphabet, alphabet);
|
|
419
|
+
__privateSet(this, _paths, __privateGet(this, _utils).createPaths(__privateGet(this, _states), __privateGet(this, _alphabet)));
|
|
420
|
+
if (!states.has(start)) throw new Error(ErrorCode.START_STATE_NOT_FOUND);
|
|
421
|
+
__privateSet(this, _start, start);
|
|
422
|
+
if (Object.keys(accepts).length === 0 && accepts.constructor === Object) accepts = /* @__PURE__ */ new Set([]);
|
|
423
|
+
if (!isSubsetOf(accepts, states)) throw new Error(ErrorCode.ACCEPTS_NOT_SUBSET);
|
|
424
|
+
__privateSet(this, _accepts, accepts);
|
|
425
|
+
__privateSet(this, _tfunc, __privateGet(this, _utils).validateTFunc(__privateGet(this, _states), __privateGet(this, _paths), tfunc, __privateGet(this, _alphabet)));
|
|
426
|
+
}
|
|
427
|
+
/*
|
|
428
|
+
* Getters
|
|
429
|
+
*/
|
|
430
|
+
getStates() {
|
|
431
|
+
return __privateGet(this, _states);
|
|
432
|
+
}
|
|
433
|
+
getAlphabet() {
|
|
434
|
+
return __privateGet(this, _alphabet);
|
|
435
|
+
}
|
|
436
|
+
getTFunc() {
|
|
437
|
+
return __privateGet(this, _tfunc);
|
|
438
|
+
}
|
|
439
|
+
getStartState() {
|
|
440
|
+
return __privateGet(this, _start);
|
|
441
|
+
}
|
|
442
|
+
getAcceptStates() {
|
|
443
|
+
return __privateGet(this, _accepts);
|
|
444
|
+
}
|
|
445
|
+
getType() {
|
|
446
|
+
return "DFA";
|
|
447
|
+
}
|
|
448
|
+
generateDigraph() {
|
|
449
|
+
const acceptArr = [];
|
|
450
|
+
for (const state of __privateGet(this, _accepts)) acceptArr.push(state.name);
|
|
451
|
+
const pairs = /* @__PURE__ */ new Map();
|
|
452
|
+
Object.values([...__privateGet(this, _tfunc)]).map(function(t) {
|
|
453
|
+
const key = t.origin.name + t.dest.name;
|
|
454
|
+
let _input = t.input;
|
|
455
|
+
if (_input === "") _input = "\u03B5";
|
|
456
|
+
if (!pairs.has(key)) {
|
|
457
|
+
pairs.set(key, t.origin.name + " -> " + t.dest.name + ' [ label = "' + _input + '" ];');
|
|
458
|
+
} else {
|
|
459
|
+
let _line = getOrDefault(pairs, key, "");
|
|
460
|
+
const _oldinput = _line.split('"')[1];
|
|
461
|
+
const _toAdd = _oldinput.split(",");
|
|
462
|
+
_toAdd.push(_input);
|
|
463
|
+
_toAdd.sort();
|
|
464
|
+
_line = _line.replace('"' + _oldinput + '"', '"' + _toAdd.toString() + '"');
|
|
465
|
+
pairs.set(key, _line);
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
return `digraph fsa {
|
|
469
|
+
${Object.values(
|
|
470
|
+
__privateGet(this, _utils).determineStateOrder(__privateGet(this, _links), __privateGet(this, _tfunc), __privateGet(this, _states), __privateGet(this, _start), __privateGet(this, _accepts))
|
|
471
|
+
).map(function(str) {
|
|
472
|
+
if (acceptArr.indexOf(str) !== -1) return str + " [shape = doublecircle];";
|
|
473
|
+
else return str;
|
|
474
|
+
}).join("\n ")}
|
|
475
|
+
rankdir=LR;
|
|
476
|
+
node [shape = point ]; qi;
|
|
477
|
+
node [shape = circle];
|
|
478
|
+
qi -> ${__privateGet(this, _start).name};
|
|
479
|
+
${Object.values([...pairs]).map(function([, val]) {
|
|
480
|
+
return val;
|
|
481
|
+
}).join("\n ")}
|
|
482
|
+
}
|
|
483
|
+
`;
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
_states = new WeakMap();
|
|
487
|
+
_alphabet = new WeakMap();
|
|
488
|
+
_tfunc = new WeakMap();
|
|
489
|
+
_start = new WeakMap();
|
|
490
|
+
_accepts = new WeakMap();
|
|
491
|
+
_paths = new WeakMap();
|
|
492
|
+
_links = new WeakMap();
|
|
493
|
+
_utils = new WeakMap();
|
|
494
|
+
|
|
495
|
+
// src/automata/NFA.ts
|
|
496
|
+
var NFA = class extends DFA {
|
|
497
|
+
constructor(states, alphabet, tfunc, start, accepts) {
|
|
498
|
+
if (!alphabet.sigma.includes("")) alphabet.sigma.push("");
|
|
499
|
+
const expandedTfunc = /* @__PURE__ */ new Set();
|
|
500
|
+
for (const _t of tfunc) {
|
|
501
|
+
_t.dest.forEach((_dest) => {
|
|
502
|
+
expandedTfunc.add(new Transition(_t.origin, _dest, _t.input));
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
super(states, alphabet, expandedTfunc, start, accepts);
|
|
506
|
+
}
|
|
507
|
+
getType() {
|
|
508
|
+
return "NFA";
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
// src/engine/Simulators.ts
|
|
513
|
+
var simulateFSA = (w, fsa, logging = false, returnEndState = false) => {
|
|
514
|
+
if (instanceOf(NFA, fsa)) {
|
|
515
|
+
return simulateNFA(w, fsa, new FSAUtils(NFA), logging, returnEndState);
|
|
516
|
+
} else {
|
|
517
|
+
return simulateDFA(w, fsa, new FSAUtils(DFA), logging, returnEndState);
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
var stepOnceFSA = (w, qin, fsa, logging = false) => {
|
|
521
|
+
if (typeof w !== "string") {
|
|
522
|
+
if (logging) console.error("Input w was invalid type: %O", w);
|
|
523
|
+
throw new TypeError();
|
|
524
|
+
}
|
|
525
|
+
if (typeof qin !== "string" && !Array.isArray(qin)) {
|
|
526
|
+
if (logging) console.error("Input state was invalid type: %O", qin);
|
|
527
|
+
throw new TypeError();
|
|
528
|
+
}
|
|
529
|
+
if (logging) console.log("Input Processing Started");
|
|
530
|
+
let prevState = [];
|
|
531
|
+
if (typeof qin === "string") {
|
|
532
|
+
for (const state of fsa.getStates().values()) {
|
|
533
|
+
if (qin === state.name) prevState = state;
|
|
534
|
+
}
|
|
535
|
+
if (!prevState || Array.isArray(prevState) && prevState.length === 0)
|
|
536
|
+
throw new Error(ErrorCode.INVALID_STATE_NAME);
|
|
537
|
+
} else {
|
|
538
|
+
prevState = [];
|
|
539
|
+
for (const state of fsa.getStates().values()) {
|
|
540
|
+
if (qin.includes(state.name)) prevState.push(state);
|
|
541
|
+
}
|
|
542
|
+
if (prevState.length !== qin.length) {
|
|
543
|
+
throw new Error(ErrorCode.INVALID_STATE_NAME);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
let newState;
|
|
547
|
+
if (instanceOf(NFA, fsa)) newState = [...new FSAUtils(NFA).receiveInput(fsa, w, prevState)];
|
|
548
|
+
else newState = new FSAUtils(DFA).receiveInput(fsa, w, prevState);
|
|
549
|
+
if (logging) console.log("%o x '%s' -> %o", JSON.stringify(prevState), w, JSON.stringify(newState));
|
|
550
|
+
if (logging) console.log("Input Processing Ended");
|
|
551
|
+
if (newState instanceof State) return newState.name;
|
|
552
|
+
else {
|
|
553
|
+
const retArray = [];
|
|
554
|
+
for (const _s of newState) {
|
|
555
|
+
retArray.push(_s.name);
|
|
556
|
+
}
|
|
557
|
+
return retArray;
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
function simulateDFA(w, dfa, utils, logging, returnEndState) {
|
|
561
|
+
if (logging) console.log("Beginning DFA Simulation");
|
|
562
|
+
if (!Array.isArray(w)) {
|
|
563
|
+
if (typeof w === "string") w = [...w];
|
|
564
|
+
else {
|
|
565
|
+
if (logging) console.error("Input w was invalid type: %O", w);
|
|
566
|
+
throw new TypeError();
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
if (logging) console.log("Input Processing Started");
|
|
570
|
+
let currentState = dfa.getStartState();
|
|
571
|
+
for (const char of w) {
|
|
572
|
+
const prevState = currentState;
|
|
573
|
+
currentState = utils.receiveInput(dfa, char, prevState);
|
|
574
|
+
if (logging) console.log("%o x '%s' -> %o", JSON.stringify(prevState), char, JSON.stringify(currentState));
|
|
575
|
+
}
|
|
576
|
+
if (logging) console.log("Input Processing Ended");
|
|
577
|
+
if (dfa.getAcceptStates().has(currentState)) {
|
|
578
|
+
if (logging) console.log("Input Accepted!");
|
|
579
|
+
if (returnEndState) return currentState.name;
|
|
580
|
+
else return true;
|
|
581
|
+
} else {
|
|
582
|
+
if (logging) console.log("Input Rejected!");
|
|
583
|
+
if (returnEndState) return currentState.name;
|
|
584
|
+
else return false;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
function simulateNFA(w, nfa, utils, logging, returnEndState) {
|
|
588
|
+
if (logging) console.log("Beginning NFA Simulation");
|
|
589
|
+
if (!(w instanceof Array)) {
|
|
590
|
+
if (typeof w === "string") {
|
|
591
|
+
if (w === "") w = [""];
|
|
592
|
+
else w = [...w];
|
|
593
|
+
} else {
|
|
594
|
+
if (logging) console.error("Input w was invalid type: %O", w);
|
|
595
|
+
throw new TypeError();
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
if (logging) console.log("Input Processing Started");
|
|
599
|
+
let currentState = [nfa.getStartState()];
|
|
600
|
+
for (const char of w) {
|
|
601
|
+
const prevState = currentState;
|
|
602
|
+
currentState = [...utils.receiveInput(nfa, char, currentState)];
|
|
603
|
+
if (logging) console.log("%o x '%s' -> %o", JSON.stringify(prevState), char, JSON.stringify(currentState));
|
|
604
|
+
}
|
|
605
|
+
if (logging) console.log("Input Processing Ended");
|
|
606
|
+
const retObj = [];
|
|
607
|
+
for (const _accState of nfa.getAcceptStates()) {
|
|
608
|
+
if (currentState.includes(_accState)) {
|
|
609
|
+
if (!returnEndState) {
|
|
610
|
+
if (logging) console.log("Input Accepted!");
|
|
611
|
+
return true;
|
|
612
|
+
}
|
|
613
|
+
retObj.push(_accState.name);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (retObj.length > 0) {
|
|
617
|
+
if (logging) console.log("Input Accepted!");
|
|
618
|
+
return retObj;
|
|
619
|
+
}
|
|
620
|
+
if (logging) console.log("Input Rejected!");
|
|
621
|
+
if (returnEndState) {
|
|
622
|
+
if (currentState.length > 0) {
|
|
623
|
+
for (const _cState of currentState) retObj.push(_cState.name);
|
|
624
|
+
}
|
|
625
|
+
return retObj;
|
|
626
|
+
} else {
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
631
|
+
0 && (module.exports = {
|
|
632
|
+
createFSA,
|
|
633
|
+
simulateFSA,
|
|
634
|
+
stepOnceFSA
|
|
635
|
+
});
|
|
636
|
+
//# sourceMappingURL=index.cjs.map
|