def reduce_tree(f, parent_unit_node, unit_node, get_children, *state):
    """Enumerate a tree, applying f to in a pre-order fashion to each node.

    parent_unit_node contains the parent of unit_node. For the root of the tree,
    parent_unit_node == unit_node.

    get_children is a single argument function applied to a unit_node to
    get a list/iterator to its children.

    state is used by f to modify state information relating to whatever f does
    to the tree.
    """

    def as_tuple(x):
        if isinstance(x, tuple):
            return x
        else:
            return (x,)

    state = f(parent_unit_node, unit_node, *state)
    for child_unit_node in get_children(unit_node):
        state = reduce_tree(f, unit_node, child_unit_node, get_children, *as_tuple(state))
    return state