run.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. from sccd.statechart.parser.xml import *
  2. from sccd.statechart.dynamic.statechart_instance import *
  3. if __name__ == "__main__":
  4. # Load model
  5. globals = Globals()
  6. rules = statechart_parser_rules(globals, path=".")
  7. statechart_model = parse_f("statechart_semantics.xml", [("statechart", rules)])
  8. globals.init_durations()
  9. # Generate semantic variants, and filter invalid ones
  10. variants = statechart_model.generate_semantic_variants()
  11. variants_filtered = [v for v in variants if v.semantics.enabledness_memory_protocol == v.semantics.assignment_memory_protocol]
  12. print("Total variants:", len(variants_filtered))
  13. # These rules perfectly partition the set of variants into "valid" and "invalid":
  14. def is_valid(semantics):
  15. # Combo-steps should be smaller (or equal to) big-steps, obviously.
  16. if semantics.combo_step_maximality > semantics.big_step_maximality:
  17. return False
  18. # Combo steps only make sense if another semantic option refers to them
  19. combo_steps_defined = (semantics.input_event_lifeline == InputEventLifeline.FIRST_COMBO_STEP or
  20. semantics.internal_event_lifeline == InternalEventLifeline.NEXT_COMBO_STEP or
  21. semantics.enabledness_memory_protocol == MemoryProtocol.COMBO_STEP)
  22. if combo_steps_defined:
  23. if semantics.big_step_maximality == Maximality.TAKE_ONE:
  24. # Combo steps will always equal big steps, and therefore don't really exist!
  25. # E.g. Input event lifeline "Present in First Combo Step" should be "Present in Whole" instead.
  26. # E.g. Internal event lifeline "Present in Next Combo Step" makes no sense, the event will never be sensed!
  27. # E.g. Memory protocol "Combo Step" should be "Big Step" instead.
  28. return False
  29. else:
  30. # Has no effect
  31. if semantics.combo_step_maximality > Maximality.TAKE_ONE:
  32. return False
  33. return True
  34. valid_variants = [v for v in variants_filtered if is_valid(v.semantics)]
  35. invalid_variants = [v for v in variants_filtered if not is_valid(v.semantics)]
  36. print("Valid variants:", len(valid_variants))
  37. print("Invalid variants:", len(invalid_variants))
  38. # We'll need these mappings to translate the statechart's post-big-step configuration to a semantic configuration
  39. state_name_to_semantics = {
  40. "/P/BigStepMaximality/TakeOne": ("big_step_maximality", Maximality.TAKE_ONE),
  41. "/P/BigStepMaximality/Syntactic": ("big_step_maximality", Maximality.SYNTACTIC),
  42. "/P/BigStepMaximality/TakeMany": ("big_step_maximality", Maximality.TAKE_MANY),
  43. "/P/ComboStepMaximality/ComboStepMaximality/TakeOne": ("combo_step_maximality", Maximality.TAKE_ONE),
  44. "/P/ComboStepMaximality/ComboStepMaximality/Syntactic": ("combo_step_maximality", Maximality.SYNTACTIC),
  45. "/P/ComboStepMaximality/ComboStepMaximality/TakeMany": ("combo_step_maximality", Maximality.TAKE_MANY),
  46. "/P/InputEventLifeline/FirstSmallStep": ("input_event_lifeline", InputEventLifeline.FIRST_SMALL_STEP),
  47. "/P/InputEventLifeline/FirstComboStep": ("input_event_lifeline", InputEventLifeline.FIRST_COMBO_STEP),
  48. "/P/InputEventLifeline/Whole": ("input_event_lifeline", InputEventLifeline.WHOLE),
  49. "/P/InternalEventLifeline/InternalEventLifeline/NextSmallStep": ("internal_event_lifeline", InternalEventLifeline.NEXT_SMALL_STEP),
  50. "/P/InternalEventLifeline/InternalEventLifeline/NextComboStep": ("internal_event_lifeline", InternalEventLifeline.NEXT_COMBO_STEP),
  51. "/P/InternalEventLifeline/InternalEventLifeline/Remainder": ("internal_event_lifeline", InternalEventLifeline.REMAINDER),
  52. "/P/InternalEventLifeline/InternalEventLifeline/Queue": ("internal_event_lifeline", InternalEventLifeline.QUEUE),
  53. "/P/MemoryProtocol/MemoryProtocol/BigStep": ("enabledness_memory_protocol", MemoryProtocol.BIG_STEP),
  54. "/P/MemoryProtocol/MemoryProtocol/ComboStep": ("enabledness_memory_protocol", MemoryProtocol.COMBO_STEP),
  55. "/P/MemoryProtocol/MemoryProtocol/SmallStep": ("enabledness_memory_protocol", MemoryProtocol.SMALL_STEP),
  56. "/P/Priority/SourceParent": ("hierarchical_priority", HierarchicalPriority.SOURCE_PARENT),
  57. "/P/Priority/SourceChild": ("hierarchical_priority", HierarchicalPriority.SOURCE_CHILD),
  58. }
  59. state_id_to_semantics = {
  60. statechart_model.tree.state_dict[state_name].state_id: tup
  61. for state_name, tup in state_name_to_semantics.items()
  62. }
  63. # Some mock callbacks that we have to pass to the StatechartInstance
  64. def on_output(e: OutputEvent):
  65. pass
  66. def schedule(after, event, targets):
  67. return 0
  68. def cancel(id):
  69. pass
  70. # List of input events for the big-step is always the same, so declare it outside the loop
  71. input_events = [InternalEvent(name="input0", params=[])]
  72. def check_variants(variants):
  73. correct = []
  74. incorrect = []
  75. for v in variants:
  76. instance = StatechartInstance(
  77. statechart=v,
  78. object_manager=None,
  79. output_callback=on_output,
  80. schedule_callback=schedule,
  81. cancel_callback=cancel)
  82. instance.initialize()
  83. instance.big_step(input_events)
  84. inferred_semantics = SemanticConfiguration()
  85. for state_id in bm_items(instance.execution.configuration):
  86. if state_id in state_id_to_semantics:
  87. aspect_name, aspect_val = state_id_to_semantics[state_id]
  88. setattr(inferred_semantics, aspect_name, aspect_val)
  89. inferred_semantics.assignment_memory_protocol = inferred_semantics.enabledness_memory_protocol
  90. # print("\nActual semantics:")
  91. # print(v.semantics)
  92. # print("\nInferred semantics:")
  93. # print(inferred_semantics)
  94. if v.semantics == inferred_semantics:
  95. correct.append(inferred_semantics)
  96. else:
  97. incorrect.append((v.semantics, inferred_semantics))
  98. return (correct, incorrect)
  99. correct, incorrect = check_variants(valid_variants)
  100. # for inc in correct:
  101. # print("CORRECT:")
  102. # print(inc)
  103. # for inc in incorrect:
  104. # print("INCORRECT:")
  105. # print("what it was:", inc[0])
  106. # print("what the SC says it is:", inc[1])
  107. print("\nOf the valid variants, correctly inferred %d, incorrectly inferred %d." % (len(correct), len(incorrect)))
  108. correct, incorrect = check_variants(invalid_variants)
  109. print("Of the invalid variants, correctly inferred %d, incorrectly inferred %d." % (len(correct), len(incorrect)))
  110. # for inc in correct:
  111. # print("CORRECT:")
  112. # print(inc)
  113. # for inc in incorrect:
  114. # print("INCORRECT:")
  115. # print("what it was:", inc[0])
  116. # print("what the SC says it is:", inc[1])