def __get_scope(cls,
            expr: Union['Expression', Tuple]) -> Set[str]:
        '''Returns the set of fluents in the expression's scope.

        Args:
            expr: Expression object or nested tuple of Expressions.

        Returns:
            The set of fluents in the expression's scope.
        '''
        scope = set()
        for i, atom in enumerate(expr):
            if isinstance(atom, Expression):
                scope.update(cls.__get_scope(atom._expr))
            elif type(atom) in [tuple, list]:
                scope.update(cls.__get_scope(atom))
            elif atom == 'pvar_expr':
                functor, params = expr[i+1]
                arity = len(params) if params is not None else 0
                name = '{}/{}'.format(functor, arity)
                scope.add(name)
                break
        return scope