Просмотр исходного кода

hierarchical version of FSA simulator

Simon Van Mierlo 9 лет назад
Родитель
Сommit
279593e840

+ 222 - 0
debugging_fsa_cbd_composition/fsasimulator/HierarchicalSimulator/fsaclasses.py

@@ -0,0 +1,222 @@
+import numpy
+from operator import attrgetter
+
+############### runtime classes
+
+class RunTimeEvent:
+    def __init__(self, name, time):
+        self.name = name
+        self.time = time
+        self.processed = False
+
+class Events:
+    def __init__(self, events):
+        self.events = sorted(events, key=attrgetter('time'))
+    
+    '''
+    Returns the most recent event with the timestamp smaller than time.
+    '''
+    def getInputAt(self,time):
+        event = None
+        if self.events != []:
+            # Claudio: this approach is assuming that the queue is sorted according the time of the events.
+            for e in self.events:
+                if e.time < time or numpy.isclose(e.time, time, 1e-05, 1e-08):
+                    event = e
+                else:
+                    # stop at the first event that satisfies e.time > time
+                    break
+        return event
+    
+    '''
+        Removes event all other older events from the queue.
+    '''
+    def popEvent(self, event):
+        if event == None:
+            return
+        
+        assert event in self.events
+        # Claudio: this approach is assuming that the queue is sorted according the time of the events.
+        # first collect list of events to be removed.
+        # then remove them.
+        eventsToBeRemoved = []
+        for e in self.events:
+            eventsToBeRemoved.append(e)
+            if e == event:
+                break
+        assert len(eventsToBeRemoved)>0
+        for e in eventsToBeRemoved:
+            self.events.remove(e)
+        
+
+############### static classes - invariants
+
+class Expression:
+    def __init__(self):
+        pass
+
+class FSAModel:
+    def __init__(self,states,transitions):
+        self.transitions = transitions
+        self.states = states
+        self.initialState = None
+        
+    def getTransitionFrom(self, state, event, elapsed):
+        assert state != None
+        assert elapsed >= 0.0
+        
+        # Priotiry goes to event.
+        selectedTransition = None
+        
+        if event!=None:
+            selectedTransition = self.getTriggeredTransition(state, event)
+        
+        # Then to after 
+        if (selectedTransition == None):
+            selectedTransition = self.getTransitionAfter(state, elapsed)
+        
+        # And finally to default transitions
+        if (selectedTransition == None):
+            selectedTransition = self.getDefaultTransition(state)
+        
+        return selectedTransition
+    
+    def getDefaultTransition(self, state):
+        assert state != None
+        for t in self.transitions:
+                if t.source == state and t.trigger == None:
+                    return t
+        
+        return None
+    
+    
+    def getTriggeredTransition(self, state, event):
+        assert event != None
+        for t in self.transitions:
+                if t.source == state and isinstance(t.trigger,Event) and t.trigger.name == event.name:
+                        return t
+        
+        return None
+    
+    def getTransitionAfter(self, state, elapsed):
+        for t in self.transitions:
+            if t.source == state and isinstance(t.trigger,After):
+                if ExpressionVisitor(t.trigger.after).visit() <= elapsed:
+                    return t
+        return None 
+
+class ExpressionVisitor:
+    def __init__(self, expression):
+        self.expression = expression
+        
+    def visit(self):
+        if(isinstance(self.expression,AtomValue)):
+            return self.expression.value
+        if(isinstance(self.expression,Operation)):
+            left = ExpressionVisitor(self.expression.left).visit()
+            right = ExpressionVisitor(self.expression.right).visit()
+            if(self.expression.op == '+'):
+                return left + right
+            if(self.expression.op == '-'):
+                return left - right
+            if(self.expression.op == '*'):
+                return left * right
+            if(self.expression.op == '/'):
+                return left / right
+            if(self.expression.op == 'and'):
+                return left and right
+            if(self.expression.op == 'or'):
+                return left or right
+        if(isinstance(self.expression,Not)):
+            return not ExpressionVisitor(self.expression.expression).visit()
+
+class State:
+    def __init__(self, name, final = False):
+        self.name = name
+        self.final = final
+        
+    def getName(self):
+        return self.name
+    
+    def __str__(self):
+        return self.name
+    
+    
+class Operation(Expression):
+    def __init__(self, left, right, op):
+        self.op = op
+        self.left = left
+        self.right = right
+        
+class Transition:
+    def __init__(self,name, source,target):
+        self.name = name
+        self.source = source
+        self.target = target
+        self.trigger = None
+        self.guard = None
+    
+    def __str__(self):
+        return str(self.source) + "--" + self.name + ": " +  str(self.trigger) + "-->" + str(self.target)
+    
+class Trigger:
+    def __init__(self):
+        pass
+
+class Event(Trigger):
+    def __init__(self,name):
+        self.name = name
+        
+    def __str__(self):
+        return self.name
+    
+class After(Trigger):
+    def __init__(self, expression):
+        self.after = expression
+    
+    def __str__(self):
+        return "after("+ str(self.after) + ")"
+    
+class Guard:
+    def __init__(self, expression):
+        self.expression = expression
+
+class And(Operation):
+    def __init__(self, lexpression, rexpression):
+        self.left = lexpression
+        self.right = rexpression
+        self.op = "and"
+
+class Or(Operation):
+    def __init__(self, lexpression, rexpression):
+        self.left = lexpression
+        self.right = rexpression
+        self.op = "or"
+
+class Not(Expression):
+    def __init__(self, expression):
+        self.expression = expression
+
+class Variable(Expression):
+    def __init__(self, varname):
+        self.name = varname
+
+class AtomValue(Expression):
+    def __init__(self, value):
+        self.value = value
+        
+    def __str__(self):
+        return str(self.value)
+    
+
+class Integer(AtomValue):
+    def __init__(self, value):
+        self.value = value
+    
+class Float(AtomValue):
+    def __init__(self, value):
+        self.value = value
+
+class String(AtomValue):
+    def __init__(self, value):
+        self.value = value

+ 128 - 0
debugging_fsa_cbd_composition/fsasimulator/HierarchicalSimulator/run_debug.py

