<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def walk_transitive_dependency_graph(self, addresses, work, predicate=None, postorder=False, dep_predicate=None, prelude=None, epilogue=None):
 """Given a work function, walks the transitive dependency closure of `addresses` using DFS. :API: public :param list<Address> addresses: The closure of `addresses` will be walked. :param function work: The function that will be called on every target in the closure using the specified traversal order. :param bool postorder: When ``True``, the traversal order is postorder (children before parents), else it is preorder (parents before children). :param function predicate: If this parameter is not given, no Targets will be filtered out of the closure. If it is given, any Target which fails the predicate will not be walked, nor will its dependencies. Thus predicate effectively trims out any subgraph that would only be reachable through Targets that fail the predicate. :param function dep_predicate: Takes two parameters, the current target and the dependency of the current target. If this parameter is not given, no dependencies will be filtered when traversing the closure. If it is given, when the predicate fails, the edge to the dependency will not be expanded. :param function prelude: Function to run before any dependency expansion. It takes the currently explored target as an argument. If ``postorder`` is ``False``, it will run after the current node is visited. It is not affected by ``dep_predicate``. It is not run if ``predicate`` does not succeed. :param function epilogue: Function to run after children nodes are visited. It takes the currently explored target as an argument. If ``postorder`` is ``True``, it runs before visiting the current node. It is not affected by ``dep_predicate``. It is not run if ``predicate`` is not passed. """

    walk = self._walk_factory(dep_predicate)

    def _walk_rec(addr, level=0):
      # If we've followed an edge to this address, stop recursing.
      if not walk.expand_once(addr, level):
        return

      target = self._target_by_address[addr]

      if predicate and not predicate(target):
        return

      if not postorder and walk.do_work_once(addr):
        work(target)

      if prelude:
        prelude(target)

      for dep_address in self._target_dependencies_by_address[addr]:
        if walk.expanded_or_worked(dep_address):
          continue
        if walk.dep_predicate(target, self._target_by_address[dep_address], level):
          _walk_rec(dep_address, level + 1)

      if epilogue:
        epilogue(target)

      if postorder and walk.do_work_once(addr):
        work(target)

    for address in addresses:
      _walk_rec(address)