def uniao(automato_A: AutomatoFinito, automato_B: AutomatoFinito):
    # INICIALIZACAO DAS NOVAS TRANSICOES E ESTADOS DE ACEITACAO
    novas_transicoes = {}
    novos_estados_de_aceitacao = []
    qtd_estados_A = len(automato_A.estados)
    qtd_estado_B = len(automato_B.estados)
    novos_estados = ajustar_estados_novos(qtd_estados_A, qtd_estado_B)

    # PREPARANDO O NOVO ESTADO INICIAL
    novo_estado_inicial = 'q0'
    novas_transicoes[novo_estado_inicial] = ['V'] * len(automato_A.alfabeto)
    estado_inicial_A = novos_estados[0]
    estado_inicial_B = novos_estados[len(automato_A.estados)]
    transicao_novo_estado_inicial = estado_inicial_A + ',' + estado_inicial_B
    novas_transicoes[novo_estado_inicial].append(transicao_novo_estado_inicial)

    # INICIALIZANDO AS TRANSICOES COM OS ESTADOS NOVOS
    for estado in novos_estados:
        novas_transicoes[estado] = []

    pegando_transicoes(automato_A, novas_transicoes, novos_estados, 0,
                       novos_estados_de_aceitacao)
    pegando_transicoes(automato_B, novas_transicoes, novos_estados,
                       qtd_estados_A, novos_estados_de_aceitacao)
    verificar_transicoes_por_e(automato_A, novas_transicoes, novos_estados, 0)
    verificar_transicoes_por_e(automato_B, novas_transicoes, novos_estados,
                               qtd_estados_A)

    novos_estados.insert(0, novo_estado_inicial)
    novo_automato = AutomatoFinito(novos_estados, automato_A.alfabeto,
                                   novas_transicoes, novo_estado_inicial,
                                   novos_estados_de_aceitacao)

    return novo_automato
def er_para_afd(er: ExpressaoRegular):
    followpos = {i: set() for i in er.indexes}

    followpos = make_followpos(er.root, followpos)

    estado_inicial = str(er.root.firstpos)
    estados_de_aceitacao = []
    d_states_unmarked = [er.root.firstpos]
    d_states_marked = []
    d_tran = []
    while d_states_unmarked:
        S = d_states_unmarked.pop(0)
        d_states_marked.append(S)
        for a in er.alfabeto:
            U = set()
            for p in S:
                if er.correspondentes[p] == a:
                    fp = followpos[p]
                    U = U.union(fp)

            if U and U not in d_states_marked and U not in d_states_marked:
                d_states_unmarked.append(U)

            n = {'state': S, 'symbol': a, 'next': U}
            if U and n not in d_tran:
                if max(er.indexes) in n['state'] and str(
                        n['state']) not in estados_de_aceitacao:
                    estados_de_aceitacao.append(str(n['state']))
                d_tran.append(n)

    transicoes = {}
    for t in d_tran:
        if str(t['state']) not in transicoes.keys():
            transicoes[str(t['state'])] = {}
        transicoes[str(t['state'])][str(t['symbol'])] = str(t['next'])

    alfabeto = er.alfabeto

    novas_transicoes = {}
    for k in transicoes.keys():
        t = transicoes[k]
        n_t = []
        for a in alfabeto:
            if a in t.keys():
                n_t.append(t[a])
            else:
                n_t.append('V')

        novas_transicoes[k] = n_t

    return AutomatoFinito(estados=novas_transicoes.keys(),
                          alfabeto=alfabeto,
                          estado_inicial=estado_inicial,
                          estados_aceitacao=estados_de_aceitacao,
                          transicoes=novas_transicoes)
