<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def prune_unused_nodes(meta_graph, signature_def):
 """Function to prune unused ops given a signature def. This function does a graph traversal through from all outputs as defined in the signature_def to collect all used nodes. Then, any nodes which are unused can be discarded. This is useful for graph which are executing eagerly or on TPUs. Args: meta_graph: The input/output MetaGraphDef for which we wish to prune. signature_def: A SignatureDef which specifies the outputs from which we wish to start graph traversal. """

  # Instantiate a temporary empty graph so that we have access to Graph API
  # and import the meta_graph.
  graph = tf_v1.Graph()
  with graph.as_default():
    tf_v1.train.import_meta_graph(meta_graph, input_map={}, import_scope="")
    # Traverse from all outputs and mark all nodes.
    used_node_names = set()
    for _, tensor_def in signature_def.outputs.items():
      output_tensor = graph.get_tensor_by_name(tensor_def.name)
      mark_backward(output_tensor, used_node_names)
    # Filter out all nodes in the meta_graph that are not used.
    node_filter_in_list = []
    for node in meta_graph.graph_def.node:
      # Make a special exception for VarHandleOp. Removing VarhandleOps
      # will make the graph not importable as they often leave nodes hanging.
      # These will be disconnected through the feedmap when importing the
      # metagraph.
      if node.name in used_node_names or node.op == "VarHandleOp":
        node_filter_in_list.append(node)
    del meta_graph.graph_def.node[:]
    meta_graph.graph_def.node.extend(node_filter_in_list)
  del graph