瀏覽代碼

Basic yield catching framework in DEVS model

Yentl Van Tendeloo 9 年之前
父節點
當前提交
6e17c946b2
共有 1 個文件被更改,包括 59 次插入3 次删除
  1. 59 3
      model/model.py

+ 59 - 3
model/model.py

@@ -125,6 +125,9 @@ class MvKState(object):
     def __init__(self):
         self.mvk = None
         self.waiting = False
+        self.inputs = []
+        self.outputs = []
+        self.users = []
 
 class ModelverseKernel(AtomicDEVS):
     def __init__(self):
@@ -139,25 +142,74 @@ class ModelverseKernel(AtomicDEVS):
     def extTransition(self, inputs):
         if self.from_mvi in inputs:
             # Got input from MvI, so we queue it
-            pass
-        elif self.from_mvs in inputs:
+            for inp in inputs[self.from_mvi]:
+                if inp is not None:
+                    self.state.inputs.append(inp)
+                else:
+                    self.state.outputs.append(None)
+
+        if self.from_mvs in inputs:
             # Got input from MvS, so we can continue processing
             if self.state.mvk is None:
                 # No MvK, so set it with the root we have just received (or should have received)
                 self.state.mvk = MvK(inputs[self.from_mvs][0])
+            else:
+                self.state.reply = inputs[self.from_mvs][0]
+            self.state.waiting = False
 
         return self.state
 
     def intTransition(self):
         if self.state.mvk is None:
+            # Initializing
             self.state.waiting = True
+        else:
+            # Are initialized and have work to do
+            if len(self.state.users) == 0:
+                # Read out new set of users first
+                if self.state.reply is None:
+                    commands = [("RDK", [])]
+                else:
+                    self.users = self.state.reply
+                    print("Got users: " + str(self.users))
+                    commands = None
+            elif self.state.phase == "input":
+                # Process inputs
+                commands = self.state.mvk.execute_yields(self.state.users[0], "set_input", [self.state.inputs[0]], self.state.reply)
+            elif self.state.phase == "computation":
+                commands = self.state.mvk.execute_yields(self.state.users[0], "execute_rule", [], self.state.reply)
+            elif self.state.phase == "output":
+                commands = self.state.mvk.execute_yields(self.state.users[0], "get_output", [], self.state.reply)
+
+            # Advance phase
+            if commands is None:
+                if len(self.state.users) == 0:
+                    self.state.phase = "input"
+                elif self.state.phase == "input":
+                    self.state.inputs.pop(0)
+                    self.state.phase = "computation"
+                elif self.state.phase == "computation":
+                    self.state.phase = "output"
+                elif self.state.phase == "output":
+                    self.state.users.pop(0)
+                    self.state.phase = "input"
+                self.state.waiting = False
+                self.state.reply = None
+            else:
+                self.state.waiting = True
 
+            # Send the commands to the MvS
+            self.state.commands = commands
         return self.state
 
     def outputFnc(self):
         if self.state.mvk is None:
             # Ask the root first
             return {self.to_mvs: [[("RR", [])]]}
+        elif self.state.waiting:
+            return {self.to_mvs: [self.state.commands]}
+
+        return {}
 
     def timeAdvance(self):
         if self.state.waiting:
@@ -173,6 +225,7 @@ class MvIState():
         self.output = []
         self.processing = []
         self.memory = {}
+        self.init = True
 
 class ModelverseInterface(AtomicDEVS):
     def __init__(self, operations):
@@ -184,6 +237,7 @@ class ModelverseInterface(AtomicDEVS):
         self.from_mvk = self.addInPort("from_MvK")
 
     def intTransition(self):
+        self.state.init = False
         while self.state.operations:
             i = self.state.operations[0]
             if isinstance(i, int) and i not in self.memory:
@@ -212,7 +266,9 @@ class ModelverseInterface(AtomicDEVS):
         return {self.to_mvk: [send]}
 
     def timeAdvance(self):
-        if self.state.processing and (not isinstance(self.state.processing[0], int) or self.state.processing[0] in self.memory):
+        if self.state.init:
+            return 0
+        elif self.state.processing and (not isinstance(self.state.processing[0], int) or self.state.processing[0] in self.memory):
             return 0
         else:
             return float("inf")