def apply(self, fgraph):
            tasks = defaultdict(list)

            if self.max_use_ratio is not None:
                max_uses = self.max_use_ratio * len(fgraph.apply_nodes)
                runs = defaultdict(int)
            else:
                runs = None

            def importer(node):
                # print 'IMPORTING', node
                self.backtrack(node, tasks)
            def pruner(node):
                try:
                    del tasks[node]
                except __HOLE__:
                    pass
            def chin(node, i, r, new_r):
                if new_r.owner and not r.clients:
                    self.backtrack(new_r.owner, tasks)

    #         # == NOT IDEAL == #
    #         for node in fgraph.apply_nodes:
    #             importer(node)

            for node in fgraph.toposort():
                tasks[node].extend(lopt for track, i, lopt in self.fetch_tracks0(node.op))

            u = self.attach_updater(fgraph, importer, pruner, chin)
            print('KEYS', [hash(t) for t in tasks.keys()])
            while tasks:
                for node in tasks:
                    todo = tasks.pop(node)
                    break
                for lopt in todo:
                    if runs is not None and runs[lopt] >= max_uses:
                        print('Warning: optimization exceeded its maximal use ratio: %s, %s' % (lopt, max_uses), file=sys.stderr)
                        continue
                    success = self.process_node(fgraph, node, lopt)
                    if success:
                        if runs is not None: runs[lopt] += 1
                        break
            self.detach_updater(fgraph, u)

#     def match(self, node, candidates):
#         candidates[:] = [candidate
#                          for candidate in candidates
#                          if candidate.current.op is None or candidate.current.op == node.op]
#         for candidate in candidates:
#             if candidate.current.inputs is not None:
#                 for in1, in2 in zip(candidate.current.inputs, node.inputs):
#                     if isinstance(in1, string_types):
#                         candidate.match[in1] = in2
#         for client in node.clients:


#         op = node.op
#         patterns = self.pattern_base[(depth, op)].union(self.pattern_base[(depth, WILDCARD)])
#         if not patterns:
#             return patterns
#         return self.match(node, depth + 1).intersection(patterns)


#     def backtrack(self, node, q):
#         for node2, i in node.clients:
#             op2 = node2.op
dataset/ETHPy150Open rizar/attention-lvcsr/libs/Theano/theano/gof/sandbox/equilibrium.py/_EquilibriumOptimizer.apply