예제 #1
0
        private bool elimEstMorto(ref Automato automato, ref Dictionary <string, bool> visitados, string estado)
        {
            bool ret = false;

            if (visitados.ContainsKey(estado))
            {
                visitados.TryGetValue(estado, out ret);
                return(ret);
            }
            else
            {
                visitados.Add(estado, automato.estadosFinais.Contains(estado));
                foreach (string s in automato.simbolos)
                {
                    Transicao t = automato.GetTransicao(estado, s);

                    foreach (string e2 in t.estado2)
                    {
                        if (elimEstMorto(ref automato, ref visitados, e2))
                        {
                            ret = true;
                        }
                    }
                }
            }
            visitados.Remove(estado);
            visitados.Add(estado, ret | automato.estadosFinais.Contains(estado));
            return(ret);
        }
예제 #2
0
        // Concatena 2 autômatos
        public Automato Interseccao(Automato a2)
        {
            Automato r = new Automato(ID * a2.ID, this);

            r.simbolos.UnionWith(a2.simbolos);
            r.estados.UnionWith(a2.estados);

            foreach (KeyValuePair <KeyTransicao, Transicao> tra in a2.transicoes)
            {
                r.addTransicao(tra.Value);
            }

            HashSet <string> temp = new HashSet <string>
            {
                a2.estadoInicial
            };

            foreach (string ef in r.estadosFinais)
            {
                r.addTransicao(ef, "&", temp);
            }

            r.estadosFinais.Clear();
            r.estadosFinais.UnionWith(a2.estadosFinais);

            return(r);
        }
예제 #3
0
        public static void Main(string[] args)
        {
            //string text = "+1234";
            //text = text.Replace("5", "");
            //Console.WriteLine(text);
            ExpressaoRegular exp  = new ExpressaoRegular("(a|b)*.(b|c).#");
            Automato         auto = exp.transformaERemAFD();

            Console.WriteLine("Execução OK!");

            //Automato automato = new Automato(1);
            //automato.addEstado("A");
            //automato.addEstado("B");
            //automato.addSimbolo("a");
            //automato.addTransicao("A", "a", "B");
            //foreach (var k in automato.transicoes.Keys)
            //{
            //    Console.WriteLine("k[0]={0}", k[0]);
            //    Console.WriteLine("k[1]={0}", k[1]);
            //}
            //var t = automato.GetTransicao("A", "a");
            //if (t.estado1 == "")
            //    Console.WriteLine("Estado Vazio");
            //if (t.simbolo == "")
            //    Console.WriteLine("Simbolo Vazio");
            //foreach (var e in t.estado2)
            //    Console.WriteLine("estado {0}", e);
        }
예제 #4
0
        //Gera os estados do Automato de acordo com a tabela posicao_seguinte no algoritmo Aho
        private Automato geraEstados(Automato automato, Stack <HashSet <int> > stack)
        {
            HashSet <int> estado1, estado2 = new HashSet <int>();

            while (stack.Count() > 0)
            {
                estado1 = stack.Pop();
                string nomeEstado1 = geraNomeDoEstado(estado1);
                estado2 = new HashSet <int>();
                foreach (var simbol in arvore.simbolos.ToList())
                {
                    estado2 = new HashSet <int>();
                    foreach (var i in estado1.ToList())
                    {
                        if ((string)arvore.folhas[i] == simbol)
                        {
                            if (arvore.posicao_seguinte.ContainsKey(i))
                            {
                                estado2.UnionWith((HashSet <int>)arvore.posicao_seguinte[i]);
                            }
                        }
                    }
                    if (estado2.Count > 0)
                    {
                        string nomeEstado2 = geraNomeDoEstado(estado2);

                        if (estado1.SetEquals(estado2))
                        {
                            automato.addTransicao(nomeEstado1, simbol, nomeEstado1);
                        }
                        else
                        {
                            bool contemTransacao = false;
                            var  t = automato.GetTransicao(nomeEstado1, simbol);
                            foreach (var e in t.estado2)
                            {
                                if (e == nomeEstado2)
                                {
                                    contemTransacao = true;
                                }
                            }
                            //foreach (var k in automato.transicoes.Keys)
                            //    if (k[0] == nomeEstado1 && k[1] == simbol)
                            //        contemTransacao = true;
                            if (!contemTransacao)
                            {
                                if (!automato.estados.Contains(nomeEstado2))
                                {
                                    stack.Push(estado2);
                                    automato.addEstado(nomeEstado2);
                                }
                                automato.addTransicao(nomeEstado1, simbol, nomeEstado2);
                                //estado2.Clear();
                            }
                        }
                    }
                }
            }
            return(automato);
        }