@@ -0,0 +1,128 @@
+import target
+from sccd.runtime.statecharts_core import Event
+import threading
+import fsaclasses
+
+def buildModel():
+    statea = fsaclasses.State("a")
+    stateb = fsaclasses.State("b")
+    statet = fsaclasses.State("t")
+    statec = fsaclasses.State("c", final=True)
+    
+    transitionab = fsaclasses.Transition("a2b",statea,stateb)
+    transitionab.trigger = fsaclasses.Event("a")
+    
+    transitionbt = fsaclasses.Transition("b2t",stateb,statet)
+    transitionbt.trigger = fsaclasses.After(fsaclasses.Float(2.0))
+    
+    transitiontc = fsaclasses.Transition("t2c",statet,statec)
+
+    fsamodel = fsaclasses.FSAModel(
+                        [statea,stateb,statec],
+                        [transitionab,transitionbt, transitiontc]
+                        )
+    fsamodel.initialState = statea
+    return fsamodel
+
+if __name__ == '__main__':
+    fsamodel = buildModel()
+    events = fsaclasses.Events([fsaclasses.RunTimeEvent('a', 3.0)])
+    controller = target.Controller(fsamodel, events)
+    
+    def set_defaults(inp, defaultlist):
+        for i, v in enumerate(defaultlist):
+            if len(inp) == i + 1:
+                inp.append(v)
+                
+    def get_bool(val):
+        if val.lower() in ["true", "yes", "1"]:
+            return True
+        else:
+            return False
+
+    def raw_inputter():
+        while 1:
+            inp = raw_input().split(" ")
+            action = inp[0]
+            if action == "continuous":
+                params = []
+            elif action == "realtime":
+                set_defaults(inp, [1.0])
+                params = [inp[1]]
+            elif action == "big_step":
+                params = []
+            elif action == "small_step":
+                params = []
+            elif action == "pause":
+                params = []
+            elif action == "add_breakpoint":
+                if len(inp) < 5:
+                    print("Adding a breakpoint requires 4 parameters!")
+                    continue
+                # Merge together the final part again
+                params = [inp[1], " ".join(inp[2:-2]).replace("\\n", "\n").replace("\\t", "\t"), get_bool(inp[-2]), get_bool(inp[-1])]
+                print("Generated parameters: " + str(params))
+            elif action == "del_breakpoint":
+                if len(inp) < 2:
+                    print("Breakpoint removal requires 1 parameter!")
+                    continue
+                params = [inp[1]]
+            elif action == "toggle_breakpoint":
+                params = [inp[1]]
+            elif action == "list_breakpoints":
+                params = []
+            elif action == "god_event":
+                if len(inp) != 2:
+                    print("God events require 1 parameter!")
+                    continue
+                params = [inp[1]]
+            elif action == "help":
+                print("Supported operations:")
+                print("  continuous")
+                print("   --> Simulate until termination time is reached")
+                print("  pause")
+                print("   --> Pause the simulation")
+                print("  realtime [realtime_scale]")
+                print("   --> Simulate in realtime")
+                print("       realtime_scale can speed up or slow down the pace")
+                print("  big_step")
+                print("   --> Simulate a big step")
+                print("  small_step")
+                print("   --> Simulate a small step")
+                print("  add_breakpoint name function enabled disable_on_trigger")
+                print("   --> Add a breakpoint that will pause simulation when function returns True")
+                print("       the function should contain a definition of the 'breakpoint' function")
+                print("       and must take 1 parameter")
+                print("       enabled indicates whether or not the breakpoint should be checked")
+                print("       disable_on_trigger determines if the breakpoint should auto-disable")
+                print("       after being triggered")
+                print("  del_breakpoint name")
+                print("   --> Remove a breakpoint")
+                print("  toggle_breakpoint name")
+                print("   --> Toggle the designated breakpoint")
+                print("  list_breakpoints")
+                print("   --> List all breakpoints")
+                print("  god_event new_state")
+                print("   --> Updates the current state")
+                print("")
+                print("Defaults: ")
+                print("  realtime_scale   --> 1.0")
+                continue
+            else:
+                print("Command not understood: " + str(inp))
+                continue
+            controller.addInput(Event(action, "user_input", params))
+            
+    input_thread = threading.Thread(target=raw_inputter)
+    input_thread.daemon = True
+    input_thread.start()
+
+    output_listener = controller.addOutputListener(["user_output"])
+    def outputter():
+        while 1:
+            print output_listener.fetch(-1)
+    output_thread = threading.Thread(target=outputter)
+    output_thread.daemon = True
+    output_thread.start()
+
+    controller.start()

+ 223 - 0
debugging_fsa_cbd_composition/fsasimulator/HierarchicalSimulator/sim_bigstep.xml

