Переглянути джерело

dynamic LI and HI models now start at width 1 and dynamically get to the specified width instead if starting at that width and generating a fixed amount of atomic models g

Snej69420 2 місяців тому
батько
коміт
8163470ad8
1 змінених файлів з 21 додано та 20 видалено
  1. 21 20
      devstone/pythonpdevs/devstone.py

+ 21 - 20
devstone/pythonpdevs/devstone.py

@@ -101,7 +101,7 @@ class DelayedAtomicStats(DelayedAtomic):
 class DEVStoneWrapper(CoupledDEVS, ABC):
 
     def __init__(self, name: str, depth: int, width: int, int_delay: float, ext_delay: float,
-                 add_atomic_out_ports: bool = False, prep_time=0, stats=False, mode: str = ""):
+                 add_atomic_out_ports: bool = False, prep_time=0, stats=False, mode: str = "", dynamic: bool = False):
         super().__init__(name)
 
         self.depth = depth
@@ -143,6 +143,9 @@ class DEVStoneWrapper(CoupledDEVS, ABC):
             self.connectPorts(self.i_in, coupled.i_in)
             self.connectPorts(coupled.o_out, self.o_out)
 
+            if dynamic:
+                return # width will be dynamically generated
+
             # + (idx * 1e-6) to address too many transitions at the same time
             # => problem for Classic DEVS only it seems
             for idx in range(width - 1):
@@ -173,7 +176,7 @@ class DEVStoneWrapper(CoupledDEVS, ABC):
         result.append(coupled)
         return "".join(result)
 
-    def dot(self, output: bool=False) -> None:
+    def dot(self, name) -> None:
         result = ("\n\ndigraph {\n\tlayout=dot;"
                   "\n\tnodesep=0.25;"
                   "\n\tranksep=0.2;"
@@ -197,10 +200,7 @@ class DEVStoneWrapper(CoupledDEVS, ABC):
         result += "}\n"
 
         src = Source(result)
-        src.view(filename=f'graph_coupled_{self.depth}')  # Opens in default PDF viewer
-
-        if output:
-            print(result)
+        src.view(filename=f'{name}_{self.depth}')
 
     @abstractmethod
     def gen_coupled(self):
@@ -436,13 +436,14 @@ class dLI(DEVStoneWrapper):
     """
     def __init__(self, name: str, depth: int, width: int, int_delay: float, ext_delay: float, prep_time=0, stats=False):
         super().__init__(name, depth, width, int_delay, ext_delay, add_atomic_out_ports=False, prep_time=prep_time,
-                         stats=stats, mode="LI-Dynamic")
+                         stats=stats, mode="LI-Dynamic", dynamic=True)
 
-        self.max_gen = 5
         for idx in range(1, len(self.component_set)):
             assert isinstance(self.component_set[idx], AtomicDEVS)
             self.connectPorts(self.i_in, self.component_set[idx].i_in)
 
+        self.current_width = 1
+        self.max_gen = width - 1 # dynamically generate atomic components until width is reached excludes the coupled model
         self.generator = self.addSubModel(DynamicGenerator(self.name + "_gen", repeat=self.max_gen))
 
     def gen_coupled(self):
@@ -451,8 +452,7 @@ class dLI(DEVStoneWrapper):
 
     def modelTransition(self, state):
         if state.get("generate", True) and self.depth > 1:
-            # print("model", self.name)
-            name = "Atomic_%d_%d" % (self.depth - 1, self.width) if self.depth > 1 else "Atomic_0_%d" % self.width
+            name = "Atomic_%d_%d" % (self.depth - 1, self.current_width) if self.depth > 1 else "Atomic_0_%d" % self.current_width
             if self.stats:
                 new_atom = DelayedAtomicStats(name, self.int_delay, self.ext_delay,
                                               add_out_port=self.add_atomic_out_ports, prep_time=self.prep_time, mode="LI-Dynamic")
@@ -463,7 +463,7 @@ class dLI(DEVStoneWrapper):
             self.models.append(self.addSubModel(new_atom))
             self.connectPorts(self.i_in, new_atom.i_in)
 
-            self.width += 1
+            self.current_width += 1
             # print(f"{self.name}: added {new_atom.name} (width is now {self.width})")
             return False
         return False
@@ -475,9 +475,8 @@ class dHI(DEVStoneWrapper):
     """
     def __init__(self, name: str, depth: int, width: int, int_delay: float, ext_delay: float, prep_time=0, stats=False):
         super().__init__(name, depth, width, int_delay, ext_delay, add_atomic_out_ports=True, prep_time=prep_time,
-                         stats=stats, mode="HI-Dynamic")
+                         stats=stats, mode="HI-Dynamic", dynamic=True)
 
-        self.max_gen = 5
         if len(self.component_set) > 1:
             assert isinstance(self.component_set[-1], AtomicDEVS)
             self.connectPorts(self.i_in, self.component_set[-1].i_in)
@@ -487,6 +486,8 @@ class dHI(DEVStoneWrapper):
             self.connectPorts(self.component_set[idx].o_out, self.component_set[idx + 1].i_in)
             self.connectPorts(self.i_in, self.component_set[idx].i_in)
 
+        self.current_width = 1
+        self.max_gen = width - 1 # dynamically generate atomic components until width is reached excludes the coupled model
         self.generator = self.addSubModel(DynamicGenerator(self.name + "_gen", repeat=self.max_gen))
 
     def gen_coupled(self):
@@ -495,7 +496,7 @@ class dHI(DEVStoneWrapper):
 
     def modelTransition(self, state):
         if state.get("generate", True) and self.depth > 1:
-            name = "Atomic_%d_%d" % (self.depth - 1, self.width) if self.depth > 1 else "Atomic_0_%d" % self.width
+            name = "Atomic_%d_%d" % (self.depth - 1, self.current_width) if self.depth > 1 else "Atomic_0_%d" % self.current_width
             if self.stats:
                 new_atom = DelayedAtomicStats(name, self.int_delay, self.ext_delay,
                                               add_out_port=self.add_atomic_out_ports, prep_time=self.prep_time, mode="LI-Dynamic")
@@ -503,15 +504,15 @@ class dHI(DEVStoneWrapper):
                 new_atom = DelayedAtomic(name, self.int_delay, self.ext_delay,
                                          add_out_port=self.add_atomic_out_ports, prep_time=self.prep_time, mode="LI-Dynamic")
 
-            last = self.models[-1]
-            print("last: ", last.name)
             self.models.append(self.addSubModel(new_atom))
             self.connectPorts(self.i_in, new_atom.i_in)
-            if isinstance(last, AtomicDEVS) and hasattr(last, "o_out"):
-                self.connectPorts(last.o_out, new_atom.i_in)
+            if len(self.models) > 1:
+                prev = self.models[-2]
+                print("last: ", prev.name)
+                if isinstance(prev, AtomicDEVS) and hasattr(prev, "o_out"):
+                    self.connectPorts(prev.o_out, new_atom.i_in)
 
-            self.width += 1
-            # print(f"{self.name}: added {new_atom.name} (width is now {self.width})")
+            self.current_width += 1
             return False
         return False