def traverse_graph(graph, rules, domains, classifiers=None):
    """Traverses a rule graph and classifies a collection of domains.

    Each node is a dictionary with the schema:

        {
            "title": "Rule name",
            "children": [
                {
                    "title": Rule name",
                    "children": [ ... ],
                },
                ...
            ]
        }

    Rules are evaluated in order. If a rule is successfully evaluated,
    this function will recurse into any child rules, if any exist.

    Finally a classification list, containing the path of rules satisfied
    by the given domains, is returned.

    Args:
        graph (list, dict): Rule graph to traverse.
        rules (dict): Rule objects to evaluate on domains.
        domains (list): Domain objects to classify.
        classifiers (list): Current classifiers for a Domain collection.
    Returns:
        classifiers
    """
    if not classifiers:
        classifiers = []
    for node in graph:
        title = node["title"]
        rule = rules[title]
        if not rule.satisfied_by(domains):
            continue
        classifiers.append(title)
        children = node.get("children")
        if children:
            classifiers = traverse_graph(children, rules, domains, classifiers)
        rule.rename_domains(domains)
        return classifiers
    return classifiers