Exemple #1
0
        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));
        }
Exemple #2
0
        public IAutomat KleeneStern()
        {
            var neaET = new NFAeTransform
            {
                { 0, null, this.StartState + 1 } // accepted front state
            };

            // add transforms, +1
            foreach (var item in this.Transforms)
            {
                uint[] qnext = new uint[item.Value.Length];
                for (int i = 0; i < item.Value.Length; i++)
                {
                    qnext[i] = item.Value[i] + 1;
                }
                neaET.Add(item.Key.q + 1, item.Key.c, qnext);
            }

            var acceptedStates = new uint[this.AcceptedStates.Length + 1];

            acceptedStates[0] = 0;
            // add e-transform from org accepted to front state
            for (uint i = 0; i < this.AcceptedStates.Length; i++)
            {
                acceptedStates[i + 1] = this.AcceptedStates[i] + 1; // a little redundant, because all accepted states must go back to first
                neaET.Add(this.AcceptedStates[i] + 1, null, 0);
            }

            return(new NFAe($"NFAe_KleeneStern({Name})", this.StatesCount + 1, this.Alphabet, neaET, 0, acceptedStates));
        }
Exemple #3
0
        public override IAutomat HomomorphismChar(Dictionary <char, char> translate)
        {
            var neat = new NFAeTransform();

            char[] Alp = this.Alphabet.Clone() as char[];

            foreach (var dt in this.Transforms)
            {
                if (translate.ContainsKey(dt.Key.c.Value))
                {
                    neat.Add(dt.Key.q, translate[dt.Key.c.Value], dt.Value);
                }
                else
                {
                    neat.Add(dt.Key.q, dt.Key.c.Value, dt.Value);
                }
            }

            for (int i = 0; i < this.Alphabet.Length; i++)
            {
                if (translate.ContainsKey(this.Alphabet[i]))
                {
                    Alp[i] = translate[this.Alphabet[i]];
                }
            }

            return(new NFA($"NFA_HomomorphismChar({Name})", StatesCount, Alp, neat, StartState, AcceptedStates));
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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));
        }
Exemple #7
0
 public NFAe(string name, string[] states, char[] alphabet, NFAeTransform transform, uint startState, params uint[] acceptedStates)
     : base(name, states, alphabet, transform, startState, acceptedStates) {
 }
Exemple #8
0
        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));
        }
Exemple #9
0
 public NFA(string name, uint StateCount, char[] Alphabet, NFAeTransform Transform, uint StartState, params uint[] acceptedStates)
     : base(name, StateCount, Alphabet, Transform, StartState, acceptedStates)
 {
 }