code: def tail_pop(
      tail: CrayTail,
      pop_indices: ndarray,
      allow_empty_pop: bool = False,
  ) -> Tuple[CrayTail, ndarray]:
      """
      Pop data from tail at specified indices.
  
      Args:
          tail: A CrayTail to pop data from.
          pop_indices: Indices specifying pop locations (for interleaved
              coding).
          allows_empty_pops: A boolean that specifys if random bits should
              be created on demand, if the stack is depleted.
  
      Returns:
          A 2-tuple containing:
              ``tail`` with data popped from top of stack by moving the tail
                  pointer.
              The information content that was popped.
  
      """
      pop_indices_flat = jnp.ravel(pop_indices)  # interleave flattening
      limit, data = tail
      unsorted = lax.sort_key_val(
          pop_indices_flat, jnp.arange(pop_indices.size)
      )[1]
  
      limit = lax.cond(
          allow_empty_pop,
          lambda _: jnp.clip(limit + pop_indices.sum(), 0, len(data)),
          lambda _: limit + pop_indices.sum(),
          None,
      )
      # here we return a slice containing the information in the pop indices
      # we don't actually need to pop the values from the array - instead we just
      # move the pointer along and remove the popped values at the end
      return CrayTail(limit, data), jnp.reshape(
          lax.sort_key_val(
              unsorted,
              lax.dynamic_slice(
                  data, limit - pop_indices.size, pop_indices_flat.shape  # type: ignore
              ),
          )[1],
          pop_indices.shape,
      )
  
imports: from typing import NamedTuple, Sequence, Tuple
  import jax.lax
  import jax.numpy
  from jax.numpy import ndarray
  from jax.random import PRNGKey, randint
label_desc: Use image node_id 4 for calling a global function with example usage: tail_pop(tail, pop_indices, allow_empty_pop) and returns: CrayTail,  jnp