<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

def _compile_random_variable_expression(self,
                                            expr: Expression,
                                            scope: Dict[str, TensorFluent],
                                            batch_size: Optional[int] = None,
                                            noise: Optional[List[tf.Tensor]] = None) -> TensorFluent:
        '''Compile a random variable expression `expr` into a TensorFluent
        in the given `scope` with optional batch size.

        If `reparam` tensor is given, then it conditionally stops gradient
        backpropagation at the batch level where `reparam` is False.

        Args:
            expr (:obj:`rddl2tf.expr.Expression`): A RDDL random variable 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

        if etype[1] == 'KronDelta':
            sample = self._compile_expression(args[0], scope, batch_size, noise)
        elif etype[1] == 'Bernoulli':
            mean = self._compile_expression(args[0], scope, batch_size, noise)
            dist, sample = TensorFluent.Bernoulli(mean, batch_size)
        elif etype[1] == 'Uniform':
            low = self._compile_expression(args[0], scope, batch_size, noise)
            high = self._compile_expression(args[1], scope, batch_size, noise)
            dist, sample = TensorFluent.Uniform(low, high, batch_size)
        elif etype[1] == 'Normal':
            if noise is None:
                mean = self._compile_expression(args[0], scope, batch_size, noise)
                variance = self._compile_expression(args[1], scope, batch_size, noise)
                dist, sample = TensorFluent.Normal(mean, variance, batch_size)
            else:
                xi = noise.pop()
                xi = TensorFluent(xi, scope=[], batch=True)
                mean = self._compile_expression(args[0], scope, batch_size, noise)
                variance = self._compile_expression(args[1], scope, batch_size, noise)
                sample = mean + TensorFluent.sqrt(variance) * xi
        elif etype[1] == 'Laplace':
            mean = self._compile_expression(args[0], scope, batch_size, noise)
            variance = self._compile_expression(args[1], scope, batch_size, noise)
            dist, sample = TensorFluent.Laplace(mean, variance, batch_size)
        elif etype[1] == 'Gamma':
            shape = self._compile_expression(args[0], scope, batch_size, noise)
            scale = self._compile_expression(args[1], scope, batch_size, noise)
            dist, sample = TensorFluent.Gamma(shape, scale, batch_size)
        elif etype[1] == 'Exponential':
            mean = self._compile_expression(args[0], scope, batch_size, noise)
            dist, sample = TensorFluent.Exponential(mean, batch_size)
        else:
            raise ValueError('Invalid random variable expression:\n{}.'.format(expr))

        return sample