Repository: sympy/sympy
File: sympy/logic/boolalg.py (Python)

Code before:
    Returns a list of lists, with all possible combinations of n zeros and ones
    with an even number of ones.
    """
    return [e for e in [ibin(i, n) for i in range(2**n)] if sum(e) % 2 == 0]


def _simplified_pairs(terms):
    """
    Reduces a set of minterms, if possible, to a simplified set of minterms
    with one less variable in the terms using QM method.
    """
    if not terms:
        return []

    simplified_terms = []
    todo = list(range(len(terms)))

    # Count number of ones as _check_pair can only potentially match if there
    # is at most a difference of a single one
    termdict = defaultdict(list)
    for n, term in enumerate(terms):
        ones = sum(1 for t in term if t == 1)
        termdict[ones].append(n)

    variables = len(terms[0])
    for k in range(variables):
        for i in termdict[k]:
            for j in termdict[k+1]:
                index = _check_pair(terms[i], terms[j])
                if index != -1:
                    # Mark terms handled
                    todo[i] = todo[j] = None
                    # Copy old term
                    newterm = terms[i][:]
                    # Set differing position to don't care
                    newterm[index] = 3
                    # Add if not already there
                    if newterm not in simplified_terms:
                        simplified_terms.append(newterm)

    if simplified_terms:
        # Further simplifications only among the new terms
        simplified_terms = _simplified_pairs(simplified_terms)

    # Add remaining, non-simplified, terms
    simplified_terms.extend([terms[i] for i in todo if i is not None])
    return simplified_terms


def _rem_redundancy(l1, terms):
    """

Review comment (suggestion):
The `int.bit_count` method does not exist in Python 3.9 so this should be changed to use something else.

Code after:
    """
    Converts a term in the expansion of a function from binary to its
    variable form (for ANF).

    Parameters
    ==========

    term : list of 1's and 0's (complementation pattern)
    variables : list of variables

    """
    temp = [variables[n] for n, t in enumerate(term) if t == 1]

    if not temp:
        return true

    return And(*temp)


def _get_odd_parity_terms(n):
    """
    Returns a list of lists, with all possible combinations of n zeros and ones
    with an odd number of ones.
    """
    return [[1 if (mask >> i) & 1 else 0 for i in range(n)]
            for mask in range(1 << n) if mask.bit_count() % 2 == 1]


def _get_even_parity_terms(n):
    """
    Returns a list of lists, with all possible combinations of n zeros and ones
    with an even number of ones.
    """
    return [[1 if (mask >> i) & 1 else 0 for i in range(n)]
            for mask in range(1 << n) if mask.bit_count() % 2 == 0]


def _simplified_pairs(terms):
    """
    Reduces a set of minterms, if possible, to a simplified set of minterms
    with one less variable in the terms using QM method.
    """
    if not terms:
        return []

    simplified_terms = []
    todo = list(range(len(terms)))

    # Count number of ones as _check_pair can only potentially match if there
    # is at most a difference of a single one
    termdict = defaultdict(list)