docs: def _build_action_bound_constraints_table(self):
          '''Builds the lower and upper action bound constraint expressions.'''
          self.action_lower_bound_constraints = {}
          self.action_upper_bound_constraints = {}
  
          for name, preconds in self.local_action_preconditions.items():
  
              for precond in preconds:
                  expr_type = precond.etype
                  expr_args = precond.args
  
                  bounds_expr = None
  
                  if expr_type == ('aggregation', 'forall'):
                      inner_expr = expr_args[1]
                      if inner_expr.etype[0] == 'relational':
                          bounds_expr = inner_expr
                  elif expr_type[0] == 'relational':
                      bounds_expr = precond
  
                  if bounds_expr:
                      # lower bound
                      bound = self._extract_lower_bound(name, bounds_expr)
                      if bound is not None:
                          self.action_lower_bound_constraints[name] = bound
                      else: # upper bound
                          bound = self._extract_upper_bound(name, bounds_expr)
                          if bound is not None:
                              self.action_upper_bound_constraints[name] = bound