123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- import subprocess
- try:
- import pydot
- has_pydot = True
- except ImportError:
- has_pydot = False
- class LoLADraw:
- def __init__(self):
- print("Starting LoLADraw...")
- print("Please ensure that GraphViz is installed before use.")
- def get_net(self, filename):
- places = []
- markings = {}
- transitions = {}
- place_mode = False
- marking_mode = False
- transition_mode = False
- trans_consume_mode = True
- trans_name = ""
- trans_consume = {}
- trans_produce = {}
- with open(filename) as f:
- for line in f:
- if "PLACE" in line:
- place_mode = True
- continue
- elif "MARKING" in line:
- place_mode = False
- marking_mode = True
- continue
- elif "TRANSITION" in line:
- marking_mode = False
- transition_mode = True
- line = line.strip()
- if not line:
- continue
- print(line)
- if place_mode:
- if "SAFE" in line:
- continue
- for place in line.split(','):
- place = place.replace(";", "").strip()
- if place:
- places.append(place)
- elif marking_mode:
- for marking in line.split(','):
- if not marking:
- continue
- m = marking.split(":")
- markings[m[0].strip()] = m[1].replace(";", "").strip()
- elif transition_mode:
- if "TRANSITION" in line:
- if trans_name:
- transitions[trans_name] = (trans_consume, trans_produce)
- trans_consume = {}
- trans_produce = {}
- trans_name = line.split(" ")[1]
- elif trans_consume_mode:
- if "CONSUME" in line:
- continue
- elif "PRODUCE" in line:
- trans_consume_mode = False
- else:
- for consume in line.split(","):
- if not consume:
- continue
- place, marking = consume.split(":")
- trans_consume[place.strip()] = marking.replace(";", "").strip()
- elif not trans_consume_mode:
- if ";" in line:
- trans_consume_mode = True
- for produce in line.split(","):
- if not produce:
- continue
- place, marking = produce.split(":")
- trans_produce[place.strip()] = marking.replace(";", "").strip()
- # do end-of-file
- if trans_name:
- transitions[trans_name] = (trans_consume, trans_produce)
- return places, markings, transitions
- def draw(self, filename):
- name = filename.replace(".lola", "")
- nodes = {}
- graph = pydot.Dot(name, graph_type='digraph', layout='neato')
- places, markings, transitions = self.get_net(filename)
- print("Places: " + str(places))
- print("Markings: " + str(markings))
- print("Transitions: " + str(transitions))
- for i, place in enumerate(places):
- v_attr = place
- if place in markings:
- v_attr += "\n" + markings[place]
- nodes[place] = pydot.Node(v_attr, style="filled", fillcolor='lightblue')
- graph.add_node(nodes[place])
- for t_name, _ in transitions.items():
- v_attr = t_name
- nodes[t_name] = pydot.Node(v_attr, style="filled")
- graph.add_node(nodes[t_name])
- for t_name, conpro in transitions.items():
- c, p = conpro
- for c_name, weight in c.items():
- graph.add_edge(pydot.Edge(nodes[c_name], nodes[t_name]))#, color=color))
- for p_name, weight in p.items():
- graph.add_edge(pydot.Edge(nodes[t_name], nodes[p_name], label=weight))
- # , color=color))
- dot_filename = filename.replace(".lola", ".dot")
- graph.write(dot_filename, prog='dot')
- command = "dot -Tsvg " + dot_filename + " -o " + filename.replace(".lola", ".svg")
- subprocess.call(command, shell=True)
- # command = "rm " + dot_filename
- # subprocess.call(command, shell=True)
- if __name__ == "__main__":
- if not has_pydot:
- print("ERROR: Install pydot first!")
- exit(1)
- filename = "dining_philo.lola"
- ld = LoLADraw()
- ld.draw(filename)
|