LoLAConvert.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import sys
  2. import xml.etree.ElementTree as ET
  3. class LoLAConvert:
  4. def __init__(self):
  5. # TODO:
  6. # - Add capacity
  7. # - Prevent inhibitors
  8. pass
  9. def convert_file(self, filename):
  10. places, transitions, arcs = self.parse_pnml(filename)
  11. print("Places: ")
  12. for p, v in places.items():
  13. print(str(p) + " : " + str(v))
  14. print("Transitions: ")
  15. for t, v in transitions.items():
  16. print(str(t) + ",")# + str(v))
  17. print("Arcs: ")
  18. for a in arcs:
  19. print(a)
  20. places_with_markings = []
  21. for p_id, p_data in places.items():
  22. p_name, marking = p_data
  23. if int(marking) > 0:
  24. places_with_markings.append((p_id, p_name, marking))
  25. lola_file = filename.replace(".xml", ".lola")
  26. with open(lola_file, 'w') as f:
  27. f.write("PLACE\n")
  28. for i, p_id in enumerate(places):
  29. p_name, marking = places[p_id]
  30. f.write("\t" + p_name)
  31. if i < len(places) - 1:
  32. f.write(",\n")
  33. else:
  34. f.write(";\n")
  35. f.write("\nMARKING\n")
  36. for i, pm in enumerate(places_with_markings):
  37. f.write("\t" + pm[1] + " : " + pm[2])
  38. if i < len(places_with_markings) - 1:
  39. f.write(",\n")
  40. else:
  41. f.write(";\n")
  42. for trans_id, trans_name in transitions.items():
  43. f.write("\nTRANSITION " + trans_name + "\n")
  44. consume = {}
  45. produce = {}
  46. for arc in arcs:
  47. s, t, w = arc
  48. if t == trans_id:
  49. consume[s] = w
  50. elif s == trans_id:
  51. produce[t] = w
  52. f.write("\tCONSUME\n")
  53. if len(consume) == 0:
  54. f.write(";\n")
  55. for i, s in enumerate(consume):
  56. f.write("\t\t" + places[s][0] + " : " + consume[s])
  57. if i < len(consume) - 1:
  58. f.write(",\n")
  59. else:
  60. f.write(";\n")
  61. f.write("\tPRODUCE\n")
  62. if len(produce) == 0:
  63. f.write(";\n")
  64. for i, t in enumerate(produce):
  65. f.write("\t\t" + places[t][0] + " : " + produce[t])
  66. if i < len(produce) - 1:
  67. f.write(",\n")
  68. else:
  69. f.write(";\n")
  70. print("Wrote to: " + str(lola_file))
  71. def parse_pnml(self, filename):
  72. tree = ET.parse(filename)
  73. root = tree.getroot()
  74. net = root[0]
  75. places = {}
  76. transitions = {}
  77. arcs = []
  78. for child in net:
  79. if child.tag == "place":
  80. p_id = child.get("id")
  81. name_node = self.get_child_with_name(child, "name")
  82. name = self.get_child_with_name(name_node, "value").text
  83. name = name.replace(" ", ".")
  84. marking_node = self.get_child_with_name(child, 'initialMarking')
  85. marking_value_node = self.get_child_with_name(marking_node, 'value')
  86. marking = marking_value_node.text.split(",")[1]
  87. places[p_id] = (name, marking)
  88. elif child.tag == "transition":
  89. t_id = child.get("id")
  90. name_node = self.get_child_with_name(child, "name")
  91. name = self.get_child_with_name(name_node, "value").text
  92. name = name.replace(" ", ".")
  93. transitions[t_id] = name
  94. elif child.tag == "arc":
  95. source = child.get("source")
  96. target = child.get("target")
  97. inscription_node = self.get_child_with_name(child, 'inscription')
  98. inscription_value_node = self.get_child_with_name(inscription_node, 'value')
  99. inscription = inscription_value_node.text.split(",")[1]
  100. arcs.append((source, target, inscription))
  101. return places, transitions, arcs
  102. def get_child_with_name(self, node, name):
  103. for child in node:
  104. if child.tag == name:
  105. return child
  106. raise Exception("On node: " + str(node) + ", the child " + name + " was not found!")
  107. if __name__ == "__main__":
  108. print("Starting LoLAConvert...")
  109. if len(sys.argv) < 2:
  110. print("Error: Please pass a filename as the first argument.")
  111. exit(1)
  112. filename = sys.argv[1]
  113. lc = LoLAConvert()
  114. lc.convert_file(filename)