def dependency_list(e):
    """
    Get the set of config identifiers referred to by an expression. A
    set is returned instead of a list as we don't need duplicates, and
    order doesn't matter.
    """
    if e is None:
        return set()
    assert type(e) == tuple

    if e[0] in ['and', 'or', '=', '!=', '<', '<=', '>', '>=', '+', '-']:
        return dependency_list(e[1]) | dependency_list(e[2])
    elif e[0] == 'not':
        return dependency_list(e[1])
    elif e[0] in ['string', 'number', 'boolean']:
        # Quoted string, number or boolean
        return set()
    elif e[0] == 'identifier':
        return {e[1]}
    raise Exception("Unexpected depend list: " + str(e))