from typing import Dict
from typing import Set


def is_relevant(article_dict: Dict[str, bool], search_set: Set[str],
                major_bool: bool) -> bool:
    """
    Determine whether article is relevant w.r.t. the desired MeSH
    descriptors/keywords. Since descriptors and keywords are both
    represented as strings, this function handles either type of search set.
    Article considered relevant if there is any overlap between its
    descriptors/keywords and the set of desired descriptors/keywords.
    If major topic flag is True, consider only those descriptors/keywords
    marked as major topic for this article.
    :param article_dict: maps each MeSH descriptor/keyword to boolean flag
                         indicating major topic
    :param search_set: set of descriptors/keywords that user specified as relevant
    :param major_bool: if true, consider only article's major topics
    :return: True if this article is relevant, False otherwise
    """
    article_set = set(article_dict.keys())
    if major_bool:
        # Keep only the descriptors/keywords that are marked as major topics
        # Note: some entries in the input files have no descriptors marked as
        # major topics for the article; this probably means that one of the
        # qualifiers on the descriptor is marked as a major topic. We do not
        # extract qualifiers from the .xml file. Also, most keywords are
        # marked N so it is not very useful to filter keywords by their major
        # topic flag, the result will likely be an empty set.
        article_set = set(filter(lambda d: article_dict[d], article_set))
    return not search_set.isdisjoint(article_set)