@@ -0,0 +1,223 @@
+<class name="FSASimulator_BigStep">
+    <relationships>
+        <association name="parent" class="FSASimulator_Simulation" min="1" max="1" />
+        <association name="child_simulator" class="FSASimulator_SmallStep" min="0" max="1" />
+    </relationships>
+    <method name="FSASimulator_BigStep">
+        <parameter name="model" />
+        <parameter name="state" />
+        <parameter name="clock" />
+        <parameter name="elapsed" />
+        <parameter name="eventList" />
+        <parameter name="timeNext" />
+        <parameter name="delta" />
+        <body>
+        <![CDATA[
+            self.model = model
+            self.state = state
+            self.clock = clock
+            self.elapsed = elapsed
+            self.eventList = eventList
+            self.timeNext = timeNext
+            self.delta = delta
+        ]]>
+        </body>
+    </method>
+    <method name="initialize">
+        <body>
+        <![CDATA[
+            self.currentEvent = self.getInputEventAt(self.clock / 1000.0)
+            self.selectedTransition = self.model.getTransitionFrom(self.state, self.currentEvent, self.elapsed)
+            self.small_step_executed = False
+        ]]>
+        </body>
+    </method>
+    <method name="initializeDebugger">
+        <body>
+        <![CDATA[
+            pass
+        ]]>
+        </body>
+    </method>
+    <method name="endCondition">
+        <body>
+        <![CDATA[
+            ''' We make sure to "execute" a small step, even if no transition was selected. '''
+            return self.small_step_executed and self.selectedTransition == None
+        ]]>
+        </body>
+    </method>
+    <method name="finalize">
+        <body>
+        <![CDATA[
+            self.advanceTime()
+        ]]>
+        </body>
+    </method>
+    <method name="advanceTime">
+        <body>
+        <![CDATA[
+            self.clock = self.timeNext
+            self.elapsed = self.elapsed + self.delta
+            self.timeNext = self.clock + self.delta
+        ]]>
+        </body>
+    </method>
+    <method name="getInputEventAt">
+        <parameter name="time"/>
+        <body>
+        <![CDATA[
+            return self.eventList.getInputAt(time)
+        ]]>
+        </body>
+    </method>
+    <scxml initial="Main" final="Stopped">
+        <parallel id="Main">
+            <state id="ModeSelector" initial="Paused">
+                <state id="Paused">
+                    <transition target="../Running/SmallStep" event="SmallStep.Execute">
+                        <raise event="SmallStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Running/Continuous" event="BigStep.Execute" />
+                </state>
+                <state id="Running" initial="Continuous">
+                    <state id="Continuous" />
+                    <state id="SmallStep">
+                        <transition target="../../Paused" event="SmallStep.Finished">
+                            <parameter name="selectedTransition" />
+                            <parameter name="currentEvent" />
+                            <parameter name="eventList" />
+                            <parameter name="elapsed" />
+                            <parameter name="newState" />
+                            <raise event="SmallStep.Finished" scope="narrow" target="'parent'">
+                                <parameter expr="selectedTransition" />
+                                <parameter expr="currentEvent" />
+                                <parameter expr="eventList" />
+                                <parameter expr="elapsed" />
+                                <parameter expr="newState" />
+                            </raise>
+                        </transition>
+                    </state>                    
+                    <transition target="../Paused" event="BigStep.Finished" />
+                </state>
+            </state>
+            <state id="ChildState" initial="Uninitialized">
+                <state id="Uninitialized">
+                    <transition event="SmallStep.Initialized" target="../Initialized" />
+                </state>
+                <state id="Initialized">
+                    <transition target="../Uninitialized" event="SmallStep.Finished">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id="Initializer" initial="Waiting">
+                <state id="Waiting">
+                    <transition target="../CreatingChildSimulator" cond="INSTATE('../../ModeSelector/Running') and INSTATE('../../ChildState/Uninitialized') and not self.endCondition()">
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                            <parameter expr="'FSASimulator_SmallStep'" />
+                            <parameter expr="self.model" />
+                            <parameter expr="self.state" />
+                            <parameter expr="self.clock" />
+                            <parameter expr="self.elapsed" />
+                            <parameter expr="self.selectedTransition" />
+                            <parameter expr="self.currentEvent" />
+                            <parameter expr="self.eventList" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="CreatingChildSimulator">
+                    <transition target="../StartingChildSimulator" event="instance_created">
+                        <raise event="start_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="StartingChildSimulator">
+                    <transition target="../Running" event="SmallStep.Initialized" />
+                </state>
+                <state id="Running">
+                    <transition target="../SettleBeforeWaiting" event="SmallStep.Finished" />
+                </state>
+                <state id="SettleBeforeWaiting">
+                    <transition target="../Waiting" after="self.sccd_yield()" />
+                </state>
+            </state>
+            <state id="SimulationFlow" initial="Started">
+                <state id="Started">
+                    <transition target="../Initialized">
+                        <script>
+                        <![CDATA[
+                            self.initialize()
+                        ]]>
+                        </script>
+                    </transition>
+                </state>
+                <state id="Initialized">
+                    <transition target="../InitializeDebugger" />
+                </state>
+                <state id="InitializeDebugger">
+                    <transition target="../Waiting">
+                        <script>
+                        <![CDATA[
+                            self.initializeDebugger()
+                        ]]>
+                        </script>
+                        <raise event="BigStep.Initialized" scope="narrow" target="'parent'" />
+                    </transition>
+                </state>
+                <state id="Waiting">
+                    <transition target="../CheckTermination" cond="INSTATE('../../ModeSelector/Running')" />
+                </state>
+                <state id="SettleBeforeCheckTermination">
+                    <transition target="../CheckTermination" after="self.sccd_yield()" />
+                </state>
+                <state id="CheckTermination">
+                    <transition target="../Executing" cond="(INSTATE('../../ModeSelector/Running/Continuous') or INSTATE('../../ModeSelector/Running/SmallStep')) and INSTATE('../../ChildState/Initialized') and not self.endCondition()">
+                        <raise event="SmallStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Stopped" cond="self.endCondition()">
+                        <script>
+                        <![CDATA[
+                            # print '>>> big step executed <<<'
+                            self.finalize()
+                        ]]>
+                        </script>
+                        <raise event="BigStep.Finished" />
+                        <raise event="BigStep.Finished" scope="narrow" target="'parent'">
+                            <parameter expr="self.clock" />
+                            <parameter expr="self.timeNext" />
+                            <parameter expr="self.elapsed" />
+                            <parameter expr="self.eventList" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="Executing">
+                    <transition target="../SettleBeforeCheckTermination" event="SmallStep.Finished">
+                        <parameter name="selectedTransition" />
+                        <parameter name="currentEvent" />
+                        <parameter name="eventList" />
+                        <parameter name="elapsed" />
+                        <parameter name="newState" />
+                        <script>
+                        <![CDATA[
+                            self.selectedTransition = selectedTransition
+                            self.currentEvent = currentEvent
+                            self.eventList = eventList
+                            self.elapsed = elapsed
+                            self.state = newState
+                            self.small_step_executed = True
+                        ]]>
+                        </script>
+                    </transition>
+                </state>
+                <state id="Stopped" />
+            </state>
+        </parallel>
+        <state id="Stopped" />
+    </scxml>
+</class>

+ 332 - 0
debugging_fsa_cbd_composition/fsasimulator/HierarchicalSimulator/sim_coordinator.xml

