code: def cleave_sequence(input_layer, unroll=None):
    
    if unroll is None:
      raise ValueError('You must set unroll either here or in the defaults.')
  
    shape = input_layer.shape
    if shape[0] is not None and shape[0] % unroll != 0:
      raise ValueError('Must divide the split dimension evenly: %d mod %d != 0' %
                       (shape[0], unroll))
  
    if unroll <= 0:
      raise ValueError('Unroll must be > 0: %s' % unroll)
    elif unroll == 1:
      splits = [input_layer.tensor]
    else:
      splits = tf.split(
          value=input_layer.tensor, num_or_size_splits=unroll, axis=0)
    result = input_layer.with_sequence(splits)
  
    # This is an abuse of the defaults system, but it is safe because we are only
    # modifying result.
    defaults = result.defaults
    if 'unroll' in defaults:
      del defaults['unroll']
    return result
docs: Cleaves a tensor into a sequence, this is the inverse of squash.
  
    Recurrent methods unroll across an array of Tensors with each one being a
    timestep.  This cleaves the first dim so that each it is an array of Tensors.
    It is the inverse of squash_sequence.
  
    Args:
      input_layer: The input layer.
      unroll: The number of time steps.
    Returns:
      A PrettyTensor containing an array of tensors.
    Raises:
      ValueError: If unroll is not specified and it has no default or it is <= 0.