[rtems-central commit] validation: Add get_post_conditions()

Sebastian Huber sebh at rtems.org
Tue Apr 13 08:27:20 UTC 2021


Module:    rtems-central
Branch:    master
Commit:    9e7ee2687d8f0189564b9e72a2d598444a8433d2
Changeset: http://git.rtems.org/rtems-central/commit/?id=9e7ee2687d8f0189564b9e72a2d598444a8433d2

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Apr 13 10:07:12 2021 +0200

validation: Add get_post_conditions()

---

 rtemsspec/tests/spec-validation/action2.yml | 10 ++++++
 rtemsspec/tests/test_validation.py          | 19 +++++++++--
 rtemsspec/validation.py                     | 49 +++++++++++++++++++++++++++++
 specview.py                                 | 45 ++------------------------
 4 files changed, 79 insertions(+), 44 deletions(-)

diff --git a/rtemsspec/tests/spec-validation/action2.yml b/rtemsspec/tests/spec-validation/action2.yml
index 822a470..8c269a1 100644
--- a/rtemsspec/tests/spec-validation/action2.yml
+++ b/rtemsspec/tests/spec-validation/action2.yml
@@ -272,4 +272,14 @@ transition-map:
     - B0
     C:
     - C0
+- enabled-by: BOOM
+  post-conditions:
+    A: N/A
+    B: B0
+  pre-conditions:
+    A: N/A
+    B:
+    - B0
+    C:
+    - C0
 type: requirement
diff --git a/rtemsspec/tests/test_validation.py b/rtemsspec/tests/test_validation.py
index 938762c..a35ff37 100644
--- a/rtemsspec/tests/test_validation.py
+++ b/rtemsspec/tests/test_validation.py
@@ -49,8 +49,13 @@ def test_validation(tmpdir):
     assert len(list(transition_map.get_variants([]))) == 36
     assert len(list(transition_map.get_variants(["RTEMS_MULTIPROCESSING"
                                                  ]))) == 36
+    assert len(list(transition_map.get_post_conditions([]))) == 4
+    assert len(
+        list(transition_map.get_post_conditions(["RTEMS_MULTIPROCESSING"
+                                                 ]))) == 5
     transition_map = TransitionMap(item_cache["/action2"])
     assert transition_map.skip_idx_to_name(1) == "SkipReason"
+    assert len(list(transition_map.get_post_conditions(["BOOM"]))) == 6
 
     generate(validation_config, item_cache)
 
@@ -2109,14 +2114,24 @@ static const Action2_Entry
 Action2_Entries[] = {
   { 0, 1, 0, 0, Action2_Post_A_A1, Action2_Post_B_NA },
   { 0, 0, 0, 0, Action2_Post_A_A2, Action2_Post_B_B0 },
-  { 0, 0, 0, 0, Action2_Post_A_A1, Action2_Post_B_B0 },
   { 1, 0, 0, 0, Action2_Post_A_NA, Action2_Post_B_NA },
+  { 0, 0, 0, 0, Action2_Post_A_A1, Action2_Post_B_B0 },
+#if defined(BOOM)
+  { 0, 1, 0, 0, Action2_Post_A_NA, Action2_Post_B_B0 },
+#else
+  { 0, 0, 0, 0, Action2_Post_A_A1, Action2_Post_B_B0 },
+#endif
+#if defined(BOOM)
+  { 0, 1, 0, 0, Action2_Post_A_NA, Action2_Post_B_B0 },
+#else
+  { 0, 0, 0, 0, Action2_Post_A_A2, Action2_Post_B_B0 },
+#endif
   { 0, 0, 0, 0, Action2_Post_A_A3, Action2_Post_B_B0 }
 };
 
 static const uint8_t
 Action2_Map[] = {
-  2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 4, 0, 0, 0, 3, 3, 3
+  4, 3, 3, 0, 0, 0, 1, 1, 1, 5, 1, 6, 0, 0, 0, 2, 2, 2
 };
 
 static size_t Action2_Scope( void *arg, char *buf, size_t n )
diff --git a/rtemsspec/validation.py b/rtemsspec/validation.py
index 944764f..baff530 100644
--- a/rtemsspec/validation.py
+++ b/rtemsspec/validation.py
@@ -615,6 +615,10 @@ _POST_COND_OP = {
     "specified-by": _post_cond_specified_by,
 }
 
+PostCond = Tuple[int, ...]
+
+PreCondsOfPostCond = List[Tuple[List[int], ...]]
+
 
 class TransitionMap:
     """ Representation of an action requirement transition map. """
@@ -677,6 +681,51 @@ class TransitionMap:
                 variant = transitions[0]
             yield map_idx, variant
 
