Yield lines of warnings and errors about input bbl lines.

    profiling -- yield also info lines about input bbl file.

    If bbllines is a valid file name, it will be read.
    Else, it should be an iterable of bubble file lines.

def validate(bbllines:iter, *, profiling=False):
    """Yield lines of warnings and errors about input bbl lines.

    profiling -- yield also info lines about input bbl file.

    If bbllines is a valid file name, it will be read.
    Else, it should be an iterable of bubble file lines.

    """
    if isinstance(bbllines, str):
        if os.path.exists(bbllines):  # filename containing bubble
            bbllines = utils.file_lines(bbllines)
        elif '\n' not in bbllines or '\t' not in bbllines:
            # probably a bad file name: let's rise the proper error
            bbllines = utils.file_lines(bbllines)
        else:  # bubble itself
            bbllines = bbllines.split('\n')
    bubble = tuple(bbllines)
    data = tuple(utils.line_data(line) for line in bubble)
    types = tuple(utils.line_type(line) for line in bubble)
    # launch profiling
    if profiling:
        ltype_counts = Counter(types)
        for ltype, count in ltype_counts.items():
            yield 'INFO {} lines of type {}'.format(count, ltype)
        yield 'INFO {} lines of payload'.format(
            ltype_counts['EDGE'] + ltype_counts['IN'] +
            ltype_counts['NODE'] + ltype_counts['SET'])
    # launch validation
    for errline in (l for l, t in zip(bubble, types) if t == 'ERROR'):
        yield 'ERROR line is not bubble: "{}"'.format(errline)
    tree = BubbleTree.from_bubble_data(data)
    cc, subroots = tree.connected_components()
    # print('cc:', cc)
    # print('subroots:', subroots)
    if profiling:
        yield 'INFO {} top (power)nodes'.format(len(tree.roots))
        yield 'INFO {} connected components'.format(len(cc))
        yield 'INFO {} nodes are defined, {} are used'.format(
            ltype_counts['NODE'], len(tuple(tree.nodes())))
        yield 'INFO {} powernodes are defined, {} are used'.format(
            ltype_counts['SET'], len(tuple(tree.powernodes())))

    yield from inclusions_validation(tree)
    yield from mergeability_validation(tree)