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: Return None.
  
  Raise InconsistencyError when
  a) orderings() raises an error
  b) orderings cannot be topologically sorted.
docstr_tok: ["Return","None",".","Raise","InconsistencyError","when","a",")","orderings","(",")","raises","an","error","b",")","orderings","can","not","be","topologically","sorted","."]
code: def validate(self, fgraph):
      """
      Return None.
  
      Raise InconsistencyError when
      a) orderings() raises an error
      b) orderings cannot be topologically sorted.
  
      """
      if self.destroyers:
          if self.algo == "fast":
              if self.fail_validate:
                  app_err_pairs = self.fail_validate
                  self.fail_validate = OrderedDict()
                  # self.fail_validate can only be a hint that maybe/probably
                  # there is a cycle.This is because inside replace() we could
                  # record many reasons to not accept a change, but we don't
                  # know which one will fail first inside validate(). Thus,the
                  # graph might have already changed when we raise the
                  # self.fail_validate error. So before raising the error, we
                  # double check here.
                  for app in app_err_pairs:
                      if app in fgraph.apply_nodes:
                          self.fast_destroy(app, "validate")
                  if self.fail_validate:
                      self.fail_validate = app_err_pairs
                      raise app_err_pairs[app]
          else:
              ords = self.orderings(fgraph, ordered=False)
              if _contains_cycle(fgraph, ords):
                  raise InconsistencyError(
                      "Dependency graph contains cycles"
                  )
      else:
          # James's Conjecture:
          # If there are no destructive ops, then there can be no cycles.
  
          # FB: This isn't always True. It can happened that
          # optimization introduce node that depend on itself. This
          # is very rare and should not happen in general. It will be
          # caught later. The error will be far from the source. But
          # doing this conjecture should speed up compilation most of
          # the time. The user should create such dependency except
          # if he mess too much with the internal.
          pass
      return True
  
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 10 for calling the DestroyHandler obj's underlying member method code with example usage: obj.validate(fgraph) and returns: True