예제 #5
0
        // Construtor a partir de um outro Autômato
        public Automato(int id, Automato a) : this(id)
        {
            simbolos.UnionWith(a.simbolos);
            estados.UnionWith(a.estados);
            estadoInicial = a.estadoInicial;
            estadosFinais.UnionWith(a.estadosFinais);

            foreach (KeyValuePair <KeyTransicao, Transicao> t in a.transicoes)
            {
                transicoes.Add(t.Key, t.Value);
            }
        }
예제 #6
0
 //metodo para debugar o automato na caixa de saída.
 public void showAutomato(Automato automato)
 {
     System.Console.WriteLine("transicoes");
     foreach (KeyValuePair <KeyTransicao, Transicao> t in automato.transicoes)
     {
         foreach (string e in t.Value.estado2)
         {
             KeyTransicao k = t.Key;
             System.Console.WriteLine("{0}, {1} -> {2}", k.estado, k.simbolo, e);
             //showAutomato(a, e2);
         }
     }
 }
예제 #7
0
        //Metodo Elimina Estados Mortos.
        //Todo estado que não alcança un estado final é removido.

        public Automato eliminaEstadosMortos(Automato automato)
        {
            Dictionary <string, bool> t = new Dictionary <string, bool>();

            elimEstMorto(ref automato, ref t, automato.estadoInicial);
            List <KeyTransicao> lk = new List <KeyTransicao>();
            List <Transicao>    li = new List <Transicao>();

            foreach (KeyValuePair <string, bool> v in t)
            {
                if (v.Value == false)
                {
                    automato.estados.Remove(v.Key);
                    foreach (KeyValuePair <KeyTransicao, Transicao> tran in automato.transicoes)
                    {
                        if (tran.Key.estado == v.Key)
                        {
                            lk.Add(tran.Key);
                        }
                        if (tran.Value.estado2.Contains(v.Key))
                        {
                            Transicao temp = tran.Value;
                            temp.estado2.Remove(v.Key);
                            li.Add(temp);
                        }
                    }
                }
            }

            foreach (KeyTransicao l in lk)
            {
                automato.transicoes.Remove(l);
            }

            foreach (Transicao l in li)
            {
                KeyTransicao kt = new KeyTransicao
                {
                    estado  = l.estado1,
                    simbolo = l.simbolo
                };
                automato.transicoes.Remove(kt);
                if (l.estado2.Count > 0)
                {
                    automato.transicoes.Add(kt, l);
                }
            }

            return(automato);
        }
예제 #8
0
        //Função que cria o Automato a partir da tabela posicao_seguinte do algoritmo Aho
        private Automato montaAutomato()
        {
            Automato automato = new Automato(1);
            Stack <HashSet <int> > stackEstados = new Stack <HashSet <int> >();

            automato.simbolos = arvore.simbolos;
            automato.simbolos.Remove("#");
            HashSet <int> estadoRaiz = arvore.raiz.primeira_posicao;
            string        estado     = geraNomeDoEstado(estadoRaiz);

            stackEstados.Push(estadoRaiz);
            automato.addEstado("+" + estado);
            automato = geraEstados(automato, stackEstados);
            return(automato);
        }
예제 #9
0
        //Metodo Principal para a transformaçao.
        public Automato transformaERemAFD()
        {
            Automato a = new Automato(1);

            createTree();                           //Monta Arvore Sintatica
            readTree();                             //Marca Indicadores Folha e cria Pilha com Nodos Internos
            arvore.copyStack();                     //Duplica Pilha para os metodos seguintes
            arvore.calculaPrimeiraEUltimaPosicao(); //Preenche pri_pos, ult_pos e anulavel - esvazia pilha 1
            arvore.calculaTabelaPosicaoSeguinte();  // usa segunda pilha pra calcular posicao_seguinte
            showPosSeguinte();
            //fixPosSeguinteTable();
            a = montaAutomato();
            a.showAutomato(a);
            return(a);
        }
