Check the consistency of the taxonomy.

    Outputs a list of errors and warnings.

def check_taxonomy(taxonomy):
    """Check the consistency of the taxonomy.

    Outputs a list of errors and warnings.
    """
    current_app.logger.info(
        "Building graph with Python RDFLib version %s" %
        rdflib.__version__
    )

    store = rdflib.ConjunctiveGraph()
    store.parse(taxonomy)

    current_app.logger.info("Graph was successfully built.")

    prefLabel = "prefLabel"
    hiddenLabel = "hiddenLabel"
    altLabel = "altLabel"
    composite = "composite"
    compositeOf = "compositeOf"
    note = "note"

    both_skw_and_ckw = []

    # Build a dictionary we will reason on later.
    uniq_subjects = {}
    for subject in store.subjects():
        uniq_subjects[subject] = None

    subjects = {}
    for subject in uniq_subjects:
        strsubject = str(subject).split("#Composite.")[-1]
        strsubject = strsubject.split("#")[-1]
        if (strsubject == "http://cern.ch/thesauri/HEPontology.rdf" or
                strsubject == "compositeOf"):
            continue
        components = {}
        for predicate, value in store.predicate_objects(subject):
            strpredicate = str(predicate).split("#")[-1]
            strobject = str(value).split("#Composite.")[-1]
            strobject = strobject.split("#")[-1]
            components.setdefault(strpredicate, []).append(strobject)
        if strsubject in subjects:
            both_skw_and_ckw.append(strsubject)
        else:
            subjects[strsubject] = components

    current_app.logger.info("Taxonomy contains %s concepts." % len(subjects))

    no_prefLabel = []
    multiple_prefLabels = []
    bad_notes = []
    # Subjects with no composite or compositeOf predicate
    lonely = []
    both_composites = []
    bad_hidden_labels = {}
    bad_alt_labels = {}
    # Problems with composite keywords
    composite_problem1 = []
    composite_problem2 = []
    composite_problem3 = []
    composite_problem4 = {}
    composite_problem5 = []
    composite_problem6 = []

    stemming_collisions = []
    interconcept_collisions = {}

    for subject, predicates in iteritems(subjects):
        # No prefLabel or multiple prefLabels
        try:
            if len(predicates[prefLabel]) > 1:
                multiple_prefLabels.append(subject)
        except KeyError:
            no_prefLabel.append(subject)

        # Lonely and both composites.
        if composite not in predicates and compositeOf not in predicates:
            lonely.append(subject)
        elif composite in predicates and compositeOf in predicates:
            both_composites.append(subject)

        # Multiple or bad notes
        if note in predicates:
            bad_notes += [(subject, n) for n in predicates[note]
                          if n not in ('nostandalone', 'core')]

        # Bad hidden labels
        if hiddenLabel in predicates:
            for lbl in predicates[hiddenLabel]:
                if lbl.startswith("/") ^ lbl.endswith("/"):
                    bad_hidden_labels.setdefault(subject, []).append(lbl)

        # Bad alt labels
        if altLabel in predicates:
            for lbl in predicates[altLabel]:
                if len(re.findall("/", lbl)) >= 2 or ":" in lbl:
                    bad_alt_labels.setdefault(subject, []).append(lbl)

        # Check composite
        if composite in predicates:
            for ckw in predicates[composite]:
                if ckw in subjects:
                    if compositeOf in subjects[ckw]:
                        if subject not in subjects[ckw][compositeOf]:
                            composite_problem3.append((subject, ckw))
                    else:
                        if ckw not in both_skw_and_ckw:
                            composite_problem2.append((subject, ckw))
                else:
                    composite_problem1.append((subject, ckw))

        # Check compositeOf
        if compositeOf in predicates:
            for skw in predicates[compositeOf]:
                if skw in subjects:
                    if composite in subjects[skw]:
                        if subject not in subjects[skw][composite]:
                            composite_problem6.append((subject, skw))
                    else:
                        if skw not in both_skw_and_ckw:
                            composite_problem5.append((subject, skw))
                else:
                    composite_problem4.setdefault(skw, []).append(subject)

        # Check for stemmed labels
        if compositeOf in predicates:
            labels = (altLabel, hiddenLabel)
        else:
            labels = (prefLabel, altLabel, hiddenLabel)

        patterns = {}
        for label in [lbl for lbl in labels if lbl in predicates]:
            for expression in [expr for expr in predicates[label]
                               if not _is_regex(expr)]:
                pattern = _get_regex_pattern(expression)
                interconcept_collisions.setdefault(pattern, []).\
                    append((subject, label))
                if pattern in patterns:
                    stemming_collisions.append(
                        (subject,
                         patterns[pattern],
                         (label, expression)
                         )
                    )
                else:
                    patterns[pattern] = (label, expression)

    print("\n==== ERRORS ====")

    if no_prefLabel:
        print("\nConcepts with no prefLabel: %d" % len(no_prefLabel))
        print("\n".join(["   %s" % subj for subj in no_prefLabel]))
    if multiple_prefLabels:
        print(("\nConcepts with multiple prefLabels: %d" %
               len(multiple_prefLabels)))
        print("\n".join(["   %s" % subj for subj in multiple_prefLabels]))
    if both_composites:
        print(("\nConcepts with both composite properties: %d" %
               len(both_composites)))
        print("\n".join(["   %s" % subj for subj in both_composites]))
    if bad_hidden_labels:
        print("\nConcepts with bad hidden labels: %d" % len(bad_hidden_labels))
        for kw, lbls in iteritems(bad_hidden_labels):
            print("   %s:" % kw)
            print("\n".join(["      '%s'" % lbl for lbl in lbls]))
    if bad_alt_labels:
        print("\nConcepts with bad alt labels: %d" % len(bad_alt_labels))
        for kw, lbls in iteritems(bad_alt_labels):
            print("   %s:" % kw)
            print("\n".join(["      '%s'" % lbl for lbl in lbls]))
    if both_skw_and_ckw:
        print(("\nKeywords that are both skw and ckw: %d" %
               len(both_skw_and_ckw)))
        print("\n".join(["   %s" % subj for subj in both_skw_and_ckw]))

    print()

    if composite_problem1:
        print("\n".join(["SKW '%s' references an unexisting CKW '%s'." %
                         (skw, ckw) for skw, ckw in composite_problem1]))
    if composite_problem2:
        print("\n".join(["SKW '%s' references a SKW '%s'." %
                         (skw, ckw) for skw, ckw in composite_problem2]))
    if composite_problem3:
        print("\n".join(["SKW '%s' is not composite of CKW '%s'." %
                         (skw, ckw) for skw, ckw in composite_problem3]))
    if composite_problem4:
        for skw, ckws in iteritems(composite_problem4):
            print("SKW '%s' does not exist but is " "referenced by:" % skw)
            print("\n".join(["    %s" % ckw for ckw in ckws]))
    if composite_problem5:
        print("\n".join(["CKW '%s' references a CKW '%s'." % kw
                         for kw in composite_problem5]))
    if composite_problem6:
        print("\n".join(["CKW '%s' is not composed by SKW '%s'." % kw
                         for kw in composite_problem6]))

    print("\n==== WARNINGS ====")

    if bad_notes:
        print(("\nConcepts with bad notes: %d" % len(bad_notes)))
        print("\n".join(["   '%s': '%s'" % _note for _note in bad_notes]))
    if stemming_collisions:
        print("\nFollowing keywords have unnecessary labels that have "
              "already been generated by Classifier.")
        for subj in stemming_collisions:
            print("   %s:\n     %s\n     and %s" % subj)

    print("\nFinished.")
    sys.exit(0)