Kaynağa Gözat

hierarchical simulator in a somewhat stable state

Simon Van Mierlo 9 yıl önce
ebeveyn
işleme
520f6a6c5b
30 değiştirilmiş dosya ile 6459 ekleme ve 2 silme
  1. 891 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/CBD.py
  2. 54 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/CBDDraw.py
  3. 0 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/__init__.py
  4. 129 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/naivelog.py
  5. 49 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/plot.py
  6. 48 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/CounterTest.py
  7. 0 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/__init__.py
  8. 551 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/basicCBDTest.py
  9. 201 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/flattenCBDTest.py
  10. 201 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/hierarchyCBDTest.py
  11. 172 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/sortedGraphCBDTest.py
  12. 0 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/__init__.py
  13. 80 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/models/EvenNumbersCBD.py
  14. 21 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/models/HarmonicOscilator.py
  15. 300 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/models/TrainControlCBD.py
  16. 0 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/models/__init__.py
  17. 262 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBD_Controller.py
  18. 56 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/Options.py
  19. 14 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/log.txt
  20. 43 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/plot.html
  21. 116 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/run_debug.py
  22. 219 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_bigstep.xml
  23. 45 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_block.xml
  24. 273 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_coordinator.xml
  25. 457 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_simulation.xml
  26. 187 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_smallstep.xml
  27. 30 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/simulator.xml
  28. 2058 0
      debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/target.py
  29. 1 1
      debugging_fsa_cbd_composition/cbdsimulator/cbdsim_parallel_debugging_realtime.xml
  30. 1 1
      debugging_fsa_cbd_composition/cbdsimulator/target.py

+ 891 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/CBD.py