@@ -0,0 +1,332 @@
+<class name="FSASimulator_Coordinator" default="True">        
+    <relationships>
+        <association name="child_simulator" class="FSASimulator_Simulation" min="0" max="1" />
+    </relationships>
+    <method name="FSASimulator_Coordinator">
+        <parameter name="model"/>
+        <parameter name="events"/>
+        <body>
+            <![CDATA[
+            self.model = model
+            self.eventList = events
+            ]]>
+        </body>
+    </method>
+    <scxml initial="Main" final="Stopped">
+        <parallel id="Main">
+            <state id="ModeSelector" initial="Paused">
+                <state id="Paused">
+                    <transition target="../Running/SmallStep" event="small_step" port="user_input" />
+                    <transition target="../Running/BigStep" event="big_step" port="user_input" />
+                    <transition target="../Running/Continuous" event="continuous" port="user_input" />
+                    <transition target="../Running/Realtime" event="realtime" port="user_input">
+                        <parameter name="realtime_scale" default="1.0" />
+                        <script>
+                            self.realtime_scale = float(realtime_scale)
+                        </script>
+                    </transition>
+                    <transition target="." event="BigStep.Finished">
+                        <parameter name="clock" />
+                        <parameter name="timeNext" />
+                        <parameter name="eventList" />
+                        <parameter name="state" />
+                        <raise event="BigStep.Finished" port="user_output" />
+                        <raise event="State" port="user_output">
+                            <parameter expr="clock / 1000.0" />
+                            <!--parameter expr="timeNext" /-->
+                            <!--parameter expr="eventList" /-->
+                            <parameter expr="state" />
+                        </raise>
+                    </transition>
+                    <transition target="." event="Simulation.Finished">
+                        <parameter name="clock" />
+                        <parameter name="state" />
+                        <raise event="Simulation.Finished" port="user_output" />
+                        <raise event="State" port="user_output">
+                            <parameter expr="clock / 1000.0" />
+                            <parameter expr="state" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="Running" initial="Continuous">
+                    <state id="Continuous">
+                        <transition target="../../WaitingForPaused" event="pause" port="user_input">
+                            <raise event="Simulation.Pause" scope="narrow" target="'child_simulator'" />
+                        </transition>
+                        <transition target="../../Stopped" event="Simulation.Finished">
+                            <parameter name="clock" />
+                            <parameter name="state" />
+                            <raise event="Simulation.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="clock / 1000.0" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                    </state>
+                    <state id="Realtime">
+                        <transition target="../../WaitingForPaused" event="pause" port="user_input">
+                            <raise event="Simulation.Pause" scope="narrow" target="'child_simulator'" />
+                        </transition>
+                        <transition target="../../Stopped" event="Simulation.Finished">
+                            <parameter name="clock" />
+                            <parameter name="state" />
+                            <raise event="Simulation.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="clock / 1000.0" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                        <transition target="." event="BigStep.Finished">
+                        <parameter name="clock" />
+                        <parameter name="timeNext" />
+                        <parameter name="eventList" />
+                        <parameter name="state" />
+                            <raise event="BigStep.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="clock / 1000.0" />
+                                <!--parameter expr="timeNext" /-->
+                                <!--parameter expr="eventList" /-->
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                    </state>
+                    <state id="BigStep">
+                        <transition target="../../Paused" event="BigStep.Finished">
+                            <parameter name="clock" />
+                            <parameter name="timeNext" />
+                            <parameter name="eventList" />
+                            <parameter name="state" />
+                            <raise event="BigStep.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="clock / 1000.0" />
+                                <!--parameter expr="timeNext" /-->
+                                <!--parameter expr="eventList" /-->
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                        <transition target="../../Stopped" event="Simulation.Finished">
+                            <parameter name="clock" />
+                            <parameter name="state" />
+                            <raise event="Simulation.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="clock / 1000.0" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                    </state>
+                    <state id="SmallStep">
+                        <transition target="../../Paused" event="SmallStep.Finished">
+                            <parameter name="selectedTransition" />
+                            <parameter name="currentEvent" />
+                            <parameter name="eventList" />
+                            <parameter name="elapsed" />
+                            <parameter name="state" />
+                            <raise event="SmallStep.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="selectedTransition" />
+                                <parameter expr="currentEvent" />
+                                <parameter expr="eventList" />
+                                <parameter expr="elapsed" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                        <transition target="../../Paused" event="BigStep.Finished">
+                            <parameter name="clock" />
+                            <parameter name="timeNext" />
+                            <parameter name="eventList" />
+                            <parameter name="state" />
+                            <raise event="BigStep.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="clock / 1000.0" />
+                                <!--parameter expr="timeNext" /-->
+                                <!--parameter expr="eventList" /-->
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                        <transition target="../../Stopped" event="Simulation.Finished">
+                            <parameter name="clock" />
+                            <parameter name="state" />
+                            <raise event="Simulation.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="clock / 1000.0" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                    </state>
+                    <transition target="../Paused" event="Simulation.Finished">
+                        <parameter name="clock" />
+                        <parameter name="state" />
+                        <raise event="Simulation.Finished" port="user_output"/>
+                        <raise event="State" port="user_output">
+                            <parameter expr="clock / 1000.0" />
+                            <parameter expr="state" />
+                        </raise>
+                    </transition>
+                    <transition target="../Paused" event="Breakpoint.Triggered">
+                        <parameter name="triggered_bp" />
+                        <parameter name="clock" />
+                        <parameter name="state" />
+                        <raise event="Breakpoint.Triggered" port="user_output">
+                            <parameter expr="triggered_bp" />
+                            <parameter expr="clock" />
+                            <parameter expr="state" />
+                        </raise>
+                        <raise event="State" port="user_output">
+                            <parameter expr="clock / 1000.0" />
+                            <parameter expr="state" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="WaitingForPaused">
+                    <transition target="../Paused" event="Simulation.Paused">
+                        <parameter name="clock" />
+                        <parameter name="state" />
+                        <raise event="Simulation.Paused" port="user_output" />
+                        <raise event="State" port="user_output">
+                            <parameter expr="clock / 1000.0" />
+                            <parameter expr="state" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="Stopped" />
+            </state>
+            <state id="ChildState" initial="Uninitialized">
+                <state id="Uninitialized">
+                    <transition event="Simulation.Initialized" target="../Initialized" />
+                </state>
+                <state id="Initialized">
+                    <transition target="../Uninitialized" event="Simulation.Finished">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id="Initializer" initial="Waiting">
+                <state id="Waiting">
+                    <!-- always initialize an uninitialized simulation -->
+                    <transition target="../CreatingChildSimulator" cond="INSTATE('../../ChildState/Uninitialized')">
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                            <parameter expr="'FSASimulator_Simulation'" />
+                            <parameter expr="deepcopy(self.model)"/>
+                            <parameter expr="deepcopy(self.eventList)"/>
+                        </raise>
+                    </transition>
+                </state>
+                <state id="CreatingChildSimulator">
+                    <transition target="../StartingChildSimulator" event="instance_created">
+                        <raise event="start_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="StartingChildSimulator">
+                    <transition target="../Waiting" event="Simulation.Initialized" />
+                </state>
+            </state>
+            <state id="SimulationFlow" initial="Paused">
+                <state id="PrePaused">
+                    <transition target="../Paused" after="self.sccd_yield()" />
+                </state>
+                <state id="Paused">
+                    <transition target="../Executing" cond="INSTATE('../../ModeSelector/Running/Continuous') and INSTATE('../../ChildState/Initialized')">
+                        <raise event="Simulation.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Executing" cond="INSTATE('../../ModeSelector/Running/Realtime') and INSTATE('../../ChildState/Initialized')">
+                        <raise event="Simulation.ExecuteRealtime" scope="narrow" target="'child_simulator'">
+                            <parameter expr="self.realtime_scale" />
+                        </raise>
+                    </transition>
+                    <transition target="../Executing" cond="INSTATE('../../ModeSelector/Running/BigStep') and INSTATE('../../ChildState/Initialized')">
+                        <raise event="BigStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Executing" cond="INSTATE('../../ModeSelector/Running/SmallStep') and INSTATE('../../ChildState/Initialized')">
+                        <raise event="SmallStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                </state>
+                <state id="Executing">
+                    <transition target="../Paused" cond="INSTATE('../../ModeSelector/Paused')" />
+                    <transition target="../PrePaused" event="Simulation.Finished" cond="INSTATE('../../ModeSelector/Running/Continuous') or INSTATE('../../ModeSelector/Running/Realtime')" />
+                </state>
+            </state>
+            <state id="GodEventManager" initial="Listening">
+                <state id="Listening">
+                    <transition target="../Waiting" event="god_event" port="user_input" cond="INSTATE('../../ModeSelector/Paused')">
+                        <parameter name="block_name" />
+                        <parameter name="new_val" />
+                        <raise event="Simulation.GodEvent" target="'child_simulator'">
+                            <parameter expr="block_name" />
+                            <parameter expr="new_val" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="Waiting">
+                    <transition target="../Listening" event="Simulation.GodEventResult">
+                        <parameter name="result" />
+                        <raise event="GodEventResult" port="user_output">
+                            <parameter expr="result" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id="BreakpointManager" initial="Listening">
+                <state id="Listening">
+                    <transition target="../Waiting" event="add_breakpoint" port="user_input">
+                        <parameter name="name"/>
+                        <parameter name="function"/>
+                        <parameter name="enabled"/>
+                        <parameter name="disable_on_trigger"/>
+                        <raise event="Breakpoint.Add" target="'child_simulator'">
+                            <parameter expr="name"/>
+                            <parameter expr="function"/>
+                            <parameter expr="enabled"/>
+                            <parameter expr="disable_on_trigger"/>
+                        </raise>
+                    </transition>
+                    <transition target="../Waiting" event="del_breakpoint" port="user_input">
+                        <parameter name="name"/>
+                        <raise event="Breakpoint.Del" target="'child_simulator'">
+                            <parameter expr="name"/>
+                        </raise>
+                    </transition>
+                    <transition target="../Waiting" event="toggle_breakpoint" port="user_input">
+                        <parameter name="name"/>
+                        <raise event="Breakpoint.Toggle" target="'child_simulator'">
+                            <parameter expr="name"/>
+                        </raise>
+                    </transition>
+                    <transition target="../Waiting" event="list_breakpoints" port="user_input">
+                        <raise event="Breakpoint.List" target="'child_simulator'" />
+                    </transition>
+                </state>
+                <state id="Waiting">
+                    <transition target="../Listening" event="Breakpoint.AddResult">
+                        <parameter name="result" />
+                        <raise event="Breakpoint.AddResult" port="user_output">
+                            <parameter expr="result" />
+                        </raise>
+                    </transition>
+                    <transition target="../Listening" event="Breakpoint.DelResult">
+                        <parameter name="result" />
+                        <raise event="Breakpoint.DelResult" port="user_output">
+                            <parameter expr="result" />
+                        </raise>
+                    </transition>
+                    <transition target="../Listening" event="Breakpoint.ToggleResult">
+                        <parameter name="result" />
+                        <raise event="Breakpoint.ToggleResult" port="user_output">
+                            <parameter expr="result" />
+                        </raise>
+                    </transition>
+                    <transition target="../Listening" event="Breakpoint.ListResult">
+                        <parameter name="result" />
+                        <raise event="Breakpoint.ListResult" port="user_output">
+                            <parameter expr="result" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+        </parallel>
+    </scxml>
+</class>

