docs: def _compile_aggregation_expression(self,
                                          expr: Expression,
                                          scope: Dict[str, TensorFluent],
                                          batch_size: Optional[int] = None,
                                          noise: Optional[List[tf.Tensor]] = None) -> TensorFluent:
          '''Compile an aggregation expression `expr` into a TensorFluent
          in the given `scope` with optional batch size.
  
          Args:
              expr (:obj:`rddl2tf.expr.Expression`): A RDDL aggregation expression.
              scope (Dict[str, :obj:`rddl2tf.fluent.TensorFluent`]): A fluent scope.
              batch_size (Optional[size]): The batch size.
  
          Returns:
              :obj:`rddl2tf.fluent.TensorFluent`: The compiled expression as a TensorFluent.
          '''
          etype = expr.etype
          args = expr.args
  
          typed_var_list = args[:-1]
          vars_list = [var for _, (var, _) in typed_var_list]
          expr = args[-1]
  
          x = self._compile_expression(expr, scope)
  
          etype2aggr = {
              'sum':     x.sum,
              'prod':    x.prod,
              'avg':     x.avg,
              'maximum': x.maximum,
              'minimum': x.minimum,
              'exists':  x.exists,
              'forall':  x.forall
          }
  
          if etype[1] not in etype2aggr:
              raise ValueError('Invalid aggregation expression {}.'.format(expr))
  
          aggr = etype2aggr[etype[1]]
          fluent = aggr(vars_list=vars_list)
  
          return fluent