@@ -0,0 +1,891 @@
+import math
+import naivelog
+from collections import namedtuple
+
+InputLink = namedtuple("InputLink", ["block", "output_port"])
+Signal = namedtuple("Signal", ["time", "value"])
+def enum(**enums):
+            return type('Enum', (), enums)
+level = enum(WARNING=1, ERROR=2, FATAL=3)	
+epsilon = 0.001		
+
+class BaseBlock:
+    """
+    A base class for all types of basic blocks
+    """
+    def __init__(self, name, input_ports, output_ports):
+        self.setBlockName(name)
+
+        #The output signals produced by this block is encoded as a dictionary.
+        #The key of this dictionary is the name of the output port.
+        #Each element of the dictionary contains an ordered list of values.
+        self.__signals = dict()
+        for output_port in output_ports:
+            self.__signals[output_port] = []
+        
+        self._output_ports = output_ports
+        
+        #The input links produced by this block is encoded as a dictionary.
+        #The key of this dictionary is the name of the input port.
+        #Each element of the dictionary contains
+        #an tuple of the block and the output name of the other block.
+        self._linksIn = dict()
+
+        #The list of possible input ports
+        self.__nameLinks = input_ports
+        #In wich CBD the baseblock is situated
+        self._parent = None
+    
+    def getOutputPorts(self):
+        return self._output_ports
+    
+    def resetSignals(self):
+        for output_port in self.__signals:
+            self.__signals[output_port] = []
+    
+    def getBlockName(self):
+        return self.__block_name
+
+    def setBlockName(self, block_name):
+        self.__block_name = block_name
+
+    def setParent(self, parent):
+        self._parent = parent
+
+    def getBlockType(self):
+        return self.__class__.__name__
+
+    def getLinksIn(self):
+        return self._linksIn
+
+    def getOutputNameOfInput(self, inputBlock):
+        return [ y for (x,y) in self._linksIn.iteritems() if y.block == inputBlock ][0].output_port
+
+    def getInputName(self, inputBlock):
+        return [ x for (x,y) in self._linksIn.iteritems() if y.block == inputBlock ]
+
+    def getClock(self):
+        return self._parent.getClock()
+
+    def appendToSignal(self, value, name_output = None):
+        name_output = "OUT1" if name_output == None else name_output
+        assert name_output in self.__signals.keys()
+        self.__signals[name_output].append(Signal(self.getClock().getTime(), value))
+        
+    def setSignal(self, value, name_output = None):
+        name_output = "OUT1" if name_output == None else name_output
+        assert name_output in self.__signals.keys()
+        if len(self.__signals[name_output]) > 0:
+            self.__signals[name_output][-1] = Signal(self.getClock().getTime(), value)
+
+    def getSignal(self, name_output = None):
+        name_output = "OUT1" if name_output == None else name_output
+        assert name_output in self.__signals.keys()
+        return self.__signals[name_output] if name_output != None else self.__signals["OUT1"]
+
+    def getDependencies(self, curIteration):
+        return list(set([ tup.block for tup in self._linksIn.values() ]))
+
+    def getBlockConnectedToInput(self, input_port):
+        return self._linksIn[input_port]
+
+    def getInputSignal(self, curIteration, input_port = None):
+        """
+        Returns the signal sent out by the input block (IN1 if none given,
+        at the last time if no curIteration is given).
+        """
+        input_port = "IN1" if input_port == None else input_port
+        curIteration = -1 if curIteration == None else curIteration
+
+        (incoming_block, out_port_name) = self._linksIn[input_port]
+        return incoming_block.getSignal(out_port_name)[curIteration]
+
+    def compute(self, curIteration):
+        exit("BaseBlock has nothing to compute")
+
+    def linkInput(self, in_block, name_input, name_output):
+        """
+        linkInput will link the output of the from_block to the input of the to_block
+        -if no name_input was given for the to_block, we will derive the right input,
+        by checking which input IN has nothing connected to it yet
+        -if no name_output was given we use the first OUT output
+        """
+        name_output = "OUT1" if name_output == None else name_output
+        if name_input != None:
+            assert name_input in self.__nameLinks
+            self._linksIn[name_input] = InputLink(in_block, name_output)
+        else:
+            i = 1
+            while True:
+                nextIn = "IN" + str(i)
+                if nextIn in self.__nameLinks:
+                    if not nextIn in self._linksIn:
+                        self._linksIn[nextIn] = InputLink(in_block, name_output)
+                        return
+                else:
+                    exit("There are no open IN inputs left in block %s" % self.getBlockName())
+                i += 1
+
+    def __repr__(self):
+        repr = self.getBlockName() + ":" + self.getBlockType() + "\n"
+        if len(self._linksIn) == 0:
+            repr+= "  No incoming connections to IN ports\n"
+        else:
+            for (key, (in_block, out_port)) in self._linksIn.iteritems():
+                repr += "In input " + key + ":  IN <- " + in_block.getBlockName() + ":" + in_block.getBlockType() + "\n"
+        return repr
+
+class ConstantBlock(BaseBlock):
+    """
+    The constant block will always output its constant value
+    """
+    def __init__(self, block_name, value=0.0):
+        BaseBlock.__init__(self, block_name, [], ["OUT1"])
+        self.__value = value
+
+    def getValue(self):
+        return self.__value
+
+    def setValue(self, value):
+        self.__value = value
+
+    def compute(self, curIteration):
+        self.appendToSignal(self.getValue())
+
+    def __repr__(self):
+        return BaseBlock.__repr__(self) + "  Value = " + str(self.getValue()) + "\n"
+
+class NegatorBlock(BaseBlock):
+    """
+    The negator block will output the value of the input multiplied with -1
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1"], ["OUT1"])
+
+    def compute(self, curIteration):
+        self.appendToSignal(-self.getInputSignal(curIteration).value)
+
+class InverterBlock(BaseBlock):
+    """
+    The invertblock will output 1/IN
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1"], ["OUT1"])
+
+    def compute(self, curIteration):
+        self.appendToSignal(1.0/self.getInputSignal(curIteration).value)
+
+class AdderBlock(BaseBlock):
+    """
+    The adderblock will add the 2 inputs
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1", "IN2"], ["OUT1"])
+
+    def	compute(self, curIteration):
+        self.appendToSignal(self.getInputSignal(curIteration, "IN1").value + self.getInputSignal(curIteration, "IN2").value)
+
+class ProductBlock(BaseBlock):
+    """
+    The product block will multiply the two inputs
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1", "IN2"], ["OUT1"])
+
+    def	compute(self, curIteration):
+        self.appendToSignal(self.getInputSignal(curIteration, "IN1").value * self.getInputSignal(curIteration, "IN2").value)
+
+class GenericBlock(BaseBlock):
+    """
+    The generic block will evaluate the operator on the input
+    operator is the name (a string) of a Python function from the math library
+    which will be called when the block is evaluated
+    by default, initialized to None
+    """
+    def __init__(self, block_name, block_operator=None):
+        # operator is the name (a string) of a Python function from the math library
+        BaseBlock.__init__(self, block_name, ["IN1"], ["OUT1"])
+        self.__block_operator = block_operator
+
+    def getBlockOperator(self):
+        return self.__block_operator
+
+    def compute(self, curIteration):
+        operator = getattr(math, self.getBlockOperator())
+        self.appendToSignal(operator(self.getInputSignal(curIteration).value))
+
+    def __repr__(self):
+        repr = BaseBlock.__repr__(self)
+        if self.__block_operator == None:
+            repr += "  No operator given\n"
+        else:
+            repr += "  Operator :: " + self.__block_operator + "\n"
+        return repr
+
+class RootBlock(BaseBlock):
+    """
+    A basic block that computes the IN2-th root from IN1
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1", "IN2"], ["OUT1"])
+
+    def compute(self, curIteration):
+        self.appendToSignal(pow(self.getInputSignal(curIteration, "IN1").value, 1.0/self.getInputSignal(curIteration, "IN2").value))
+
+class ModuloBlock(BaseBlock):
+    """
+    A basic block that computes the IN1 modulo IN3
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1", "IN2"], ["OUT1"])
+
+    def compute(self, curIteration):
+        self.appendToSignal(math.fmod(self.getInputSignal(curIteration, "IN1").value, self.getInputSignal(curIteration, "IN2").value))
+
+class DelayBlock(BaseBlock):
+    """
+    A delay block that takes the last value from the list
+    IC: Initial Condition
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1", "IC"], ["OUT1"])
+        self.__values = []
+
+    def getDependencies(self, curIteration):
+        if curIteration == 0:
+            return [self._linksIn["IC"].block]
+        return []
+    
+    def resetSignals(self):
+        BaseBlock.resetSignals(self)
+        self.__values = []
+    
+    def compute(self, curIteration):
+        if curIteration == 0:
+            outputValue = self.getInputSignal(curIteration, "IC")
+            self.appendToSignal(outputValue.value)
+        else:
+            assert curIteration == len(self.__values)+1
+            (incoming_block, out_port_name) = self._linksIn["IN1"]
+            self.__values.append(incoming_block.getSignal(out_port_name)[curIteration-1])
+            self.appendToSignal(self.__values[curIteration-1].value)
+    
+class InputPortBlock(BaseBlock):
+    """
+    The input port of a CBD
+    """
+    def __init__(self, block_name, parent):
+        BaseBlock.__init__(self, block_name, [], ["OUT1"])
+        self.parent = parent
+
+    def	compute(self, curIteration):
+        self.appendToSignal(self.parent.getInputSignal(curIteration, self.getBlockName()).value)
+
+class OutputPortBlock(BaseBlock):
+    """
+    The output port of a CBD
+    """
+    def __init__(self, block_name, parent):
+        BaseBlock.__init__(self, block_name, ["IN1"], ["OUT1"])
+        self.parent = parent
+
+    def	compute(self, curIteration):
+        self.appendToSignal(self.getInputSignal(curIteration, "IN1").value)
+
+class WireBlock(BaseBlock):
+    """
+    When a CBD gets flattened, the port blocks will be replaced by a wire block
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1"], ["OUT1"])
+
+    def	compute(self, curIteration):
+        self.appendToSignal(self.getInputSignal(curIteration, "IN1").value)
+
+class TimeBlock(BaseBlock):
+    """
+    Outputs the current time of the simulation
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, [], ["OUT1"])
+
+    def	compute(self, curIteration):
+        self.appendToSignal(self.getClock().getTime())
+
+class LessThanBlock(BaseBlock):
+    """
+    A simple block that will test if the IN1 is smaller than IC (output == 1 if true else 0)
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IC", "IN1"], ["OUT1"])
+
+    def	compute(self, curIteration):
+        gisv = lambda s: self.getInputSignal(curIteration, s).value
+        self.appendToSignal(1 if gisv("IN1") < gisv("IC") else 0)
+
+class EqualsBlock(BaseBlock):
+    """
+    A simple block that will test if the IN1 is equal to IC (output == 1 if true else 0)
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IC", "IN1"], ["OUT1"])
+
+    def	compute(self, curIteration):
+        gisv = lambda s: self.getInputSignal(curIteration, s).value
+        self.appendToSignal(1 if gisv("IN1") == gisv("IC") else 0)
+
+class NotBlock(BaseBlock):
+    """
+    A simple Not block that will set a 0 to 1 and vice versa
+    """
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1"], ["OUT1"])
+
+    def	compute(self, curIteration):
+        result = 0 if self.getInputSignal(curIteration, "IN1").value else 1
+        self.appendToSignal(result)    
+
+class OrBlock(BaseBlock):
+    """
+    A simple Or block with possibly multiple inputlines
+    """
+    def __init__(self, block_name, numberOfInputs=2):
+        BaseBlock.__init__(self, block_name, ["IN{0}".format(i) for i in xrange(1,numberOfInputs+1)], ["OUT1"])
+        self.__numberOfInputs = numberOfInputs
+
+    def	compute(self, curIteration):
+        result = 0
+        for i in xrange(1, self.__numberOfInputs+1):
+            result = result or self.getInputSignal(curIteration, "IN"+str(i)).value
+        self.appendToSignal(result)    
+
+class AndBlock(BaseBlock):
+    """
+    A simple And block with possibly multiple inputlines
+    """
+    def __init__(self, block_name, numberOfInputs=2):
+        BaseBlock.__init__(self, block_name, ["IN{0}".format(i) for i in xrange(1,numberOfInputs+1)], ["OUT1"])
+        self.__numberOfInputs = numberOfInputs
+
+    def	compute(self, curIteration):
+        result = 1
+        for i in xrange(1, self.__numberOfInputs+1):
+            result = result and self.getInputSignal(curIteration, "IN"+str(i)).value
+        self.appendToSignal(result)
+
+class SequenceBlock(BaseBlock):
+    """
+    A simple Sequence block: block initializes signal input with given sequence
+    Use only for the tests please
+    """
+    def __init__(self, block_name, sequence):
+        BaseBlock.__init__(self, block_name, [], ["OUT1"])
+        self.__sequence = sequence
+
+    def	compute(self, curIteration):
+        if len(self.__sequence) < curIteration:
+            self.__logger.fatal("Sequence is not long enough")
+        self.appendToSignal(self.__sequence[curIteration])
+
+class LoggingBlock(BaseBlock):
+    """
+    A simple Logging block
+    """
+    def __init__(self, block_name, string, lev = level.WARNING):
+        BaseBlock.__init__(self, block_name, ["IN1"], [])
+        self.__string = string
+        self.__logger = naivelog.getLogger("WarningLog")
+        self.__lev = lev
+
+    def	compute(self, curIteration):
+        if self.getInputSignal(curIteration, "IN1").value == 1:
+            if self.__lev == level.WARNING:
+                self.__logger.warning("Time " + str(self.getClock().getTime()) + ": " + self.__string)
+            elif self.__lev == level.ERROR:
+                self.__logger.error("Time " + str(self.getClock().getTime()) + ": " + self.__string)
+            elif self.__lev == level.FATAL:
+                self.__logger.fatal("Time " + str(self.getClock().getTime()) + ": " + self.__string)
+
+class Clock:
+    """
+    The clock of the simulation
+    delta_t is the timestep of the simulation
+    """
+    def __init__(self, delta_t):
+        self.__delta_t = delta_t
+        self.__time = 0.0
+
+    def getTime(self):
+        return self.__time
+
+    def step(self):
+        self.__time = self.__time + self.__delta_t
+
+    def setDeltaT(self, new_delta_t):
+        self.__delta_t = new_delta_t
+
+    def getDeltaT(self):
+        return self.__delta_t
+
+class CBD(BaseBlock):
+    """
+    The CBD class, contains an entire Causal Block Diagram
+    Call the run function to simulate the model.
+    """
+    def __init__(self, block_name, input_ports = None, output_ports = None):
+        input_ports = input_ports if input_ports != None else []
+        output_ports = output_ports if output_ports != None else []
+        BaseBlock.__init__(self, block_name, input_ports, output_ports)
+        #The blocks in the CBD will be stored both
+        #-as an ordered list __blocks and
+        #-as a dictionary __blocksDict with the blocknames as keys
+        #for fast name-based retrieval and to ensure block names are unique within a single CBD
+        self.__blocks = []
+        self.__blocksDict = {}
+        self.__clock = None
+        self.__deltaT = None
+        self.__logger = naivelog.getLogger("CBD")
+
+        for input_port in input_ports:
+            self.addBlock(InputPortBlock(input_port, self))
+
+        for output_port in output_ports:
+            self.addBlock(OutputPortBlock(output_port, self))
+
+    def getTopCBD(self):
+        return self if self._parent == None else self._parent.getTopCBD()
+
+    def setBlocks(self, blocks):
+        # blocks must be a list of BaseBlock (subclass) instances
+        assert type(blocks) == list, ("CBD.setBlocks() takes a list as argument, not a %s" % type(blocks))
+        for block in blocks:
+            assert isinstance(block, BaseBlock), "CBD.setBlocks() takes a list of BaseBlock (subclass) instances"
+
+    def getBlocks(self):
+        return self.__blocks
+
+    def getBlockByName(self, name):
+        return self.__blocksDict[name]
+    
+    def setClock(self, clock):
+        self.__clock = clock;
+    
+    def getClock(self):
+        return self.__clock if self._parent == None else self._parent.getClock()
+
+    def setDeltaT(self, deltaT):
+        self.__deltaT = deltaT
+
+    def addBlock(self, block):
+        """
+        Add a block to the CBD model
+        """
+        assert isinstance(block, BaseBlock), "Can only add BaseBlock (subclass) instances to a CBD"
+        block.setParent(self)
+
+        if not self.__blocksDict.has_key(block.getBlockName()):
+            self.__blocks.append(block)
+            self.__blocksDict[block.getBlockName()] = block
+        else:
+            print("Warning: did not add this block as it has the same name %s as an existing block" % block.getBlockName())
+
+    def removeBlock(self, block):
+        assert isinstance(block, BaseBlock), "Can only delete BaseBlock (subclass) instances to a CBD"
+
+        if self.__blocksDict.has_key(block.getBlockName()):
+            self.__blocks.remove(block)
+            del self.__blocksDict[block.getBlockName()]
+        else:
+            exit("Warning: did not remove this block %s as it was not found" % block.getBlockName())
+
+    def addConnection(self, from_block, to_block, input_port_name = None, output_port_name = None):
+        """
+        Add a connection between from_block with input_port_name to to_block with outport_port_name
+        """
+        if type(from_block) == str:
+            from_block = self.getBlockByName(from_block)
+        if type(to_block) == str:
+            to_block = self.getBlockByName(to_block)
+        to_block.linkInput(from_block, input_port_name, output_port_name)
+
+    def __repr__(self):
+        repr = BaseBlock.__repr__(self)
+        repr += "\n"
+        for block in self.getBlocks():
+            repr+= block.__repr__()
+        return repr
+
+    def dump(self):
+        print("=========== Start of Model Dump ===========")
+        print(self)
+        print("=========== End of Model Dump =============\n")
+
+    def dumpSignals(self):
+        print("=========== Start of Signals Dump ===========")
+        for block in self.getBlocks():
+            print("%s:%s" % (block.getBlockName(), block.getBlockType()))
+            print(str(block.getSignal()) + "\n")
+        print("=========== End of Signals Dump =============\n")
+    
+    def resetSignals(self):
+        for block in self.getBlocks():
+            block.resetSignals()
+    
+    def getSignal(self, name_output = None):
+        name_output = "OUT1" if name_output == None else name_output
+        portBlock = self.getBlockByName(name_output)
+        assert portBlock != None
+        return portBlock.getSignal("OUT1")
+    
+    
+class AddOneBlock(CBD):
+    """
+    Block adds a one to the input (used a lot for mux)
+    """
+    def __init__(self, block_name, faultOrder=3):
+        CBD.__init__(self, block_name, ["IN1"], ["OUT1"])
+        self.addBlock(ConstantBlock(block_name="OneConstant", value=1))
+        self.addBlock(AdderBlock("PlusOne"))
+        self.addConnection("IN1", "PlusOne")
+        self.addConnection("OneConstant", "PlusOne")
+        self.addConnection("PlusOne", "OUT1")
+
+class DerivatorBlock(CBD):
+    """
+    The derivator block is a CBD that calculates the derivative
+    """
+    def __init__(self, block_name):
+        CBD.__init__(self, block_name, ["IN1", "delta_t", "IC"], ["OUT1"])
+        self.addBlock(ProductBlock(block_name="multIc"))
+        self.addBlock(NegatorBlock(block_name="neg1"))
+        self.addBlock(AdderBlock(block_name="sum1"))
+        self.addBlock(DelayBlock(block_name="delay"))
+        self.addBlock(NegatorBlock(block_name="neg2"))
+        self.addBlock(AdderBlock(block_name="sum2"))
+        self.addBlock(ProductBlock(block_name="mult"))
+        self.addBlock(InverterBlock(block_name="inv"))
+        
+        self.addConnection("IC", "multIc")
+        self.addConnection("delta_t", "multIc")
+        self.addConnection("multIc", "neg1")
+        self.addConnection("neg1", "sum1")
+        self.addConnection("IN1", "sum1")
+        self.addConnection("sum1", "delay", input_port_name="IC")
+        self.addConnection("IN1", "delay", input_port_name="IN1")
+        self.addConnection("delay", "neg2")
+        self.addConnection("neg2", "sum2")
+        self.addConnection("IN1", "sum2")
+        self.addConnection("sum2", "mult")
+        self.addConnection("delta_t", "inv")
+        self.addConnection("inv", "mult")
+        self.addConnection("mult", "OUT1")
+        
+
+class IntegratorBlock(CBD):
+    """
+    The integrator block is a CBD that calculates the integration
+    """
+    def __init__(self, block_name):
+        CBD.__init__(self, block_name, ["IN1", "delta_t", "IC"], ["OUT1"])
+        self.addBlock(ConstantBlock(block_name="zero", value=0))
+        self.addBlock(DelayBlock(block_name="delayIn"))
+        self.addBlock(ProductBlock(block_name="multDelta"))
+        self.addBlock(DelayBlock(block_name="delayState"))
+        self.addBlock(AdderBlock(block_name="sumState"))
+        
+        self.addConnection("zero", "delayIn", input_port_name="IC")
+        self.addConnection("IN1", "delayIn", input_port_name="IN1")
+        self.addConnection("delayIn", "multDelta")
+        self.addConnection("delta_t", "multDelta")
+        self.addConnection("multDelta", "sumState")
+        self.addConnection("IC", "delayState", input_port_name="IC")
+        self.addConnection("delayState", "sumState")
+        self.addConnection("sumState", "delayState", input_port_name="IN1")
+        self.addConnection("sumState", "OUT1")
+        
+        
+
+""" This module implements a dependency graph
+    @author: Marc Provost
+    @organization: McGill University
+    @license: GNU General Public License
+    @contact: marc.provost@mail.mcgill.ca
+"""
+
+import copy
+class DepNode:
+    """ Class implementing a node in the dependency graph.
+    """
+
+    def __init__(self, object):
+        """ DepNode's constructor.
+                @param object: Reference to a semantic object identifying the node
+                @type object: Object
+        """
+        self.__object = object
+        self.__isMarked	 = False
+
+    def mark(self):
+        self.__isMarked = True
+
+    def unMark(self):
+        self.__isMarked = False
+
+    def isMarked(self):
+        return self.__isMarked
+
+    def getMappedObj(self):
+        return self.__object
+
+    def __repr__(self):
+        return "DepNode :: "+str(self.__object)
+
+class DepGraph:
+    """ Class implementing dependency graph.
+    """
+
+    def __init__(self):
+        """ DepGraph's constructor.
+        """
+        #Dict holding a mapping "Object -> DepNode"
+        self.__semanticMapping = {}
+
+        #map object->list of objects depending on object
+        self.__dependents = {}
+        #map object->list of objects that influences object
+        self.__influencers = {}
+
+    def __repr__(self):
+        repr = "Dependents: \n"
+        for dep in self.__dependents:
+            repr += dep.getBlockName() + ":" + str(self.__dependents[dep]) + "\n"
+        repr += "Influencers: \n"
+        for infl in self.__influencers:
+            repr += infl.getBlockName() + ":" + str(self.__influencers[infl]) + "\n"
+        return repr
+
+    def addMember(self, object):
+        """ Add an object mapped to this graph.
+                @param object: the object to be added
+                @type object: Object
+                @raise ValueError: If object is already in the graph
+        """
+        if not self.hasMember(object):
+            if not isinstance(object, CBD):
+                node = DepNode(object)
+                self.__dependents[object] = []
+                self.__influencers[object] = []
+                self.__semanticMapping[object] = node
+            else:
+                for block in object.getBlocks():
+                    self.addMember(block)
+        else:
+            raise ValueError("Specified object is already member of this graph")
+
+    def hasMember(self, object):
+        return self.__semanticMapping.has_key(object)
+
+    def removeMember(self, object):
+        """ Remove a object from this graph.
+                @param object: the object to be removed
+                @type object: Object
+                @raise ValueError: If object is not in the graph
+        """
+        if self.hasMember(object):
+            for dependent in self.getDependents(object):
+                self.__influencers[dependent].remove(object)
+            for influencer in self.getInfluencers(object):
+                self.__dependents[influencer].remove(object)
+
+            del self.__dependents[object]
+            del self.__influencers[object]
+            del self.__semanticMapping[object]
+        else:
+            raise ValueError("Specified object is not member of this graph")
+
+    def setDependency(self, dependent, influencer, curIt):
+        """
+            Creates a dependency between two objects.
+                @param dependent: The object which depends on the other
+                @param influcencer: The object which influences the other
+                @type dependent: Object
+                @type dependent: Object
+                @raise ValueError: if depedent or influencer is not member of this graph
+                @raise ValueError: if the dependency already exists
+        """
+
+        # Link CBD outputs
+        if isinstance(influencer, CBD):
+            # When there is more than one connection from a CBD to one and the same block,
+            # more than one dependency should be set, as there is more than one underlying
+            # output block
+            for output_port in [ y.output_port for (x,y) in dependent.getLinksIn().iteritems() if y.block == influencer ]:
+                self.setDependency(dependent, influencer.getBlockByName(output_port), curIt)
+            return
+
+        # Link CBD inputs
+        if isinstance(dependent, CBD):
+            cbd = dependent
+            directlyConnected = influencer.parent if isinstance(influencer, OutputPortBlock) else influencer
+            inputnames = dependent.getInputName(directlyConnected)
+
+            # When one influencer has multiple connections to this CBD, call this function once fo
+            for inputname in inputnames:
+                inputtingBlock = dependent.getBlockByName(inputname)
+                thisdep = inputtingBlock
+                self.setDependency(thisdep, influencer, curIt)
+            return
+
+        if self.hasMember(dependent) and self.hasMember(influencer):
+            if not influencer in self.__influencers[dependent] and\
+                 not dependent in self.__dependents[influencer]:
+                self.__influencers[dependent].append(influencer)
+                self.__dependents[influencer].append(dependent)
+        else:
+            if not self.hasMember(dependent):
+                raise ValueError("Specified dependent object is not member of this graph")
+            if not self.hasMember(influencer):
+                print(influencer)
+                raise ValueError("Specified influencer object is not member of this graph")
+
+    def hasDependency(self, dependent, influencer):
+        if self.hasMember(dependent) and self.hasMember(influencer):
+            return influencer in self.__influencers[dependent] and\
+                         dependent in self.__dependents[influencer]
+        else:
+            if not self.hasMember(dependent):
+                raise ValueError("Specified dependent object is not member of this graph")
+            if not self.hasMember(influencer):
+                raise ValueError("Specified influencer object is not member of this graph")
+
+    def unsetDependency(self, dependent, influencer):
+        """ Removes a dependency between two objects.
+                @param dependent: The object which depends on the other
+                @param influcencer: The object which influences the other
+                @type dependent: Object
+                @type dependent: Object
+                @raise ValueError: if depedent or influencer is not member of this graph
+                @raise ValueError: if the dependency does not exists
+        """
+        if self.hasMember(dependent) and self.hasMember(influencer):
+            if influencer in self.__influencers[dependent] and\
+                 dependent in self.__dependents[influencer]:
+                self.__influencers[dependent].remove(influencer)
+                self.__dependents[influencer].remove(dependent)
+            else:
+                raise ValueError("Specified dependency does not exists")
+        else:
+            if not self.hasMember(dependent):
+                raise ValueError("Specified dependent object is not member of this graph")
+            if not self.hasMember(influencer):
+                raise ValueError("Specified influencer object is not member of this graph")
+
+    def getDependents(self, object):
+        if self.hasMember(object):
+            return copy.copy(self.__dependents[object])
+        else:
+            raise ValueError("Specified object is not member of this graph")
+
+    def getInfluencers(self, object):
+        if self.hasMember(object):
+            return copy.copy(self.__influencers[object])
+        else:
+            raise ValueError("Specified object is not member of this graph")
+
+    def getStrongComponents(self, curIt = 1):
+        return self.__strongComponents(curIt)
+
+    def __getDepNode(self, object):
+        if self.hasMember(object):
+            return self.__semanticMapping[object]
+        else:
+            raise ValueError("Specified object is not a member of this graph")
+
+    def __mark(self, object):
+        self.__getDepNode(object).mark()
+
+    def __unMark(self, object):
+        self.__getDepNode(object).unMark()
+
+    def __isMarked(self, object):
+        return self.__getDepNode(object).isMarked()
+
+    def __topoSort(self):
+        """ Performs a topological sort on the graph.
+        """
+        for object in self.__semanticMapping.keys():
+            self.__unMark(object)
+
+        sortedList = []
+
+        for object in self.__semanticMapping.keys():
+            if not self.__isMarked(object):
+                self.__dfsSort(object, sortedList)
+
+        return sortedList
+
+    def __dfsSort(self, object, sortedList):
+        """ Performs a depth first search collecting
+                the objects in topological order.
+                @param object: the currently visited object.
+                @param sortedList: partial sorted list of objects
+                @type object: Object
+                @type sortedList: list Of Object
+        """
+
+        if not self.__isMarked(object):
+            self.__mark(object)
+
+            for influencer in self.getInfluencers(object):
+                self.__dfsSort(influencer, sortedList)
+
+            sortedList.append(object)
+
+    def __strongComponents(self, curIt):
+        """ Determine the strong components of the graph
+                @rtype: list of list of Object
+        """
+        strongComponents = []
+        sortedList = self.__topoSort()
+
+        for object in self.__semanticMapping.keys():
+            self.__unMark(object)
+
+        sortedList.reverse()
+
+        for object in sortedList:
+            if not self.__isMarked(object):
+                component = []
+                self.__dfsCollect(object, component, curIt)
+                strongComponents.append(component)
+
+        strongComponents.reverse()
+        return strongComponents
+
+    def __dfsCollect(self, object, component, curIt):
+        """ Collects objects member of a strong component.
+                @param object: Node currently visited
+                @param component: current component
+                @type object: Object
+                @type component: List of Object
+        """
+        if not self.__isMarked(object):
+            self.__mark(object)
+
+            for dependent in self.getDependents(object):
+                self.__dfsCollect(dependent, component, curIt)
+
+            component.append(object)
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 54 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/CBDDraw.py

@@ -0,0 +1,54 @@
+from CBD import *
+
+def draw(cbd, filename, colors=None):
+	""" Output cbd as a dot script to filename.
+
+	colors is a dictionary of blockname => color
+	"""
+	f = open(filename, "w")
+	write = lambda s: f.write(s)
+
+	write("""
+digraph graphname {
+ """)
+
+	if colors == None:
+		colors = {}
+
+	def writeBlock(block):
+		if isinstance(block, ConstantBlock):
+			label = block.getBlockType() + " (" + block.getBlockName() + ")\\n" + str(block.getValue())
+		else:
+			label = block.getBlockType() + " (" + block.getBlockName() + ")"
+
+		shape = ""
+		if isinstance(block, CBD):
+			shape=",shape=Msquare"
+
+		col = ""
+		if block.getBlockName() in colors:
+			col = ", color=\"{0}\", fontcolor=\"{0}\"".format(colors[block.getBlockName()])
+
+		write("{b} [label=\"{lbl}\"{shape}{col}];\n".format(b=block.getBlockName(),
+			lbl=label,
+			shape=shape,
+			col=col))
+
+
+	for block in cbd.getBlocks():
+		writeBlock(block)
+		for (name, other) in  block.getLinksIn().iteritems():
+			label = ""
+
+			if not name.startswith("IN"):
+				label=name
+
+			if not other.output_port.startswith("OUT"):
+				label = label + " / " + other.output_port
+
+			write("{a} -> {b} [label=\"{lbl}\"];\n".format(a=other.block.getBlockName(),
+				b=block.getBlockName(),
+				lbl=label))
+
+	write("\n}")
+

+ 0 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/__init__.py


+ 129 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/naivelog.py

@@ -0,0 +1,129 @@
+import os
+import sys
+import datetime
+(DEBUG, INFO, WARNING, ERROR, FATAL) = (0, 1, 2, 3, 4)
+
+def strToLevel(elvl):
+	if elvl == "DEBUG":
+		return DEBUG
+	if elvl == "INFO":
+		return INFO
+	if elvl == "WARNING":
+		return WARNING
+	if elvl == "ERROR":
+		return ERROR
+	if elvl == "FATAL":
+		return FATAL
+	else:
+		return None
+
+def levelToStr(lvl):
+	if lvl == DEBUG:
+		return "DEBUG"
+	if lvl == INFO:
+		return "INFO"
+	if lvl == WARNING:
+		return "WARNING"
+	if lvl == ERROR:
+		return "ERROR"
+	if lvl == FATAL:
+		return "FATAL"
+	return None
+
+
+def levelToShortStr(lvl):
+	if lvl == DEBUG:
+		return "DBUG"
+	if lvl == INFO:
+		return "INFO"
+	if lvl == WARNING:
+		return "WARN"
+	if lvl == ERROR:
+		return "ERROR"
+	if lvl == FATAL:
+		return "FATAL"
+	return None
+
+class Logger:
+	def __init__(self, modulename, level, crashlevel):
+		self.__modulename = modulename
+		self.__level = level
+		self.__crashlevel = crashlevel
+
+	def debug(self, mainstr, *args, **kwargs):
+		self.log(DEBUG, mainstr, *args, **kwargs)
+	def info(self, mainstr, *args, **kwargs):
+		self.log(INFO, mainstr, *args, **kwargs)
+	def warning(self, mainstr, *args, **kwargs):
+		self.log(WARNING, mainstr, *args, **kwargs)
+	def error(self, mainstr, *args, **kwargs):
+		self.log(ERROR, mainstr, *args, **kwargs)
+	def fatal(self, mainstr, *args, **kwargs):
+		self.log(FATAL, mainstr, *args, **kwargs)
+
+	def log(self, level, mainstr, *args, **kwargs):
+		if level >= self.__level:
+			sys.stdout.write(self.formatmsg(level,str(mainstr).format(*args, **kwargs)))
+
+		if level >= self.__crashlevel:
+			exit(1)
+
+	def setLevel(self, level):
+		self.__level = level
+
+	def formatmsg(self, level, mainstr):
+		class bcolors:
+			HEADER = '\033[95m'
+			OKBLUE = '\033[94m'
+			OKGREEN = '\033[92m'
+			WARNING = '\033[93m'
+			FAIL = '\033[91m'
+			ENDC = '\033[0m'
+	
+
+		col = bcolors.OKGREEN
+		if level >= WARNING:
+			col = bcolors.WARNING
+		if level >= ERROR:
+			col = bcolors.FAIL
+
+		return "{startcol}[{now:%H:%M:%S.%f} {module} {lvl}] {mainstr}{endcol}\n".format(
+				lvl=levelToShortStr(level),
+				module=self.__modulename,
+				now=datetime.datetime.today(),
+				mainstr=mainstr,
+				startcol=col,
+				endcol=bcolors.ENDC);
+
+defaultLogLevel = INFO
+defaultCrashLevel = FATAL
+
+def getAbstractLogLevel(env, default):
+	elvl = os.environ[env] if env in os.environ else ''
+
+	lvl = strToLevel(elvl)
+	if lvl:
+		return lvl
+	else:
+		return default
+
+def getLogLevel():
+	return getAbstractLogLevel('NAIVE_LOGLEVEL', defaultLogLevel)
+
+def getCrashLevel():
+	return getAbstractLogLevel('NAIVE_CRASHLEVEL', defaultCrashLevel)
+
+def getLogger(modulename):
+	return Logger(modulename, getLogLevel(), getCrashLevel())
+
+if __name__ == "__main__":
+	l = getLogger('testmodule')
+	l.info("bla");
+	l.info("test nummer {}{}", 2, " is good")
+	l.info("test {hier} is ook ok", hier=3, daar=4)
+	l.info("should not see this")
+
+
+	l2 = getLogger('testmodule.m2')
+	l2.info("More info")
+	l2.info("and even more")

+ 49 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Source/plot.py

@@ -0,0 +1,49 @@
+__author__ = 'joachimdenil'
+
+from math import ceil
+import matplotlib
+matplotlib.use('TkAgg')
+from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
+from matplotlib.figure import Figure
+from matplotlib.lines import Line2D
+import numpy as np
+import threading
+
+try:
+    import Tkinter as Tk
+except ImportError:
+    import tkinter as Tk
+
+class ScopeWindow():
+    def __init__(self, theOutportRefs, names):
+        """
+        Plot results in a Tk window using matlplotlib
+        @param theOutportRefs: array of values to plot: [[x1,x2,xn], ... ,[y1,y2, , yn]]
+        @param names: the labels for each of the plots: list [name1, name2, ...,  namen]
+        @return:
+        """
+        self.root = Tk.Tk()
+        self.f = Figure()
+        n = len(theOutportRefs)
+        n = int(ceil(n*1.00/2))
+        index = 1
+        self.ax = []
+        for outport in theOutportRefs:
+            self.ax.append(self.f.add_subplot(n, 2, index))
+            # add values:
+            self.ax[index-1].plot(outport, 'ro')
+            self.ax[index-1].set_xlabel('t')
+            self.ax[index-1].set_ylabel(names[index-1])
+            index+=1
+
+        self.canvas = FigureCanvasTkAgg(self.f, master=self.root)
+        self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
+        self.canvas.show()
+
+        self.toolbar = NavigationToolbar2TkAgg( self.canvas, self.root )
+        self.toolbar.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
+        self.toolbar.update()
+
+        self.button = Tk.Button(master=self.root, text='Quit', command=self.root.destroy)
+        self.button.pack(side=Tk.BOTTOM)
+        self.root.mainloop()

+ 48 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/CounterTest.py

@@ -0,0 +1,48 @@
+__author__ = 'joachimdenil'
+
+import unittest
+from CBDMultipleOutput.Source.CBD import *
+from CBDMultipleOutput.Source.plot import ScopeWindow
+from basicCBDTest import BasicCBDTestCase
+
+NUM_DISCR_TIME_STEPS = 10
+
+class FlattenCBDTest(unittest.TestCase):
+    def setUp(self):
+        self.CBD = CBD("block_under_test")
+
+    def _run(self, num_steps=1, step = 1):
+        self.CBD.run(num_steps, step)
+
+    def _getSignal(self, blockname, output_port = None):
+        foundBlocks = [ block for block in self.CBD.getBlocks() if block.getBlockName() == blockname ]
+        signal =  foundBlocks[0].getSignal(name_output = output_port)
+        if len(foundBlocks) == 1:
+            return [x.value for x in signal]
+        else:
+            raise Exception("No single block with name " + blockname + " found")
+
+    def testCounter(self):
+        self.CBD.addBlock(ConstantBlock(block_name="zero", value=0.0))
+        self.CBD.addBlock(DelayBlock(block_name="s"))
+        self.CBD.addConnection("zero", "s", input_port_name="IC")
+        self.CBD.addBlock(ConstantBlock(block_name="one", value=1.0))
+        self.CBD.addBlock(AdderBlock(block_name="plusOne"))
+        self.CBD.addConnection("one", "plusOne")
+        self.CBD.addConnection("s", "plusOne")
+        self.CBD.addConnection("plusOne", "s")
+
+        self._run(NUM_DISCR_TIME_STEPS)
+        ScopeWindow([self._getSignal("zero"), self._getSignal("one"), self._getSignal("s")],
+            ["zero", "one", "s"] )
+        self.assertEquals(self._getSignal("s"), [float(x) for x in range(NUM_DISCR_TIME_STEPS)])
+
+def suite():
+    """Returns a suite containing all the test cases in this module."""
+    suite1 = unittest.makeSuite(BasicCBDTestCase)
+
+    return unittest.TestSuite((suite1))
+
+if __name__ == '__main__':
+    # When this module is executed from the command-line, run all its tests
+    unittest.main()

+ 0 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/__init__.py


+ 551 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/basicCBDTest.py

@@ -0,0 +1,551 @@
+#!/usr/bin/env python
+#
+# Unit tests for all the basic CBD blocks, discrete-time CBD. 
+
+import unittest
+
+from CBDMultipleOutput.Source.CBD import *
+
+NUM_DISCR_TIME_STEPS = 5
+
+class BasicCBDTestCase(unittest.TestCase):
+  def setUp(self):
+    self.CBD = CBD("CBD_for_block_under_test")    
+    
+  def _run(self, num_steps=1, delta_t = 1.0):
+    self.CBD.run(num_steps, delta_t)      
+      
+  def _getSignal(self, blockname, output_port = None):
+    foundBlocks = [ block for block in self.CBD.getBlocks() if block.getBlockName() == blockname ]
+    numFoundBlocks = len(foundBlocks)  
+    if numFoundBlocks == 1:
+      signal =  foundBlocks[0].getSignal(name_output = output_port)
+      return [x.value for x in signal]
+    else:
+      raise Exception(str(numFoundBlocks) + " blocks with name " + blockname + " found.\nExpected a single block.")  
+  
+  def testConstantBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=3.3))
+
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("c1"), [3.3] * NUM_DISCR_TIME_STEPS)
+    
+  def testNegatorBlockPos(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=6.0))
+    self.CBD.addBlock(NegatorBlock(block_name="n"))
+    self.CBD.addConnection("c1", "n")
+
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("n"), [-6.0] * NUM_DISCR_TIME_STEPS)  
+  
+  def testNegatorBlockNeg(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=-6.0))
+    self.CBD.addBlock(NegatorBlock(block_name="n"))
+    self.CBD.addConnection("c1", "n")
+
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("n"), [6.0] * NUM_DISCR_TIME_STEPS)  
+    
+  def testNegatorBlockZero(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=0.0))
+    self.CBD.addBlock(NegatorBlock(block_name="n"))
+    self.CBD.addConnection("c1", "n")
+
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("n"), [0.0] * NUM_DISCR_TIME_STEPS)  
+    
+  def testInverterBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=5.0))
+    self.CBD.addBlock(InverterBlock(block_name="i1"))
+    self.CBD.addBlock(InverterBlock(block_name="i2"))
+
+    self.CBD.addConnection("c1", "i1")
+    self.CBD.addConnection("i1", "i2")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("i1"), [0.2] * NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("i2"), [5.0] * NUM_DISCR_TIME_STEPS)
+
+  def testAdderBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=2.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=6.0))
+    self.CBD.addBlock(AdderBlock(block_name="a"))
+    
+    self.CBD.addConnection("c1", "a")
+    self.CBD.addConnection("c2", "a")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("a"), [8.0] * NUM_DISCR_TIME_STEPS)
+    
+  def testAdderBlock2(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=2.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=-6.0))
+    self.CBD.addBlock(AdderBlock(block_name="a"))
+    
+    self.CBD.addConnection("c1", "a")
+    self.CBD.addConnection("c2", "a")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("a"), [-4.0] * NUM_DISCR_TIME_STEPS)    
+    
+  def testProductBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=2.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=5.0))
+    self.CBD.addBlock(ProductBlock(block_name="p"))
+    
+    self.CBD.addConnection("c1", "p")
+    self.CBD.addConnection("c2", "p")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("p"), [10.0] * 5)
+
+  def testProductBlock2(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=1.0/2.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=4.0))
+    self.CBD.addBlock(ProductBlock(block_name="p"))
+    
+    self.CBD.addConnection("c1", "p")
+    self.CBD.addConnection("c2", "p")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("p"), [2.0] * 5)
+    
+  def testGenericBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=2.2))
+    self.CBD.addBlock(GenericBlock(block_name="g", block_operator="ceil"))
+    
+    self.CBD.addConnection("c1", "g")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("g"), [3.0] * 5)  
+    
+  def testRootBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=8.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=3.0))
+    self.CBD.addBlock(RootBlock(block_name="g"))
+
+    self.CBD.addConnection("c1", "g")
+    self.CBD.addConnection("c2", "g")
+    self._run(1)
+    self.assertEquals(self._getSignal("g"), [2.0])
+        
+  def testRootBlock2(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=9.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=2.0))
+    self.CBD.addBlock(RootBlock(block_name="g"))
+
+    self.CBD.addConnection("c1", "g")
+    self.CBD.addConnection("c2", "g")
+    self._run(1)
+    self.assertEquals(self._getSignal("g"), [3.0])
+        
+  def testModuloBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=8.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=3.0))
+    self.CBD.addBlock(ModuloBlock(block_name="g"))
+
+    self.CBD.addConnection("c1", "g")
+    self.CBD.addConnection("c2", "g")
+    self._run(1)
+    self.assertEquals(self._getSignal("g"), [2.0])
+
+  def testModuloBlock2(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=8.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=8.0))
+    self.CBD.addBlock(ModuloBlock(block_name="g"))
+
+    self.CBD.addConnection("c1", "g")
+    self.CBD.addConnection("c2", "g")
+    self._run(1)
+    self.assertEquals(self._getSignal("g"), [0.0])
+
+  def testPreviousValueDelayBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="ZeroConstant", value=0.0))
+    self.CBD.addBlock(SequenceBlock(block_name="seq", sequence=[0, 2, 4, 6, 8, 10, 12]))
+    self.CBD.addBlock(DelayBlock(block_name="d"))
+    
+    self.CBD.addConnection("ZeroConstant", "d", input_port_name="IC")
+    self.CBD.addConnection("seq", "d")
+    
+    self._run(7, 0.5)
+    self.assertEquals(self._getSignal("d"), [0, 0, 2, 4, 6, 8, 10])    
+    
+  def testPreviousValueDelayBlock2(self):
+    self.CBD.addBlock(SequenceBlock(block_name="FirstSeq", sequence=[2, 12, 22, 23, 32, 11, 91]))
+    self.CBD.addBlock(SequenceBlock(block_name="SecSeq", sequence=[5, 5, 5, 5, 3, 3, 3]))
+    self.CBD.addBlock(DelayBlock(block_name="prev"))
+    self.CBD.addConnection(self.CBD.getBlockByName("FirstSeq"), "prev")
+    self.CBD.addConnection(self.CBD.getBlockByName("SecSeq"), "prev", input_port_name="IC")
+    self._run(7)  
+    self.assertEquals(self._getSignal("prev"), [5, 2, 12, 22, 23, 32, 11])    
+          
+  def testTimeBlock(self):
+    self.CBD.addBlock(TimeBlock(block_name="t"))
+    self._run(4)
+    self.assertEquals(self._getSignal("t"), [0.0, 1.0, 2.0, 3.0])
+
+  def testLessThanBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=6.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=-5.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c3", value=0))
+    self.CBD.addBlock(LessThanBlock(block_name="lt1"))
+    self.CBD.addBlock(LessThanBlock(block_name="lt2"))
+    self.CBD.addBlock(LessThanBlock(block_name="lt3"))
+    
+    self.CBD.addConnection("c1", "lt1")
+    self.CBD.addConnection("c1", "lt1", input_port_name="IC")
+    self.CBD.addConnection("c1", "lt2")
+    self.CBD.addConnection("c2", "lt2", input_port_name="IC")
+    self.CBD.addConnection("c2", "lt3")
+    self.CBD.addConnection("c3", "lt3", input_port_name="IC")
+
+    self._run(1)
+    self.assertEquals(self._getSignal("lt1"), [0.0])  
+    self.assertEquals(self._getSignal("lt2"), [0.0])  
+    self.assertEquals(self._getSignal("lt3"), [1.0])  
+    
+  def testEqualsBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=6.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=-5.0))
+    self.CBD.addBlock(EqualsBlock(block_name="eq1"))
+    self.CBD.addBlock(EqualsBlock(block_name="eq2"))
+    
+    self.CBD.addConnection("c1", "eq1")
+    self.CBD.addConnection("c1", "eq1", input_port_name="IC")
+    self.CBD.addConnection("c1", "eq2")
+    self.CBD.addConnection("c2", "eq2", input_port_name="IC")
+    
+    self._run(1)
+    self.assertEquals(self._getSignal("eq1"), [1.0])  
+    self.assertEquals(self._getSignal("eq2"), [0.0])  
+    
+  def testNotBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="One", value=1))
+    self.CBD.addBlock(NotBlock(block_name="NotBlock"))
+    self.CBD.addConnection("One", "NotBlock")      
+    self._run(1)
+    self.assertEquals(self._getSignal("NotBlock"), [0])    
+    
+  def testNotBlock2(self):
+    self.CBD.addBlock(ConstantBlock(block_name="Zero", value=0))
+    self.CBD.addBlock(NotBlock(block_name="NotBlock"))
+    self.CBD.addConnection("Zero", "NotBlock")      
+    self._run(1)      
+    self.assertEquals(self._getSignal("NotBlock"), [1])        
+    
+  def testOrBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="One", value=1))
+    self.CBD.addBlock(ConstantBlock(block_name="Zero", value=0))
+    self.CBD.addBlock(OrBlock(block_name="OrBlock1"))
+    self.CBD.addConnection("Zero", "OrBlock1")    
+    self.CBD.addConnection("Zero", "OrBlock1")  
+    
+    self.CBD.addBlock(OrBlock(block_name="OrBlock2"))
+    self.CBD.addConnection("One", "OrBlock2")    
+    self.CBD.addConnection("Zero", "OrBlock2")
+    
+    self.CBD.addBlock(OrBlock(block_name="OrBlock3"))    
+    self.CBD.addConnection("One", "OrBlock3")    
+    self.CBD.addConnection("One", "OrBlock3")
+    
+    self.CBD.addBlock(OrBlock(block_name="OrBlock4", numberOfInputs=4))
+    self.CBD.addConnection("Zero", "OrBlock4")    
+    self.CBD.addConnection("Zero", "OrBlock4")
+    self.CBD.addConnection("One", "OrBlock4")
+    self.CBD.addConnection("Zero", "OrBlock4")
+        
+    self._run(1)
+    self.assertEquals(self._getSignal("OrBlock1"), [0])      
+    self.assertEquals(self._getSignal("OrBlock2"), [1])      
+    self.assertEquals(self._getSignal("OrBlock3"), [1])      
+    self.assertEquals(self._getSignal("OrBlock4"), [1])      
+    
+  def testAndBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="One", value=1))
+    self.CBD.addBlock(ConstantBlock(block_name="Zero", value=0))
+    self.CBD.addBlock(AndBlock(block_name="AndBlock1"))
+    self.CBD.addConnection("Zero", "AndBlock1")    
+    self.CBD.addConnection("Zero", "AndBlock1")  
+    
+    self.CBD.addBlock(AndBlock(block_name="AndBlock2"))
+    self.CBD.addConnection("One", "AndBlock2")    
+    self.CBD.addConnection("Zero", "AndBlock2")
+    
+    self.CBD.addBlock(AndBlock(block_name="AndBlock3"))    
+    self.CBD.addConnection("One", "AndBlock3")    
+    self.CBD.addConnection("One", "AndBlock3")
+    
+    self.CBD.addBlock(AndBlock(block_name="AndBlock4"))    
+    self.CBD.addConnection("Zero", "AndBlock4")    
+    self.CBD.addConnection("One", "AndBlock4")
+    
+    self.CBD.addBlock(AndBlock(block_name="AndBlock5", numberOfInputs=4))
+    self.CBD.addConnection("Zero", "AndBlock5")    
+    self.CBD.addConnection("Zero", "AndBlock5")
+    self.CBD.addConnection("One", "AndBlock5")
+    self.CBD.addConnection("Zero", "AndBlock5")
+        
+    self._run(1)
+    self.assertEquals(self._getSignal("AndBlock1"), [0])      
+    self.assertEquals(self._getSignal("AndBlock2"), [0])      
+    self.assertEquals(self._getSignal("AndBlock3"), [1])      
+    self.assertEquals(self._getSignal("AndBlock4"), [0])      
+    self.assertEquals(self._getSignal("AndBlock5"), [0])      
+    
+  def testSequenceBlock(self):
+    self.CBD.addBlock(SequenceBlock(block_name="FirstSeq", sequence=[2, 2, 2, 3, 2, 1, 1]))
+    self._run(7)  
+    self.assertEquals(self._getSignal("FirstSeq"), [2, 2, 2, 3, 2, 1, 1])
+
+  def testLoggingBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="One", value=1))
+    self.CBD.addBlock(LoggingBlock("Test", "Logging block test with level is error", level.ERROR))
+    self.CBD.addConnection("One", "Test")
+    self._run(1)
+    
+
+  def testLinearStrongComponent(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=5.5))
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=-5))
+    self.CBD.addBlock(AdderBlock(block_name="a1"))
+    self.CBD.addBlock(AdderBlock(block_name="a3"))
+    self.CBD.addBlock(AdderBlock(block_name="a2"))
+
+    self.CBD.addConnection("a3", "a1")
+    self.CBD.addConnection("c1", "a1")
+    self.CBD.addConnection("a1", "a3")
+    self.CBD.addConnection("a2", "a3")
+    self.CBD.addConnection("c2", "a2")
+    self.CBD.addConnection("a3", "a2")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("a1"), [-5.5]*5)
+    self.assertEquals(self._getSignal("a2"), [5.0]*5)
+    self.assertEquals(self._getSignal("a3"), [-0.5]*5)
+    
+  def testLinearStrongComponentWithDelay(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=3.0))
+    self.CBD.addBlock(AdderBlock(block_name="sum"))
+    self.CBD.addBlock(DelayBlock(block_name="delay"))
+    self.CBD.addBlock(NegatorBlock(block_name="neg"))
+
+    self.CBD.addConnection("c1", "sum")
+    self.CBD.addConnection("neg", "sum")
+    self.CBD.addConnection("sum", "delay", input_port_name="IC")
+    self.CBD.addConnection("delay", "neg")
+    self.CBD.addConnection("neg", "delay")
+    
+    self._run(1)
+    self.assertEquals(self._getSignal("delay"), [1.5])
+    
+  def testLinearStrongComponentWithMult(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=3))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=5))
+    self.CBD.addBlock(AdderBlock(block_name="a"))
+    self.CBD.addBlock(ProductBlock(block_name="p"))
+
+    self.CBD.addConnection("c1", "a")
+    self.CBD.addConnection("p", "a")
+    self.CBD.addConnection("a", "p")
+    self.CBD.addConnection("c2", "p")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("a"), [-0.75]*5)
+    self.assertEquals(self._getSignal("p"), [-3.75]*5)
+    
+  def testLinearStrongComponentWithNeg(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=5))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=8))
+    self.CBD.addBlock(AdderBlock(block_name="a1"))
+    self.CBD.addBlock(AdderBlock(block_name="a2"))
+    self.CBD.addBlock(NegatorBlock(block_name="n"))
+
+    self.CBD.addConnection("c1", "a1")
+    self.CBD.addConnection("a2", "a1")
+    self.CBD.addConnection("c2", "a2")
+    self.CBD.addConnection("n", "a2")
+    self.CBD.addConnection("a1", "n")  
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("a1"), [6.5]*5)
+    self.assertEquals(self._getSignal("a2"), [1.5]*5)  
+    self.assertEquals(self._getSignal("n"), [-6.5]*5)  
+    
+  def testTwoLinearStrongComponent(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=3))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=2))
+    self.CBD.addBlock(ConstantBlock(block_name="c3", value=1.5))
+    self.CBD.addBlock(ConstantBlock(block_name="c4", value=1))
+    self.CBD.addBlock(AdderBlock(block_name="a1"))
+    self.CBD.addBlock(AdderBlock(block_name="a2"))
+    self.CBD.addBlock(AdderBlock(block_name="a3"))
+    self.CBD.addBlock(AdderBlock(block_name="a4"))
+    self.CBD.addBlock(AdderBlock(block_name="a5"))
+    self.CBD.addBlock(ProductBlock(block_name="p"))
+    self.CBD.addBlock(NegatorBlock(block_name="n1"))
+    self.CBD.addBlock(NegatorBlock(block_name="n2"))
+
+    self.CBD.addConnection("a3", "a1")
+    self.CBD.addConnection("c1", "a1")
+    self.CBD.addConnection("c2", "a2")
+    self.CBD.addConnection("a3", "a2")
+    self.CBD.addConnection("a1", "a3")
+    self.CBD.addConnection("a2", "a3")
+    self.CBD.addConnection("a3", "p")
+    self.CBD.addConnection("c3", "p")
+    self.CBD.addConnection("p", "n1")
+    self.CBD.addConnection("n1", "a4")
+    self.CBD.addConnection("a5", "a4")
+    self.CBD.addConnection("c4", "a5")
+    self.CBD.addConnection("n2", "a5")
+    self.CBD.addConnection("a4", "n2")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("a1"), [-2.0]*5)
+    self.assertEquals(self._getSignal("a2"), [-3.0]*5)
+    self.assertEquals(self._getSignal("a3"), [-5.0]*5)
+    self.assertEquals(self._getSignal("a4"), [4.25]*5)
+    self.assertEquals(self._getSignal("a5"), [-3.25]*5)
+    self.assertEquals(self._getSignal("p"), [-7.5]*5)
+    self.assertEquals(self._getSignal("n1"), [7.5]*5)
+    self.assertEquals(self._getSignal("n2"), [-4.25]*5)
+        
+  def testNonLinearStrongComponent(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=15))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=10))
+    self.CBD.addBlock(AdderBlock(block_name="a1"))
+    self.CBD.addBlock(AdderBlock(block_name="a2"))
+    self.CBD.addBlock(ProductBlock(block_name="p"))
+
+    self.CBD.addConnection("c2", "a1")
+    self.CBD.addConnection("p", "a1")
+    self.CBD.addConnection("a1", "p")
+    self.CBD.addConnection("a2", "p")
+    self.CBD.addConnection("p", "a2")
+    self.CBD.addConnection("c1", "a2")
+    self.assertRaises(SystemExit, self._run, 5)    
+    
+  def initializeFuncDerBas(self):
+    #f(t) = 5*t  
+    CBDFunc = CBD("function", output_ports = ["OUT1"])
+    CBDFunc.addBlock(TimeBlock(block_name="t"))
+    CBDFunc.addBlock(ProductBlock(block_name="p"))
+    CBDFunc.addBlock(ConstantBlock(block_name="c", value=5.0))
+    CBDFunc.addConnection("t", "p") 
+    CBDFunc.addConnection("c", "p")
+    CBDFunc.addConnection("p", "OUT1")
+    return CBDFunc      
+      
+  def initializeFunc(self):
+    #f(t) = (t-2)^3  
+    CBDFunc = CBD("function", output_ports = ["OUT1"])
+    CBDFunc.addBlock(TimeBlock(block_name="t"))
+    CBDFunc.addBlock(ProductBlock(block_name="p"))
+    CBDFunc.addBlock(ProductBlock(block_name="p2"))
+    CBDFunc.addBlock(AdderBlock(block_name="a"))
+    CBDFunc.addBlock(ConstantBlock(block_name="c", value=-2.0))
+    CBDFunc.addConnection("t", "a") 
+    CBDFunc.addConnection("c", "a")
+    CBDFunc.addConnection("a", "p")
+    CBDFunc.addConnection("a", "p")
+    CBDFunc.addConnection("p", "p2")
+    CBDFunc.addConnection("a", "p2")
+    CBDFunc.addConnection("p2", "OUT1")
+    return CBDFunc  
+      
+  def initializeFunc2(self):
+    #f(t) = (t-2)^4
+    CBDFunc = CBD("function", output_ports = ["OUT1"])
+    CBDFunc.addBlock(TimeBlock(block_name="t"))
+    CBDFunc.addBlock(ProductBlock(block_name="p"))
+    CBDFunc.addBlock(ProductBlock(block_name="p2"))
+    CBDFunc.addBlock(ProductBlock(block_name="p3"))
+    CBDFunc.addBlock(AdderBlock(block_name="a"))
+    CBDFunc.addBlock(ConstantBlock(block_name="c", value=-2.0))
+    CBDFunc.addConnection("t", "a") 
+    CBDFunc.addConnection("c", "a")
+    CBDFunc.addConnection("a", "p")
+    CBDFunc.addConnection("a", "p")
+    CBDFunc.addConnection("p", "p2")
+    CBDFunc.addConnection("a", "p2")
+    CBDFunc.addConnection("p2", "p3")
+    CBDFunc.addConnection("a", "p3")
+    CBDFunc.addConnection("p3", "OUT1")
+    return CBDFunc      
+  
+  def initializeFuncInt(self):
+    #f(t) = 2*t  
+    CBDFunc = CBD("function", output_ports = ["OUT1"])
+    CBDFunc.addBlock(TimeBlock(block_name="t"))
+    CBDFunc.addBlock(ProductBlock(block_name="p"))
+    CBDFunc.addBlock(ConstantBlock(block_name="c", value=2.0))
+    CBDFunc.addConnection("t", "p") 
+    CBDFunc.addConnection("c", "p")
+    CBDFunc.addConnection("p", "OUT1")
+    return CBDFunc  
+     
+  def testDerivatorBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c3", value=1.0))
+    self.CBD.addBlock(ConstantBlock(block_name="zero", value=0.0))
+    CBDFunc = self.initializeFuncDerBas()
+    self.CBD.addBlock(CBDFunc) 
+    self.CBD.addBlock(DerivatorBlock(block_name="der"))
+    
+    self.CBD.addConnection("c3", "der", input_port_name="delta_t")
+    self.CBD.addConnection("zero", "der", input_port_name="IC")
+    self.CBD.addConnection("function", "der")
+    self._run(5)
+    self.assertEquals(self._getSignal("der"), [0.0]+[5.0]*4)    
+
+            
+  def testIntegratorBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=6.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=0.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c3", value=0.001))
+    self.CBD.addBlock(AdderBlock(block_name="a"))
+    self.CBD.addBlock(DelayBlock(block_name="d"))
+    
+    self.CBD.addBlock(IntegratorBlock(block_name="int"))
+    self.CBD.addConnection("c3", "int", input_port_name="delta_t")
+    self.CBD.addConnection("a", "int")
+    self.CBD.addConnection("c2", "int", input_port_name="IC")
+    
+    self.CBD.addConnection("c1", "a")
+    self.CBD.addConnection("d", "a")
+    self.CBD.addConnection("a", "d")
+    self.CBD.addConnection("c2", "d", input_port_name="IC")
+    self._run(NUM_DISCR_TIME_STEPS)
+    self.assertEquals(self._getSignal("int"), [0.0, 0.006, 0.018000000000000002, 0.036000000000000004, 0.060000000000000005])
+  
+  def testDelayBlock(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=5.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=3.0))
+    self.CBD.addBlock(DelayBlock(block_name="d"))
+    
+    self.CBD.addConnection("c2", "d")
+    self.CBD.addConnection("c1", "d", input_port_name="IC")
+    self._run(4)
+    self.assertEquals(self._getSignal("d"), [5.0, 3.0, 3.0, 3.0])
+
+  def testDelayBlock2(self):
+    self.CBD.addBlock(ConstantBlock(block_name="c1", value=1.0))
+    self.CBD.addBlock(ConstantBlock(block_name="c2", value=5.0))
+    self.CBD.addBlock(DelayBlock(block_name="d"))
+    self.CBD.addBlock(AdderBlock(block_name="a"))
+
+    self.CBD.addConnection("c2", "a")
+    self.CBD.addConnection("d", "a")
+    self.CBD.addConnection("c1", "d", input_port_name="IC")
+    self.CBD.addConnection("a", "d")
+    self._run(5)
+    self.assertEquals(self._getSignal("d"), [1.0, 6.0, 11.0, 16.0, 21.0])
+      
+
+def suite():
+    """Returns a test suite containing all the test cases in this module."""
+    suite = unittest.makeSuite(BasicCBDTestCase)
+    
+    return unittest.TestSuite((suite))
+
+if __name__ == '__main__':
+    # When this module is executed from the command-line, run all its tests
+    unittest.main(verbosity=2)
+
+  
+  
+  
+  
+  
+  
+  
+  

+ 201 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/flattenCBDTest.py

@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+#
+# Unit tests for the flatten function on the CBD
+
+import unittest
+from CBDMultipleOutput.Source.CBD import *
+from basicCBDTest import BasicCBDTestCase
+
+class FlattenCBDTest(unittest.TestCase):
+	def setUp(self):
+		self.CBD = CBD("block_under_test")		
+		
+	def _run(self, num_steps=1, step = 1):
+		self.CBD.run(num_steps, step)			
+			
+	def _getSignal(self, blockname, output_port = None):
+		foundBlocks = [ block for block in self.CBD.getBlocks() if block.getBlockName() == blockname ]
+		
+		signal =  foundBlocks[0].getSignal(name_output = output_port)
+		
+		if len(foundBlocks) == 1:
+			return [x.value for x in signal]
+		else:
+			raise Exception("No single block with name " + blockname + " found")
+							
+	def testInterCBD(self):
+		CBDLittle1 = CBD("first_child", output_ports = ["outCBD1"])
+		CBDLittle2 = CBD("second_child", input_ports = ["inCBD2"])
+		
+		self.CBD.addBlock(CBDLittle1)
+		self.CBD.addBlock(CBDLittle2)
+		self.CBD.addConnection("first_child", "second_child", input_port_name = "inCBD2", output_port_name = "outCBD1") 
+
+		CBDLittle1.addBlock(ConstantBlock(block_name="c1", value=2.0))
+		CBDLittle1.addConnection("c1", "outCBD1")
+		
+		self.CBD.flatten()
+		self._run(5)
+		self.assertEquals(self._getSignal("second_child.inCBD2"), [2.0]*5)
+
+		
+	def testLinearStrongComponentWithMult(self):
+		CBDConstant1 = CBD("constantCBD1", output_ports = ["outConstant1"])
+		CBDConstant1.addBlock(ConstantBlock(block_name="c", value=3))
+		CBDConstant1.addConnection("c", "outConstant1")
+		
+		CBDConstant2 = CBD("constantCBD2", output_ports = ["outConstant2"])
+		CBDConstant2.addBlock(ConstantBlock(block_name="c", value=5))
+		CBDConstant2.addConnection("c", "outConstant2")
+		
+		CBDAdder = CBD("adderCBD", input_ports = ["in1Add", "in2Add"], output_ports = ["outAdd"])
+		CBDAdder.addBlock(AdderBlock(block_name="a"))
+		CBDAdder.addConnection("in1Add", "a")
+		CBDAdder.addConnection("in2Add", "a")
+		CBDAdder.addConnection("a", "outAdd")
+		
+		CBDProduct = CBD("productCBD", input_ports = ["in1Prod", "in2Prod"], output_ports = ["outProd"])
+		CBDProduct.addBlock(ProductBlock(block_name="p"))
+		CBDProduct.addConnection("in1Prod", "p")
+		CBDProduct.addConnection("in2Prod", "p")
+		CBDProduct.addConnection("p", "outProd")
+		
+		self.CBD.addBlock(CBDConstant1)
+		self.CBD.addBlock(CBDConstant2)
+		self.CBD.addBlock(CBDAdder)
+		self.CBD.addBlock(CBDProduct)
+		self.CBD.addConnection("constantCBD1", "adderCBD", input_port_name="in1Add", output_port_name = "outConstant1")
+		self.CBD.addConnection("productCBD", "adderCBD", input_port_name="in2Add", output_port_name = "outProd")
+		self.CBD.addConnection("adderCBD", "productCBD", input_port_name="in1Prod", output_port_name = "outAdd")
+		self.CBD.addConnection("constantCBD2", "productCBD", input_port_name="in2Prod", output_port_name = "outConstant2")
+			
+		self.CBD.flatten()
+		self._run(5)
+		self.assertEquals(self._getSignal("adderCBD.outAdd"), [-0.75]*5)
+		self.assertEquals(self._getSignal("productCBD.outProd"), [-3.75]*5)
+		
+	def testLinearStrongComponentWithNeg(self):
+		CBDConstant1 = CBD("constantCBD1", output_ports = ["outConstant1"])
+		CBDConstant1.addBlock(ConstantBlock(block_name="c", value=5))
+		CBDConstant1.addConnection("c", "outConstant1")
+		
+		CBDConstant2 = CBD("constantCBD2", output_ports = ["outConstant2"])
+		CBDConstant2.addBlock(ConstantBlock(block_name="c", value=8))
+		CBDConstant2.addConnection("c", "outConstant2")
+		
+		CBDAdder1 = CBD("adder1CBD", input_ports = ["in1Add1", "in2Add1"], output_ports = ["outAdd1"])
+		CBDAdder1.addBlock(AdderBlock(block_name="a"))
+		CBDAdder1.addConnection("in1Add1", "a")
+		CBDAdder1.addConnection("in2Add1", "a")
+		CBDAdder1.addConnection("a", "outAdd1")
+		
+		CBDAdder2 = CBD("adder2CBD", input_ports = ["in1Add2", "in2Add2"], output_ports = ["outAdd2"])
+		CBDAdder2.addBlock(AdderBlock(block_name="a"))
+		CBDAdder2.addConnection("in1Add2", "a")
+		CBDAdder2.addConnection("in2Add2", "a")
+		CBDAdder2.addConnection("a", "outAdd2")
+		
+		CBDNegator = CBD("negatorCBD", input_ports = ["inNeg"], output_ports = ["outNeg"])
+		CBDNegator.addBlock(NegatorBlock(block_name="n"))
+		CBDNegator.addConnection("inNeg", "n")
+		CBDNegator.addConnection("n", "outNeg")
+		
+		self.CBD.addBlock(CBDConstant1)
+		self.CBD.addBlock(CBDConstant2)
+		self.CBD.addBlock(CBDAdder1)
+		self.CBD.addBlock(CBDAdder2)
+		self.CBD.addBlock(CBDNegator)
+		self.CBD.addConnection("constantCBD1", "adder1CBD", input_port_name="in1Add1", output_port_name = "outConstant1")
+		self.CBD.addConnection("adder2CBD", "adder1CBD", input_port_name="in2Add1", output_port_name = "outAdd2")
+		self.CBD.addConnection("constantCBD2", "adder2CBD", input_port_name="in1Add2", output_port_name = "outConstant2")
+		self.CBD.addConnection("negatorCBD", "adder2CBD", input_port_name="in2Add2", output_port_name = "outNeg")
+		self.CBD.addConnection("adder1CBD", "negatorCBD", input_port_name="inNeg", output_port_name = "outAdd1")
+		
+		self.CBD.flatten()
+		self._run(5)
+		self.assertEquals(self._getSignal("adder1CBD.outAdd1"), [6.5]*5)
+		self.assertEquals(self._getSignal("adder2CBD.outAdd2"), [1.5]*5)	
+		self.assertEquals(self._getSignal("negatorCBD.outNeg"), [-6.5]*5)		
+		
+	def testInterInterCBD(self):
+		"""
+							  +--------------------------------------------+
+				   +----+     |                    +------+                |
+				   |    |+--->|+------------------>|      |                |
+				   |  2 |     ||                   |  +   +--------------->+-------+
+		+----+     +----+     || +---------+   +-->|      |                |       |
+		|    |                |+>|         |   |   +------+                |       v
+		| 5  |   +------+     |  |         |   |                           |    +------+
+		+----++->|      |     |  |    *    |   |                           |    |      |
+				 |  +   |     |  |         |   |                           |    |  +   +------> 0
+		+----++->|      |+--->|+>|         |   |                           |    |      |
+		| 2  |   +------+     |  +--+------+   +--------------+            |    +------+
+		|    |                |     |                         |   +-----+  |       ^
+		+----+                |     |   +--------------------+|   |     |  |       |
+							  |     |   |     +-----+        ||   | 12  +->+-------+
+							  |     |   |     |     |        ||   |     |  |
+							  |     +-->+---->|  -  +------->++   +-----+  |
+							  |         |     |     |        |             |
+							  |         |     +-----+        |             |
+							  |         +--------------------+             |
+							  +--------------------------------------------+
+		"""		  
+		CBDLittle1 = CBD("first_child", input_ports = ["in1CBD1", "in2CBD1"], output_ports = ["out1CBD1", "out2CBD1"])
+		CBDLittle2 = CBD("first_child_of_first_child", input_ports = ["inCBD2"], output_ports = ["outCBD2"])
+		
+		self.CBD.addBlock(ConstantBlock(block_name="c1", value=2.0))
+		self.CBD.addBlock(ConstantBlock(block_name="c2", value=5.0))
+		self.CBD.addBlock(ConstantBlock(block_name="c3", value=2.0))
+		self.CBD.addBlock(AdderBlock(block_name="a"))
+		self.CBD.addBlock(AdderBlock(block_name="a2"))
+		self.CBD.addBlock(CBDLittle1)
+		self.CBD.addConnection("c3", "a")
+		self.CBD.addConnection("c2", "a")
+		self.CBD.addConnection("c1", "first_child", input_port_name = "in1CBD1")
+		self.CBD.addConnection("a", "first_child", input_port_name = "in2CBD1")
+		self.CBD.addConnection("first_child", "a2", output_port_name = "out1CBD1")
+		self.CBD.addConnection("first_child", "a2", output_port_name = "out2CBD1")
+				
+		CBDLittle1.addBlock(ProductBlock(block_name="p"))
+		CBDLittle1.addBlock(AdderBlock(block_name="a"))
+		CBDLittle1.addBlock(CBDLittle2)
+		CBDLittle1.addBlock(ConstantBlock(block_name="c", value=12.0))
+		CBDLittle1.addConnection("in1CBD1", "p")
+		CBDLittle1.addConnection("in2CBD1", "p")
+		CBDLittle1.addConnection("in1CBD1", "a")
+		CBDLittle1.addConnection("first_child_of_first_child", "a", output_port_name = "outCBD2")
+		CBDLittle1.addConnection("p", "first_child_of_first_child", input_port_name = "inCBD2")
+		CBDLittle1.addConnection("c", "out1CBD1")
+		CBDLittle1.addConnection("a", "out2CBD1")
+		
+		CBDLittle2.addBlock(NegatorBlock(block_name="n"))
+		CBDLittle2.addConnection("inCBD2", "n")
+		CBDLittle2.addConnection("n", "outCBD2")
+		
+		self.CBD.flatten()
+		self._run(5)		
+		self.assertEquals(self._getSignal("first_child.p"), [14.0]*5)
+		self.assertEquals(self._getSignal("first_child.first_child_of_first_child.n"), [-14.0]*5)
+		self.assertEquals(self._getSignal("first_child.in1CBD1"), [2.0]*5)
+		self.assertEquals(self._getSignal("first_child.a"), [-12.0]*5)		
+		self.assertEquals(self._getSignal("a2"), [0.0]*5)
+		
+		
+def suite():
+    """Returns a suite containing all the test cases in this module."""
+    suite1 = unittest.makeSuite(BasicCBDTestCase)
+    
+    return unittest.TestSuite((suite1))
+
+if __name__ == '__main__':
+    # When this module is executed from the command-line, run all its tests
+    unittest.main()
+
+	
+	
+	
+	
+	
+	
+	
+	

+ 201 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/hierarchyCBDTest.py

@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+#
+# Unit tests for the hierarchy functionality of the CBD
+
+import unittest
+from CBDMultipleOutput.Source.CBD import *
+from basicCBDTest import BasicCBDTestCase
+
+class HierarchyCBDTest(unittest.TestCase):
+	def setUp(self):
+		self.CBD = CBD("block_under_test")		
+		
+	def _run(self, num_steps=1, step = 1):
+		self.CBD.run(num_steps, step)			
+			
+	def _getSignal(self, blockname, output_port = None):
+		foundBlocks = [ block for block in self.CBD.getBlocks() if block.getBlockName() == blockname ]
+		
+		signal =  foundBlocks[0].getSignal(name_output = output_port)
+		
+		if len(foundBlocks) == 1:
+			return [x.value for x in signal]
+		else:
+			raise Exception("No single block with name " + blockname + " found")			
+		
+	def testInterCBD(self):		
+		CBDLittle1 = CBD("first_child", output_ports = ["outCBD1"])
+		CBDLittle1.addBlock(ConstantBlock(block_name="c1", value=2.0))
+		CBDLittle1.addConnection("c1", "outCBD1")
+		
+		CBDLittle2 = CBD("second_child", input_ports = ["inCBD2"], output_ports = ["outCBD2"])
+		CBDLittle2.addBlock(NegatorBlock(block_name="n"))
+		CBDLittle2.addConnection("inCBD2", "n")
+		CBDLittle2.addConnection("n", "outCBD2")
+		
+		self.CBD.addBlock(CBDLittle1)
+		self.CBD.addBlock(CBDLittle2)
+		neg = NegatorBlock(block_name="n")
+		self.CBD.addBlock(neg)
+		self.CBD.addConnection("first_child", "second_child", input_port_name = "inCBD2", output_port_name = "outCBD1") 
+		self.CBD.addConnection("second_child", "n", output_port_name = "outCBD2") 
+
+		self._run(5)
+		self.assertEquals(self._getSignal("n"), [2.0]*5)
+
+		
+	def testLinearStrongComponentWithMult(self):
+		CBDConstant1 = CBD("constantCBD1", output_ports = ["outConstant1"])
+		CBDConstant1.addBlock(ConstantBlock(block_name="c", value=3))
+		CBDConstant1.addConnection("c", "outConstant1")
+		
+		CBDConstant2 = CBD("constantCBD2", output_ports = ["outConstant2"])
+		CBDConstant2.addBlock(ConstantBlock(block_name="c", value=5))
+		CBDConstant2.addConnection("c", "outConstant2")
+		
+		CBDAdder = CBD("adderCBD", input_ports = ["in1Add", "in2Add"], output_ports = ["outAdd"])
+		CBDAdder.addBlock(AdderBlock(block_name="a"))
+		CBDAdder.addConnection("in1Add", "a")
+		CBDAdder.addConnection("in2Add", "a")
+		CBDAdder.addConnection("a", "outAdd")
+		
+		CBDProduct = CBD("productCBD", input_ports = ["in1Prod", "in2Prod"], output_ports = ["outProd"])
+		CBDProduct.addBlock(ProductBlock(block_name="p"))
+		CBDProduct.addConnection("in1Prod", "p")
+		CBDProduct.addConnection("in2Prod", "p")
+		CBDProduct.addConnection("p", "outProd")
+		
+		self.CBD.addBlock(CBDConstant1)
+		self.CBD.addBlock(CBDConstant2)
+		self.CBD.addBlock(CBDAdder)
+		self.CBD.addBlock(CBDProduct)
+		self.CBD.addConnection("constantCBD1", "adderCBD", input_port_name="in1Add", output_port_name = "outConstant1")
+		self.CBD.addConnection("productCBD", "adderCBD", input_port_name="in2Add", output_port_name = "outProd")
+		self.CBD.addConnection("adderCBD", "productCBD", input_port_name="in1Prod", output_port_name = "outAdd")
+		self.CBD.addConnection("constantCBD2", "productCBD", input_port_name="in2Prod", output_port_name = "outConstant2")
+
+		self._run(5)
+		self.assertEquals(self._getSignal("adderCBD", output_port = "outAdd"), [-0.75]*5)
+		self.assertEquals(self._getSignal("productCBD", output_port = "outProd"), [-3.75]*5)	
+		
+	def testLinearStrongComponentWithNeg(self):
+		CBDConstant1 = CBD("constantCBD1", output_ports = ["outConstant1"])
+		CBDConstant1.addBlock(ConstantBlock(block_name="c", value=5))
+		CBDConstant1.addConnection("c", "outConstant1")
+		
+		CBDConstant2 = CBD("constantCBD2", output_ports = ["outConstant2"])
+		CBDConstant2.addBlock(ConstantBlock(block_name="c", value=8))
+		CBDConstant2.addConnection("c", "outConstant2")
+		
+		CBDAdder1 = CBD("adder1CBD", input_ports = ["in1Add1", "in2Add1"], output_ports = ["outAdd1"])
+		CBDAdder1.addBlock(AdderBlock(block_name="a"))
+		CBDAdder1.addConnection("in1Add1", "a")
+		CBDAdder1.addConnection("in2Add1", "a")
+		CBDAdder1.addConnection("a", "outAdd1")
+		
+		CBDAdder2 = CBD("adder2CBD", input_ports = ["in1Add2", "in2Add2"], output_ports = ["outAdd2"])
+		CBDAdder2.addBlock(AdderBlock(block_name="a"))
+		CBDAdder2.addConnection("in1Add2", "a")
+		CBDAdder2.addConnection("in2Add2", "a")
+		CBDAdder2.addConnection("a", "outAdd2")
+		
+		CBDNegator = CBD("negatorCBD", input_ports = ["inNeg"], output_ports = ["outNeg"])
+		CBDNegator.addBlock(NegatorBlock(block_name="n"))
+		CBDNegator.addConnection("inNeg", "n")
+		CBDNegator.addConnection("n", "outNeg")
+		
+		self.CBD.addBlock(CBDConstant1)
+		self.CBD.addBlock(CBDConstant2)
+		self.CBD.addBlock(CBDAdder1)
+		self.CBD.addBlock(CBDAdder2)
+		self.CBD.addBlock(CBDNegator)
+		self.CBD.addConnection("constantCBD1", "adder1CBD", input_port_name="in1Add1", output_port_name = "outConstant1")
+		self.CBD.addConnection("adder2CBD", "adder1CBD", input_port_name="in2Add1", output_port_name = "outAdd2")
+		self.CBD.addConnection("constantCBD2", "adder2CBD", input_port_name="in1Add2", output_port_name = "outConstant2")
+		self.CBD.addConnection("negatorCBD", "adder2CBD", input_port_name="in2Add2", output_port_name = "outNeg")
+		self.CBD.addConnection("adder1CBD", "negatorCBD", input_port_name="inNeg", output_port_name = "outAdd1")
+
+		self._run(5)
+		self.assertEquals(self._getSignal("adder1CBD", output_port = "outAdd1"), [6.5]*5)
+		self.assertEquals(self._getSignal("adder2CBD", output_port = "outAdd2"), [1.5]*5)	
+		self.assertEquals(self._getSignal("negatorCBD", output_port = "outNeg"), [-6.5]*5)	
+		
+	def testInterInterCBD(self):
+		"""
+							  +--------------------------------------------+
+				   +----+     |                    +------+                |
+				   |    |+--->|+------------------>|      |                |
+				   |  2 |     ||                   |  +   +--------------->+-------+
+		+----+     +----+     || +---------+   +-->|      |                |       |
+		|    |                |+>|         |   |   +------+                |       v
+		| 5  |   +------+     |  |         |   |                           |    +------+
+		+----++->|      |     |  |    *    |   |                           |    |      |
+				 |  +   |     |  |         |   |                           |    |  +   +------> 0
+		+----++->|      |+--->|+>|         |   |                           |    |      |
+		| 2  |   +------+     |  +--+------+   +--------------+            |    +------+
+		|    |                |     |                         |   +-----+  |       ^
+		+----+                |     |   +--------------------+|   |     |  |       |
+							  |     |   |     +-----+        ||   | 12  +->+-------+
+							  |     |   |     |     |        ||   |     |  |
+							  |     +-->+---->|  -  +------->++   +-----+  |
+							  |         |     |     |        |             |
+							  |         |     +-----+        |             |
+							  |         +--------------------+             |
+							  +--------------------------------------------+
+		"""		  
+		CBDLittle1 = CBD("first_child", input_ports = ["in1CBD1", "in2CBD1"], output_ports = ["out1CBD1", "out2CBD1"])
+		CBDLittle2 = CBD("first_child_of_first_child", input_ports = ["inCBD2"], output_ports = ["outCBD2"])
+		
+		self.CBD.addBlock(ConstantBlock(block_name="c1", value=2.0))
+		self.CBD.addBlock(ConstantBlock(block_name="c2", value=5.0))
+		self.CBD.addBlock(ConstantBlock(block_name="c3", value=2.0))
+		self.CBD.addBlock(AdderBlock(block_name="a"))
+		self.CBD.addBlock(AdderBlock(block_name="a2"))
+		self.CBD.addBlock(CBDLittle1)
+		self.CBD.addConnection("c3", "a")
+		self.CBD.addConnection("c2", "a")
+		self.CBD.addConnection("c1", "first_child", input_port_name = "in1CBD1")
+		self.CBD.addConnection("a", "first_child", input_port_name = "in2CBD1")
+		self.CBD.addConnection("first_child", "a2", output_port_name = "out1CBD1")
+		self.CBD.addConnection("first_child", "a2", output_port_name = "out2CBD1")
+				
+		CBDLittle1.addBlock(ProductBlock(block_name="p"))
+		CBDLittle1.addBlock(AdderBlock(block_name="a"))
+		CBDLittle1.addBlock(CBDLittle2)
+		CBDLittle1.addBlock(ConstantBlock(block_name="c", value=12.0))
+		CBDLittle1.addConnection("in1CBD1", "p")
+		CBDLittle1.addConnection("in2CBD1", "p")
+		CBDLittle1.addConnection("in1CBD1", "a")
+		CBDLittle1.addConnection("first_child_of_first_child", "a", output_port_name = "outCBD2")
+		CBDLittle1.addConnection("p", "first_child_of_first_child", input_port_name = "inCBD2")
+		CBDLittle1.addConnection("c", "out1CBD1")
+		CBDLittle1.addConnection("a", "out2CBD1")
+		
+		CBDLittle2.addBlock(NegatorBlock(block_name="n"))
+		CBDLittle2.addConnection("inCBD2", "n")
+		CBDLittle2.addConnection("n", "outCBD2")
+		
+		self._run(5)		
+		self.assertEquals(self._getSignal("first_child", output_port = "p"), [14.0]*5)
+		self.assertEquals(self._getSignal("first_child", output_port = "in1CBD1"), [2.0]*5)
+		self.assertEquals(self._getSignal("first_child", output_port = "a"), [-12.0]*5)		
+		self.assertEquals(self._getSignal("a2"), [0.0]*5)	
+		
+def suite():
+    """Returns a suite containing all the test cases in this module."""
+    suite1 = unittest.makeSuite(BasicCBDTestCase)
+    
+    return unittest.TestSuite((suite1))
+
+if __name__ == '__main__':
+    # When this module is executed from the command-line, run all its tests
+    unittest.main()
+
+	
+	
+	
+	
+	
+	
+	
+	

+ 172 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/Test/sortedGraphCBDTest.py

@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+#
+# Unit tests for the sorting of a CBD.
+
+import unittest
+from CBDMultipleOutput.Source.CBD import *
+from basicCBDTest import BasicCBDTestCase
+
+class SortedGraphCBDTest(unittest.TestCase):
+	def setUp(self):
+		self.CBD = CBD("block_under_test")		
+		
+	def _run(self, num_steps=1):
+		self.CBD.run(num_steps)			
+	
+	def testSortedGraph(self):
+		CBDNegator = CBD("negatorCBD", input_ports = ["inNegator"], output_ports = ["outNegator"])
+		negCbd = NegatorBlock(block_name="nC")
+		CBDNegator.addBlock(negCbd)
+		CBDNegator.addConnection("inNegator", "nC")	
+		CBDNegator.addConnection("nC", "outNegator")	
+		
+		const = ConstantBlock(block_name="c", value=5.5)
+		self.CBD.addBlock(const)
+		neg = NegatorBlock(block_name="n")
+		self.CBD.addBlock(neg)
+		self.CBD.addBlock(CBDNegator)
+		self.CBD.addConnection("negatorCBD", "n", output_port_name = "outNegator")
+		self.CBD.addConnection("c", "negatorCBD", input_port_name = "inNegator")
+		
+		depGraph = self.CBD._CBD__createDepGraph(0)
+		sortedGraph = depGraph.getStrongComponents()
+		
+		self.assertEquals(len(sortedGraph), 5)
+		self.assertEquals(sortedGraph[0][0], const)
+		self.assertEquals(sortedGraph[2][0], negCbd)
+		self.assertEquals(sortedGraph[4][0], neg)
+		
+	def testSortedGraph2(self):
+		CBDAdder = CBD("adderCBD", input_ports = ["in1", "in2"], output_ports = ["outAdd"])
+		addCBD = AdderBlock(block_name="aC")
+		CBDAdder.addBlock(addCBD)
+		CBDAdder.addConnection("in1", "aC")	
+		CBDAdder.addConnection("in2", "aC")	
+		CBDAdder.addConnection("aC", "outAdd")	
+		
+		const1 = ConstantBlock(block_name="c1", value=5.5)
+		const2 = ConstantBlock(block_name="c2", value=4.5)
+		self.CBD.addBlock(const1)
+		self.CBD.addBlock(const2)
+		neg = NegatorBlock(block_name="n")
+		self.CBD.addBlock(neg)
+		self.CBD.addBlock(CBDAdder)
+		self.CBD.addConnection("adderCBD", "n", output_port_name = "outAdd")
+		self.CBD.addConnection("c1", "adderCBD", input_port_name = "in1")
+		self.CBD.addConnection("c2", "adderCBD", input_port_name = "in2")
+		
+		depGraph = self.CBD._CBD__createDepGraph(0)
+		sortedGraph = depGraph.getStrongComponents()
+		comps = [ x[0] for x in sortedGraph ]
+		
+		tester = self
+		ag = lambda x,y: tester.assertTrue(comps.index(x) > comps.index(y))
+		
+		self.assertEquals(len(sortedGraph), 7)
+		ag(addCBD, const1)
+		ag(addCBD, const2)
+		ag(neg, addCBD)
+		
+	def testSortedGraph3(self):	
+		CBDNegator = CBD("negatorCBD", input_ports = ["inNegator"], output_ports = ["outNegator", "outInverter"])
+		negCbd = NegatorBlock(block_name="nC")
+		invCBD = InverterBlock(block_name="iC")
+		CBDNegator.addBlock(negCbd)
+		CBDNegator.addBlock(invCBD)
+		CBDNegator.addConnection("inNegator", "nC")	
+		CBDNegator.addConnection("inNegator", "iC")	
+		CBDNegator.addConnection("nC", "outNegator")	
+		CBDNegator.addConnection("iC", "outInverter")	
+		
+		const = ConstantBlock(block_name="c", value=5.5)
+		self.CBD.addBlock(const)
+		add = AdderBlock(block_name="a")
+		self.CBD.addBlock(add)
+		self.CBD.addBlock(CBDNegator)
+		self.CBD.addConnection("negatorCBD", "a", output_port_name = "outNegator")
+		self.CBD.addConnection("negatorCBD", "a", output_port_name = "outInverter")
+		self.CBD.addConnection("c", "negatorCBD", input_port_name = "inNegator")
+		
+		depGraph = self.CBD._CBD__createDepGraph(0)
+		sortedGraph = depGraph.getStrongComponents()
+		comps = [ x[0] for x in sortedGraph ]
+		
+		tester = self
+		ag = lambda x,y: tester.assertTrue(comps.index(x) > comps.index(y))
+
+		self.assertEquals(len(sortedGraph), 7)
+		ag(negCbd, const)
+		ag(invCBD, const)
+		ag(add, negCbd)
+		ag(add, invCBD)
+		
+	def testSortedGraph4(self):
+		CBDStrong = CBD("strongCBD", input_ports = ["inC1", "inC2"], output_ports = [])
+		CBDStrong.addBlock(AdderBlock(block_name="a1"))
+		CBDStrong.addBlock(AdderBlock(block_name="a3"))
+		CBDStrong.addBlock(AdderBlock(block_name="a2"))
+		CBDStrong.addConnection("a3", "a1")		
+		CBDStrong.addConnection("a1", "a3")
+		CBDStrong.addConnection("a2", "a3")
+		CBDStrong.addConnection("inC1", "a1")
+		CBDStrong.addConnection("inC2", "a2")
+		CBDStrong.addConnection("a3", "a2")
+		
+		self.CBD.addBlock(CBDStrong)
+		self.CBD.addBlock(ConstantBlock(block_name="c2", value=5.5))
+		self.CBD.addBlock(ConstantBlock(block_name="c1", value=-5))
+		self.CBD.addConnection("c1", "strongCBD", input_port_name = "inC1")
+		self.CBD.addConnection("c2", "strongCBD", input_port_name = "inC2")
+		
+		depGraph = self.CBD._CBD__createDepGraph(0)
+		sortedGraph = depGraph.getStrongComponents()
+				
+		self.assertEquals(len(sortedGraph), 5)
+		self.assertEquals(len(sortedGraph[4]), 3)
+		
+	def testSortedGraph5(self):
+		CBDStrong = CBD("strongCBD", input_ports = ["inC1", "inC2", "inA"], output_ports = ["out1", "out2"])
+		CBDStrong.addBlock(AdderBlock(block_name="a1"))
+		CBDStrong.addBlock(AdderBlock(block_name="a2"))
+		CBDStrong.addConnection("inA", "a1")		
+		CBDStrong.addConnection("a1", "out1")
+		CBDStrong.addConnection("a2", "out2")
+		CBDStrong.addConnection("inC1", "a1")
+		CBDStrong.addConnection("inC2", "a2")
+		CBDStrong.addConnection("inA", "a2")
+		
+		self.CBD.addBlock(CBDStrong)
+		self.CBD.addBlock(AdderBlock(block_name="a3"))
+		self.CBD.addBlock(ConstantBlock(block_name="c2", value=5.5))
+		self.CBD.addBlock(ConstantBlock(block_name="c1", value=-5))
+		self.CBD.addConnection("c1", "strongCBD", input_port_name = "inC1")
+		self.CBD.addConnection("c2", "strongCBD", input_port_name = "inC2")
+		self.CBD.addConnection("a3", "strongCBD", input_port_name = "inA")
+		self.CBD.addConnection("strongCBD", "a3", output_port_name = "out1")
+		self.CBD.addConnection("strongCBD", "a3", output_port_name = "out2")
+		
+		depGraph = self.CBD._CBD__createDepGraph(0)
+		sortedGraph = depGraph.getStrongComponents()
+				
+		self.assertEquals(len(sortedGraph), 5)
+		self.assertEquals(len(sortedGraph[4]), 6)	
+		
+		
+def suite():
+    """Returns a suite containing all the test cases in this module."""
+    suite1 = unittest.makeSuite(BasicCBDTestCase)
+    
+    return unittest.TestSuite((suite1))
+
+if __name__ == '__main__':
+    # When this module is executed from the command-line, run all its tests
+    unittest.main()
+
+	
+	
+	
+	
+	
+	
+	
+	

+ 0 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/__init__.py


+ 80 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/models/EvenNumbersCBD.py

@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+from bokeh.plotting import figure, output_file, show
+from CBDMultipleOutput.Source.CBD import *
+from CBDMultipleOutput.Source.CBDDraw import draw
+
+
+class Counter(CBD):
+    def __init__(self, block_name):
+        CBD.__init__(self, 
+                    block_name, 
+                    input_ports=[], 
+                    output_ports=["OutCount"])
+        
+        self.addBlock(DelayBlock(block_name="delay"))
+        self.addBlock(AdderBlock(block_name="sum"))
+        self.addBlock(ConstantBlock(block_name="zero", value=0.0))
+        self.addBlock(ConstantBlock(block_name="one", value=1.0))
+        
+        self.addConnection("zero", "delay", 
+                            input_port_name="IC")
+        self.addConnection("delay", "OutCount")
+        self.addConnection("delay", "sum")
+        self.addConnection("sum", "delay", input_port_name="IN1")
+        self.addConnection("one", "sum")
+        
+class Double(CBD):        
+    def __init__(self, block_name):
+        CBD.__init__(self, 
+                     block_name, 
+                     input_ports=["InNumber"], 
+                     output_ports=["OutDouble"])
+        self.addBlock(ProductBlock(block_name="mult"))
+        self.addBlock(ConstantBlock(block_name="two", value=2.0))
+        
+        self.addConnection("InNumber", "mult")
+        self.addConnection("two", "mult")
+        self.addConnection("mult", "OutDouble")
+    
+    
+class EvenNumberGen(CBD):
+    def __init__(self, block_name):
+        CBD.__init__(self, 
+                     block_name, 
+                     input_ports=[],
+                     output_ports=["OutEven"])
+        
+        self.addBlock(Counter(block_name="counter"))
+        self.addBlock(Double(block_name="double"))
+        
+        self.addConnection("counter", "double", 
+                           input_port_name="InNumber",
+                           output_port_name="OutCount")
+        self.addConnection("double", "OutEven",
+                           output_port_name="OutDouble")
+        
+
+
+if __name__ == "__main__":
+    
+    cbd = EvenNumberGen("number_gen")
+    draw(cbd, "number_gen.dot")
+    draw(cbd.getBlockByName("counter"), "counter.dot")
+    cbd.run(10)
+    
+    times = []
+    output = []
+    
+    for timeValuePair in cbd.getSignal("OutEven"):
+        times.append(timeValuePair.time)
+        output.append(timeValuePair.value)
+                
+    #Plot
+    output_file("./number_gen.html", title="Even Numbers")
+    p = figure(title="Even Numbers", x_axis_label='time', y_axis_label='N')
+    p.circle(x=times, y=output, legend="Even numbers")
+    show(p)
+
+
+
+

+ 21 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/models/HarmonicOscilator.py

@@ -0,0 +1,21 @@
+from CBDMultipleOutput.Source.CBD import *
+
+class CircleCBDDerivative(CBD):
+    def __init__(self, blockName, delta_t):
+        CBD.__init__(self,blockName, [], [])
+        self.delta=delta_t;
+        self.addBlock(ConstantBlock(block_name="one", value=1.0))
+        self.addBlock(ConstantBlock(block_name="zero", value=0.0))
+        self.addBlock(ConstantBlock(block_name="delta", value=self.delta))
+        self.addBlock(NegatorBlock(block_name="neg"))
+        self.addBlock(DerivatorBlock(block_name="derxv"))
+        self.addBlock(DerivatorBlock(block_name="derva"))
+        
+        self.addConnection("delta", "derxv",  input_port_name="delta_t")
+        self.addConnection("delta", "derva",  input_port_name="delta_t")
+        self.addConnection("zero", "derva",  input_port_name="IC")
+        self.addConnection("one", "derxv",  input_port_name="IC")
+        self.addConnection("derva", "neg")
+        self.addConnection("neg", "derxv")
+        self.addConnection("derxv", "derva")
+        

+ 300 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/models/TrainControlCBD.py

@@ -0,0 +1,300 @@
+#!/usr/bin/env python
+from CBDMultipleOutput.Source.CBD import *
+
+DELTA = 0.1
+MASS_PERSON = 73
+MASS_TRAIN = 6000
+K = 300
+C = 150
+
+
+
+class TrainControlCBD(CBD):
+    def __init__(self, block_name, kp, ki, kd):
+        CBD.__init__(self, block_name)
+        self.addBlock(FixedTimeCBD(block_name="time"))
+        self.addBlock(LookUpBlockFixed(block_name="computer"))
+        self.addBlock(AdderBlock(block_name="sum"))
+        self.addBlock(NegatorBlock(block_name="neg"))
+        self.addBlock(TrainPIDController("controller", kp, ki, kd))
+        self.addBlock(TrainPerson(block_name="plant"))
+        self.addBlock(CostFunctionCBD(block_name="cost"))
+        
+        # the connections follow the topological sort.
+        self.addConnection("time", "computer", 
+                            input_port_name="IN1", output_port_name="OutTime")
+        self.addConnection("time", "plant", 
+                            input_port_name="InDelta", output_port_name="OutDelta")
+        self.addConnection("time", "controller", 
+                            input_port_name="InDelta", output_port_name="OutDelta")
+        self.addConnection("computer", "sum", 
+                            input_port_name="IN1", output_port_name="OUT1")
+        self.addConnection("plant", "neg", 
+                            input_port_name="IN1", output_port_name="OutVTrain")
+        self.addConnection("neg", "sum", 
+                            input_port_name="IN2", output_port_name="OUT1")
+        self.addConnection("sum", "controller", 
+                            input_port_name="InError", output_port_name="OUT1")
+        self.addConnection("controller", "plant", 
+                            input_port_name="InTraction", output_port_name="OutTraction")
+        self.addConnection("sum", "cost", 
+                            input_port_name="InError")
+        self.addConnection("time", "cost", 
+                            input_port_name="InDelta", output_port_name="OutDelta")
+        self.addConnection("plant", "cost", 
+                            input_port_name="InXPerson", output_port_name="OutXPerson")
+        
+        
+
+class CostFunctionCBD(CBD):        
+    def __init__(self, block_name):
+        CBD.__init__(self, block_name, ["InError","InDelta","InXPerson"], ["OutCost"])
+        self.addBlock(ABSBlock(block_name="abs"))
+        self.addBlock(ABSBlock(block_name="absError"))
+        self.addBlock(IntegratorBlock(block_name="integral"))
+        self.addBlock(ConstantBlock(block_name="zero", value=0.0))
+        self.addBlock(AboveThresholdBlock(block_name="above04", threshold=0.4))
+        self.addBlock(StopSimulationBlock(block_name="stop"))
+        
+        self.addConnection("InError", "absError")
+        self.addConnection("absError", "integral", input_port_name="IN1")
+        self.addConnection("InDelta", "integral", input_port_name="delta_t")
+        self.addConnection("zero", "integral", input_port_name="IC")
+        self.addConnection("integral", "OutCost")
+        self.addConnection("InXPerson", "abs")
+        self.addConnection("abs", "above04")
+        self.addConnection("above04", "stop")
+        
+
+class ABSBlock(BaseBlock):
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1"], ["OUT1"])
+
+    def compute(self, curIteration):
+        self.appendToSignal(abs(self.getInputSignal(curIteration).value))
+
+class LookUpBlockFixed(BaseBlock):
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1"], ["OUT1"])
+        
+    def compute(self, curIteration):
+        currentTime = self.getInputSignal(curIteration, "IN1").value
+        if currentTime < 0:
+            result = 0
+        elif currentTime < 160:
+            result = 14
+        elif currentTime < 200:
+            result = 2
+        elif currentTime < 260:
+            result = 15
+        else:
+            result = 0
+        
+        self.appendToSignal(result)
+
+
+
+class AboveThresholdBlock(BaseBlock):
+    def __init__(self, block_name, threshold):
+        BaseBlock.__init__(self, block_name, ["IN1"], ["OUT1"])
+        self.threshold = threshold
+
+    def compute(self, curIteration):
+        self.appendToSignal(1.0 if self.getInputSignal(curIteration).value > self.threshold else -1.0)
+
+
+
+class StopSimulationBlock(BaseBlock):
+    def __init__(self, block_name):
+        BaseBlock.__init__(self, block_name, ["IN1"], [])
+
+    def compute(self, curIteration):
+        inSignalValue = self.getInputSignal(curIteration).value
+        if inSignalValue > 0.0:
+            raise StopSimulationException()
+        
+
+class StopSimulationException(Exception):
+    pass
+        
+class FixedTimeCBD(CBD):        
+    def __init__(self, block_name):
+        CBD.__init__(self, block_name, [], ["OutTime", "OutDelta"])
+        self.addBlock(ConstantBlock(block_name="delta", value=DELTA))
+        self.addBlock(ConstantBlock(block_name="zero", value=0.0))
+        self.addBlock(AdderBlock(block_name="sum"))
+        self.addBlock(DelayBlock(block_name="delay"))
+        
+        self.addConnection("delta", "OutDelta")
+        self.addConnection("delay", "OutTime")
+        self.addConnection("delay", "sum")
+        self.addConnection("delta", "sum")
+        self.addConnection("sum", "delay")
+        self.addConnection("zero", "delay",
+                            input_port_name="IC")
+    
+
+class TrainPIDController(CBD):
+    def __init__(self, block_name, kp, ki, kd):
+        CBD.__init__(self, block_name, ["InError","InDelta"],["OutTraction"])
+        self.addBlock(IntegratorBlock(block_name="integral"))
+        self.addBlock(DerivatorBlock(block_name="derivative"))
+        self.addBlock(ConstantBlock(block_name="Kp", value=kp))
+        self.addBlock(ProductBlock(block_name="multKp"))
+        self.addBlock(ConstantBlock(block_name="Ki", value=ki))
+        self.addBlock(ProductBlock(block_name="multKi"))
+        self.addBlock(ConstantBlock(block_name="Kd", value=kd))
+        self.addBlock(ProductBlock(block_name="multKd"))
+        self.addBlock(ConstantBlock(block_name="zero", value=0.0))
+        self.addBlock(AdderBlock(block_name="sum1"))
+        self.addBlock(AdderBlock(block_name="sum2"))
+        
+        self.addConnection("InError", "multKp")
+        self.addConnection("Kp", "multKp")
+        self.addConnection("InError", "integral")
+        self.addConnection("InError", "derivative")
+        self.addConnection("InDelta", "derivative", 
+                            input_port_name="delta_t")
+        self.addConnection("InDelta", "integral", 
+                            input_port_name="delta_t")
+        self.addConnection("zero", "derivative", 
+                            input_port_name="IC")
+        self.addConnection("zero", "integral", 
+                            input_port_name="IC")
+        self.addConnection("integral", "multKi")
+        self.addConnection("Ki", "multKi")
+        self.addConnection("derivative", "multKd")
+        self.addConnection("Kd", "multKd")
+        self.addConnection("multKd", "sum1")
+        self.addConnection("multKi", "sum1")
+        self.addConnection("sum1", "sum2")
+        self.addConnection("multKp", "sum2")
+        self.addConnection("sum2", "OutTraction")
+        
+        
+class TrainPerson(CBD):
+    def __init__(self, block_name):
+        CBD.__init__(self, block_name, ["InTraction","InDelta"],["OutVTrain", "OutXPerson", "OutATrain"])
+        self.addBlock(ConstantBlock(block_name="zero", value=0.0))
+        self.addBlock(AccelerationPerson(block_name="accelerationPerson"))
+        self.addBlock(AccelerationTrain(block_name="accelerationTrain"))
+        self.addBlock(IntegratorBlock(block_name="integral_person_a_v"))
+        self.addBlock(IntegratorBlock(block_name="integral_person_v_x"))
+        self.addBlock(IntegratorBlock(block_name="integral_train_a_v"))
+        
+        self.addConnection("zero", "integral_person_a_v", 
+                            input_port_name="IC")
+        self.addConnection("zero", "integral_person_v_x", 
+                            input_port_name="IC")
+        self.addConnection("zero", "integral_train_a_v", 
+                            input_port_name="IC")
+        
+        self.addConnection("InDelta", "integral_person_a_v", 
+                            input_port_name="delta_t")
+        self.addConnection("InDelta", "integral_person_v_x", 
+                            input_port_name="delta_t")
+        self.addConnection("InDelta", "integral_train_a_v", 
+                            input_port_name="delta_t")
+        
+        self.addConnection("InTraction", "accelerationPerson", 
+                            input_port_name="InTraction")
+        self.addConnection("InTraction", "accelerationTrain", 
+                            input_port_name="InTraction")
+        
+        self.addConnection("accelerationPerson", "integral_person_a_v", 
+                            input_port_name="IN1", output_port_name="OutAPerson")
+        self.addConnection("integral_person_a_v", "accelerationPerson", 
+                            input_port_name="InVPerson", output_port_name="OUT1")
+        self.addConnection("integral_person_a_v", "integral_person_v_x", 
+                            input_port_name="IN1", output_port_name="OUT1")
+        self.addConnection("integral_person_v_x", "accelerationPerson", 
+                            input_port_name="InXPerson", output_port_name="OUT1")
+        
+        self.addConnection("accelerationTrain", "integral_train_a_v", 
+                            input_port_name="IN1", output_port_name="OutATrain")
+        
+        self.addConnection("integral_train_a_v", "OutVTrain")
+        
+        self.addConnection("integral_person_v_x", "OutXPerson")
+        
+        self.addConnection("accelerationTrain", "OutATrain", input_port_name=None, output_port_name="OutATrain")
+        
+        
+        
+class AccelerationPerson(CBD):
+    def __init__(self, block_name):
+        CBD.__init__(self, block_name, ["InTraction","InVPerson","InXPerson"],["OutAPerson"])
+        self.addBlock(ConstantBlock(block_name="m_train", value=MASS_TRAIN))
+        self.addBlock(ConstantBlock(block_name="m_person", value=MASS_PERSON))
+        self.addBlock(ConstantBlock(block_name="c", value=C))
+        self.addBlock(ConstantBlock(block_name="k", value=K))
+        self.addBlock(AdderBlock(block_name="sum_masses"))
+        self.addBlock(InverterBlock(block_name="inv_sum_masses"))
+        self.addBlock(ProductBlock(block_name="mult_inv_sum_masses"))
+        self.addBlock(ProductBlock(block_name="mult_mult_inv_sum_masses"))
+        self.addBlock(InverterBlock(block_name="inv_mperson"))
+        self.addBlock(NegatorBlock(block_name="neg_mult_mult_inv_sum_masses"))
+        self.addBlock(NegatorBlock(block_name="neg_vperson"))
+        self.addBlock(NegatorBlock(block_name="neg_xperson"))
+        self.addBlock(ProductBlock(block_name="mult_neg_vperson"))
+        self.addBlock(ProductBlock(block_name="mult_neg_xperson"))
+        self.addBlock(AdderBlock(block_name="sum_mults_person"))
+        self.addBlock(AdderBlock(block_name="sum_sum_mults_person"))
+        self.addBlock(ProductBlock(block_name="mult_inv_mperson"))
+        
+        self.addConnection("m_train", "sum_masses")
+        self.addConnection("m_person", "sum_masses")
+        self.addConnection("sum_masses", "inv_sum_masses")
+        self.addConnection("inv_sum_masses", "mult_inv_sum_masses")
+        self.addConnection("InTraction", "mult_inv_sum_masses")
+        self.addConnection("mult_inv_sum_masses", "mult_mult_inv_sum_masses")
+        
+        self.addConnection("m_person", "mult_mult_inv_sum_masses")
+        
+        self.addConnection("m_person", "inv_mperson")
+        self.addConnection("inv_mperson", "mult_inv_mperson")
+        
+        self.addConnection("mult_mult_inv_sum_masses", "neg_mult_mult_inv_sum_masses")
+        self.addConnection("neg_mult_mult_inv_sum_masses", "sum_sum_mults_person")
+        
+        self.addConnection("InVPerson", "neg_vperson")
+        self.addConnection("neg_vperson", "mult_neg_vperson")
+        self.addConnection("c", "mult_neg_vperson")
+        
+        self.addConnection("InXPerson", "neg_xperson")
+        self.addConnection("neg_xperson", "mult_neg_xperson")
+        self.addConnection("k", "mult_neg_xperson")
+        
+        self.addConnection("mult_neg_vperson", "sum_mults_person")
+        self.addConnection("mult_neg_xperson", "sum_mults_person")
+        
+        self.addConnection("sum_mults_person", "sum_sum_mults_person")
+        self.addConnection("sum_sum_mults_person", "mult_inv_mperson")
+        self.addConnection("mult_inv_mperson", "OutAPerson")
+        
+        
+        
+class AccelerationTrain(CBD):
+    def __init__(self, block_name):
+        CBD.__init__(self, block_name, ["InTraction"],["OutATrain"])
+        self.addBlock(ConstantBlock(block_name="m_train", value=MASS_TRAIN))
+        self.addBlock(ConstantBlock(block_name="m_person", value=MASS_PERSON))
+        self.addBlock(AdderBlock(block_name="sum"))
+        self.addBlock(InverterBlock(block_name="inv"))
+        self.addBlock(ProductBlock(block_name="mult"))
+        
+        self.addConnection("InTraction", "mult")
+        self.addConnection("m_train", "sum")
+        self.addConnection("m_person", "sum")
+        self.addConnection("sum", "inv")
+        self.addConnection("inv", "mult")
+        self.addConnection("mult", "OutATrain")
+
+
+
+
+
+
+
+
+

+ 0 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBDMultipleOutput/models/__init__.py


+ 262 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/CBD_Controller.py

@@ -0,0 +1,262 @@
+"""
+This is CBD simulator controller exposing the most relevant methods of 
+a CBD simulator (See CBDMultipleOutput.Source.CBD.run) to allow for control from a SCCD.
+
+date: Oct 2015
+author (responsible): Claudio Gomes
+"""
+
+import math
+from CBDMultipleOutput.Source.CBD import Clock, DepGraph
+from CBDMultipleOutput.Source.CBD import CBD
+
+
+class CBDController:
+    """The CBD contoller acts as a facade to the simulator methods that are in the CBD objects.
+    The original design decision to keep the methods in the CBD Domain classes 
+    (as opposed to, for instance, keep them in a visitor/interpreter was not the decision of the current author.)"""
+    
+    def __init__(self, cbdModel, delta_t):
+        self.model = cbdModel
+        self.model.setDeltaT(delta_t)
+        self.delta = delta_t
+        
+    def initSimulation(self):
+        self.model.resetSignals();
+        self.model.setClock(Clock(self.delta))
+    
+    def createDepGraph(self, iteratonStep):
+        return self.__createDepGraph(iteratonStep)
+    
+    def createStrongComponents(self, depGraph, iteratonStep):
+        return depGraph.getStrongComponents(iteratonStep)
+    
+    def componentIsCycle(self, component, depGraph):
+        return self.__hasCycle(component, depGraph)    
+    
+    def computeNextBlock(self, comp, iteratonStep):
+        block = comp[0]   # the strongly connected component has a single element
+        block.compute(iteratonStep)
+    
+    def computeNextAlgebraicLoop(self, comp, iteratonStep):
+        currentComponent = comp
+        # Detected a strongly connected component
+        if not self.__isLinear(currentComponent):
+            raise NotImplementedError("Cannot solve non-linear algebraic loop")
+        solverInput = self.__constructLinearInput(currentComponent, iteratonStep)
+        self.__gaussjLinearSolver(solverInput)
+        solutionVector = solverInput[1]
+        for block in currentComponent:
+            blockIndex = currentComponent.index(block)
+            block.appendToSignal(solutionVector[blockIndex])
+    
+    def advanceTimeStep(self):
+        self.model.getClock().step()
+    
+    def getCurrentSimulationTime(self):
+        return self.model.getClock().getTime()
+    
+    def __isLinear(self, strongComponent):
+        """
+        Determines if an algebraic loop describes a linear equation or not
+        As input you get the detected loop in a list.
+        If the loop is linear return True
+        Else: call exit(1) to exit the simulation with exit code 1
+        
+        The strong component parameter is a list of blocks that comprise the strong component.
+        For a block to comprise the strong component, at least one of its dependencies must be in the strong component as well.
+        A non-linear equation is generated when the following conditions occur:
+         (1) there is a multiplication operation being performed between two unknowns.
+         (2) there is an invertion operatioon being performed in an unknown.
+         (3) some non linear block belongs to the strong component
+        
+        The condition (1) can be operationalized by finding a product block that has two dependencies belonging to the strong component.
+        This will immediatly tell us that it is a product between two unknowns.
+        The condition (2) can be operationalized simply by finding an inverter block in the strong component. 
+        Because the inverter block only has one input, if it is in the strong component, it means that its only dependency is in the strong component.
+        
+        """
+        for block in strongComponent:
+            if not block.getBlockType() == "AdderBlock" and not block.getBlockType() == "NegatorBlock":
+                # condition (1)
+                if block.getBlockType() == "ProductBlock":
+                    dependenciesUnknown = [x for x in block.getDependencies(0) if x in strongComponent ]
+                    if (len(dependenciesUnknown) == 2):
+                        return False
+                
+                # conditions (2) and (3)
+                if block.getBlockType() in ["InverterBlock", "LessThanBlock", "ModuloBlock", "RootBlock", "EqualsBlock", "NotBlock", "OrBlock", "AndBlock", "SequenceBlock"]:
+                    return False
+        
+        return True
+    
+    def __hasCycle(self, component, depGraph):
+        """
+        Determine whether a component is cyclic
+        """
+        assert len(component)>=1, "A component should have at least one element"
+        if len(component)>1:
+            return True
+        else: # a strong component of size one may still have a cycle: a self-loop
+            if depGraph.hasDependency(component[0], component[0]):
+                return True
+            else:
+                return False
+
+    def __constructLinearInput(self, strongComponent, curIteration):
+        """
+        Constructs input for a solver of systems of linear equations
+        Input consists of two matrices:
+        M1: coefficient matrix, where each row represents an equation of the system
+        M2: result matrix, where each element is the result for the corresponding equation in M1
+        """
+        size = len(strongComponent)
+        row = []
+        M1 = []
+        M2 = []
+
+        # Initialize matrices with zeros
+        i = 0
+        while (i < size):
+            j = 0
+            row = []
+            while (j < size):
+                row.append(0)
+                j += 1
+            M1.append(row)
+            M2.append(0)
+            i += 1
+
+        # block -> index of block
+        indexdict = dict()
+
+        for (i,block) in enumerate(strongComponent):
+            indexdict[block] = i
+
+        resolveBlock = lambda possibleDep, output_port: possibleDep if not isinstance(possibleDep, CBD) else possibleDep.getBlockByName(output_port)
+
+        def getBlockDependencies2(block):
+            return [ resolveBlock(b,output_port) for (b, output_port) in [block.getBlockConnectedToInput("IN1"),  block.getBlockConnectedToInput("IN2")]]
+
+        for (i, block) in enumerate(strongComponent):
+            if block.getBlockType() == "AdderBlock":
+                for external in [ x for x in getBlockDependencies2(block) if x not in strongComponent ]:
+                    M2[i] -= external.getSignal()[curIteration].value
+                M1[i][i] = -1
+
+                for compInStrong in [ x for x in getBlockDependencies2(block) if x in strongComponent ]:
+                    M1[i][indexdict[compInStrong]] = 1
+            elif block.getBlockType() == "ProductBlock":
+                #M2 can stay 0
+                M1[i][i] = -1
+                M1[i][indexdict[[ x for x in getBlockDependencies2(block)  if x in strongComponent ][0]]] = reduce(lambda x,y: x*y, [ x.getSignal()[curIteration].value for x in getBlockDependencies2(block) if x not in strongComponent ])
+            elif block.getBlockType() == "NegatorBlock":
+                #M2 can stay 0
+                M1[i][i] = -1
+                possibleDep, output_port = block.getBlockConnectedToInput("IN1")
+                M1[i][indexdict[resolveBlock(possibleDep, output_port)]] = - 1
+            elif block.getBlockType() == "InputPortBlock":
+                #M2 can stay 0
+                M1[i][i] = 1
+                possibleDep, output_port = block.parent.getBlockConnectedToInput(block.getBlockName())
+                M1[i][indexdict[resolveBlock(possibleDep, output_port)]] = - 1
+            elif block.getBlockType() == "OutputPortBlock" or block.getBlockType() == "WireBlock":
+                #M2 can stay 0
+                M1[i][i] = 1
+                M1[i][indexdict[block.getDependencies(0)[0]]] = - 1
+            elif block.getBlockType() == "DelayBlock":
+                # If a delay is in a strong component, this is the first iteration
+                assert curIteration == 0
+                # And so the dependency is the IC
+                # M2 can stay 0 because we have an equation of the type -x = -ic <=> -x + ic = 0
+                M1[i][i] = -1
+                possibleDep, output_port = block.getBlockConnectedToInput("IC")
+                dependency = resolveBlock(possibleDep, output_port)
+                assert dependency in strongComponent
+                M1[i][indexdict[dependency]] = 1
+            else:
+                self.__logger.fatal("Unknown element, please implement")
+        return [M1, M2]
+
+    
+    def __gaussjLinearSolver(self, solverInput):
+        M1 = solverInput[0]
+        M2 = solverInput[1]
+        n = len(M1)
+        indxc = self.__ivector(n)
+        indxr = self.__ivector(n)
+        ipiv = self.__ivector(n)
+        icol = 0
+        irow = 0
+        for i in range(n):
+            big = 0.0
+            for j in range(n):
+                if (ipiv[j] != 1):
+                    for k in range(n):
+                        if (ipiv[k] == 0):
+                            if (math.fabs(M1[j][k]) >= big):
+                                big = math.fabs(M1[j][k])
+                                irow = j
+                                icol = k
+                        elif (ipiv[k] > 1):
+                            raise ValueError("GAUSSJ: Singular Matrix-1")
+            ipiv[icol] += 1
+            if (irow != icol):
+                for l in range(n):
+                    (M1[irow][l], M1[icol][l]) = self.__swap(M1[irow][l], M1[icol][l])
+                (M2[irow], M2[icol]) = self.__swap(M2[irow], M2[icol])
+            indxr[i] = irow
+            indxc[i] = icol
+            if (M1[icol][icol] == 0.0):
+                raise ValueError("GAUSSJ: Singular Matrix-2")
+            pivinv = 1.0/M1[icol][icol]
+            M1[icol][icol] = 1.0
+            for l in range(n):
+                M1[icol][l] *= pivinv
+            M2[icol] *= pivinv
+            for ll in range(n):
+                if (ll != icol):
+                    dum = M1[ll][icol]
+                    M1[ll][icol] = 0.0
+                    for l in range(n):
+                        M1[ll][l] -= M1[icol][l] * dum
+                    M2[ll] -= M2[icol] * dum
+        l = n
+        while (l > 0):
+            l -= 1
+            if (indxr[l] != indxc[l]):
+                for k in range(n):
+                    (M1[k][indxr[l]], M1[k][indxc[l]]) = self.__swap(M1[k][indxr[l]], M1[k][indxc[l]])
+
+    def __createDepGraph(self, curIteration):
+        """
+         Create a dependency graph of the CBD model.
+         Use the curIteration to differentiate between the first and other iterations
+         Watch out for dependencies with sub-models.
+        """
+        blocks = self.model.getBlocks()
+        depGraph = DepGraph()
+        for block in blocks:      
+            depGraph.addMember(block);
+        
+        def recSetInternalDependencies(blocks, curIteration):
+            for block in blocks:
+                for dep in block.getDependencies(curIteration):
+                    depGraph.setDependency(block, dep, curIteration)
+                if isinstance(block, CBD):
+                    recSetInternalDependencies(block.getBlocks(), curIteration)
+        
+        recSetInternalDependencies(blocks, curIteration);
+        
+        return depGraph
+    
+    def __ivector(self, n):
+        v = []
+        for i in range(n):
+            v.append(0)
+        return v
+
+    def __swap(self, a, b):
+        return (b, a)
+
+    

+ 56 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/Options.py

@@ -0,0 +1,56 @@
+AUTO_TIME_MODE = 0X01
+MANUAL_TIME_MODE = 0x02
+MANUAL_STEP_TIME_MODE = 0x03
+FAST_TIME_MODE = 0x04
+
+#a list containg the aboves modes so that the option class can do an 'in' check instead of == one by one
+#to check the legality of a received mode. 
+LEGAL_TIME_MODES = [AUTO_TIME_MODE, MANUAL_TIME_MODE, MANUAL_STEP_TIME_MODE, FAST_TIME_MODE]
+
+class Options:
+  """A class that contains options that should be given trough the interface)"""
+  def __init__(self,maxIter = 10, mode = AUTO_TIME_MODE, scaleFactor = 1, delta = 0.001):
+    """
+    a couple of options
+    @param maxIter the number or iterations of 1 simulation
+    @param mode the time mode
+    @param scaleFactor the scale factor by which to run an iteration default 1
+    """
+    self.__max_iter = maxIter
+    self.setTimeMode(mode)
+    self.setDeltaT(delta)
+    if scaleFactor >= 0:
+      self.__factor = scaleFactor 
+    else:
+      self.__factor  = 1
+        
+  def setMaxIterations(self, max):
+    self.__max_iter = max
+   
+  def getMaxIterations(self):
+    return self.__max_iter 
+  
+  def setDeltaT(self, delta):
+    self.__delta = delta
+   
+  def getDeltaT(self):
+    return self.__delta 
+  
+  
+  def setScaleFactor(self, factor):
+    if factor >= 0:
+      self.__factor = factor
+      #if value is illegal keep simply keep previous value
+
+  def getScaleFactor(self):
+    return self.__factor
+  
+  def setTimeMode(self, mode):
+    """Set the time mode. If it isn't a legal value set it to AUTO_TIME_MODE"""
+    if (mode in LEGAL_TIME_MODES): #since there is no enumeration in python this is a check to make sure a level has been added and not a random int
+      self.__mode = mode
+    else:
+      self.__mode = AUTO_TIME_MODE 
+
+  def getTimeMode(self):
+    return self.__mode

