pn_semantics.alc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. include "primitives.alh"
  2. include "modelling.alh"
  3. include "object_operations.alh"
  4. include "library.alh"
  5. include "conformance_scd.alh"
  6. Void function petrinet_enabled(model : Element):
  7. Element set_enabled
  8. set_enabled = petrinet_enabled_set(model)
  9. output("Enabled transitions:")
  10. while (0 < read_nr_out(set_enabled)):
  11. output(set_pop(set_enabled))
  12. return!
  13. Element function petrinet_enabled_set(model : Element):
  14. Element all_transitions
  15. Element enabled_transitions
  16. String under_study
  17. Element in_arcs
  18. String arc_under_study
  19. Boolean enabled
  20. all_transitions = allInstances(model, "Transition")
  21. enabled_transitions = create_node()
  22. while (0 < read_nr_out(all_transitions)):
  23. under_study = set_pop(all_transitions)
  24. enabled = True
  25. // Find all incoming transitions
  26. in_arcs = allIncomingAssociationInstances(model, under_study, "P2T")
  27. while (0 < read_nr_out(in_arcs)):
  28. arc_under_study = set_pop(in_arcs)
  29. Integer present_tokens
  30. Integer required_tokens
  31. required_tokens = read_attribute(model, arc_under_study, "weight")
  32. log("Weight: " + cast_i2s(required_tokens))
  33. present_tokens = read_attribute(model, reverseKeyLookup(model["model"], read_edge_src(model["model"][arc_under_study])), "tokens")
  34. log("Tokens: " + cast_i2s(present_tokens))
  35. if (present_tokens < required_tokens):
  36. // Less tokens than required, so disable the transition completely
  37. enabled = False
  38. if (enabled):
  39. set_add(enabled_transitions, under_study)
  40. log("Got all enabled transitions!")
  41. return enabled_transitions!
  42. Void function petrinet_fire(model : Element):
  43. output("Transition to fire?")
  44. String transition
  45. transition = input()
  46. if (dict_in(model["model"], transition)):
  47. if (set_in(petrinet_enabled_set(model), transition)):
  48. Element workset
  49. String working_place
  50. String working_arc
  51. Integer new_value
  52. // Consume tokens
  53. workset = allIncomingAssociationInstances(model, transition, "P2T")
  54. while (0 < read_nr_out(workset)):
  55. working_arc = set_pop(workset)
  56. working_place = reverseKeyLookup(model["model"], read_edge_src(model["model"][working_arc]))
  57. new_value = integer_subtraction(read_attribute(model, working_place, "tokens"), read_attribute(model, working_arc, "weight"))
  58. unset_attribute(model, working_place, "tokens")
  59. instantiate_attribute(model, working_place, "tokens", new_value)
  60. output(((" " + working_place) + ": ") + cast_i2s(read_attribute(model, working_place, "tokens")))
  61. // Add tokens
  62. workset = allOutgoingAssociationInstances(model, transition, "T2P")
  63. while (0 < read_nr_out(workset)):
  64. working_arc = set_pop(workset)
  65. working_place = reverseKeyLookup(model["model"], read_edge_dst(model["model"][working_arc]))
  66. new_value = integer_addition(read_attribute(model, working_place, "tokens"), read_attribute(model, working_arc, "weight"))
  67. unset_attribute(model, working_place, "tokens")
  68. instantiate_attribute(model, working_place, "tokens", new_value)
  69. output(((" " + working_place) + ": ") + cast_i2s(read_attribute(model, working_place, "tokens")))
  70. output("Transition fired!")
  71. else:
  72. output("Cannot fire if not enabled; aborting")
  73. else:
  74. output("Unknown transition; aborting")
  75. return!
  76. Void function petrinet_list(model : Element):
  77. Element keys
  78. Element typemap
  79. Element place
  80. String name
  81. keys = dict_keys(model["model"])
  82. typemap = model["type_mapping"]
  83. place = model["metamodel"]["model"]["Place"]
  84. while (list_len(keys) > 0):
  85. name = set_pop(keys)
  86. if (element_eq(dict_read_node(typemap, model["model"][name]), place)):
  87. // Found a place
  88. output((name + ": ") + cast_i2s(read_attribute(model, name, "tokens")))
  89. return!
  90. Void function main():
  91. Element model
  92. String verify_result
  93. while (True):
  94. output("Which model do you want to execute with petri net semantics?")
  95. model = import_node(input())
  96. if (element_eq(model, read_root())):
  97. output("Could not find model; aborting")
  98. elif (element_neq(model["metamodel"], import_node("models/PetriNets"))):
  99. output("Not a PetriNets model; aborting")
  100. else:
  101. verify_result = conformance_scd(model)
  102. if (verify_result == "OK"):
  103. output("Model OK!")
  104. execute_petrinet(model)
  105. else:
  106. output("Non-conforming model: " + verify_result)
  107. return!
  108. Void function execute_petrinet(model : Element):
  109. String cmd
  110. while (True):
  111. output("Which operation do you want to execute?")
  112. cmd = input()
  113. if (cmd == "help"):
  114. output("Supported operations:")
  115. output(" help -- this information")
  116. output(" enabled -- list the enabled transitions")
  117. output(" fire -- fire a transition")
  118. output(" list -- list the state of the petrinet")
  119. output(" exit -- select another model")
  120. elif (cmd == "enabled"):
  121. petrinet_enabled(model)
  122. elif (cmd == "fire"):
  123. petrinet_fire(model)
  124. elif (cmd == "list"):
  125. petrinet_list(model)
  126. elif (cmd == "exit"):
  127. return!
  128. else:
  129. output("Did not understand command!")
  130. output("Use 'help' for a list of available options")
  131. return!