@@ -23,10 +23,42 @@ def validate_step_parameter_space_dimensions(
2323 ExpressionError if the combination expression violates constraints.
2424 """
2525 parse_tree = Parser ().parse (combination )
26- _validate_expr_tree (parse_tree , parameter_range_lengths )
26+ _validate_expr_tree_dimensions (parse_tree , parameter_range_lengths )
2727
2828
29- def _validate_expr_tree (root : Node , parameter_range_lengths : dict [str , int ]) -> int :
29+ def validate_step_parameter_space_chunk_constraint (chunk_parameter : str , parse_tree : Node ) -> bool :
30+ """This validates that the task parameter of type CHUNK[INT] never appears
31+ within scope of an associative expression. A single chunk consists of
32+ individual values from the non-chunk parameters, and a set of values from the
33+ chunk parameter. With this restriction, the session script code can interpret
34+ these parameters easily, while without it the specification would need to define
35+ how the associations are represented and provided to the script.
36+
37+ Raises:
38+ ExpressionError if the combination expression violates the chunk constraint.
39+ """
40+ # Returns True if the subtree includes the chunk parameter, otherwise False
41+ if isinstance (parse_tree , IdentifierNode ):
42+ return parse_tree .parameter == chunk_parameter
43+ elif isinstance (parse_tree , AssociationNode ):
44+ for child in parse_tree .children :
45+ if validate_step_parameter_space_chunk_constraint (chunk_parameter , child ):
46+ raise ExpressionError (
47+ (
48+ f"CHUNK[INT] parameter { chunk_parameter } must not be part of an associative expression. "
49+ )
50+ )
51+ return False
52+ else :
53+ # For type hinting
54+ assert isinstance (parse_tree , ProductNode )
55+ return any (
56+ validate_step_parameter_space_chunk_constraint (chunk_parameter , child )
57+ for child in parse_tree .children
58+ )
59+
60+
61+ def _validate_expr_tree_dimensions (root : Node , parameter_range_lengths : dict [str , int ]) -> int :
3062 # Returns the length of the subtree while recursively validating it.
3163 if isinstance (root , IdentifierNode ):
3264 name = root .parameter
@@ -35,7 +67,8 @@ def _validate_expr_tree(root: Node, parameter_range_lengths: dict[str, int]) ->
3567 # Association requires that all arguments are the exact same length.
3668 # Ensure that is the case
3769 arg_lengths = tuple (
38- _validate_expr_tree (child , parameter_range_lengths ) for child in root .children
70+ _validate_expr_tree_dimensions (child , parameter_range_lengths )
71+ for child in root .children
3972 )
4073 if len (set (arg_lengths )) > 1 :
4174 raise ExpressionError (
@@ -49,5 +82,10 @@ def _validate_expr_tree(root: Node, parameter_range_lengths: dict[str, int]) ->
4982 # For type hinting
5083 assert isinstance (root , ProductNode )
5184 return reduce (
52- mul , (_validate_expr_tree (child , parameter_range_lengths ) for child in root .children ), 1
85+ mul ,
86+ (
87+ _validate_expr_tree_dimensions (child , parameter_range_lengths )
88+ for child in root .children
89+ ),
90+ 1 ,
5391 )
0 commit comments