+ 14 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/log.txt

@@ -0,0 +1,14 @@
+EXIT: /Main/Initializer/Waiting
+ENTER: /Main/Initializer/CreatingChildSimulator
+EXIT: /Main/Initializer/CreatingChildSimulator
+ENTER: /Main/Initializer/StartingChildSimulator
+EXIT: /Main/Initializer/Started
+ENTER: /Main/Initializer/Initialized
+EXIT: /Main/Initializer/Initialized
+ENTER: /Main/Initializer/InitializeDebugger
+EXIT: /Main/Initializer/InitializeDebugger
+ENTER: /Main/Initializer/Waiting
+EXIT: /Main/SimulationState/Uninitialized
+ENTER: /Main/SimulationState/Initialized
+EXIT: /Main/Initializer/StartingChildSimulator
+ENTER: /Main/Initializer/Waiting

Dosya farkı çok büyük olduğundan ihmal edildi
+ 43 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/plot.html


+ 116 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/run_debug.py

@@ -0,0 +1,116 @@
+import target
+from sccd.runtime.statecharts_core import Event
+import threading
+from Options import Options
+from CBDMultipleOutput.models.HarmonicOscilator import CircleCBDDerivative
+from CBDMultipleOutput.Source.CBD import CBD
+
+'''
+add_breakpoint test def breakpoint(parameters): return parameters['clock'] >= 0.5 True True
+'''
+
+if __name__ == '__main__':
+    options = Options(delta = 0.01)
+    options.setMaxIterations(1000);
+    #cbdModel = EvenNumberGen("EvenNumbersGenerator")
+    cbdModel = CircleCBDDerivative("CircleCBDDerivative", options.getDeltaT())
+    # Use keep_running false for as fast as possible simulation.
+    controller = target.Controller(options, cbdModel)
+    
+    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) != 3:
+                    print("God events require 2 parameters!")
+                    continue
+                params = [inp[1], eval(inp[2])]
+            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 signal_name new_value")
+                print("   --> Updates the last value of the signal")
+                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()

