瀏覽代碼

Added another example from Day & Atlee. Test nonterminating big step by setting limit on subrounds in superround.

Joeri Exelmans 5 年之前
父節點
當前提交
ea2e32768e

+ 6 - 1
src/sccd/execution/round.py

@@ -97,18 +97,23 @@ class Round(ABC):
 
 # Examples: Big step, combo step
 class SuperRound(Round):
-    def __init__(self, name, subround: Round, take_one: bool):
+    def __init__(self, name, subround: Round, take_one: bool, limit: Optional[int] = None):
         super().__init__(name)
         self.subround = subround
         subround.parent = self
         self.take_one = take_one
+        self.limit = limit
     
     def _internal_run(self, arenas_changed: Bitmap) -> Bitmap:
+        subrounds = 0
         while True:
             if self.take_one:
                 changed = self.subround.run(arenas_changed)
             else:
+                if self.limit and subrounds == self.limit:
+                    raise Exception("%s: Limit reached! (%d×%s) Possibly a never-ending big step." % (self.name, self.limit, self.subround.name))
                 changed = self.subround.run()
+                subrounds += 1
             if not changed:
                 break
             arenas_changed |= changed

+ 8 - 6
src/sccd/execution/statechart_instance.py

@@ -25,23 +25,24 @@ class StatechartInstance(Instance):
 
         small_step = SmallStep(termcolor.colored("small", 'blue'), None, generator)
 
-        # Always add a layer of 'fairness' above our small steps, so
-        # orthogonal transitions take turns fairly.
-        combo_one = SuperRound(termcolor.colored("combo_one", 'magenta'), small_step, take_one=True)
 
         if semantics.big_step_maximality == BigStepMaximality.TAKE_ONE:
-            self._big_step = combo_step = combo_one # No combo steps
+            self._big_step = combo_step = SuperRound(termcolor.colored("big_one", 'red'), small_step, take_one=True) # No combo steps
 
         elif semantics.big_step_maximality == BigStepMaximality.TAKE_MANY:
+            # Always add a layer of 'fairness' above our small steps, so
+            # orthogonal transitions take turns fairly.
+            combo_one = SuperRound(termcolor.colored("combo_one", 'magenta'), small_step, take_one=True)
 
             if semantics.combo_step_maximality == ComboStepMaximality.COMBO_TAKE_ONE:
                 # Fairness round becomes our combo step round
                 combo_step = combo_one
+
             elif semantics.combo_step_maximality == ComboStepMaximality.COMBO_TAKE_MANY:
                 # Add even more layers, basically an onion at this point.
-                combo_step = SuperRound(termcolor.colored("combo_many", 'cyan'), combo_one, take_one=False)
+                combo_step = SuperRound(termcolor.colored("combo_many", 'cyan'), combo_one, take_one=False, limit=1000)
 
-            self._big_step = SuperRound(termcolor.colored("big_many", 'red'), combo_step, take_one=False)
+            self._big_step = SuperRound(termcolor.colored("big_many", 'red'), combo_step, take_one=False, limit=1000)
 
         def whole(input):
             self._big_step.remainder_events = input
@@ -59,6 +60,7 @@ class StatechartInstance(Instance):
         }[semantics.input_event_lifeline]
 
         raise_internal = {
+            # InternalEventLifeline.QUEUE: self._big_step.add_next_event,
             InternalEventLifeline.QUEUE: lambda e: self.state.output.append(OutputEvent(e, InstancesTarget([self]))),
             InternalEventLifeline.NEXT_COMBO_STEP: combo_step.add_next_event,
             InternalEventLifeline.NEXT_SMALL_STEP: small_step.add_next_event

+ 20 - 0
test/test_files/day_atlee/fail_02_counter_takemany.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" ?>
+<test>
+  <statechart src="statechart_fig8_counter.xml">
+    <!-- these semantics yield a never-ending big step -->
+    <override_semantics big_step_maximality="take_many"/>
+  </statechart>
+
+  <input>
+    <input_event port="in" name="tk0" time="0 d"/>
+    <input_event port="in" name="tk0" time="0 d"/>
+    <input_event port="in" name="tk0" time="0 d"/>
+    <input_event port="in" name="tk0" time="0 d"/>
+  </input>
+
+  <output>
+    <big_step>
+      <event port="out" name="done"/>
+    </big_step>
+  </output>
+</test>

+ 4 - 2
test/test_files/day_atlee/statechart_fig8_counter.xml

@@ -1,9 +1,11 @@
 <?xml version="1.0" ?>
 <statechart>
-  <semantics />
+  <!-- day & atlee dictates "whole", had to add "next_small_step" myself-->
+  <semantics
+    input_event_lifeline="whole"
+    internal_event_lifeline="next_small_step"/>
 
   <datamodel>
-    <var id="c" expr="0"/>
   </datamodel>
 
   <tree>

+ 19 - 0
test/test_files/day_atlee/test_02_counter_takeone.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+<test>
+  <statechart src="statechart_fig8_counter.xml">
+    <override_semantics big_step_maximality="take_one"/>
+  </statechart>
+
+  <input>
+    <input_event port="in" name="tk0" time="0 d"/>
+    <input_event port="in" name="tk0" time="0 d"/>
+    <input_event port="in" name="tk0" time="0 d"/>
+    <input_event port="in" name="tk0" time="0 d"/>
+  </input>
+
+  <output>
+    <big_step>
+      <event port="out" name="done"/>
+    </big_step>
+  </output>
+</test>