def remover_mortos(automato: AutomatoFinito):
    # vivos = automato.estados_aceitacao
    vivos = []
    vivos.extend(automato.estados_aceitacao)
    while (True):
        mudanca = False
        for estado in automato.estados:
            novos_vivos = []
            transicao = automato.transicoes[estado]
            for estado_transicao in transicao:
                if (estado_transicao in vivos) and (estado not in vivos) and (
                        estado not in novos_vivos):
                    # UMA MUDANCA OCORREU, LOGO PRECISO AVALIAR NOVAMENTE OS ESTADOS
                    # QUE JA TINHA AVALIADO
                    mudanca = True
                    novos_vivos.append(estado)
            vivos.extend(novos_vivos)
        if not mudanca:
            break
    automato.estados = intersecao_listas(automato.estados, vivos)
    automato.transicoes = pegar_novas_transicoes(automato.transicoes, vivos)
예제 #4
0
def gr_para_af(gr: GramaticaRegular):
    # Estados
    K = gr.nao_terminais
    novo_simbolo_nao_terminal = 'Z'
    K.append(novo_simbolo_nao_terminal)
    # Alfabeto
    alfabeto = gr.terminais

    # Estado inicial
    q0 = gr.simbolo_inicial

    # Estados de aceitação
    F = [novo_simbolo_nao_terminal]
    for nt, p in gr.producoes.items():
        if nt == gr.simbolo_inicial and '&' in p:
            F.append(nt)
            break

    # Transições
    trans = dict()
    for simb, prods in gr.producoes.items():
        for prod in prods:
            terminal, nao_terminal, e = pegar_simbolos(prod,
                                                       gr.terminais,
                                                       gr.nao_terminais)
            if e:
                continue

            if (simb, terminal) not in trans.keys():
                trans[(simb, terminal)] = []

            if nao_terminal is None:
                trans[(simb, terminal)].append(novo_simbolo_nao_terminal)

            if nao_terminal is not None and terminal is not None:
                trans[(simb, terminal)].append(nao_terminal)

    for nt in gr.nao_terminais:
        for t in gr.terminais:
            if (nt, t) not in trans.keys():
                trans[(nt, t)] = ['V']

    transicoes = []
    for nt in gr.nao_terminais:
        nexts = []
        for t in gr.terminais:
            for comb, dest in trans.items():
                if comb[0] == nt and comb[1] == t:
                    nexts.append(','.join(dest))

        transicoes.append(' '.join(nexts))

    return AutomatoFinito(K, alfabeto, transicoes, q0, F)
def remover_inalcancaveis(automato: AutomatoFinito):
    alcancaveis = [automato.estado_inicial]
    while (True):
        mudanca = False
        for estado in alcancaveis:
            novos_alcancaveis = []
            transicao = automato.transicoes[estado]
            for estado_transicao in transicao:
                if (estado_transicao
                        not in alcancaveis) and (estado_transicao
                                                 not in novos_alcancaveis):
                    # UMA MUDANCA OCORREU, LOGO PRECISO AVALIAR NOVAMENTE OS ESTADOS
                    # QUE JA TINHA AVALIADO
                    mudanca = True
                    novos_alcancaveis.append(estado_transicao)
            alcancaveis.extend(novos_alcancaveis)
        if not mudanca:
            break
    automato.estados = intersecao_listas(automato.estados, alcancaveis)
    automato.estados_aceitacao = intersecao_listas(automato.estados_aceitacao,
                                                   alcancaveis)
    automato.transicoes = pegar_novas_transicoes(automato.transicoes,
                                                 alcancaveis)
예제 #6
0
    def ler_automato(self, texto):
        estados = self.pegar_estados(texto)
        alfabeto = self.pegar_alfabeto(texto)
        transicoes = self.pegar_transicoes(texto)
        estado_inicial = self.pegar_estado_inicial(texto)
        estados_aceitacao = self.pegar_estados_aceitacao(texto)

        automato = AutomatoFinito(estados, alfabeto, transicoes, estado_inicial, estados_aceitacao)

        # ========================== DEBUG
        # if DEBUG:
        #     logger.debug(automato.alfabeto)
        #     logger.debug(automato.transicoes)
        #     logger.debug(automato.transicoes[len(automato.alfabeto)])
        # ========================== DEBUG

        return automato
def intersecao(automato_A: AutomatoFinito, automato_B: AutomatoFinito):
    automato_A.negar()
    automato_B.negar()
    return uniao(automato_A, automato_B)