+ 444 - 0
debugging_fsa_cbd_composition/fsasimulator/HierarchicalSimulator/sim_simulation.xml

@@ -0,0 +1,444 @@
+<class name="FSASimulator_Simulation">
+    <relationships>
+        <association name="parent" class="FSASimulator_Coordinator" min="1" max="1" />
+        <association name="child_simulator" class="FSASimulator_BigStep" min="0" max="1" />
+    </relationships>
+    <method name="FSASimulator_Simulation">
+        <parameter name="model"/>
+        <parameter name="events"/>
+        <body>
+        <![CDATA[
+            self.model = model
+            self.eventList = events
+        ]]>
+        </body>
+    </method>
+    <method name="initialize">
+        <body>
+        <![CDATA[
+            self.clock = 0
+            self.elapsed = 0
+            self.delta = 1.0 * 1000.0 # in miliseconds for real-time simulation
+            self.timeNext = self.delta
+            self.state = self.model.initialState
+        ]]>
+        </body>
+    </method>
+    <method name="endCondition">
+        <body>
+        <![CDATA[
+            return self.state and self.state.final
+        ]]>
+        </body>
+    </method>
+    <method name="finalize">
+        <body>
+        <![CDATA[
+            print 'Simulation finalized.'
+        ]]>
+        </body>
+    </method>
+    <method name="initializeDebugger">
+        <body>
+        <![CDATA[
+            self.breakpoints = []
+            self.triggered_bp = None
+        ]]>
+        </body>
+    </method>
+    <method name="waitTime">
+        <body>
+        <![CDATA[
+            # First, we convert from wall-clock time to simulated time.
+            # This means the elapsed time in wall-clock time needs to be scaled according to the realtime scale (for example, if the realtime scale is 2, an elapsed time of 1 second in wall-clock time is equal to an elapsed time of 2 seconds in simulated time).
+            simulated_diff = (accurate_time.time() - self.realtime_start_time) * self.realtime_scale
+            # timeNext and simulated_diff are both in simulated time: so now scale back to wall-clock time by dividing.
+            # This function returns an amount of miliseconds.
+            return ((self.timeNext - simulated_diff) / self.realtime_scale)
+        ]]>
+        </body>
+    </method>
+    <method name="syncSimulatedTime">
+        <body>
+        <![CDATA[
+            diff = accurate_time.time() - self.realtime_start_time
+            self.clock = diff * self.realtime_scale
+        ]]>
+        </body>
+    </method>
+    <method name="addBreakpoint">
+        <parameter name="name" />
+        <parameter name="function" />
+        <parameter name="enabled" default="true" />
+        <parameter name="disable_on_trigger" default="true" />
+        <body>
+        <![CDATA[
+            if len([bp for bp in self.breakpoints if bp.name == name]) > 0:
+                return -1
+            self.breakpoints.append(Breakpoint(name, function, enabled, disable_on_trigger))
+            return 0
+        ]]>
+        </body>
+    </method>
+    <method name="delBreakpoint">
+        <parameter name="name" />
+        <body>
+        <![CDATA[
+            if len([bp for bp in self.breakpoints if bp.name == name]) == 0:
+                return -1
+            self.breakpoints = [bp for bp in self.breakpoints if bp.name != name]
+            return 0
+        ]]>
+        </body>
+    </method>
+    <method name="toggleBreakpoint">
+        <parameter name="name" />
+        <body>
+        <![CDATA[
+            if len([bp for bp in self.breakpoints if bp.name == name]) == 0:
+                return -1
+            for bp in self.breakpoints:
+                if bp.name == name:
+                    bp.enabled = enabled
+                    break
+            return 0
+        ]]>
+        </body>
+    </method>
+    <method name="breakpointTriggers">
+        <parameter name="is_realtime_simulation" />
+        <body>
+        <![CDATA[
+            self.triggered_bp = None
+            for bp in self.breakpoints:
+                if not bp.enabled:
+                    continue
+                # include the function in the scope...
+                exec(bp.function)
+                # ... and execute it, note that the breakpoint thus has to start with "def breakpoint("
+                # note that we pass self.timeNext instead of self.simulated_time in the case of as-fast-as-possible simulation (or stepping)
+                # this is to make sure that the simulation is stopped BEFORE the specified time is reached, and not AFTER (because we don't necessarily implement 'step back')
+                # in case of realtime simulation, we do pass the current simulated time, since we can stop at (more or less) exactly the right time
+                if breakpoint({'clock': (self.clock if is_realtime_simulation else self.timeNext) / 1000.0, 'state': self.state}):
+                    # triggered!
+                    self.triggered_bp = bp.name
+                    if bp.disable_on_trigger:
+                        bp.enabled = False
+                    return True
+                else:
+                    # not triggered, so continue
+                    continue
+            return False
+        ]]>
+        </body>
+    </method>
+        <method name="godEvent">
+            <parameter name="new_state" />
+            <body>
+            <![CDATA[
+                filtered_states = [s for s in self.model.states if s.name == new_state]
+                if not len(filtered_states) == 1:
+                    return -1
+                self.state = filtered_states[0]
+                return 0
+            ]]>
+            </body>
+        </method>
+    <scxml initial="Main" final="Stopped">
+        <parallel id="Main">
+            <state id="ModeSelector" initial="Paused">
+                <state id="Paused">
+                    <transition target="../Running/SmallStep" event="SmallStep.Execute">
+                        <raise event="SmallStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Running/BigStep" event="BigStep.Execute">
+                        <raise event="BigStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Running/Continuous" event="Simulation.Execute" />
+                    <transition target="../Running/Realtime" event="Simulation.ExecuteRealtime">
+                        <parameter name="realtime_scale" default="1.0" />
+                        <script>
+                            self.realtime_scale = float(realtime_scale)
+                            # If the simulation was paused, we need to reset the start time of the simulation.
+                            # The start time of the simulation is equal to the point in wall-clock time where simulated time is 0.
+                            # If the simulation was paused, we have to recompute this point in time: it is the difference of the wall-clock time and the simulated time.
+                            # If the scale was changed after the pause, this point of course moves backwards (for scales smaller than 1) or forwards (for scales larger than 1)
+                            self.realtime_start_time = accurate_time.time() - (self.clock / self.realtime_scale)
+                        </script>
+                    </transition>
+                    <transition target="." event="BigStep.Finished">
+                        <parameter name="clock" />
+                        <parameter name="timeNext" />
+                        <parameter name="elapsed" />
+                        <parameter name="eventList" />
+                        <parameter name="state" />
+                        <raise event="BigStep.Finished" scope="narrow" target="'parent'">
+                            <parameter expr="clock" />
+                            <parameter expr="timeNext" />
+                            <parameter expr="elapsed" />
+                            <parameter expr="eventList" />
+                            <parameter expr="state" />
+                        </raise>
+                   </transition>
+                </state>
+                <state id="Running" initial="Continuous">
+                    <state id="Continuous">
+                        <transition target="../../Paused" event="Simulation.Pause" />
+                    </state>
+                    <state id="Realtime">
+                        <transition target="../../Paused" event="Simulation.Pause" />
+                        <transition target="." event="BigStep.Finished">
+                            <parameter name="clock" />
+                            <parameter name="timeNext" />
+                            <parameter name="elapsed" />
+                            <parameter name="eventList" />
+                            <parameter name="state" />
+                            <raise event="BigStep.Finished" scope="narrow" target="'parent'">
+                                <parameter expr="clock" />
+                                <parameter expr="timeNext" />
+                                <parameter expr="elapsed" />
+                                <parameter expr="eventList" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                    </state>
+                    <state id="BigStep">
+                        <transition target="../../Paused" event="BigStep.Finished">
+                            <parameter name="clock" />
+                            <parameter name="timeNext" />
+                            <parameter name="elapsed" />
+                            <parameter name="eventList" />
+                            <parameter name="state" />
+                            <raise event="BigStep.Finished" scope="narrow" target="'parent'">
+                                <parameter expr="clock" />
+                                <parameter expr="timeNext" />
+                                <parameter expr="elapsed" />
+                                <parameter expr="eventList" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                    </state>
+                    <state id="SmallStep">
+                        <transition target="../../Paused" event="SmallStep.Finished">
+                            <parameter name="selectedTransition" />
+                            <parameter name="currentEvent" />
+                            <parameter name="eventList" />
+                            <parameter name="elapsed" />
+                            <parameter name="state" />
+                            <raise event="SmallStep.Finished" scope="narrow" target="'parent'">
+                                <parameter expr="selectedTransition" />
+                                <parameter expr="currentEvent" />
+                                <parameter expr="eventList" />
+                                <parameter expr="elapsed" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                    </state>
+                    <transition target="../Paused" event="Simulation.Finished" />
+                    <transition target="../Paused" cond="self.breakpointTriggers(INSTATE('Realtime'))">
+                        <raise event="Breakpoint.Triggered" scope="narrow" target="'parent'">
+                            <parameter expr="self.triggered_bp" />
+                            <parameter expr="self.clock" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id="ChildState" initial="Uninitialized">
+                <state id="Uninitialized">
+                    <transition event="BigStep.Initialized" target="../Initialized" />
+                </state>
+                <state id="Initialized">
+                    <transition target="../Uninitialized" event="BigStep.Finished">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id="Initializer" initial="Waiting">
+                <state id="Waiting">
+                    <transition target="../CreatingChildSimulator" cond="INSTATE('../../ModeSelector/Running') and INSTATE('../../ChildState/Uninitialized') and not self.endCondition()">
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                            <parameter expr="'FSASimulator_BigStep'" />
+                            <parameter expr="self.model" />
+                            <parameter expr="self.state" />
+                            <parameter expr="self.clock" />
+                            <parameter expr="self.elapsed" />
+                            <parameter expr="self.eventList" />
+                            <parameter expr="self.timeNext" />
+                            <parameter expr="self.delta" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="CreatingChildSimulator">
+                    <transition target="../StartingChildSimulator" event="instance_created">
+                        <raise event="start_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="StartingChildSimulator">
+                    <transition target="../Running" event="BigStep.Initialized" />
+                </state>
+                <state id="Running">
+                    <transition target="../SettleBeforeWaiting" event="BigStep.Finished" />
+                </state>
+                <state id="SettleBeforeWaiting">
+                    <transition target="../Waiting" after="self.sccd_yield()" />
+                </state>
+            </state>
+            <state id="SimulationFlow" initial="Started">
+                <state id="Started">
+                    <transition target="../Initialized">
+                        <script>
+                        <![CDATA[
+                            self.initialize()
+                        ]]>
+                        </script>
+                    </transition>
+                </state>
+                <state id="Initialized">
+                    <transition target="../InitializeDebugger" />
+                </state>
+                <state id="InitializeDebugger">
+                    <transition target="../Waiting">
+                        <script>
+                        <![CDATA[
+                            self.initializeDebugger()
+                        ]]>
+                        </script>
+                        <raise event="Simulation.Initialized" scope="narrow" target="'parent'" />
+                    </transition>
+                </state>
+                <state id="Waiting">
+                    <transition target="../CheckTermination" cond="INSTATE('../../ModeSelector/Running')" />
+                </state>
+                <state id="SettleBeforeCheckTermination">
+                    <transition target="../CheckTermination" after="self.sccd_yield()" />
+                    <transition target="../CheckTermination" cond="INSTATE('../../ModeSelector/Paused')">
+                        <raise event="Simulation.Paused" scope="narrow" target="'parent'">
+                            <parameter expr="self.clock" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="CheckTermination">
+                    <transition target="../Executing" cond="(INSTATE('../../ModeSelector/Running/Continuous') or INSTATE('../../ModeSelector/Running/BigStep')) and INSTATE('../../ChildState/Initialized') and not self.endCondition()">
+                        <raise event="BigStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Executing" cond="INSTATE('../../ModeSelector/Running/SmallStep') and INSTATE('../../ChildState/Initialized') and not self.endCondition()">
+                        <raise event="SmallStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../WaitingRealtime" cond="INSTATE('../../ModeSelector/Running/Realtime') and INSTATE('../../ChildState/Initialized') and not self.endCondition()" />
+                    <transition target="../Stopped" cond="self.endCondition()">
+                        <script>
+                        <![CDATA[
+                            # print '>>> simulation executed <<<'
+                            self.finalize()
+                        ]]>
+                        </script>
+                        <raise event="Simulation.Finished" />
+                        <raise event="Simulation.Finished" scope="narrow" target="'parent'">
+                            <parameter expr="self.clock" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="WaitingRealtime">
+                    <!-- We schedule to go back to the check_termination state after the smallest possible delay (to accomodate for pauses). -->
+                    <transition target="../CheckTermination" after="self.sccd_yield()" cond="INSTATE('../../ModeSelector/Running')">                            
+                        <!-- We set the simulation time to the correct value. -->
+                        <script>
+                            self.syncSimulatedTime()
+                        </script>
+                    </transition>
+                    <transition target="../CheckTermination" cond="INSTATE('../../ModeSelector/Paused') and (not ((self.waitTime() / 1000.0) &lt;= self.sccd_yield()))">
+                        <raise event="Simulation.Paused" scope="narrow" target="'parent'">
+                            <parameter expr="self.clock" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                    <!-- We execute a step when the wait time is smaller than the smallest possible delay. -->
+                    <transition target="../Executing" cond="self.waitTime() / 1000.0 &lt;= self.sccd_yield()">
+                        <raise event="BigStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                </state>
+                <state id="Executing">
+                    <transition target="../SettleBeforeCheckTermination" event="BigStep.Finished">
+                        <parameter name="clock" />
+                        <parameter name="timeNext" />
+                        <parameter name="elapsed" />
+                        <parameter name="eventList" />
+                        <parameter name="state" />
+                        <script>
+                        <![CDATA[
+                            self.clock = clock
+                            self.timeNext = timeNext
+                            self.elapsed = elapsed
+                            self.eventList = eventList
+                            self.state = state
+                        ]]>
+                        </script>
+                   </transition>
+                </state>
+                <state id="Stopped" />
+            </state>
+            <state id="GodEventManager" initial="Listening">
+                <state id="Listening">
+                    <transition target="." event="Simulation.GodEvent" cond="INSTATE('../../ModeSelector/Paused')">
+                        <parameter name="block_name" />
+                        <parameter name="new_val" />
+                        <script>
+                            result = self.godEvent(block_name, new_val)
+                        </script>
+                        <raise event="Simulation.GodEventResult" scope="narrow" target="'parent'">
+                            <parameter expr="result" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id="BreakpointManager" initial="Listening">
+                <state id="Listening">
+                    <transition target="." event="Breakpoint.Add">
+                        <parameter name="name"/>
+                        <parameter name="function"/>
+                        <parameter name="enabled"/>
+                        <parameter name="disable_on_trigger"/>
+                        <script>
+                            result = self.addBreakpoint(name, function, bool(enabled), bool(disable_on_trigger))
+                        </script>
+                        <raise event="Breakpoint.AddResult" scope="narrow" target="'parent'">
+                            <parameter expr="result" />
+                        </raise>
+                    </transition>
+                    <transition target="." event="Breakpoint.Del">
+                        <parameter name="name"/>
+                        <script>
+                            result = self.delBreakpoint(name)
+                        </script>
+                        <raise event="Breakpoint.DelResult" scope="narrow" target="'parent'">
+                            <parameter expr="result" />
+                        </raise>
+                    </transition>
+                    <transition target="." event="Breakpoint.Toggle">
+                        <parameter name="name"/>
+                        <script>
+                            result = self.toggleBreakpoint(name)
+                        </script>
+                        <raise event="Breakpoint.ToggleResult" scope="narrow" target="'parent'">
+                            <parameter expr="result" />
+                        </raise>
+                    </transition>
+                    <transition target="." event="Breakpoint.List">
+                        <raise event="Breakpoint.ListResult" scope="narrow" target="'parent'">
+                            <parameter expr="[bp.name for bp in self.breakpoints]" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+        </parallel>
+        <state id="Stopped" />
+    </scxml>
+</class>

