A continuación presento una función que nos permitirá visulizar un autómata de estado finito (FSM) con python. Espero que les sea útil para sus trabajos. Requiere python3 y la librería graphviz. Primero mostraré un FSM que genera y posteriormente le código fuente.

 

Para diagramar el FSM se necesita agregar un alfabeto con el cuál trabajar. Este alfabeto es una lista de símbolos que serán usados para las transicione entre los estados. También será necesario definir una lista de estados que se utilizarán, donde los estados son cadenas de caracteres. Tamién es necesario agrear una lista de 3-tuplas, done se se especificará primero el estado de salida, el de llegada y el símbolo del alfabeto que realizará la transición de un estado a otro. Esto se verá así: [("A","B", 1),("A","E",0),]. Finalmente debemos especificar los estado de salida y de de finalización. Estos deben de ser mayores que 0. 

Un ejemplo de cómo llamar a la función de graficación se presenta en el apartado main del código. Espero esto sirva para facilitar sus diagramas. 

 

# -*- coding:utf-8 -*-
# Author: Jesús Mager
# GPL v.3+
# 2015

import graphviz as gv

# Todos los parámetros son listas o tuplas
# donde:
#  * alfabeto:  es el alfabeto aceptado por el 
#               autómata.
#  * estados:   es una lista de estados aceptados
#               por el autómata.
#  * inicio:    Son los estados de inicio del fsm.
#  * trans:     Es una tupla de funciones de transición
#               con tres elementos que son: (a,b,c) donde
#               (a,b) son los estados de partida y llegada;
#               mientras que c es la letra que acepta.
#  * final      Son los estados finales del autómata.

def draw(alfabeto, estados, inicio, trans, final):
    print("inicio:", str(inicio))
    g = gv.Digraph(format='svg')
    g.graph_attr['rankdir'] = 'LR'
    g.node('ini', shape="point")
    for e in estados:
        if e in final:
            g.node(e, shape="doublecircle")
        else:
            g.node(e)
        if e in inicio:
            g.edge('ini',e)

    for t in trans:
        if t[2] not in alfabeto:
            return 0
        g.edge(t[0], t[1], label=str(t[2]))
    g.render(view=True)

# Ejemplo de uso

if __name__ == '__main__':
    estados = ["A","B","C","E","F"]
    trans = [("A","B", 1),("A","E",0),("A","E",1),("A","A",1),("A","D",1),("F","F",1),("D","C",1),("B","A",0), ("E","C",0),("F","D",0), ("C","A",0), ("B","B", 1)]
    inicial = ["A"]
    alf = [0,1]
    terminal = ("C",)

    draw(alf, estados, inicial, trans, terminal)

 

Share This