예제 #10
0
        //Minimização, invoca os tres passos da Minimização de AFD:
        //1-Elimina Estados Inalcancaveis
        //2-Elimina Estados Mortos
        //3-Elimina Estados Equivalentes
        public Automato Minimizacao(Automato automato, int ID)
        {
            Automato miniAuto = new Automato(ID)
            {
                estadoInicial = automato.estadoInicial,
                simbolos      = automato.simbolos,
                estadosFinais = automato.estadosFinais
            };

            miniAuto.addEstado(miniAuto.estadoInicial);
            miniAuto = eliminaEstadosInalcancaveis(automato, miniAuto, automato.estadoInicial);
            miniAuto = miniAuto.eliminaEstadosMortos(miniAuto);
            miniAuto = eliminaEstadosEquivalentes(miniAuto);

            return(miniAuto);
        }
예제 #11
0
 //Cria Transições para o novo Automato resultante das classes de equivalencia.
 private void criaTransicoes(HashSet <HashSet <string> > classes, Automato automato, Hashtable rel)
 {
     foreach (HashSet <string> classe in classes)
     {
         foreach (string e in classe)
         {
             foreach (string s in simbolos)
             {
                 foreach (string e2 in automato.GetTransicao(e, s).estado2)
                 {
                     string origem  = (string)rel[e];
                     string destino = (string)rel[e2];
                     addTransicao(origem, s, destino);
                 }
             }
             break;
         }
     }
 }
예제 #12
0
        // Função para gerar uma Gramática a partir de um autômato finito determinístico
        public Gramatica(Automato a)
        {
            foreach (string e in a.estados)
            {
                foreach (char s in e.ToCharArray())
                {
                    SimbolosNaoTerminais.Add(s);
                }
            }

            foreach (string s in a.simbolos)
            {
                foreach (char c in s.ToCharArray())
                {
                    SimbolosTerminais.Add(c);
                }
            }

            Inicial = a.estadoInicial.ToCharArray()[0];

            foreach (KeyValuePair <Automato.KeyTransicao, Automato.Transicao> trans in a.transicoes)
            {
                foreach (string tra in trans.Value.estado2)
                {
                    Regular temp;
                    temp.Atual    = trans.Value.estado1.ToArray()[0];
                    temp.Proximos = new List <string>();

                    if (a.estadosFinais.Contains(tra))
                    {
                        temp.Proximos.Add(trans.Key.simbolo);
                    }
                    else
                    {
                        temp.Proximos.Add(trans.Key.simbolo + tra);
                    }

                    AddProducao(temp);
                }
            }
        }
예제 #13
0
        public Automato eliminaEstadosInalcancaveis(Automato automato, Automato miniAuto, string estado)
        {
            foreach (string s in automato.simbolos)
            {
                HashSet <string> temp = automato.GetTransicao(estado, s).estado2;
                foreach (string e in temp)
                {
                    bool exists = miniAuto.estados.Contains(e);
                    if (!exists)
                    {
                        miniAuto.addEstado(e);
                    }

                    miniAuto.addTransicao(estado, s, e);
                    if (!exists /*&& !miniAuto.estadoInicial.Contains(e)*/)
                    {
                        eliminaEstadosInalcancaveis(automato, miniAuto, e);
                    }
                }
            }
            return(miniAuto);
        }
예제 #14
0
        // Faz a união de 2 autômatos
        public Automato Uniao(Automato a2)
        {
            Automato r = new Automato(ID * a2.ID, this);

            r.estadosFinais.UnionWith(a2.estadosFinais);
            r.simbolos.UnionWith(a2.simbolos);
            r.simbolos.Add("&");

            foreach (KeyValuePair <KeyTransicao, Transicao> tra in a2.transicoes)
            {
                r.addTransicao(tra.Value);
            }

            r.addEstado("+Uniao");
            HashSet <string> temp = new HashSet <string>
            {
                a2.estadoInicial,
                estadoInicial
            };

            r.addTransicao("+Uniao", "&", temp);
            return(r);
        }