+ 192 - 0
debugging_fsa_cbd_composition/fsasimulator/HierarchicalSimulator/sim_smallstep.xml

@@ -0,0 +1,192 @@
+<class name="FSASimulator_SmallStep">
+    <relationships>
+        <association name="parent" class="FSASimulator_BigStep" min="1" max="1" />
+        <association name="child_simulator" class="FSASimulator_Block" min="0" max="1" />
+    </relationships>
+    <method name="FSASimulator_SmallStep">
+        <parameter name="model" />
+        <parameter name="state" />
+        <parameter name="clock" />
+        <parameter name="elapsed" />
+        <parameter name="selectedTransition" />
+        <parameter name="currentEvent" />
+        <parameter name="eventList" />
+        <body>
+        <![CDATA[
+            self.model = model
+            self.state = state
+            self.clock = clock
+            self.elapsed = elapsed
+            self.selectedTransition = selectedTransition
+            self.currentEvent = currentEvent
+            self.eventList = eventList
+        ]]>
+        </body>
+    </method>
+    <method name="initialize">
+        <body>
+        <![CDATA[
+            self.small_step_executed = False
+        ]]>
+        </body>
+    </method>
+    <method name="initializeDebugger">
+        <body>
+        <![CDATA[
+            pass
+        ]]>
+        </body>
+    </method>
+    <method name="endCondition">
+        <body>
+        <![CDATA[
+            ''' In case nothing is to be done, we immediately end. '''
+            return not self.selectedTransition or self.small_step_executed
+        ]]>
+        </body>
+    </method>
+    <method name="finalize">
+        <body>
+        <![CDATA[
+            self.elapsed = 0
+            self.processEvent(self.currentEvent)
+            self.currentEvent = self.getInputEventAt(self.clock / 1000.0)
+            self.selectedTransition = self.model.getTransitionFrom(self.state, self.currentEvent, self.elapsed)
+        ]]>
+        </body>
+    </method>
+    <method name="processEvent">
+        <parameter name="event"/>
+        <body>
+        <![CDATA[
+            if (event != None):
+                self.eventList.popEvent(event)
+                event.processed = True
+        ]]>
+        </body>
+    </method>
+    <method name="getInputEventAt">
+        <parameter name="time"/>
+        <body>
+        <![CDATA[
+            return self.eventList.getInputAt(time)
+        ]]>
+        </body>
+    </method>
+    <scxml initial="Main" final="Stopped">
+        <parallel id="Main">
+            <state id="ModeSelector" initial="Paused">
+                <state id="Paused">
+                    <transition target="../Running/Continuous" event="SmallStep.Execute" />
+                </state>
+                <state id="Running" initial="Continuous">
+                    <state id="Continuous" />             
+                    <transition target="../Paused" event="SmallStep.Finished" />
+                </state>
+            </state>
+            <state id="ChildState" initial="Uninitialized">
+                <state id="Uninitialized">
+                    <transition event="Transition.Initialized" target="../Initialized" />
+                </state>
+                <state id="Initialized">
+                    <transition target="../Uninitialized" event="Transition.Finished">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id="Initializer" initial="Waiting">
+                <state id="Waiting">
+                    <transition target="../CreatingChildSimulator" cond="INSTATE('../../ModeSelector/Running') and INSTATE('../../ChildState/Uninitialized') and not self.endCondition()">
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                            <parameter expr="'FSASimulator_Transition'" />
+                            <parameter expr="self.selectedTransition" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="CreatingChildSimulator">
+                    <transition target="../StartingChildSimulator" event="instance_created">
+                        <raise event="start_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="StartingChildSimulator">
+                    <transition target="../Running" event="Transition.Initialized" />
+                </state>
+                <state id="Running">
+                    <transition target="../SettleBeforeWaiting" event="Transition.Finished" />
+                </state>
+                <state id="SettleBeforeWaiting">
+                    <transition target="../Waiting" after="self.sccd_yield()" />
+                </state>
+            </state>
+            <state id="SimulationFlow" initial="Started">
+                <state id="Started">
+                    <transition target="../Initialized">
+                        <script>
+                        <![CDATA[
+                            self.initialize()
+                        ]]>
+                        </script>
+                    </transition>
+                </state>
+                <state id="Initialized">
+                    <transition target="../InitializeDebugger" />
+                </state>
+                <state id="InitializeDebugger">
+                    <transition target="../Waiting">
+                        <script>
+                        <![CDATA[
+                            self.initializeDebugger()
+                        ]]>
+                        </script>
+                        <raise event="SmallStep.Initialized" scope="narrow" target="'parent'" />
+                    </transition>
+                </state>
+                <state id="Waiting">
+                    <transition target="../CheckTermination" cond="INSTATE('../../ModeSelector/Running')" />
+                </state>
+                <state id="SettleBeforeCheckTermination">
+                    <transition target="../CheckTermination" after="self.sccd_yield()" />
+                </state>
+                <state id="CheckTermination">
+                    <transition target="../Executing" cond="INSTATE('../../ModeSelector/Running/Continuous') and INSTATE('../../ChildState/Initialized') and not self.endCondition()">
+                        <raise event="Transition.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Stopped" cond="self.endCondition()">
+                        <script>
+                        <![CDATA[
+                            # print '>>> small step executed <<<'
+                            self.finalize()
+                        ]]>
+                        </script>
+                        <raise event="SmallStep.Finished" />
+                        <raise event="SmallStep.Finished" scope="narrow" target="'parent'">
+                            <parameter expr="self.selectedTransition" />
+                            <parameter expr="self.currentEvent" />
+                            <parameter expr="self.eventList" />
+                            <parameter expr="self.elapsed" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="Executing">
+                    <transition target="../SettleBeforeCheckTermination" event="Transition.Finished">
+                        <parameter name="new_state" />
+                        <script>
+                        <![CDATA[
+                            self.small_step_executed = True
+                            self.state = new_state
+                        ]]>
+                        </script>
+                    </transition>
+                </state>
+                <state id="Stopped" />
+            </state>
+        </parallel>
+        <state id="Stopped" />
+    </scxml>
+</class>

