public IAcceptWord Reverse() { var neaET = new NFAeTransform(); string[] names = new string[this.StatesCount + 1]; // array pointer old to new state uint[] newstate = new uint[this.StatesCount]; for (uint i = 0; i < newstate.Length; i++) { newstate[i] = this.StatesCount - i; names[i + 1] = (newstate[i] - 1).ToString(); } names[0] = "new"; // turn and add each transform foreach (var dt in this.Transforms.Reverse()) { foreach (var dtv in dt.Value) { neaET.AddM(newstate[dtv], dt.Key.c, newstate[dt.Key.q]); } } // start state is qe, which leads to every old accepted state for (int i = 0; i < this.AcceptedStates.Length; i++) { neaET.AddM(0, null, newstate[this.AcceptedStates[i]]); } return(new NFAe($"NFAe_Reverse({Name})", names, this.Alphabet, neaET, 0, this.StatesCount)); }
public static NFA GenerateRandom() { const byte MAX_STATES = 20; const byte MAX_CHAR = 7; var rnd = Uni.Utils.RND; var t = new NFAeTransform(); int stateCount = rnd.Next(1, MAX_STATES); char[] alphabet = RandomGenerator.RandomAlphabet(1, MAX_CHAR); uint[] accState = RandomGenerator.RandomAcceptedStates(1, stateCount / 3, stateCount); for (uint i = 0; i < stateCount; i++) { int transformsRnd = rnd.Next(0, alphabet.Length); for (int j = 0; j < transformsRnd; j++) { t.AddM(i, alphabet.RndElement(), (uint)rnd.Next(0, stateCount)); } } var ret = new NFA("NFA_Random", (uint)stateCount, alphabet, t, (uint)rnd.Next(0, stateCount), accState); ret.Name = $"NFA_Random_{ret.GetHashCode()}"; return(ret); }
public static Finite.NFAe HammingGraph(byte count) { var transform = new Finite.NFAeTransform(); for (uint v1 = 0; v1 < count; v1++) { for (uint v2 = 0; v2 < count; v2++) { if (Serpen.Uni.Utils.HammingDistance(v1, v2) == 1) { transform.AddM(v1, '1', v2); } } } var ret = new Finite.NFAe("Hamming-" + count, count, new char[] { '1' }, transform, 0, new uint[] {}); for (int v = 0; v < count; v++) { ret.States[v] = System.Convert.ToString(v, 2).PadLeft(Uni.Utils.Log2(count), '0'); } return(ret); }
public override IAutomat PurgeStates() { (uint[] translate, string[] names, uint[] aStates) = base.RemovedStateTranslateTables(); var newT = new NFAeTransform(); foreach (var t2 in Transforms) { if (translate.Contains(t2.Key.q)) { foreach (var v in t2.Value) { if (translate.Contains(v)) { newT.AddM(translate.ArrayIndex(t2.Key.q), t2.Key.c, translate.ArrayIndex(v)); } } } } return(new NFA($"{Name}_purged", names, Alphabet, newT, translate.ArrayIndex(StartState), aStates)); }
IAcceptWord JoinConcatUnion(IAcceptWord automat, JoinConcatUnionKind unionConcatJoinKind) { if (!(automat is FABase fa2)) { throw new System.NotSupportedException(); } uint offsetA1 = 0; // first state of A2 uint offsetA2 = this.StatesCount; // first state of A2 if (unionConcatJoinKind == JoinConcatUnionKind.Union) { offsetA1 = 1; offsetA2++; } char[] inputAlphabet = this.Alphabet.Union(fa2.Alphabet).ToArray(); var neaeT = new NFAeTransform(); uint startState; // Union: add new start state, with e to both starts if (unionConcatJoinKind == JoinConcatUnionKind.Union) { startState = 0; neaeT.Add(0, null, this.StartState + offsetA1); neaeT.AddM(0, null, fa2.StartState + offsetA2); } else { startState = this.StartState; } // add each A1 transform + offset of A1 foreach (var item in this.Transforms) { foreach (var val in item.Value) { neaeT.AddM(item.Key.q + offsetA1, item.Key.c, val + offsetA1); } } // add each A1 transform, + offset of A2 foreach (var item in fa2.Transforms) { foreach (var val in item.Value) { neaeT.AddM(item.Key.q + offsetA2, item.Key.c, val + offsetA2); } } uint[] accStates; if (unionConcatJoinKind == JoinConcatUnionKind.Concat) { // Concat: has only accepted states from A2 accStates = new uint[fa2.AcceptedStates.Length]; } else { // Join, Union has A1, A2 accpted states accStates = new uint[this.AcceptedStates.Length + fa2.AcceptedStates.Length]; } int i = 0; // store where D1 acc ends // iterate A1 acc for (; i < this.AcceptedStates.Length; i++) { if (unionConcatJoinKind == JoinConcatUnionKind.Concat) { // Concat: lead accepted states from A1 to A2 start neaeT.AddM(this.AcceptedStates[i] + offsetA1, null, fa2.StartState + offsetA2); } else { // Join, Union: states from A1 are normal accepted accStates[i] = this.AcceptedStates[i] + offsetA1; } } if (unionConcatJoinKind == JoinConcatUnionKind.Concat) { i = 0; } // iterate A2 acs and + offsetA2 for (int j = 0; j < fa2.AcceptedStates.Length; j++) { accStates[i + j] = (fa2.AcceptedStates[j] + offsetA2); } return(new NFAe($"NEAe{unionConcatJoinKind.ToString()}({Name}+{fa2.Name})", this.StatesCount + fa2.StatesCount + offsetA1, inputAlphabet, neaeT, startState, accStates)); }