LoLADraw.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import subprocess
  2. try:
  3. import pydot
  4. has_pydot = True
  5. except ImportError:
  6. has_pydot = False
  7. class LoLADraw:
  8. def __init__(self):
  9. print("Starting LoLADraw...")
  10. print("Please ensure that GraphViz is installed before use.")
  11. def get_net(self, filename):
  12. places = []
  13. markings = {}
  14. transitions = {}
  15. place_mode = False
  16. marking_mode = False
  17. transition_mode = False
  18. trans_consume_mode = True
  19. trans_name = ""
  20. trans_consume = {}
  21. trans_produce = {}
  22. with open(filename) as f:
  23. for line in f:
  24. if "PLACE" in line:
  25. place_mode = True
  26. continue
  27. elif "MARKING" in line:
  28. place_mode = False
  29. marking_mode = True
  30. continue
  31. elif "TRANSITION" in line:
  32. marking_mode = False
  33. transition_mode = True
  34. line = line.strip()
  35. if not line:
  36. continue
  37. print(line)
  38. if place_mode:
  39. if "SAFE" in line:
  40. continue
  41. for place in line.split(','):
  42. place = place.replace(";", "").strip()
  43. if place:
  44. places.append(place)
  45. elif marking_mode:
  46. for marking in line.split(','):
  47. if not marking:
  48. continue
  49. m = marking.split(":")
  50. markings[m[0].strip()] = m[1].replace(";", "").strip()
  51. elif transition_mode:
  52. if "TRANSITION" in line:
  53. if trans_name:
  54. transitions[trans_name] = (trans_consume, trans_produce)
  55. trans_consume = {}
  56. trans_produce = {}
  57. trans_name = line.split(" ")[1]
  58. elif trans_consume_mode:
  59. if "CONSUME" in line:
  60. continue
  61. elif "PRODUCE" in line:
  62. trans_consume_mode = False
  63. else:
  64. for consume in line.split(","):
  65. if not consume:
  66. continue
  67. place, marking = consume.split(":")
  68. trans_consume[place.strip()] = marking.replace(";", "").strip()
  69. elif not trans_consume_mode:
  70. if ";" in line:
  71. trans_consume_mode = True
  72. for produce in line.split(","):
  73. if not produce:
  74. continue
  75. place, marking = produce.split(":")
  76. trans_produce[place.strip()] = marking.replace(";", "").strip()
  77. # do end-of-file
  78. if trans_name:
  79. transitions[trans_name] = (trans_consume, trans_produce)
  80. return places, markings, transitions
  81. def draw(self, filename):
  82. name = filename.replace(".lola", "")
  83. nodes = {}
  84. graph = pydot.Dot(name, graph_type='digraph', layout='neato')
  85. places, markings, transitions = self.get_net(filename)
  86. print("Places: " + str(places))
  87. print("Markings: " + str(markings))
  88. print("Transitions: " + str(transitions))
  89. for i, place in enumerate(places):
  90. v_attr = place
  91. if place in markings:
  92. v_attr += "\n" + markings[place]
  93. nodes[place] = pydot.Node(v_attr, style="filled", fillcolor='lightblue')
  94. graph.add_node(nodes[place])
  95. for t_name, _ in transitions.items():
  96. v_attr = t_name
  97. nodes[t_name] = pydot.Node(v_attr, style="filled")
  98. graph.add_node(nodes[t_name])
  99. for t_name, conpro in transitions.items():
  100. c, p = conpro
  101. for c_name, weight in c.items():
  102. graph.add_edge(pydot.Edge(nodes[c_name], nodes[t_name]))#, color=color))
  103. for p_name, weight in p.items():
  104. graph.add_edge(pydot.Edge(nodes[t_name], nodes[p_name], label=weight))
  105. # , color=color))
  106. dot_filename = filename.replace(".lola", ".dot")
  107. graph.write(dot_filename, prog='dot')
  108. command = "dot -Tsvg " + dot_filename + " -o " + filename.replace(".lola", ".svg")
  109. subprocess.call(command, shell=True)
  110. # command = "rm " + dot_filename
  111. # subprocess.call(command, shell=True)
  112. if __name__ == "__main__":
  113. if not has_pydot:
  114. print("ERROR: Install pydot first!")
  115. exit(1)
  116. filename = "dining_philo.lola"
  117. ld = LoLADraw()
  118. ld.draw(filename)