+ 36 - 0
debugging_fsa_cbd_composition/fsasimulator/HierarchicalSimulator/sim_transition.xml

@@ -0,0 +1,36 @@
+<class name="FSASimulator_Transition">
+    <relationships>
+        <association name="parent" class="FSASimulator_SmallStep" min="1" max="1" />
+    </relationships>
+    <method name="FSASimulator_Transition">
+        <parameter name="selectedTransition" />
+        <body>
+            self.selectedTransition = selectedTransition
+        </body>
+    </method>
+    <method name="executeTransition">
+        <body>
+        <![CDATA[
+            self.newState = self.selectedTransition.target
+        ]]>
+        </body>
+    </method>
+    <scxml initial="Started" final="Stopped">
+        <state id="Started">
+            <transition target="../Waiting">
+                <raise event="Transition.Initialized" scope="narrow" target="'parent'" />
+            </transition>
+        </state>
+        <state id="Waiting">
+            <transition target="../Stopped" event="Transition.Execute">
+                <script>
+                    self.executeTransition()
+                </script>
+                <raise event="Transition.Finished" scope="narrow" target="'parent'">
+                    <parameter expr="self.newState" />
+                </raise>
+            </transition>
+        </state>
+        <state id="Stopped" />
+    </scxml>
+</class>

