Joeri Exelmans 5 years ago
parent
commit
b5d9ee35b0

+ 0 - 6
src/sccd/cd/globals.py

@@ -1,12 +1,8 @@
-# from dataclasses import *
-import termcolor
 from typing import *
-from sccd.action_lang.static.expression import *
 from sccd.util.namespace import *
 from sccd.util.duration import *
 from sccd.util.debug import *
 
-# @dataclass
 class Globals:
   def __init__(self):
     self.events = Namespace()
@@ -39,8 +35,6 @@ class Globals:
       for d in self.durations:
         d.opt = 0
 
-    print_debug("Model delta is %s" % str(self.delta))
-
   def assert_ready(self):
     if self.delta is None:
       raise Exception("Globals not ready: durations not yet processed.")

+ 1 - 1
src/sccd/controller/controller.py

@@ -26,7 +26,7 @@ class Controller:
         self.initialized = False
 
         self.cd.globals.assert_ready()
-        # print_debug("model delta is %s" % str(self.cd.globals.delta))
+        print_debug("Model delta is %s" % str(self.cd.globals.delta))
 
         # First call to 'run_until' method initializes
         self.run_until = self._run_until_w_initialize

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

@@ -278,7 +278,7 @@ def statechart_parser_rules(globals, path, load_external = True, parse_f = parse
           except Exception as e:
             raise XmlErrorElement(t_el, "Could not find target '%s'." % (transition.target_string)) from e
 
-        statechart.tree = StateTree(root)
+        statechart.tree = optimize_tree(root)
 
       return (state_child_rules(root, sibling_dict=children_dict), finish_root)
 

+ 108 - 107
src/sccd/statechart/static/tree.py

@@ -203,115 +203,116 @@ class TransitionOptimization:
     arena: State
     arena_bitmap: Bitmap
 
+@dataclass
+class StateTree:
+    root: State
+    transition_list: List[Transition] # depth-first document order
+    state_list: List[State] # depth-first document order
+    state_dict: Dict[str, State] # mapping from 'full name' to State
+    after_triggers: List[AfterTrigger] # all after-triggers in the statechart
+    stable_bitmap: Bitmap # set of states that are syntactically marked 'stable'
+
 # Reduce a list of states to a set of states, as a bitmap
 def states_to_bitmap(state_list: List[State]) -> Bitmap:
     return reduce(lambda x,y: x|y, (s.opt.state_id_bitmap for s in state_list), Bitmap())
 
-
-# @dataclass
-class StateTree:
-
-    # root: The root state of a state,transition tree structure with with all fields filled in,
-    #       except the 'gen' fields. This function will fill in the 'gen' fields.
-    def __init__(self, root: State):
-        timer.start("optimize tree")
-
-        self.root = root
-
-        self.transition_list = []
-        self.after_triggers = []
-        def init_opt():
-            next_id = 0
-            def f(state: State, _=None):
-                state.opt = StateOptimization()
-
-                nonlocal next_id
-                state.opt.state_id = next_id
-                state.opt.state_id_bitmap = bit(next_id)
-                next_id += 1
-
-                for t in state.transitions:
-                    self.transition_list.append(t)
-                    if t.trigger and isinstance(t.trigger, AfterTrigger):
-                        state.opt.after_triggers.append(t.trigger)
-                        self.after_triggers.append(t.trigger)
-            return f
-
-        def assign_full_name(state: State, parent_full_name: str = ""):
-            if state is root:
-                full_name = '/'
-            elif state.parent is root:
-                full_name = '/' + state.short_name
+def optimize_tree(root: State) -> StateTree:
+    timer.start("optimize tree")
+
+    transition_list = []
+    after_triggers = []
+    def init_opt():
+        next_id = 0
+        def f(state: State, _=None):
+            state.opt = StateOptimization()
+
+            nonlocal next_id
+            state.opt.state_id = next_id
+            state.opt.state_id_bitmap = bit(next_id)
+            next_id += 1
+
+            for t in state.transitions:
+                transition_list.append(t)
+                if t.trigger and isinstance(t.trigger, AfterTrigger):
+                    state.opt.after_triggers.append(t.trigger)
+                    after_triggers.append(t.trigger)
+        return f
+
+    def assign_full_name(state: State, parent_full_name: str = ""):
+        if state is root:
+            full_name = '/'
+        elif state.parent is root:
+            full_name = '/' + state.short_name
+        else:
+            full_name = parent_full_name + '/' + state.short_name
+        state.opt.full_name = full_name
+        return full_name
+
+    state_dict = {}
+    state_list = []
+    stable_bitmap = Bitmap()
+    def add_to_list(state: State ,_=None):
+        nonlocal stable_bitmap
+        state_dict[state.opt.full_name] = state
+        state_list.append(state)
+        if state.stable:
+            stable_bitmap |= state.opt.state_id_bitmap
+
+    def set_ancestors(state: State, ancestors=[]):
+        state.opt.ancestors = states_to_bitmap(ancestors)
+        return ancestors + [state]
+
+    def set_descendants(state: State, children_descendants):
+        descendants = reduce(lambda x,y: x|y, children_descendants, Bitmap())
+        state.opt.descendants = descendants
+        return state.opt.state_id_bitmap | descendants
+
+    def set_static_target_states(state: State, _):
+        if isinstance(state, ParallelState):
+            state.opt.ts_static = reduce(lambda x,y: x|y, (s.opt.ts_static for s in state.children), state.opt.state_id_bitmap)
+            state.opt.ts_dynamic = list(itertools.chain.from_iterable(c.opt.ts_dynamic for c in state.children if not isinstance(c, HistoryState)))
+        elif isinstance(state, HistoryState):
+            state.opt.ts_static = Bitmap()
+            state.opt.ts_dynamic = state.children
+        else: # "regular" state:
+            if state.default_state:
+                state.opt.ts_static = state.opt.state_id_bitmap | state.default_state.opt.ts_static
+                state.opt.ts_dynamic = state.default_state.opt.ts_dynamic
             else:
-                full_name = parent_full_name + '/' + state.short_name
-            state.opt.full_name = full_name
-            return full_name
-
-        self.state_dict = {}
-        self.state_list = []
-        self.stable_bitmap = Bitmap()
-        def add_to_list(state: State ,_=None):
-            self.state_dict[state.opt.full_name] = state
-            self.state_list.append(state)
-            if state.stable:
-                self.stable_bitmap |= state.opt.state_id_bitmap
-
-        def set_ancestors(state: State, ancestors=[]):
-            state.opt.ancestors = states_to_bitmap(ancestors)
-            return ancestors + [state]
-
-        def set_descendants(state: State, children_descendants):
-            descendants = reduce(lambda x,y: x|y, children_descendants, Bitmap())
-            state.opt.descendants = descendants
-            return state.opt.state_id_bitmap | descendants
-
-        def set_static_target_states(state: State, _):
-            if isinstance(state, ParallelState):
-                state.opt.ts_static = reduce(lambda x,y: x|y, (s.opt.ts_static for s in state.children), state.opt.state_id_bitmap)
-                state.opt.ts_dynamic = list(itertools.chain.from_iterable(c.opt.ts_dynamic for c in state.children if not isinstance(c, HistoryState)))
-            elif isinstance(state, HistoryState):
-                state.opt.ts_static = Bitmap()
-                state.opt.ts_dynamic = state.children
-            else: # "regular" state:
-                if state.default_state:
-                    state.opt.ts_static = state.opt.state_id_bitmap | state.default_state.opt.ts_static
-                    state.opt.ts_dynamic = state.default_state.opt.ts_dynamic
-                else:
-                    state.opt.ts_static = state.opt.state_id_bitmap
-                    state.opt.ts_dynamic = []
-
-        def add_history(state: State, _= None):
-            for c in state.children:
-                if isinstance(c, HistoryState):
-                    state.opt.history.append((c, c.history_mask()))
-
-        visit_tree(root, lambda s: s.children,
-            before_children=[
-                init_opt(),
-                assign_full_name,
-                add_to_list,
-                set_ancestors,
-            ],
-            after_children=[
-                set_descendants,
-                add_history,
-                set_static_target_states,
-            ])
-
-
-        for t in self.transition_list:
-            # intersection between source & target ancestors, last member in depth-first sorted state list.
-            lca_id = (t.source.opt.ancestors & t.targets[0].opt.ancestors).highest_bit()
-            lca = self.state_list[lca_id]
-            arena = lca
-            while isinstance(arena, (ParallelState, HistoryState)):
-                arena = arena.parent
-
-            t.opt = TransitionOptimization(
-                arena=arena,
-                arena_bitmap=arena.opt.descendants | arena.opt.state_id_bitmap)
-
-        timer.stop("optimize tree")
-
-    def __repr__(self):
-        return "StateTree(root=%s, state_list=%s, transition_list=%s)" % (self.root, self.state_list, self.transition_list)
+                state.opt.ts_static = state.opt.state_id_bitmap
+                state.opt.ts_dynamic = []
+
+    def add_history(state: State, _= None):
+        for c in state.children:
+            if isinstance(c, HistoryState):
+                state.opt.history.append((c, c.history_mask()))
+
+    visit_tree(root, lambda s: s.children,
+        before_children=[
+            init_opt(),
+            assign_full_name,
+            add_to_list,
+            set_ancestors,
+        ],
+        after_children=[
+            set_descendants,
+            add_history,
+            set_static_target_states,
+        ])
+
+
+    for t in transition_list:
+        # intersection between source & target ancestors, last member in depth-first sorted state list.
+        lca_id = (t.source.opt.ancestors & t.targets[0].opt.ancestors).highest_bit()
+        lca = state_list[lca_id]
+        arena = lca
+        while isinstance(arena, (ParallelState, HistoryState)):
+            arena = arena.parent
+
+        t.opt = TransitionOptimization(
+            arena=arena,
+            arena_bitmap=arena.opt.descendants | arena.opt.state_id_bitmap)
+
+    timer.stop("optimize tree")
+
+    return StateTree(root, transition_list, state_list, state_dict, after_triggers, stable_bitmap)