예제 #1
0
        public override IAcceptWord Join(IJoin A) {
            if (!(A is DFA D2))
                throw new NotSupportedException();

            if (!this.SameAlphabet(D2))
                throw new NotImplementedException("Different Alphabets are not implemented");

            var deat = new DFATransform();

            var accStates = new List<uint>(this.AcceptedStates.Length + D2.AcceptedStates.Length);
            uint sc = this.StatesCount;

            foreach (var t in (DFATransform)Transforms)
                deat.Add(t.Key.q, t.Key.c.Value, t.Value[0]);
            foreach (var t in (DFATransform)D2.Transforms)
                deat.Add(t.Key.q + sc, t.Key.c.Value, t.Value[0] + sc);

            accStates.AddRange(this.AcceptedStates);
            for (int i = 0; i < D2.AcceptedStates.Length; i++)
                accStates.Add(D2.AcceptedStates[i] + sc);

            accStates.Sort();

            return new DFA($"DFA_Join({Name}+{A.Name})", (D2.StatesCount + sc), this.Alphabet, deat, this.StartState, accStates.ToArray());
        }
예제 #2
0
        /// <summary>
        /// Minimize DFA with TableFillingAlg
        /// </summary>
        /// <returns></returns>
        public DFA Minimize() {
            var tfEqClasses = TableFillingAlgEqClasses(this); // half matrix TF
            var State2eqClass = new uint[this.StatesCount];

            // Fill state to eqClass matching
            for (uint i = 0; i < tfEqClasses.Length; i++)
                for (int j = 0; j < tfEqClasses[i].Length; j++)
                    State2eqClass[tfEqClasses[i][j]] = i;

            // generate Transform, and modify to eqclasses
            var deaT = new DFATransform();
            foreach (var item in Transforms) {
                // q,qnext EqClass
                uint tSrcEqClass = State2eqClass[item.Key.q];
                uint tDstEqClass = State2eqClass[item.Value[0]];

                deaT.TryAdd(tSrcEqClass, item.Key.c.Value, tDstEqClass);
            }

            // add eqClasses of accepted states 
            var acc = new List<uint>(AcceptedStates.Length);
            for (uint i = 0; i < AcceptedStates.Length; i++)
                acc.Add(State2eqClass[AcceptedStates[i]]);

            acc.Sort();

            // give each onging state its eqClass states[] as name 
            string[] names = new string[tfEqClasses.Length];
            for (uint i = 0; i < tfEqClasses.Length; i++)
                names[i] = string.Join(',', tfEqClasses[i]);

            return new DFA($"DFA_Minimized({Name})", names, this.Alphabet, deaT, State2eqClass[this.StartState], acc.Distinct().ToArray());
        }
예제 #3
0
        public override IAutomat PurgeStates() {

            (uint[] translate, string[] names, uint[] aStates) = base.RemovedStateTranslateTables();

            var newT = new DFATransform();
            foreach (var t2 in Transforms)
                if (translate.Contains(t2.Key.q))
                    foreach (var v in t2.Value)
                        if (translate.Contains(v))
                            newT.Add(translate.ArrayIndex(t2.Key.q), t2.Key.c.Value, translate.ArrayIndex(v));

            return new DFA($"{Name}_purged", names, Alphabet, newT, translate.ArrayIndex(StartState), aStates);
        }
예제 #4
0
        } // end StatesEqual

        #region "Operations"

        public override IAutomat HomomorphismChar(Dictionary<char, char> Translate) {
            var deat = new DFATransform();
            var Alp = (char[])this.Alphabet.Clone();

            foreach (var dt in (DFATransform)Transforms)
                if (Translate.ContainsKey(dt.Key.c.Value))
                    deat.Add(dt.Key.q, Translate[dt.Key.c.Value], dt.Value[0]);
                else
                    deat.Add(dt.Key.q, dt.Key.c.Value, dt.Value[0]);

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

            return new DFA($"DFA_HomomorphismChar({Name})", this.StatesCount, Alp, deat, this.StartState, this.AcceptedStates);
        }