+ 30 - 0
debugging_fsa_cbd_composition/fsasimulator/HierarchicalSimulator/simulator.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<diagram name="FSASimulator_Coordinator" author="Sadaf Mustafiz and Claudio Gomes and Simon Van Mierlo">
+    <description>
+        A debuggeable CBD simulator.
+    </description>
+    
+    <inport name="user_input" />
+    <inport name="user_output" />
+    
+    <top>
+        from sccd.runtime.libs.ui import *
+        from sccd.runtime.libs.utils import *
+        from copy import deepcopy
+        import fsaclasses
+        import sccd.runtime.accurate_time as accurate_time
+        
+        class Breakpoint:
+            def __init__(self, name, function, enabled, disable_on_trigger):
+                self.name = name
+                self.function = function
+                self.enabled = enabled
+                self.disable_on_trigger = disable_on_trigger
+    </top>
+
+    <class src="sim_coordinator.xml" default="True" />
+    <class src="sim_simulation.xml"/>
+    <class src="sim_bigstep.xml"/>
+    <class src="sim_smallstep.xml"/>
+    <class src="sim_transition.xml"/>
+</diagram>

Разница между файлами не показана из-за своего большого размера
+ 2061 - 0
debugging_fsa_cbd_composition/fsasimulator/HierarchicalSimulator/target.py