예제 #15
0
        //Metodo Elimina Estados Equivalentes.
        public Automato eliminaEstadosEquivalentes(Automato automato)
        {
            // System.Collections.Hashtable passos = new System.Collections.Hashtable();
            HashSet <HashSet <string> > classes      = new HashSet <HashSet <string> >();
            HashSet <HashSet <string> > classesNovas = new HashSet <HashSet <string> >();

            classes.Add(automato.estadosFinais);
            HashSet <string> notFinals = new HashSet <string>(automato.estados);

            notFinals.SymmetricExceptWith(automato.estadosFinais);
            classes.Add(notFinals);
            bool novoPasso = true;

            while (novoPasso)
            {
                foreach (string e in automato.estados)
                {
                    alocaEstadoEmClasseNova(e, classesNovas, classes);
                }
                if (classes.Count == classesNovas.Count)
                {
                    novoPasso = false;
                }
                else
                {
                    novoPasso = true;
                }

                classes = new HashSet <HashSet <string> >(classesNovas);
                classesNovas.Clear();
            }

            //debug
            Console.WriteLine("classes");
            foreach (HashSet <string> c in classes)
            {
                Console.Write("{");
                foreach (string e in c)
                {
                    Console.Write(e);
                }
                Console.Write("}");
                Console.WriteLine(".");
            }
            Automato newAuto = new Automato(5)
            {
                simbolos = automato.simbolos
            };
            Hashtable relEstadoClasse = new Hashtable();

            foreach (HashSet <string> c in classes)
            {
                string nomeEstado = "";
                foreach (string e in c)
                {
                    nomeEstado = nomeEstado + e;
                }
                foreach (string est in c)
                {
                    relEstadoClasse.Add(est, nomeEstado);
                }
                foreach (string f in estadosFinais)
                {
                    if (c.Contains(f))
                    {
                        nomeEstado = "*" + nomeEstado;
                        break;
                    }
                }

                if (c.Contains(automato.estadoInicial))
                {
                    nomeEstado = "+" + nomeEstado;
                }

                newAuto.addEstado(nomeEstado);
            }
            newAuto.criaTransicoes(classes, automato, relEstadoClasse);
            return(newAuto);
        }
예제 #16
0
        public Automato getAutomato()
        {
            Automato novo = new Automato(automato);

            return(novo);
        }
예제 #17
0
        // Gera um autômato a partir dessa Gramática
        public Automato GetAutomato()
        {
            Automato ret  = new Automato();
            Random   rand = new Random();

            string novo = rand.Next(100).ToString();

            foreach (char NT in SimbolosNaoTerminais)
            {
                ret.addEstado(NT.ToString());
            }
            ret.addEstado(novo);

            ret.estadoInicial = Inicial.ToString();

            foreach (char T in SimbolosTerminais)
            {
                ret.simbolos.Add(T.ToString());
            }

            ret.estadosFinais.Add(novo);



            foreach (KeyValuePair <char, Regular> Pr in Producoes)
            {
                foreach (string P in Pr.Value.Proximos)
                {
                    string nt = "";
                    string t  = "";

                    foreach (char NT in SimbolosNaoTerminais)
                    {
                        if (P.Contains(NT))
                        {
                            nt += NT;
                        }
                    }
                    foreach (char T in SimbolosTerminais)
                    {
                        if (P.Contains(T))
                        {
                            t += T;
                        }
                    }

                    if (nt.Length != 0 && t.Length != 0)
                    {
                        foreach (char c in t)
                        {
                            ret.addTransicao(Pr.Key.ToString(), c.ToString(), nt);
                        }
                    }
                    else if (nt.Length == 0)
                    {
                        foreach (char c in t)
                        {
                            ret.addTransicao(Pr.Key.ToString(), c.ToString(), novo);
                        }
                    }
                }
            }

            return(ret);
        }