Browse Source

Correction: event-based candidate generation should pre-cache all trigger's enabling events, not just the internal events (-> further improvement in no. cache hits)

Joeri Exelmans 5 years ago
parent
commit
15128efe3f

+ 1 - 1
src/sccd/statechart/dynamic/round.py

@@ -60,7 +60,7 @@ class CandidatesGeneratorEventBased(CandidatesGenerator):
 
     def __post_init__(self):
         # Prepare cache with all single-item sets-of-events since these are the most common sets of events.
-        for event_id in self.statechart.internal_events.items():
+        for event_id in self.statechart.events.items():
             events_bitmap = bit(event_id)
             self.cache[(events_bitmap, 0)] = self._candidates(events_bitmap, 0)
 

+ 5 - 1
src/sccd/statechart/parser/xml.py

@@ -27,6 +27,7 @@ def create_statechart_parser(globals, src_file, load_external = True, parse = pa
         semantics=SemanticConfiguration(),
         scope=Scope("instance", parent=BuiltIn),
         datamodel=None,
+        events=Bitmap(),
         internal_events=Bitmap(),
         inport_events={},
         event_outport={},
@@ -186,7 +187,7 @@ def create_statechart_parser(globals, src_file, load_external = True, parse = pa
 
         def parse_transition(el):
           if parent is root:
-            raise XmlError("Root <state> cannot be source of a transition.")
+            raise XmlError("Root cannot be source of a transition.")
 
           scope = Scope("event_params", parent=statechart.scope)
           target_string = require_attribute(el, "target")
@@ -212,6 +213,7 @@ def create_statechart_parser(globals, src_file, load_external = True, parse = pa
 
             if not negative_events:
               transition.trigger = Trigger(positive_events)
+              statechart.events |= transition.trigger.enabling_bitmap
             else:
               transition.trigger = NegatedTrigger(positive_events, negative_events)
 
@@ -265,6 +267,8 @@ def create_statechart_parser(globals, src_file, load_external = True, parse = pa
                 continue
               elif item.type == "IDENTIFIER":
                 state = [x for x in state.children if x.short_name == item.value][0]
+            if state is root:
+              raise XmlError("Root cannot be target of a transition.")
             return state
 
           try:

+ 1 - 0
src/sccd/statechart/static/statechart.py

@@ -89,6 +89,7 @@ class Statechart:
   scope: Scope
   datamodel: Optional[Block] # block of statements setting up the datamodel (variables in instance scope)
 
+  events: Bitmap # union of all transition trigger's enabling sets
   internal_events: Bitmap
   inport_events: Dict[str, Set[int]] # mapping from inport to set of event IDs
   event_outport: Dict[str, str] # mapping from event name to outport

+ 1 - 0
test/lib/test_parser.py

@@ -75,6 +75,7 @@ def create_test_parser(create_statechart_parser):
             #  All other fields remain the same
             scope=statechart.scope,
             datamodel=statechart.datamodel,
+            events=statechart.events,
             internal_events=statechart.internal_events,
             inport_events=statechart.inport_events,
             event_outport=statechart.event_outport,