예제 #1
0
 //проверка на пустые переходы
 public static bool isENKA(eNKA nka)
 {
     if (nka.Function.Keys.Where(arg => arg.Char == "0"[0]).Count() > 0)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #2
0
        public static void print(string name, eNKA nka)
        {
            using (FileStream fs = new FileStream($"../../" + name + ".txt", FileMode.Create, FileAccess.Write))
            {
                TextWriter tw = new StreamWriter(fs);

                string temp = string.Empty;
                foreach (char ch in nka.InputChars)
                {
                    temp += ch + " ";
                }
                tw.WriteLine(temp);
                temp = string.Empty;

                foreach (string state in nka.States)
                {
                    temp += state + " ";
                }
                tw.WriteLine(temp);
                temp = string.Empty;

                foreach (string state in nka.firstStates)
                {
                    temp += state + " ";
                }
                tw.WriteLine(temp);
                temp = string.Empty;

                foreach (string state in nka.lastStates)
                {
                    temp += state + " ";
                }
                tw.WriteLine(temp);
                temp = string.Empty;

                foreach (Arg arg in nka.Function.Keys)
                {
                    temp = arg.State + " " + arg.Char + " ";
                    foreach (string str in nka.Function[arg])
                    {
                        temp += str + " ";
                    }
                    tw.WriteLine(temp);
                    temp = string.Empty;
                }
                tw.Flush();
                fs.Flush();
            }
        }
예제 #3
0
        //состояния в которые можно попасть из state используя сколько угодно пустых переходов
        public static List <string> StatesFromStateByEpsilon(string state, List <string> states, eNKA enka)
        {
            Arg arg = new Arg(state, "0"[0]);

            if (enka.Function.ContainsKey(arg))
            {
                states.AddRange(enka.Function[arg]);
                foreach (string st in enka.Function[arg])
                {
                    StatesFromStateByEpsilon(st, states, enka);
                }
            }
            return(states);
        }
예제 #4
0
        //детерминизируем автомат
        public static DKA toDKA(eNKA nka)
        {
            //проверили если есть пустые переходы, удаляем их
            if (isENKA(nka))
            {
                nka = deleteEps(nka);
            }

            //новые символы
            List <char> InputCharsDKA = nka.InputChars;

            //новые состояния
            List <List <string> > StatesDKA = new List <List <string> >();

            StatesDKA.Add(nka.firstStates);

            //начальное состояние
            List <string> firstState = nka.firstStates;

            //функция переходов, ключ - множество состояний и символ перехода, значение множество состояний в которое можно попасть
            Dictionary <ArgDKA, List <string> > FunctionDKA = new Dictionary <ArgDKA, List <string> >();

            Queue <List <string> > quStates = new Queue <List <string> >();

            quStates.Enqueue(firstState);
            while (quStates.Count != 0)
            {
                List <string> tempState = quStates.Dequeue();
                foreach (char inpchar in nka.InputChars)
                {
                    List <string> tempStates = new List <string>();

                    foreach (string st in tempState)
                    {
                        try
                        {
                            foreach (string str in nka.Function[nka.Function.Keys.First(arg => arg.State == st && arg.Char == inpchar)])
                            {
                                if (!tempStates.Contains(str))
                                {
                                    tempStates.Add(str);
                                }
                            }
                        }
                        catch (Exception) {  }
                    }

                    bool flag = true;
                    foreach (ArgDKA arg in FunctionDKA.Keys)
                    {
                        if (arg.State.SequenceEqual(tempState) && arg.Char == inpchar)
                        {
                            FunctionDKA[arg].Union(tempStates);
                            flag = false;
                        }
                    }
                    if (flag && tempState.Count > 0 && tempStates.Count > 0)
                    {
                        FunctionDKA.Add(new ArgDKA(tempState, inpchar), tempStates);
                    }
                    //if (flag) FunctionDKA.Add(new ArgDKA(tempState, inpchar), tempStates);
                    flag = true;
                    foreach (List <string> e in StatesDKA)
                    {
                        if (e.SequenceEqual(tempStates))
                        {
                            flag = false;
                        }
                    }
                    if (flag)
                    {
                        quStates.Enqueue(tempStates);
                        StatesDKA.Add(tempStates);
                    }
                }
            }

            DKA dka = new DKA();

            //переписали полученные символы
            dka.InputChars = nka.InputChars;
            //переписали начальное состояние
            foreach (string state in nka.firstStates)
            {
                dka.firstState += state;
            }
            //переписали символы
            dka.InputChars = InputCharsDKA;

            //переписали состояния
            foreach (List <string> states in StatesDKA)
            {
                string temp = string.Empty;
                foreach (string state in states)
                {
                    temp += state;
                }
                dka.States.Add(temp);
            }

            //переписали функции
            foreach (ArgDKA arg in FunctionDKA.Keys)
            {
                string statefrom = string.Empty;
                string stateto   = string.Empty;
                foreach (string state in arg.State)
                {
                    statefrom += state;
                }
                foreach (string state1 in FunctionDKA[arg])
                {
                    stateto += state1;
                }
                dka.Function.Add(new Arg(statefrom, arg.Char), stateto);
            }

            //переписали заключительные состояния
            foreach (List <string> state in StatesDKA)
            {
                bool   last      = false;
                string lastState = string.Empty;
                foreach (string _state in state)
                {
                    if (nka.lastStates.Contains(_state))
                    {
                        last = true;
                    }
                }
                if (last)
                {
                    foreach (string _state in state)
                    {
                        lastState += _state;
                    }
                }
                dka.lastStates.Add(lastState);
            }
            return(dka);
        }
예제 #5
0
        //удаляем пустые переходы
        public static eNKA deleteEps(eNKA enka)
        {
            //
            eNKA nka = new eNKA();

            nka.InputChars = enka.InputChars;
            //nka.States = enka.States;
            nka.firstStates = enka.firstStates;
            //nka.lastStates = enka.lastStates;

            //получаем состояния в которые можно перейти по пустому переходу
            List <string> stateFromEpsilon = new List <string>();

            foreach (Arg arg in enka.Function.Keys)
            {
                if (arg.Char == "0"[0])
                {
                    stateFromEpsilon.AddRange(enka.Function[arg]);
                }
            }
            //получаем состояния в которые можно перейти ТОЛЬКО по пустому переходу
            List <string> stateFromEpsilonOnly = new List <string>();

            foreach (string state in stateFromEpsilon)
            {
                bool flag = true;
                foreach (Arg arg in enka.Function.Keys)
                {
                    if (enka.Function[arg].Contains(state))
                    {
                        if (arg.Char != "0"[0])
                        {
                            flag = false;
                        }
                    }
                }
                if (flag)
                {
                    stateFromEpsilonOnly.Add(state);
                }
            }
            //1)новое множество состояний, без состояний в которые можно попасть только по пустому переходу
            //удалили из состояний такие состояния, и объединили с начальными состояниями(в случае если такое было удалено)
            nka.States = enka.States.Except(stateFromEpsilonOnly).Union(enka.firstStates).ToList();
            //

            //2)переносим все функции без пустных символов где исходящее состояние входит в множество новых состояний
            //(используем пересечение с состояниями нка во входящих состояниях, чтобы не добавить удаленное состояние)

            foreach (Arg arg in enka.Function.Keys)
            {
                if (arg.Char != "0"[0] && nka.States.Contains(arg.State))
                {
                    nka.Function.Add(arg, enka.Function[arg].Intersect(nka.States).ToList());
                }
            }

            //для тройки состояний p, q, r ищем путь из p в q ненулевой длины состоящий из пустых переходов, и путь длины 1 из q в r по не пустому символу, это будет новая функция
            foreach (string stateP in nka.States)
            {
                List <string> temp = new List <string>();
                //лист состояний в которые можно попасть из p используя сколько угодно пустых переходов
                List <string> statesFromPbyEpsilon = StatesFromStateByEpsilon(stateP, temp, enka);

                foreach (string stateQ in enka.States)
                {
                    foreach (string stateR in nka.States)
                    {
                        foreach (Arg arg in enka.Function.Keys.Where(state => state.State == stateQ && state.Char != "0"[0]))
                        {
                            if (enka.Function[arg].Contains(stateR))
                            {
                                //если есть путь по пустым в состояние q
                                if (statesFromPbyEpsilon.Contains(stateQ))
                                {
                                    Arg arg2 = new Arg(stateP, arg.Char);
                                    if (nka.Function.ContainsKey(arg2))
                                    {
                                        if (!nka.Function[arg2].Contains(stateR))
                                        {
                                            nka.Function[arg2].Add(stateR);
                                        }
                                    }
                                    else
                                    {
                                        List <string> st = new List <string>();
                                        st.Add(stateR);
                                        nka.Function.Add(arg2, st);
                                    }
                                }
                            }
                        }
                    }
                }
                temp.Clear();
            }


            //3)если из неконечного состояния по пустым переходам можно попасть в конечное, то делаем его конечным состоянием
            foreach (string state in nka.States)
            {
                List <string> temp = new List <string>();
                if (StatesFromStateByEpsilon(state, temp, enka).Intersect(enka.lastStates).ToList().Count > 0)
                {
                    nka.lastStates.Add(state);
                }
            }
            //оставшиеся заключительные состояния которые не удалились после пунка 1 так же переносятся
            nka.lastStates.AddRange(enka.lastStates.Intersect(nka.States));
            eNKA.print("noEps", nka);
            return(nka);
        }