+    def get_post_conditions(
+            self, enabled: List[str]
+    ) -> Iterator[Tuple[PostCond, PreCondsOfPostCond]]:
+        """
+        Yields tuples of post-condition variants and the corresponding
+        pre-condition variants which are enabled by the enabled list.
+
+        The first entry of the post-condition variant is the skip index.  The
+        remaining entries are post-condition indices.  The pre-condition
+        variants are a list of tuples.  Each tuple entry corresponds to a
+        pre-condition and provides a list of corresponding pre-condition state
+        indices.
+        """
+        entries = {}  # type: Dict[PostCond, PreCondsOfPostCond]
+        for map_idx, variant in self.get_variants(enabled):
+            key = (variant.skip, ) + variant.post_cond
+            entry = entries.setdefault(key, [])
+            entry.append(
+                tuple([state] for state in self.map_idx_to_pre_co_states(
+                    map_idx, variant.pre_cond_na)))
+        for post_cond, pre_conds in sorted(entries.items(),
+                                           key=lambda x: (x[0][0], len(x[1]))):
+            while True:
+                last = pre_conds[0]
+                combined_pre_conds = [last]
+                combined_count = 0
+                for row in pre_conds[1:]:
+                    if row == last:
+                        continue
+                    diff = [
+                        index for index, states in enumerate(last)
+                        if states != row[index]
+                    ]
+                    if len(diff) == 1:
+                        index = diff[0]
+                        combined_count += 1
+                        last[index].extend(row[index])
+                    else:
+                        combined_pre_conds.append(row)
+                        last = row
+                pre_conds = combined_pre_conds
+                if combined_count == 0:
+                    break
+            yield post_cond, pre_conds
+
     def _post_process(self) -> None:
         for map_idx, transitions in enumerate(self):
             if not transitions or not isinstance(
diff --git a/specview.py b/specview.py
index 40c988d..5ef0f73 100755
--- a/specview.py
+++ b/specview.py
@@ -28,7 +28,7 @@
 import argparse
 import itertools
 import sys
-from typing import Dict, Iterator, List, Set, Tuple
+from typing import List, Set, Tuple
 
 from rtemsspec.items import Item, ItemCache, Link
 from rtemsspec.sphinxcontent import SphinxContent
@@ -124,48 +124,9 @@ def _to_name(transition_map, co_idx: int, st_idx: int) -> str:
             f"{transition_map.post_co_idx_st_idx_to_st_name(co_idx, st_idx)}")
 
 
-_PostCond = Tuple[int, ...]
-_Entries = List[Tuple[List[int], ...]]
-
-
-def _get_entries(transition_map: TransitionMap,
-                 enabled: List[str]) -> Iterator[Tuple[_PostCond, _Entries]]:
-    entries = {}  # type: Dict[_PostCond, _Entries]
-    for map_idx, variant in transition_map.get_variants(enabled):
-        key = (variant.skip, ) + variant.post_cond
-        entry = entries.setdefault(key, [])
-        entry.append(
-            tuple([state] for state in transition_map.map_idx_to_pre_co_states(
-                map_idx, variant.pre_cond_na)))
-    for post_cond, entry in sorted(entries.items(),
-                                   key=lambda x: (x[0][0], len(x[1]))):
-        while True:
-            last = entry[0]
-            combined_entry = [last]
-            combined_count = 0
-            for row in entry[1:]:
-                if row == last:
-                    continue
-                diff = [
-                    index for index, states in enumerate(last)
-                    if states != row[index]
-                ]
-                if len(diff) == 1:
-                    index = diff[0]
-                    combined_count += 1
-                    last[index].extend(row[index])
-                else:
-                    combined_entry.append(row)
-                    last = row
-            entry = combined_entry
-            if combined_count == 0:
-                break
-        yield post_cond, entry
-
-
 def _action_list(enabled: List[str], item: Item) -> None:
     transition_map = TransitionMap(item)
-    for post_cond, entry in _get_entries(transition_map, enabled):
+    for post_cond, pre_conds in transition_map.get_post_conditions(enabled):
         print("")
         if post_cond[0]:
             print(transition_map.skip_idx_to_name(post_cond[0]))
@@ -173,7 +134,7 @@ def _action_list(enabled: List[str], item: Item) -> None:
             print(", ".join(
                 _to_name(transition_map, co_idx, st_idx)
                 for co_idx, st_idx in enumerate(post_cond[1:])))
-        for row in entry:
+        for row in pre_conds:
             entries = []
             for co_idx, co_states in enumerate(row):
                 co_name = transition_map.pre_co_idx_to_co_name(co_idx)



More information about the vc mailing list