docs: def _remove_predicates(xast, node, context):
      '''Remove any constructible predicates specified in the xpath
      relative to the specified node.
  
      :param xast: parsed xpath (xpath abstract syntax tree) from
  	:mod:`eulxml.xpath`
      :param node: lxml element which predicates will be removed from
      :param context: any context required for the xpath (e.g.,
      	namespace definitions)
  
      :returns: updated a copy of the xast without the predicates that
  	were successfully removed
      '''
      # work from a copy since it may be modified
      xast_c = deepcopy(xast)
      # check if predicates are constructable
      for pred in list(xast_c.predicates):
          # ignore predicates that we can't construct
          if not _predicate_is_constructible(pred):
              continue
  
          if isinstance(pred, ast.BinaryExpression):
              # TODO: support any other predicate operators?
              # predicate construction supports op /
  
              # If the xml still matches the constructed value, remove it.
              # e.g., @type='text' or level='leaf'
              if pred.op == '=' and \
                     node.xpath(serialize(pred), **context) is True:
                  # predicate xpath returns True if node=value
  
                  if isinstance(pred.left, ast.Step):
                      if pred.left.axis in ('@', 'attribute'):
                          if _remove_attribute_node(node, context, pred.left):
                              # remove from the xast
                              xast_c.predicates.remove(pred)
                      elif pred.left.axis in (None, 'child'):
                          if _remove_child_node(node, context, pred.left, if_empty=True):
                              xast_c.predicates.remove(pred)
  
                  elif isinstance(pred.left, ast.BinaryExpression):
                      # e.g., level/@id='b' or level/deep='deeper'
                      # - value has already been checked by xpath above,
                      # so just remove the multipart path
                      _remove_xml(pred.left, node, context, if_empty=True)
  
      return xast_c