+ 219 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_bigstep.xml

@@ -0,0 +1,219 @@
+<class name="CBDSimulator_BigStep">
+    <relationships>
+        <association name="parent" class="CBDSimulator_Simulation" min="1" max="1" />
+        <association name="child_simulator" class="CBDSimulator_SmallStep" min="0" max="1" />
+    </relationships>
+    <method name="CBDSimulator_BigStep">
+        <parameter name="cbd_controller" />
+        <parameter name="clock" />
+        <parameter name="iteration" />
+        <parameter name="time_next" />
+        <parameter name="delta" />
+        <parameter name="state" />
+        <body>
+        <![CDATA[
+            self.cbd_controller = cbd_controller
+            self.clock = clock
+            self.iteration = iteration
+            self.time_next = time_next
+            self.delta = delta
+            self.state = state
+        ]]>
+        </body>
+    </method>
+    <method name="initialize">
+        <body>
+        <![CDATA[
+            self.current_component_idx = 0
+            self.dependency_graph = self.cbd_controller.createDepGraph(self.iteration)
+            self.strong_component_list = self.cbd_controller.createStrongComponents(self.dependency_graph, self.iteration)
+        ]]>
+        </body>
+    </method>
+    <method name="initializeDebugger">
+        <body>
+        <![CDATA[
+            pass
+        ]]>
+        </body>
+    </method>
+    <method name="endCondition">
+        <body>
+        <![CDATA[
+            return self.current_component_idx >= len(self.strong_component_list)
+        ]]>
+        </body>
+    </method>
+    <method name="finalize">
+        <body>
+        <![CDATA[
+            self.advanceTime()
+        ]]>
+        </body>
+    </method>
+    <method name="advanceTime">
+        <body>
+        <![CDATA[
+            self.clock = self.time_next
+            self.iteration = self.iteration + 1
+            self.cbd_controller.advanceTimeStep()
+            self.time_next = self.clock + self.delta
+        ]]>
+        </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="new_current_component_idx" />
+                            <parameter name="new_state" />
+                            <raise event="SmallStep.Finished" scope="narrow" target="'parent'">
+                                <parameter expr="new_current_component_idx" />
+                                <parameter expr="new_state" />
+                            </raise>
+                        </transition>
+                    </state>                    
+                    <transition target="../Paused" event="BigStep.Finished" />
+                </state>
+            </state>
+            <state id="SmallStepState" 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="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="SettleBeforeWaiting">
+                    <transition target="../Waiting" after="self.sccd_yield()" />
+                </state>
+                <state id="Waiting">
+                    <transition target="../CreatingChildSimulator" cond="INSTATE('../../ModeSelector/Running') and INSTATE('../../SmallStepState/Uninitialized') and not self.endCondition()">
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                            <parameter expr="'CBDSimulator_SmallStep'" />
+                            <parameter expr="self.cbd_controller" />
+                            <parameter expr="self.strong_component_list" />
+                            <parameter expr="self.current_component_idx" />
+                            <parameter expr="self.dependency_graph" />
+                            <parameter expr="self.iteration" />
+                            <parameter expr="self.state" />
+                        </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">
+                        <parameter name="new_current_component_idx" />
+                        <parameter name="new_state" />
+                        <script>
+                        <![CDATA[
+                            self.current_component_idx = new_current_component_idx
+                            self.state = new_state
+                        ]]>
+                        </script>
+                    </transition>
+                </state>
+            </state>
+            <state id="SimulationFlow" initial="Initializing">
+                <state id="Initializing">
+                    <!-- We make sure we are initialized -->
+                    <transition target="../Waiting" cond="INSTATE('../../Initializer/Waiting')" />
+                </state>
+                <state id="Waiting">
+                    <transition target="../CheckTermination" cond="INSTATE('../../ModeSelector/Running')" />
+                    <!-- in case a small step triggers the end condition of the simulation -->
+                    <!-- TODO: Probably we don't need this anymore, since the simulation will always coordinate big steps... -->
+                    <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.iteration" />
+                            <parameter expr="self.time_next" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                </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('../../SmallStepState/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.iteration" />
+                            <parameter expr="self.time_next" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="Executing">
+                    <transition target="../SettleBeforeCheckTermination" event="SmallStep.Finished" />
+                </state>
+                <state id="Stopped" />
+            </state>
+        </parallel>
+        <state id="Stopped" />
+    </scxml>
+</class>

+ 45 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_block.xml

@@ -0,0 +1,45 @@
+<class name="CBDSimulator_Block">
+    <relationships>
+        <association name="parent" class="CBDSimulator_SmallStep" min="1" max="1" />
+    </relationships>
+    <method name="CBDSimulator_Block">
+        <parameter name="cbd_controller" />
+        <parameter name="block_to_compute" />
+        <parameter name="is_cycle" />
+        <parameter name="iteration" />
+        <body>
+            self.cbd_controller = cbd_controller
+            self.block_to_compute = block_to_compute
+            self.is_cycle = is_cycle
+            self.iteration = iteration
+        </body>
+    </method>
+    <method name="computeBlock">
+        <body>
+        <![CDATA[
+            if self.is_cycle:
+                self.cbd_controller.computeNextAlgebraicLoop(self.block_to_compute, self.iteration)
+            else:
+                self.cbd_controller.computeNextBlock(self.block_to_compute, self.iteration)
+        ]]>
+        </body>
+    </method>
+    <scxml initial="Started" final="Stopped">
+        <state id="Started">
+            <transition target="../Waiting">
+                <raise event="Block.Initialized" scope="narrow" target="'parent'" />
+            </transition>
+        </state>
+        <state id="Waiting">
+            <transition target="../Stopped" event="Block.Execute">
+                <script>
+                    self.computeBlock()
+                </script>
+                <raise event="Block.Finished" scope="narrow" target="'parent'">
+                    <parameter expr="{b.getBlockName(): b.getSignal() for b in self.cbd_controller.model.getBlocks()}" />
+                </raise>
+            </transition>
+        </state>
+        <state id="Stopped" />
+    </scxml>
+</class>

+ 273 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_coordinator.xml

@@ -0,0 +1,273 @@
+<class name="CBDSimulator_Coordinator" default="True">        
+    <relationships>
+        <association name="child_simulator" class="CBDSimulator_Simulation" min="0" max="1" />
+    </relationships>
+    <method name="CBDSimulator_Coordinator">
+        <parameter name="options"/>
+        <parameter name="model"/>
+        <body>
+            <![CDATA[
+            self.options = options
+            self.model = model
+            ]]>
+        </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>
+                </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="iteration" />
+                            <parameter name="time_next" />
+                            <parameter name="state" />
+                            <raise event="BigStep.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="clock / 1000.0" />
+                                <!--parameter expr="iteration" /-->
+                                <!--parameter expr="time_next" /-->
+                                <!--parameter expr="state" /-->
+                            </raise>
+                        </transition>
+                    </state>
+                    <state id="BigStep">
+                        <transition target="../../Paused" event="BigStep.Finished">
+                            <parameter name="clock" />
+                            <parameter name="iteration" />
+                            <parameter name="time_next" />
+                            <parameter name="state" />
+                            <raise event="BigStep.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="clock / 1000.0" />
+                                <!--parameter expr="iteration" /-->
+                                <!--parameter expr="time_next" /-->
+                                <!--parameter expr="state" /-->
+                            </raise>
+                        </transition>
+                    </state>
+                    <state id="SmallStep">
+                        <transition target="../../Paused" event="SmallStep.Finished">
+                            <parameter name="current_component_idx" />
+                            <parameter name="state" />
+                            <raise event="SmallStep.Finished" port="user_output" />
+                            <raise event="State" port="user_output">
+                                <parameter expr="current_component_idx" />
+                                <!--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="SimulationState" 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('../../SimulationState/Uninitialized')">
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                            <parameter expr="'CBDSimulator_Simulation'" />
+                            <parameter expr="self.options" />
+                            <parameter expr="self.model" />
+                        </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('../../SimulationState/Initialized')">
+                        <raise event="Simulation.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Executing" cond="INSTATE('../../ModeSelector/Running/Realtime') and INSTATE('../../SimulationState/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('../../SimulationState/Initialized')">
+                        <raise event="BigStep.Execute" scope="narrow" target="'child_simulator'" />
+                    </transition>
+                    <transition target="../Executing" cond="INSTATE('../../ModeSelector/Running/SmallStep') and INSTATE('../../SimulationState/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>

+ 457 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_simulation.xml

@@ -0,0 +1,457 @@
+<class name="CBDSimulator_Simulation">
+    <relationships>
+        <association name="parent" class="CBDSimulator_Coordinator" min="1" max="1" />
+        <association name="child_simulator" class="CBDSimulator_BigStep" min="0" max="1" />
+    </relationships>
+    <method name="CBDSimulator_Simulation">
+        <parameter name="options"/>
+        <parameter name="model"/>
+        <body>
+        <![CDATA[
+            self.options = options
+            self.delta = self.options.getDeltaT() * 1000.0 # in miliseconds for real-time simulation
+            self.model = model
+            self.initialized = False
+        ]]>
+        </body>
+    </method>
+    <method name="initialize">
+        <body>
+        <![CDATA[
+            self.iteration = 0
+            self.clock = 0
+            self.time_next = self.delta
+            self.cbd_controller = CBDController(self.model, self.delta / 1000.0)
+            self.cbd_controller.initSimulation()
+            self.state = {b.getBlockName(): b.getSignal() for b in self.model.getBlocks()}
+            self.initialized = True
+        ]]>
+        </body>
+    </method>
+    <method name="endCondition">
+        <body>
+        <![CDATA[
+            return self.initialized and self.iteration >= self.options.getMaxIterations()
+        ]]>
+        </body>
+    </method>
+    <method name="finalize">
+        <body>
+        <![CDATA[
+            from bokeh.plotting import figure, output_file, show    
+            times = []
+            values = []
+            for timeValuePair in self.model.getSignal("neg"):
+                times.append(timeValuePair.time)
+                values.append(timeValuePair.value)
+
+            output_file("./plot.html", title="Plot")
+            p = figure(title="Something vs Otherthing", x_axis_label="Time", y_axis_label="Values")
+            p.line(times, values, legend="Something", line_width=1, line_color="red")
+            show(p)
+            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
+            # time_next 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.time_next - 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.time_next 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.time_next) / 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="block_name" />
+        <parameter name="new_val" />
+        <body>
+        <![CDATA[
+            if not self.initialized:
+                return -1
+            if block_name not in self.state:
+                return -1
+            for b in self.model.getBlocks():
+                if b.getBlockName() == block_name:
+                    b.setSignal(new_val)
+            self.state = {b.getBlockName(): b.getSignal() for b in self.model.getBlocks()}
+            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>
+                </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="iteration" />
+                            <parameter name="time_next" />
+                            <parameter name="state" />
+                            <raise event="BigStep.Finished" scope="narrow" target="'parent'">
+                                <parameter expr="clock" />
+                                <parameter expr="iteration" />
+                                <parameter expr="time_next" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                    </state>
+                    <state id="BigStep">
+                        <transition target="../../Paused" event="BigStep.Finished">
+                            <parameter name="clock" />
+                            <parameter name="iteration" />
+                            <parameter name="time_next" />
+                            <parameter name="state" />
+                            <raise event="BigStep.Finished" scope="narrow" target="'parent'">
+                                <parameter expr="clock" />
+                                <parameter expr="iteration" />
+                                <parameter expr="time_next" />
+                                <parameter expr="state" />
+                            </raise>
+                        </transition>
+                    </state>
+                    <state id="SmallStep">
+                        <transition target="../../Paused" event="SmallStep.Finished">
+                            <parameter name="current_component_idx" />
+                            <parameter name="state" />
+                            <raise event="SmallStep.Finished" scope="narrow" target="'parent'">
+                                <parameter expr="current_component_idx" />
+                                <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="BigStepState" 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="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="SettleBeforeWaiting">
+                    <transition target="../Waiting" after="self.sccd_yield()" />
+                </state>
+                <state id="Waiting">
+                    <transition target="../CreatingChildSimulator" cond="INSTATE('../../ModeSelector/Running') and INSTATE('../../BigStepState/Uninitialized') and not self.endCondition()">
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                            <parameter expr="'CBDSimulator_BigStep'" />
+                            <parameter expr="self.cbd_controller" />
+                            <parameter expr="self.clock" />
+                            <parameter expr="self.iteration" />
+                            <parameter expr="self.time_next" />
+                            <parameter expr="self.delta" />
+                            <parameter expr="self.state" />
+                        </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">
+                        <parameter name="clock" />
+                        <parameter name="iteration" />
+                        <parameter name="time_next" />
+                        <parameter name="state" />
+                        <script>
+                        <![CDATA[
+                            self.clock = clock
+                            self.iteration = iteration
+                            self.time_next = time_next
+                            self.state = state
+                        ]]>
+                        </script>
+                    </transition>
+                </state>
+            </state>
+            <state id="SimulationFlow" initial="Initializing">
+                <state id="Initializing">
+                    <!-- we make sure we are initialized -->
+                    <!-- TODO: Probably it's best if we move the initialization states to the SimulationFlow state. -->
+                    <transition target="../Waiting" cond="INSTATE('../../Initializer/Waiting')" />
+                </state>
+                <state id="Waiting">
+                    <transition target="../CheckTermination" cond="INSTATE('../../ModeSelector/Running')" />
+                    <!-- in case a big step triggers the end condition of the simulation -->
+                    <!-- TODO: Probably we don't need this anymore, since the simulation will always coordinate big steps... -->
+                    <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="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('../../BigStepState/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('../../BigStepState/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('../../BigStepState/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" />
+                </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>

+ 187 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/sim_smallstep.xml

@@ -0,0 +1,187 @@
+<class name="CBDSimulator_SmallStep">
+    <relationships>
+        <association name="parent" class="CBDSimulator_BigStep" min="1" max="1" />
+        <association name="child_simulator" class="CBDSimulator_Block" min="0" max="1" />
+    </relationships>
+    <method name="CBDSimulator_SmallStep">
+        <parameter name="cbd_controller" />
+        <parameter name="strong_component_list" />
+        <parameter name="current_component_idx" />
+        <parameter name="dependency_graph" />
+        <parameter name="iteration" />
+        <parameter name="state" />
+        <body>
+        <![CDATA[
+            self.cbd_controller = cbd_controller
+            self.strong_component_list = strong_component_list
+            self.current_component_idx = current_component_idx
+            self.dependency_graph = dependency_graph
+            self.iteration = iteration
+            self.state = state
+        ]]>
+        </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[
+            return self.small_step_executed
+        ]]>
+        </body>
+    </method>
+    <method name="finalize">
+        <body>
+        <![CDATA[
+            self.current_component_idx += 1
+        ]]>
+        </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="BlockState" initial="Uninitialized">
+                <state id="Uninitialized">
+                    <transition event="Block.Initialized" target="../Initialized" />
+                </state>
+                <state id="Initialized">
+                    <transition target="../Uninitialized" event="Block.Finished">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id="Initializer" 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="SettleBeforeWaiting">
+                    <transition target="../Waiting" after="self.sccd_yield()" />
+                </state>
+                <state id="Waiting">
+                    <transition target="../CreatingChildSimulator" cond="INSTATE('../../ModeSelector/Running') and INSTATE('../../BlockState/Uninitialized') and not self.endCondition()">
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'child_simulator'" />
+                            <parameter expr="'CBDSimulator_Block'" />
+                            <parameter expr="self.cbd_controller" />
+                            <parameter expr="self.strong_component_list[self.current_component_idx]" />
+                            <parameter expr="self.cbd_controller.componentIsCycle(self.strong_component_list[self.current_component_idx], self.dependency_graph)" />
+                            <parameter expr="self.iteration" />
+                        </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="Block.Initialized" />
+                </state>
+                <state id="Running">
+                    <transition target="../SettleBeforeWaiting" event="Block.Finished">
+                        <parameter name="new_state" />
+                        <script>
+                        <![CDATA[
+                            self.small_step_executed = True
+                            self.state = new_state
+                        ]]>
+                        </script>
+                    </transition>
+                </state>
+            </state>
+            <state id="SimulationFlow" initial="Initializing">
+                <state id="Initializing">
+                    <!-- We make sure we are initialized -->
+                    <transition target="../Waiting" cond="INSTATE('../../Initializer/Waiting')" />
+                </state>
+                <state id="Waiting">
+                    <transition target="../CheckTermination" cond="INSTATE('../../ModeSelector/Running')" />
+                    <!-- in case a small step triggers the end condition of the simulation -->
+                    <!-- TODO: Probably we don't need this anymore, since the simulation will always coordinate big steps... -->
+                    <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.current_component_idx" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                </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('../../BlockState/Initialized') and not self.endCondition()">
+                        <raise event="Block.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.current_component_idx" />
+                            <parameter expr="self.state" />
+                        </raise>
+                    </transition>
+                </state>
+                <state id="Executing">
+                    <transition target="../SettleBeforeCheckTermination" event="Block.Finished" />
+                </state>
+                <state id="Stopped" />
+            </state>
+        </parallel>
+        <state id="Stopped" />
+    </scxml>
+</class>

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

@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<diagram name="CBDSimulator_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 CBD_Controller import CBDController
+        import Options
+        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_block.xml"/>
+</diagram>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 2058 - 0
debugging_fsa_cbd_composition/cbdsimulator/HierarchicalSimulator/target.py


+ 1 - 1
debugging_fsa_cbd_composition/cbdsimulator/cbdsim_parallel_debugging_realtime.xml

@@ -120,7 +120,7 @@
             <![CDATA[
             <![CDATA[
                 self.advanceTime()
                 self.advanceTime()
             ]]>
             ]]>
-            </body>        
+            </body>
         </method>
         </method>
         <method name="finalizeSmallStep">
         <method name="finalizeSmallStep">
             <body>
             <body>

+ 1 - 1
debugging_fsa_cbd_composition/cbdsimulator/target.py

@@ -1,7 +1,7 @@
 """
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
 
-Date:   Thu Oct 27 20:37:34 2016
+Date:   Fri Oct 28 14:17:28 2016
 
 
 Model author: Sadaf Mustafiz and Claudio Gomes and Simon Van Mierlo
 Model author: Sadaf Mustafiz and Claudio Gomes and Simon Van Mierlo
 Model name:   CBDSimulator
 Model name:   CBDSimulator