//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); }
//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); }
//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); }
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); }
// 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); }
//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); }
// 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); }