class_docstr: The DestroyHandler class detects when a graph is impossible to evaluate
  because of aliasing and destructive operations.
  
  Several data structures are used to do this.
  
  An Op can use its view_map property to declare that an output may be
  aliased to an input. If that output is destroyed, the input is also
  considered to be destroyed. The view_maps of several Ops can feed into
  one another and form a directed graph. The consequence of destroying any
  variable in such a graph is that all variables in the graph must be
  considered to be destroyed, because they could all be referring to the
  same underlying storage.
  
  In the current implementation, that graph is a tree, and the root of that
  tree is called the foundation.
  
  TODO: why "in the current implementation" ? is there another implementation
        planned?
  TODO: why is the graph a tree? isn't it possible that one variable could
        be aliased to many variables? for example, don't switch and ifelse
        have to do this?
  
  The original DestroyHandler (if 0'ed out above) computed several data
  structures from scratch each time it was asked to validate the graph.
  Because this happens potentially thousands of times and each graph to
  validate is extremely similar to the previous one, computing the
  data structures from scratch repeatedly was wasteful and resulted in
  high compile times for large graphs.
  
  This implementation computes the data structures once at initialization
  and then incrementally updates them.
  
  It is a work in progress. The following data structures have been
  converted to use the incremental strategy:
      <none>
  
  The following data structures remain to be converted:
      <unknown>
class_docstr_tok: ["The","DestroyHandler","class","detects","when","a","graph","is","impossible","to","evaluate","because","of","aliasing","and","destructive","operations",".","Several","data","structures","are","used","to","do","this",".","An","Op","can","use","its","view_map","property","to","declare","that","an","output","may","be","aliased","to","an","input",".","If","that","output","is","destroyed",",","the","input","is","also","considered","to","be","destroyed",".","The","view_maps","of","several","Ops","can","feed","into","one","another","and","form","a","directed","graph",".","The","consequence","of","destroying","any","variable","in","such","a","graph","is","that","all","variables","in","the","graph","must","be","considered","to","be","destroyed",",","because","they","could","all","be","referring","to","the","same","underlying","storage",".","In","the","current","implementation",",","that","graph","is","a","tree",",","and","the","root","of","that","tree","is","called","the","foundation",".","TODO",":","why","``","in","the","current","implementation","''","?","is","there","another","implementation","planned","?","TODO",":","why","is","the","graph","a","tree","?","is","n't","it","possible","that","one","variable","could","be","aliased","to","many","variables","?","for","example",",","do","n't","switch","and","ifelse","have","to","do","this","?","The","original","DestroyHandler","(","if","0'ed","out","above",")","computed","several","data","structures","from","scratch","each","time","it","was","asked","to","validate","the","graph",".","Because","this","happens","potentially","thousands","of","times","and","each","graph","to","validate","is","extremely","similar","to","the","previous","one",",","computing","the","data","structures","from","scratch","repeatedly","was","wasteful","and","resulted","in","high","compile","times","for","large","graphs",".","This","implementation","computes","the","data","structures","once","at","initialization","and","then","incrementally","updates","them",".","It","is","a","work","in","progress",".","The","following","data","structures","have","been","converted","to","use","the","incremental","strategy",":","<","none",">","The","following","data","structures","remain","to","be","converted",":","<","unknown",">"]
docstr: Remove Apply instance from set which must be computed.
docstr_tok: ["Remove","Apply","instance","from","set","which","must","be","computed","."]
code: def on_prune(self, fgraph, app, reason):
      """
      Remove Apply instance from set which must be computed.
  
      """
      if app not in self.debug_all_apps:
          raise ProtocolError("prune without import")
      self.debug_all_apps.remove(app)
  
      # UPDATE self.clients
      for input in set(app.inputs):
          del self.clients[input][app]
  
      if getattr(app.op, "destroy_map", OrderedDict()):
          self.destroyers.remove(app)
  
      # Note: leaving empty client dictionaries in the struct.
      # Why? It's a pain to remove them. I think they aren't doing any harm, they will be
      # deleted on_detach().
  
      # UPDATE self.view_i, self.view_o
      for o_idx, i_idx_list in iteritems(
          getattr(app.op, "view_map", OrderedDict())
      ):
          if len(i_idx_list) > 1:
              # destroying this output invalidates multiple inputs
              raise NotImplementedError()
          o = app.outputs[o_idx]
          i = app.inputs[i_idx_list[0]]
  
          del self.view_i[o]
  
          self.view_o[i].remove(o)
          if not self.view_o[i]:
              del self.view_o[i]
  
      self.stale_droot = True
      if app in self.fail_validate:
          del self.fail_validate[app]
  
imports: from __future__ import absolute_import, print_function, division
  from collections import deque, OrderedDict
  from six import iteritems
  import itertools
  import theano
  from theano import config
  from .None import toolbox
  from .None import graph
  from theano.misc.ordered_set import OrderedSet
  from .fg import InconsistencyError
label_desc: Use image node_id 8 for calling the DestroyHandler obj's underlying member method code with example usage: obj.on_prune(fgraph, app, reason) without return types