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); }
// 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); }
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); }
//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); }
// 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); } }
//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); } } }
//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); }
//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); }
//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); }
//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); }
//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; } } }
// 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); } } }
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); }
public Automato getAutomato() { Automato novo = new Automato(automato); return(novo); }
// 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); }