예제 #5
0
        public static DFA GenerateRandom() {
            const byte MAX_STATES = 20;
            const byte MAX_CHAR = 7;

            var rnd = Uni.Utils.RND;

            int stateCount = rnd.Next(1, MAX_STATES);

            char[] alphabet = RandomGenerator.RandomAlphabet(1, MAX_CHAR);
            uint[] accState = RandomGenerator.RandomAcceptedStates(1, stateCount / 3, stateCount);


            var t = new DFATransform();
            for (uint i = 0; i < stateCount; i++) {
                char[] rndAlph = alphabet.Randomize();
                for (int j = 0; j < rndAlph.Length; j++)
                    t.Add(i, alphabet[j], (uint)rnd.Next(0, stateCount));
            }

            var ret = new DFA("DFA_Random", (uint)stateCount, alphabet, t, (uint)rnd.Next(0, stateCount), accState);
            ret.Name = $"DFA_Random_q{stateCount}_a{alphabet.Length}_{ret.GetHashCode()}";
            return ret;
        }
예제 #6
0
        public static DFA ProductDea(DFA D1, DFA D2, eProductDeaMode mode) {

            uint len = (D1.StatesCount * D2.StatesCount);

            char[] newAlphabet = D1.Alphabet.Union(D2.Alphabet).ToArray();
            // if (!D1.SameAlphabet(D2))
            //     throw new NotImplementedException("Different Alphabets are not implemented");

            var accStates = new List<uint>(D1.AcceptedStates.Length + D2.AcceptedStates.Length);

            string[] stateNames = new string[len];

            var deat = new DFATransform();

            // iterate Cross D1xD2, chars
            for (uint i = 0; i < D1.StatesCount; i++) {
                for (uint j = 0; j < D2.StatesCount; j++) {
                    // index of state in matrix
                    uint index = (i * D2.StatesCount + j);
                    stateNames[index] = $"{i},{j}";

                    foreach (char c in newAlphabet) {
                        // Transform exists, out qNext
                        bool exist1 = ((DFATransform)D1.Transforms).TryGetValue(i, c, out uint qNext1);
                        bool exist2 = ((DFATransform)D2.Transforms).TryGetValue(j, c, out uint qNext2);

                        // same calc logic for dstIndex in Matrix
                        uint dstIndex;
                        if (exist1 & exist2)
                            dstIndex = (qNext1 * D2.StatesCount + qNext2);
                        else if (exist1)
                            dstIndex = (qNext1 * D2.StatesCount + qNext1);
                        else if (exist2)
                            dstIndex = qNext2;
                        else
                            throw new ApplicationException();

                        // add non existing tuple
                        if (!deat.ContainsKey(index, c)) // & exist1 & exist2)
                            deat.Add(index, c, dstIndex);
                        else
                            throw new ApplicationException();

                        if (mode == eProductDeaMode.Intersect) {
                            // add to accStates if both dea state ist acc
                            if (D1.IsAcceptedState(i) & D2.IsAcceptedState(j))
                                accStates.Add(index);
                        } else if (mode == eProductDeaMode.Union) {
                            // add to accStates if one dea state ist acc
                            if (D1.IsAcceptedState(i) | D2.IsAcceptedState(j))
                                accStates.Add(index);
                        } else if (mode == eProductDeaMode.Diff) {
                            // add to accStates if first and not second accepted
                            if (D1.IsAcceptedState(i) & !D2.IsAcceptedState(j))
                                accStates.Add(index);
                        }
                    }
                }
            }

            return new DFA($"DEA_Product{mode}({D1.Name}+{D2.Name})", stateNames, newAlphabet, deat, 0, accStates.Distinct().ToArray());
        }
예제 #7
0
 public DFA(string name, string[] states, char[] alphabet, DFATransform transform, uint startState, params uint[] acceptedStates)
     : base(name, states, alphabet, transform, startState, acceptedStates) {
 }