def METHOD_NAME(fn=None, prefix=None, inner=None):
    """
    :param fn: a stochastic function (callable containing Pyro primitive calls)
    :param prefix: a string to prepend to sample names (optional if ``fn`` is provided)
    :param inner: switch to determine where duplicate name counters appear
    :returns: ``fn`` decorated with a :class:`~pyro.contrib.autoname.scoping.ScopeMessenger`
    ``scope`` prepends a prefix followed by a ``/`` to the name at a Pyro sample site.
    It works much like TensorFlow's ``name_scope`` and ``variable_scope``,
    and can be used as a context manager, a decorator, or a higher-order function.
    ``scope`` is very useful for aligning compositional models with guides or data.
    Example::
        >>> @scope(prefix="a")
        ... def model():
        ...     return pyro.sample("x", dist.Bernoulli(0.5))
        ...
        >>> assert "a/x" in poutine.trace(model).get_trace()
    Example::
        >>> def model():
        ...     with scope(prefix="a"):
        ...         return pyro.sample("x", dist.Bernoulli(0.5))
        ...
        >>> assert "a/x" in poutine.trace(model).get_trace()
    Scopes compose as expected, with outer scopes appearing before inner scopes in names::
        >>> @scope(prefix="b")
        ... def model():
        ...     with scope(prefix="a"):
        ...         return pyro.sample("x", dist.Bernoulli(0.5))
        ...
        >>> assert "b/a/x" in poutine.trace(model).get_trace()
    When used as a decorator or higher-order function,
    ``scope`` will use the name of the input function as the prefix
    if no user-specified prefix is provided.
    Example::
        >>> @scope
        ... def model():
        ...     return pyro.sample("x", dist.Bernoulli(0.5))
        ...
        >>> assert "model/x" in poutine.trace(model).get_trace()
    """
    msngr = ScopeMessenger(prefix=prefix, inner=inner)
    return msngr(fn) if fn is not None else msngr